diff options
author | Daniel Harding <33dannye@gmail.com> | 2021-09-26 23:07:03 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-26 23:07:03 -0500 |
commit | 40dc6651c4f56c067e4237a46ea38a5c8f6f55b4 (patch) | |
tree | bdf4be22a2176e19aeffba4cbadd736d767381f8 | |
parent | df67aac83b466dadf5f74c881bf84dd9ef19bdfc (diff) | |
parent | 48f83527c769441b6c123f3382d90e2e962ef9a0 (diff) |
Merge pull request #111 from ElectroDeoxys/master
Split bank1 & bank2
33 files changed, 10779 insertions, 10728 deletions
diff --git a/src/data/ai_trainer_card_logic.asm b/src/data/duel/ai_trainer_card_logic.asm index 57bf90f..57bf90f 100644 --- a/src/data/ai_trainer_card_logic.asm +++ b/src/data/duel/ai_trainer_card_logic.asm diff --git a/src/data/anims1.asm b/src/data/duel/animations/anims1.asm index 278a145..278a145 100644 --- a/src/data/anims1.asm +++ b/src/data/duel/animations/anims1.asm diff --git a/src/data/anims2.asm b/src/data/duel/animations/anims2.asm index 48f8e41..48f8e41 100644 --- a/src/data/anims2.asm +++ b/src/data/duel/animations/anims2.asm diff --git a/src/data/anims3.asm b/src/data/duel/animations/anims3.asm index d6ebd4d..d6ebd4d 100644 --- a/src/data/anims3.asm +++ b/src/data/duel/animations/anims3.asm diff --git a/src/data/anims4.asm b/src/data/duel/animations/anims4.asm index 07b575c..07b575c 100644 --- a/src/data/anims4.asm +++ b/src/data/duel/animations/anims4.asm diff --git a/src/data/attack_animations.asm b/src/data/duel/animations/attack_animations.asm index 48fa192..48fa192 100644 --- a/src/data/attack_animations.asm +++ b/src/data/duel/animations/attack_animations.asm diff --git a/src/data/duel_animations.asm b/src/data/duel/animations/duel_animations.asm index ba1e0f9..ba1e0f9 100644 --- a/src/data/duel_animations.asm +++ b/src/data/duel/animations/duel_animations.asm diff --git a/src/data/effect_commands.asm b/src/data/duel/effect_commands.asm index e96ef7e..e96ef7e 100644 --- a/src/data/effect_commands.asm +++ b/src/data/duel/effect_commands.asm diff --git a/src/data/duel/practice_text.asm b/src/data/duel/practice_text.asm new file mode 100644 index 0000000..d28e7fa --- /dev/null +++ b/src/data/duel/practice_text.asm @@ -0,0 +1,66 @@ +PracticeDuelTextPointerTable: + dw PracticeDuelText_Turn1 + dw PracticeDuelText_Turn2 + dw PracticeDuelText_Turn3 + dw PracticeDuelText_Turn4 + dw PracticeDuelText_Turn5 + dw PracticeDuelText_Turn6 + dw PracticeDuelText_Turn7 + dw PracticeDuelText_Turn8 + +practicetext: MACRO + db \1 ; Y coord to place the point-by-point instruction + tx \2 ; Dr. Mason's instruction + tx \3 ; static point-by-point instruction +ENDM + +PracticeDuelText_Turn1: + practicetext 2, Turn1DrMason1PracticeDuelText, Turn1Instr1PracticeDuelText + practicetext 5, Turn1DrMason2PracticeDuelText, Turn1Instr2PracticeDuelText + practicetext 8, Turn1DrMason3PracticeDuelText, Turn1Instr3PracticeDuelText + db $00 + +PracticeDuelText_Turn2: + practicetext 2, Turn2DrMason1PracticeDuelText, Turn2Instr1PracticeDuelText + practicetext 5, Turn2DrMason2PracticeDuelText, Turn2Instr2PracticeDuelText + practicetext 8, Turn2DrMason3PracticeDuelText, Turn2Instr3PracticeDuelText + db $00 + +PracticeDuelText_Turn3: + practicetext 2, Turn3DrMason1PracticeDuelText, Turn3Instr1PracticeDuelText + practicetext 5, Turn3DrMason2PracticeDuelText, Turn3Instr2PracticeDuelText + practicetext 8, Turn3DrMason3PracticeDuelText, Turn3Instr3PracticeDuelText + db $00 + +PracticeDuelText_Turn4: + practicetext 2, Turn4DrMason1PracticeDuelText, Turn4Instr1PracticeDuelText + practicetext 5, Turn4DrMason2PracticeDuelText, Turn4Instr2PracticeDuelText + practicetext 8, Turn4DrMason3PracticeDuelText, Turn4Instr3PracticeDuelText + db $00 + +PracticeDuelText_Turn5: + practicetext 2, Turn5DrMason1PracticeDuelText, Turn5Instr1PracticeDuelText + practicetext 6, Turn5DrMason2PracticeDuelText, Turn5Instr2PracticeDuelText + db $00 + +PracticeDuelText_Turn6: + practicetext 2, Turn6DrMason1PracticeDuelText, Turn6Instr1PracticeDuelText + practicetext 5, Turn6DrMason2PracticeDuelText, Turn6Instr2PracticeDuelText + practicetext 8, Turn6DrMason3PracticeDuelText, Turn6Instr3PracticeDuelText + db $00 + +PracticeDuelText_Turn7: + practicetext 2, Turn7DrMason1PracticeDuelText, Turn7Instr1PracticeDuelText + practicetext 5, Turn7DrMason2PracticeDuelText, Turn7Instr2PracticeDuelText + db $00 + +PracticeDuelText_Turn8: + practicetext 2, Turn8DrMason1PracticeDuelText, Turn8Instr1PracticeDuelText + practicetext 5, Turn8DrMason2PracticeDuelText, Turn8Instr2PracticeDuelText + db $00 + +; on player's Seaking knocked out +PracticeDuelText_SamTurn4: + practicetext 2, SamTurn4DrMason1PracticeDuelText, SamTurn4Instr1PracticeDuelText + practicetext 7, SamTurn4DrMason2PracticeDuelText, SamTurn4Instr2PracticeDuelText + db $00 diff --git a/src/data/glossary_menu_transitions.asm b/src/data/glossary_menu_transitions.asm new file mode 100644 index 0000000..17c84e7 --- /dev/null +++ b/src/data/glossary_menu_transitions.asm @@ -0,0 +1,11 @@ +OpenGlossaryScreen_TransitionTable: + cursor_transition $08, $28, $00, $04, $01, $05, $05 + cursor_transition $08, $38, $00, $00, $02, $06, $06 + cursor_transition $08, $48, $00, $01, $03, $07, $07 + cursor_transition $08, $58, $00, $02, $04, $08, $08 + cursor_transition $08, $68, $00, $03, $00, $09, $09 + cursor_transition $58, $28, $00, $09, $06, $00, $00 + cursor_transition $58, $38, $00, $05, $07, $01, $01 + cursor_transition $58, $48, $00, $06, $08, $02, $02 + cursor_transition $58, $58, $00, $07, $09, $03, $03 + cursor_transition $58, $68, $00, $08, $05, $04, $04 diff --git a/src/engine/ai/init.asm b/src/engine/ai/init.asm index 406d7d9..33132cf 100644 --- a/src/engine/ai/init.asm +++ b/src/engine/ai/init.asm @@ -1,11 +1,11 @@ InitAIDuelVars: ; 15636 (5:5636) - ld a, $10 - ld hl, wcda5 + ld a, wAIDuelVarsEnd - wAIDuelVars + ld hl, wAIDuelVars call ClearMemory_Bank5 ld a, 5 ld [wAIPokedexCounter], a ld a, $ff - ld [wcda5], a + ld [wAIPeekedPrizes], a ret ; initializes some variables and sets value of wAIBarrierFlagCounter. diff --git a/src/engine/ai/pkmn_powers.asm b/src/engine/ai/pkmn_powers.asm index 52a8036..8ae629a 100644 --- a/src/engine/ai/pkmn_powers.asm +++ b/src/engine/ai/pkmn_powers.asm @@ -727,7 +727,7 @@ HandleAIPeek: ; 224e6 (8:64e6) .check_ai_prizes ld a, DUELVARS_PRIZES call GetTurnDuelistVariable - ld hl, wcda5 + ld hl, wAIPeekedPrizes and [hl] ld [hl], a or a diff --git a/src/engine/ai/trainer_cards.asm b/src/engine/ai/trainer_cards.asm index 6c1f3a2..4bee001 100644 --- a/src/engine/ai/trainer_cards.asm +++ b/src/engine/ai/trainer_cards.asm @@ -1,4 +1,4 @@ -INCLUDE "data/ai_trainer_card_logic.asm" +INCLUDE "data/duel/ai_trainer_card_logic.asm" _AIProcessHandTrainerCards: ; 200e5 (8:40e5) ld [wAITrainerCardPhase], a diff --git a/src/engine/bank02.asm b/src/engine/bank02.asm deleted file mode 100644 index 0b1f6f7..0000000 --- a/src/engine/bank02.asm +++ /dev/null @@ -1,10076 +0,0 @@ -_OpenDuelCheckMenu: ; 8000 (2:4000) - call ResetCheckMenuCursorPositionAndBlink - xor a - ld [wce5e], a - call DrawWideTextBox - -; reset cursor blink - xor a - ld [wCheckMenuCursorBlinkCounter], a - ld hl, CheckMenuData - call PlaceTextItems -.loop - call DoFrame - call HandleCheckMenuInput - jr nc, .loop - cp $ff - ret z ; B pressed - -; A was pressed - ld a, [wCheckMenuCursorYPosition] - sla a - ld b, a - ld a, [wCheckMenuCursorXPosition] - add b - ld hl, .jump_table - call JumpToFunctionInTable - jr _OpenDuelCheckMenu - -.jump_table - dw DuelCheckMenu_InPlayArea - dw DuelCheckMenu_Glossary - dw DuelCheckMenu_YourPlayArea - dw DuelCheckMenu_OppPlayArea - -; opens the In Play Area submenu -DuelCheckMenu_InPlayArea: ; 8039 (2:4039) - xor a - ld [wInPlayAreaFromSelectButton], a - farcall OpenInPlayAreaScreen - ret - -; opens the Glossary submenu -DuelCheckMenu_Glossary: ; 8042 (2:4042) - farcall OpenGlossaryScreen - ret - -; opens the Your Play Area submenu -DuelCheckMenu_YourPlayArea: ; 8047 (2:4047) - call ResetCheckMenuCursorPositionAndBlink - xor a - ld [wce5e], a - ldh a, [hWhoseTurn] -.draw - ld h, a - ld l, a - call DrawYourOrOppPlayAreaScreen - - ld a, [wCheckMenuCursorYPosition] - sla a - ld b, a - ld a, [wCheckMenuCursorXPosition] - add b - ld [wYourOrOppPlayAreaLastCursorPosition], a - ld b, $f8 ; black arrow tile - call DrawYourOrOppPlayArea_DrawArrows - - call DrawWideTextBox - -; reset cursor blink - xor a - ld [wCheckMenuCursorBlinkCounter], a - ld hl, YourPlayAreaMenuData - call PlaceTextItems - -.loop - call DoFrame - xor a - call DrawYourOrOppPlayArea_RefreshArrows - call HandleCheckMenuInput_YourOrOppPlayArea - jr nc, .loop - - call DrawYourOrOppPlayArea_EraseArrows - cp $ff - ret z - - ld a, [wCheckMenuCursorYPosition] - sla a - ld b, a - ld a, [wCheckMenuCursorXPosition] - add b - ld hl, .jump_table - call JumpToFunctionInTable - jr .draw - -.jump_table - dw OpenYourOrOppPlayAreaScreen_TurnHolderPlayArea - dw OpenYourOrOppPlayAreaScreen_TurnHolderHand - dw OpenYourOrOppPlayAreaScreen_TurnHolderDiscardPile - -OpenYourOrOppPlayAreaScreen_TurnHolderPlayArea: ; 809e (2:409e) - ldh a, [hWhoseTurn] - push af - bank1call OpenTurnHolderPlayAreaScreen - pop af - ldh [hWhoseTurn], a - ret - -OpenYourOrOppPlayAreaScreen_NonTurnHolderPlayArea: ; 80a8 (2:40a8) - ldh a, [hWhoseTurn] - push af - bank1call OpenNonTurnHolderPlayAreaScreen - pop af - ldh [hWhoseTurn], a - ret - -OpenYourOrOppPlayAreaScreen_TurnHolderHand: ; 80b2 (2:40b2) - ldh a, [hWhoseTurn] - push af - bank1call OpenTurnHolderHandScreen_Simple - pop af - ldh [hWhoseTurn], a - ret - -OpenYourOrOppPlayAreaScreen_NonTurnHolderHand: ; 80bc (2:40bc) - ldh a, [hWhoseTurn] - push af - bank1call OpenNonTurnHolderHandScreen_Simple - pop af - ldh [hWhoseTurn], a - ret - -OpenYourOrOppPlayAreaScreen_TurnHolderDiscardPile: ; 80c6 (2:40c6) - ldh a, [hWhoseTurn] - push af - bank1call OpenTurnHolderDiscardPileScreen - pop af - ldh [hWhoseTurn], a - ret - -OpenYourOrOppPlayAreaScreen_NonTurnHolderDiscardPile: ; 80d0 (2:40d0) - ldh a, [hWhoseTurn] - push af - bank1call OpenNonTurnHolderDiscardPileScreen - pop af - ldh [hWhoseTurn], a - ret - -; opens the Opp. Play Area submenu -; if clairvoyance is active, add the option to check -; opponent's hand -DuelCheckMenu_OppPlayArea: ; 80da (2:40da) - call ResetCheckMenuCursorPositionAndBlink - call IsClairvoyanceActive - jr c, .clairvoyance1 - - ld a, %10000000 - ld [wce5e], a - jr .begin -.clairvoyance1 - xor a - ld [wce5e], a - -.begin - ldh a, [hWhoseTurn] -.turns - ld l, a - cp PLAYER_TURN - jr nz, .opponent - ld a, OPPONENT_TURN - ld h, a - jr .cursor -.opponent - ld a, PLAYER_TURN - ld h, a - -.cursor - call DrawYourOrOppPlayAreaScreen - -; convert cursor position and -; store it in wYourOrOppPlayAreaLastCursorPosition - ld a, [wCheckMenuCursorYPosition] - sla a - ld b, a - ld a, [wCheckMenuCursorXPosition] - add b - add 3 - ld [wYourOrOppPlayAreaLastCursorPosition], a - -; draw black arrows in the Play Area - ld b, $f8 ; black arrow tile - call DrawYourOrOppPlayArea_DrawArrows - call DrawWideTextBox - -; reset cursor blink - xor a - ld [wCheckMenuCursorBlinkCounter], a - -; place text items depending on clairvoyance -; when active, allows to look at opp. hand - call IsClairvoyanceActive - jr c, .clairvoyance2 - ld hl, OppPlayAreaMenuData - call PlaceTextItems - jr .loop -.clairvoyance2 - ld hl, OppPlayAreaMenuData_WithClairvoyance - call PlaceTextItems - -; handle input -.loop - call DoFrame - ld a, 1 - call DrawYourOrOppPlayArea_RefreshArrows - call HandleCheckMenuInput_YourOrOppPlayArea - jr nc, .loop - call DrawYourOrOppPlayArea_EraseArrows - cp $ff - ret z ; B was pressed - -; A was pressed -; jump to function corresponding to cursor position - ld a, [wCheckMenuCursorYPosition] - sla a - ld b, a - ld a, [wCheckMenuCursorXPosition] - add b - ld hl, .jump_table - call JumpToFunctionInTable - jr .turns - -.jump_table - dw OpenYourOrOppPlayAreaScreen_NonTurnHolderPlayArea - dw OpenYourOrOppPlayAreaScreen_NonTurnHolderHand - dw OpenYourOrOppPlayAreaScreen_NonTurnHolderDiscardPile - -CheckMenuData: ; 8158 (2:4158) - textitem 2, 14, InPlayAreaText - textitem 2, 16, YourPlayAreaText - textitem 12, 14, GlossaryText - textitem 12, 16, OppPlayAreaText - db $ff - -YourPlayAreaMenuData: ; 8169 (2:4169) - textitem 2, 14, YourPokemonText - textitem 12, 14, YourHandText - textitem 2, 16, YourDiscardPileText2 - db $ff - -OppPlayAreaMenuData: ; 8176 (2:4176) - textitem 2, 14, OpponentsPokemonText - textitem 2, 16, OpponentsDiscardPileText2 - db $ff - -OppPlayAreaMenuData_WithClairvoyance: ; 8176 (2:4176) - textitem 2, 14, OpponentsPokemonText - textitem 12, 14, OpponentsHandText - textitem 2, 16, OpponentsDiscardPileText2 - db $ff - -; checks if arrows need to be erased in Your Play Area or Opp. Play Area -; and draws new arrows upon cursor position change -; input: -; a = an initial offset applied to the cursor position (used to adjust -; for the different layouts of the Your Play Area and Opp. Play Area screens) -DrawYourOrOppPlayArea_RefreshArrows: ; 818c (2:418c) - push af - ld b, a - add b - add b - ld c, a - ld a, [wCheckMenuCursorYPosition] - sla a - ld b, a - ld a, [wCheckMenuCursorXPosition] - add b - add c -; a = 2 * cursor ycoord + cursor xcoord + 3*a - -; if cursor position is different than -; last position, then update arrows - ld hl, wYourOrOppPlayAreaLastCursorPosition - cp [hl] - jr z, .unchanged - -; erase and draw arrows - call DrawYourOrOppPlayArea_EraseArrows - ld [wYourOrOppPlayAreaLastCursorPosition], a - ld b, $f8 ; black arrow tile byte - call DrawYourOrOppPlayArea_DrawArrows - -.unchanged - pop af - ret - -; write SYM_SPACE to positions tabulated in -; YourOrOppPlayAreaArrowPositions, with offset calculated from the -; cursor x and y positions in [wYourOrOppPlayAreaLastCursorPosition] -; input: -; [wYourOrOppPlayAreaLastCursorPosition]: cursor position (2*y + x) -DrawYourOrOppPlayArea_EraseArrows: ; 81af (2:41af) - push af - ld a, [wYourOrOppPlayAreaLastCursorPosition] - ld b, SYM_SPACE ; white tile - call DrawYourOrOppPlayArea_DrawArrows - pop af - ret - -; writes tile in b to positions tabulated in -; YourOrOppPlayAreaArrowPositions, with offset calculated from the -; cursor x and y positions in a -; input: -; a = cursor position (2*y + x) -; b = byte to draw -DrawYourOrOppPlayArea_DrawArrows: ; 81ba (2:41ba) - push bc - ld hl, YourOrOppPlayAreaArrowPositions - sla a - ld c, a - ld b, $00 - add hl, bc -; hl points to YourOrOppPlayAreaArrowPositions -; plus offset corresponding to a - -; load hl with draw position pointer - ld a, [hli] - ld h, [hl] - ld l, a - pop de - -.loop - ld a, [hli] - cp $ff - jr z, .done - ld b, a - ld a, [hli] - ld c, a - ld a, d - call WriteByteToBGMap0 - jr .loop -.done - ret - -YourOrOppPlayAreaArrowPositions: ; 81d7 (2:41d7) - dw YourOrOppPlayAreaArrowPositions_PlayerPokemon - dw YourOrOppPlayAreaArrowPositions_PlayerHand - dw YourOrOppPlayAreaArrowPositions_PlayerDiscardPile - dw YourOrOppPlayAreaArrowPositions_OpponentPokemon - dw YourOrOppPlayAreaArrowPositions_OpponentHand - dw YourOrOppPlayAreaArrowPositions_OpponentDiscardPile - -YourOrOppPlayAreaArrowPositions_PlayerPokemon: ; 81e3 (2:41e3) -; x and y coordinates to draw byte - db 5, 5 - db 0, 10 - db 4, 10 - db 8, 10 - db 12, 10 - db 16, 10 - db $ff - -YourOrOppPlayAreaArrowPositions_PlayerHand: - db 14, 7 - db $ff - -YourOrOppPlayAreaArrowPositions_PlayerDiscardPile: - db 14, 5 - db $ff - -YourOrOppPlayAreaArrowPositions_OpponentPokemon: - db 5, 7 - db 0, 3 - db 4, 3 - db 8, 3 - db 12, 3 - db 16, 3 - db $ff - -YourOrOppPlayAreaArrowPositions_OpponentHand: - db 0, 5 - db $ff - -YourOrOppPlayAreaArrowPositions_OpponentDiscardPile: - db 0, 8 - db $ff - -; loads tiles and icons to display Your Play Area / Opp. Play Area screen, -; and draws the screen according to the turn player -; input: h -> [wCheckMenuPlayAreaWhichDuelist] and l -> [wCheckMenuPlayAreaWhichLayout] -DrawYourOrOppPlayAreaScreen: ; 8209 (2:4209) -; loads the turn holders - ld a, h - ld [wCheckMenuPlayAreaWhichDuelist], a - ld a, l - ld [wCheckMenuPlayAreaWhichLayout], a -; fallthrough - -; loads tiles and icons to display Your Play Area / Opp. Play Area screen, -; and draws the screen according to the turn player -; input: [wCheckMenuPlayAreaWhichDuelist] and [wCheckMenuPlayAreaWhichLayout] -_DrawYourOrOppPlayAreaScreen: ; 8211 (2:4211) - xor a - ld [wTileMapFill], a - call ZeroObjectPositions - - ld a, $01 - ld [wVBlankOAMCopyToggle], a - - call DoFrame - call EmptyScreen - call Set_OBJ_8x8 - call LoadCursorTile - call LoadSymbolsFont - call LoadDeckAndDiscardPileIcons - - ld a, [wCheckMenuPlayAreaWhichDuelist] - cp PLAYER_TURN - jr nz, .opp_turn1 - -; print <RAMNAME>'s Play Area - ld de, wDefaultText - call CopyPlayerName - jr .get_text_length -.opp_turn1 - ld de, wDefaultText - call CopyOpponentName -.get_text_length - ld hl, wDefaultText - - call GetTextLengthInTiles - ld a, 6 ; max name size in tiles - sub b - srl a - add 4 -; a = (6 - name text in tiles) / 2 + 4 - ld d, a ; text horizontal alignment - - ld e, 0 - call InitTextPrinting - ldtx hl, DuelistsPlayAreaText - ldh a, [hWhoseTurn] - cp PLAYER_TURN - jr nz, .opp_turn2 - ld a, [wCheckMenuPlayAreaWhichDuelist] - cp PLAYER_TURN - jr nz, .swap -.opp_turn2 - call PrintTextNoDelay - jr .draw -.swap - call SwapTurn - call PrintTextNoDelay - call SwapTurn - -.draw - ld a, [wCheckMenuPlayAreaWhichDuelist] - ld b, a - ld a, [wCheckMenuPlayAreaWhichLayout] - cp b - jr nz, .not_equal - - ld hl, PrizeCardsCoordinateData_YourOrOppPlayArea.player - call DrawPlayArea_PrizeCards - lb de, 6, 2 ; coordinates of player's active card - call DrawYourOrOppPlayArea_ActiveCardGfx - lb de, 1, 9 ; coordinates of player's bench cards - ld c, 4 ; spacing - call DrawPlayArea_BenchCards - xor a - call DrawYourOrOppPlayArea_Icons - jr .done - -.not_equal - ld hl, PrizeCardsCoordinateData_YourOrOppPlayArea.opponent - call DrawPlayArea_PrizeCards - lb de, 6, 5 ; coordinates of opponent's active card - call DrawYourOrOppPlayArea_ActiveCardGfx - lb de, 1, 2 ; coordinates of opponent's bench cards - ld c, 4 ; spacing - call DrawPlayArea_BenchCards - ld a, $01 - call DrawYourOrOppPlayArea_Icons - -.done - call EnableLCD - ret - -Func_82b6: ; 82b6 (2:42b6) - ld a, [wCheckMenuPlayAreaWhichDuelist] - ld b, a - ld a, [wCheckMenuPlayAreaWhichLayout] - cp b - jr nz, .not_equal - - ld hl, PrizeCardsCoordinateData_YourOrOppPlayArea.player - call DrawPlayArea_PrizeCards - ret - -.not_equal - ld hl, PrizeCardsCoordinateData_YourOrOppPlayArea.opponent - call DrawPlayArea_PrizeCards - ret - -; loads tiles and icons to display the In Play Area screen, -; and draws the screen -DrawInPlayAreaScreen: ; 82ce (2:42ce) - xor a - ld [wTileMapFill], a - call ZeroObjectPositions - - ld a, $01 - ld [wVBlankOAMCopyToggle], a - call DoFrame - call EmptyScreen - - ld a, CHECK_PLAY_AREA - ld [wDuelDisplayedScreen], a - call Set_OBJ_8x8 - call LoadCursorTile - call LoadSymbolsFont - call LoadDeckAndDiscardPileIcons - - lb de, $80, $9f - call SetupText - -; reset turn holders - ldh a, [hWhoseTurn] - ld [wCheckMenuPlayAreaWhichDuelist], a - ld [wCheckMenuPlayAreaWhichLayout], a - -; player prize cards - ld hl, PrizeCardsCoordinateData_InPlayArea.player - call DrawPlayArea_PrizeCards - -; player bench cards - lb de, 3, 15 - ld c, 3 - call DrawPlayArea_BenchCards - - ld hl, PlayAreaIconCoordinates.player2 - call DrawInPlayArea_Icons - - call SwapTurn - ldh a, [hWhoseTurn] - ld [wCheckMenuPlayAreaWhichDuelist], a - call SwapTurn - -; opponent prize cards - ld hl, PrizeCardsCoordinateData_InPlayArea.opponent - call DrawPlayArea_PrizeCards - -; opponent bench cards - lb de, 3, 0 - ld c, 3 - call DrawPlayArea_BenchCards - - call SwapTurn - ld hl, PlayAreaIconCoordinates.opponent2 - call DrawInPlayArea_Icons - - call SwapTurn - call DrawInPlayArea_ActiveCardGfx - ret - -; draws players prize cards and bench cards -_DrawPlayersPrizeAndBenchCards: ; 833c (2:433c) - xor a - ld [wTileMapFill], a - call ZeroObjectPositions - ld a, $01 - ld [wVBlankOAMCopyToggle], a - call DoFrame - call EmptyScreen - call LoadSymbolsFont - call LoadDeckAndDiscardPileIcons - -; player cards - ld a, PLAYER_TURN - ld [wCheckMenuPlayAreaWhichDuelist], a - ld [wCheckMenuPlayAreaWhichLayout], a - ld hl, PrizeCardsCoordinateData_2.player - call DrawPlayArea_PrizeCards - lb de, 5, 10 ; coordinates - ld c, 3 ; spacing - call DrawPlayArea_BenchCards - -; opponent cards - ld a, OPPONENT_TURN - ld [wCheckMenuPlayAreaWhichDuelist], a - ld hl, PrizeCardsCoordinateData_2.opponent - call DrawPlayArea_PrizeCards - lb de, 1, 0 ; coordinates - ld c, 3 ; spacing - call DrawPlayArea_BenchCards - ret - -; draws the active card gfx at coordinates de -; of the player (or opponent) depending on wCheckMenuPlayAreaWhichDuelist -; input: -; de = coordinates -DrawYourOrOppPlayArea_ActiveCardGfx: ; 837e (2:437e) - push de - ld a, DUELVARS_ARENA_CARD - ld l, a - ld a, [wCheckMenuPlayAreaWhichDuelist] - ld h, a - ld a, [hl] - cp -1 - jr z, .no_pokemon - - ld d, a - ld a, [wCheckMenuPlayAreaWhichDuelist] - ld b, a - ldh a, [hWhoseTurn] - cp b - jr nz, .swap - ld a, d - call LoadCardDataToBuffer1_FromDeckIndex - jr .draw -.swap - call SwapTurn - ld a, d - call LoadCardDataToBuffer1_FromDeckIndex - call SwapTurn - -.draw - ld de, v0Tiles1 + $20 tiles ; destination offset of loaded gfx - ld hl, wLoadedCard1Gfx - ld a, [hli] - ld h, [hl] - ld l, a - lb bc, $30, TILE_SIZE - call LoadCardGfx - bank1call SetBGP6OrSGB3ToCardPalette - bank1call FlushAllPalettesOrSendPal23Packet - pop de - -; draw card gfx - ld a, $a0 - lb hl, 6, 1 - lb bc, 8, 6 - call FillRectangle - bank1call ApplyBGP6OrSGB3ToCardImage - ret - -.no_pokemon - pop de - ret - -; draws player and opponent arena card graphics -; in the "In Play Area" screen -DrawInPlayArea_ActiveCardGfx: ; 83cc (2:43cc) - xor a - ld [wArenaCardsInPlayArea], a - - ld a, DUELVARS_ARENA_CARD - call GetTurnDuelistVariable - cp -1 ; no pokemon - jr z, .opponent1 - - push af - ld a, [wArenaCardsInPlayArea] - or %00000001 ; set the player arena Pokemon bit - ld [wArenaCardsInPlayArea], a - pop af - -; load card gfx - call LoadCardDataToBuffer1_FromDeckIndex - lb de, $8a, $00 - ld hl, wLoadedCard1Gfx - ld a, [hli] - ld h, [hl] - ld l, a - lb bc, $30, TILE_SIZE - call LoadCardGfx - bank1call SetBGP6OrSGB3ToCardPalette - -.opponent1 - ld a, DUELVARS_ARENA_CARD - call GetNonTurnDuelistVariable - cp -1 ; no pokemon - jr z, .draw - - push af - ld a, [wArenaCardsInPlayArea] - or %00000010 ; set the opponent arena Pokemon bit - ld [wArenaCardsInPlayArea], a - pop af - -; load card gfx - call SwapTurn - call LoadCardDataToBuffer1_FromDeckIndex - lb de, $95, $00 - ld hl, wLoadedCard1Gfx - ld a, [hli] - ld h, [hl] - ld l, a - lb bc, $30, TILE_SIZE - call LoadCardGfx - bank1call SetBGP7OrSGB2ToCardPalette - call SwapTurn - -.draw - ld a, [wArenaCardsInPlayArea] - or a - ret z ; no arena cards in play - - bank1call FlushAllPalettesOrSendPal23Packet - ld a, [wArenaCardsInPlayArea] - and %00000001 ; test player arena card bit - jr z, .opponent2 - -; draw player arena card - ld a, $a0 - lb de, 6, 9 - lb hl, 6, 1 - lb bc, 8, 6 - call FillRectangle - bank1call ApplyBGP6OrSGB3ToCardImage - -.opponent2 - ld a, [wArenaCardsInPlayArea] - and %00000010 ; test opponent arena card bit - ret z - -; draw opponent arena card - call SwapTurn - ld a, $50 - lb de, 6, 2 - lb hl, 6, 1 - lb bc, 8, 6 - call FillRectangle - bank1call ApplyBGP7OrSGB2ToCardImage - call SwapTurn - ret - -; draws prize cards depending on the turn -; loaded in wCheckMenuPlayAreaWhichDuelist -; input: -; hl = pointer to coordinates -DrawPlayArea_PrizeCards: ; 8464 (2:4464) - push hl - call GetDuelInitialPrizesUpperBitsSet - ld a, [wCheckMenuPlayAreaWhichDuelist] - ld h, a - ld l, DUELVARS_PRIZES - ld a, [hl] - - pop hl - ld b, 0 - push af -; loop each prize card -.loop - inc b - ld a, [wDuelInitialPrizes] - inc a - cp b - jr z, .done - - pop af - srl a ; right shift prize cards left - push af - jr c, .not_taken - ld a, $e0 ; tile byte for empty slot - jr .draw -.not_taken - ld a, $dc ; tile byte for card -.draw - ld e, [hl] - inc hl - ld d, [hl] - inc hl - - push hl - push bc - lb hl, $01, $02 ; card tile gfx - lb bc, 2, 2 ; rectangle size - call FillRectangle - - ld a, [wConsole] - cp CONSOLE_CGB - jr nz, .not_cgb - ld a, $02 ; blue colour - lb bc, 2, 2 - lb hl, 0, 0 - call BankswitchVRAM1 - call FillRectangle - call BankswitchVRAM0 -.not_cgb - pop bc - pop hl - jr .loop -.done - pop af - ret - -PrizeCardsCoordinateData_YourOrOppPlayArea: ; 84b4 (2:44b4) -; x and y coordinates for player prize cards -.player - db 2, 1 - db 2, 3 - db 4, 1 - db 4, 3 - db 6, 1 - db 6, 3 -; x and y coordinates for opponent prize cards -.opponent - db 9, 17 - db 9, 15 - db 7, 17 - db 7, 15 - db 5, 17 - db 5, 15 - -; used by Func_833c -PrizeCardsCoordinateData_2: ; 84cc (2:44cc) -; x and y coordinates for player prize cards -.player - db 6, 0 - db 6, 2 - db 8, 0 - db 8, 2 - db 10, 0 - db 10, 2 -; x and y coordinates for opponent prize cards -.opponent - db 4, 18 - db 4, 16 - db 2, 18 - db 2, 16 - db 0, 18 - db 0, 16 - -PrizeCardsCoordinateData_InPlayArea: ; 84e4 (2:44e4) -; x and y coordinates for player prize cards -.player - db 9, 1 - db 9, 3 - db 11, 1 - db 11, 3 - db 13, 1 - db 13, 3 -; x and y coordinates for opponent prize cards -.opponent - db 6, 17 - db 6, 15 - db 4, 17 - db 4, 15 - db 2, 17 - db 2, 15 - -; calculates bits set up to the number of initial prizes, with upper 2 bits set, i.e: -; 6 prizes: a = %11111111 -; 4 prizes: a = %11001111 -; 3 prizes: a = %11000111 -; 2 prizes: a = %11000011 -GetDuelInitialPrizesUpperBitsSet: ; 84fc (2:44fc) - ld a, [wDuelInitialPrizes] - ld b, $01 -.loop - or a - jr z, .done - sla b - dec a - jr .loop -.done - dec b - ld a, b - or %11000000 - ld [wDuelInitialPrizesUpperBitsSet], a - ret - -; draws filled and empty bench slots depending on the turn loaded in wCheckMenuPlayAreaWhichDuelist -; if wCheckMenuPlayAreaWhichDuelist is different from wCheckMenuPlayAreaWhichLayout adjusts coordinates of the bench slots -; input: -; de = coordinates to draw bench -; c = spacing between slots -DrawPlayArea_BenchCards: ; 8511 (2:4511) - ld a, [wCheckMenuPlayAreaWhichLayout] - ld b, a - ld a, [wCheckMenuPlayAreaWhichDuelist] - cp b - jr z, .skip - -; adjust the starting bench position for opponent - ld a, d - add c - add c - add c - add c - ld d, a - ; d = d + 4 * c - -; have the spacing go to the left instead of right - xor a - sub c - ld c, a - ; c = $ff - c + 1 - - ld a, [wCheckMenuPlayAreaWhichDuelist] -.skip - ld h, a - ld l, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA - ld b, [hl] - ld l, DUELVARS_BENCH1_CARD_STAGE -.loop_1 - dec b ; num of Bench Pokemon left - jr z, .done - - ld a, [hli] - push hl - push bc - sla a - sla a - add $e4 -; a holds the correct stage gfx tile - ld b, a - push bc - - lb hl, 1, 2 - lb bc, 2, 2 - call FillRectangle - - ld a, [wConsole] - cp CONSOLE_CGB - pop bc - jr nz, .next - - ld a, b - cp $ec ; tile offset of 2 stage - jr z, .two_stage - cp $f0 ; tile offset of 2 stage with no 1 stage - jr z, .two_stage - - ld a, $02 ; blue colour - jr .palette -.two_stage - ld a, $01 ; red colour -.palette - lb bc, 2, 2 - lb hl, 0, 0 - call BankswitchVRAM1 - call FillRectangle - call BankswitchVRAM0 - -.next ; adjust coordinates for next card - pop bc - pop hl - ld a, d - add c - ld d, a - ; d = d + c - jr .loop_1 - -.done - ld a, [wCheckMenuPlayAreaWhichDuelist] - ld h, a - ld l, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA - ld b, [hl] - ld a, MAX_PLAY_AREA_POKEMON - sub b - ret z ; return if already full - - ld b, a - inc b -.loop_2 - dec b - ret z - - push bc - ld a, $f4 ; empty bench slot tile - lb hl, 1, 2 - lb bc, 2, 2 - call FillRectangle - - ld a, [wConsole] - cp CONSOLE_CGB - jr nz, .not_cgb - - ld a, $02 ; colour - lb bc, 2, 2 - lb hl, 0, 0 - call BankswitchVRAM1 - call FillRectangle - call BankswitchVRAM0 - -.not_cgb - pop bc - ld a, d - add c - ld d, a - jr .loop_2 - -; draws Your/Opp Play Area icons depending on value in a -; the icons correspond to Deck, Discard Pile, and Hand -; the corresponding number of cards is printed alongside each icon -; for "Hand", text is displayed rather than an icon -; input: -; a = $00: draws player icons -; a = $01: draws opponent icons -DrawYourOrOppPlayArea_Icons: ; 85aa (2:45aa) - or a - jr nz, .opponent - ld hl, PlayAreaIconCoordinates.player1 - jr .draw -.opponent - ld hl, PlayAreaIconCoordinates.opponent1 - -.draw -; hand icon and value - ld a, [wCheckMenuPlayAreaWhichDuelist] - ld d, a - ld e, DUELVARS_NUMBER_OF_CARDS_IN_HAND - ld a, [de] - ld b, a - ld a, $d0 ; hand icon, unused? - call DrawPlayArea_HandText - -; deck icon and value - ld a, [wCheckMenuPlayAreaWhichDuelist] - ld d, a - ld e, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK - ld a, [de] - ld b, a - ld a, DECK_SIZE - sub b - ld b, a - ld a, $d4 ; deck icon - call DrawPlayArea_IconWithValue - -; discard pile icon and value - ld a, [wCheckMenuPlayAreaWhichDuelist] - ld d, a - ld e, DUELVARS_NUMBER_OF_CARDS_IN_DISCARD_PILE - ld a, [de] - ld b, a - ld a, $d8 ; discard pile icon - call DrawPlayArea_IconWithValue - ret - -; draws the interface icon corresponding to the gfx tile in a -; also prints the number in decimal corresponding to the value in b -; the coordinates in screen are given by [hl] -; input: -; a = tile for the icon -; b = value to print alongside icon -; hl = pointer to coordinates -DrawPlayArea_IconWithValue: ; 85e1 (2:45e1) -; drawing the icon - ld d, [hl] - inc hl - ld e, [hl] - inc hl - push hl - push bc - lb hl, 1, 2 - lb bc, 2, 2 - call FillRectangle - - ld a, [wConsole] - cp CONSOLE_CGB - jr nz, .skip - - ld a, $02 - lb bc, 2, 2 - lb hl, 0, 0 - call BankswitchVRAM1 - call FillRectangle - call BankswitchVRAM0 - -.skip -; adjust coordinate to the lower right - inc d - inc d - inc e - call InitTextPrinting - pop bc - ld a, b - call CalculateOnesAndTensDigits - - ld hl, wOnesAndTensPlace - ld a, [hli] - ld b, a - ld a, [hl] - -; loading numerical and cross symbols - ld hl, wDefaultText - ld [hl], TX_SYMBOL - inc hl - ld [hl], SYM_CROSS - inc hl - ld [hl], TX_SYMBOL - inc hl - ld [hli], a ; tens place - ld [hl], TX_SYMBOL - inc hl - ld a, b - ld [hli], a ; ones place - ld [hl], TX_END - -; printing the decimal value - ld hl, wDefaultText - call ProcessText - pop hl - ret - -PlayAreaIconCoordinates: ; 8635 (2:4635) -; used for "Your/Opp. Play Area" screen -.player1 - db 15, 7 ; hand - db 15, 2 ; deck - db 15, 4 ; discard pile -.opponent1 - db 1, 5 ; hand - db 1, 9 ; deck - db 1, 7 ; discard pile - -; used for "In Play Area" screen -.player2 - db 15, 14 - db 15, 9 - db 15, 11 -.opponent2 - db 0, 2 - db 0, 6 - db 0, 4 - -; draws In Play Area icons depending on value in a -; the icons correspond to Deck, Discard Pile, and Hand -; the corresponding number of cards is printed alongside each icon -; for "Hand", text is displayed rather than an icon -; input: -; a = $00: draws player icons -; a = $01: draws opponent icons -DrawInPlayArea_Icons: ; 864d (2:464d) - ldh a, [hWhoseTurn] - ld d, a - ld e, DUELVARS_NUMBER_OF_CARDS_IN_HAND - ld a, [de] - ld b, a - ld a, $d0 ; hand icon, unused? - call DrawPlayArea_HandText - -; deck - ldh a, [hWhoseTurn] - ld d, a - ld e, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK - ld a, [de] - ld b, a - ld a, DECK_SIZE - sub b - ld b, a - ld a, $d4 ; deck tile - call DrawPlayArea_IconWithValue - -; discard pile - ldh a, [hWhoseTurn] - ld d, a - ld e, $ed - ld a, [de] - ld b, a - ld a, $d8 ; discard pile tile - call DrawPlayArea_IconWithValue - ret - -; prints text HandText_2 and a cross with decimal value of b -; input -; b = value to print alongside text -DrawPlayArea_HandText: ; 8676 (2:4676) - ld d, [hl] - inc hl - ld e, [hl] - inc hl - -; text - push hl - push bc - call InitTextPrinting - ldtx hl, HandText_2 - call ProcessTextFromID - pop bc - -; decimal value - ld a, b - call CalculateOnesAndTensDigits - ld hl, wOnesAndTensPlace - ld a, [hli] - ld b, a - ld a, [hl] - - ld hl, wDefaultText - ld [hl], TX_SYMBOL - inc hl - ld [hl], SYM_CROSS - inc hl - ld [hl], TX_SYMBOL - inc hl - ld [hli], a - ld [hl], TX_SYMBOL - inc hl - -; draw to screen - ld a, b - ld [hli], a - ld [hl], TX_END - ld hl, wDefaultText - call ProcessText - pop hl - ret - -; handle player input in menu in Your or Opp. Play Area -; works out which cursor coordinate to go to -; and sets carry flag if A or B are pressed -; returns a = $1 if A pressed -; returns a = $ff if B pressed -HandleCheckMenuInput_YourOrOppPlayArea: ; 86ac (2:46ac) - xor a - ld [wPlaysSfx], a - ld a, [wCheckMenuCursorXPosition] - ld d, a - ld a, [wCheckMenuCursorYPosition] - ld e, a - -; d = cursor x position -; e = cursor y position - - ldh a, [hDPadHeld] - or a - jr z, .skip - -; pad is pressed - ld a, [wce5e] - and %10000000 - ldh a, [hDPadHeld] - jr nz, .check_vertical - bit D_LEFT_F, a ; test left button - jr nz, .horizontal - bit D_RIGHT_F, a ; test right button - jr z, .check_vertical - -; handle horizontal input -.horizontal - ld a, [wce5e] - and %01111111 - or a - jr nz, .asm_86dd ; jump if wce5e's lower 7 bits aren't set - ld a, e - or a - jr z, .flip_x ; jump if y is 0 - -; wce5e = %10000000 -; e = 1 - dec e ; change y position - jr .flip_x - -.asm_86dd - ld a, e - or a - jr nz, .flip_x ; jump if y is not 0 - inc e ; change y position -.flip_x - ld a, d - xor $01 ; flip x position - ld d, a - jr .erase - -.check_vertical - bit D_UP_F, a - jr nz, .vertical - bit D_DOWN_F, a - jr z, .skip - -; handle vertical input -.vertical - ld a, d - or a - jr z, .flip_y ; jump if x is 0 - dec d -.flip_y - ld a, e - xor $01 ; flip y position - ld e, a - -.erase - ld a, TRUE - ld [wPlaysSfx], a - push de - call EraseCheckMenuCursor_YourOrOppPlayArea - pop de - -; update x and y cursor positions - ld a, d - ld [wCheckMenuCursorXPosition], a - ld a, e - ld [wCheckMenuCursorYPosition], a - -; reset cursor blink - xor a - ld [wCheckMenuCursorBlinkCounter], a - -.skip - ldh a, [hKeysPressed] - and A_BUTTON | B_BUTTON - jr z, .sfx - and A_BUTTON - jr nz, .a_pressed - -; B pressed - ld a, $ff ; cancel - call PlaySFXConfirmOrCancel - scf - ret - -.a_pressed - call DisplayCheckMenuCursor_YourOrOppPlayArea - ld a, $01 - call PlaySFXConfirmOrCancel - scf - ret - -.sfx - ld a, [wPlaysSfx] - or a - jr z, .draw_cursor - call PlaySFX - -.draw_cursor - ld hl, wCheckMenuCursorBlinkCounter - ld a, [hl] - inc [hl] - and %00001111 - ret nz ; only update cursor if blink's lower nibble is 0 - - ld a, SYM_CURSOR_R ; cursor byte - bit 4, [hl] ; only draw cursor if blink counter's fourth bit is not set - jr z, DrawCheckMenuCursor_YourOrOppPlayArea -; fallthrough - -; transforms cursor position into coordinates -; in order to draw byte on menu cursor -EraseCheckMenuCursor_YourOrOppPlayArea: ; 8741 (2:4741) - ld a, SYM_SPACE ; white tile -; fallthrough - -; draws in the cursor position -; input: -; a = tile byte to draw -DrawCheckMenuCursor_YourOrOppPlayArea: ; 8743 (2:4743) - ld e, a - ld a, 10 - ld l, a - ld a, [wCheckMenuCursorXPosition] - ld h, a - call HtimesL -; h = 10 * cursor x pos - - ld a, l - add 1 - ld b, a - ld a, [wCheckMenuCursorYPosition] - sla a - add 14 - ld c, a -; c = 11 + 2 * cursor y pos + 14 - -; draw tile loaded in e - ld a, e - call WriteByteToBGMap0 - or a - ret - -DisplayCheckMenuCursor_YourOrOppPlayArea: ; 8760 (2:4760) - ld a, SYM_CURSOR_R ; load cursor byte - jr DrawCheckMenuCursor_YourOrOppPlayArea - -; handles Peek Pkmn Power selection menus -_HandlePeekSelection: ; 8764 (2:4764) - call Set_OBJ_8x8 - call LoadCursorTile -; reset wce5c and wIsSwapTurnPending - xor a - ld [wce5c], a - ld [wIsSwapTurnPending], a - -; draw play area screen for the turn player - ldh a, [hWhoseTurn] - ld h, a - ld l, a - call DrawYourOrOppPlayAreaScreen - -.check_swap - ld a, [wIsSwapTurnPending] - or a - jr z, .draw_menu_1 -; if wIsSwapTurnPending is TRUE, swap turn - call SwapTurn - xor a - ld [wIsSwapTurnPending], a - -; prompt player to choose either own Play Area or opponent's -.draw_menu_1 - xor a - ld hl, .PlayAreaMenuParameters - call InitializeMenuParameters - call DrawWideTextBox - ld hl, .YourOrOppPlayAreaData - call PlaceTextItems - -.loop_input_1 - call DoFrame - call HandleMenuInput - jr nc, .loop_input_1 - cp -1 - jr z, .loop_input_1 ; can't use B btn - - call EraseCursor - ldh a, [hCurMenuItem] - or a - jp nz, .PrepareYourPlayAreaSelection ; jump if not Opp Play Area - -; own Play Area was chosen - ld a, [wCheckMenuPlayAreaWhichDuelist] - ld b, a - ldh a, [hWhoseTurn] - cp b - jr z, .text_1 - -; switch the play area to draw - ld h, a - ld l, a - call DrawYourOrOppPlayAreaScreen - xor a - ld [wIsSwapTurnPending], a - -.text_1 - call DrawWideTextBox - lb de, 1, 14 - call InitTextPrinting - ldtx hl, WhichCardWouldYouLikeToSeeText - call ProcessTextFromID - - xor a - ld [wYourOrOppPlayAreaCurPosition], a - ld de, PeekYourPlayAreaTransitionTable - ld hl, wTransitionTablePtr - ld [hl], e - inc hl - ld [hl], d - -.loop_input_2 - ld a, $01 - ld [wVBlankOAMCopyToggle], a - call DoFrame - call YourOrOppPlayAreaScreen_HandleInput - jr c, .selection_cancelled - jr .loop_input_2 -.selection_cancelled - cp -1 - jr nz, .selection_made - call ZeroObjectPositionsWithCopyToggleOn - jr .check_swap -.selection_made - ld hl, .SelectionFunctionTable - call JumpToFunctionInTable - jr .loop_input_2 - -.SelectionFunctionTable -rept 6 - dw .SelectedPrize -endr - dw .SelectedOppsHand - dw .SelectedDeck - -.YourOrOppPlayAreaData ; 8808 (2:4808) - textitem 2, 14, YourPlayAreaText - textitem 2, 16, OppPlayAreaText - db $ff - -.PlayAreaMenuParameters ; 8811 (2:4811) - db 1, 14 ; cursor x, cursor y - db 2 ; y displacement between items - db 2 ; number of items - db SYM_CURSOR_R ; cursor tile number - db SYM_SPACE ; tile behind cursor - dw NULL ; function pointer if non-0 - -.SelectedPrize ; 8819 (2:4819) - ld a, [wYourOrOppPlayAreaCurPosition] - ld c, a - ld b, $1 - -; left-shift b a number of times -; corresponding to this prize card -.loop_prize_bitmask - or a - jr z, .got_prize_bitmask - sla b - dec a - jr .loop_prize_bitmask - -.got_prize_bitmask - ld a, DUELVARS_PRIZES - call GetTurnDuelistVariable - and b - ret z ; return if prize card taken - - ld a, c - add $40 - ld [wce5c], a - ld a, c - add DUELVARS_PRIZE_CARDS - call GetTurnDuelistVariable - jr .ShowSelectedCard - -.SelectedOppsHand ; 883c (2:483c) - call CreateHandCardList - ret c - ld hl, wDuelTempList - call ShuffleCards - ld a, [hl] - jr .ShowSelectedCard - -.SelectedDeck ; 8849 (2:4849) - call CreateDeckCardList - ret c - ld a, %01111111 - ld [wce5c], a - ld a, [wDuelTempList] -; fallthrough - -; input: -; a = deck index of card to be loaded -; output: -; a = wce5c -; with upper bit set if turn was swapped -.ShowSelectedCard ; 8855 (2:4855) - ld b, a - ld a, [wce5c] - or a - jr nz, .display - ; if wce5c is not set, set it as input deck index - ld a, b - ld [wce5c], a -.display - ld a, b - call LoadCardDataToBuffer1_FromDeckIndex - call Set_OBJ_8x16 - bank1call OpenCardPage_FromHand - ld a, $01 - ld [wVBlankOAMCopyToggle], a - pop af - -; if wIsSwapTurnPending is TRUE, swap turn - ld a, [wIsSwapTurnPending] - or a - jr z, .dont_swap - call SwapTurn - ld a, [wce5c] - or %10000000 - ret -.dont_swap - ld a, [wce5c] - ret - -; prepare menu parameters to handle selection -; of player's own Play Area -.PrepareYourPlayAreaSelection: ; 8883 (2:4883) - ld a, [wCheckMenuPlayAreaWhichDuelist] - ld b, a - ldh a, [hWhoseTurn] - cp b - jr nz, .text_2 - - ld l, a - cp PLAYER_TURN - jr nz, .opponent - ld a, OPPONENT_TURN - jr .draw_menu_2 -.opponent - ld a, PLAYER_TURN - -.draw_menu_2 - ld h, a - call DrawYourOrOppPlayAreaScreen - -.text_2 - call DrawWideTextBox - lb de, 1, 14 - call InitTextPrinting - ldtx hl, WhichCardWouldYouLikeToSeeText - call ProcessTextFromID - - xor a - ld [wYourOrOppPlayAreaCurPosition], a - ld de, PeekOppPlayAreaTransitionTable - ld hl, wTransitionTablePtr - ld [hl], e - inc hl - ld [hl], d - - call SwapTurn - ld a, TRUE - ld [wIsSwapTurnPending], a ; mark pending to swap turn - jp .loop_input_2 - -PeekYourPlayAreaTransitionTable: ; 88c2 (2:48c2) - cursor_transition $08, $28, $00, $04, $02, $01, $07 - cursor_transition $30, $28, $20, $05, $03, $07, $00 - cursor_transition $08, $38, $00, $00, $04, $03, $07 - cursor_transition $30, $38, $20, $01, $05, $07, $02 - cursor_transition $08, $48, $00, $02, $00, $05, $07 - cursor_transition $30, $48, $20, $03, $01, $07, $04 - cursor_transition $78, $50, $00, $07, $07, $00, $01 - cursor_transition $78, $28, $00, $07, $07, $00, $01 - -PeekOppPlayAreaTransitionTable: ; 88fa (2:48fa) - cursor_transition $a0, $60, $20, $02, $04, $07, $01 - cursor_transition $78, $60, $00, $03, $05, $00, $07 - cursor_transition $a0, $50, $20, $04, $00, $06, $03 - cursor_transition $78, $50, $00, $05, $01, $02, $06 - cursor_transition $a0, $40, $20, $00, $02, $06, $05 - cursor_transition $78, $40, $00, $01, $03, $04, $06 - cursor_transition $08, $38, $00, $07, $07, $05, $04 - cursor_transition $08, $60, $00, $06, $06, $01, $00 - -_DrawAIPeekScreen: ; 8932 (2:4932) - push bc - call Set_OBJ_8x8 - call LoadCursorTile - xor a - ld [wIsSwapTurnPending], a - ldh a, [hWhoseTurn] - ld l, a - ld de, PeekYourPlayAreaTransitionTable - pop bc - bit AI_PEEK_TARGET_HAND_F, b - jr z, .draw_play_area - -; AI chose the hand - call SwapTurn - ld a, TRUE - ld [wIsSwapTurnPending], a ; mark pending to swap turn - ldh a, [hWhoseTurn] - ld de, PeekOppPlayAreaTransitionTable -.draw_play_area - ld h, a - push bc - push de - call DrawYourOrOppPlayAreaScreen - pop de - pop bc - -; get the right cursor position -; depending on what action the AI chose -; (prize card, hand, deck) - ld hl, wMenuInputTablePointer - ld [hl], e - inc hl - ld [hl], d - ld a, b - and $7f - cp $7f - jr nz, .prize_card -; cursor on the deck - ld a, $7 - ld [wYourOrOppPlayAreaCurPosition], a - jr .got_cursor_position -.prize_card - bit AI_PEEK_TARGET_PRIZE_F, a - jr z, .hand - and $3f - ld [wYourOrOppPlayAreaCurPosition], a - jr .got_cursor_position -.hand - ld a, $6 - ld [wYourOrOppPlayAreaCurPosition], a -.got_cursor_position - call YourOrOppPlayAreaScreen_HandleInput.draw_cursor - - ld a, $1 - ld [wVBlankOAMCopyToggle], a - ld a, [wIsSwapTurnPending] - or a - ret z - call SwapTurn - ret - -LoadCursorTile: ; 8992 (2:4992) - ld de, v0Tiles0 - ld hl, .tile_data - ld b, 16 - call SafeCopyDataHLtoDE - ret - -.tile_data: ; 899e (2:499e) - db $e0, $c0, $98, $b0, $84, $8c, $83, $82 - db $86, $8f, $9d, $be, $f4, $f8, $50, $60 - -; handles input inside the "Your Play Area" or "Opp Play Area" screens -; returns carry if either A or B button were pressed -; returns -1 in a if B button was pressed -YourOrOppPlayAreaScreen_HandleInput: ; 89ae (2:49ae) - xor a - ld [wPlaysSfx], a - -; get the transition data for the prize card with cursor - ld hl, wTransitionTablePtr - ld e, [hl] - inc hl - ld d, [hl] - ld a, [wYourOrOppPlayAreaCurPosition] - ld [wPrizeCardCursorTemporaryPosition], a - ld l, a - ld h, 7 ; length of each transition table item - call HtimesL - add hl, de - -; get the transition index related to the directional input - ldh a, [hDPadHeld] - or a - jp z, .check_button - inc hl - inc hl - inc hl - - bit D_UP_F, a - jr z, .else_if_down - - ; up - ld a, [hl] - jr .process_dpad - -.else_if_down - inc hl - bit D_DOWN_F, a - jr z, .else_if_right - - ; down - ld a, [hl] - jr .process_dpad - -.else_if_right - inc hl - bit D_RIGHT_F, a - jr z, .else_if_left - - ; right - ld a, [hl] - jr .process_dpad - -.else_if_left - inc hl - bit D_LEFT_F, a - jr z, .check_button - - ; left - ld a, [hl] -.process_dpad - ld [wYourOrOppPlayAreaCurPosition], a - cp $8 ; if a >= 0x8 - jr nc, .next - ld b, $1 - -; this loop equals to -; b = (1 << a) -.make_bitmask_loop - or a - jr z, .make_bitmask_done - sla b - dec a - jr .make_bitmask_loop - -.make_bitmask_done -; check if the moved cursor refers to an existing item. -; it's always true when this function was called from the glossary procedure. - ld a, [wDuelInitialPrizesUpperBitsSet] - and b - jr nz, .next - -; when no cards exist at the cursor, - ld a, [wPrizeCardCursorTemporaryPosition] - cp $06 - jr nz, YourOrOppPlayAreaScreen_HandleInput - ; move once more in the direction (recursively) until it reaches an existing item. - -; check if one of the dpad, left or right, is pressed. -; if not, just go back to the start. - ldh a, [hDPadHeld] - bit D_RIGHT_F, a - jr nz, .left_or_right - bit D_LEFT_F, a - jr z, YourOrOppPlayAreaScreen_HandleInput - -.left_or_right - ; if started with 5 or 6 prize cards - ; can switch sides normally, - ld a, [wDuelInitialPrizes] - cp PRIZES_5 - jr nc, .next - ; else if it's last card, - ld a, [wYourOrOppPlayAreaCurPosition] - cp 5 - jr nz, .not_last_card - ; place it at pos 3 - ld a, 3 - ld [wYourOrOppPlayAreaCurPosition], a - jr .ok -.not_last_card - ; otherwise place at pos 2 - ld a, 2 - ld [wYourOrOppPlayAreaCurPosition], a - -.ok - ld a, [wDuelInitialPrizes] - cp PRIZES_3 - jr nc, .handled_cursor_pos - ; in this case can just sub 2 from pos - ld a, [wYourOrOppPlayAreaCurPosition] - sub 2 - ld [wYourOrOppPlayAreaCurPosition], a - -.handled_cursor_pos - ld a, [wYourOrOppPlayAreaCurPosition] - ld [wPrizeCardCursorTemporaryPosition], a - ld b, $1 - jr .make_bitmask_loop - -.next - ld a, TRUE - ld [wPlaysSfx], a - -; reset cursor blink - xor a - ld [wCheckMenuCursorBlinkCounter], a -.check_button - ldh a, [hKeysPressed] - and A_BUTTON | B_BUTTON - jr z, .return - - and A_BUTTON - jr nz, .a_button - - ld a, -1 ; cancel - call PlaySFXConfirmOrCancel - scf - ret - -.a_button - call .draw_cursor - ld a, $01 - call PlaySFXConfirmOrCancel - ld a, [wYourOrOppPlayAreaCurPosition] - scf - ret - -.return - ld a, [wPlaysSfx] - or a - jr z, .skip_sfx - call PlaySFX -.skip_sfx - ld hl, wCheckMenuCursorBlinkCounter - ld a, [hl] - inc [hl] - and (1 << 4) - 1 - ret nz - bit 4, [hl] - jr nz, ZeroObjectPositionsWithCopyToggleOn - -.draw_cursor - call ZeroObjectPositions - ld hl, wTransitionTablePtr - ld e, [hl] - inc hl - ld d, [hl] - ld a, [wYourOrOppPlayAreaCurPosition] - ld l, a - ld h, 7 - call HtimesL - add hl, de -; hl = [wTransitionTablePtr] + 7 * wce52 - - ld d, [hl] - inc hl - ld e, [hl] - inc hl - ld b, [hl] - ld c, $00 - call SetOneObjectAttributes - or a - ret - -ZeroObjectPositionsWithCopyToggleOn: ; 8aa1 (2:4aa1) - call ZeroObjectPositions - - ld a, $01 - ld [wVBlankOAMCopyToggle], a - ret - -; handles the screen for Player to select prize card(s) -_SelectPrizeCards: ; 8aaa (2:4aaa) - xor a - call GetFirstSetPrizeCard - ld [wYourOrOppPlayAreaCurPosition], a - ld de, hTempPlayAreaLocation_ffa1 - ld hl, wSelectedPrizeCardListPtr - ld [hl], e - inc hl - ld [hl], d - -.check_prize_cards_to_select - ld a, [wNumberOfPrizeCardsToSelect] - or a - jr z, .done_selection - ld a, DUELVARS_PRIZES - call GetTurnDuelistVariable - or a - jr nz, .got_prizes - -.done_selection - ld a, DUELVARS_PRIZES - call GetTurnDuelistVariable - ldh [hTemp_ffa0], a - ld a, [wSelectedPrizeCardListPtr + 0] - ld l, a - ld a, [wSelectedPrizeCardListPtr + 1] - ld h, a - ld [hl], $ff - ret - -.got_prizes - ldh a, [hWhoseTurn] - ld h, a - ld l, a - call DrawYourOrOppPlayAreaScreen - call DrawWideTextBox - lb de, 1, 14 - call InitTextPrinting - ldtx hl, PleaseChooseAPrizeText - call ProcessTextFromID - ld de, .cursor_transition_table - ld hl, wMenuInputTablePointer - ld [hl], e - inc hl - ld [hl], d -.loop_handle_input - ld a, $1 - ld [wVBlankOAMCopyToggle], a - call DoFrame - call YourOrOppPlayAreaScreen_HandleInput - jr nc, .loop_handle_input - cp $ff - jr z, .loop_handle_input - - call ZeroObjectPositionsWithCopyToggleOn - -; get prize bit mask that corresponds -; to the one pointed by the cursor - ld a, [wYourOrOppPlayAreaCurPosition] - ld c, a - ld b, $1 -.loop - or a - jr z, .got_prize_mask - sla b - dec a - jr .loop - -.got_prize_mask - ; if cursor prize is not set, - ; then return to input loop - ld a, DUELVARS_PRIZES - call GetTurnDuelistVariable - and b - jp z, .loop_handle_input ; can be jr - - ; remove prize - ld a, DUELVARS_PRIZES - call GetTurnDuelistVariable - sub b - ld [hl], a - - ; get its deck index - ld a, c - add DUELVARS_PRIZE_CARDS - call GetTurnDuelistVariable - - ld hl, wSelectedPrizeCardListPtr - ld e, [hl] - inc hl - ld d, [hl] - ld [de], a ; store deck index - inc de - ld [hl], d - dec hl - ld [hl], e - - ; add prize card to hand - call AddCardToHand - call LoadCardDataToBuffer1_FromDeckIndex - call Set_OBJ_8x16 - bank1call OpenCardPage_FromHand - ld a, [wNumberOfPrizeCardsToSelect] - dec a - ld [wNumberOfPrizeCardsToSelect], a - ld a, [wYourOrOppPlayAreaCurPosition] - call GetFirstSetPrizeCard - ld [wYourOrOppPlayAreaCurPosition], a - jp .check_prize_cards_to_select - -.cursor_transition_table - cursor_transition $08, $28, $00, $04, $02, $01, $01 - cursor_transition $30, $28, $20, $05, $03, $00, $00 - cursor_transition $08, $38, $00, $00, $04, $03, $03 - cursor_transition $30, $38, $20, $01, $05, $02, $02 - cursor_transition $08, $48, $00, $02, $00, $05, $05 - cursor_transition $30, $48, $20, $03, $01, $04, $04 - -_DrawPlayAreaToPlacePrizeCards: ; 8b85 (2:4b85) - xor a - ld [wTileMapFill], a - call ZeroObjectPositions - call EmptyScreen - call LoadSymbolsFont - call LoadPlacingThePrizesScreenTiles - - ldh a, [hWhoseTurn] - ld [wCheckMenuPlayAreaWhichLayout], a - ld [wCheckMenuPlayAreaWhichDuelist], a - - lb de, 0, 10 - ld c, 3 - call DrawPlayArea_BenchCards - ld hl, .player_icon_coordinates - call DrawYourOrOppPlayArea_Icons.draw - lb de, 8, 6 - ld a, $a0 - lb hl, 1, 4 - lb bc, 4, 3 - call FillRectangle - - call SwapTurn - ld a, TRUE - ld [wIsSwapTurnPending], a ; mark pending to swap turn - ldh a, [hWhoseTurn] - ld [wCheckMenuPlayAreaWhichDuelist], a - lb de, 6, 0 - ld c, 3 - call DrawPlayArea_BenchCards - ld hl, .opp_icon_coordinates - call DrawYourOrOppPlayArea_Icons.draw - lb de, 8, 3 - ld a, $a0 - lb hl, 1, 4 - lb bc, 4, 3 - call FillRectangle - call SwapTurn - ret - -.player_icon_coordinates - db 15, 11 - db 15, 6 - db 15, 8 - -.opp_icon_coordinates - db 0, 0 - db 0, 4 - db 0, 2 - -; seems like a function to draw prize cards -; given a list of coordinates in hl -; unreferenced? -; hl = pointer to coords -Func_8bf2: ; 8bf2 (2:4bf2) - push hl - ld a, [wCheckMenuPlayAreaWhichDuelist] - ld h, a - ld l, DUELVARS_PRIZES - ld a, [hl] - pop hl - - ld b, 0 - push af -.loop_prize_cards - inc b - ld a, [wDuelInitialPrizes] - inc a - cp b - jr z, .done - pop af - srl a - push af - jr c, .not_taken - ; same tile whether the prize card is taken or not - ld a, $ac - jr .got_tile -.not_taken - ld a, $ac -.got_tile - ld e, [hl] - inc hl - ld d, [hl] - inc hl - push hl - push bc - lb hl, 0, 0 - lb bc, 1, 1 - call FillRectangle - ld a, [wConsole] - cp CONSOLE_CGB - jr nz, .skip_pal - ld a, $02 - lb bc, 1, 1 - lb hl, 0, 0 - call BankswitchVRAM1 - call FillRectangle - call BankswitchVRAM0 -.skip_pal - pop bc - pop hl - jr .loop_prize_cards -.done - pop af - ret - -; unknown data -; unreferenced? -Data_8c3f: ; 8c3f (6:4c3f) - db $06, $05, $06, $06, $07, $05, $07, $06 - db $08, $05, $08, $06, $05, $0e, $05, $0d - db $04, $0e, $04, $0d, $03, $0e, $03, $0d - -; gets the first prize card index that is set -; beginning from index in register a -; a = prize card index -GetFirstSetPrizeCard: ; 8c57 (2:4c57) - push bc - push de - push hl - ld e, PRIZES_6 - ld c, a - ldh a, [hWhoseTurn] - ld h, a - ld l, DUELVARS_PRIZES - ld d, [hl] -.loop_prizes - call .GetPrizeMask - and d - jr nz, .done ; prize is set - dec e - jr nz, .next_prize - ld c, 0 - jr .done -.next_prize - inc c - ld a, PRIZES_6 - cp c - jr nz, .loop_prizes - ld c, 0 - jr .loop_prizes - -.done - ld a, c ; first prize index that is set - pop hl - pop de - pop bc - ret - -; returns 1 shifted left by c bits -.GetPrizeMask - push bc - ld a, c - ld b, $1 -.loop - or a - jr z, .got_mask - sla b - dec a - jr .loop -.got_mask - ld a, b - pop bc - ret - -OpenGlossaryScreen_TransitionTable: ; 8c8e (2:4c8e) - cursor_transition $08, $28, $00, $04, $01, $05, $05 - cursor_transition $08, $38, $00, $00, $02, $06, $06 - cursor_transition $08, $48, $00, $01, $03, $07, $07 - cursor_transition $08, $58, $00, $02, $04, $08, $08 - cursor_transition $08, $68, $00, $03, $00, $09, $09 - cursor_transition $58, $28, $00, $09, $06, $00, $00 - cursor_transition $58, $38, $00, $05, $07, $01, $01 - cursor_transition $58, $48, $00, $06, $08, $02, $02 - cursor_transition $58, $58, $00, $07, $09, $03, $03 - cursor_transition $58, $68, $00, $08, $05, $04, $04 - -; copies DECK_SIZE number of cards from de to hl in SRAM -CopyDeckFromSRAM: ; 8cd4 (2:4cd4) - push bc - call EnableSRAM - ld b, DECK_SIZE -.loop - ld a, [de] - inc de - ld [hli], a - dec b - jr nz, .loop - xor a - ld [hl], a - call DisableSRAM - pop bc - ret - -; clears some WRAM addresses to act as -; terminator bytes to wFilteredCardList and wCurDeckCards -WriteCardListsTerminatorBytes: ; 8ce7 (2:4ce7) - xor a - ld hl, wFilteredCardList - ld bc, DECK_SIZE - add hl, bc - ld [hl], a ; wcf16 - ld hl, wCurDeckCards - ld bc, DECK_CONFIG_BUFFER_SIZE - add hl, bc - ld [hl], a ; wCurDeckCardsTerminator - ret - -; inits some SRAM addresses -Func_8cf9: ; 8cf9 (2:4cf9) - call EnableSRAM - xor a - ld hl, sHasPromotionalCards - ld [hli], a - inc a ; $1 - ld [hli], a ; sb704 - ld [hli], a - ld [hl], a - ld [sUnnamedDeckCounter], a - call DisableSRAM -; ret missing -; unintentional fallthrough - -; loads the Hard Cards icon gfx to v0Tiles2 -LoadHandCardsIcon: ; 8d0b (2:4d0b) - ld hl, HandCardsGfx - ld de, v0Tiles2 + $38 tiles - call CopyListFromHLToDE - ret - -HandCardsGfx: ; 8d15 (2:4d15) - INCBIN "gfx/hand_cards.2bpp" - db $00 ; end of data - -EmptyScreenAndLoadFontDuelAndHandCardsIcons: ; 8d56 (2:4d56) - xor a - ld [wTileMapFill], a - call EmptyScreen - call ZeroObjectPositions - ld a, $1 - ld [wVBlankOAMCopyToggle], a - call LoadSymbolsFont - call LoadDuelCardSymbolTiles - call LoadHandCardsIcon - bank1call SetDefaultPalettes - lb de, $3c, $bf - call SetupText - ret - -; empties screen, zeroes object positions, -; loads cursor tile, symbol fonts, duel card symbols -; hand card icon and sets default palettes -Func_8d78: ; 8d78 (2:4d78) - xor a - ld [wTileMapFill], a - call ZeroObjectPositions - call EmptyScreen - ld a, $1 - ld [wVBlankOAMCopyToggle], a - call LoadCursorTile - call LoadSymbolsFont - call LoadDuelCardSymbolTiles - call LoadHandCardsIcon - bank1call SetDefaultPalettes - lb de, $3c, $bf - call SetupText - ret - -; inits the following deck building params from hl: -; wMaxNumCardsAllowed -; wSameNameCardsLimit -; wIncludeCardsInDeck -; wDeckConfigurationMenuHandlerFunction -; wDeckConfigurationMenuTransitionTable -InitDeckBuildingParams: ; 8d9d (2:4d9d) - ld de, wMaxNumCardsAllowed - ld b, $7 -.loop - ld a, [hli] - ld [de], a - inc de - dec b - jr nz, .loop - ret - -DeckBuildingParams: ; 8da9 (2:4da9) - db DECK_CONFIG_BUFFER_SIZE ; max number of cards - db MAX_NUM_SAME_NAME_CARDS ; max number of same name cards - db TRUE ; whether to include deck cards - dw HandleDeckConfigurationMenu - dw DeckConfigurationMenu_TransitionTable - -DeckSelectionMenu: ; 8db0 (2:4db0) - ld hl, DeckBuildingParams - call InitDeckBuildingParams - ld a, ALL_DECKS - call DrawDecksScreen - xor a - -.init_menu_params - ld hl, .DeckSelectionMenuParameters - call InitializeMenuParameters - ldtx hl, PleaseSelectDeckText - call DrawWideTextBox_PrintText -.loop_input - call DoFrame - jr c, .init_menu_params ; reinit menu parameters - call HandleStartButtonInDeckSelectionMenu - jr c, .init_menu_params - call HandleMenuInput - jr nc, .loop_input - ldh a, [hCurMenuItem] - cp $ff - ret z ; B btn returns -; A btn pressed on a deck - ld [wCurDeck], a - jp DeckSelectionSubMenu - -.DeckSelectionMenuParameters - db 1, 2 ; cursor x, cursor y - db 3 ; y displacement between items - db 4 ; number of items - db SYM_CURSOR_R ; cursor tile number - db SYM_SPACE ; tile behind cursor - dw NULL ; function pointer if non-0 - -; handles START button press when in deck selection menu -; does nothing if START button isn't pressed -; if a press was handled, returns carry -; prints "There is no deck here!" if the selected deck is empty -HandleStartButtonInDeckSelectionMenu: ; 8dea (2:4dea) - ldh a, [hDPadHeld] - and START - ret z ; skip - -; set menu item as current deck - ld a, [wCurMenuItem] - ld [wCurDeck], a - call CheckIfCurDeckIsValid - jp nc, .valid_deck ; can be jr - -; not a valid deck, cancel - ld a, $ff ; cancel - call PlaySFXConfirmOrCancel - call PrintThereIsNoDeckHereText - scf - ret - -.valid_deck - ld a, $1 - call PlaySFXConfirmOrCancel - call GetPointerToDeckCards - push hl - call GetPointerToDeckName - pop de - call OpenDeckConfirmationMenu - ld a, ALL_DECKS - call DrawDecksScreen - ld a, [wCurDeck] - scf - ret - -OpenDeckConfirmationMenu: ; 8e1f (2:4e1f) -; copy deck name - push de - ld de, wCurDeckName - call CopyListFromHLToDEInSRAM - pop de - -; copy deck cards - ld hl, wCurDeckCards - call CopyDeckFromSRAM - - ld a, NUM_FILTERS - ld hl, wCardFilterCounts - call ClearNBytesFromHL - ld a, DECK_SIZE - ld [wTotalCardCount], a - ld hl, wCardFilterCounts - ld [hl], a - call HandleDeckConfirmationMenu - ret - -; handles the submenu when selecting a deck -; (Modify Deck, Select Deck, Change Name and Cancel) -DeckSelectionSubMenu: ; 8e42 (2:4e42) - call DrawWideTextBox - ld hl, DeckSelectionData - call PlaceTextItems - call ResetCheckMenuCursorPositionAndBlink -.loop_input - call DoFrame - call HandleCheckMenuInput - jp nc, .loop_input - cp $ff - jr nz, .option_selected -; B btn pressed -; erase cursor and go back -; to deck selection handling - call EraseCheckMenuCursor - ld a, [wCurDeck] - jp DeckSelectionMenu.init_menu_params - -.option_selected - ld a, [wCheckMenuCursorXPosition] - or a - jp nz, DeckSelectionSubMenu_SelectOrCancel - ld a, [wCheckMenuCursorYPosition] - or a - jp nz, .ChangeName - -; Modify Deck -; read deck from SRAM -; TODO - call GetPointerToDeckCards - ld e, l - ld d, h - ld hl, wCurDeckCards - call CopyDeckFromSRAM - ld a, 20 - ld hl, wCurDeckName - call ClearNBytesFromHL - ld de, wCurDeckName - call GetPointerToDeckName - call CopyListFromHLToDEInSRAM - - call HandleDeckBuildScreen - jr nc, .asm_8ec4 - call EnableSRAM - ld hl, wCurDeckCards - call DecrementDeckCardsInCollection - call GetPointerToDeckCards - call AddDeckToCollection - ld e, l - ld d, h - ld hl, wCurDeckCards - ld b, DECK_SIZE -.asm_8ea9 - ld a, [hli] - ld [de], a - inc de - dec b - jr nz, .asm_8ea9 - call GetPointerToDeckName - ld d, h - ld e, l - ld hl, wCurDeckName - call CopyListFromHLToDE - call GetPointerToDeckName - ld a, [hl] - call DisableSRAM - or a - jr z, .get_input_deck_name -.asm_8ec4 - ld a, ALL_DECKS - call DrawDecksScreen - ld a, [wCurDeck] - jp DeckSelectionMenu.init_menu_params - -.ChangeName - call CheckIfCurDeckIsValid - jp nc, .get_input_deck_name - call PrintThereIsNoDeckHereText - jp DeckSelectionMenu.init_menu_params -.get_input_deck_name - ld a, 20 - ld hl, wCurDeckName - call ClearNBytesFromHL - ld de, wCurDeckName - call GetPointerToDeckName - call CopyListFromHLToDEInSRAM - call InputCurDeckName - call GetPointerToDeckName - ld d, h - ld e, l - ld hl, wCurDeckName - call CopyListFromHLToDEInSRAM - ld a, ALL_DECKS - call DrawDecksScreen - ld a, [wCurDeck] - jp DeckSelectionMenu.init_menu_params - -; gets current deck's name from user input -InputCurDeckName: ; 8f05 (2:4f05) - ld a, [wCurDeck] - or a - jr nz, .deck_2 - ld hl, Deck1Data - jr .got_deck_ptr -.deck_2 - dec a - jr nz, .deck_3 - ld hl, Deck2Data - jr .got_deck_ptr -.deck_3 - dec a - jr nz, .deck_4 - ld hl, Deck3Data - jr .got_deck_ptr -.deck_4 - ld hl, Deck4Data -.got_deck_ptr - ld a, MAX_DECK_NAME_LENGTH - lb bc, 4, 1 - ld de, wCurDeckName - farcall InputDeckName - ld a, [wCurDeckName] - or a - ret nz - ; empty name - call .UnnamedDeck - ret - -; handles the naming of unnamed decks -; inputs as the deck name "DECK XXX" -; where XXX is the current unnamed deck counter -.UnnamedDeck -; read the current unnamed deck number -; and convert it to text - ld hl, sUnnamedDeckCounter - call EnableSRAM - ld a, [hli] - ld h, [hl] - call DisableSRAM - ld l, a - ld de, wDefaultText - call TwoByteNumberToText - - ld hl, wCurDeckName - ld [hl], $6 - inc hl - ld [hl], "D" - inc hl - ld [hl], "e" - inc hl - ld [hl], "c" - inc hl - ld [hl], "k" - inc hl - ld [hl], " " - inc hl - ld de, wDefaultText + 2 - ld a, [de] - inc de - ld [hli], a - ld a, [de] - inc de - ld [hli], a - ld a, [de] - ld [hli], a - xor a - ld [hl], a - -; increment the unnamed deck counter - ld hl, sUnnamedDeckCounter - call EnableSRAM - ld e, [hl] - inc hl - ld d, [hl] -; capped at 999 - ld a, HIGH(MAX_UNNAMED_DECK_NUM) - cp d - jr nz, .incr_counter - ld a, LOW(MAX_UNNAMED_DECK_NUM) - cp e - jr nz, .incr_counter - ; reset counter - ld de, 0 -.incr_counter - inc de - ld [hl], d - dec hl - ld [hl], e - call DisableSRAM - ret - -; handle deck selection sub-menu -; the option is either "Select Deck" or "Cancel" -; depending on the cursor Y pos -DeckSelectionSubMenu_SelectOrCancel: ; 8f8a (2:4f8a) - ld a, [wCheckMenuCursorYPosition] - or a - jp nz, CancelDeckSelectionSubMenu - -; select deck - call CheckIfCurDeckIsValid - jp nc, .SelectDeck - ; invalid deck - call PrintThereIsNoDeckHereText - jp DeckSelectionMenu.init_menu_params - -.SelectDeck - call EnableSRAM - ld a, [sCurrentlySelectedDeck] - call DisableSRAM - -; draw empty rectangle on currently selected deck -; i.e. erase the Hand Cards Gfx icon - ld h, $3 - ld l, a - call HtimesL - ld e, l - inc e - ld d, 2 - xor a - lb hl, 0, 0 - lb bc, 2, 2 - call FillRectangle - -; set current deck as the selected deck -; and draw the Hand Cards Gfx icon - ld a, [wCurDeck] - call EnableSRAM - ld [sCurrentlySelectedDeck], a - call DisableSRAM - call DrawHandCardsTileOnCurDeck - -; print "<DECK> was chosen as the dueling deck!" - call GetPointerToDeckName - call EnableSRAM - call CopyDeckName - call DisableSRAM - xor a - ld [wTxRam2], a - ld [wTxRam2 + 1], a - ldtx hl, ChosenAsDuelingDeckText - call DrawWideTextBox_WaitForInput - ld a, [wCurDeck] - jp DeckSelectionMenu.init_menu_params - -PrintThereIsNoDeckHereText: ; 8fe8 (2:4fe8) - ldtx hl, ThereIsNoDeckHereText - call DrawWideTextBox_WaitForInput - ld a, [wCurDeck] - ret - -; returns carry if deck in wCurDeck -; is not a valid deck -CheckIfCurDeckIsValid: ; 8ff2 (2:4ff2) - ld a, [wCurDeck] - ld hl, wDecksValid - ld b, $0 - ld c, a - add hl, bc - ld a, [hl] - or a - ret nz ; is valid - scf - ret ; is not valid - -; write to $d00a the decimal representation (number characters) -; of the value in hl -; unreferenced? -Func_9001: ; 9001 (2:5001) - ld de, $d00a - ld bc, -100 - call .GetNumberChar - ld bc, -10 - call .GetNumberChar - ld bc, -1 - call .GetNumberChar - ret - -.GetNumberChar - ld a, SYM_0 - 1 -.loop - inc a - add hl, bc - jr c, .loop - ld [de], a - inc de - ld a, l - sub c - ld l, a - ld a, h - sbc b - ld h, a - ret - -CancelDeckSelectionSubMenu: ; 9026 (2:5026) - ret - -DeckSelectionData: ; 9027 (2:5027) - textitem 2, 14, ModifyDeckText - textitem 12, 14, SelectDeckText - textitem 2, 16, ChangeNameText - textitem 12, 16, CancelText - db $ff - -; return, in hl, the pointer to sDeckXName where X is [wCurDeck] + 1 -GetPointerToDeckName: ; 9038 (2:5038) - ld a, [wCurDeck] - ld h, a - ld l, DECK_STRUCT_SIZE - call HtimesL - push de - ld de, sDeck1Name - add hl, de - pop de - ret - -; return, in hl, the pointer to sDeckXCards where X is [wCurDeck] + 1 -GetPointerToDeckCards: ; 9048 (2:5048) - push af - ld a, [wCurDeck] - ld h, a - ld l, sDeck2Cards - sDeck1Cards - call HtimesL - push de - ld de, sDeck1Cards - add hl, de - pop de - pop af - ret - -ResetCheckMenuCursorPositionAndBlink: ; 905a (2:505a) - xor a - ld [wCheckMenuCursorXPosition], a - ld [wCheckMenuCursorYPosition], a - ld [wCheckMenuCursorBlinkCounter], a - ret - -; handle player input in check menu -; works out which cursor coordinate to go to -; and sets carry flag if A or B are pressed -; returns a = $1 if A pressed -; returns a = $ff if B pressed -HandleCheckMenuInput: ; 9065 (2:5065) - xor a - ld [wPlaysSfx], a - ld a, [wCheckMenuCursorXPosition] - ld d, a - ld a, [wCheckMenuCursorYPosition] - ld e, a - -; d = cursor x position -; e = cursor y position - - ldh a, [hDPadHeld] - or a - jr z, .no_pad - bit D_LEFT_F, a - jr nz, .horizontal - bit D_RIGHT_F, a - jr z, .check_vertical - -; handle horizontal input -.horizontal - ld a, d - xor $1 ; flips x coordinate - ld d, a - jr .okay -.check_vertical - bit D_UP_F, a - jr nz, .vertical - bit D_DOWN_F, a - jr z, .no_pad - -; handle vertical input -.vertical - ld a, e - xor $01 ; flips y coordinate - ld e, a - -.okay - ld a, TRUE - ld [wPlaysSfx], a - push de - call EraseCheckMenuCursor - pop de - -; update x and y cursor positions - ld a, d - ld [wCheckMenuCursorXPosition], a - ld a, e - ld [wCheckMenuCursorYPosition], a - -; reset cursor blink - xor a - ld [wCheckMenuCursorBlinkCounter], a -.no_pad - ldh a, [hKeysPressed] - and A_BUTTON | B_BUTTON - jr z, .no_input - and A_BUTTON - jr nz, .a_press - ld a, $ff ; cancel - call PlaySFXConfirmOrCancel - scf - ret - -.a_press - call DisplayCheckMenuCursor - ld a, $01 - call PlaySFXConfirmOrCancel - scf - ret - -.no_input - ld a, [wPlaysSfx] - or a - jr z, .check_blink - call PlaySFX - -.check_blink - ld hl, wCheckMenuCursorBlinkCounter - ld a, [hl] - inc [hl] - and %00001111 - ret nz ; only update cursor if blink's lower nibble is 0 - - ld a, SYM_CURSOR_R ; cursor byte - bit 4, [hl] ; only draw cursor if blink counter's fourth bit is not set - jr z, DrawCheckMenuCursor - -; draws in the cursor position -EraseCheckMenuCursor: ; 90d8 (2:50d8) - ld a, SYM_SPACE ; empty cursor -; fallthrough - -; draws in the cursor position -; input: -; a = tile byte to draw -DrawCheckMenuCursor: ; 90da (2:50da) - ld e, a - ld a, 10 - ld l, a - ld a, [wCheckMenuCursorXPosition] - ld h, a - call HtimesL - - ld a, l - add 1 - ld b, a - ld a, [wCheckMenuCursorYPosition] - sla a - add 14 - ld c, a - - ld a, e - call WriteByteToBGMap0 - or a - ret - -DisplayCheckMenuCursor: ; 90f7 (2:50f7) - ld a, SYM_CURSOR_R - jr DrawCheckMenuCursor - -; plays sound depending on value in a -; input: -; a = $ff: play cancel sound -; a != $ff: play confirm sound -PlaySFXConfirmOrCancel: ; 90fb (2:50fb) - push af - inc a - jr z, .asm_9103 - ld a, SFX_02 ; confirmation sfx - jr .asm_9105 -.asm_9103 - ld a, SFX_03 ; cancellation sfx -.asm_9105 - call PlaySFX - pop af - ret - -; goes through whole deck in hl -; for each card ID, goes to its corresponding -; entry in sCardCollection and decrements its count -DecrementDeckCardsInCollection: ; 910a (2:510a) - push hl - ld b, $0 - ld d, DECK_SIZE -.loop_deck - ld a, [hli] - or a - jr z, .done - ld c, a - push hl - ld hl, sCardCollection - add hl, bc - dec [hl] - pop hl - dec d - jr nz, .loop_deck -.done - pop hl - ret - -; like AddDeckToCollection, but takes care to -; check if increasing the collection count would -; go over MAX_AMOUNT_OF_CARD and caps it -; this is because it's used within Gift Center, -; so we cannot assume that the deck configuration -; won't make it go over MAX_AMOUNT_OF_CARD -; hl = deck configuration, with cards to add -AddGiftCenterDeckCardsToCollection: ; 9120 (2:5120) - push hl - ld b, $0 - ld d, DECK_SIZE -.loop_deck - ld a, [hli] - or a - jr z, .done - ld c, a - push hl - push de - push bc - ld a, ALL_DECKS - call CreateCardCollectionListWithDeckCards - pop bc - pop de - ld hl, wTempCardCollection - add hl, bc - ld a, [hl] - cp MAX_AMOUNT_OF_CARD - jr z, .next_card ; capped - call EnableSRAM ; no DisableSRAM - ld hl, sCardCollection - add hl, bc - ld a, [hl] - cp CARD_NOT_OWNED - jr nz, .incr - ; not owned - xor a - ld [hl], a -.incr - inc [hl] -.next_card - pop hl - dec d - jr nz, .loop_deck -.done - pop hl - ret - -; adds all cards in deck in hl to player's collection -; assumes SRAM is enabled -; hl = pointer to deck cards -AddDeckToCollection: ; 9152 (2:5152) - push hl - ld b, $0 - ld d, DECK_SIZE -.loop_deck - ld a, [hli] - or a - jr z, .done - ld c, a - push hl - ld hl, sCardCollection - add hl, bc - inc [hl] - pop hl - dec d - jr nz, .loop_deck -.done - pop hl - ret - -; draws the screen which shows the player's current -; deck configurations -; a = DECK_* flags to pick which deck names to show -DrawDecksScreen: ; 9168 (2:5168) - ld [hffb5], a - call EmptyScreenAndLoadFontDuelAndHandCardsIcons - lb de, 0, 0 - lb bc, 20, 4 - call DrawRegularTextBox - lb de, 0, 3 - lb bc, 20, 4 - call DrawRegularTextBox - lb de, 0, 6 - lb bc, 20, 4 - call DrawRegularTextBox - lb de, 0, 9 - lb bc, 20, 4 - call DrawRegularTextBox - ld hl, DeckNameMenuData - call PlaceTextItems - -; mark all decks as invalid - ld a, NUM_DECKS - ld hl, wDecksValid - call ClearNBytesFromHL - -; for each deck, check if it has cards and if so -; mark is as valid in wDecksValid - -; deck 1 - ld a, [hffb5] ; should be ldh - bit 0, a - jr z, .skip_name_1 - ld hl, sDeck1Name - lb de, 6, 2 - call PrintDeckName -.skip_name_1 - ld hl, sDeck1Cards - call CheckIfDeckHasCards - jr c, .deck_2 - ld a, TRUE - ld [wDeck1Valid], a - -.deck_2 - ld a, [hffb5] ; should be ldh - bit 1, a - jr z, .skip_name_2 - ld hl, sDeck2Name - lb de, 6, 5 - call PrintDeckName -.skip_name_2 - ld hl, sDeck2Cards - call CheckIfDeckHasCards - jr c, .deck_3 - ld a, TRUE - ld [wDeck2Valid], a - -.deck_3 - ld a, [hffb5] ; should be ldh - bit 2, a - jr z, .skip_name_3 - ld hl, sDeck3Name - lb de, 6, 8 - call PrintDeckName -.skip_name_3 - ld hl, sDeck3Cards - call CheckIfDeckHasCards - jr c, .deck_4 - ld a, TRUE - ld [wDeck3Valid], a - -.deck_4 - ld a, [hffb5] ; should be ldh - bit 3, a - jr z, .skip_name_4 - ld hl, sDeck4Name - lb de, 6, 11 - call PrintDeckName -.skip_name_4 - ld hl, sDeck4Cards - call CheckIfDeckHasCards - jr c, .place_cursor - ld a, TRUE - ld [wDeck4Valid], a - -.place_cursor -; places cursor on sCurrentlySelectedDeck -; if it's an empty deck, then advance the cursor -; until it's selecting a valid deck - call EnableSRAM - ld a, [sCurrentlySelectedDeck] - ld c, a - ld b, $0 - ld d, 2 -.check_valid_deck - ld hl, wDecksValid - add hl, bc - ld a, [hl] - or a - jr nz, .valid_selected_deck - inc c - ld a, NUM_DECKS - cp c - jr nz, .check_valid_deck - ld c, 0 ; roll back to deck 1 - dec d - jr z, .valid_selected_deck - jr .check_valid_deck - -.valid_selected_deck - ld a, c - ld [sCurrentlySelectedDeck], a - call DisableSRAM - call DrawHandCardsTileOnCurDeck - call EnableLCD - ret - -DeckNameMenuData: ; 9242 (2:5242) - textitem 4, 2, Deck1Text - textitem 4, 5, Deck2Text - textitem 4, 8, Deck3Text - textitem 4, 11, Deck4Text - db $ff - -; copies text from hl to wDefaultText -; with " deck" appended to the end -; hl = ptr to deck name -CopyDeckName: ; 9253 (2:5253) - ld de, wDefaultText - call CopyListFromHLToDE - ld hl, wDefaultText - call GetTextLengthInTiles - ld b, $0 - ld hl, wDefaultText - add hl, bc - ld d, h - ld e, l - ld hl, DeckNameSuffix - call CopyListFromHLToDE - ret - -; prints deck name given in hl in position de -; if it's an empty deck, print "NEW DECK" instead -; returns carry if it's an empty deck -; hl = deck name (sDeck1Name ~ sDeck4Name) -; de = coordinates to print text -PrintDeckName: ; 926e (2:526e) - push hl - call CheckIfDeckHasCards - pop hl - jr c, .new_deck - -; print "<deck name> deck" - push de - ld de, wDefaultText - call CopyListFromHLToDEInSRAM - ld hl, wDefaultText - call GetTextLengthInTiles - ld b, $0 - ld hl, wDefaultText - add hl, bc - ld d, h - ld e, l - ld hl, DeckNameSuffix - call CopyListFromHLToDE - pop de - ld hl, wDefaultText - call InitTextPrinting - call ProcessText - or a - ret - -.new_deck -; print "NEW DECK" - call InitTextPrinting - ldtx hl, NewDeckText - call ProcessTextFromID - scf - ret - -DeckNameSuffix: ; 92a7 (2:52a7) - db " deck" - done - -; copies a $00-terminated list from hl to de -CopyListFromHLToDE: ; 92ad (2:52ad) - ld a, [hli] - ld [de], a - or a - ret z - inc de - jr CopyListFromHLToDE - -; same as CopyListFromHLToDE, but for SRAM copying -CopyListFromHLToDEInSRAM: ; 92b4 (2:52b4) - call EnableSRAM - call CopyListFromHLToDE - call DisableSRAM - ret - -; appends text in hl to wDefaultText -; then adds "deck" to the end -; returns carry if deck has no cards -; hl = text to append -; de = input to InitTextPrinting -AppendDeckName: ; 92be (2:52be) - push hl - call CheckIfDeckHasCards - pop hl - ret c ; no cards - - push de - ; append the text from hl - ld de, wDefaultText - call CopyListFromHLToDEInSRAM - - ; get string length (up to DECK_NAME_SIZE_WO_SUFFIX) - ld hl, wDefaultText - call GetTextLengthInTiles - ld a, c - cp DECK_NAME_SIZE_WO_SUFFIX - jr c, .got_len - ld c, DECK_NAME_SIZE_WO_SUFFIX -.got_len - ld b, $0 - ld hl, wDefaultText - add hl, bc - ld d, h - ld e, l - ; append "deck" starting from the given length - ld hl, .text_start - ld b, .text_end - .text_start - call CopyNBytesFromHLToDE - xor a ; TX_END - ld [wDefaultText + DECK_NAME_SIZE + 2], a - pop de - ld hl, wDefaultText - call InitTextPrinting - call ProcessText - or a - ret - -.text_start - db " deck " -.text_end - -; returns carry if the deck in hl -; is not valid, that is, has no cards -; alternatively, the direct address of the cards -; can be used, since DECK_SIZE > DECK_NAME_SIZE -; hl = deck name (sDeck1Name ~ sDeck4Name) -; or deck cards (sDeck1Cards ~ sDeck4Cards) -CheckIfDeckHasCards: ; 9314 (2:5314) - ld bc, DECK_NAME_SIZE - add hl, bc - call EnableSRAM - ld a, [hl] - call DisableSRAM - ; being max size means last char - ; is not TX_END, i.e. $0 - or a - jr nz, .max_size - scf - ret -.max_size - or a - ret - -; calculates the y coordinate of the currently selected deck -; and draws the hands card tile at that position -DrawHandCardsTileOnCurDeck: ; 9326 (2:5326) - call EnableSRAM - ld a, [sCurrentlySelectedDeck] - call DisableSRAM - ld h, 3 - ld l, a - call HtimesL - ld e, l - inc e ; (sCurrentlySelectedDeck * 3) + 1 - ld d, 2 -; fallthrough - -; de = coordinates to draw rectangle -DrawHandCardsTileAtDE: ; 9339 (2:5339) - ld a, $38 ; hand cards tile - lb hl, 1, 2 - lb bc, 2, 2 - call FillRectangle - ret - -; handles user input when selecting a card filter -; when building a deck configuration -; the handling of selecting cards themselves from the list -; to add/remove to the deck is done in HandleDeckCardSelectionList -HandleDeckBuildScreen: ; 9345 (2:5345) - call WriteCardListsTerminatorBytes - call CountNumberOfCardsForEachCardType -.skip_count - call DrawCardTypeIconsAndPrintCardCounts - - xor a - ld [wCardListVisibleOffset], a - ld [wCurCardTypeFilter], a ; FILTER_GRASS - call PrintFilteredCardList - -.skip_draw - ld hl, FiltersCardSelectionParams - call InitCardSelectionParams -.wait_input - call DoFrame - ldh a, [hDPadHeld] - and START - jr z, .no_start_btn_1 - ld a, $01 - call PlaySFXConfirmOrCancel - call ConfirmDeckConfiguration - ld a, [wCurCardTypeFilter] - ld [wTempCardTypeFilter], a - jr .wait_input - -.no_start_btn_1 - ld a, [wCurCardTypeFilter] - ld b, a - ld a, [wTempCardTypeFilter] - cp b - jr z, .check_down_btn - ; need to refresh the filtered card list - ld [wCurCardTypeFilter], a - ld hl, wCardListVisibleOffset - ld [hl], 0 - call PrintFilteredCardList - ld a, NUM_FILTERS - ld [wCardListNumCursorPositions], a - -.check_down_btn - ldh a, [hDPadHeld] - and D_DOWN - jr z, .no_down_btn - call ConfirmSelectionAndReturnCarry - jr .jump_to_list - -.no_down_btn - call HandleCardSelectionInput - jr nc, .wait_input - ld a, [hffb3] - cp $ff ; operation cancelled? - jp z, OpenDeckConfigurationMenu - -; input was made to jump to the card list -.jump_to_list - ld a, [wNumEntriesInCurFilter] - or a - jr z, .wait_input - xor a -.wait_list_input - ld hl, FilteredCardListSelectionParams - call InitCardSelectionParams - ld a, [wNumEntriesInCurFilter] - ld [wNumCardListEntries], a - ld hl, wNumVisibleCardListEntries - cp [hl] - jr nc, .ok - ; if total number of entries is greater than or equal to - ; the number of visible entries, then set number of cursor positions - ; as number of visible entries - ld [wCardListNumCursorPositions], a -.ok - ld hl, PrintDeckBuildingCardList - ld d, h - ld a, l - ld hl, wCardListUpdateFunction - ld [hli], a - ld [hl], d - - ld a, $01 - ld [wced2], a -.loop_input - call DoFrame - ldh a, [hDPadHeld] - and START - jr z, .no_start_btn_2 - ld a, $01 - call PlaySFXConfirmOrCancel - - ; temporarily store current cursor position - ; to retrieve it later - ld a, [wCardListCursorPos] - ld [wTempFilteredCardListNumCursorPositions], a - call ConfirmDeckConfiguration - ld a, [wTempFilteredCardListNumCursorPositions] - jr .wait_list_input - -.no_start_btn_2 - call HandleSelectUpAndDownInList - jr c, .loop_input - call HandleDeckCardSelectionList - jr c, .selection_made - jr .loop_input - -.open_card_page - ld a, $01 - call PlaySFXConfirmOrCancel - ld a, [wCardListNumCursorPositions] - ld [wTempCardListNumCursorPositions], a - ld a, [wCardListCursorPos] - ld [wTempCardListCursorPos], a - - ; set wFilteredCardList as current card list - ; and show card page screen - ld de, wFilteredCardList - ld hl, wCurCardListPtr - ld [hl], e - inc hl - ld [hl], d - call OpenCardPageFromCardList - call DrawCardTypeIconsAndPrintCardCounts - - ld hl, FiltersCardSelectionParams - call InitCardSelectionParams - ld a, [wCurCardTypeFilter] - ld [wTempCardTypeFilter], a - call DrawHorizontalListCursor_Visible - call PrintDeckBuildingCardList - ld hl, FilteredCardListSelectionParams - call InitCardSelectionParams - ld a, [wTempCardListNumCursorPositions] - ld [wCardListNumCursorPositions], a - ld a, [wTempCardListCursorPos] - ld [wCardListCursorPos], a - jr .loop_input - -.selection_made - call DrawListCursor_Invisible - ld a, [wCardListCursorPos] - ld [wTempCardListCursorPos], a - ld a, [hffb3] - cp $ff - jr nz, .open_card_page - ; cancelled - ld hl, FiltersCardSelectionParams - call InitCardSelectionParams - ld a, [wCurCardTypeFilter] - ld [wTempCardTypeFilter], a - jp .wait_input - -OpenDeckConfigurationMenu: ; 9461 (2:5461) - xor a - ld [wYourOrOppPlayAreaCurPosition], a - ld de, wDeckConfigurationMenuTransitionTable - ld hl, wMenuInputTablePointer - ld a, [de] - ld [hli], a - inc de - ld a, [de] - ld [hl], a - ld a, $ff - ld [wDuelInitialPrizesUpperBitsSet], a -.skip_init - xor a - ld [wCheckMenuCursorBlinkCounter], a - ld hl, wDeckConfigurationMenuHandlerFunction - ld a, [hli] - ld h, [hl] - ld l, a - jp hl - -HandleDeckConfigurationMenu: ; 9480 (2:5480) - lb de, 0, 0 - lb bc, 20, 6 - call DrawRegularTextBox - ld hl, DeckBuildMenuData - call PlaceTextItems - -.do_frame - ld a, $1 - ld [wVBlankOAMCopyToggle], a - call DoFrame - call YourOrOppPlayAreaScreen_HandleInput - jr nc, .do_frame - ld [wced6], a - cp $ff - jr nz, .asm_94b5 -.draw_icons - call DrawCardTypeIconsAndPrintCardCounts - ld a, [wTempCardListCursorPos] - ld [wCardListCursorPos], a - ld a, [wCurCardTypeFilter] - call PrintFilteredCardList - jp HandleDeckBuildScreen.skip_draw - -.asm_94b5 - push af - call YourOrOppPlayAreaScreen_HandleInput.draw_cursor - ld a, $01 - ld [wVBlankOAMCopyToggle], a - pop af - ld hl, .func_table - call JumpToFunctionInTable - jr OpenDeckConfigurationMenu.skip_init - -.func_table - dw ConfirmDeckConfiguration ; Confirm - dw ModifyDeckConfiguration ; Modify - dw ChangeDeckName ; Name - dw SaveDeckConfiguration ; Save - dw DismantleDeck ; Dismantle - dw CancelDeckModifications ; Cancel - -ConfirmDeckConfiguration: ; 94d3 (2:54d3) - ld hl, wCardListVisibleOffset - ld a, [hl] - ld hl, wCardListVisibleOffsetBackup - ld [hl], a - call HandleDeckConfirmationMenu - ld hl, wCardListVisibleOffsetBackup - ld a, [hl] - ld hl, wCardListVisibleOffset - ld [hl], a - call DrawCardTypeIconsAndPrintCardCounts - ld hl, FiltersCardSelectionParams - call InitCardSelectionParams - ld a, [wCurCardTypeFilter] - ld [wTempCardTypeFilter], a - call DrawHorizontalListCursor_Visible - ld a, [wCurCardTypeFilter] - call PrintFilteredCardList - ld a, [wced6] - ld [wCardListCursorPos], a - ret - -ModifyDeckConfiguration: ; 9505 (2:5505) - add sp, $2 - jr HandleDeckConfigurationMenu.draw_icons - -; returns carry set if player chose to go back -CancelDeckModifications: ; 9509 (2:5509) -; if deck was not changed, cancel modification immediately - call CheckIfCurrentDeckWasChanged - jr nc, .cancel_modification -; else prompt the player to confirm - ldtx hl, QuitModifyingTheDeckText - call YesOrNoMenuWithText - jr c, SaveDeckConfiguration.go_back -.cancel_modification - add sp, $2 - or a - ret - -SaveDeckConfiguration: ; 951a (2:551a) -; handle deck configuration size - ld a, [wTotalCardCount] - cp DECK_SIZE - jp z, .ask_to_save_deck ; can be jr - ldtx hl, ThisIsntA60CardDeckText - call DrawWideTextBox_WaitForInput - ldtx hl, ReturnToOriginalConfigurationText - call YesOrNoMenuWithText - jr c, .print_deck_size_warning -; return no carry - add sp, $2 - or a - ret -.print_deck_size_warning - ldtx hl, TheDeckMustInclude60CardsText - call DrawWideTextBox_WaitForInput - jr .go_back - -.ask_to_save_deck - ldtx hl, SaveThisDeckText - call YesOrNoMenuWithText - jr c, .go_back - call CheckIfThereAreAnyBasicCardsInDeck - jr c, .set_carry - ldtx hl, ThereAreNoBasicPokemonInThisDeckText - call DrawWideTextBox_WaitForInput - ldtx hl, YouMustIncludeABasicPokemonInTheDeckText - call DrawWideTextBox_WaitForInput - -.go_back - call DrawCardTypeIconsAndPrintCardCounts - call PrintDeckBuildingCardList - ld a, [wced6] - ld [wCardListCursorPos], a - ret - -.set_carry - add sp, $2 - scf - ret - -DismantleDeck: ; 9566 (2:5566) - ldtx hl, DismantleThisDeckText - call YesOrNoMenuWithText - jr c, SaveDeckConfiguration.go_back - call CheckIfHasOtherValidDecks - jp nc, .Dismantle ; can be jr - ldtx hl, ThereIsOnly1DeckSoCannotBeDismantledText - call DrawWideTextBox_WaitForInput - call EmptyScreen - ld hl, FiltersCardSelectionParams - call InitCardSelectionParams - ld a, [wCurCardTypeFilter] - ld [wTempCardTypeFilter], a - call DrawHorizontalListCursor_Visible - call PrintDeckBuildingCardList - call EnableLCD - ld a, [wced6] - ld [wCardListCursorPos], a - ret - -.Dismantle - call EnableSRAM - call GetPointerToDeckName - ld a, [hl] - or a - jr z, .done_dismantle - ld a, NAME_BUFFER_LENGTH - call ClearNBytesFromHL - call GetPointerToDeckCards - call AddDeckToCollection - ld a, DECK_SIZE - call ClearNBytesFromHL -.done_dismantle - call DisableSRAM - add sp, $2 - ret - -ChangeDeckName: ; 95b9 (2:55b9) - call InputCurDeckName - add sp, $2 - jp HandleDeckBuildScreen.skip_count - -; returns carry if current deck was changed -; either through its card configuration or its name -CheckIfCurrentDeckWasChanged: ; 95c1 (2:55c1) - ld a, [wTotalCardCount] - or a - jr z, .skip_size_check - cp DECK_SIZE - jr nz, .set_carry -.skip_size_check - -; copy the selected deck to wCurDeckCardChanges - call GetPointerToDeckCards - ld de, wCurDeckCardChanges - ld b, DECK_SIZE - call EnableSRAM - call CopyNBytesFromHLToDE - call DisableSRAM - -; loops through cards in wCurDeckCards -; then if that card is found in wCurDeckCardChanges -; overwrite it by $0 - ld a, $ff ; terminator byte - ld [wCurDeckCardChanges + DECK_SIZE], a - ld de, wCurDeckCards -.loop_outer - ld a, [de] - or a - jr z, .check_empty - ld b, a - inc de - ld hl, wCurDeckCardChanges -.loop_inner - ld a, [hli] - cp $ff - jr z, .loop_outer - cp b - jr nz, .loop_inner - ; found - dec hl - xor a - ld [hli], a ; remove - jr .loop_outer - -.check_empty - ld hl, wCurDeckCardChanges -.loop_check_empty - ld a, [hli] - cp $ff - jr z, .is_empty - or a - jr nz, .set_carry - jr .loop_check_empty - -.is_empty -; wCurDeckCardChanges is empty (all $0) -; check if name was changed - call GetPointerToDeckName - ld de, wCurDeckName - call EnableSRAM -.loop_name - ld a, [de] - cp [hl] - jr nz, .set_carry - inc de - inc hl - or a - jr nz, .loop_name - call DisableSRAM - ret - -.set_carry - call DisableSRAM - scf - ret - -; returns carry if doesn't have a valid deck -; aside from the current deck -CheckIfHasOtherValidDecks: ; 9622 (2:5622) - ld hl, wDecksValid - lb bc, 0, 0 -.loop - inc b - ld a, NUM_DECKS - cp b - jr c, .check_has_cards - ld a, [hli] - or a - jr z, .loop - ; is valid - inc c - ld a, 1 - cp c - jr nc, .loop ; just 1 valid - ; at least 2 decks are valid -.no_carry - or a - ret - -.check_has_cards -; doesn't have at least 2 valid decks -; check if current deck is the only one -; that is valid (i.e. has cards) - call GetPointerToDeckCards - call EnableSRAM - ld a, [hl] - call DisableSRAM - or a - jr z, .no_carry ; no cards - ; has cards, is the only valid deck! - scf - ret - -; checks if wCurDeckCards has any basics -; returns carry set if there is at least -; 1 Basic Pokemon card -CheckIfThereAreAnyBasicCardsInDeck: ; 9649 (2:5649) - ld hl, wCurDeckCards -.loop_cards - ld a, [hli] - ld e, a - or a - jr z, .no_carry - call LoadCardDataToBuffer1_FromCardID - jr c, .no_carry - ld a, [wLoadedCard1Type] - and TYPE_ENERGY - jr nz, .loop_cards - ld a, [wLoadedCard1Stage] - or a - jr nz, .loop_cards - ; is basic card - scf - ret -.no_carry - or a - ret - -FiltersCardSelectionParams: ; 9667 (2:5667) - db 1 ; x pos - db 1 ; y pos - db 0 ; y spacing - db 2 ; x spacing - db NUM_FILTERS ; num entries - db SYM_CURSOR_D ; visible cursor tile - db SYM_SPACE ; invisible cursor tile - dw NULL ; wCardListHandlerFunction - -FilteredCardListSelectionParams: ; 9670 (2:5670) - db 0 ; x pos - db 7 ; y pos - db 2 ; y spacing - db 0 ; x spacing - db NUM_FILTERED_LIST_VISIBLE_CARDS ; num entries - db SYM_CURSOR_R ; visible cursor tile - db SYM_SPACE ; invisible cursor tile - dw NULL ; wCardListHandlerFunction - -DeckConfigurationMenu_TransitionTable: ; 9679 (2:5679) - cursor_transition $10, $20, $00, $03, $03, $01, $02 - cursor_transition $48, $20, $00, $04, $04, $02, $00 - cursor_transition $80, $20, $00, $05, $05, $00, $01 - cursor_transition $10, $30, $00, $00, $00, $04, $05 - cursor_transition $48, $30, $00, $01, $01, $05, $03 - cursor_transition $80, $30, $00, $02, $02, $03, $04 - -; draws each card type icon in a line -; the respective card counts underneath each icon -; and prints"X/60" in the upper-right corner, -; where X is the total card count -DrawCardTypeIconsAndPrintCardCounts: ; 96a3 (2:56a3) - call Set_OBJ_8x8 - call Func_8d78 - lb bc, 0, 5 - ld a, SYM_BOX_TOP - call FillBGMapLineWithA - call DrawCardTypeIcons - call PrintCardTypeCounts - lb de, 15, 0 - call PrintTotalCardCount - lb de, 17, 0 - call PrintSlashSixty - call EnableLCD - ret - -; fills one line at coordinate bc in BG Map -; with the byte in register a -; fills the same line with $04 in VRAM1 if in CGB -; bc = coordinates -FillBGMapLineWithA: ; 96c7 (2:56c7) - call BCCoordToBGMap0Address - ld b, SCREEN_WIDTH - call FillDEWithA - ld a, [wConsole] - cp CONSOLE_CGB - ret nz ; return if not CGB - ld a, $04 - ld b, SCREEN_WIDTH - call BankswitchVRAM1 - call FillDEWithA - call BankswitchVRAM0 - ret - -; saves the count of each type of card that is in wCurDeckCards -; stores these values in wCardFilterCounts -CountNumberOfCardsForEachCardType: ; 96e3 (2:56e3) - ld hl, wCardFilterCounts - ld de, CardTypeFilters -.loop - ld a, [de] - cp -1 - ret z - inc de - call CountNumberOfCardsOfType - ld [hli], a - jr .loop - -; fills de with b bytes of the value in register a -FillDEWithA: ; 96f4 (2:56f4) - push hl - ld l, e - ld h, d -.loop - ld [hli], a - dec b - jr nz, .loop - pop hl - ret - -; draws all the card type icons -; in a line specified by .CardTypeIcons -DrawCardTypeIcons: ; 96fd (2:56fd) - ld hl, .CardTypeIcons -.loop - ld a, [hli] - or a - ret z ; done - ld d, [hl] ; x coord - inc hl - ld e, [hl] ; y coord - inc hl - call .DrawIcon - jr .loop - -; input: -; de = coordinates -.DrawIcon - push hl - push af - lb hl, 1, 2 - lb bc, 2, 2 - call FillRectangle - pop af - call GetCardTypeIconPalette - ld b, a - ld a, [wConsole] - cp CONSOLE_CGB - jr nz, .not_cgb - ld a, b - lb bc, 2, 2 - lb hl, 0, 0 - call BankswitchVRAM1 - call FillRectangle - call BankswitchVRAM0 -.not_cgb - pop hl - ret - -.CardTypeIcons -; icon tile, x coord, y coord - db ICON_TILE_GRASS, 1, 2 - db ICON_TILE_FIRE, 3, 2 - db ICON_TILE_WATER, 5, 2 - db ICON_TILE_LIGHTNING, 7, 2 - db ICON_TILE_FIGHTING, 9, 2 - db ICON_TILE_PSYCHIC, 11, 2 - db ICON_TILE_COLORLESS, 13, 2 - db ICON_TILE_TRAINER, 15, 2 - db ICON_TILE_ENERGY, 17, 2 - db $00 - -DeckBuildMenuData: ; 9751 (1:5751) - ; x, y, text id - textitem 2, 2, ConfirmText - textitem 9, 2, ModifyText - textitem 16, 2, NameText - textitem 2, 4, SaveText - textitem 9, 4, DismantleText - textitem 16, 4, CancelText - db $ff - -; prints "/60" to the coordinates given in de -PrintSlashSixty: ; 976a (2:576a) - ld hl, wDefaultText - ld a, TX_SYMBOL - ld [hli], a - ld a, SYM_SLASH - ld [hli], a - ld a, TX_SYMBOL - ld [hli], a - ld a, SYM_6 - ld [hli], a - ld a, TX_SYMBOL - ld [hli], a - ld a, SYM_0 - ld [hli], a - ld [hl], TX_END - call InitTextPrinting - ld hl, wDefaultText - call ProcessText - ret - -; creates two separate lists given the card type in register a -; if a card matches the card type given, then it's added to wFilteredCardList -; if a card has been owned by the player, and its card count is at least 1, -; (or in case it's 0 if it's in any deck configurations saved) -; then its collection count is also added to wOwnedCardsCountList -; if input a is $ff, then all card types are included -CreateFilteredCardList: ; 978b (2:578b) - push af - push bc - push de - push hl - -; clear wOwnedCardsCountList and wFilteredCardList - push af - ld a, DECK_SIZE - ld hl, wOwnedCardsCountList - call ClearNBytesFromHL - ld a, DECK_SIZE - ld hl, wFilteredCardList - call ClearNBytesFromHL - pop af - -; loops all cards in collection - ld hl, $0 - ld de, $0 - ld b, a ; input card type -.loop_card_ids - inc e - call GetCardType - jr c, .store_count - ld c, a - ld a, b - cp $ff - jr z, .add_card - and FILTER_ENERGY - cp FILTER_ENERGY - jr z, .check_energy - ld a, c - cp b - jr nz, .loop_card_ids - jr .add_card -.check_energy - ld a, c - and TYPE_ENERGY - cp TYPE_ENERGY - jr nz, .loop_card_ids - -.add_card - push bc - push hl - ld bc, wFilteredCardList - add hl, bc - ld [hl], e - ld hl, wTempCardCollection - add hl, de - ld a, [hl] - pop hl - cp CARD_NOT_OWNED - jr z, .next_card ; jump if never seen card - or a - jr nz, .ok ; has at least 1 - call IsCardInAnyDeck - jr c, .next_card ; jump if not in any deck -.ok - push hl - ld bc, wOwnedCardsCountList - add hl, bc - ld [hl], a - pop hl - inc l -.next_card - pop bc - jr .loop_card_ids - -.store_count - ld a, l - ld [wNumEntriesInCurFilter], a -; add terminator bytes in both lists - xor a - ld c, l - ld b, h - ld hl, wFilteredCardList - add hl, bc - ld [hl], a ; $00 - ld a, $ff - ld hl, wOwnedCardsCountList - add hl, bc - ld [hl], a ; $ff - pop hl - pop de - pop bc - pop af - ret - -; returns carry if card ID in register e is not -; found in any of the decks saved in SRAM -IsCardInAnyDeck: ; 9803 (2:5803) - push af - push hl - ld hl, sDeck1Cards - call .FindCardInDeck - jr nc, .found_card - ld hl, sDeck2Cards - call .FindCardInDeck - jr nc, .found_card - ld hl, sDeck3Cards - call .FindCardInDeck - jr nc, .found_card - ld hl, sDeck4Cards - call .FindCardInDeck - jr nc, .found_card - pop hl - pop af - scf - ret -.found_card - pop hl - pop af - or a - ret - -; returns carry if input card ID in register e -; is not found in deck given by hl -.FindCardInDeck - call EnableSRAM - ld b, DECK_SIZE -.loop - ld a, [hli] - cp e - jr z, .not_found - dec b - jr nz, .loop -; not found - call DisableSRAM - scf - ret -.not_found - call DisableSRAM - or a - ret - -; preserves all registers -; hl = start of bytes to set to $0 -; a = number of bytes to set to $0 -ClearNBytesFromHL: ; 9843 (2:5843) - push af - push bc - push hl - ld b, a - xor a -.loop - ld [hli], a - dec b - jr nz, .loop - pop hl - pop bc - pop af - ret - -; returns the number of times that card e -; appears in wCurDeckCards -GetCountOfCardInCurDeck: ; 9850 (2:5850) - push hl - ld hl, wCurDeckCards - ld d, 0 -.loop - ld a, [hli] - or a - jr z, .done - cp e - jr nz, .loop - inc d - jr .loop -.done - ld a, d - pop hl - ret - -; returns total count of card ID e -; looks it up in wFilteredCardList -; then uses the index to retrieve the count -; value from wOwnedCardsCountList -GetOwnedCardCount: ; 9863 (2:5863) - push hl - ld hl, wFilteredCardList - ld d, -1 -.loop - inc d - ld a, [hli] - or a - jr z, .not_found - cp e - jr nz, .loop - ld hl, wOwnedCardsCountList - push de - ld e, d - ld d, $00 - add hl, de - pop de - ld a, [hl] - pop hl - ret -.not_found - xor a - pop hl - ret - -; appends text "X/Y", where X is the number of included cards -; and Y is the total number of cards in storage of a given card ID -; input: -; e = card ID -AppendOwnedCardCountAndStorageCountNumbers: ; 9880 (2:5880) - push af - push bc - push de - push hl -; count how many bytes until $00 -.loop - ld a, [hl] - or a - jr z, .print - inc hl - jr .loop -.print - push de - call GetCountOfCardInCurDeck - call ConvertToNumericalDigits - ld [hl], TX_SYMBOL - inc hl - ld [hl], SYM_SLASH - inc hl - pop de - call GetOwnedCardCount - call ConvertToNumericalDigits - ld [hl], TX_END - pop hl - pop de - pop bc - pop af - ret - -; determines the ones and tens digits in a for printing -; the ones place is added $20 (SYM_0) so that it maps to a numerical character -; if the tens is 0, it maps to an empty character -; a = value to calculate digits -CalculateOnesAndTensDigits: ; 98a6 (2:58a6) - push af - push bc - push de - push hl - ld c, -1 -.loop - inc c - sub 10 - jr nc, .loop - jr z, .zero1 - add 10 - ; a = a mod 10 - ; c = floor(a / 10) -.zero1 -; ones digit - add SYM_0 - ld hl, wOnesAndTensPlace - ld [hli], a - -; tens digit - ld a, c - or a - jr z, .zero2 - add SYM_0 -.zero2 - ld [hl], a - - pop hl - pop de - pop bc - pop af - ret - -; converts value in register a to -; numerical symbols for ProcessText -; places the symbols in hl -ConvertToNumericalDigits: ; 98c7 (2:58c7) - call CalculateOnesAndTensDigits - push hl - ld hl, wOnesAndTensPlace - ld a, [hli] - ld b, a - ld a, [hl] - pop hl - ld [hl], TX_SYMBOL - inc hl - ld [hli], a - ld [hl], TX_SYMBOL - inc hl - ld a, b - ld [hli], a - ret - -; counts the number of cards in wCurDeckCards -; that are the same type as input in register a -; if input is $20, counts all energy cards instead -; input: -; - a = card type -; output: -; - a = number of cards of same type -CountNumberOfCardsOfType: ; 98dc (2:58dc) - push de - push hl - ld hl, $0 - ld b, a - ld c, 0 -.loop_cards - push hl - push bc - ld bc, wCurDeckCards - add hl, bc - ld a, [hl] - pop bc - pop hl - inc l - or a - jr z, .done ; end of card list - -; get card type and compare it with input type -; if input is FILTER_ENERGY, run a separate comparison -; if it's the same type, increase the count - ld e, a - call GetCardType - jr c, .done - push hl - ld l, a - ld a, b - and FILTER_ENERGY - cp FILTER_ENERGY - jr z, .check_energy - ld a, l - pop hl - cp b - jr nz, .loop_cards - jr .incr_count - -; counts all energy cards as the same -.check_energy - ld a, l - pop hl - and TYPE_ENERGY - cp TYPE_ENERGY - jr nz, .loop_cards -.incr_count - inc c - jr .loop_cards -.done - ld a, c - pop hl - pop de - ret - -; prints the card count of each individual card type -; assumes CountNumberOfCardsForEachCardType was already called -; this is done by processing text in a single line -; and concatenating all digits -PrintCardTypeCounts: ; 9916 (2:5916) - ld bc, $0 - ld hl, wDefaultText -.loop - push hl - ld hl, wCardFilterCounts - add hl, bc - ld a, [hl] - pop hl - push bc - call ConvertToNumericalDigits - pop bc - inc c - ld a, NUM_FILTERS - cp c - jr nz, .loop - ld [hl], TX_END - lb de, 1, 4 - call InitTextPrinting - ld hl, wDefaultText - call ProcessText - ret - -; prints the list of cards, applying the filter from register a -; the counts of each card displayed is taken from wCurDeck -; a = card type filter -PrintFilteredCardList: ; 993d (2:593d) - push af - ld hl, CardTypeFilters - ld b, $00 - ld c, a - add hl, bc - ld a, [hl] - push af - -; copy sCardCollection to wTempCardCollection - call EnableSRAM - ld hl, sCardCollection - ld de, wTempCardCollection - ld b, CARD_COLLECTION_SIZE - 1 - call CopyNBytesFromHLToDE - call DisableSRAM - - ld a, [wIncludeCardsInDeck] - or a - jr z, .ok - call GetPointerToDeckCards - ld d, h - ld e, l - call IncrementDeckCardsInTempCollection -.ok - pop af - - call CreateFilteredCardList - ld a, NUM_FILTERED_LIST_VISIBLE_CARDS - ld [wNumVisibleCardListEntries], a - lb de, 1, 7 - ld hl, wCardListCoords - ld [hl], e - inc hl - ld [hl], d - call PrintDeckBuildingCardList - pop af - ret - -; used to filter the cards in the deck building/card selection screen -CardTypeFilters: ; 997d (2:597d) - db FILTER_GRASS - db FILTER_FIRE - db FILTER_WATER - db FILTER_LIGHTNING - db FILTER_FIGHTING - db FILTER_PSYCHIC - db FILTER_COLORLESS - db FILTER_TRAINER - db FILTER_ENERGY - db -1 ; end of list - -; counts all the cards from each card type -; (stored in wCardFilterCounts) and store it in wTotalCardCount -; also prints it in coordinates de -PrintTotalCardCount: ; 9987 (2:5987) - push de - ld bc, $0 - ld hl, wCardFilterCounts -.loop - ld a, [hli] - add b - ld b, a - inc c - ld a, NUM_FILTERS - cp c - jr nz, .loop - ld hl, wDefaultText - ld a, b - ld [wTotalCardCount], a - push bc - call ConvertToNumericalDigits - pop bc - ld [hl], TX_END - pop de - call InitTextPrinting - ld hl, wDefaultText - call ProcessText - ret - -; prints the name, level and storage count of the cards -; that are visible in the list window -; in the form: -; CARD NAME/LEVEL X/Y -; where X is the current count of that card -; and Y is the storage count of that card -PrintDeckBuildingCardList: ; 99b0 (2:59b0) - push bc - ld hl, wCardListCoords - ld e, [hl] - inc hl - ld d, [hl] - ld b, 19 ; x coord - ld c, e - dec c - ld a, [wCardListVisibleOffset] - or a - jr z, .no_cursor - ld a, SYM_CURSOR_U - jr .got_cursor_tile -.no_cursor - ld a, SYM_SPACE -.got_cursor_tile - call WriteByteToBGMap0 - -; iterates by decreasing value in wNumVisibleCardListEntries -; by 1 until it reaches 0 - ld a, [wCardListVisibleOffset] - ld c, a - ld b, $0 - ld hl, wFilteredCardList - add hl, bc - ld a, [wNumVisibleCardListEntries] -.loop_filtered_cards - push de - or a - jr z, .exit_loop - ld b, a - ld a, [hli] - or a - jr z, .invalid_card ; card ID of 0 - ld e, a - call AddCardIDToVisibleList - call LoadCardDataToBuffer1_FromCardID - ld a, 13 - push bc - push hl - push de - call CopyCardNameAndLevel - pop de - call AppendOwnedCardCountAndStorageCountNumbers - pop hl - pop bc - pop de - push hl - call InitTextPrinting - ld hl, wDefaultText - jr .process_text - -.invalid_card - pop de - push hl - call InitTextPrinting - ld hl, Text_9a30 -.process_text - call ProcessText - pop hl - - ld a, b - dec a - inc e - inc e - jr .loop_filtered_cards - -.exit_loop - ld a, [hli] - or a - jr z, .cannot_scroll - pop de -; draw down cursor because -; there are still more cards -; to be scrolled down - xor a ; FALSE - ld [wUnableToScrollDown], a - ld a, SYM_CURSOR_D - jr .draw_cursor -.cannot_scroll - pop de - ld a, TRUE - ld [wUnableToScrollDown], a - ld a, SYM_SPACE -.draw_cursor - ld b, 19 ; x coord - ld c, e - dec c - dec c - call WriteByteToBGMap0 - pop bc - ret - -Text_9a30: - db TX_SYMBOL, TX_END - -Text_9a32: - db TX_SYMBOL, TX_END - -Text_9a34: - db TX_SYMBOL, TX_END - -Text_9a36: - db TX_SYMBOL, TX_END - -Text_9a38: - db TX_SYMBOL, TX_END - -Text_9a3a: - db TX_SYMBOL, TX_END - -Text_9a3c: - db TX_SYMBOL, TX_END - -Text_9a3e: - db TX_SYMBOL, TX_END - -Text_9a40: - db TX_SYMBOL, TX_END - -Text_9a42: - db TX_SYMBOL, TX_END - -Text_9a44: - db TX_SYMBOL, TX_END - -Text_9a46: - db TX_SYMBOL, TX_END - -Text_9a48: - db TX_SYMBOL, TX_END - -Text_9a4a: - db TX_SYMBOL, TX_END - -Text_9a4c: - db TX_SYMBOL, TX_END - -Text_9a4e: - db TX_SYMBOL, TX_END - -Text_9a50: - db TX_SYMBOL, TX_END - -Text_9a52: - db TX_SYMBOL, TX_END - -Text_9a54: - db TX_SYMBOL, TX_END - -Text_9a56: - db TX_SYMBOL, TX_END - -Text_9a58: - done - -; writes the card ID in register e to wVisibleListCardIDs -; given its position in the list in register b -; input: -; b = list position (starts from bottom) -; e = card ID -AddCardIDToVisibleList: ; 9a59 (2:5a59) - push af - push bc - push hl - ld hl, wVisibleListCardIDs - ld c, b - ld a, [wNumVisibleCardListEntries] - sub c - ld c, a ; wNumVisibleCardListEntries - b - ld b, $0 - add hl, bc - ld [hl], e - pop hl - pop bc - pop af - ret - -; copies data from hl to: -; wCardListCursorXPos -; wCardListCursorYPos -; wCardListYSpacing -; wCardListXSpacing -; wCardListNumCursorPositions -; wVisibleCursorTile -; wInvisibleCursorTile -; wCardListHandlerFunction -InitCardSelectionParams: ; 9a6d (2:5a6d) - ld [wCardListCursorPos], a - ld [hffb3], a - ld de, wCardListCursorXPos - ld b, $9 -.loop - ld a, [hli] - ld [de], a - inc de - dec b - jr nz, .loop - xor a - ld [wCheckMenuCursorBlinkCounter], a - ret - -HandleCardSelectionInput: ; 9a83 (2:5a83) - xor a ; FALSE - ld [wPlaysSfx], a - ldh a, [hDPadHeld] - or a - jr z, .handle_ab_btns - -; handle d-pad - ld b, a - ld a, [wCardListNumCursorPositions] - ld c, a - ld a, [wCardListCursorPos] - bit D_LEFT_F, b - jr z, .check_d_right - dec a - bit 7, a - jr z, .got_cursor_pos - ; if underflow, set to max cursor pos - ld a, [wCardListNumCursorPositions] - dec a - jr .got_cursor_pos -.check_d_right - bit D_RIGHT_F, b - jr z, .handle_ab_btns - inc a - cp c - jr c, .got_cursor_pos - ; if over max pos, set to pos 0 - xor a -.got_cursor_pos - push af - ld a, TRUE - ld [wPlaysSfx], a - call DrawHorizontalListCursor_Invisible - pop af - ld [wCardListCursorPos], a - xor a - ld [wCheckMenuCursorBlinkCounter], a - -.handle_ab_btns - ld a, [wCardListCursorPos] - ld [hffb3], a - ldh a, [hKeysPressed] - and A_BUTTON | B_BUTTON - jr z, HandleCardSelectionCursorBlink - and A_BUTTON - jr nz, ConfirmSelectionAndReturnCarry - ; b button - ld a, $ff - ld [hffb3], a - call PlaySFXConfirmOrCancel - scf - ret - -; outputs cursor position in e and selection in a -ConfirmSelectionAndReturnCarry: ; 9ad7 (2:5ad7) - call DrawHorizontalListCursor_Visible - ld a, $01 - call PlaySFXConfirmOrCancel - ld a, [wCardListCursorPos] - ld e, a - ld a, [hffb3] - scf - ret - -HandleCardSelectionCursorBlink: ; 9ae8 (2:5ae8) - ld a, [wPlaysSfx] - or a - jr z, .skip_sfx - call PlaySFX -.skip_sfx - ld hl, wCheckMenuCursorBlinkCounter - ld a, [hl] - inc [hl] - and $0f - ret nz - ld a, [wVisibleCursorTile] - bit 4, [hl] - jr z, DrawHorizontalListCursor - -DrawHorizontalListCursor_Invisible: ; 9b00 (2:5b00) - ld a, [wInvisibleCursorTile] -; fallthrough - -; like DrawListCursor but only -; for lists with one line, and each entry -; being laid horizontally -; a = tile to write -DrawHorizontalListCursor: ; 9b03 (2:5b03) - ld e, a - ld a, [wCardListXSpacing] - ld l, a - ld a, [wCardListCursorPos] - ld h, a - call HtimesL - ld a, l - ld hl, wCardListCursorXPos - add [hl] - ld b, a ; x coord - ld hl, wCardListCursorYPos - ld a, [hl] - ld c, a ; y coord - ld a, e - call WriteByteToBGMap0 - or a - ret - -DrawHorizontalListCursor_Visible: ; 9b20 (2:5b20) - ld a, [wVisibleCursorTile] - jr DrawHorizontalListCursor - -; handles user input when selecting cards to add -; to deck configuration -; returns carry if a selection was made -; (either selected card or cancelled) -; outputs in a the list index if selection was made -; or $ff if operation was cancelled -HandleDeckCardSelectionList: ; 9b25 (2:5b25) - xor a ; FALSE - ld [wPlaysSfx], a - - ldh a, [hDPadHeld] - or a - jp z, .asm_9bb9 - - ld b, a - ld a, [wCardListNumCursorPositions] - ld c, a - ld a, [wCardListCursorPos] - bit D_UP_F, b - jr z, .check_d_down - push af - ld a, TRUE - ld [wPlaysSfx], a - pop af - dec a - bit 7, a - jr z, .asm_9b8f - ld a, [wCardListVisibleOffset] - or a - jr z, .asm_9b5a - dec a - ld [wCardListVisibleOffset], a - ld hl, wCardListUpdateFunction - call CallIndirect - xor a - jr .asm_9b8f -.asm_9b5a - xor a - ld [wPlaysSfx], a - jr .asm_9b8f - -.check_d_down - bit D_DOWN_F, b - jr z, .asm_9b9d - push af - ld a, TRUE - ld [wPlaysSfx], a - pop af - inc a - cp c - jr c, .asm_9b8f - push af - ld a, [wUnableToScrollDown] - or a - jr nz, .cannot_scroll_down - ld a, [wCardListVisibleOffset] - inc a - ld [wCardListVisibleOffset], a - ld hl, wCardListUpdateFunction - call CallIndirect - pop af - dec a - jr .asm_9b8f - -.cannot_scroll_down - pop af - dec a - push af - xor a ; FALSE - ld [wPlaysSfx], a - pop af - -.asm_9b8f - push af - call DrawListCursor_Invisible - pop af - ld [wCardListCursorPos], a - xor a - ld [wCheckMenuCursorBlinkCounter], a - jr .asm_9bb9 -.asm_9b9d - ld a, [wced2] - or a - jr z, .asm_9bb9 - - bit D_LEFT_F, b - jr z, .check_d_right - call GetSelectedVisibleCardID - call RemoveCardFromDeckAndUpdateCount - jr .asm_9bb9 -.check_d_right - bit D_RIGHT_F, b - jr z, .asm_9bb9 - call GetSelectedVisibleCardID - call AddCardToDeckAndUpdateCount - -.asm_9bb9 - ld a, [wCardListCursorPos] - ld [hffb3], a - ld hl, wCardListHandlerFunction - ld a, [hli] - or [hl] - jr z, .handle_ab_btns - - ; this code seemingly never runs - ; because wCardListHandlerFunction is always NULL - ld a, [hld] - ld l, [hl] - ld h, a - ld a, [hffb3] - call CallHL - jr nc, .handle_blink - -.select_card - call DrawListCursor_Visible - ld a, $01 - call PlaySFXConfirmOrCancel - ld a, [wCardListCursorPos] - ld e, a - ld a, [hffb3] - scf - ret - -.handle_ab_btns - ldh a, [hKeysPressed] - and A_BUTTON | B_BUTTON - jr z, .check_sfx - and A_BUTTON - jr nz, .select_card - ld a, $ff - ld [hffb3], a - call PlaySFXConfirmOrCancel - scf - ret - -.check_sfx - ld a, [wPlaysSfx] - or a - jr z, .handle_blink - call PlaySFX -.handle_blink - ld hl, wCheckMenuCursorBlinkCounter - ld a, [hl] - inc [hl] - and $0f - ret nz - ld a, [wVisibleCursorTile] - bit 4, [hl] - jr z, DrawListCursor -; fallthrough - -DrawListCursor_Invisible: ; 9c0e (2:5c0e) - ld a, [wInvisibleCursorTile] -; fallthrough - -; draws cursor considering wCardListCursorPos -; spaces each entry horizontally by wCardListXSpacing -; and vertically by wCardListYSpacing -; a = tile to write -DrawListCursor: ; 9c11 (2:5c11) - ld e, a - ld a, [wCardListXSpacing] - ld l, a - ld a, [wCardListCursorPos] - ld h, a - call HtimesL - ld a, l - ld hl, wCardListCursorXPos - add [hl] - ld b, a ; x coord - ld a, [wCardListYSpacing] - ld l, a - ld a, [wCardListCursorPos] - ld h, a - call HtimesL - ld a, l - ld hl, wCardListCursorYPos - add [hl] - ld c, a ; y coord - ld a, e - call WriteByteToBGMap0 - or a - ret - -DrawListCursor_Visible: ; 9c3a (2:5c3a) - ld a, [wVisibleCursorTile] - jr DrawListCursor - -OpenCardPageFromCardList: ; 9c3f (2:5c3f) -; get the card index that is selected -; and open its card page - ld hl, wCurCardListPtr - ld a, [hli] - ld h, [hl] - ld l, a - ld a, [wCardListCursorPos] - ld c, a - ld b, $0 - add hl, bc - ld a, [wCardListVisibleOffset] - ld c, a - ld b, $0 - add hl, bc - ld e, [hl] - ld d, $0 - push de - call LoadCardDataToBuffer1_FromCardID - lb de, $38, $9f - call SetupText - bank1call OpenCardPage_FromCheckHandOrDiscardPile - pop de - -.handle_input - ldh a, [hDPadHeld] - ld b, a - and A_BUTTON | B_BUTTON | SELECT | START - jp nz, .exit - -; check d-pad -; if UP or DOWN is pressed, change the -; card that is being shown, given the -; order in the current card list - xor a ; FALSE - ld [wPlaysSfx], a - ld a, [wCardListNumCursorPositions] - ld c, a - ld a, [wCardListCursorPos] - bit D_UP_F, b - jr z, .check_d_down - push af - ld a, TRUE - ld [wPlaysSfx], a - pop af - dec a - bit 7, a - jr z, .reopen_card_page - ld a, [wCardListVisibleOffset] - or a - jr z, .handle_regular_card_page_input - dec a - ld [wCardListVisibleOffset], a - xor a - jr .reopen_card_page - -.check_d_down - bit D_DOWN_F, b - jr z, .handle_regular_card_page_input - push af - ld a, TRUE - ld [wPlaysSfx], a - pop af - inc a - cp c - jr c, .reopen_card_page - push af - ld hl, wCurCardListPtr - ld a, [hli] - ld h, [hl] - ld l, a - ld a, [wCardListCursorPos] - ld c, a - ld b, $0 - add hl, bc - ld a, [wCardListVisibleOffset] - inc a - ld c, a - ld b, $0 - add hl, bc - ld a, [hl] - or a - jr z, .skip_change_card - ld a, [wCardListVisibleOffset] - inc a - ld [wCardListVisibleOffset], a - pop af - dec a -.reopen_card_page - ld [wCardListCursorPos], a - ld a, [wPlaysSfx] - or a - jp z, OpenCardPageFromCardList - call PlaySFX - jp OpenCardPageFromCardList - -.skip_change_card - pop af - jr .handle_regular_card_page_input ; unnecessary jr -.handle_regular_card_page_input - push de - bank1call OpenCardPage.input_loop - pop de - jp .handle_input - -.exit - ld a, $1 - ld [wVBlankOAMCopyToggle], a - ld a, [wCardListCursorPos] - ld [wTempCardListCursorPos], a - ret - -; opens card page from the card list -; unreferenced? -Func_9ced: ; 9ced (2:5ced) - ld hl, wVisibleListCardIDs - ld a, [wCardListCursorPos] - ld c, a - ld b, $00 - add hl, bc - ld e, [hl] - inc hl - ld d, [hl] - call LoadCardDataToBuffer1_FromCardID - ld de, $389f - call SetupText - bank1call OpenCardPage_FromHand - ld a, $01 - ld [wVBlankOAMCopyToggle], a - ret - -; adds card in register e to deck configuration -; and updates the values shown for its count -; in the card selection list -; input: -; e = card ID -AddCardToDeckAndUpdateCount: ; 9d0c (2:5d0c) - call TryAddCardToDeck - ret c ; failed to add card - push de - call PrintCardTypeCounts - lb de, 15, 0 - call PrintTotalCardCount - pop de - call GetCountOfCardInCurDeck - call PrintNumberValueInCursorYPos - ret - -; tries to add card ID in register e to wCurDeckCards -; fails to add card if one of the following conditions are met: -; - total cards are equal to wMaxNumCardsAllowed -; - cards with the same name as it reached the allowed limit -; - player doesn't own more copies in the collection -; returns carry if fails -; otherwise, writes card ID to first empty slot in wCurDeckCards -; input: -; e = card ID -TryAddCardToDeck: ; 9d22 (2:5d22) - ld a, [wMaxNumCardsAllowed] - ld d, a - ld a, [wTotalCardCount] - cp d - jr nz, .not_equal - ; wMaxNumCardsAllowed == wTotalCardCount - scf - ret - -.not_equal - push de - call .CheckIfCanAddCardWithSameName - pop de - ret c ; cannot add more cards with this name - - push de - call GetCountOfCardInCurDeck - ld b, a - ld hl, wOwnedCardsCountList - ld d, $0 - ld a, [wCardListVisibleOffset] - ld e, a - add hl, de - ld a, [wCardListCursorPos] - ld e, a - add hl, de - ld d, [hl] - ld a, b - cp d - pop de - scf - ret z ; cannot add because player doesn't own more copies - - ld a, SFX_01 - call PlaySFX - push de - call .AddCardToCurDeck - ld a, [wCurCardTypeFilter] - ld c, a - ld b, $0 - ld hl, wCardFilterCounts - add hl, bc - inc [hl] - pop de - or a - ret - -; finds first empty slot in wCurDeckCards -; then writes the value in e to it -.AddCardToCurDeck - ld hl, wCurDeckCards -.loop - ld a, [hl] - or a - jr z, .empty - inc hl - jr .loop -.empty - ld [hl], e - inc hl - xor a - ld [hl], a - ret - -; returns carry if card ID in e cannot be -; added to the current deck configuration -; due to having reached the maximum number -; of cards allowed with that same name -; e = card id -.CheckIfCanAddCardWithSameName - call LoadCardDataToBuffer1_FromCardID - ld a, [wLoadedCard1Type] - cp TYPE_ENERGY_DOUBLE_COLORLESS - jr z, .double_colorless - ; basic energy cards have no limit - and TYPE_ENERGY - cp TYPE_ENERGY - jr z, .exit ; return if basic energy card -.double_colorless - -; compare this card's name to -; the names of cards in list wCurDeckCards - ld a, [wLoadedCard1Name + 0] - ld c, a - ld a, [wLoadedCard1Name + 1] - ld b, a - ld hl, wCurDeckCards - ld d, 0 - push de -.loop_cards - ld a, [hli] - or a - jr z, .exit_pop_de - ld e, a - ld d, $0 - call GetCardName - ld a, e - cp c - jr nz, .loop_cards - ld a, d - cp b - jr nz, .loop_cards - ; has same name - pop de - inc d ; increment counter of cards with this name - ld a, [wSameNameCardsLimit] - cp d - push de - jr nz, .loop_cards - ; reached the maximum number - ; of cards with same name allowed - pop de - scf - ret - -.exit_pop_de - pop de -.exit - or a - ret - -; gets the element in wVisibleListCardIDs -; corresponding to index wCardListCursorPos -GetSelectedVisibleCardID: ; 9db3 (2:5db3) - ld hl, wVisibleListCardIDs - ld a, [wCardListCursorPos] - ld e, a - ld d, $00 - add hl, de - ld e, [hl] - ret - -; appends the digits of value in register a to wDefaultText -; then prints it in cursor Y position -; a = value to convert to numerical digits -PrintNumberValueInCursorYPos: ; 9dbf (2:5dbf) - ld hl, wDefaultText - call ConvertToNumericalDigits - ld [hl], TX_END - ld a, [wCardListYSpacing] - ld l, a - ld a, [wCardListCursorPos] - ld h, a - call HtimesL - ld a, l - ld hl, wCardListCursorYPos - add [hl] - ld e, a - ld d, 14 - call InitTextPrinting - ld hl, wDefaultText - call ProcessText - ret - -; removes card in register e from deck configuration -; and updates the values shown for its count -; in the card selection list -; input: -; e = card ID -RemoveCardFromDeckAndUpdateCount: ; 9de4 (2:5de4) - call RemoveCardFromDeck - ret nc - push de - call PrintCardTypeCounts - lb de, 15, 0 - call PrintTotalCardCount - pop de - call GetCountOfCardInCurDeck - call PrintNumberValueInCursorYPos - ret - -; removes card ID in e from wCurDeckCards -RemoveCardFromDeck: ; 9dfa (2:5dfa) - push de - call GetCountOfCardInCurDeck - pop de - or a - ret z ; card is not in deck - ld a, SFX_01 - call PlaySFX - push de - call .RemoveCard - ld a, [wCurCardTypeFilter] - ld c, a - ld b, $0 - ld hl, wCardFilterCounts - add hl, bc - dec [hl] - pop de - scf - ret - -; remove first card instance of card ID in e -; and shift all elements up by one -.RemoveCard - ld hl, wCurDeckCards - ld d, 0 ; unnecessary -.loop_1 - inc d ; unnecessary - ld a, [hli] - cp e - jr nz, .loop_1 - ld c, l - ld b, h - dec bc - -.loop_2 - inc d ; unnecessary - ld a, [hli] - or a - jr z, .done - ld [bc], a - inc bc - jr .loop_2 - -.done - xor a - ld [bc], a - ret - -UpdateConfirmationCardScreen: ; 9e31 (2:5e31) - ld hl, hffb0 - ld [hl], $01 - call PrintCurDeckNumberAndName - ld hl, hffb0 - ld [hl], $00 - jp PrintConfirmationCardList - -HandleDeckConfirmationMenu: ; 9e41 (2:5e41) -; if deck is empty, just show deck info header with empty card list - ld a, [wTotalCardCount] - or a - jp z, ShowDeckInfoHeaderAndWaitForBButton - -; create list of all unique cards - call SortCurDeckCardsByID - call CreateCurDeckUniqueCardList - - xor a - ld [wCardListVisibleOffset], a -.init_params - ld hl, .CardSelectionParams - call InitCardSelectionParams - ld a, [wNumUniqueCards] - ld [wNumCardListEntries], a - cp NUM_DECK_CONFIRMATION_VISIBLE_CARDS - jr c, .no_cap - ld a, NUM_DECK_CONFIRMATION_VISIBLE_CARDS -.no_cap - ld [wCardListNumCursorPositions], a - ld [wNumVisibleCardListEntries], a - call ShowConfirmationCardScreen - - ld hl, UpdateConfirmationCardScreen - ld d, h - ld a, l - ld hl, wCardListUpdateFunction - ld [hli], a - ld [hl], d - - xor a - ld [wced2], a -.loop_input - call DoFrame - call HandleDeckCardSelectionList - jr c, .selection_made - call HandleLeftRightInCardList - jr c, .loop_input - ldh a, [hDPadHeld] - and START - jr z, .loop_input - -.selected_card - ld a, $01 - call PlaySFXConfirmOrCancel - ld a, [wCardListCursorPos] - ld [wced7], a - - ; set wOwnedCardsCountList as current card list - ; and show card page screen - ld de, wOwnedCardsCountList - ld hl, wCurCardListPtr - ld [hl], e - inc hl - ld [hl], d - call OpenCardPageFromCardList - jr .init_params - -.selection_made - ld a, [hffb3] - cp $ff - ret z ; operation cancelled - jr .selected_card - -.CardSelectionParams - db 0 ; x pos - db 5 ; y pos - db 2 ; y spacing - db 0 ; x spacing - db 7 ; num entries - db SYM_CURSOR_R ; visible cursor tile - db SYM_SPACE ; invisible cursor tile - dw NULL ; wCardListHandlerFunction - -; handles pressing left/right in card lists -; scrolls up/down a number of wCardListNumCursorPositions -; entries respectively -; returns carry if scrolling happened -HandleLeftRightInCardList: ; 9eb8 (2:5eb8) - ld a, [wCardListNumCursorPositions] - ld d, a - ld a, [wCardListVisibleOffset] - ld c, a - ldh a, [hDPadHeld] - cp D_RIGHT - jr z, .right - cp D_LEFT - jr z, .left - or a - ret - -.right - ld a, [wCardListVisibleOffset] - add d - ld b, a - add d - ld hl, wNumCardListEntries - cp [hl] - jr c, .got_new_pos - ld a, [wNumCardListEntries] - sub d - ld b, a - jr .got_new_pos - -.left - ld a, [wCardListVisibleOffset] - sub d - ld b, a - jr nc, .got_new_pos - ld b, 0 ; first index -.got_new_pos - ld a, b - ld [wCardListVisibleOffset], a - cp c - jr z, .asm_9efa - ld a, SFX_01 - call PlaySFX - ld hl, wCardListUpdateFunction - call CallIndirect -.asm_9efa - scf - ret - -; handles scrolling up and down with Select button -; in this case, the cursor position goes up/down -; by wCardListNumCursorPositions entries respectively -; return carry if scrolling happened, otherwise no carry -HandleSelectUpAndDownInList: ; 9efc (2:5efc) - ld a, [wCardListNumCursorPositions] - ld d, a - ld a, [wCardListVisibleOffset] - ld c, a - ldh a, [hDPadHeld] - cp SELECT | D_DOWN - jr z, .sel_down - cp SELECT | D_UP - jr z, .sel_up - or a - ret - -.sel_down - ld a, [wCardListVisibleOffset] - add d - ld b, a ; wCardListVisibleOffset + wCardListNumCursorPositions - add d - ld hl, wNumCardListEntries - cp [hl] - jr c, .got_new_pos - ld a, [wNumCardListEntries] - sub d - ld b, a ; wNumCardListEntries - wCardListNumCursorPositions - jr .got_new_pos -.sel_up - ld a, [wCardListVisibleOffset] - sub d - ld b, a ; wCardListVisibleOffset - wCardListNumCursorPositions - jr nc, .got_new_pos - ld b, 0 ; go to first position - -.got_new_pos - ld a, b - ld [wCardListVisibleOffset], a - cp c - jr z, .set_carry - ld a, SFX_01 - call PlaySFX - ld hl, wCardListUpdateFunction - call CallIndirect -.set_carry - scf - ret - -; simply draws the deck info header -; then awaits a b button press to exit -ShowDeckInfoHeaderAndWaitForBButton: ; 9f40 (2:5f40) - call ShowDeckInfoHeader -.wait_input - call DoFrame - ldh a, [hKeysPressed] - and B_BUTTON - jr z, .wait_input - ld a, $ff - call PlaySFXConfirmOrCancel - ret - -ShowConfirmationCardScreen: ; 9f52 (2:5f52) - call ShowDeckInfoHeader - lb de, 3, 5 - ld hl, wCardListCoords - ld [hl], e - inc hl - ld [hl], d - call PrintConfirmationCardList - ret - -; counts all values stored in wCardFilterCounts -; if the total count is 0, then -; prints "No cards chosen." -TallyCardsInCardFilterLists: ; 9f62 (2:5f62) - lb bc, 0, 0 - ld hl, wCardFilterCounts -.loop - ld a, [hli] - add b - ld b, a - inc c - ld a, NUM_FILTERS - cp c - jr nz, .loop - ld a, b - or a - ret nz - lb de, 11, 1 - call InitTextPrinting - ldtx hl, NoCardsChosenText - call ProcessTextFromID - ret - -; draws a box on the top of the screen -; with wCurDeck's number, name and card count -; and draws the Hand Cards icon if it's -; the current dueling deck -ShowDeckInfoHeader: ; 9f81 (2:5f81) - call EmptyScreenAndLoadFontDuelAndHandCardsIcons - lb de, 0, 0 - lb bc, 20, 4 - call DrawRegularTextBox - ld a, [wCurDeckName] - or a - jp z, .print_card_count ; can be jr - -; draw hand cards icon if it's the current dueling deck - call PrintCurDeckNumberAndName - ld a, [wCurDeck] - ld b, a - call EnableSRAM - ld a, [sCurrentlySelectedDeck] - call DisableSRAM - cp b - jr nz, .print_card_count - lb de, 2, 1 - call DrawHandCardsTileAtDE - -.print_card_count - lb de, 14, 1 - call PrintTotalCardCount - lb de, 16, 1 - call PrintSlashSixty - call TallyCardsInCardFilterLists - call EnableLCD - ret - -; prints the name of wCurDeck in the form -; "X· <deck name> deck", where X is the number -; of the deck in the given menu -; if no current deck, print blank line -PrintCurDeckNumberAndName: ; 9fc0 (2:5fc0) - ld a, [wCurDeck] - cp $ff - jr z, .skip_deck_numeral - -; print the deck number in the menu -; in the form "X·" - lb de, 3, 2 - call InitTextPrinting - ld a, [wCurDeck] - bit 7, a - jr z, .incr_by_one - and $7f - jr .got_deck_numeral -.incr_by_one - inc a -.got_deck_numeral - ld hl, wDefaultText - call ConvertToNumericalDigits - ld [hl], "FW0_·" - inc hl - ld [hl], TX_END - ld hl, wDefaultText - call ProcessText - -.skip_deck_numeral - ld hl, wCurDeckName - ld de, wDefaultText - call CopyListFromHLToDE - ld a, [wCurDeck] - cp $ff - jr z, .blank_deck_name - -; print "<deck name> deck" - ld hl, wDefaultText - call GetTextLengthInTiles - ld b, $0 - ld hl, wDefaultText - add hl, bc - ld d, h - ld e, l - ld hl, DeckNameSuffix - call CopyListFromHLToDE - lb de, 6, 2 - ld hl, wDefaultText - call InitTextPrinting - call ProcessText - ret - -.blank_deck_name - lb de, 2, 2 - ld hl, wDefaultText - call InitTextPrinting - call ProcessText - ret - -; sorts wCurDeckCards by ID -SortCurDeckCardsByID: ; a028 (2:6028) -; wOpponentDeck is used to temporarily store deck's cards -; so that it can be later sorted by ID - ld hl, wCurDeckCards - ld de, wOpponentDeck - ld bc, wDuelTempList - ld a, -1 - ld [bc], a -.loop_copy - inc a ; incr deck index - push af - ld a, [hli] - ld [de], a - inc de - or a - jr z, .sort_cards - pop af - ld [bc], a ; store deck index - inc bc - jr .loop_copy - -.sort_cards - pop af - ld a, $ff ; terminator byte for wDuelTempList - ld [bc], a - -; force Opp Turn so that SortCardsInDuelTempListByID can be used - ldh a, [hWhoseTurn] - push af - ld a, OPPONENT_TURN - ldh [hWhoseTurn], a - call SortCardsInDuelTempListByID - pop af - ldh [hWhoseTurn], a - -; given the ordered cards in wOpponentDeck, -; each entry in it corresponds to its deck index -; (first ordered card is deck index 0, second is deck index 1, etc) -; place these in this order in wCurDeckCards - ld hl, wCurDeckCards - ld de, wDuelTempList -.loop_order_by_deck_index - ld a, [de] - cp $ff - jr z, .done - ld c, a - ld b, $0 - push hl - ld hl, wOpponentDeck - add hl, bc - ld a, [hl] - pop hl - ld [hli], a - inc de - jr .loop_order_by_deck_index - -.done - xor a - ld [hl], a - ret - -; goes through list in wCurDeckCards, and for each card in it -; creates list in wUniqueDeckCardList of all unique cards -; it finds (assuming wCurDeckCards is sorted by ID) -; also counts the total number of the different cards -CreateCurDeckUniqueCardList: ; a06e (2:606e) - ld b, 0 - ld c, $0 - ld hl, wCurDeckCards - ld de, wUniqueDeckCardList -.loop - ld a, [hli] - cp c - jr z, .loop - ld c, a - ld [de], a - inc de - or a - jr z, .done - inc b - jr .loop -.done - ld a, b - ld [wNumUniqueCards], a - ret - -; prints the list of cards visible in the window -; of the confirmation screen -; card info is presented with name, level and -; its count preceded by "x" -PrintConfirmationCardList: ; a08a (2:608a) - push bc - ld hl, wCardListCoords - ld e, [hl] - inc hl - ld d, [hl] - ld b, 19 ; x coord - ld c, e - dec c - ld a, [wCardListVisibleOffset] - or a - jr z, .no_cursor - ld a, SYM_CURSOR_U - jr .got_cursor_tile_1 -.no_cursor - ld a, SYM_SPACE -.got_cursor_tile_1 - call WriteByteToBGMap0 - -; iterates by decreasing value in wNumVisibleCardListEntries -; by 1 until it reaches 0 - ld a, [wCardListVisibleOffset] - ld c, a - ld b, $0 - ld hl, wOwnedCardsCountList - add hl, bc - ld a, [wNumVisibleCardListEntries] -.loop_cards - push de - or a - jr z, .exit_loop - ld b, a - ld a, [hli] - or a - jr z, .no_more_cards - ld e, a - call AddCardIDToVisibleList - call LoadCardDataToBuffer1_FromCardID - ; places in wDefaultText the card's name and level - ; then appends at the end "x" with the count of that card - ; draws the card's type icon as well - ld a, 13 - push bc - push hl - push de - call CopyCardNameAndLevel - pop de - call .PrintCardCount - pop hl - pop bc - pop de - call .DrawCardTypeIcon - push hl - call InitTextPrinting - ld hl, wDefaultText - call ProcessText - pop hl - ld a, b - dec a - inc e - inc e - jr .loop_cards - -.exit_loop - ld a, [hli] - or a - jr z, .no_more_cards - pop de - xor a ; FALSE - ld [wUnableToScrollDown], a - ld a, SYM_CURSOR_D - jr .got_cursor_tile_2 - -.no_more_cards - pop de - ld a, TRUE - ld [wUnableToScrollDown], a - ld a, SYM_SPACE -.got_cursor_tile_2 - ld b, 19 ; x coord - ld c, e - dec c - dec c - call WriteByteToBGMap0 - pop bc - ret - -; prints the card count preceded by a cross -; for example "x42" -.PrintCardCount - push af - push bc - push de - push hl -.loop_search - ld a, [hl] - or a - jr z, .found_card_id - inc hl - jr .loop_search -.found_card_id - call GetCountOfCardInCurDeck - ld [hl], TX_SYMBOL - inc hl - ld [hl], SYM_CROSS - inc hl - call ConvertToNumericalDigits - ld [hl], TX_END - pop hl - pop de - pop bc - pop af - ret - -; draws the icon corresponding to the loaded card's type -; can be any of Pokemon stages (basic, 1st and 2nd stage) -; Energy or Trainer -; draws it 2 tiles to the left and 1 up to -; the current coordinate in de -.DrawCardTypeIcon - push hl - push de - push bc - ld a, [wLoadedCard1Type] - cp TYPE_ENERGY - jr nc, .not_pkmn_card - -; pokemon card - ld a, [wLoadedCard1Stage] - ld b, a - add b - add b - add b ; *4 - add ICON_TILE_BASIC_POKEMON - jr .got_tile - -.not_pkmn_card - cp TYPE_TRAINER - jr nc, .trainer_card - -; energy card - sub TYPE_ENERGY - ld b, a - add b - add b - add b ; *4 - add ICON_TILE_FIRE - jr .got_tile - -.trainer_card - ld a, ICON_TILE_TRAINER -.got_tile - dec d - dec d - dec e - push af - lb hl, 1, 2 - lb bc, 2, 2 - call FillRectangle - pop af - - call GetCardTypeIconPalette - ld b, a - ld a, [wConsole] - cp CONSOLE_CGB - jr nz, .skip_pal - ld a, b - lb bc, 2, 2 - lb hl, 0, 0 - call BankswitchVRAM1 - call FillRectangle - call BankswitchVRAM0 -.skip_pal - pop bc - pop de - pop hl - ret - -; returns in a the BG Pal corresponding to the -; card type icon in input register a -; if not found, returns $00 -GetCardTypeIconPalette: ; a173 (2:6173) - push bc - push hl - ld b, a - ld hl, .CardTypeIconPalettes -.loop - ld a, [hli] - or a - jr z, .done - cp b - jr z, .done - inc hl - jp .loop ; can be jr -.done - ld a, [hl] - pop hl - pop bc - ret - -.CardTypeIconPalettes -; icon tile, BG pal - db ICON_TILE_FIRE, 1 - db ICON_TILE_GRASS, 2 - db ICON_TILE_LIGHTNING, 1 - db ICON_TILE_WATER, 2 - db ICON_TILE_FIGHTING, 3 - db ICON_TILE_PSYCHIC, 3 - db ICON_TILE_COLORLESS, 0 - db ICON_TILE_ENERGY, 2 - db ICON_TILE_BASIC_POKEMON, 2 - db ICON_TILE_STAGE_1_POKEMON, 2 - db ICON_TILE_STAGE_2_POKEMON, 1 - db ICON_TILE_TRAINER, 2 - db $00, $ff - -; inits WRAM vars to start creating deck configuration to send -PrepareToBuildDeckConfigurationToSend: ; a1a2 (2:61a2) - ld hl, wCurDeckCards - ld a, wCurDeckCardsEnd - wCurDeckCards - call ClearNBytesFromHL - ld a, $ff - ld [wCurDeck], a - ld hl, .text - ld de, wCurDeckName - call CopyListFromHLToDE - ld hl, .DeckConfigurationParams - call InitDeckBuildingParams - call HandleDeckBuildScreen - ret - -.text - text "Cards chosen to send" - done - -.DeckConfigurationParams - db DECK_SIZE ; max number of cards - db 60 ; max number of same name cards - db FALSE ; whether to include deck cards - dw HandleSendDeckConfigurationMenu - dw SendDeckConfigurationMenu_TransitionTable - -SendDeckConfigurationMenu_TransitionTable: ; a1df (2:61df) - cursor_transition $10, $20, $00, $00, $00, $01, $02 - cursor_transition $48, $20, $00, $01, $01, $02, $00 - cursor_transition $80, $20, $00, $02, $02, $00, $01 - -SendDeckConfigurationMenuData: ; a1f4 (2:61f4) - textitem 2, 2, ConfirmText - textitem 9, 2, SendText - textitem 16, 2, CancelText - db $ff - -HandleSendDeckConfigurationMenu: ; a201 (2:6201) - ld de, $0 - lb bc, 20, 6 - call DrawRegularTextBox - ld hl, SendDeckConfigurationMenuData - call PlaceTextItems - ld a, $ff - ld [wDuelInitialPrizesUpperBitsSet], a -.loop_input - ld a, $01 - ld [wVBlankOAMCopyToggle], a - call DoFrame - call YourOrOppPlayAreaScreen_HandleInput - jr nc, .loop_input - ld [wced6], a - cp $ff - jr nz, .asm_a23b - call DrawCardTypeIconsAndPrintCardCounts - ld a, [wTempCardListCursorPos] - ld [wCardListCursorPos], a - ld a, [wCurCardTypeFilter] - call PrintFilteredCardList - jp HandleDeckBuildScreen.skip_draw -.asm_a23b - ld hl, .func_table - call JumpToFunctionInTable - jp OpenDeckConfigurationMenu.skip_init - -.func_table - dw ConfirmDeckConfiguration ; Confirm - dw .SendDeckConfiguration ; Send - dw .CancelSendDeckConfiguration ; Cancel - -.SendDeckConfiguration - ld a, [wCurDeckCards] - or a - jr z, .CancelSendDeckConfiguration - xor a - ld [wCardListVisibleOffset], a - ld hl, Data_b04a - call InitCardSelectionParams - ld hl, wCurDeckCards - ld de, wDuelTempList - call CopyListFromHLToDE - call PrintCardToSendText - call Func_b088 - call EnableLCD - ldtx hl, SendTheseCardsText - call YesOrNoMenuWithText - jr nc, .asm_a279 - add sp, $2 - jp HandleDeckBuildScreen.skip_count -.asm_a279 - add sp, $2 - scf - ret - -.CancelSendDeckConfiguration - add sp, $2 - or a - ret - -; copies b bytes from hl to de -CopyNBytesFromHLToDE: ; a281 (2:6281) - ld a, [hli] - ld [de], a - inc de - dec b - jr nz, CopyNBytesFromHLToDE - ret - -; handles the screen showing all the player's cards -HandlePlayersCardsScreen: ; a288 (2:6288) - call WriteCardListsTerminatorBytes - call PrintPlayersCardsHeaderInfo - xor a - ld [wCardListVisibleOffset], a - ld [wCurCardTypeFilter], a - call PrintFilteredCardSelectionList - call EnableLCD - xor a - ld hl, FiltersCardSelectionParams - call InitCardSelectionParams -.wait_input - call DoFrame - ld a, [wCurCardTypeFilter] - ld b, a - ld a, [wTempCardTypeFilter] - cp b - jr z, .check_d_down - ld [wCurCardTypeFilter], a - ld hl, wCardListVisibleOffset - ld [hl], $00 - call PrintFilteredCardSelectionList - - ld hl, hffb0 - ld [hl], $01 - call PrintPlayersCardsText - ld hl, hffb0 - ld [hl], $00 - - ld a, NUM_FILTERS - ld [wCardListNumCursorPositions], a -.check_d_down - ldh a, [hDPadHeld] - and D_DOWN - jr z, .no_d_down - call ConfirmSelectionAndReturnCarry - jr .jump_to_list - -.no_d_down - call HandleCardSelectionInput - jr nc, .wait_input - ld a, [hffb3] - cp $ff ; operation cancelled - jr nz, .jump_to_list - ret - -.jump_to_list - ld a, [wNumEntriesInCurFilter] - or a - jr z, .wait_input - - xor a - ld hl, Data_a396 - call InitCardSelectionParams - ld a, [wNumEntriesInCurFilter] - ld [wNumCardListEntries], a - ld hl, wNumVisibleCardListEntries - cp [hl] - jr nc, .asm_a300 - ld [wCardListNumCursorPositions], a -.asm_a300 - ld hl, PrintCardSelectionList - ld d, h - ld a, l - ld hl, wCardListUpdateFunction - ld [hli], a - ld [hl], d - xor a - ld [wced2], a - -.loop_input - call DoFrame - call HandleSelectUpAndDownInList - jr c, .loop_input - call HandleDeckCardSelectionList - jr c, .asm_a36a - ldh a, [hDPadHeld] - and START - jr z, .loop_input - ; start btn pressed - -.open_card_page - ld a, $01 - call PlaySFXConfirmOrCancel - ld a, [wCardListNumCursorPositions] - ld [wTempCardListNumCursorPositions], a - ld a, [wCardListCursorPos] - ld [wTempCardListCursorPos], a - - ; set wFilteredCardList as current card list - ; and show card page screen - ld de, wFilteredCardList - ld hl, wCurCardListPtr - ld [hl], e - inc hl - ld [hl], d - call OpenCardPageFromCardList - call PrintPlayersCardsHeaderInfo - - ld hl, FiltersCardSelectionParams - call InitCardSelectionParams - ld a, [wCurCardTypeFilter] - ld [wTempCardTypeFilter], a - call DrawHorizontalListCursor_Visible - call PrintCardSelectionList - call EnableLCD - ld hl, Data_a396 - call InitCardSelectionParams - ld a, [wTempCardListNumCursorPositions] - ld [wCardListNumCursorPositions], a - ld a, [wTempCardListCursorPos] - ld [wCardListCursorPos], a - jr .loop_input - -.asm_a36a - call DrawListCursor_Invisible - ld a, [wCardListCursorPos] - ld [wTempCardListCursorPos], a - ld a, [hffb3] - cp $ff - jr nz, .open_card_page - ld hl, FiltersCardSelectionParams - call InitCardSelectionParams - ld a, [wCurCardTypeFilter] - ld [wTempCardTypeFilter], a - ld hl, hffb0 - ld [hl], $01 - call PrintPlayersCardsText - ld hl, hffb0 - ld [hl], $00 - jp .wait_input - -Data_a396: ; a396 (2:6396) - db 1 ; x pos - db 5 ; y pos - db 2 ; y spacing - db 0 ; x spacing - db 7 ; num entries - db SYM_CURSOR_R ; visible cursor tile - db SYM_SPACE ; invisible cursor tile - dw NULL ; wCardListHandlerFunction - -; a = which card type filter -PrintFilteredCardSelectionList: ; a39f (2:639f) - push af - ld hl, CardTypeFilters - ld b, $00 - ld c, a - add hl, bc - ld a, [hl] - push af - ld a, ALL_DECKS - call CreateCardCollectionListWithDeckCards - pop af - call CreateFilteredCardList - - ld a, NUM_DECK_CONFIRMATION_VISIBLE_CARDS - ld [wNumVisibleCardListEntries], a - lb de, 2, 5 - ld hl, wCardListCoords - ld [hl], e - inc hl - ld [hl], d - ld a, SYM_SPACE - ld [wCursorAlternateTile], a - call PrintCardSelectionList - pop af - ret - -; outputs in wTempCardCollection all the cards in sCardCollection -; plus the cards that are being used in built decks -; a = DECK_* flags for which decks to include in the collection -CreateCardCollectionListWithDeckCards: ; a3ca (2:63ca) - ld [hffb5], a -; copies sCardCollection to wTempCardCollection - ld hl, sCardCollection - ld de, wTempCardCollection - ld b, CARD_COLLECTION_SIZE - 1 - call EnableSRAM - call CopyNBytesFromHLToDE - call DisableSRAM - -; deck_1 - ld a, [hffb5] ; should be ldh - bit DECK_1_F, a - jr z, .deck_2 - ld de, sDeck1Cards - call IncrementDeckCardsInTempCollection -.deck_2 - ld a, [hffb5] ; should be ldh - bit DECK_2_F, a - jr z, .deck_3 - ld de, sDeck2Cards - call IncrementDeckCardsInTempCollection -.deck_3 - ld a, [hffb5] ; should be ldh - bit DECK_3_F, a - jr z, .deck_4 - ld de, sDeck3Cards - call IncrementDeckCardsInTempCollection -.deck_4 - ld a, [hffb5] ; should be ldh - bit DECK_4_F, a - ret z - ld de, sDeck4Cards - call IncrementDeckCardsInTempCollection - ret - -; goes through cards in deck in de -; and for each card ID, increments its corresponding -; entry in wTempCardCollection -IncrementDeckCardsInTempCollection: ; a412 (2:6412) - call EnableSRAM - ld bc, wTempCardCollection - ld h, DECK_SIZE -.loop - ld a, [de] - inc de - or a - jr z, .done - push hl - ld h, $0 - ld l, a - add hl, bc - inc [hl] - pop hl - dec h - jr nz, .loop -.done - call DisableSRAM - ret - -; prints the name, level and storage count of the cards -; that are visible in the list window -; in the form: -; CARD NAME/LEVEL X -; where X is the current count of that card -PrintCardSelectionList: ; a42d (2:642d) - push bc - ld hl, wCardListCoords - ld e, [hl] - inc hl - ld d, [hl] - ld b, 19 ; x coord - ld c, e - ld a, [wCardListVisibleOffset] - or a - jr z, .alternate_cursor_tile - ld a, SYM_CURSOR_U - jr .got_cursor_tile_1 -.alternate_cursor_tile - ld a, [wCursorAlternateTile] -.got_cursor_tile_1 - call WriteByteToBGMap0 - -; iterates by decreasing value in wNumVisibleCardListEntries -; by 1 until it reaches 0 - ld a, [wCardListVisibleOffset] - ld c, a - ld b, $0 - ld hl, wFilteredCardList - add hl, bc - ld a, [wNumVisibleCardListEntries] -.loop_filtered_cards - push de - or a - jr z, .exit_loop - ld b, a - ld a, [hli] - or a - jr z, .invalid_card ; card ID of 0 - ld e, a - call AddCardIDToVisibleList - call LoadCardDataToBuffer1_FromCardID - ; places in wDefaultText the card's name and level - ; then appends at the end the count of that card - ; in the card storage - ld a, 14 - push bc - push hl - push de - call CopyCardNameAndLevel - pop de - call AppendOwnedCardCountNumber - pop hl - pop bc - pop de - push hl - call InitTextPrinting - ld hl, wDefaultText - jr .process_text -.invalid_card - pop de - push hl - call InitTextPrinting - ld hl, Text_9a36 -.process_text - call ProcessText - pop hl - - ld a, b - dec a - inc e - inc e - jr .loop_filtered_cards - -.exit_loop - ld a, [hli] - or a - jr z, .cannot_scroll - pop de -; draw down cursor because -; there are still more cards -; to be scrolled down - xor a ; FALSE - ld [wUnableToScrollDown], a - ld a, SYM_CURSOR_D - jr .got_cursor_tile_2 -.cannot_scroll - pop de - ld a, TRUE - ld [wUnableToScrollDown], a - ld a, [wCursorAlternateTile] -.got_cursor_tile_2 - ld b, 19 ; x coord - ld c, e - dec c - dec c - call WriteByteToBGMap0 - pop bc - ret - -; appends the card count given in register e -; to the list in hl, in numerical form -; (i.e. its numeric symbol representation) -AppendOwnedCardCountNumber: ; a4ae (2:64ae) - push af - push bc - push de - push hl -; increment hl until end is reached ($00 byte) -.loop - ld a, [hl] - or a - jr z, .end - inc hl - jr .loop -.end - call GetOwnedCardCount - call ConvertToNumericalDigits - ld [hl], $00 ; insert byte terminator - pop hl - pop de - pop bc - pop af - ret - -; print header info (card count and player name) -PrintPlayersCardsHeaderInfo: ; a4c6 (2:64c6) - call Set_OBJ_8x8 - call Func_8d78 -.skip_empty_screen - lb bc, 0, 4 - ld a, SYM_BOX_TOP - call FillBGMapLineWithA - call PrintTotalNumberOfCardsInCollection - call PrintPlayersCardsText - call DrawCardTypeIcons - ret - -; prints "<PLAYER>'s cards" -PrintPlayersCardsText: ; a4de (2:64de) - lb de, 1, 0 - call InitTextPrinting - ld de, wDefaultText - call CopyPlayerName - ld hl, wDefaultText - call ProcessText - ld hl, wDefaultText - call GetTextLengthInTiles - inc b - ld d, b - ld e, 0 - call InitTextPrinting - ldtx hl, SCardsText - call ProcessTextFromID - ret - -PrintTotalNumberOfCardsInCollection: ; a504 (2:6504) - ld a, ALL_DECKS - call CreateCardCollectionListWithDeckCards - -; count all the cards in collection - ld de, wTempCardCollection + 1 - ld b, 0 - ld hl, 0 -.loop_all_cards - ld a, [de] - inc de - and $7f - push bc - ld b, $00 - ld c, a - add hl, bc - pop bc - inc b - ld a, NUM_CARDS - cp b - jr nz, .loop_all_cards - -; hl = total number of cards in collection - call .GetTotalCountDigits - ld hl, wTempCardCollection - ld de, wOnesAndTensPlace - ld b, $00 - call .PlaceNumericalChar - call .PlaceNumericalChar - call .PlaceNumericalChar - call .PlaceNumericalChar - call .PlaceNumericalChar - ld a, $07 - ld [hli], a - ld [hl], TX_END - lb de, 13, 0 - call InitTextPrinting - ld hl, wTempCardCollection - call ProcessText - ret - -; places a numerical character in hl from de -; doesn't place a 0 if no non-0 -; numerical character has been placed before -; this makes it so that there are no -; 0s in more significant digits -.PlaceNumericalChar - ld [hl], TX_SYMBOL - inc hl - ld a, b - or a - jr z, .leading_num - ld a, [de] - inc de - ld [hli], a - ret -.leading_num -; don't place a 0 as a leading number - ld a, [de] - inc de - cp SYM_0 - jr z, .space_char - ld [hli], a - ld b, $01 ; at least one non-0 char was placed - ret -.space_char - xor a ; SYM_SPACE - ld [hli], a - ret - -; gets the digits in decimal form -; of value stored in hl -; stores the result in wOnesAndTensPlace -.GetTotalCountDigits - ld de, wOnesAndTensPlace - ld bc, -10000 - call .GetDigit - ld bc, -1000 - call .GetDigit - ld bc, -100 - call .GetDigit - ld bc, -10 - call .GetDigit - ld bc, -1 - call .GetDigit - ret - -.GetDigit - ld a, SYM_0 - 1 -.loop - inc a - add hl, bc - jr c, .loop - ld [de], a - inc de - ld a, l - sub c - ld l, a - ld a, h - sbc b - ld h, a - ret - -; fills wFilteredCardList and wOwnedCardsCountList -; with cards IDs and counts, respectively, -; from given Card Set in register a -; a = CARD_SET_* constant -CreateCardSetList: ; a596 (2:6596) - push af - ld a, DECK_SIZE - ld hl, wFilteredCardList - call ClearNBytesFromHL - ld a, DECK_SIZE - ld hl, wOwnedCardsCountList - call ClearNBytesFromHL - xor a - ld [wOwnedPhantomCardFlags], a - pop af - - ld hl, 0 - lb de, 0, 0 - ld b, a -.loop_all_cards - inc e - call LoadCardDataToBuffer1_FromCardID - jr c, .done_pkmn_cards - ld a, [wLoadedCard1Set] - and $f0 ; set 1 - swap a - cp b - jr nz, .loop_all_cards - -; it's same set as input - ld a, e - cp VENUSAUR1 - jp z, .SetVenusaur1OwnedFlag - cp MEW2 - jp z, .SetMew2OwnedFlag - - push bc - push hl - ld bc, wFilteredCardList - add hl, bc - ld [hl], e ; card ID - - ld hl, wTempCardCollection - add hl, de - ld a, [hl] - pop hl - push hl - ld bc, wOwnedCardsCountList - add hl, bc - ld [hl], a ; card count in collection - pop hl - - inc l - pop bc - jr .loop_all_cards - -.done_pkmn_cards -; for the energy cards, put all basic energy cards in Colosseum -; and Double Colorless energy in Mystery - ld a, b - cp CARD_SET_MYSTERY - jr z, .mystery - or a - jr nz, .skip_energy_cards - -; colosseum -; places all basic energy cards in wFilteredCardList - lb de, 0, 0 -.loop_basic_energy_cards - inc e - ld a, e - cp DOUBLE_COLORLESS_ENERGY - jr z, .skip_energy_cards - push bc - push hl - ld bc, wFilteredCardList - add hl, bc - ld [hl], e - ld hl, wTempCardCollection - add hl, de - ld a, [hl] - pop hl - push hl - ld bc, wOwnedCardsCountList - add hl, bc - ld [hl], a - pop hl - inc l - pop bc - jr .loop_basic_energy_cards - -.mystery -; places double colorless energy card in wFilteredCardList - lb de, 0, 0 -.loop_find_double_colorless - inc e - ld a, e - cp BULBASAUR - jr z, .skip_energy_cards - cp DOUBLE_COLORLESS_ENERGY - jr nz, .loop_find_double_colorless - ; double colorless energy - push bc - push hl - ld bc, wFilteredCardList - add hl, bc - ld [hl], e - ld hl, wTempCardCollection - add hl, de - ld a, [hl] - pop hl - push hl - ld bc, wOwnedCardsCountList - add hl, bc - ld [hl], a - pop hl - inc l - pop bc - jr .loop_find_double_colorless - -.skip_energy_cards - ld a, [wOwnedPhantomCardFlags] - bit VENUSAUR_OWNED_PHANTOM_F, a - jr z, .check_mew - call .PlaceVenusaur1InList -.check_mew - bit MEW_OWNED_PHANTOM_F, a - jr z, .find_first_owned - call .PlaceMew2InList - -.find_first_owned - dec l - ld c, l - ld b, h -.loop_owned_cards - ld hl, wOwnedCardsCountList - add hl, bc - ld a, [hl] - cp CARD_NOT_OWNED - jr nz, .found_owned - dec c - jr .loop_owned_cards - -.found_owned - inc c - ld a, c - ld [wNumEntriesInCurFilter], a - xor a - ld hl, wFilteredCardList - add hl, bc - ld [hl], a - ld a, $ff ; terminator byte - ld hl, wOwnedCardsCountList - add hl, bc - ld [hl], a - ret - -.SetMew2OwnedFlag - ld a, (1 << MEW_OWNED_PHANTOM_F) -; fallthrough - -.SetPhantomOwnedFlag - push hl - push bc - ld b, a - ld hl, wTempCardCollection - add hl, de - ld a, [hl] - cp CARD_NOT_OWNED - jr z, .skip_set_flag - ld a, [wOwnedPhantomCardFlags] - or b - ld [wOwnedPhantomCardFlags], a -.skip_set_flag - pop bc - pop hl - jp .loop_all_cards - -.SetVenusaur1OwnedFlag - ld a, (1 << VENUSAUR_OWNED_PHANTOM_F) - jr .SetPhantomOwnedFlag - -.PlaceVenusaur1InList - push af - push hl - ld e, VENUSAUR1 -; fallthrough - -; places card in register e directly in the list -.PlaceCardInList - ld bc, wFilteredCardList - add hl, bc - ld [hl], e - pop hl - push hl - ld bc, wOwnedCardsCountList - add hl, bc - ld [hl], $01 - pop hl - inc l - pop af - ret - -.PlaceMew2InList - push af - push hl - ld e, MEW2 - jr .PlaceCardInList - -; a = CARD_SET_* constant -CreateCardSetListAndInitListCoords: ; a6a0 (2:66a0) - push af - ld hl, sCardCollection - ld de, wTempCardCollection - ld b, CARD_COLLECTION_SIZE - 1 - call EnableSRAM - call CopyNBytesFromHLToDE - call DisableSRAM - pop af - - push af - call .GetEntryPrefix - call CreateCardSetList - ld a, NUM_CARD_ALBUM_VISIBLE_CARDS - ld [wNumVisibleCardListEntries], a - lb de, 2, 4 - ld hl, wCardListCoords - ld [hl], e - inc hl - ld [hl], d - pop af - ret - -; places in entry name the prefix associated with the selected Card Set -; a = CARD_SET_* constant -.GetEntryPrefix - push af - cp CARD_SET_PROMOTIONAL - jr nz, .laboratory - lb de, 3, "FW3_P" - jr .got_prefix -.laboratory - cp CARD_SET_LABORATORY - jr nz, .mystery - lb de, 3, "FW3_D" - jr .got_prefix -.mystery - cp CARD_SET_MYSTERY - jr nz, .evolution - lb de, 3, "FW3_C" - jr .got_prefix -.evolution - cp CARD_SET_EVOLUTION - jr nz, .colosseum - lb de, 3, "FW3_B" - jr .got_prefix -.colosseum - lb de, 3, "FW3_A" - -.got_prefix - ld hl, wCurDeckName - ld [hl], d - inc hl - ld [hl], e - pop af - ret - -; prints the cards being shown in the Card Album screen -; for the corresponding Card Set -PrintCardSetListEntries: ; a6fa (2:66fa) - push bc - ld hl, wCardListCoords - ld e, [hl] - inc hl - ld d, [hl] - ld b, $13 - ld c, e - dec c - dec c - -; draw up cursor on top right - ld a, [wCardListVisibleOffset] - or a - jr z, .no_up_cursor - ld a, SYM_CURSOR_U - jr .got_up_cursor_tile -.no_up_cursor - ld a, SYM_BOX_TOP_R -.got_up_cursor_tile - call WriteByteToBGMap0 - - ld a, [wCardListVisibleOffset] - ld l, a - ld h, $00 - ld a, [wNumVisibleCardListEntries] -.loop_visible_cards - push de - or a - jr z, .handle_down_cursor - ld b, a - ld de, wFilteredCardList - push hl - add hl, de - ld a, [hl] - pop hl - inc l - or a - jr z, .no_down_cursor - ld e, a - call AddCardIDToVisibleList - call LoadCardDataToBuffer1_FromCardID - push bc - push hl - ld de, wOwnedCardsCountList - add hl, de - dec hl - ld a, [hl] - cp CARD_NOT_OWNED - jr nz, .owned - ld hl, .EmptySlotText - ld de, wDefaultText - call CopyListFromHLToDE - jr .print_text -.owned - ld a, 13 - call CopyCardNameAndLevel -.print_text - pop hl - pop bc - pop de - push hl - call InitTextPrinting - pop hl - push hl - call .AppendCardListIndex - call ProcessText - ld hl, wDefaultText - jr .asm_a76d - - ; this code is never reached - pop de - push hl - call InitTextPrinting - ld hl, Text_9a36 - -.asm_a76d - call ProcessText - pop hl - ld a, b - dec a - inc e - inc e - jr .loop_visible_cards - -.handle_down_cursor - ld de, wFilteredCardList - add hl, de - ld a, [hl] - or a - jr z, .no_down_cursor - pop de - xor a ; FALSE - ld [wUnableToScrollDown], a - ld a, SYM_CURSOR_D - jr .got_down_cursor_tile -.no_down_cursor - pop de - ld a, TRUE - ld [wUnableToScrollDown], a - ld a, SYM_BOX_BTM_R -.got_down_cursor_tile - ld b, 19 - ld c, 17 - call WriteByteToBGMap0 - pop bc - ret - -.EmptySlotText - textfw0 "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-" - done - -; gets the index in the card list and adds it to wCurDeckName -.AppendCardListIndex - push bc - push de - ld de, wFilteredCardList - add hl, de - dec hl - ld a, [hl] - cp DOUBLE_COLORLESS_ENERGY + 1 - jr c, .energy_card - cp VENUSAUR1 - jr z, .phantom_card - cp MEW2 - jr z, .phantom_card - - ld a, [wNumVisibleCardListEntries] - sub b - ld hl, wCardListVisibleOffset - add [hl] - inc a - call CalculateOnesAndTensDigits - ld hl, wOnesAndTensPlace - ld a, [hli] - ld b, a - ld a, [hl] - or a - jr nz, .got_index - ld a, SYM_0 -.got_index - ld hl, wCurDeckName + 2 ; skip prefix - ld [hl], TX_SYMBOL - inc hl - ld [hli], a ; tens place - ld [hl], TX_SYMBOL - inc hl - ld a, b - ld [hli], a ; ones place - ld [hl], TX_SYMBOL - inc hl - xor a ; SYM_SPACE - ld [hli], a - ld [hl], a - ld hl, wCurDeckName - pop de - pop bc - ret - -.energy_card - call CalculateOnesAndTensDigits - ld hl, wOnesAndTensPlace - ld a, [hli] - ld b, a - ld hl, wCurDeckName + 2 - lb de, 3, "FW3_E" - ld [hl], d - inc hl - ld [hl], e - inc hl - ld [hl], TX_SYMBOL - inc hl - ld a, SYM_0 - ld [hli], a - ld [hl], TX_SYMBOL - inc hl - ld a, b - ld [hli], a - ld [hl], TX_SYMBOL - inc hl - xor a ; SYM_SPACE - ld [hli], a - ld [hl], a - ld hl, wCurDeckName + 2 - pop de - pop bc - ret - -.phantom_card -; phantom cards get only "✕✕" in their index number - ld hl, wCurDeckName + 2 - ld [hl], "FW0_✕" - inc hl - ld [hl], "FW0_✕" - inc hl - ld [hl], TX_SYMBOL - inc hl - xor a ; SYM_SPACE - ld [hli], a - ld [hl], a - ld hl, wCurDeckName - pop de - pop bc - ret - -; handles opening card page, and inputs when inside Card Album -HandleCardAlbumCardPage: ; a828 (2:6828) - ld a, [wCardListCursorPos] - ld b, a - ld a, [wCardListVisibleOffset] - add b - ld c, a - ld b, $00 - ld hl, wOwnedCardsCountList - add hl, bc - ld a, [hl] - cp CARD_NOT_OWNED - jr z, .handle_input - - ld hl, wCurCardListPtr - ld a, [hli] - ld h, [hl] - ld l, a - add hl, bc - ld e, [hl] - ld d, $00 - push de - call LoadCardDataToBuffer1_FromCardID - lb de, $38, $9f - call SetupText - bank1call OpenCardPage_FromCheckHandOrDiscardPile - pop de - -.handle_input - ldh a, [hDPadHeld] - ld b, a - and A_BUTTON | B_BUTTON | SELECT | START - jp nz, .exit - xor a ; FALSE - ld [wPlaysSfx], a - ld a, [wCardListNumCursorPositions] - ld c, a - ld a, [wCardListCursorPos] - bit D_UP_F, b - jr z, .check_d_down - - push af - ld a, TRUE - ld [wPlaysSfx], a - ld a, [wCardListCursorPos] - ld hl, wCardListVisibleOffset - add [hl] - ld hl, wFirstOwnedCardIndex - cp [hl] - jr z, .open_card_page_pop_af_2 - pop af - - dec a - bit 7, a - jr z, .got_new_pos - ld a, [wCardListVisibleOffset] - or a - jr z, .open_card_page - dec a - ld [wCardListVisibleOffset], a - xor a - jr .got_new_pos - -.check_d_down - bit D_DOWN_F, b - jr z, .asm_a8d6 - - push af - ld a, TRUE - ld [wPlaysSfx], a - pop af - - inc a - cp c - jr c, .got_new_pos - push af - ld hl, wCurCardListPtr - ld a, [hli] - ld h, [hl] - ld l, a - ld a, [wCardListCursorPos] - ld c, a - ld b, $00 - add hl, bc - ld a, [wCardListVisibleOffset] - inc a - ld c, a - ld b, $00 - add hl, bc - ld a, [hl] - or a - jr z, .open_card_page_pop_af_1 - ld a, [wCardListVisibleOffset] - inc a - ld [wCardListVisibleOffset], a - pop af - dec a -.got_new_pos - ; loop back to the start - ld [wCardListCursorPos], a - ld a, [wPlaysSfx] - or a - jp z, HandleCardAlbumCardPage - call PlaySFX - jp HandleCardAlbumCardPage -.open_card_page_pop_af_1 - pop af - jr .open_card_page - -.asm_a8d6 - ld a, [wced2] - or a - jr z, .open_card_page - bit D_LEFT_F, b - jr z, .check_d_right - call RemoveCardFromDeck - jr .open_card_page -.check_d_right - bit D_RIGHT_F, b - jr z, .open_card_page - call TryAddCardToDeck - -.open_card_page_pop_af_2 - pop af -.open_card_page - push de - bank1call OpenCardPage.input_loop - pop de - jp .handle_input - -.exit - ld a, $01 - ld [wVBlankOAMCopyToggle], a - ld a, [wCardListCursorPos] - ld [wTempCardListCursorPos], a - ret - -GetFirstOwnedCardIndex: ; a901 (2:6901) - ld hl, wOwnedCardsCountList - ld b, 0 -.loop_cards - ld a, [hli] - cp CARD_NOT_OWNED - jr nz, .owned - inc b - jr .loop_cards -.owned - ld a, b - ld [wFirstOwnedCardIndex], a - ret - -HandleCardAlbumScreen: ; a913 (2:6913) - ld a, $01 - ld [hffb4], a ; should be ldh - - xor a -.album_card_list - ld hl, .MenuParameters - call InitializeMenuParameters - call .DrawCardAlbumScreen -.loop_input_1 - call DoFrame - call HandleMenuInput - jp nc, .loop_input_1 ; can be jr - ldh a, [hCurMenuItem] - cp $ff - ret z - - ; ignore input if this Card Set is unavailable - ld c, a - ld b, $0 - ld hl, wUnavailableAlbumCardSets - add hl, bc - ld a, [hl] - or a - jr nz, .loop_input_1 - - ld a, c - ld [wSelectedCardSet], a - call CreateCardSetListAndInitListCoords - call .PrintCardCount - xor a - ld [wCardListVisibleOffset], a - call PrintCardSetListEntries - call EnableLCD - ld a, [wNumEntriesInCurFilter] - or a - jr nz, .asm_a968 - -.loop_input_2 - call DoFrame - ldh a, [hKeysPressed] - and B_BUTTON - jr z, .loop_input_2 - ld a, $ff - call PlaySFXConfirmOrCancel - ldh a, [hCurMenuItem] - jp .album_card_list - -.asm_a968 - call .GetNumCardEntries - xor a - ld hl, .CardSelectionParams - call InitCardSelectionParams - ld a, [wNumEntriesInCurFilter] - ld hl, wNumVisibleCardListEntries - cp [hl] - jr nc, .asm_a97e - ld [wCardListNumCursorPositions], a -.asm_a97e - ld hl, PrintCardSetListEntries - ld d, h - ld a, l - ld hl, wCardListUpdateFunction - ld [hli], a - ld [hl], d - - xor a - ld [wced2], a -.loop_input_3 - call DoFrame - call HandleDeckCardSelectionList - jr c, .selection_made - call HandleLeftRightInCardList - jr c, .loop_input_3 - ldh a, [hDPadHeld] - and START - jr z, .loop_input_3 -.open_card_page - ld a, $01 - call PlaySFXConfirmOrCancel - ld a, [wCardListNumCursorPositions] - ld [wTempCardListNumCursorPositions], a - ld a, [wCardListCursorPos] - ld [wTempCardListCursorPos], a - ld c, a - ld a, [wCardListVisibleOffset] - add c - ld hl, wOwnedCardsCountList - ld c, a - ld b, $00 - add hl, bc - ld a, [hl] - cp CARD_NOT_OWNED - jr z, .loop_input_3 - - ; set wFilteredCardList as current card list - ld de, wFilteredCardList - ld hl, wCurCardListPtr - ld [hl], e - inc hl - ld [hl], d - - call GetFirstOwnedCardIndex - call HandleCardAlbumCardPage - call .PrintCardCount - call PrintCardSetListEntries - call EnableLCD - ld hl, .CardSelectionParams - call InitCardSelectionParams - ld a, [wTempCardListNumCursorPositions] - ld [wCardListNumCursorPositions], a - ld a, [wTempCardListCursorPos] - ld [wCardListCursorPos], a - jr .loop_input_3 - -.selection_made - call DrawListCursor_Invisible - ld a, [wCardListCursorPos] - ld [wTempCardListCursorPos], a - ld a, [hffb3] - cp $ff - jr nz, .open_card_page - ldh a, [hCurMenuItem] - jp .album_card_list - -.MenuParameters - db 3, 3 ; cursor x, cursor y - db 2 ; y displacement between items - db 5 ; number of items - db SYM_CURSOR_R ; cursor tile number - db SYM_SPACE ; tile behind cursor - dw NULL ; function pointer if non-0 - -.CardSelectionParams - db 1 ; x pos - db 4 ; y pos - db 2 ; y spacing - db 0 ; x spacing - db NUM_CARD_ALBUM_VISIBLE_CARDS ; num entries - db SYM_CURSOR_R ; visible cursor tile - db SYM_SPACE ; invisible cursor tile - dw NULL ; wCardListHandlerFunction - -.GetNumCardEntries - ld hl, wFilteredCardList - ld b, $00 -.loop_card_ids - ld a, [hli] - or a - jr z, .asm_aa1f - inc b - jr .loop_card_ids -.asm_aa1f - ld a, b - ld [wNumCardListEntries], a - ret - -; prints "X/Y" where X is number of cards owned in the set -; and Y is the total card count of the Card Set -.PrintCardCount - call Set_OBJ_8x8 - xor a - ld [wTileMapFill], a - call ZeroObjectPositions - call EmptyScreen - ld a, $01 - ld [wVBlankOAMCopyToggle], a - call LoadCursorTile - call LoadSymbolsFont - call LoadDuelCardSymbolTiles - bank1call SetDefaultPalettes - lb de, $3c, $ff - call SetupText - lb de, 1, 1 - call InitTextPrinting - -; print the total number of cards that are in the Card Set - ld a, [wSelectedCardSet] - cp CARD_SET_PROMOTIONAL - jr nz, .check_laboratory -; promotional - ldtx hl, Item5PromotionalCardText - ld e, NUM_CARDS_PROMOTIONAL - 2 ; minus the phantom cards - ld a, [wOwnedPhantomCardFlags] - bit VENUSAUR_OWNED_PHANTOM_F, a - jr z, .check_owns_mew - inc e -.check_owns_mew - bit MEW_OWNED_PHANTOM_F, a - jr z, .has_card_set_count - inc e - jr .has_card_set_count -.check_laboratory - cp CARD_SET_LABORATORY - jr nz, .check_mystery - ldtx hl, Item4LaboratoryText - ld e, NUM_CARDS_LABORATORY - jr .has_card_set_count -.check_mystery - cp CARD_SET_MYSTERY - jr nz, .check_evolution - ldtx hl, Item3MysteryText - ld e, NUM_CARDS_MYSTERY - jr .has_card_set_count -.check_evolution - cp CARD_SET_EVOLUTION - jr nz, .colosseum - ldtx hl, Item2EvolutionText - ld e, NUM_CARDS_EVOLUTION - jr .has_card_set_count -.colosseum - ldtx hl, Item1ColosseumText - ld e, NUM_CARDS_COLOSSEUM - -.has_card_set_count - push de - call ProcessTextFromID - call .CountOwnedCardsInSet - lb de, 14, 1 - call InitTextPrinting - - ld a, [wNumOwnedCardsInSet] - ld hl, wDefaultText - call ConvertToNumericalDigits - call CalculateOnesAndTensDigits - ld [hl], TX_SYMBOL - inc hl - ld [hl], SYM_SLASH - inc hl - pop de - - ld a, e - call ConvertToNumericalDigits - ld [hl], TX_END - ld hl, wDefaultText - call ProcessText - lb de, 0, 2 - lb bc, 20, 16 - call DrawRegularTextBox - call EnableLCD - ret - -; counts number of cards in wOwnedCardsCountList -; that is not set as CARD_NOT_OWNED -.CountOwnedCardsInSet - ld hl, wOwnedCardsCountList - ld b, 0 -.loop_card_count - ld a, [hli] - cp $ff - jr z, .got_num_owned_cards - cp CARD_NOT_OWNED - jr z, .loop_card_count - inc b - jr .loop_card_count -.got_num_owned_cards - ld a, b - ld [wNumOwnedCardsInSet], a - ret - -.DrawCardAlbumScreen - xor a - ld [wTileMapFill], a - call EmptyScreen - ld a, [hffb4] - dec a - jr nz, .skip_clear_screen - ld [hffb4], a - call Set_OBJ_8x8 - call ZeroObjectPositions - ld a, $01 - ld [wVBlankOAMCopyToggle], a - call LoadCursorTile - call LoadSymbolsFont - call LoadDuelCardSymbolTiles - bank1call SetDefaultPalettes - lb de, $3c, $ff - call SetupText - -.skip_clear_screen - lb de, 0, 0 - lb bc, 20, 13 - call DrawRegularTextBox - ld hl, .BoosterPacksMenuData - call PlaceTextItems - - ; set all Card Sets as available - ld a, NUM_CARD_SETS - ld hl, wUnavailableAlbumCardSets - call ClearNBytesFromHL - - ; check whether player has had promotional cards - call EnableSRAM - ld a, [sHasPromotionalCards] - call DisableSRAM - or a - jr nz, .has_promotional - - ; doesn't have promotional, check if - ; this is still the case by checking the collection - ld a, CARD_SET_PROMOTIONAL - call CreateCardSetListAndInitListCoords - ld a, [wFilteredCardList] - or a - jr nz, .set_has_promotional - ; still has no promotional, print empty Card Set name - ld a, TRUE - ld [wUnavailableAlbumCardSets + CARD_SET_PROMOTIONAL], a - ld e, 11 - ld d, 5 - call InitTextPrinting - ldtx hl, EmptyPromotionalCardText - call ProcessTextFromID - jr .has_promotional - -.set_has_promotional - call EnableSRAM - ld a, TRUE - ld [sHasPromotionalCards], a - call DisableSRAM -.has_promotional - ldtx hl, ViewWhichCardFileText - call DrawWideTextBox_PrintText - call EnableLCD - ret - -.BoosterPacksMenuData - textitem 7, 1, BoosterPackTitleText - textitem 5, 3, Item1ColosseumText - textitem 5, 5, Item2EvolutionText - textitem 5, 7, Item3MysteryText - textitem 5, 9, Item4LaboratoryText - textitem 5, 11, Item5PromotionalCardText - db $ff - -PrinterMenu_PokemonCards: ; ab7b (2:6b7b) - call WriteCardListsTerminatorBytes - call PrintPlayersCardsHeaderInfo - xor a - ld [wCardListVisibleOffset], a - ld [wCurCardTypeFilter], a - call PrintFilteredCardSelectionList - call EnableLCD - xor a - ld hl, FiltersCardSelectionParams - call InitCardSelectionParams - -.loop_frame_1 - call DoFrame - ld a, [wCurCardTypeFilter] - ld b, a - ld a, [wTempCardTypeFilter] - cp b - jr z, .handle_input - ld [wCurCardTypeFilter], a - ld hl, wCardListVisibleOffset - ld [hl], $00 - call PrintFilteredCardSelectionList - ld hl, hffb0 - ld [hl], $01 - call PrintPlayersCardsText - ld hl, hffb0 - ld [hl], $00 - ld a, NUM_FILTERS - ld [wCardListNumCursorPositions], a -.handle_input - ldh a, [hDPadHeld] - and D_DOWN - jr z, .asm_abca -; d_down - call ConfirmSelectionAndReturnCarry - jr .asm_abd7 -.asm_abca - call HandleCardSelectionInput - jr nc, .loop_frame_1 - ld a, [hffb3] - cp $ff - jr nz, .asm_abd7 - ret - -.asm_abd7 - ld a, [wNumEntriesInCurFilter] - or a - jr z, .loop_frame_1 - - xor a - ld hl, Data_a396 - call InitCardSelectionParams - ld a, [wNumEntriesInCurFilter] - ld [wNumCardListEntries], a - ld hl, wNumVisibleCardListEntries - cp [hl] - jr nc, .asm_abf6 - ld [wCardListNumCursorPositions], a - ld [wTempCardListNumCursorPositions], a -.asm_abf6 - ld hl, PrintCardSelectionList - ld d, h - ld a, l - ld hl, wCardListUpdateFunction - ld [hli], a - ld [hl], d - xor a - ld [wced2], a - -.loop_frame_2 - call DoFrame - call HandleSelectUpAndDownInList - jr c, .loop_frame_2 - call HandleDeckCardSelectionList - jr c, .asm_ac60 - ldh a, [hDPadHeld] - and START - jr z, .loop_frame_2 -; start btn - ld a, $01 - call PlaySFXConfirmOrCancel - ld a, [wCardListNumCursorPositions] - ld [wTempCardListNumCursorPositions], a - ld a, [wCardListCursorPos] - ld [wTempCardListCursorPos], a - - ; set wFilteredCardList as current card list - ; and show card page screen - ld de, wFilteredCardList - ld hl, wCurCardListPtr - ld [hl], e - inc hl - ld [hl], d - call OpenCardPageFromCardList - call PrintPlayersCardsHeaderInfo - -.asm_ac37 - ld hl, FiltersCardSelectionParams - call InitCardSelectionParams - ld a, [wCurCardTypeFilter] - ld [wTempCardTypeFilter], a - call DrawHorizontalListCursor_Visible - call PrintCardSelectionList - call EnableLCD - ld hl, Data_a396 - call InitCardSelectionParams - ld a, [wTempCardListNumCursorPositions] - ld [wCardListNumCursorPositions], a - ld a, [wTempCardListCursorPos] - ld [wCardListCursorPos], a - jr .loop_frame_2 - -.asm_ac60 - call DrawListCursor_Invisible - ld a, [wCardListNumCursorPositions] - ld [wTempCardListNumCursorPositions], a - ld a, [wCardListCursorPos] - ld [wTempCardListCursorPos], a - ld a, [hffb3] - cp $ff - jr nz, .asm_ac92 - - ld hl, FiltersCardSelectionParams - call InitCardSelectionParams - ld a, [wCurCardTypeFilter] - ld [wTempCardTypeFilter], a - ld hl, hffb0 - ld [hl], $01 - call PrintPlayersCardsText - ld hl, hffb0 - ld [hl], $00 - jp .loop_frame_1 - -.asm_ac92 - call DrawListCursor_Visible - call .Func_acde - lb de, 1, 1 - call InitTextPrinting - ldtx hl, PrintThisCardYesNoText - call ProcessTextFromID - ld a, $01 - ld hl, Data_ad05 - call InitCardSelectionParams -.loop_frame - call DoFrame - call HandleCardSelectionInput - jr nc, .loop_frame - ld a, [hffb3] - or a - jr nz, .asm_acd5 - ld hl, wFilteredCardList - ld a, [wTempCardListCursorPos] - ld c, a - ld b, $00 - add hl, bc - ld a, [wCardListVisibleOffset] - ld c, a - ld b, $00 - add hl, bc - ld a, [hl] - bank1call Func_758a - call PrintPlayersCardsHeaderInfo - jp .asm_ac37 - -.asm_acd5 - call .Func_acde - call PrintPlayersCardsHeaderInfo.skip_empty_screen - jp .asm_ac37 - -.Func_acde - xor a - lb hl, 0, 0 - lb de, 0, 0 - lb bc, 20, 4 - call FillRectangle - ld a, [wConsole] - cp CONSOLE_CGB - ret nz ; exit if not CGB - - xor a - lb hl, 0, 0 - lb de, 0, 0 - lb bc, 20, 4 - call BankswitchVRAM1 - call FillRectangle - call BankswitchVRAM0 - ret - -Data_ad05: ; ad05 (2:6d05) - db 3 ; x pos - db 3 ; y pos - db 0 ; y spacing - db 4 ; x spacing - db 2 ; num entries - db SYM_CURSOR_R ; visible cursor tile - db SYM_SPACE ; invisible cursor tile - dw NULL ; wCardListHandlerFunction - -PrinterMenu_CardList: ; ad0e (2:6d0e) - call WriteCardListsTerminatorBytes - call Set_OBJ_8x8 - call Func_8d78 - lb bc, 0, 4 - ld a, SYM_BOX_TOP - call FillBGMapLineWithA - - xor a - ld [wCardListVisibleOffset], a - ld [wCurCardTypeFilter], a - call PrintFilteredCardSelectionList - call EnableLCD - lb de, 1, 1 - call InitTextPrinting - ld hl, EnableLCD - call ProcessTextFromID - ld a, $01 - ld hl, Data_ad05 - call InitCardSelectionParams -.loop_frame - call DoFrame - call HandleCardSelectionInput - jr nc, .loop_frame - ld a, [hffb3] - or a - ret nz - bank1call PrintCardList - ret - -HandlePrinterMenu: ; ad51 (2:6d51) - bank1call PreparePrinterConnection - ret c - xor a -.loop - ld hl, PrinterMenuParameters - call InitializeMenuParameters - call EmptyScreenAndLoadFontDuelAndHandCardsIcons - lb de, 4, 0 - lb bc, 12, 12 - call DrawRegularTextBox - lb de, 6, 2 - call InitTextPrinting - ldtx hl, PrintMenuItemsText - call ProcessTextFromID - ldtx hl, WhatWouldYouLikeToPrintText - call DrawWideTextBox_PrintText - call EnableLCD -.loop_input - call DoFrame - call HandleMenuInput - jr nc, .loop_input - ldh a, [hCurMenuItem] - cp $ff - call z, PrinterMenu_QuitPrint - ld [wSelectedPrinterMenuItem], a - ld hl, PrinterMenuFunctionTable - call JumpToFunctionInTable - ld a, [wSelectedPrinterMenuItem] - jr .loop - -PrinterMenu_QuitPrint: ; ad9a (2:6d9a) - add sp, $2 ; exit menu - ldtx hl, PleaseMakeSureToTurnGameBoyPrinterOffText - call DrawWideTextBox_WaitForInput - ret - -PrinterMenuFunctionTable: ; ada3 (2:6da3) - dw PrinterMenu_PokemonCards - dw PrinterMenu_DeckConfiguration - dw PrinterMenu_CardList - dw PrinterMenu_PrintQuality - dw PrinterMenu_QuitPrint - -PrinterMenuParameters: ; adad (2:6dad) - db 5, 2 ; cursor x, cursor y - db 2 ; y displacement between items - db 5 ; number of items - db SYM_CURSOR_R ; cursor tile number - db SYM_SPACE ; tile behind cursor - dw NULL ; function pointer if non-0 - -PrinterMenu_PrintQuality: ; adb5 (2:6db5) - ldtx hl, PleaseSetTheContrastText - call DrawWideTextBox_PrintText - call EnableSRAM - ld a, [sPrinterContrastLevel] - call DisableSRAM - ld hl, Data_adf5 - call InitCardSelectionParams -.loop_frame - call DoFrame - call HandleCardSelectionInput - jr nc, .loop_frame - ld a, [hffb3] - cp $ff - jr z, .asm_ade2 - call EnableSRAM - ld [sPrinterContrastLevel], a - call DisableSRAM -.asm_ade2 - add sp, $2 ; exit menu - ld a, [wSelectedPrinterMenuItem] - ld hl, PrinterMenuParameters - call InitializeMenuParameters - ldtx hl, WhatWouldYouLikeToPrintText - call DrawWideTextBox_PrintText - jr HandlePrinterMenu.loop_input - -Data_adf5: ; adf5 (2:6df5) - db 5 ; x pos - db 16 ; y pos - db 0 ; y spacing - db 2 ; x spacing - db 5 ; num entries - db SYM_CURSOR_R ; visible cursor tile - db SYM_SPACE ; invisible cursor tile - dw NULL ; wCardListHandlerFunction - -; handles printing and player input -; in the card confirmation list shown -; when cards are missing for some deck configuration -; hl = deck name -; de = deck cards -HandleDeckMissingCardsList: ; adfe (2:6dfe) -; read deck name from hl and cards from de - push de - ld de, wCurDeckName - call CopyListFromHLToDEInSRAM - pop de - ld hl, wCurDeckCards - call CopyDeckFromSRAM - - ld a, NUM_FILTERS - ld hl, wCardFilterCounts - call ClearNBytesFromHL - ld a, DECK_SIZE - ld [wTotalCardCount], a - ld hl, wCardFilterCounts - ld [hl], a - call .HandleList ; can skip call and fallthrough instead - ret - -.HandleList - call SortCurDeckCardsByID - call CreateCurDeckUniqueCardList - xor a - ld [wCardListVisibleOffset], a -.loop - ld hl, .DeckConfirmationCardSelectionParams - call InitCardSelectionParams - ld a, [wNumUniqueCards] - ld [wNumCardListEntries], a - cp $05 - jr c, .got_num_positions - ld a, $05 -.got_num_positions - ld [wCardListNumCursorPositions], a - ld [wNumVisibleCardListEntries], a - call .PrintTitleAndList - ld hl, wCardConfirmationText - ld a, [hli] - ld h, [hl] - ld l, a - call DrawWideTextBox_PrintText - -; set card update function - ld hl, .CardListUpdateFunction - ld d, h - ld a, l - ld hl, wCardListUpdateFunction - ld [hli], a - ld [hl], d - xor a - ld [wced2], a - -.loop_input - call DoFrame - call HandleDeckCardSelectionList - jr c, .selection_made - call HandleLeftRightInCardList - jr c, .loop_input - ldh a, [hDPadHeld] - and START - jr z, .loop_input - -.open_card_pge - ld a, $01 - call PlaySFXConfirmOrCancel - ld a, [wCardListCursorPos] - ld [wced7], a - - ; set wOwnedCardsCountList as current card list - ; and show card page screen - ld de, wOwnedCardsCountList - ld hl, wCurCardListPtr - ld [hl], e - inc hl - ld [hl], d - call OpenCardPageFromCardList - jr .loop - -.selection_made - ld a, [hffb3] - cp $ff - ret z - jr .open_card_pge - -.DeckConfirmationCardSelectionParams - db 0 ; x pos - db 3 ; y pos - db 2 ; y spacing - db 0 ; x spacing - db 5 ; num entries - db SYM_CURSOR_R ; visible cursor tile - db SYM_SPACE ; invisible cursor tile - dw NULL ; wCardListHandlerFunction - -.CardListUpdateFunction - ld hl, hffb0 - ld [hl], $01 - call .PrintDeckIndexAndName - lb de, 1, 14 - call InitTextPrinting - ld hl, wCardConfirmationText - ld a, [hli] - ld h, [hl] - ld l, a - call ProcessTextFromID - ld hl, hffb0 - ld [hl], $00 - jp PrintConfirmationCardList - -.PrintTitleAndList - call .ClearScreenAndPrintDeckTitle - lb de, 3, 3 - ld hl, wCardListCoords - ld [hl], e - inc hl - ld [hl], d - call PrintConfirmationCardList - ret - -.ClearScreenAndPrintDeckTitle - call EmptyScreenAndLoadFontDuelAndHandCardsIcons - call .PrintDeckIndexAndName - call EnableLCD - ret - -; prints text in the form "X.<DECK NAME> deck" -; where X is the deck index in the list -.PrintDeckIndexAndName - ld a, [wCurDeckName] - or a - ret z ; not a valid deck - lb de, 0, 1 - call InitTextPrinting - ld a, [wCurDeck] - inc a - ld hl, wDefaultText - call ConvertToNumericalDigits - ld [hl], "FW0_·" - inc hl - ld [hl], TX_END - ld hl, wDefaultText - call ProcessText - - ld hl, wCurDeckName - ld de, wDefaultText - call CopyListFromHLToDE - ld hl, wDefaultText - call GetTextLengthInTiles - ld b, $0 - ld hl, wDefaultText - add hl, bc - ld d, h - ld e, l - ld hl, DeckNameSuffix - call CopyListFromHLToDE - lb de, 3, 1 - ld hl, wDefaultText - call InitTextPrinting - call ProcessText - ret - -Func_af1d: ; af1d (2:6f1d) - xor a - ld [wTileMapFill], a - call ZeroObjectPositions - call EmptyScreen - ld a, $1 - ld [wVBlankOAMCopyToggle], a - call LoadSymbolsFont - bank1call SetDefaultPalettes - - lb de, $3c, $bf - call SetupText - lb de, 3, 1 - call InitTextPrinting - ldtx hl, ProceduresForSendingCardsText - call ProcessTextFromID - lb de, 1, 3 - call InitTextPrinting - ldtx hl, CardSendingProceduresText - ld a, $01 - ld [wLineSeparation], a - call ProcessTextFromID - xor a - ld [wLineSeparation], a - ldtx hl, PleaseReadTheProceduresForSendingCardsText - call DrawWideTextBox_WaitForInput - - call EnableLCD - call PrepareToBuildDeckConfigurationToSend - jr c, .asm_af6b - ld a, $01 - or a - ret - -.asm_af6b - ld hl, wCurDeckCards - ld de, wDuelTempList - call CopyListFromHLToDE - xor a - ld [wNameBuffer], a - bank1call SendCard - ret c - call EnableSRAM - ld hl, wCurDeckCards - call DecrementDeckCardsInCollection - call DisableSRAM - call SaveGame - ld hl, wNameBuffer - ld de, wDefaultText - call CopyListFromHLToDE - xor a - ret - -; never reached - scf - ret - -Func_af98: ; af98 (2:6f98) - xor a - ld [wDuelTempList], a - ld [wNameBuffer], a - bank1call ReceiveCard - ret c - - call EnableSRAM - ld hl, wDuelTempList - call AddGiftCenterDeckCardsToCollection - call DisableSRAM - call SaveGame - xor a - ld [wCardListVisibleOffset], a - ld hl, Data_b04a - call InitCardSelectionParams - call PrintReceivedTheseCardsText - call Func_b088 - call EnableLCD - ld a, [wNumEntriesInCurFilter] - ld [wNumCardListEntries], a - ld hl, wNumVisibleCardListEntries - cp [hl] - jr nc, .asm_afd4 - ld [wCardListNumCursorPositions], a -.asm_afd4 - ld hl, ShowReceivedCardsList - ld d, h - ld a, l - ld hl, wCardListUpdateFunction - ld [hli], a - ld [hl], d - - xor a - ld [wced2], a -.asm_afe2 - call DoFrame - call HandleDeckCardSelectionList - jr c, .asm_b02f - call HandleLeftRightInCardList - jr c, .asm_afe2 - ldh a, [hDPadHeld] - and START - jr z, .asm_afe2 -.asm_aff5 - ld a, $01 - call PlaySFXConfirmOrCancel - ld a, [wCardListCursorPos] - ld [wTempCardListCursorPos], a - - ; set wFilteredCardList as current card list - ; and show card page screen - ld de, wFilteredCardList - ld hl, wCurCardListPtr - ld [hl], e - inc hl - ld [hl], d - call OpenCardPageFromCardList - call PrintReceivedTheseCardsText - - call PrintCardSelectionList - call EnableLCD - ld hl, Data_b04a - call InitCardSelectionParams - ld a, [wNumEntriesInCurFilter] - ld hl, wNumVisibleCardListEntries - cp [hl] - jr nc, .asm_b027 - ld [wCardListNumCursorPositions], a -.asm_b027 - ld a, [wTempCardListCursorPos] - ld [wCardListCursorPos], a - jr .asm_afe2 -.asm_b02f - call DrawListCursor_Invisible - ld a, [wCardListCursorPos] - ld [wTempCardListCursorPos], a - ld a, [hffb3] - cp $ff - jr nz, .asm_aff5 - ld hl, wNameBuffer - ld de, wDefaultText - call CopyListFromHLToDE - or a - ret - -Data_b04a: ; b04a (2:704a) - db 1 ; x pos - db 3 ; y pos - db 2 ; y spacing - db 0 ; x spacing - db 5 ; num entries - db SYM_CURSOR_R ; visible cursor tile - db SYM_SPACE ; invisible cursor tile - dw NULL ; wCardListHandlerFunction - -ShowReceivedCardsList: ; b053 (2:7053) - ld hl, hffb0 - ld [hl], $01 - lb de, 1, 1 - call InitTextPrinting - ldtx hl, CardReceivedText - call ProcessTextFromID - ld hl, wNameBuffer - ld de, wDefaultText - call CopyListFromHLToDE - xor a - ld [wTxRam2 + 0], a - ld [wTxRam2 + 1], a - lb de, 1, 14 - call InitTextPrinting - ldtx hl, ReceivedTheseCardsFromText - call PrintTextNoDelay - ld hl, hffb0 - ld [hl], $00 - jp PrintCardSelectionList - -Func_b088: ; b088 (2:7088) - ld a, CARD_COLLECTION_SIZE - 1 - ld hl, wTempCardCollection - call ClearNBytesFromHL - ld de, wDuelTempList - call .Func_b0b2 - ld a, $ff - call .Func_b0c0 - ld a, $05 - ld [wNumVisibleCardListEntries], a - lb de, 2, 3 - ld hl, wCardListCoords - ld [hl], e - inc hl - ld [hl], d - ld a, SYM_BOX_RIGHT - ld [wCursorAlternateTile], a - call PrintCardSelectionList - ret - -.Func_b0b2 - ld bc, wTempCardCollection -.loop - ld a, [de] - inc de - or a - ret z - ld h, $00 - ld l, a - add hl, bc - inc [hl] - jr .loop - -.Func_b0c0 - push af - push bc - push de - push hl - push af - ld a, DECK_SIZE - ld hl, wOwnedCardsCountList - call ClearNBytesFromHL - ld a, DECK_SIZE - ld hl, wFilteredCardList - call ClearNBytesFromHL - pop af - ld hl, $0 - ld de, $0 - ld b, a -.asm_b0dd - inc e - call GetCardType - jr c, .asm_b119 - ld c, a - ld a, b - cp $ff - jr z, .asm_b0fc - and FILTER_ENERGY - cp FILTER_ENERGY - jr z, .asm_b0f5 - ld a, c - cp b - jr nz, .asm_b0dd - jr .asm_b0fc -.asm_b0f5 - ld a, c - and TYPE_ENERGY - cp TYPE_ENERGY - jr nz, .asm_b0dd -.asm_b0fc - push bc - push hl - ld bc, wFilteredCardList - add hl, bc - ld [hl], e - ld hl, wTempCardCollection - add hl, de - ld a, [hl] - and $7f - pop hl - or a - jr z, .asm_b116 - push hl - ld bc, wOwnedCardsCountList - add hl, bc - ld [hl], a - pop hl - inc l -.asm_b116 - pop bc - jr .asm_b0dd - -.asm_b119 - ld a, l - ld [wNumEntriesInCurFilter], a - xor a - ld c, l - ld b, h - ld hl, wFilteredCardList - add hl, bc - ld [hl], a - ld a, $ff - ld hl, wOwnedCardsCountList - add hl, bc - ld [hl], a - pop hl - pop de - pop bc - pop af - ret - -PrintCardToSendText: ; b131 (2:7131) - call EmptyScreenAndDrawTextBox - lb de, 1, 1 - call InitTextPrinting - ldtx hl, CardToSendText - call ProcessTextFromID - ret - -PrintReceivedTheseCardsText: ; b141 (2:7141) - call EmptyScreenAndDrawTextBox - lb de, 1, 1 - call InitTextPrinting - ldtx hl, CardReceivedText - call ProcessTextFromID - ld hl, wNameBuffer - ld de, wDefaultText - call CopyListFromHLToDE - xor a - ld [wTxRam2 + 0], a - ld [wTxRam2 + 1], a - ldtx hl, ReceivedTheseCardsFromText - call DrawWideTextBox_PrintText - ret - -EmptyScreenAndDrawTextBox: ; b167 (2:7167) - call Set_OBJ_8x8 - call Func_8d78 - lb de, 0, 0 - lb bc, 20, 13 - call DrawRegularTextBox - ret - -Func_b177: ; b177 (2:7177) - ld a, [wd10e] - and $03 - ld hl, .FunctionTable - call JumpToFunctionInTable - jr c, .asm_b18f - or a - jr nz, .asm_b18f - xor a - ld [wTxRam2 + 0], a - ld [wTxRam2 + 1], a - ret -.asm_b18f - ld a, $ff - ld [wd10e], a - ret - -.FunctionTable - dw Func_af1d - dw Func_af98 - dw Func_bc04 - dw Func_bc7a - -HandleDeckSaveMachineMenu: ; b19d (2:719d) - xor a - ld [wCardListVisibleOffset], a - ldtx de, DeckSaveMachineText - ld hl, wDeckMachineTitleText - ld [hl], e - inc hl - ld [hl], d - call ClearScreenAndDrawDeckMachineScreen - ld a, NUM_DECK_SAVE_MACHINE_SLOTS - ld [wNumDeckMachineEntries], a - - xor a -.wait_input - ld hl, DeckMachineSelectionParams - call InitCardSelectionParams - call DrawListScrollArrows - call PrintNumSavedDecks - ldtx hl, PleaseSelectDeckText - call DrawWideTextBox_PrintText - ldtx de, PleaseSelectDeckText - call InitDeckMachineDrawingParams - call HandleDeckMachineSelection - jr c, .wait_input - cp $ff - ret z ; operation cancelled - ; get the index of selected deck - ld b, a - ld a, [wCardListVisibleOffset] - add b - ld [wSelectedDeckMachineEntry], a - - call ResetCheckMenuCursorPositionAndBlink - call DrawWideTextBox - ld hl, .DeckMachineMenuData - call PlaceTextItems -.wait_input_submenu - call DoFrame - call HandleCheckMenuInput - jp nc, .wait_input_submenu - cp $ff - jr nz, .submenu_option_selected - ; return from submenu - ld a, [wTempDeckMachineCursorPos] - jp .wait_input - -.submenu_option_selected - ld a, [wCheckMenuCursorYPosition] - sla a - ld hl, wCheckMenuCursorXPosition - add [hl] - or a - jr nz, .ok_1 - -; Save a Deck - call CheckIfSelectedDeckMachineEntryIsEmpty - jr nc, .prompt_ok_if_deleted - call SaveDeckInDeckSaveMachine - ld a, [wTempDeckMachineCursorPos] - jp c, .wait_input - jr .return_to_list -.prompt_ok_if_deleted - ldtx hl, OKIfFileDeletedText - call YesOrNoMenuWithText - ld a, [wTempDeckMachineCursorPos] - jr c, .wait_input - call SaveDeckInDeckSaveMachine - ld a, [wTempDeckMachineCursorPos] - jp c, .wait_input - jr .return_to_list - -.ok_1 - cp $1 - jr nz, .ok_2 - -; Delete a Deck - call CheckIfSelectedDeckMachineEntryIsEmpty - jr c, .is_empty - call TryDeleteSavedDeck - ld a, [wTempDeckMachineCursorPos] - jp c, .wait_input - jr .return_to_list - -.is_empty - ld hl, WaitForVBlank - call DrawWideTextBox_WaitForInput - ld a, [wTempDeckMachineCursorPos] - jp .wait_input - -.ok_2 - cp $2 - jr nz, .cancel - -; Build a Deck - call CheckIfSelectedDeckMachineEntryIsEmpty - jr c, .is_empty - call TryBuildDeckMachineDeck - ld a, [wTempDeckMachineCursorPos] - jp nc, .wait_input - -.return_to_list - ld a, [wTempCardListVisibleOffset] - ld [wCardListVisibleOffset], a - call ClearScreenAndDrawDeckMachineScreen - call DrawListScrollArrows - call PrintNumSavedDecks - ld a, [wTempDeckMachineCursorPos] - jp .wait_input - -.cancel - ret - -.DeckMachineMenuData - textitem 2, 14, SaveADeckText - textitem 12, 14, DeleteADeckText - textitem 2, 16, BuildADeckText - textitem 12, 16, CancelText - db $ff - -; sets the number of cursor positions for deck machine menu, -; sets the text ID to show given by de -; and sets DrawDeckMachineScreen as the update function -; de = text ID -InitDeckMachineDrawingParams: ; b285 (2:7285) - ld a, NUM_DECK_MACHINE_SLOTS - ld [wCardListNumCursorPositions], a - ld hl, wDeckMachineText - ld [hl], e - inc hl - ld [hl], d - ld hl, DrawDeckMachineScreen - ld d, h - ld a, l - ld hl, wCardListUpdateFunction - ld [hli], a - ld [hl], d - xor a - ld [wced2], a - ret - -; handles player input inside the Deck Machine screen -; the Start button opens up the deck confirmation menu -; and returns carry -; otherwise, returns no carry and selection made in a -HandleDeckMachineSelection: ; b29f (2:729f) - call DoFrame - call HandleDeckCardSelectionList - jr c, .selection_made - - call .HandleListJumps - jr c, HandleDeckMachineSelection ; jump back to start - ldh a, [hDPadHeld] - and START - jr z, HandleDeckMachineSelection ; jump back to start - -; start btn - ld a, [wCardListVisibleOffset] - ld [wTempCardListVisibleOffset], a - ld b, a - ld a, [wCardListCursorPos] - ld [wTempDeckMachineCursorPos], a - add b - ld c, a - inc a - or $80 - ld [wCurDeck], a - - ; get pointer to selected deck cards - ; and if it's an empty deck, jump to start - sla c - ld b, $0 - ld hl, wMachineDeckPtrs - add hl, bc - ld a, [hli] - ld h, [hl] - ld l, a - push hl - ld bc, DECK_NAME_SIZE - add hl, bc - ld d, h - ld e, l - call EnableSRAM - ld a, [hl] - call DisableSRAM - pop hl - or a - jr z, HandleDeckMachineSelection ; jump back to start - -; show deck confirmation screen with deck cards -; and return carry set - ld a, $01 - call PlaySFXConfirmOrCancel - call OpenDeckConfirmationMenu - ld a, [wTempCardListVisibleOffset] - ld [wCardListVisibleOffset], a - call ClearScreenAndDrawDeckMachineScreen - call DrawListScrollArrows - call PrintNumSavedDecks - ld a, [wTempDeckMachineCursorPos] - ld [wCardListCursorPos], a - scf - ret - -.selection_made - call DrawListCursor_Visible - ld a, [wCardListVisibleOffset] - ld [wTempCardListVisibleOffset], a - ld a, [wCardListCursorPos] - ld [wTempDeckMachineCursorPos], a - ld a, [hffb3] - or a - ret - -; handles right and left input for jumping several entries at once -; returns carry if jump was made -.HandleListJumps - ld a, [wCardListVisibleOffset] - ld c, a - ldh a, [hDPadHeld] - cp D_RIGHT - jr z, .d_right - cp D_LEFT - jr z, .d_left - or a - ret - -.d_right - ld a, [wCardListVisibleOffset] - add NUM_DECK_MACHINE_SLOTS - ld b, a - add NUM_DECK_MACHINE_SLOTS - ld hl, wNumDeckMachineEntries - cp [hl] - jr c, .got_new_pos - ld a, [wNumDeckMachineEntries] - sub NUM_DECK_MACHINE_SLOTS - ld b, a - jr .got_new_pos - -.d_left - ld a, [wCardListVisibleOffset] - sub NUM_DECK_MACHINE_SLOTS - ld b, a - jr nc, .got_new_pos - ld b, 0 ; first entry - -.got_new_pos - ld a, b - ld [wCardListVisibleOffset], a - cp c - jr z, .set_carry - ; play SFX if jump was made - ; and update UI - ld a, SFX_01 - call PlaySFX - call DrawDeckMachineScreen - call PrintNumSavedDecks -.set_carry - scf - ret - -; returns carry if deck corresponding to the -; entry selected in the Deck Machine menu is empty -CheckIfSelectedDeckMachineEntryIsEmpty: ; b35b (2:735b) - ld a, [wSelectedDeckMachineEntry] - sla a - ld l, a - ld h, $0 - ld bc, wMachineDeckPtrs - add hl, bc - ld a, [hli] - ld h, [hl] - ld l, a - ld bc, DECK_NAME_SIZE - add hl, bc - call EnableSRAM - ld a, [hl] - call DisableSRAM - or a - ret nz ; is valid - scf - ret; is empty - -ClearScreenAndDrawDeckMachineScreen: ; b379 (2:7379) - call Set_OBJ_8x8 - xor a - ld [wTileMapFill], a - call ZeroObjectPositions - call EmptyScreen - ld a, $01 - ld [wVBlankOAMCopyToggle], a - call LoadSymbolsFont - call LoadDuelCardSymbolTiles - bank1call SetDefaultPalettes - lb de, $3c, $ff - call SetupText - lb de, 0, 0 - lb bc, 20, 13 - call DrawRegularTextBox - call SetDeckMachineTitleText - call GetSavedDeckPointers - call PrintVisibleDeckMachineEntries - call GetSavedDeckCount - call EnableLCD - ret - -; prints wDeckMachineTitleText as title text -SetDeckMachineTitleText: ; b3b3 (2:73b3) - lb de, 1, 0 - call InitTextPrinting - ld hl, wDeckMachineTitleText - ld a, [hli] - ld h, [hl] - ld l, a - call ProcessTextFromID - ret - -; save all sSavedDecks pointers in wMachineDeckPtrs -GetSavedDeckPointers: ; b3c3 (2:73c3) - ld a, NUM_DECK_SAVE_MACHINE_SLOTS - add NUM_DECK_SAVE_MACHINE_SLOTS ; add a is better - ld hl, wMachineDeckPtrs - call ClearNBytesFromHL - ld de, wMachineDeckPtrs - ld hl, sSavedDecks - ld bc, DECK_STRUCT_SIZE - ld a, NUM_DECK_SAVE_MACHINE_SLOTS -.loop_saved_decks - push af - ld a, l - ld [de], a - inc de - ld a, h - ld [de], a - inc de - add hl, bc - pop af - dec a - jr nz, .loop_saved_decks - ret - -; given the cursor position in the deck machine menu -; prints the deck names of all entries that are visible -PrintVisibleDeckMachineEntries: ; b3e5 (2:73e5) - ld a, [wCardListVisibleOffset] - lb de, 2, 2 - ld b, NUM_DECK_MACHINE_VISIBLE_DECKS -.loop - push af - push bc - push de - call PrintDeckMachineEntry - pop de - pop bc - pop af - ret c ; jump never made? - dec b - ret z ; no more entries - inc a - inc e - inc e - jr .loop - -UpdateDeckMachineScrollArrowsAndEntries: ; b3fe (2:73fe) - call DrawListScrollArrows - jr PrintVisibleDeckMachineEntries - -DrawDeckMachineScreen: ; b403 (2:7403) - call DrawListScrollArrows - ld hl, hffb0 - ld [hl], $01 - call SetDeckMachineTitleText - lb de, 1, 14 - call InitTextPrinting - ld hl, wDeckMachineText - ld a, [hli] - ld h, [hl] - ld l, a - call ProcessTextFromID - ld hl, hffb0 - ld [hl], $00 - jr PrintVisibleDeckMachineEntries - -; prints the deck name of the deck corresponding -; to index in register a, from wMachineDeckPtrs -; also checks whether the deck can be built -; either by dismantling other decks or not, -; and places the corresponding symbol next to the name -PrintDeckMachineEntry: ; b424 (2:7424) - ld b, a - push bc - ld hl, wDefaultText - inc a - call ConvertToNumericalDigits - ld [hl], "FW0_·" - inc hl - ld [hl], TX_END - call InitTextPrinting - ld hl, wDefaultText - call ProcessText - pop af - -; get the deck corresponding to input index -; and append its name to wDefaultText - push af - sla a - ld l, a - ld h, $0 - ld bc, wMachineDeckPtrs - add hl, bc - ld a, [hli] - ld h, [hl] - ld l, a - inc d - inc d - inc d - push de - call AppendDeckName - pop de - pop bc - jr nc, .valid_deck - -; invalid deck, give it the default -; empty deck name ("--------------") - call InitTextPrinting - ldtx hl, EmptyDeckNameText - call ProcessTextFromID - ld d, 13 - inc e - call InitTextPrinting - ld hl, .text - call ProcessText - scf - ret - -.valid_deck - push de - push bc - ld d, 18 - call InitTextPrinting - -; print the symbol that symbolizes whether the deck can -; be built, or if another deck has to be dismantled to build it - ld a, $0 ; no decks dismantled - call CheckIfCanBuildSavedDeck - pop bc - ld hl, wDefaultText - jr c, .cannot_build - lb de, 3, "FW3_○" ; can build - jr .asm_b4c2 -.cannot_build - push bc - ld a, ALL_DECKS - call CheckIfCanBuildSavedDeck - jr c, .cannot_build_at_all - pop bc - lb de, 3, "FW3_❄" ; can build by dismantling - jr .asm_b4c2 - -.cannot_build_at_all - lb de, 0, "FW0_✕" ; cannot build even by dismantling - call Func_22ca - pop bc - pop de - -; place in wDefaultText the number of cards -; that are needed in order to build the deck - push bc - ld d, 17 - inc e - call InitTextPrinting - pop bc - call .GetNumCardsMissingToBuildDeck - call CalculateOnesAndTensDigits - ld hl, wOnesAndTensPlace - ld a, [hli] - ld b, a - ld a, [hl] - ld hl, wDefaultText - ld [hl], TX_SYMBOL - inc hl - ld [hli], a - ld [hl], TX_SYMBOL - inc hl - ld a, b - ld [hli], a - ld [hl], TX_END - ld hl, wDefaultText - call ProcessText - or a - ret - -.asm_b4c2 - call Func_22ca - pop de - ld d, 13 - inc e - call InitTextPrinting - ld hl, .text - call ProcessText - or a - ret - -.text - db TX_SYMBOL, TX_END - db TX_SYMBOL, TX_END - db TX_SYMBOL, TX_END - db TX_SYMBOL, TX_END - db TX_SYMBOL, TX_END - db TX_SYMBOL, TX_END - done - -; outputs in a the number of cards that the player does not own -; in order to build the deck entry from wMachineDeckPtrs -; given in register b -.GetNumCardsMissingToBuildDeck - push bc - call SafelySwitchToSRAM0 - call CreateCardCollectionListWithDeckCards - call SafelySwitchToTempSRAMBank - pop bc - -; get address to cards for the corresponding deck entry - sla b - ld c, b - ld b, $00 - ld hl, wMachineDeckPtrs - add hl, bc - ld a, [hli] - ld h, [hl] - ld l, a - ld bc, DECK_NAME_SIZE - add hl, bc - - call EnableSRAM - ld de, wTempCardCollection - lb bc, 0, 0 -.loop - inc b - ld a, DECK_SIZE - cp b - jr c, .done - ld a, [hli] - push hl - ld l, a - ld h, $00 - add hl, de - ld a, [hl] - and CARD_COUNT_MASK - or a - jr z, .none - dec a - ld [hl], a - pop hl - jr .loop -.none - inc c - pop hl - jr .loop -.done - ld a, c - call DisableSRAM - ret - -; counts how many decks in sSavedDecks are not empty -; stores value in wNumSavedDecks -GetSavedDeckCount: ; b525 (2:7525) - call EnableSRAM - ld hl, sSavedDecks - ld bc, DECK_STRUCT_SIZE - ld d, NUM_DECK_SAVE_MACHINE_SLOTS - ld e, 0 -.loop - ld a, [hl] - or a - jr z, .empty_slot - inc e -.empty_slot - dec d - jr z, .got_count - add hl, bc - jr .loop -.got_count - ld a, e - ld [wNumSavedDecks], a - call DisableSRAM - ret - -; prints "[wNumSavedDecks]/60" -PrintNumSavedDecks: ; b545 (2:7545) - ld a, [wNumSavedDecks] - ld hl, wDefaultText - call ConvertToNumericalDigits - ld a, TX_SYMBOL - ld [hli], a - ld a, SYM_SLASH - ld [hli], a - ld a, NUM_DECK_SAVE_MACHINE_SLOTS - call ConvertToNumericalDigits - ld [hl], TX_END - lb de, 14, 1 - call InitTextPrinting - ld hl, wDefaultText - call ProcessText - ret - -; prints "X/Y" where X is the current list index -; and Y is the total number of saved decks -; unreferenced? -Func_b568: ; b568 (2:7568) - ld a, [wCardListCursorPos] - ld b, a - ld a, [wCardListVisibleOffset] - add b - inc a - ld hl, wDefaultText - call ConvertToNumericalDigits - ld a, TX_SYMBOL - ld [hli], a - ld a, SYM_SLASH - ld [hli], a - ld a, [wNumSavedDecks] - call ConvertToNumericalDigits - ld [hl], TX_END - lb de, 14, 1 - call InitTextPrinting - ld hl, wDefaultText - call ProcessText - ret - -; handles player choice in what deck to save -; in the Deck Save Machine -; assumes the slot to save was selected and -; is stored in wSelectedDeckMachineEntry -; if operation was successful, return carry -SaveDeckInDeckSaveMachine: ; b592 (2:7592) - ld a, ALL_DECKS - call DrawDecksScreen - xor a -.wait_input - ld hl, DeckMachineMenuParameters - call InitializeMenuParameters - ldtx hl, ChooseADeckToSaveText - call DrawWideTextBox_PrintText -.wait_submenu_input - call DoFrame - call HandleStartButtonInDeckSelectionMenu - jr c, .wait_input - call HandleMenuInput - jp nc, .wait_submenu_input ; can be jr - ldh a, [hCurMenuItem] - cp $ff - ret z ; operation cancelled - ld [wCurDeck], a - call CheckIfCurDeckIsValid - jp nc, .SaveDeckInSelectedEntry ; can be jr - ; is an empty deck - call PrintThereIsNoDeckHereText - ld a, [wCurDeck] - jr .wait_input - -; overwrites data in the selected deck in SRAM -; with the deck that was chosen, in wCurDeck -; then returns carry -.SaveDeckInSelectedEntry - call GetPointerToDeckName - call GetSelectedSavedDeckPtr - ld b, DECK_STRUCT_SIZE - call EnableSRAM - call CopyNBytesFromHLToDE - call DisableSRAM - - call ClearScreenAndDrawDeckMachineScreen - call DrawListScrollArrows - call PrintNumSavedDecks - ld a, [wTempDeckMachineCursorPos] - ld hl, DeckMachineSelectionParams - call InitCardSelectionParams - call DrawListCursor_Visible - call GetPointerToDeckName - call EnableSRAM - call CopyDeckName - call DisableSRAM - xor a - ld [wTxRam2 + 0], a - ld [wTxRam2 + 1], a - ldtx hl, SavedTheConfigurationForText - call DrawWideTextBox_WaitForInput - scf - ret - -DeckMachineMenuParameters: ; b609 (2:7609) - db 1, 2 ; cursor x, cursor y - db 3 ; y displacement between items - db 4 ; number of items - db SYM_CURSOR_R ; cursor tile number - db SYM_SPACE ; tile behind cursor - dw NULL ; function pointer if non-0 - -; outputs in de pointer of saved deck -; corresponding to index in wSelectedDeckMachineEntry -GetSelectedSavedDeckPtr: ; b611 (2:7611) - push af - push hl - ld a, [wSelectedDeckMachineEntry] - sla a - ld e, a - ld d, $00 - ld hl, wMachineDeckPtrs - add hl, de - ld e, [hl] - inc hl - ld d, [hl] - pop hl - pop af - ret - -; checks if it's possible to build saved deck with index b -; includes cards from already built decks from flags in a -; returns carry if cannot build the deck with the given criteria -; a = DECK_* flags for which decks to include in the collection -; b = saved deck index -CheckIfCanBuildSavedDeck: ; b625 (2:7625) - push bc - call SafelySwitchToSRAM0 - call CreateCardCollectionListWithDeckCards - call SafelySwitchToTempSRAMBank - pop bc - sla b - ld c, b - ld b, $0 - ld hl, wMachineDeckPtrs - add hl, bc - ld a, [hli] - ld h, [hl] - ld l, a - ld bc, DECK_NAME_SIZE - add hl, bc - call CheckIfHasEnoughCardsToBuildDeck - ret - -; switches to SRAM bank 0 and stores current SRAM bank in wTempBankSRAM -; skips if current SRAM bank is already 0 -SafelySwitchToSRAM0: ; b644 (2:7644) - push af - ldh a, [hBankSRAM] - or a - jr z, .skip - ld [wTempBankSRAM], a - xor a - call BankswitchSRAM -.skip - pop af - ret - -; switches to SRAM bank 1 and stores current SRAM bank in wTempBankSRAM -; skips if current SRAM bank is already 1 -SafelySwitchToSRAM1: ; b653 (2:7653) - push af - ldh a, [hBankSRAM] - cp BANK("SRAM1") - jr z, .skip - ld [wTempBankSRAM], a - ld a, BANK("SRAM1") - call BankswitchSRAM -.skip - pop af - ret - -SafelySwitchToTempSRAMBank: ; b664 (2:7664) - push af - push bc - ldh a, [hBankSRAM] - ld b, a - ld a, [wTempBankSRAM] - cp b - jr z, .skip - call BankswitchSRAM -.skip - pop bc - pop af - ret - -; returns carry if wTempCardCollection does not -; have enough cards to build deck pointed by hl -; hl = pointer to cards of deck to check -CheckIfHasEnoughCardsToBuildDeck: ; b675 (2:7675) - call EnableSRAM - ld de, wTempCardCollection - ld b, 0 -.loop - inc b - ld a, DECK_SIZE - cp b - jr c, .no_carry - ld a, [hli] - push hl - ld l, a - ld h, $00 - add hl, de - ld a, [hl] - or a - jr z, .set_carry - cp CARD_NOT_OWNED - jr z, .set_carry - dec a - ld [hl], a - pop hl - jr .loop - -.set_carry - pop hl - call DisableSRAM - scf - ret - -.no_carry - call DisableSRAM - or a - ret - -; outputs in a the first slot that is empty to build a deck -; if no empty slot is found, return carry -FindFirstEmptyDeckSlot: ; b6a1 (2:76a1) - ld hl, sDeck1Cards - ld a, [hl] - or a - jr nz, .check_deck_2 - xor a - ret - -.check_deck_2 - ld hl, sDeck2Cards - ld a, [hl] - or a - jr nz, .check_deck_3 - ld a, 1 - ret - -.check_deck_3 - ld hl, sDeck3Cards - ld a, [hl] - or a - jr nz, .check_deck_4 - ld a, 2 - ret - -.check_deck_4 - ld hl, sDeck4Cards - ld a, [hl] - or a - jr nz, .set_carry - ld a, 3 - ret - -.set_carry - scf - ret - -; prompts the player whether to delete selected saved deck -; if player selects yes, clears memory in SRAM -; corresponding to that saved deck slot -; if player selects no, return carry -TryDeleteSavedDeck: ; b6ca (2:76ca) - ldtx hl, DoYouReallyWishToDeleteText - call YesOrNoMenuWithText - jr c, .no - call GetSelectedSavedDeckPtr - ld l, e - ld h, d - push hl - call EnableSRAM - call CopyDeckName - pop hl - ld a, DECK_STRUCT_SIZE - call ClearNBytesFromHL - call DisableSRAM - xor a - ld [wTxRam2 + 0], a - ld [wTxRam2 + 1], a - ldtx hl, DeletedTheConfigurationForText - call DrawWideTextBox_WaitForInput - or a - ret - -.no - ld a, [wCardListCursorPos] - scf - ret - -DeckMachineSelectionParams: ; b6fb (2:76fb) - db 1 ; x pos - db 2 ; y pos - db 2 ; y spacing - db 0 ; x spacing - db 5 ; num entries - db SYM_CURSOR_R ; visible cursor tile - db SYM_SPACE ; invisible cursor tile - dw NULL ; wCardListHandlerFunction - -DrawListScrollArrows: ; b704 (2:7704) - ld a, [wCardListVisibleOffset] - or a - jr z, .no_up_cursor - ld a, SYM_CURSOR_U - jr .got_tile_1 -.no_up_cursor - ld a, SYM_BOX_RIGHT -.got_tile_1 - lb bc, 19, 1 - call WriteByteToBGMap0 - - ld a, [wCardListVisibleOffset] - add NUM_DECK_MACHINE_VISIBLE_DECKS + 1 - ld b, a - ld a, [wNumDeckMachineEntries] - cp b - jr c, .no_down_cursor - xor a ; FALSE - ld [wUnableToScrollDown], a - ld a, SYM_CURSOR_D - jr .got_tile_2 -.no_down_cursor - ld a, TRUE - ld [wUnableToScrollDown], a - ld a, SYM_BOX_RIGHT -.got_tile_2 - lb bc, 19, 11 - call WriteByteToBGMap0 - ret - -; handles the deck menu for when the player -; needs to make space for new deck to build -HandleDismantleDeckToMakeSpace: ; b738 (2:7738) - ldtx hl, YouMayOnlyCarry4DecksText - call DrawWideTextBox_WaitForInput - call SafelySwitchToSRAM0 - ld a, ALL_DECKS - call DrawDecksScreen - xor a -.init_menu_params - ld hl, DeckMachineMenuParameters - call InitializeMenuParameters - ldtx hl, ChooseADeckToDismantleText - call DrawWideTextBox_PrintText -.loop_input - call DoFrame - call HandleStartButtonInDeckSelectionMenu - jr c, .init_menu_params - call HandleMenuInput - jp nc, .loop_input ; can be jr - ldh a, [hCurMenuItem] - cp $ff - jr nz, .selected_deck - ; operation was cancelled - call SafelySwitchToTempSRAMBank - scf - ret - -.selected_deck - ld [wCurDeck], a - ldtx hl, DismantleThisDeckText - call YesOrNoMenuWithText - jr nc, .dismantle - ld a, [wCurDeck] - jr .init_menu_params - -.dismantle - call GetPointerToDeckName - push hl - ld de, wDismantledDeckName - call EnableSRAM - call CopyListFromHLToDE - pop hl - push hl - ld bc, DECK_NAME_SIZE - add hl, bc - call AddDeckToCollection - pop hl - ld a, DECK_STRUCT_SIZE - call ClearNBytesFromHL - call DisableSRAM - - ; redraw deck screen - ld a, ALL_DECKS - call DrawDecksScreen - ld a, [wCurDeck] - ld hl, DeckMachineMenuParameters - call InitializeMenuParameters - call DrawCursor2 - call SafelySwitchToTempSRAMBank - ld hl, wDismantledDeckName - call CopyDeckName - xor a - ld [wTxRam2 + 0], a - ld [wTxRam2 + 1], a - ldtx hl, DismantledDeckText - call DrawWideTextBox_WaitForInput - ld a, [wCurDeck] - ret - -; tries to build the deck in wSelectedDeckMachineEntry -; will check if can be built with or without dismantling -; prompts the player in case a deck has to be dismantled -; or, if it's impossible to build deck, shows missing cards list -TryBuildDeckMachineDeck: ; b7c6 (2:77c6) - ld a, [wSelectedDeckMachineEntry] - ld b, a - push bc - ld a, $0 - call CheckIfCanBuildSavedDeck - pop bc - jr nc, .build_deck - ld a, ALL_DECKS - call CheckIfCanBuildSavedDeck - jr c, .do_not_own_all_cards_needed - ; can only be built by dismantling some deck - ldtx hl, ThisDeckCanOnlyBeBuiltIfYouDismantleText - call DrawWideTextBox_WaitForInput - call .DismantleDecksNeededToBuild - jr nc, .build_deck - ; player chose not to dismantle - -.set_carry_and_return - ld a, [wCardListCursorPos] - scf - ret - -.do_not_own_all_cards_needed - ldtx hl, YouDoNotOwnAllCardsNeededToBuildThisDeckText - call DrawWideTextBox_WaitForInput - jp .ShowMissingCardList - -.build_deck - call EnableSRAM - call SafelySwitchToSRAM0 - call FindFirstEmptyDeckSlot - call SafelySwitchToTempSRAMBank - call DisableSRAM - jr nc, .got_deck_slot - call HandleDismantleDeckToMakeSpace - jr nc, .got_deck_slot - scf - ret - -.got_deck_slot - ld [wDeckSlotForNewDeck], a - ld a, [wSelectedDeckMachineEntry] - ld c, a - ld b, $0 - sla c - ld hl, wMachineDeckPtrs - add hl, bc - ld a, [hli] - ld h, [hl] - ld l, a - - ; copy deck to buffer - ld de, wDeckToBuild - ld b, DECK_STRUCT_SIZE - call EnableSRAM - call CopyNBytesFromHLToDE - - ; remove the needed cards from collection - ld hl, wDeckToBuild + DECK_NAME_SIZE - call SafelySwitchToSRAM0 - call DecrementDeckCardsInCollection - - ; copy the deck cards from the buffer - ; to the deck slot that was chosen - ld a, [wDeckSlotForNewDeck] - ld l, a - ld h, DECK_STRUCT_SIZE - call HtimesL - ld bc, sBuiltDecks - add hl, bc - ld d, h - ld e, l - ld hl, wDeckToBuild - ld b, DECK_STRUCT_SIZE - call CopyNBytesFromHLToDE - call DisableSRAM - - ; draw Decks screen - ld a, ALL_DECKS - call DrawDecksScreen - ld a, [wDeckSlotForNewDeck] - ld [wCurDeck], a - ld hl, DeckMachineMenuParameters - call InitializeMenuParameters - call DrawCursor2 - call GetPointerToDeckName - call EnableSRAM - call CopyDeckName - call DisableSRAM - call SafelySwitchToTempSRAMBank - xor a - ld [wTxRam2 + 0], a - ld [wTxRam2 + 1], a - ldtx hl, BuiltDeckText - call DrawWideTextBox_WaitForInput - scf - ret - -; asks the player for confirmation to dismantle decks -; needed to build the selected deck from the Deck Save Machine -; returns carry set if player selected "no" -; if player selected "yes", dismantle decks -.DismantleDecksNeededToBuild -; shows Decks screen with the names -; of the decks to be dismantled - farcall CheckWhichDecksToDismantleToBuildSavedDeck - call SafelySwitchToSRAM0 - call DrawDecksScreen - ldtx hl, DismantleTheseDecksText - call YesOrNoMenuWithText - jr nc, .yes -; no - call SafelySwitchToTempSRAMBank - scf - ret - -.yes - call EnableSRAM - ld a, [wDecksToBeDismantled] - bit DECK_1_F, a - jr z, .deck_2 - ld a, DECK_1_F - call .DismantleDeck -.deck_2 - ld a, [wDecksToBeDismantled] - bit DECK_2_F, a - jr z, .deck_3 - ld a, DECK_2_F - call .DismantleDeck -.deck_3 - ld a, [wDecksToBeDismantled] - bit DECK_3_F, a - jr z, .deck_4 - ld a, DECK_3_F - call .DismantleDeck -.deck_4 - ld a, [wDecksToBeDismantled] - bit DECK_4_F, a - jr z, .done_dismantling - ld a, DECK_4_F - call .DismantleDeck - -.done_dismantling - call DisableSRAM - ld a, [wDecksToBeDismantled] - call DrawDecksScreen - call SafelySwitchToTempSRAMBank - ldtx hl, DismantledTheDeckText - call DrawWideTextBox_WaitForInput - or a - ret - -; dismantles built deck given by a -; and adds its cards to the collection -; a = DECK_*_F to dismantle -.DismantleDeck - ld l, a - ld h, DECK_STRUCT_SIZE - call HtimesL - ld bc, sBuiltDecks - add hl, bc - push hl - ld bc, DECK_NAME_SIZE - add hl, bc - call AddDeckToCollection - pop hl - ld a, DECK_STRUCT_SIZE - call ClearNBytesFromHL - ret - -; collects cards missing from player's collection -; and shows its confirmation list -.ShowMissingCardList -; copy saved deck card from SRAM to wCurDeckCards -; and make unique card list sorted by ID - ld a, [wSelectedDeckMachineEntry] - ld [wCurDeck], a - call GetSelectedSavedDeckPtr - ld hl, DECK_NAME_SIZE - add hl, de - ld de, wCurDeckCards - ld b, DECK_SIZE - call EnableSRAM - call CopyNBytesFromHLToDE - call DisableSRAM - xor a ; terminator byte for deck - ld [wCurDeckCards + DECK_SIZE], a - call SortCurDeckCardsByID - call CreateCurDeckUniqueCardList - -; create collection card list, including -; the cards from all built decks - ld a, ALL_DECKS - call SafelySwitchToSRAM0 - call CreateCardCollectionListWithDeckCards - call SafelySwitchToTempSRAMBank - -; creates list in wFilteredCardList with -; cards that are missing to build this deck - ld hl, wUniqueDeckCardList - ld de, wFilteredCardList -.loop_deck_configuration - ld a, [hli] - or a - jr z, .finish_missing_card_list - ld b, a - push bc - push de - push hl - ld hl, wCurDeckCards - call .CheckIfCardIsMissing - pop hl - pop de - pop bc - jr nc, .loop_deck_configuration - ; this card is missing - ; store in wFilteredCardList this card ID - ; a number of times equal to the amount still needed - ld c, a - ld a, b -.loop_number_missing - ld [de], a - inc de - dec c - jr nz, .loop_number_missing - jr .loop_deck_configuration - -.finish_missing_card_list - xor a ; terminator byte - ld [de], a - - ldtx bc, TheseCardsAreNeededToBuildThisDeckText - ld hl, wCardConfirmationText - ld a, c - ld [hli], a - ld a, b - ld [hl], a - - call GetSelectedSavedDeckPtr - ld h, d - ld l, e - ld de, wFilteredCardList - call HandleDeckMissingCardsList - jp .set_carry_and_return - -; checks if player has enough cards with ID given in register a -; in the collection to build the deck and, if not, returns -; carry set and outputs in a the difference -; a = card ID -; hl = deck cards -.CheckIfCardIsMissing - call .GetCardCountFromDeck - ld hl, wTempCardCollection - push de - call .GetCardCountFromCollection - ld a, e - pop de - - ; d = card count in deck - ; a = card count in collection - cp d - jr c, .not_enough - or a - ret - -.not_enough -; needs more cards than player owns in collection -; return carry set and the number of cards needed - ld e, a - ld a, d - sub e - scf - ret z - -; returns in d the card count of card ID given in register a -; that is found in the card list in hl -; a = card ID -; hl = deck cards -.GetCardCountFromDeck - push af - ld e, a - ld d, 0 -.loop_deck_cards - ld a, [hli] - or a - jr z, .done_deck_cards - cp e - jr nz, .loop_deck_cards - inc d - jr .loop_deck_cards -.done_deck_cards - pop af - ret - -; returns in e the card count of card ID given in register a -; that is found in the card collection -; a = card ID -; hl = card collection -.GetCardCountFromCollection - push af - ld e, a - ld d, $0 - add hl, de - ld a, [hl] - and CARD_COUNT_MASK - ld e, a - pop af - ret - -PrinterMenu_DeckConfiguration: ; b991 (2:7991) - xor a - ld [wCardListVisibleOffset], a - call ClearScreenAndDrawDeckMachineScreen - ld a, DECK_SIZE - ld [wNumDeckMachineEntries], a - - xor a -.asm_b99e - ld hl, DeckMachineSelectionParams - call InitCardSelectionParams - call DrawListScrollArrows - call PrintNumSavedDecks - ldtx hl, PleaseChooseDeckConfigurationToPrintText - call DrawWideTextBox_PrintText - ldtx de, PleaseChooseDeckConfigurationToPrintText - call InitDeckMachineDrawingParams -.asm_b9b6 - call HandleDeckMachineSelection - jr c, .asm_b99e - cp $ff - ret z - - ld b, a - ld a, [wCardListVisibleOffset] - add b - ld [wSelectedDeckMachineEntry], a - call CheckIfSelectedDeckMachineEntryIsEmpty - jr c, .asm_b9b6 - call DrawWideTextBox - ldtx hl, PrintThisDeckText - call YesOrNoMenuWithText - jr c, .no - call GetSelectedSavedDeckPtr - ld hl, $18 - add hl, de - ld de, wCurDeckCards - ld b, DECK_SIZE - call EnableSRAM - call CopyNBytesFromHLToDE - call DisableSRAM - xor a ; terminator byte for deck - ld [wCurDeckCards + DECK_SIZE], a - call SortCurDeckCardsByID - ld a, [wSelectedDeckMachineEntry] - bank1call PrintDeckConfiguration - call ClearScreenAndDrawDeckMachineScreen - -.no - ld a, [wTempDeckMachineCursorPos] - ld [wCardListCursorPos], a - jp .asm_b99e - -HandleAutoDeckMenu: ; ba04 (2:7a04) - ld a, [wCurAutoDeckMachine] - ld hl, .DeckMachineTitleTextList - sla a - ld c, a - ld b, $0 - add hl, bc - ld de, wDeckMachineTitleText - ld a, [hli] - ld [de], a - inc de - ld a, [hl] - ld [de], a - xor a - ld [wCardListVisibleOffset], a - call .InitAutoDeckMenu - ld a, NUM_DECK_MACHINE_SLOTS - ld [wNumDeckMachineEntries], a - xor a - -.please_select_deck - ld hl, .MenuParameters - call InitializeMenuParameters - ldtx hl, PleaseSelectDeckText - call DrawWideTextBox_PrintText - ld a, NUM_DECK_MACHINE_SLOTS - ld [wCardListNumCursorPositions], a - ld hl, UpdateDeckMachineScrollArrowsAndEntries - ld d, h - ld a, l - ld hl, wCardListUpdateFunction - ld [hli], a - ld [hl], d -.wait_input - call DoFrame - call HandleMenuInput - jr c, .deck_selection_made - -; the following lines do nothing - ldh a, [hDPadHeld] - and D_UP | D_DOWN - jr z, .asm_ba4e -.asm_ba4e - -; check whether to show deck confirmation list - ldh a, [hDPadHeld] - and START - jr z, .wait_input - - ld a, [wCardListVisibleOffset] - ld [wTempCardListVisibleOffset], a - ld b, a - ld a, [wCurMenuItem] - ld [wTempDeckMachineCursorPos], a - add b - ld c, a - inc a - or $80 - ld [wCurDeck], a - sla c - ld b, $0 - ld hl, wMachineDeckPtrs - add hl, bc - call SafelySwitchToSRAM1 - ld a, [hli] - ld h, [hl] - ld l, a - push hl - ld bc, DECK_NAME_SIZE - add hl, bc - ld d, h - ld e, l - ld a, [hl] - pop hl - call SafelySwitchToSRAM0 - or a - jr z, .wait_input ; invalid deck - - ; show confirmation list - ld a, $1 - call PlaySFXConfirmOrCancel - call SafelySwitchToSRAM1 - call OpenDeckConfirmationMenu - call SafelySwitchToSRAM0 - ld a, [wTempCardListVisibleOffset] - ld [wCardListVisibleOffset], a - call .InitAutoDeckMenu - ld a, [wTempDeckMachineCursorPos] - jp .please_select_deck - -.deck_selection_made - call DrawCursor2 - ld a, [wCardListVisibleOffset] - ld [wTempCardListVisibleOffset], a - ld a, [wCurMenuItem] - ld [wTempDeckMachineCursorPos], a - ldh a, [hCurMenuItem] - cp $ff - jp z, .exit ; operation cancelled - ld [wSelectedDeckMachineEntry], a - call ResetCheckMenuCursorPositionAndBlink - xor a - ld [wce5e], a - call DrawWideTextBox - ld hl, .DeckMachineMenuData - call PlaceTextItems -.wait_submenu_input - call DoFrame - call HandleCheckMenuInput_YourOrOppPlayArea - jp nc, .wait_submenu_input - cp $ff - jr nz, .submenu_option_selected - ld a, [wTempDeckMachineCursorPos] - jp .please_select_deck - -.submenu_option_selected - ld a, [wCheckMenuCursorYPosition] - sla a - ld hl, wCheckMenuCursorXPosition - add [hl] - or a - jr nz, .asm_bb09 - -; Build a Deck - call SafelySwitchToSRAM1 - call TryBuildDeckMachineDeck - call SafelySwitchToSRAM0 - ld a, [wTempDeckMachineCursorPos] - jp nc, .please_select_deck - ld a, [wTempCardListVisibleOffset] - ld [wCardListVisibleOffset], a - call .InitAutoDeckMenu - ld a, [wTempDeckMachineCursorPos] - jp .please_select_deck - -.asm_bb09 - cp $1 - jr nz, .read_the_instructions -.exit - xor a - ld [wTempBankSRAM], a - ret - -.read_the_instructions -; show card confirmation list - ld a, [wCardListVisibleOffset] - ld [wTempCardListVisibleOffset], a - ld b, a - ld a, [wCurMenuItem] - ld [wTempDeckMachineCursorPos], a - add b - ld c, a - ld [wCurDeck], a - sla c - ld b, $0 - ld hl, wMachineDeckPtrs - add hl, bc - - ; set the description text in text box - push hl - ld hl, wAutoDeckMachineTextDescriptions - add hl, bc - ld bc, wCardConfirmationText - ld a, [hli] - ld [bc], a - inc bc - ld a, [hl] - ld [bc], a - pop hl - - call SafelySwitchToSRAM1 - ld a, [hli] - ld h, [hl] - ld l, a - push hl - ld bc, DECK_NAME_SIZE - add hl, bc - ld d, h - ld e, l - ld a, [hl] - pop hl - call SafelySwitchToSRAM0 - or a - jp z, .wait_input ; invalid deck - - ; show confirmation list - ld a, $1 - call PlaySFXConfirmOrCancel - call SafelySwitchToSRAM1 - xor a - call HandleDeckMissingCardsList - call SafelySwitchToSRAM0 - ld a, [wTempCardListVisibleOffset] - ld [wCardListVisibleOffset], a - call .InitAutoDeckMenu - ld a, [wTempDeckMachineCursorPos] - jp .please_select_deck - -.MenuParameters - db 1, 2 ; cursor x, cursor y - db 2 ; y displacement between items - db 5 ; number of items - db SYM_CURSOR_R ; cursor tile number - db SYM_SPACE ; tile behind cursor - dw NULL ; function pointer if non-0 - -.DeckMachineMenuData - textitem 2, 14, BuildADeckText - textitem 12, 14, CancelText - textitem 2, 16, ReadTheInstructionsText - db $ff - -.DeckMachineTitleTextList - tx FightingMachineText - tx RockMachineText - tx WaterMachineText - tx LightningMachineText - tx GrassMachineText - tx PsychicMachineText - tx ScienceMachineText - tx FireMachineText - tx AutoMachineText - tx LegendaryMachineText - -; clears screen, loads the proper tiles -; prints the Auto Deck title and deck entries -; and creates the auto deck configurations -.InitAutoDeckMenu - call Set_OBJ_8x8 - xor a - ld [wTileMapFill], a - call ZeroObjectPositions - call EmptyScreen - ld a, $01 - ld [wVBlankOAMCopyToggle], a - call LoadSymbolsFont - call LoadDuelCardSymbolTiles - bank1call SetDefaultPalettes - lb de, $3c, $ff - call SetupText - lb de, 0, 0 - lb bc, 20, 13 - call DrawRegularTextBox - lb de, 1, 0 - call InitTextPrinting - ld hl, wDeckMachineTitleText - ld a, [hli] - ld h, [hl] - ld l, a - call ProcessTextFromID - call SafelySwitchToSRAM1 - farcall ReadAutoDeckConfiguration - call .CreateAutoDeckPointerList - call PrintVisibleDeckMachineEntries - call SafelySwitchToSRAM0 - call EnableLCD - ret - -; writes to wMachineDeckPtrs the pointers -; to the Auto Decks in sAutoDecks -.CreateAutoDeckPointerList - ld a, 2 * NUM_DECK_MACHINE_SLOTS - ld hl, wMachineDeckPtrs - call ClearNBytesFromHL - ld de, wMachineDeckPtrs - ld hl, sAutoDecks - ld bc, DECK_STRUCT_SIZE - ld a, NUM_DECK_MACHINE_SLOTS -.loop - push af - ld a, l - ld [de], a - inc de - ld a, h - ld [de], a - inc de - add hl, bc - pop af - dec a - jr nz, .loop - ret - -Func_bc04: ; bc04 (2:7c04) - xor a - ld [wCardListVisibleOffset], a - ldtx de, DeckSaveMachineText - ld hl, wDeckMachineTitleText - ld [hl], e - inc hl - ld [hl], d - call ClearScreenAndDrawDeckMachineScreen - ld a, DECK_SIZE - ld [wNumDeckMachineEntries], a - xor a -.asm_bc1a - ld hl, DeckMachineSelectionParams - call InitCardSelectionParams - call DrawListScrollArrows - call PrintNumSavedDecks - ldtx hl, PleaseChooseADeckConfigurationToSendText - call DrawWideTextBox_PrintText - ldtx de, PleaseChooseADeckConfigurationToSendText - call InitDeckMachineDrawingParams -.asm_bc32 - call HandleDeckMachineSelection - jr c, .asm_bc1a - cp $ff - jr nz, .asm_bc3f - ld a, $01 - or a - ret -.asm_bc3f - ld b, a - ld a, [wCardListVisibleOffset] - add b - ld [wSelectedDeckMachineEntry], a - call CheckIfSelectedDeckMachineEntryIsEmpty - jr c, .asm_bc32 - - call GetSelectedSavedDeckPtr - ld l, e - ld h, d - ld de, wDuelTempList - ld b, DECK_STRUCT_SIZE - call EnableSRAM - call CopyNBytesFromHLToDE - call DisableSRAM - - xor a - ld [wNameBuffer], a - bank1call SendDeckConfiguration - ret c - - call GetSelectedSavedDeckPtr - ld l, e - ld h, d - ld de, wDefaultText - call EnableSRAM - call CopyListFromHLToDE - call DisableSRAM - or a - ret - -Func_bc7a: ; bc7a (2:7c7a) - xor a - ld [wCardListVisibleOffset], a - ldtx de, DeckSaveMachineText - ld hl, wDeckMachineTitleText - ld [hl], e - inc hl - ld [hl], d - call ClearScreenAndDrawDeckMachineScreen - ld a, DECK_SIZE - ld [wNumDeckMachineEntries], a - xor a -.asm_bc90 - ld hl, DeckMachineSelectionParams - call InitCardSelectionParams - call DrawListScrollArrows - call PrintNumSavedDecks - ldtx hl, PleaseChooseASaveSlotText - call DrawWideTextBox_PrintText - ldtx de, PleaseChooseASaveSlotText - call InitDeckMachineDrawingParams - call HandleDeckMachineSelection - jr c, .asm_bc90 - cp $ff - jr nz, .asm_bcb5 - ld a, $01 - or a - ret -.asm_bcb5 - ld b, a - ld a, [wCardListVisibleOffset] - add b - ld [wSelectedDeckMachineEntry], a - call CheckIfSelectedDeckMachineEntryIsEmpty - jr nc, .asm_bcc4 - jr .asm_bcd1 -.asm_bcc4 - ldtx hl, OKIfFileDeletedText - call YesOrNoMenuWithText - jr nc, .asm_bcd1 - ld a, [wCardListCursorPos] - jr .asm_bc90 -.asm_bcd1 - xor a - ld [wDuelTempList], a - ld [wNameBuffer], a - bank1call ReceiveDeckConfiguration - ret c - call EnableSRAM - ld hl, wDuelTempList - call GetSelectedSavedDeckPtr - ld b, DECK_STRUCT_SIZE - call CopyNBytesFromHLToDE - call DisableSRAM - call SaveGame - call ClearScreenAndDrawDeckMachineScreen - ld a, [wCardListCursorPos] - ld hl, DeckMachineSelectionParams - call InitCardSelectionParams - call DrawListScrollArrows - call PrintNumSavedDecks - call DrawListCursor_Visible - ld hl, wNameBuffer - ld de, wDefaultText - call CopyListFromHLToDE - xor a - ld [wTxRam2 + 0], a - ld [wTxRam2 + 1], a - ldtx hl, ReceivedADeckConfigurationFromText - call DrawWideTextBox_WaitForInput - call GetSelectedSavedDeckPtr - ld l, e - ld h, d - ld de, wDefaultText - call EnableSRAM - call CopyListFromHLToDE - call DisableSRAM - xor a - ret diff --git a/src/engine/bank04.asm b/src/engine/bank04.asm index 6a48c3b..93a3ed3 100644 --- a/src/engine/bank04.asm +++ b/src/engine/bank04.asm @@ -5127,7 +5127,7 @@ MainMenuFunctionTable: ; 126fc (4:66fc) MainMenu_NewGame: ; 12704 (4:6704) farcall Func_c1b1 call DisplayPlayerNamingScreen - farcall Func_1996e + farcall InitSaveData call EnableSRAM ld a, [sAnimationsDisabled] ld [wAnimationsDisabled], a diff --git a/src/engine/bank06.asm b/src/engine/bank06.asm index 3e517d6..fa181f3 100644 --- a/src/engine/bank06.asm +++ b/src/engine/bank06.asm @@ -1048,8 +1048,7 @@ Func_18661: ; 18661 (6:4661) ld a, SYM_CURSOR_R jr .draw_tile -; (6:46f7) -INCLUDE "data/effect_commands.asm" +INCLUDE "data/duel/effect_commands.asm" ; reads the animation commands from PointerTable_AttackAnimation ; of attack in wLoadedAttackAnimation and plays them @@ -1404,7 +1403,7 @@ UpdateMainSceneHUD: ; 19199 (6:5199) Func_191a3: ; 191a3 (6:51a3) ret -INCLUDE "data/attack_animations.asm" +INCLUDE "data/duel/animations/attack_animations.asm" ; if carry flag is set, only delays ; if carry not set: @@ -1990,7 +1989,7 @@ Func_1991f: ; 1991f (6:591f) add $02 push hl ld hl, sDeck1Name - call Func_199e0 + call CopyDeckNameAndCards pop hl call SwapTurn ld a, [hli] @@ -2026,12 +2025,16 @@ Func_1991f: ; 1991f (6:591f) .data db $03, $04, $05, $06, $07, $08 -Func_1996e: ; 1996e (6:596e) +; clears saved data (card Collection/saved decks/Card Pop! data/etc) +; then adds the starter decks as saved decks +; marks all cards in Collection as not owned +InitSaveData: ; 1996e (6:596e) +; clear card and deck save data call EnableSRAM ld a, PLAYER_TURN ldh [hWhoseTurn], a - ld hl, sCardCollection - ld bc, $1607 + ld hl, sCardAndDeckSaveData + ld bc, sCardAndDeckSaveDataEnd - sCardAndDeckSaveData .loop_clear xor a ld [hli], a @@ -2040,16 +2043,18 @@ Func_1996e: ; 1996e (6:596e) or b jr nz, .loop_clear +; add the starter decks ld a, CHARMANDER_AND_FRIENDS_DECK ld hl, sSavedDeck1 - call Func_199e0 + call CopyDeckNameAndCards ld a, SQUIRTLE_AND_FRIENDS_DECK ld hl, sSavedDeck2 - call Func_199e0 + call CopyDeckNameAndCards ld a, BULBASAUR_AND_FRIENDS_DECK ld hl, sSavedDeck3 - call Func_199e0 + call CopyDeckNameAndCards +; marks all cards in Collection to not owned call EnableSRAM ld hl, sCardCollection ld a, CARD_NOT_OWNED @@ -2061,9 +2066,10 @@ Func_1996e: ; 1996e (6:596e) ld hl, sCurrentDuel xor a ld [hli], a - ld [hli], a + ld [hli], a ; sCurrentDuelChecksum ld [hl], a +; clears Card Pop! names ld hl, sCardPopNameList ld c, CARDPOP_NAME_LIST_MAX_ELEMS .loop_card_pop_names @@ -2073,59 +2079,66 @@ Func_1996e: ; 1996e (6:596e) dec c jr nz, .loop_card_pop_names +; saved configuration options ld a, 2 ld [sPrinterContrastLevel], a ld a, $2 ld [sTextSpeed], a ld [wTextSpeed], a + +; miscellaneous data xor a ld [sAnimationsDisabled], a ld [sSkipDelayAllowed], a ld [s0a004], a ld [sTotalCardPopsDone], a ld [sReceivedLegendaryCards], a - farcall Func_8cf9 + farcall InitPromotionalCardAndDeckCounterSaveData call DisableSRAM ret -Func_199e0: ; 199e0 (6:59e0) +; input: +; a = Deck ID +; hl = destination to copy +CopyDeckNameAndCards: ; 199e0 (6:59e0) push de push bc push hl call LoadDeck - jr c, .asm_19a0e - call Func_19a12 + jr c, .done + call .CopyDeckName pop hl call EnableSRAM push hl ld de, wDefaultText -.asm_199f3 +.loop_write_name ld a, [de] inc de ld [hli], a or a - jr nz, .asm_199f3 + jr nz, .loop_write_name pop hl + push hl - ld de, $0018 + ld de, DECK_NAME_SIZE add hl, de ld de, wPlayerDeck - ld c, $3c -.asm_19a04 + ld c, DECK_SIZE +.loop_write_cards ld a, [de] inc de ld [hli], a dec c - jr nz, .asm_19a04 + jr nz, .loop_write_cards call DisableSRAM or a -.asm_19a0e +.done pop hl pop bc pop de ret -Func_19a12: ; 19a12 (6:5a12) +.CopyDeckName ld hl, wDeckName ld a, [hli] ld h, [hl] diff --git a/src/engine/bank07.asm b/src/engine/bank07.asm index 7114b9e..d0172e5 100644 --- a/src/engine/bank07.asm +++ b/src/engine/bank07.asm @@ -1450,44 +1450,52 @@ Func_1cb18: ; 1cb18 (7:4b18) push hl push bc push de + + ; if Func_3ba2 is not set as + ; wDoFrameFunction, quit and set carry ld a, [wDoFrameFunction] cp LOW(Func_3ba2) - jr nz, .asm_1cb5b + jr nz, .carry ld a, [wDoFrameFunction + 1] cp HIGH(Func_3ba2) - jr nz, .asm_1cb5b + jr nz, .carry + ld a, $ff ld [wd4c0], a ld a, [wd42a] cp $ff - call nz, Func_1ccd4 + call nz, DoScreenAnimationUpdate + +; clear all queued animations +; and disable their sprite anims ld hl, wAnimationQueue - ld c, $07 -.asm_1cb3b + ld c, ANIMATION_QUEUE_LENGTH +.loop_queue push bc ld a, [hl] cp $ff - jr z, .asm_1cb4b + jr z, .next_queued ld [wWhichSprite], a farcall DisableCurSpriteAnim ld a, $ff ld [hl], a -.asm_1cb4b +.next_queued pop bc inc hl dec c - jr nz, .asm_1cb3b + jr nz, .loop_queue + xor a ld [wDuelAnimBufferCurPos], a ld [wDuelAnimBufferSize], a -.asm_1cb57 +.done pop de pop bc pop hl ret -.asm_1cb5b +.carry scf - jr .asm_1cb57 + jr .done Func_1cb5e: ; 1cb5e (7:4b5e) cp $96 @@ -1740,7 +1748,8 @@ DefaultScreenAnimationUpdate: ; 1ccbc (7:4cbc) ld [hl], HIGH(DefaultScreenAnimationUpdate) ret -Func_1ccd4: ; 1ccd4 (7:4cd4) +; runs the screen update function set in wScreenAnimUpdatePtr +DoScreenAnimationUpdate: ; 1ccd4 (7:4cd4) ld a, 1 ld [wScreenAnimDuration], a ld hl, wScreenAnimUpdatePtr @@ -1953,7 +1962,7 @@ Func_1ce03: ; 1ce03 (7:4e03) dw Func_191a3 ; DUEL_ANIM_156 dw Func_191a3 ; DUEL_ANIM_157 -INCLUDE "data/duel_animations.asm" +INCLUDE "data/duel/animations/duel_animations.asm" ; plays the Opening sequence, and handles player selection ; in the Title Screen and Start Menu diff --git a/src/engine/bank01.asm b/src/engine/duel/core.asm index 2fbc9e2..3b4b95c 100644 --- a/src/engine/bank01.asm +++ b/src/engine/duel/core.asm @@ -1,69 +1,12 @@ -; continuation of Bank0 Start -; meant as the main loop, but the game never returns from _GameLoop anyway -GameLoop: ; 4000 (1:4000) - di - ld sp, $e000 - call ResetSerial - call EnableInt_VBlank - call EnableInt_Timer - call EnableSRAM - ld a, [sTextSpeed] - ld [wTextSpeed], a - ld a, [sSkipDelayAllowed] - ld [wSkipDelayAllowed], a - call DisableSRAM - ld a, 1 - ld [wUppercaseHalfWidthLetters], a - ei - farcall CommentedOut_1a6cc - ldh a, [hKeysHeld] - cp A_BUTTON | B_BUTTON - jr z, .ask_erase_backup_ram - farcall _GameLoop - jr GameLoop -.ask_erase_backup_ram - call SetupResetBackUpRamScreen - call EmptyScreen - ldtx hl, ResetBackUpRamText - call YesOrNoMenuWithText - jr c, .reset_game -; erase sram - call EnableSRAM - xor a - ld [s0a000], a - call DisableSRAM -.reset_game - jp Reset - -Func_4050: ; 4050 (1:4050) - farcall Func_1996e - ld a, 1 - ld [wUppercaseHalfWidthLetters], a - ret - -; basic setup to be able to print the ResetBackUpRamText in an empty screen -SetupResetBackUpRamScreen: ; 405a (1:405a) - xor a ; SYM_SPACE - ld [wTileMapFill], a - call DisableLCD - call LoadSymbolsFont - call SetDefaultPalettes - lb de, $38, $7f - call SetupText - ret - -CommentedOut_406e: ; 406e (1:406e) - ret - ; try to resume a saved duel from the main menu -TryContinueDuel: ; 406f (1:406f) +TryContinueDuel: call SetupDuel - call Func_66e9 + call LoadAndValidateDuelSaveData ldtx hl, BackUpIsBrokenText jr c, HandleFailedToContinueDuel ; fallthrough -_ContinueDuel: ; 407a (1:407a) +_ContinueDuel: ld hl, sp+$00 ld a, l ld [wDuelReturnAddress], a @@ -77,7 +20,7 @@ _ContinueDuel: ; 407a (1:407a) call DuelMainInterface jp MainDuelLoop.between_turns -HandleFailedToContinueDuel: ; 4097 (1:4097) +HandleFailedToContinueDuel: call DrawWideTextBox_WaitForInput call ResetSerial scf @@ -85,7 +28,7 @@ HandleFailedToContinueDuel: ; 4097 (1:4097) ; this function begins the duel after the opponent's graphics, name and deck have been introduced ; loads both player's decks and sets up the variables and resources required to begin a duel. -StartDuel_VSAIOpp: ; 409f (1:409f) +StartDuel_VSAIOpp: ld a, PLAYER_TURN ldh [hWhoseTurn], a ld a, DUELIST_TYPE_PLAYER @@ -98,7 +41,7 @@ StartDuel_VSAIOpp: ; 409f (1:409f) call SwapTurn jr StartDuel -StartDuel_VSLinkOpp: ; 40bc (1:40bc) +StartDuel_VSLinkOpp: ld a, MUSIC_DUEL_THEME_1 ld [wDuelTheme], a ld hl, wOpponentName @@ -108,7 +51,7 @@ StartDuel_VSLinkOpp: ; 40bc (1:40bc) ld [wIsPracticeDuel], a ; fallthrough -StartDuel: ; 40ca (1:40ca) +StartDuel: ld hl, sp+$0 ld a, l ld [wDuelReturnAddress], a @@ -122,12 +65,12 @@ StartDuel: ; 40ca (1:40ca) call InitVariablesToBeginDuel ld a, [wDuelTheme] call PlaySong - call Func_4b60 + call HandleDuelSetup ret c ; fallthrough ; the loop returns here after every turn switch -MainDuelLoop: ; 40ee (1:40ee) +MainDuelLoop: xor a ld [wCurrentDuelMenuItem], a call UpdateSubstatusConditions_StartOfTurn @@ -257,7 +200,7 @@ MainDuelLoop: ; 40ee (1:40ee) jr z, .link_duel ld a, PLAYER_TURN ldh [hWhoseTurn], a - call Func_4b60 + call HandleDuelSetup jp MainDuelLoop .link_duel call ExchangeRNG @@ -269,12 +212,12 @@ MainDuelLoop: ; 40ee (1:40ee) .got_turn ld a, h ldh [hWhoseTurn], a - call Func_4b60 + call HandleDuelSetup jp nc, MainDuelLoop ret ; empty the screen, and setup text and graphics for a duel -SetupDuel: ; 420b (1:420b) +SetupDuel: xor a ; SYM_SPACE ld [wTileMapFill], a call ZeroObjectPositionsAndToggleOAMCopy @@ -289,7 +232,7 @@ SetupDuel: ; 420b (1:420b) ; handle the turn of the duelist identified by hWhoseTurn. ; if player's turn, display the animation of the player drawing the card at ; hTempCardIndex_ff98, and save the duel state to SRAM. -HandleTurn: ; 4225 (1:4225) +HandleTurn: ld a, DUELVARS_DUELIST_TYPE call GetTurnDuelistVariable ld [wDuelistType], a @@ -328,7 +271,7 @@ HandleTurn: ; 4225 (1:4225) ; when a practice duel turn needs to be restarted because the player did not ; follow the instructions correctly, the game loops back here -RestartPracticeDuelTurn: ; 4268 (1:4268) +RestartPracticeDuelTurn: ld a, PRACTICEDUEL_PRINT_TURN_INSTRUCTIONS call DoPracticeDuelAction ; fallthrough @@ -336,7 +279,7 @@ RestartPracticeDuelTurn: ; 4268 (1:4268) ; print the main interface during a duel, including background, Pokemon, HUDs and a text box. ; the bottom text box changes depending on whether the turn belongs to the player (show the duel menu), ; an AI opponent (print "Waiting..." and a reduced menu) or a link opponent (print "<Duelist> is thinking"). -DuelMainInterface: ; 426d (1:426d) +DuelMainInterface: call DrawDuelMainScene ld a, [wDuelistType] cp DUELIST_TYPE_PLAYER @@ -355,7 +298,7 @@ DuelMainInterface: ; 426d (1:426d) ld [wPlayerAttackingAttackIndex], a ret -PrintDuelMenuAndHandleInput: ; 4295 (1:4295) +PrintDuelMenuAndHandleInput: call DrawWideTextBox ld hl, DuelMenuData call PlaceTextItems @@ -402,7 +345,7 @@ PrintDuelMenuAndHandleInput: ; 4295 (1:4295) ld hl, DuelMenuFunctionTable jp JumpToFunctionInTable -DuelMenuFunctionTable: ; 42f1 (1:42f1) +DuelMenuFunctionTable: dw DuelMenu_Hand dw DuelMenu_Attack dw DuelMenu_Check @@ -410,7 +353,7 @@ DuelMenuFunctionTable: ; 42f1 (1:42f1) dw DuelMenu_Retreat dw DuelMenu_Done -Func_42fd: ; 42fd (1:42fd) +DrawCardFromDeckToHand: call DrawCardFromDeck call nc, AddCardToHand ld a, OPPACTION_DRAW_CARD @@ -418,52 +361,52 @@ Func_42fd: ; 42fd (1:42fd) jp PrintDuelMenuAndHandleInput.menu_items_printed ; triggered by pressing B + UP in the duel menu -DuelMenuShortcut_OpponentPlayArea: ; 430b (1:430b) +DuelMenuShortcut_OpponentPlayArea: call OpenNonTurnHolderPlayAreaScreen jp DuelMainInterface ; triggered by pressing B + DOWN in the duel menu -DuelMenuShortcut_PlayerPlayArea: ; 4311 (1:4311) +DuelMenuShortcut_PlayerPlayArea: call OpenTurnHolderPlayAreaScreen jp DuelMainInterface ; triggered by pressing B + RIGHT in the duel menu -DuelMenuShortcut_OpponentDiscardPile: ; 4317 (1:4317) +DuelMenuShortcut_OpponentDiscardPile: call OpenNonTurnHolderDiscardPileScreen jp c, PrintDuelMenuAndHandleInput jp DuelMainInterface ; triggered by pressing B + LEFT in the duel menu -DuelMenuShortcut_PlayerDiscardPile: ; 4320 (1:4320) +DuelMenuShortcut_PlayerDiscardPile: call OpenTurnHolderDiscardPileScreen jp c, PrintDuelMenuAndHandleInput jp DuelMainInterface ; draw the non-turn holder's play area screen -OpenNonTurnHolderPlayAreaScreen: ; 4329 (1:4329) +OpenNonTurnHolderPlayAreaScreen: call SwapTurn call OpenTurnHolderPlayAreaScreen call SwapTurn ret ; draw the turn holder's play area screen -OpenTurnHolderPlayAreaScreen: ; 4333 (1:4333) +OpenTurnHolderPlayAreaScreen: call HasAlivePokemonInPlayArea jp OpenPlayAreaScreenForViewing ; draw the non-turn holder's discard pile screen -OpenNonTurnHolderDiscardPileScreen: ; 4339 (1:4339) +OpenNonTurnHolderDiscardPileScreen: call SwapTurn call OpenDiscardPileScreen jp SwapTurn ; draw the turn holder's discard pile screen -OpenTurnHolderDiscardPileScreen: ; 4342 (1:4342) +OpenTurnHolderDiscardPileScreen: jp OpenDiscardPileScreen ; draw the non-turn holder's hand screen. simpler version of OpenPlayerHandScreen ; used only for checking the cards rather than for playing them. -OpenNonTurnHolderHandScreen_Simple: ; 4345 (1:4345) +OpenNonTurnHolderHandScreen_Simple: call SwapTurn call OpenTurnHolderHandScreen_Simple jp SwapTurn @@ -471,7 +414,7 @@ OpenNonTurnHolderHandScreen_Simple: ; 4345 (1:4345) ; draw the turn holder's hand screen. simpler version of OpenPlayerHandScreen ; used only for checking the cards rather than for playing them. ; used for example in the "Your Play Area" screen of the Check menu -OpenTurnHolderHandScreen_Simple: ; 434e (1:434e) +OpenTurnHolderHandScreen_Simple: call CreateHandCardList jr c, .no_cards_in_hand call InitAndDrawCardListScreenLayout @@ -483,19 +426,19 @@ OpenTurnHolderHandScreen_Simple: ; 434e (1:434e) jp DrawWideTextBox_WaitForInput ; triggered by pressing B + START in the duel menu -DuelMenuShortcut_OpponentActivePokemon: ; 4364 (1:4364) +DuelMenuShortcut_OpponentActivePokemon: call SwapTurn call OpenActivePokemonScreen call SwapTurn jp DuelMainInterface ; triggered by pressing START in the duel menu -DuelMenuShortcut_PlayerActivePokemon: ; 4370 (1:4370) +DuelMenuShortcut_PlayerActivePokemon: call OpenActivePokemonScreen jp DuelMainInterface ; draw the turn holder's active Pokemon screen if it exists -OpenActivePokemonScreen: ; 4376 (1:4376) +OpenActivePokemonScreen: ld a, DUELVARS_ARENA_CARD call GetTurnDuelistVariable cp -1 @@ -510,14 +453,14 @@ OpenActivePokemonScreen: ; 4376 (1:4376) ret ; triggered by selecting the "Pkmn Power" item in the duel menu -DuelMenu_PkmnPower: ; 438e (1:438e) +DuelMenu_PkmnPower: call Func_6431 jp c, DuelMainInterface call UseAttackOrPokemonPower jp DuelMainInterface ; triggered by selecting the "Done" item in the duel menu -DuelMenu_Done: ; 439a (1:439a) +DuelMenu_Done: ld a, PRACTICEDUEL_REPEAT_INSTRUCTIONS call DoPracticeDuelAction ; always jumps on practice duel (no action requires player to select Done) @@ -528,7 +471,7 @@ DuelMenu_Done: ; 439a (1:439a) ret ; triggered by selecting the "Retreat" item in the duel menu -DuelMenu_Retreat: ; 43ab (1:43ab) +DuelMenu_Retreat: ld a, DUELVARS_ARENA_CARD_STATUS call GetTurnDuelistVariable and CNF_SLP_PRZ @@ -593,7 +536,7 @@ DuelMenu_Retreat: ; 43ab (1:43ab) jp PrintDuelMenuAndHandleInput ; triggered by selecting the "Hand" item in the duel menu -DuelMenu_Hand: ; 4425 (1:4425) +DuelMenu_Hand: ld a, DUELVARS_NUMBER_OF_CARDS_IN_HAND call GetTurnDuelistVariable or a @@ -604,7 +547,7 @@ DuelMenu_Hand: ; 4425 (1:4425) ; draw the screen for the player's hand and handle user input to for example check ; a card or attempt to use a card, playing the card if possible in that case. -OpenPlayerHandScreen: ; 4436 (1:4436) +OpenPlayerHandScreen: call CreateHandCardList call InitAndDrawCardListScreenLayout ldtx hl, PleaseSelectHandText @@ -637,7 +580,7 @@ OpenPlayerHandScreen: ; 4436 (1:4436) ; play the energy card with deck index at hTempCardIndex_ff98 ; c contains the type of energy card being played -PlayEnergyCard: ; 4477 (1:4477) +PlayEnergyCard: ld a, c cp TYPE_ENERGY_WATER jr nz, .not_water_energy @@ -686,7 +629,7 @@ PlayEnergyCard: ; 4477 (1:4477) ; fallthrough ; reload the card list screen after the card trying to play couldn't be played -ReloadCardListScreen: ; 44d2 (1:44d2) +ReloadCardListScreen: call CreateHandCardList ; skip doing the things that have already been done when initially opened call DrawCardListScreenLayout @@ -696,7 +639,7 @@ ReloadCardListScreen: ; 44d2 (1:44d2) ; Pokemon card over a Pokemon card already in play to evolve it. ; the card to use is loaded in wLoadedCard1 and its deck index is at hTempCardIndex_ff98. ; return nc if the card was played, carry if it wasn't. -PlayPokemonCard: ; 44db (1:44db) +PlayPokemonCard: ld a, [wLoadedCard1Stage] or a ; BASIC jr nz, .try_evolve ; jump if the card being played is a Stage 1 or 2 Pokemon @@ -797,28 +740,28 @@ PlayPokemonCard: ; 44db (1:44db) ret ; triggered by selecting the "Check" item in the duel menu -DuelMenu_Check: ; 4585 (1:4585) +DuelMenu_Check: call Func_3b31 call OpenDuelCheckMenu jp DuelMainInterface ; triggered by pressing SELECT in the duel menu -DuelMenuShortcut_BothActivePokemon: ; 458e (1:458e) +DuelMenuShortcut_BothActivePokemon: call Func_3b31 call Func_4597 jp DuelMainInterface -Func_4597: ; 4597 (1:4597) +Func_4597: call OpenInPlayAreaScreen_FromSelectButton ret c - call Func_45a9 + call .Func_45a9 ret c call SwapTurn - call Func_45a9 + call .Func_45a9 call SwapTurn ret -Func_45a9: ; 45a9 (1:45a9) +.Func_45a9 call HasAlivePokemonInPlayArea ld a, $02 ld [wcbd4], a @@ -832,7 +775,7 @@ Func_45a9: ; 45a9 (1:45a9) ; check if the turn holder's arena Pokemon is unable to retreat due to ; some status condition or due the bench containing no alive Pokemon. ; return carry if unable, nc if able. -CheckAbleToRetreat: ; 45bb (1:45bb) +CheckAbleToRetreat: call CheckCantRetreatDueToAcid ret c call CheckIfActiveCardParalyzedOrAsleep @@ -866,7 +809,7 @@ CheckAbleToRetreat: ; 45bb (1:45bb) ; check if the turn holder's arena Pokemon has enough energies attached to it ; in order to retreat. Return carry if it doesn't. ; load amount of energies required to wEnergyCardsRequiredToRetreat. -CheckIfEnoughEnergiesToRetreat: ; 45f4 (1:45f4) +CheckIfEnoughEnergiesToRetreat: ld e, PLAY_AREA_ARENA call GetPlayAreaCardAttachedEnergies xor a @@ -887,7 +830,7 @@ CheckIfEnoughEnergiesToRetreat: ; 45f4 (1:45f4) ; in order to retreat a Pokemon card. also handle input in order to display ; the amount of energy cards already selected, and return whenever enough ; energy cards have been selected or if the player declines to retreat. -DisplayRetreatScreen: ; 4611 (1:4611) +DisplayRetreatScreen: ld a, $ff ldh [hTempRetreatCostCards], a ld a, [wEnergyCardsRequiredToRetreat] @@ -948,7 +891,7 @@ DisplayRetreatScreen: ; 4611 (1:4611) ; in order to retreat a Pokemon card or use an attack like Ember. includes the ; card's information and a menu to select the attached energy cards to discard. ; input: a = PLAY_AREA_* of the Pokemon trying to discard energies from. -DisplayEnergyDiscardScreen: ; 4673 (1:4673) +DisplayEnergyDiscardScreen: ld [wcbe0], a call EmptyScreen call LoadDuelCardSymbolTiles @@ -967,7 +910,7 @@ DisplayEnergyDiscardScreen: ; 4673 (1:4673) ; display the menu that belongs to the energy discard screen that lets the player ; select energy cards attached to a Pokemon card in order to retreat it or use ; an attack like Ember, Flamethrower... -DisplayEnergyDiscardMenu: ; 4693 (1:4693) +DisplayEnergyDiscardMenu: lb de, 0, 3 lb bc, 20, 10 call DrawRegularTextBox @@ -988,7 +931,7 @@ DisplayEnergyDiscardMenu: ; 4693 (1:4693) ; and [wEnergyDiscardMenuDenominator] is the total number of energies that are required to discard. ; if [wEnergyDiscardMenuDenominator] == 0: ; prints only "[wEnergyDiscardMenuNumerator]" -HandleEnergyDiscardMenuInput: ; 46b7 (1:46b7) +HandleEnergyDiscardMenuInput: lb bc, 16, 16 ld a, [wEnergyDiscardMenuDenominator] or a @@ -1021,7 +964,7 @@ HandleEnergyDiscardMenuInput: ; 46b7 (1:46b7) scf ret -EnergyDiscardCardListParameters: ; 46f3 (1:46f3) +EnergyDiscardCardListParameters: db 1, 5 ; cursor x, cursor y db 4 ; item x db 14 ; maximum length, in tiles, occupied by the name and level string of each card in the list @@ -1031,7 +974,7 @@ EnergyDiscardCardListParameters: ; 46f3 (1:46f3) dw NULL ; function pointer if non-0 ; triggered by selecting the "Attack" item in the duel menu -DuelMenu_Attack: ; 46fc (1:46fc) +DuelMenu_Attack: call HandleCantAttackSubstatus jr c, .alert_cant_attack_and_cancel_menu call CheckIfActiveCardParalyzedOrAsleep @@ -1112,7 +1055,7 @@ DuelMenu_Attack: ; 46fc (1:46fc) ; draw the attack page of the card at wLoadedCard1 and of the attack selected in the Attack ; menu by hCurMenuItem, and listen for input in order to switch the page or to exit. -OpenAttackPage: ; 478b (1:478b) +OpenAttackPage: ld a, CARDPAGE_POKEMON_OVERVIEW ld [wCardPageNumber], a xor a @@ -1163,7 +1106,7 @@ OpenAttackPage: ; 478b (1:478b) jr z, .loop ret -AttackMenuParameters: ; 47e4 (1:47e4) +AttackMenuParameters: db 1, 13 ; cursor x, cursor y db 2 ; y displacement between items db 2 ; number of items @@ -1172,25 +1115,25 @@ AttackMenuParameters: ; 47e4 (1:47e4) dw NULL ; function pointer if non-0 ; display the card page with id at wAttackPageNumber of wLoadedCard1 -DisplayAttackPage: ; 47ec (1:47ec) +DisplayAttackPage: ld a, [wAttackPageNumber] ld hl, AttackPageDisplayPointerTable jp JumpToFunctionInTable -AttackPageDisplayPointerTable: ; 47f5 (1:47f5) +AttackPageDisplayPointerTable: dw DisplayAttackPage_Attack1Page1 ; ATTACKPAGE_ATTACK1_1 dw DisplayAttackPage_Attack1Page2 ; ATTACKPAGE_ATTACK1_2 dw DisplayAttackPage_Attack2Page1 ; ATTACKPAGE_ATTACK2_1 dw DisplayAttackPage_Attack2Page2 ; ATTACKPAGE_ATTACK2_2 ; display ATTACKPAGE_ATTACK1_1 -DisplayAttackPage_Attack1Page1: ; 47fd (1:47fd) +DisplayAttackPage_Attack1Page1: call DisplayCardPage_PokemonAttack1Page1 jr SwitchAttackPage ; display ATTACKPAGE_ATTACK1_2 if it exists. otherwise return in order ; to switch back to ATTACKPAGE_ATTACK1_1 and display it instead. -DisplayAttackPage_Attack1Page2: ; 4802 (1:4802) +DisplayAttackPage_Attack1Page2: ld hl, wLoadedCard1Atk1Description + 2 ld a, [hli] or [hl] @@ -1199,13 +1142,13 @@ DisplayAttackPage_Attack1Page2: ; 4802 (1:4802) jr SwitchAttackPage ; display ATTACKPAGE_ATTACK2_1 -DisplayAttackPage_Attack2Page1: ; 480d (1:480d) +DisplayAttackPage_Attack2Page1: call DisplayCardPage_PokemonAttack2Page1 jr SwitchAttackPage ; display ATTACKPAGE_ATTACK2_2 if it exists. otherwise return in order ; to switch back to ATTACKPAGE_ATTACK2_1 and display it instead. -DisplayAttackPage_Attack2Page2: ; 4812 (1:4812) +DisplayAttackPage_Attack2Page2: ld hl, wLoadedCard1Atk2Description + 2 ld a, [hli] or [hl] @@ -1215,7 +1158,7 @@ DisplayAttackPage_Attack2Page2: ; 4812 (1:4812) ; switch to ATTACKPAGE_ATTACK*_2 if in ATTACKPAGE_ATTACK*_1 and vice versa. ; sets the next attack page to switch to if Right or Left are pressed. -SwitchAttackPage: ; 481b (1:481b) +SwitchAttackPage: ld hl, wAttackPageNumber ld a, $01 xor [hl] @@ -1228,7 +1171,7 @@ SwitchAttackPage: ; 481b (1:481b) ; if pokemon's first attack slot isn't empty or a Pokemon Power: <card_index>, 0 ; if pokemon's second attack slot isn't empty or a Pokemon Power: <card_index>, 1 ; return the amount of non-empty, non-Pokemon Power attacks in a. -PrintAndLoadAttacksToDuelTempList: ; 4823 (1:4823) +PrintAndLoadAttacksToDuelTempList: call DrawWideTextBox ld a, DUELVARS_ARENA_CARD call GetTurnDuelistVariable @@ -1280,7 +1223,7 @@ PrintAndLoadAttacksToDuelTempList: ; 4823 (1:4823) ; given de = wLoadedCard*Atk*Name, return carry if the attack is a ; Pkmn Power or if the attack slot is empty. -CheckAttackSlotEmptyOrPokemonPower: ; 4872 (1:4872) +CheckAttackSlotEmptyOrPokemonPower: push hl push de push bc @@ -1309,7 +1252,7 @@ CheckAttackSlotEmptyOrPokemonPower: ; 4872 (1:4872) ; check if the arena pokemon card has enough energy attached to it ; in order to use the selected attack. ; returns: carry if not enough energy, nc if enough energy. -CheckIfEnoughEnergiesToAttack: ; 488f (1:488f) +CheckIfEnoughEnergiesToAttack: push hl push bc ld e, PLAY_AREA_ARENA @@ -1335,7 +1278,7 @@ CheckIfEnoughEnergiesToAttack: ; 488f (1:488f) ; e = attack index (0 or 1) ; wAttachedEnergies and wTotalAttachedEnergies ; returns: carry if not enough energy, nc if enough energy. -_CheckIfEnoughEnergiesToAttack: ; 48ac (1:48ac) +_CheckIfEnoughEnergiesToAttack: push de ld a, d call LoadCardDataToBuffer1_FromDeckIndex @@ -1396,7 +1339,7 @@ _CheckIfEnoughEnergiesToAttack: ; 48ac (1:48ac) ; given the amount of energies of a specific type required for an attack in the ; lower nybble of register a, test if the pokemon card has enough energies of that type ; to use the attack. Return carry if not enough energy, nc if enough energy. -CheckIfEnoughEnergiesOfType: ; 4900 (1:4900) +CheckIfEnoughEnergiesOfType: and $f push af push hl @@ -1421,7 +1364,7 @@ CheckIfEnoughEnergiesOfType: ; 4900 (1:4900) ; return carry and the corresponding text in hl if the turn holder's ; arena Pokemon card is paralyzed or asleep. -CheckIfActiveCardParalyzedOrAsleep: ; 4918 (1:4918) +CheckIfActiveCardParalyzedOrAsleep: ld a, DUELVARS_ARENA_CARD_STATUS call GetTurnDuelistVariable and CNF_SLP_PRZ @@ -1442,7 +1385,7 @@ CheckIfActiveCardParalyzedOrAsleep: ; 4918 (1:4918) ; display the animation of the turn duelist drawing one card at the beginning of the turn ; if there isn't any card left in the deck, let the player know with a text message -DisplayDrawOneCardScreen: ; 4933 (1:4933) +DisplayDrawOneCardScreen: ld a, 1 ; fallthrough @@ -1450,7 +1393,7 @@ DisplayDrawOneCardScreen: ; 4933 (1:4933) ; if there isn't any card left in the deck, let the player know with a text message. ; input: ; - a = number of cards to draw -DisplayDrawNCardsScreen: ; 4935 (1:4935) +DisplayDrawNCardsScreen: push hl push de push bc @@ -1515,7 +1458,7 @@ DisplayDrawNCardsScreen: ; 4935 (1:4935) ret ; animates the screen for Turn Duelist drawing a card -PlayTurnDuelistDrawAnimation: ; 49a8 (1:49a8) +PlayTurnDuelistDrawAnimation: call Func_3b21 ld e, DUEL_ANIM_PLAYER_DRAW ldh a, [hWhoseTurn] @@ -1540,7 +1483,7 @@ PlayTurnDuelistDrawAnimation: ; 49a8 (1:49a8) ; prints, for each duelist, the number of cards in the hand along with the ; hand icon, and the number of cards in the deck, along with the deck icon, ; according to each element's placement in the draw card(s) screen. -PrintDeckAndHandIconsAndNumberOfCards: ; 49ca (1:49ca) +PrintDeckAndHandIconsAndNumberOfCards: call LoadDuelDrawCardsScreenTiles ld hl, DeckAndHandIconsTileData call WriteDataBlocksToBGMap0 @@ -1560,13 +1503,13 @@ PrintDeckAndHandIconsAndNumberOfCards: ; 49ca (1:49ca) ; of cards in the deck, according to their placement in the draw card(s) screen. ; input: wNumCardsBeingDrawn = number of cards being drawn (in order to add ; them to the hand cards and subtract them from the deck cards). -PrintNumberOfHandAndDeckCards: ; 49ed (1:49ed) +PrintNumberOfHandAndDeckCards: ldh a, [hWhoseTurn] cp PLAYER_TURN jr nz, PrintOpponentNumberOfHandAndDeckCards ; fallthrough -PrintPlayerNumberOfHandAndDeckCards: ; 49f3 (1:49f3) +PrintPlayerNumberOfHandAndDeckCards: ld a, [wPlayerNumberOfCardsInHand] ld hl, wNumCardsBeingDrawn add [hl] @@ -1584,7 +1527,7 @@ PrintPlayerNumberOfHandAndDeckCards: ; 49f3 (1:49f3) lb bc, 10, 10 jp WriteTwoDigitNumberInTxSymbolFormat -PrintOpponentNumberOfHandAndDeckCards: ; 4a14 (1:4a14) +PrintOpponentNumberOfHandAndDeckCards: ld a, [wOpponentNumberOfCardsInHand] ld hl, wNumCardsBeingDrawn add [hl] @@ -1602,7 +1545,7 @@ PrintOpponentNumberOfHandAndDeckCards: ; 4a14 (1:4a14) lb bc, 11, 3 jp WriteTwoDigitNumberInTxSymbolFormat -DeckAndHandIconsTileData: ; 4a35 (1:4a35) +DeckAndHandIconsTileData: ; x, y, tiles[], 0 db 4, 3, SYM_CROSS, 0 ; x for opponent's hand db 10, 3, SYM_CROSS, 0 ; x for opponent's deck @@ -1618,7 +1561,7 @@ DeckAndHandIconsTileData: ; 4a35 (1:4a35) db 13, 10, $fa, $fb, 0 ; player's hand icon db $ff -DeckAndHandIconsCGBPalData: ; 4a6e (1:4a6e) +DeckAndHandIconsCGBPalData: ; x, y, pals[], 0 db 8, 2, $02, $02, 0 db 8, 3, $02, $02, 0 @@ -1632,7 +1575,7 @@ DeckAndHandIconsCGBPalData: ; 4a6e (1:4a6e) ; draw the portraits of the two duelists and print their names. ; also draw an horizontal line separating the two sides. -DrawDuelistPortraitsAndNames: ; 4a97 (1:4a97) +DrawDuelistPortraitsAndNames: call LoadSymbolsFont ; player's name ld de, wDefaultText @@ -1668,7 +1611,7 @@ DrawDuelistPortraitsAndNames: ; 4a97 (1:4a97) ; print the number of prizes left, of active Pokemon, and of cards left in the deck ; of both duelists. this is called when the duel ends. -PrintDuelResultStats: ; 4ad6 (1:4ad6) +PrintDuelResultStats: lb de, 8, 8 call PrintDuelistResultStats call SwapTurn @@ -1680,7 +1623,7 @@ PrintDuelResultStats: ; 4ad6 (1:4ad6) ; print, at d,e, the number of prizes left, of active Pokemon, and of cards left in ; the deck of the turn duelist. b,c are used throughout as input coords for ; WriteTwoDigitNumberInTxSymbolFormat, and d,e for InitTextPrinting_ProcessTextFromID. -PrintDuelistResultStats: ; 4ae9 (1:4ae9) +PrintDuelistResultStats: call SetNoLineSeparation ldtx hl, PrizesLeftActivePokemonCardsInDeckText call InitTextPrinting_ProcessTextFromID @@ -1719,7 +1662,7 @@ PrintDuelistResultStats: ; 4ae9 (1:4ae9) ret ; display the animation of the player drawing the card at hTempCardIndex_ff98 -DisplayPlayerDrawCardScreen: ; 4b2c (1:4b2c) +DisplayPlayerDrawCardScreen: ldtx hl, YouDrewText ldh a, [hTempCardIndex_ff98] ; fallthrough @@ -1727,12 +1670,12 @@ DisplayPlayerDrawCardScreen: ; 4b2c (1:4b2c) ; display card detail when a card is drawn or played ; hl is text to display ; a is the card's deck index -DisplayCardDetailScreen: ; 4b31 (1:4b31) +DisplayCardDetailScreen: call LoadCardDataToBuffer1_FromDeckIndex call _DisplayCardDetailScreen ret -Func_4b38: ; 4b38 (1:4b38) +Func_4b38: ld a, [wDuelTempList] cp $ff ret z @@ -1749,7 +1692,12 @@ Func_4b38: ; 4b38 (1:4b38) call DrawWideTextBox_WaitForInput ret -Func_4b60: ; 4b60 (1:4b60) +; handles the initial duel actions: +; - drawing starting hand and placing the Basic Pokemon cards +; - placing the appropriate number of prize cards +; - tossing coin to determine first player to go +HandleDuelSetup: +; init variables and shuffle cards call InitializeDuelVariables call SwapTurn call InitializeDuelVariables @@ -1761,6 +1709,8 @@ Func_4b60: ; 4b60 (1:4b60) call ShuffleDeckAndDrawSevenCards call SwapTurn ld c, a + +; check if any Basic Pokémon cards were drawn ldh a, [hTemp_ffa0] ld b, a and c @@ -1802,7 +1752,7 @@ Func_4b60: ; 4b60 (1:4b60) call InitializeDuelVariables call SwapTurn call PrintReturnCardsToDeckDrawAgain - jp Func_4b60 + jp HandleDuelSetup .hand_cards_ok ldh a, [hWhoseTurn] @@ -1813,11 +1763,12 @@ Func_4b60: ; 4b60 (1:4b60) call SwapTurn call ChooseInitialArenaAndBenchPokemon call SwapTurn - jp c, .asm_4c77 + jp c, .error call DrawPlayAreaToPlacePrizeCards ldtx hl, PlacingThePrizesText call DrawWideTextBox_WaitForInput call ExchangeRNG + ld a, [wDuelInitialPrizes] ld l, a ld h, 0 @@ -1825,9 +1776,10 @@ Func_4b60: ; 4b60 (1:4b60) ldtx hl, PleasePlacePrizesText call DrawWideTextBox_PrintText call EnableLCD - call .asm_4c7c + call .PlacePrizes call WaitForWideTextBoxInput pop af + ldh [hWhoseTurn], a call InitTurnDuelistPrizes call SwapTurn @@ -1841,6 +1793,8 @@ Func_4b60: ; 4b60 (1:4b60) ldh a, [hWhoseTurn] cp PLAYER_TURN jr nz, .opponent_turn + +; player flips coin ld de, wDefaultText call CopyPlayerName ld hl, $0000 @@ -1858,6 +1812,7 @@ Func_4b60: ; 4b60 (1:4b60) ret .opponent_turn +; opp flips coin ld de, wDefaultText call CopyOpponentName ld hl, $0000 @@ -1874,32 +1829,37 @@ Func_4b60: ; 4b60 (1:4b60) or a ret -.asm_4c77 +.error pop af ldh [hWhoseTurn], a scf ret -.asm_4c7c - ld hl, .data_4cbd - ld e, $34 +; places the prize cards on both sides +; of the Play Area (player & opp) +.PlacePrizes + ld hl, .PrizeCardCoordinates + ld e, DECK_SIZE - 7 - 1 ; deck size - cards drawn - 1 ld a, [wDuelInitialPrizes] ld d, a -.asm_4c85 + +.place_prize push de - ld b, $14 -.asm_4c88 + ld b, 20 ; frames to delay +.loop_delay call DoFrame call CheckSkipDelayAllowed - jr c, .asm_4c93 + jr c, .skip_delay dec b - jr nz, .asm_4c88 -.asm_4c93 - call .asm_4cb4 - call .asm_4cb4 + jr nz, .loop_delay +.skip_delay + call .DrawPrizeTile + call .DrawPrizeTile + push hl ld a, SFX_08 call PlaySFX + ; print new deck card number lb bc, 3, 5 ld a, e call WriteTwoDigitNumberInTxSymbolFormat @@ -1908,32 +1868,33 @@ Func_4b60: ; 4b60 (1:4b60) call WriteTwoDigitNumberInTxSymbolFormat pop hl pop de - dec e - dec d - jr nz, .asm_4c85 + dec e ; decrease number of cards in deck + dec d ; decrease number of prize cards left + jr nz, .place_prize ret -.asm_4cb4 +.DrawPrizeTile ld b, [hl] inc hl ld c, [hl] inc hl - ld a, $ac + ld a, $ac ; prize card tile jp WriteByteToBGMap0 -.data_4cbd - db $05, $06, $0e, $05 - db $06, $06, $0d, $05 - db $05, $07, $0e, $04 - db $06, $07, $0d, $04 - db $05, $08, $0e, $03 - db $06, $08, $0d, $03 +.PrizeCardCoordinates +; player x, player y, opp x, opp y + db 5, 6, 14, 5 ; Prize 1 + db 6, 6, 13, 5 ; Prize 2 + db 5, 7, 14, 4 ; Prize 3 + db 6, 7, 13, 4 ; Prize 4 + db 5, 8, 14, 3 ; Prize 5 + db 6, 8, 13, 3 ; Prize 6 ; have the turn duelist place, at the beginning of the duel, the active Pokemon ; and 0 more bench Pokemon, all of which must be basic Pokemon cards. ; also transmits the turn holder's duelvars to the other duelist in a link duel. ; called twice, once for each duelist. -ChooseInitialArenaAndBenchPokemon: ; 4cd5 (1:4cd5) +ChooseInitialArenaAndBenchPokemon: ld a, DUELVARS_DUELIST_TYPE call GetTurnDuelistVariable cp DUELIST_TYPE_PLAYER @@ -2041,7 +2002,7 @@ ChooseInitialArenaAndBenchPokemon: ; 4cd5 (1:4cd5) ; the turn duelist shuffles the deck unless it's a practice duel, then draws 7 cards ; returns $00 in a and carry if no basic Pokemon cards are drawn, and $01 in a otherwise -ShuffleDeckAndDrawSevenCards: ; 4d97 (1:4d97) +ShuffleDeckAndDrawSevenCards: call InitializeDuelVariables ld a, [wDuelType] cp DUELTYPE_PRACTICE @@ -2080,7 +2041,7 @@ ShuffleDeckAndDrawSevenCards: ; 4d97 (1:4d97) ; return nc if the card at wLoadedCard1 is a basic Pokemon card ; MYSTERIOUS_FOSSIL and CLEFAIRY_DOLL do count as basic Pokemon cards -IsLoadedCard1BasicPokemon: ; 4dd1 (1:4dd1) +IsLoadedCard1BasicPokemon: ld a, [wLoadedCard1ID] cp MYSTERIOUS_FOSSIL jr z, .basic @@ -2112,14 +2073,14 @@ IsLoadedCard1BasicPokemon: ; 4dd1 (1:4dd1) or a ret ; nz -DisplayNoBasicPokemonInHandScreenAndText: ; 4df3 (1:4df3) +DisplayNoBasicPokemonInHandScreenAndText: ldtx hl, ThereAreNoBasicPokemonInHand call DrawWideTextBox_WaitForInput call DisplayNoBasicPokemonInHandScreen ; fallthrough ; prints ReturnCardsToDeckAndDrawAgainText in a textbox and calls ExchangeRNG -PrintReturnCardsToDeckDrawAgain: ; 4dfc (1:4dfc) +PrintReturnCardsToDeckDrawAgain: ldtx hl, ReturnCardsToDeckAndDrawAgainText call DrawWideTextBox_WaitForInput call ExchangeRNG @@ -2127,7 +2088,7 @@ PrintReturnCardsToDeckDrawAgain: ; 4dfc (1:4dfc) ; display a bare list of seven hand cards of the turn duelist, and the duelist's name above ; used to let the player know that there are no basic Pokemon in the hand and need to redraw -DisplayNoBasicPokemonInHandScreen: ; 4e06 (1:4e06) +DisplayNoBasicPokemonInHandScreen: call EmptyScreen call LoadDuelCardSymbolTiles lb de, 0, 0 @@ -2146,7 +2107,7 @@ DisplayNoBasicPokemonInHandScreen: ; 4e06 (1:4e06) call WaitForWideTextBoxInput ret -NoBasicPokemonCardListParameters: ; 4e37 (1:4e37) +NoBasicPokemonCardListParameters: db 1, 3 ; cursor x, cursor y db 4 ; item x db 14 ; maximum length, in tiles, occupied by the name and level string of each card in the list @@ -2157,7 +2118,7 @@ NoBasicPokemonCardListParameters: ; 4e37 (1:4e37) ; used only during the practice duel with Sam. ; displays the list with the player's cards in hand, and the player's name above the list. -DisplayPracticeDuelPlayerHandScreen: ; 4e40 (1:4e40) +DisplayPracticeDuelPlayerHandScreen: call CreateHandCardList call EmptyScreen call LoadDuelCardSymbolTiles @@ -2175,7 +2136,7 @@ DisplayPracticeDuelPlayerHandScreen: ; 4e40 (1:4e40) call EnableLCD ret -PlayShuffleAndDrawCardsAnimation_TurnDuelist: ; 4e6e (1:4e6e) +PlayShuffleAndDrawCardsAnimation_TurnDuelist: ld b, DUEL_ANIM_PLAYER_SHUFFLE ld c, DUEL_ANIM_PLAYER_DRAW ldh a, [hWhoseTurn] @@ -2188,7 +2149,7 @@ PlayShuffleAndDrawCardsAnimation_TurnDuelist: ; 4e6e (1:4e6e) ldtx de, Drew7CardsText jr PlayShuffleAndDrawCardsAnimation -PlayShuffleAndDrawCardsAnimation_BothDuelists: ; 4e84 (1:4e84) +PlayShuffleAndDrawCardsAnimation_BothDuelists: ld b, DUEL_ANIM_BOTH_SHUFFLE ld c, DUEL_ANIM_BOTH_DRAW ldtx hl, EachPlayerShuffleOpponentsDeckText @@ -2205,7 +2166,7 @@ PlayShuffleAndDrawCardsAnimation_BothDuelists: ; 4e84 (1:4e84) ; c = drawing animation index ; hl = text to print while shuffling ; de = text to print while drawing -PlayShuffleAndDrawCardsAnimation: ; 4e98 (1:4e98) +PlayShuffleAndDrawCardsAnimation: push bc push de push hl @@ -2295,7 +2256,7 @@ PlayShuffleAndDrawCardsAnimation: ; 4e98 (1:4e98) pop bc ret -Func_4f2d: ; 4f2d (1:4f2d) +Func_4f2d: ld a, [wDuelDisplayedScreen] cp SHUFFLE_DECK jr z, .skip_draw_scene @@ -2366,7 +2327,7 @@ Func_4f2d: ; 4f2d (1:4f2d) ; draw the main scene during a duel, except the contents of the bottom text box, ; which depend on the type of duelist holding the turn. ; includes the background, both arena Pokemon, and both HUDs. -DrawDuelMainScene: ; 4f9d (1:4f9d) +DrawDuelMainScene: ld a, DUELVARS_DUELIST_TYPE call GetTurnDuelistVariable cp DUELIST_TYPE_PLAYER @@ -2438,7 +2399,7 @@ DrawDuelMainScene: ; 4f9d (1:4f9d) ; draws the main elements of the main duel interface, including HUDs, HPs, card names ; and color symbols, attached cards, and other information, of both duelists. -DrawDuelHUDs: ; 503a (1:503a) +DrawDuelHUDs: ld a, DUELVARS_DUELIST_TYPE call GetTurnDuelistVariable cp DUELIST_TYPE_PLAYER @@ -2479,7 +2440,7 @@ DrawDuelHUDs: ; 503a (1:503a) call SwapTurn ret -DrawDuelHUD: ; 5093 (1:5093) +DrawDuelHUD: ld hl, wHUDEnergyAndHPBarsX ld [hl], b inc hl @@ -2616,7 +2577,7 @@ DrawDuelHUD: ; 5093 (1:5093) ; draws an horizontal line that separates the arena side of each duelist ; also colorizes the line on CGB -DrawDuelHorizontalSeparator: ; 516f (1:516f) +DrawDuelHorizontalSeparator: ld hl, DuelHorizontalSeparatorTileData call WriteDataBlocksToBGMap0 ld a, [wConsole] @@ -2628,7 +2589,7 @@ DrawDuelHorizontalSeparator: ; 516f (1:516f) call BankswitchVRAM0 ret -DuelEAndHPTileData: ; 5188 (1:5188) +DuelEAndHPTileData: ; x, y, tiles[], 0 db 1, 1, SYM_E, 0 db 1, 2, SYM_HP, 0 @@ -2636,7 +2597,7 @@ DuelEAndHPTileData: ; 5188 (1:5188) db 9, 9, SYM_HP, 0 db $ff -DuelHorizontalSeparatorTileData: ; 5199 (1:5199) +DuelHorizontalSeparatorTileData: ; x, y, tiles[], 0 db 0, 4, $37, $37, $37, $37, $37, $37, $37, $37, $37, $31, $32, 0 db 9, 5, $33, $34, 0 @@ -2644,7 +2605,7 @@ DuelHorizontalSeparatorTileData: ; 5199 (1:5199) db 9, 7, $35, $36, $37, $37, $37, $37, $37, $37, $37, $37, $37, 0 db $ff -DuelHorizontalSeparatorCGBPalData: ; 51c0 (1:51c0) +DuelHorizontalSeparatorCGBPalData: ; x, y, pals[], 0 db 0, 4, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, 0 db 9, 5, $02, $02, 0 @@ -2655,7 +2616,7 @@ DuelHorizontalSeparatorCGBPalData: ; 51c0 (1:51c0) ; if this is a practice duel, execute the practice duel action at wPracticeDuelAction ; if not a practice duel, always return nc ; the practice duel functions below return carry when something's wrong -DoPracticeDuelAction: ; 51e7 (1:51e7) +DoPracticeDuelAction: ld [wPracticeDuelAction], a ld a, [wIsPracticeDuel] or a @@ -2664,7 +2625,7 @@ DoPracticeDuelAction: ; 51e7 (1:51e7) ld hl, PracticeDuelActionTable jp JumpToFunctionInTable -PracticeDuelActionTable: ; 51f8 (1:51f8) +PracticeDuelActionTable: dw NULL dw PracticeDuel_DrawSevenCards dw PracticeDuel_PlayGoldeen @@ -2677,13 +2638,13 @@ PracticeDuelActionTable: ; 51f8 (1:51f8) dw PracticeDuel_PlayStaryuFromBench dw PracticeDuel_ReplaceKnockedOutPokemon -PracticeDuel_DrawSevenCards: ; 520e (1:520e) +PracticeDuel_DrawSevenCards: call DisplayPracticeDuelPlayerHandScreen call EnableLCD ldtx hl, DrawSevenCardsPracticeDuelText jp PrintPracticeDuelDrMasonInstructions -PracticeDuel_PlayGoldeen: ; 521a (1:521a) +PracticeDuel_PlayGoldeen: ld a, [wLoadedCard1ID] cp GOLDEEN ret z @@ -2692,13 +2653,13 @@ PracticeDuel_PlayGoldeen: ; 521a (1:521a) scf jp PrintPracticeDuelDrMasonInstructions -PracticeDuel_PutStaryuInBench: ; 522a (1:522a) +PracticeDuel_PutStaryuInBench: call DisplayPracticeDuelPlayerHandScreen call EnableLCD ldtx hl, PutPokemonOnBenchPracticeDuelText jp PrintPracticeDuelDrMasonInstructions -PracticeDuel_VerifyInitialPlay: ; 5236 (1:5236) +PracticeDuel_VerifyInitialPlay: ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable cp 2 @@ -2707,7 +2668,7 @@ PracticeDuel_VerifyInitialPlay: ; 5236 (1:5236) scf jp PrintPracticeDuelDrMasonInstructions -PracticeDuel_DonePuttingOnBench: ; 5245 (1:5245) +PracticeDuel_DonePuttingOnBench: call DisplayPracticeDuelPlayerHandScreen call EnableLCD ld a, $ff @@ -2715,7 +2676,7 @@ PracticeDuel_DonePuttingOnBench: ; 5245 (1:5245) ldtx hl, PressBToFinishPracticeDuelText jp PrintPracticeDuelDrMasonInstructions -PracticeDuel_PrintTurnInstructions: ; 5256 (1:5256) +PracticeDuel_PrintTurnInstructions: call DrawPracticeDuelInstructionsTextBox call EnableLCD ld a, [wDuelTurns] @@ -2735,7 +2696,7 @@ PracticeDuel_PrintTurnInstructions: ; 5256 (1:5256) call YesOrNoMenu jp PrintPracticeDuelInstructionsForCurrentTurn -PracticeDuel_VerifyPlayerTurnActions: ; 5278 (1:5278) +PracticeDuel_VerifyPlayerTurnActions: ld a, [wDuelTurns] srl a ld hl, PracticeDuelTurnVerificationPointerTable @@ -2744,7 +2705,7 @@ PracticeDuel_VerifyPlayerTurnActions: ; 5278 (1:5278) ret nc ; fallthrough -PracticeDuel_RepeatInstructions: ; 5284 (1:5284) +PracticeDuel_RepeatInstructions: ldtx hl, FollowMyGuidancePracticeDuelText call PrintPracticeDuelDrMasonInstructions ; restart the turn from the saved data of the previous turn @@ -2758,7 +2719,7 @@ PracticeDuel_RepeatInstructions: ; 5284 (1:5284) scf ret -PracticeDuel_PlayStaryuFromBench: ; 529b (1:529b) +PracticeDuel_PlayStaryuFromBench: ld a, [wDuelTurns] cp 7 jr z, .its_sam_turn_4 @@ -2771,7 +2732,7 @@ PracticeDuel_PlayStaryuFromBench: ; 529b (1:529b) ld hl, PracticeDuelText_SamTurn4 jp PrintPracticeDuelInstructions -PracticeDuel_ReplaceKnockedOutPokemon: ; 52b0 (1:52b0) +PracticeDuel_ReplaceKnockedOutPokemon: ldh a, [hTempPlayAreaLocation_ff9d] cp PLAY_AREA_BENCH_1 ret z @@ -2782,83 +2743,18 @@ PracticeDuel_ReplaceKnockedOutPokemon: ; 52b0 (1:52b0) ; fallthrough ; print a text box with given the text id at hl, labeled as 'Dr. Mason' -PrintPracticeDuelDrMasonInstructions: ; 52bc (1:52bc) +PrintPracticeDuelDrMasonInstructions: push af ldtx de, DrMasonText call PrintScrollableText_WithTextBoxLabel pop af ret -PracticeDuelTextPointerTable: ; 52c5 (1:52c5) - dw PracticeDuelText_Turn1 - dw PracticeDuelText_Turn2 - dw PracticeDuelText_Turn3 - dw PracticeDuelText_Turn4 - dw PracticeDuelText_Turn5 - dw PracticeDuelText_Turn6 - dw PracticeDuelText_Turn7 - dw PracticeDuelText_Turn8 - -practicetext: MACRO - db \1 ; Y coord to place the point-by-point instruction - tx \2 ; Dr. Mason's instruction - tx \3 ; static point-by-point instruction -ENDM - -PracticeDuelText_Turn1: - practicetext 2, Turn1DrMason1PracticeDuelText, Turn1Instr1PracticeDuelText - practicetext 5, Turn1DrMason2PracticeDuelText, Turn1Instr2PracticeDuelText - practicetext 8, Turn1DrMason3PracticeDuelText, Turn1Instr3PracticeDuelText - db $00 - -PracticeDuelText_Turn2: - practicetext 2, Turn2DrMason1PracticeDuelText, Turn2Instr1PracticeDuelText - practicetext 5, Turn2DrMason2PracticeDuelText, Turn2Instr2PracticeDuelText - practicetext 8, Turn2DrMason3PracticeDuelText, Turn2Instr3PracticeDuelText - db $00 - -PracticeDuelText_Turn3: - practicetext 2, Turn3DrMason1PracticeDuelText, Turn3Instr1PracticeDuelText - practicetext 5, Turn3DrMason2PracticeDuelText, Turn3Instr2PracticeDuelText - practicetext 8, Turn3DrMason3PracticeDuelText, Turn3Instr3PracticeDuelText - db $00 - -PracticeDuelText_Turn4: - practicetext 2, Turn4DrMason1PracticeDuelText, Turn4Instr1PracticeDuelText - practicetext 5, Turn4DrMason2PracticeDuelText, Turn4Instr2PracticeDuelText - practicetext 8, Turn4DrMason3PracticeDuelText, Turn4Instr3PracticeDuelText - db $00 - -PracticeDuelText_Turn5: - practicetext 2, Turn5DrMason1PracticeDuelText, Turn5Instr1PracticeDuelText - practicetext 6, Turn5DrMason2PracticeDuelText, Turn5Instr2PracticeDuelText - db $00 - -PracticeDuelText_Turn6: - practicetext 2, Turn6DrMason1PracticeDuelText, Turn6Instr1PracticeDuelText - practicetext 5, Turn6DrMason2PracticeDuelText, Turn6Instr2PracticeDuelText - practicetext 8, Turn6DrMason3PracticeDuelText, Turn6Instr3PracticeDuelText - db $00 - -PracticeDuelText_Turn7: - practicetext 2, Turn7DrMason1PracticeDuelText, Turn7Instr1PracticeDuelText - practicetext 5, Turn7DrMason2PracticeDuelText, Turn7Instr2PracticeDuelText - db $00 - -PracticeDuelText_Turn8: - practicetext 2, Turn8DrMason1PracticeDuelText, Turn8Instr1PracticeDuelText - practicetext 5, Turn8DrMason2PracticeDuelText, Turn8Instr2PracticeDuelText - db $00 - -; on player's Seaking knocked out -PracticeDuelText_SamTurn4: - practicetext 2, SamTurn4DrMason1PracticeDuelText, SamTurn4Instr1PracticeDuelText - practicetext 7, SamTurn4DrMason2PracticeDuelText, SamTurn4Instr2PracticeDuelText - db $00 +INCLUDE "data/duel/practice_text.asm" ; in a practice duel, draws the text box where the point-by-point ; instructions for the next player action will be written into -DrawPracticeDuelInstructionsTextBox: ; 5351 (1:5351) +DrawPracticeDuelInstructionsTextBox: call EmptyScreen lb de, 0, 0 lb bc, 20, 12 @@ -2866,7 +2762,7 @@ DrawPracticeDuelInstructionsTextBox: ; 5351 (1:5351) ; fallthrough ; print "<Player>'s Turn [wDuelTurns]" (usually) as the textbox label -PrintPracticeDuelInstructionsTextBoxLabel: ; 535d (1:535d) +PrintPracticeDuelInstructionsTextBoxLabel: ld a, [wDuelTurns] cp 7 jr z, .replace_due_to_knockout @@ -2891,7 +2787,7 @@ PrintPracticeDuelInstructionsTextBoxLabel: ; 535d (1:535d) ; one of the structs in PracticeDuelTextPointerTable. ; if a != 0, only the point-by-point instructions are printed, otherwise ; Dr. Mason instructions are also shown in a textbox at the bottom of the screen. -PrintPracticeDuelInstructionsForCurrentTurn: ; 5382 (1:5382) +PrintPracticeDuelInstructionsForCurrentTurn: push af ld a, [wDuelTurns] and %11111110 @@ -2910,7 +2806,7 @@ PrintPracticeDuelInstructionsForCurrentTurn: ; 5382 (1:5382) ; print practice duel instructions given hl = PracticeDuelText_* ; each practicetext entry (see above) contains a Dr. Mason text along with ; a numbered instruction text, that is later printed without text delay. -PrintPracticeDuelInstructions: ; 5396 (1:5396) +PrintPracticeDuelInstructions: xor a ld [wPracticeDuelTextY], a ld a, l @@ -2950,14 +2846,14 @@ PrintPracticeDuelInstructions: ; 5396 (1:5396) jr .print_instructions_loop ; print the generic Dr. Mason's text that completes all his practice duel instructions -PrintPracticeDuelLetsPlayTheGame: ; 53d3 (1:53d3) +PrintPracticeDuelLetsPlayTheGame: ldtx hl, LetsPlayTheGamePracticeDuelText call PrintPracticeDuelDrMasonInstructions ret ; simplified version of PrintPracticeDuelInstructions that skips Dr. Mason's text ; and instead places the point-by-point instructions all at once. -PrintPracticeDuelInstructions_Fast: ; 53da (1:53da) +PrintPracticeDuelInstructions_Fast: ld a, [hli] or a jr z, PrintPracticeDuelLetsPlayTheGame @@ -2968,7 +2864,7 @@ PrintPracticeDuelInstructions_Fast: ; 53da (1:53da) ; print a practice duel point-by-point instruction at d,e, with text id at hl, ; that has been read from an entry of PracticeDuelText_* -PrintPracticeDuelNumberedInstruction: ; 53e6 (1:53e6) +PrintPracticeDuelNumberedInstruction: inc hl inc hl ld c, [hl] @@ -2985,7 +2881,7 @@ PrintPracticeDuelNumberedInstruction: ; 53e6 (1:53e6) ret ; print a single instruction bullet for the current turn -PrintNextPracticeDuelInstruction: ; 53fa (1:53fa) +PrintNextPracticeDuelInstruction: ld a, $01 ldh [hffb0], a push hl @@ -3011,7 +2907,7 @@ PrintNextPracticeDuelInstruction: ; 53fa (1:53fa) ldh [hffb0], a ret -PracticeDuelTurnVerificationPointerTable: ; 541f (1:541f) +PracticeDuelTurnVerificationPointerTable: dw PracticeDuelVerify_Turn1 dw PracticeDuelVerify_Turn2 dw PracticeDuelVerify_Turn3 @@ -3021,13 +2917,13 @@ PracticeDuelTurnVerificationPointerTable: ; 541f (1:541f) dw PracticeDuelVerify_Turn7Or8 dw PracticeDuelVerify_Turn7Or8 -PracticeDuelVerify_Turn1: ; 542f (1:542f) +PracticeDuelVerify_Turn1: ld a, [wTempCardID_ccc2] cp GOLDEEN jp nz, ReturnWrongAction ret -PracticeDuelVerify_Turn2: ; 5438 (1:5438) +PracticeDuelVerify_Turn2: ld a, [wTempCardID_ccc2] cp SEAKING jp nz, ReturnWrongAction @@ -3041,7 +2937,7 @@ PracticeDuelVerify_Turn2: ; 5438 (1:5438) jr z, ReturnWrongAction ret -PracticeDuelVerify_Turn3: ; 5454 (1:5454) +PracticeDuelVerify_Turn3: ld a, [wTempCardID_ccc2] cp SEAKING jr nz, ReturnWrongAction @@ -3052,7 +2948,7 @@ PracticeDuelVerify_Turn3: ; 5454 (1:5454) jr z, ReturnWrongAction ret -PracticeDuelVerify_Turn4: ; 5467 (1:5467) +PracticeDuelVerify_Turn4: ld a, [wPlayerNumberOfPokemonInPlayArea] cp 3 jr nz, ReturnWrongAction @@ -3069,7 +2965,7 @@ PracticeDuelVerify_Turn4: ; 5467 (1:5467) jr nz, ReturnWrongAction ret -PracticeDuelVerify_Turn5: ; 5488 (1:5488) +PracticeDuelVerify_Turn5: ld e, PLAY_AREA_ARENA call GetPlayAreaCardAttachedEnergies ld a, [wAttachedEnergies + WATER] @@ -3080,7 +2976,7 @@ PracticeDuelVerify_Turn5: ; 5488 (1:5488) jr nz, ReturnWrongAction ret -PracticeDuelVerify_Turn6: ; 549c (1:549c) +PracticeDuelVerify_Turn6: ld e, PLAY_AREA_ARENA call GetPlayAreaCardAttachedEnergies ld a, [wAttachedEnergies + WATER] @@ -3094,7 +2990,7 @@ PracticeDuelVerify_Turn6: ; 549c (1:549c) jr nz, ReturnWrongAction ret -PracticeDuelVerify_Turn7Or8: ; 54b7 (1:54b7) +PracticeDuelVerify_Turn7Or8: ld a, [wTempCardID_ccc2] cp STARMIE jr nz, ReturnWrongAction @@ -3103,13 +2999,13 @@ PracticeDuelVerify_Turn7Or8: ; 54b7 (1:54b7) jr nz, ReturnWrongAction ret -ReturnWrongAction: ; 54c6 (1:54c6) +ReturnWrongAction: scf ret ; display BOXMSG_PLAYERS_TURN or BOXMSG_OPPONENTS_TURN and print ; DuelistTurnText in a textbox. also call ExchangeRNG. -DisplayDuelistTurnScreen: ; 54c8 (1:54c8) +DisplayDuelistTurnScreen: call EmptyScreen ld c, BOXMSG_PLAYERS_TURN ldh a, [hWhoseTurn] @@ -3124,11 +3020,10 @@ DisplayDuelistTurnScreen: ; 54c8 (1:54c8) call ExchangeRNG ret -Unknown_54e2: ; 54e2 (1:54e2) -; ??? +Unknown_54e2: ; unreferenced db $00, $0c, $06, $0f, $00, $00, $00 -DuelMenuData: ; 54e9 (1:54e9) +DuelMenuData: ; x, y, text id textitem 3, 14, HandText textitem 9, 14, CheckText @@ -3144,7 +3039,7 @@ DuelMenuData: ; 54e9 (1:54e9) ; a = 0 -> prompted to place Pokemon card in arena ; a = 1 -> prompted to place Pokemon card in bench ; return carry if no card was placed (only allowed for bench) -DisplayPlaceInitialPokemonCardsScreen: ; 5502 (1:5502) +DisplayPlaceInitialPokemonCardsScreen: ld [wPlacingInitialBenchPokemon], a push hl call CreateHandCardList @@ -3184,7 +3079,7 @@ DisplayPlaceInitialPokemonCardsScreen: ; 5502 (1:5502) pop af ret -Func_5542: ; 5542 (1:5542) +Func_5542: call CreateDiscardPileCardList ret c call InitAndDrawCardListScreenLayout @@ -3193,7 +3088,7 @@ Func_5542: ; 5542 (1:5542) ret ; draw the turn holder's discard pile screen -OpenDiscardPileScreen: ; 5550 (1:5550) +OpenDiscardPileScreen: call CreateDiscardPileCardList jr c, .discard_pile_empty call InitAndDrawCardListScreenLayout @@ -3211,7 +3106,7 @@ OpenDiscardPileScreen: ; 5550 (1:5550) ; set wCardListHeaderText and SetCardListInfoBoxText to the text ; that correspond to the Discard Pile screen -SetDiscardPileScreenTexts: ; 556d (1:556d) +SetDiscardPileScreenTexts: ldtx de, YourDiscardPileText ldh a, [hWhoseTurn] cp PLAYER_TURN @@ -3222,21 +3117,21 @@ SetDiscardPileScreenTexts: ; 556d (1:556d) call SetCardListHeaderText ret -SetCardListHeaderText: ; 5580 (1:5580) +SetCardListHeaderText: ld a, e ld [wCardListHeaderText], a ld a, d ld [wCardListHeaderText + 1], a ; fallthrough -SetCardListInfoBoxText: ; 5588 (1:5588) +SetCardListInfoBoxText: ld a, l ld [wCardListInfoBoxText], a ld a, h ld [wCardListInfoBoxText + 1], a ret -Func_5591: ; 5591 (1:5591) +Func_5591: call InitAndDrawCardListScreenLayout ld a, SELECT_CHECK ld [wCardListItemSelectionMenuType], a @@ -3248,7 +3143,7 @@ Func_5591: ; 5591 (1:5591) ; is called after this if the screen corresponds to a Discard Pile list. ; the dimensions of text box where the card list is printed are 20x13, in order to accommodate ; another text box below it (wCardListInfoBoxText) as well as the image of the selected card. -InitAndDrawCardListScreenLayout: ; 559a (1:559a) +InitAndDrawCardListScreenLayout: xor a ld hl, wSelectedDuelSubMenuItem ld [hli], a @@ -3272,7 +3167,7 @@ InitAndDrawCardListScreenLayout: ; 559a (1:559a) ; same as InitAndDrawCardListScreenLayout, except that variables like wSelectedDuelSubMenuItem, ; wNoItemSelectionMenuKeys, wCardListInfoBoxText, wCardListHeaderText, etc already set by caller. -DrawCardListScreenLayout: ; 55be (1:55be) +DrawCardListScreenLayout: call ZeroObjectPositionsAndToggleOAMCopy call EmptyScreen call LoadSymbolsFont @@ -3305,7 +3200,7 @@ DrawCardListScreenLayout: ; 55be (1:55be) ; (initial page scroll offset). Usually both 0 to begin with the first card. ; returns carry if B is pressed to exit the card list screen. ; otherwise returns the selected card at hTempCardIndex_ff98 and at a. -DisplayCardList: ; 55f0 (1:55f0) +DisplayCardList: call DrawNarrowTextBox call PrintCardListHeaderAndInfoBoxTexts .reload_list @@ -3408,7 +3303,7 @@ DisplayCardList: ; 55f0 (1:55f0) scf ret -Func_5690: ; 5690 (1:5690) +Func_5690: ldh a, [hDPadHeld] and D_PAD ret z @@ -3421,7 +3316,7 @@ Func_5690: ; 5690 (1:5690) ; prints the text ID at wCardListHeaderText at 1,1 ; and the text ID at wCardListInfoBoxText at 1,14 -PrintCardListHeaderAndInfoBoxTexts: ; 56a0 (1:56a0) +PrintCardListHeaderAndInfoBoxTexts: lb de, 1, 14 call AdjustCoordinatesForBGScroll call InitTextPrinting @@ -3442,7 +3337,7 @@ PrintCardListHeaderAndInfoBoxTexts: ; 56a0 (1:56a0) ; display the SELECT|CHECK or PLAY|CHECK menu when a card of a list is selected ; and handle input. return carry if b is pressed. ; input: wCardListItemSelectionMenuType -CardListItemSelectionMenu: ; 56c2 (1:56c2) +CardListItemSelectionMenu: ld a, [wCardListItemSelectionMenuType] or a ret z @@ -3480,7 +3375,7 @@ CardListItemSelectionMenu: ; 56c2 (1:56c2) scf ret -ItemSelectionMenuParameters: ; 5708 (1:5708) +ItemSelectionMenuParameters: db 1, 14 ; cursor x, cursor y db 2 ; y displacement between items db 2 ; number of items @@ -3488,7 +3383,7 @@ ItemSelectionMenuParameters: ; 5708 (1:5708) db SYM_SPACE ; tile behind cursor dw NULL ; function pointer if non-0 -CardListParameters: ; 5710 (1:5710) +CardListParameters: db 1, 3 ; cursor x, cursor y db 4 ; item x db 14 ; maximum length, in tiles, occupied by the name and level string of each card in the list @@ -3500,7 +3395,7 @@ CardListParameters: ; 5710 (1:5710) ; return carry if any of the buttons is pressed, and load the graphics ; of the card pointed to by the cursor whenever a d-pad key is released. ; also return $ff unto hCurMenuItem if B is pressed. -CardListFunction: ; 5719 (1:5719) +CardListFunction: ldh a, [hKeysPressed] bit B_BUTTON_F, a jr nz, .exit @@ -3521,7 +3416,7 @@ CardListFunction: ; 5719 (1:5719) or a ret -Func_5735: ; 5735 (1:5735) +Func_5735: ld hl, wPrintSortNumberInCardListPtr ld de, PrintSortNumberInCardList ld [hl], e @@ -3531,7 +3426,7 @@ Func_5735: ; 5735 (1:5735) ld [wSortCardListByID], a ret -Func_5744: ; 5744 (1:5744) +Func_5744: ld hl, wPrintSortNumberInCardListPtr jp CallIndirect @@ -3539,7 +3434,7 @@ Func_5744: ; 5744 (1:5744) ; and prints the number stored in each entry ; beside the corresponding card in screen. ; used in lists for reordering cards in the Deck. -PrintSortNumberInCardList: ; 574a (1:574a) +PrintSortNumberInCardList: lb bc, 1, 2 ld hl, wDuelTempList + 10 .next @@ -3563,7 +3458,7 @@ PrintSortNumberInCardList: ; 574a (1:574a) ; triggered by checking a hand card or a discard pile card in the Check menu. ; D_UP and D_DOWN exit the card page allowing the caller to load the card page ; of the card above or below in the list. -OpenCardPage_FromCheckHandOrDiscardPile: ; 5762 (1:5762) +OpenCardPage_FromCheckHandOrDiscardPile: ld a, B_BUTTON | D_UP | D_DOWN ld [wCardPageExitKeys], a xor a ; CARDPAGETYPE_NOT_PLAY_AREA @@ -3572,7 +3467,7 @@ OpenCardPage_FromCheckHandOrDiscardPile: ; 5762 (1:5762) ; draw the card page of the card at wLoadedCard1 and listen for input ; in order to switch the page or to exit. ; triggered by checking an arena card or a bench card in the Check menu. -OpenCardPage_FromCheckPlayArea: ; 576a (1:576a) +OpenCardPage_FromCheckPlayArea: ld a, B_BUTTON ld [wCardPageExitKeys], a ld a, CARDPAGETYPE_PLAY_AREA @@ -3581,7 +3476,7 @@ OpenCardPage_FromCheckPlayArea: ; 576a (1:576a) ; draw the card page of the card at wLoadedCard1 and listen for input ; in order to switch the page or to exit. ; triggered by checking a card in the Hand menu. -OpenCardPage_FromHand: ; 5773 (1:5773) +OpenCardPage_FromHand: ld a, B_BUTTON ld [wCardPageExitKeys], a xor a ; CARDPAGETYPE_NOT_PLAY_AREA @@ -3589,7 +3484,7 @@ OpenCardPage_FromHand: ; 5773 (1:5773) ; draw the card page of the card at wLoadedCard1 and listen for input ; in order to switch the page or to exit. -OpenCardPage: ; 5779 (1:5779) +OpenCardPage: ld [wCardPageType], a call ZeroObjectPositionsAndToggleOAMCopy call EmptyScreen @@ -3640,7 +3535,7 @@ OpenCardPage: ; 5779 (1:5779) ; when GoToFirstOrNextCardPage and GoToPreviousCardPage respectively return nc ; so the "call c, DisplayCardPage" instructions makes sure the card page switched ; to is always displayed. -DisplayCardPageOnLeftOrRightPressed: ; 57cd (1:57cd) +DisplayCardPageOnLeftOrRightPressed: bit D_LEFT_F, a jr nz, .left ;.right @@ -3655,7 +3550,7 @@ DisplayCardPageOnLeftOrRightPressed: ; 57cd (1:57cd) ; draws text box that covers the whole screen ; and prints the text ID in hl, then ; waits for Player input. -DrawWholeScreenTextBox: ; 57df (1:57df) +DrawWholeScreenTextBox: push hl call EmptyScreen lb de, 0, 0 @@ -3672,7 +3567,7 @@ DrawWholeScreenTextBox: ; 57df (1:57df) call WaitForWideTextBoxInput ret -Func_5805: ; 5805 (1:5805) +Func_5805: call Func_3b31 ld a, [wNumberPrizeCardsToTake] ld l, a @@ -3744,26 +3639,26 @@ Func_5805: ; 5805 (1:5805) call DrawWideTextBox_WaitForInput jr .return_has_prizes -Func_588a: ; 588a (1:588a) +Func_588a: ld l, PLAYER_TURN ldh a, [hWhoseTurn] ld h, a jp DrawYourOrOppPlayAreaScreen_Bank0 ; display the previous valid card page -DisplayPreviousCardPage: ; 5892 (1:5892) +DisplayPreviousCardPage: call GoToPreviousCardPage jr nc, DisplayCardPage ret ; display the next valid card page or load the first valid card page if [wCardPageNumber] == 0 -DisplayFirstOrNextCardPage: ; 5898 (1:5898) +DisplayFirstOrNextCardPage: call GoToFirstOrNextCardPage ret c ; fallthrough ; display the card page with id at wCardPageNumber of wLoadedCard1 -DisplayCardPage: ; 589c (1:589c) +DisplayCardPage: ld a, [wCardPageNumber] ld hl, CardPageDisplayPointerTable call JumpToFunctionInTable @@ -3772,7 +3667,7 @@ DisplayCardPage: ; 589c (1:589c) ret ; load the tiles and palette of the card selected in card list screen -LoadSelectedCardGfx: ; 58aa (1:58aa) +LoadSelectedCardGfx: ldh a, [hCurMenuItem] call GetCardInDuelTempList call LoadCardDataToBuffer1_FromCardID @@ -3783,7 +3678,7 @@ LoadSelectedCardGfx: ; 58aa (1:58aa) call FlushAllPalettesOrSendPal23Packet ret -CardPageDisplayPointerTable: ; 58c2 (1:58c2) +CardPageDisplayPointerTable: dw DrawDuelMainScene dw DisplayCardPage_PokemonOverview ; CARDPAGE_POKEMON_OVERVIEW dw DisplayCardPage_PokemonAttack1Page1 ; CARDPAGE_POKEMON_ATTACK1_1 @@ -3803,7 +3698,7 @@ CardPageDisplayPointerTable: ; 58c2 (1:58c2) ; given the current card page at [wCardPageNumber], go to the next valid card page or load ; the first valid card page of the current card at wLoadedCard1 if [wCardPageNumber] == 0 -GoToFirstOrNextCardPage: ; 58e2 (1:58e2) +GoToFirstOrNextCardPage: ld a, [wCardPageNumber] or a jr nz, .advance_page @@ -3838,7 +3733,7 @@ GoToFirstOrNextCardPage: ; 58e2 (1:58e2) ; given the current card page at [wCardPageNumber], go to the previous ; valid card page for the current card at wLoadedCard1 -GoToPreviousCardPage: ; 5911 (1:5911) +GoToPreviousCardPage: ld hl, wCardPageNumber dec [hl] ld a, [hl] @@ -3867,11 +3762,11 @@ GoToPreviousCardPage: ; 5911 (1:5911) ; stay in card page trying to switch to (nc, nz) ; change to card page returned in a if D_LEFT/D_RIGHT pressed, or exit if A_BUTTON/START pressed (c) ; non-existent page, so skip to next/previous (nc, z) -SwitchCardPage: ; 5930 (1:5930) +SwitchCardPage: ld hl, CardPageSwitchPointerTable jp JumpToFunctionInTable -CardPageSwitchPointerTable: ; 5936 (1:5936) +CardPageSwitchPointerTable: dw CardPageSwitch_00 dw CardPageSwitch_PokemonOverviewOrDescription ; CARDPAGE_POKEMON_OVERVIEW dw CardPageSwitch_PokemonAttack1Page1 ; CARDPAGE_POKEMON_ATTACK1_1 @@ -3890,89 +3785,89 @@ CardPageSwitchPointerTable: ; 5936 (1:5936) dw CardPageSwitch_TrainerEnd ; return with CARDPAGE_POKEMON_DESCRIPTION -CardPageSwitch_00: ; 5956 (1:5956) +CardPageSwitch_00: ld a, CARDPAGE_POKEMON_DESCRIPTION scf ret ; return with current page -CardPageSwitch_PokemonOverviewOrDescription: ; 595a (1:595a) +CardPageSwitch_PokemonOverviewOrDescription: ld a, $1 or a ret ; nz ; return with current page if [wLoadedCard1Atk1Name] non-0 ; (if card has at least one attack) -CardPageSwitch_PokemonAttack1Page1: ; 595e (1:595e) +CardPageSwitch_PokemonAttack1Page1: ld hl, wLoadedCard1Atk1Name jr CheckCardPageExists ; return with current page if [wLoadedCard1Atk1Description + 2] non-0 ; (if card's first attack has a two-page description) -CardPageSwitch_PokemonAttack1Page2: ; 5963 (1:5963) +CardPageSwitch_PokemonAttack1Page2: ld hl, wLoadedCard1Atk1Description + 2 jr CheckCardPageExists ; return with current page if [wLoadedCard1Atk2Name] non-0 ; (if card has two attacks) -CardPageSwitch_PokemonAttack2Page1: ; 5968 (1:5968) +CardPageSwitch_PokemonAttack2Page1: ld hl, wLoadedCard1Atk2Name jr CheckCardPageExists ; return with current page if [wLoadedCard1Atk1Description + 2] non-0 ; (if card's second attack has a two-page description) -CardPageSwitch_PokemonAttack2Page2: ; 596d (1:596d) +CardPageSwitch_PokemonAttack2Page2: ld hl, wLoadedCard1Atk2Description + 2 ; fallthrough -CheckCardPageExists: ; 5970 (1:5970) +CheckCardPageExists: ld a, [hli] or [hl] ret ; return with CARDPAGE_POKEMON_OVERVIEW -CardPageSwitch_PokemonEnd: ; 5973 (1:5973) +CardPageSwitch_PokemonEnd: ld a, CARDPAGE_POKEMON_OVERVIEW scf ret ; return with CARDPAGE_ENERGY + 1 -CardPageSwitch_08: ; 5977 (1:5977) +CardPageSwitch_08: ld a, CARDPAGE_ENERGY + 1 scf ret ; return with current page -CardPageSwitch_EnergyOrTrainerPage1: ; 597b (1:597b) +CardPageSwitch_EnergyOrTrainerPage1: ld a, $1 or a ret ; nz ; return with current page if [wLoadedCard1NonPokemonDescription + 2] non-0 ; (if this trainer card has a two-page description) -CardPageSwitch_TrainerPage2: ; 597f (1:597f) +CardPageSwitch_TrainerPage2: ld hl, wLoadedCard1NonPokemonDescription + 2 jr CheckCardPageExists ; return with CARDPAGE_ENERGY -CardPageSwitch_EnergyEnd: ; 5984 (1:5984) +CardPageSwitch_EnergyEnd: ld a, CARDPAGE_ENERGY scf ret ; return with CARDPAGE_TRAINER_2 -CardPageSwitch_0c: ; 5988 (1:5988) +CardPageSwitch_0c: ld a, CARDPAGE_TRAINER_2 scf ret ; return with CARDPAGE_TRAINER_1 -CardPageSwitch_TrainerEnd: ; 598c (1:598c) +CardPageSwitch_TrainerEnd: ld a, CARDPAGE_TRAINER_1 scf ret -ZeroObjectPositionsAndToggleOAMCopy: ; 5990 (1:5990) +ZeroObjectPositionsAndToggleOAMCopy: call ZeroObjectPositions ld a, $01 ld [wVBlankOAMCopyToggle], a @@ -3982,7 +3877,7 @@ ZeroObjectPositionsAndToggleOAMCopy: ; 5990 (1:5990) ; d, e: X Position and Y Position of the top-left corner. ; starting tile number is $a0 (v0Tiles1 + $20 tiles). ; used to draw the image of a card in the check card screens. -PlaceCardImageOAM: ; 5999 (1:5999) +PlaceCardImageOAM: call Set_OBJ_8x16 ld l, $a0 ld c, 8 ; number of rows @@ -4014,7 +3909,7 @@ PlaceCardImageOAM: ; 5999 (1:5999) ; given the deck index of a card in the play area (i.e. -1 indicates empty) ; load the graphics (tiles and palette) of the card to de -LoadPlayAreaCardGfx: ; 59c2 (1:59c2) +LoadPlayAreaCardGfx: cp -1 ret z push de @@ -4023,7 +3918,7 @@ LoadPlayAreaCardGfx: ; 59c2 (1:59c2) ; fallthrough ; load the graphics (tiles and palette) of the card loaded in wLoadedCard1 to de -LoadLoaded1CardGfx: ; 59ca (1:59ca) +LoadLoaded1CardGfx: ld hl, wLoadedCard1Gfx ld a, [hli] ld h, [hl] @@ -4032,7 +3927,7 @@ LoadLoaded1CardGfx: ; 59ca (1:59ca) call LoadCardGfx ret -SetBGP7OrSGB2ToCardPalette: ; 59d7 (1:59d7) +SetBGP7OrSGB2ToCardPalette: ld a, [wConsole] or a ; CONSOLE_DMG ret z @@ -4053,7 +3948,7 @@ SetBGP7OrSGB2ToCardPalette: ; 59d7 (1:59d7) jr nz, .copy_pal_loop ret -SetBGP6OrSGB3ToCardPalette: ; 59f5 (1:59f5) +SetBGP6OrSGB3ToCardPalette: ld a, [wConsole] or a ; CONSOLE_DMG ret z @@ -4063,13 +3958,13 @@ SetBGP6OrSGB3ToCardPalette: ; 59f5 (1:59f5) call CopyCGBCardPalette ret -SetSGB3ToCardPalette: ; 5a04 (1:5a04) +SetSGB3ToCardPalette: ld hl, wCardPalette + 2 ld de, wTempSGBPacket + 9 ; Pal Packet color #4 (PAL23's SGB3) ld b, 6 jr SetBGP7OrSGB2ToCardPalette.copy_pal_loop -SetOBP1OrSGB3ToCardPalette: ; 5a0e (1:5a0e) +SetOBP1OrSGB3ToCardPalette: ld a, $e4 ld [wOBP0], a ld a, [wConsole] @@ -4080,7 +3975,7 @@ SetOBP1OrSGB3ToCardPalette: ; 5a0e (1:5a0e) ld a, $09 ; CGB Object Palette 1 ; fallthrough -CopyCGBCardPalette: ; 5a1e (1:5a1e) +CopyCGBCardPalette: add a add a add a ; a *= CGB_PAL_SIZE @@ -4098,7 +3993,7 @@ CopyCGBCardPalette: ; 5a1e (1:5a1e) jr nz, .copy_pal_loop ret -FlushAllPalettesOrSendPal23Packet: ; 5a34 (1:5a34) +FlushAllPalettesOrSendPal23Packet: ld a, [wConsole] or a ; CONSOLE_DMG ret z @@ -4123,7 +4018,7 @@ FlushAllPalettesOrSendPal23Packet: ; 5a34 (1:5a34) call SendSGB ret -ApplyBGP6OrSGB3ToCardImage: ; 5a56 (1:5a56) +ApplyBGP6OrSGB3ToCardImage: ld a, [wConsole] or a ; CONSOLE_DMG ret z @@ -4136,12 +4031,12 @@ ApplyBGP6OrSGB3ToCardImage: ; 5a56 (1:5a56) ld a, 3 << 0 + 3 << 2 ; Color Palette Designation ; fallthrough -SendCardAttrBlkPacket: ; 5a67 (1:5a67) +SendCardAttrBlkPacket: call CreateCardAttrBlkPacket call SendSGB ret -ApplyBGP7OrSGB2ToCardImage: ; 5a6e (1:5a6e) +ApplyBGP7OrSGB2ToCardImage: ld a, [wConsole] or a ; CONSOLE_DMG ret z @@ -4154,7 +4049,7 @@ ApplyBGP7OrSGB2ToCardImage: ; 5a6e (1:5a6e) ld a, 2 << 0 + 2 << 2 ; Color Palette Designation jr SendCardAttrBlkPacket -Func_5a81: ; 5a81 (1:5a81) +Func_5a81: ld a, [wConsole] or a ; CONSOLE_DMG ret z @@ -4180,7 +4075,7 @@ Func_5a81: ; 5a81 (1:5a81) call SendSGB ret -CreateCardAttrBlkPacket: ; 5ab5 (1:5ab5) +CreateCardAttrBlkPacket: ; sgb ATTR_BLK, 1 ; sgb_command, length ; db 1 ; number of data sets ld hl, wTempSGBPacket @@ -4198,7 +4093,7 @@ CreateCardAttrBlkPacket: ; 5ab5 (1:5ab5) pop hl ret -CreateCardAttrBlkPacket_DataSet: ; 5ac9 (1:5ac9) +CreateCardAttrBlkPacket_DataSet: ; Control Code, Color Palette Designation, X1, Y1, X2, Y2 ; db ATTR_BLK_CTRL_INSIDE + ATTR_BLK_CTRL_LINE, a, d, e, d+7, e+5 ; data set 1 ld [hl], ATTR_BLK_CTRL_INSIDE + ATTR_BLK_CTRL_LINE @@ -4218,7 +4113,7 @@ CreateCardAttrBlkPacket_DataSet: ; 5ac9 (1:5ac9) ret ; given the 8x6 card image with coordinates at de, fill its BGMap attributes with a -ApplyCardCGBAttributes: ; 5adb (1:5adb) +ApplyCardCGBAttributes: call BankswitchVRAM1 lb hl, 0, 0 lb bc, 8, 6 @@ -4230,7 +4125,7 @@ ApplyCardCGBAttributes: ; 5adb (1:5adb) ; BGP and OBP0 on DMG ; SGB0 and SGB1 on SGB ; BGP0 to BGP5 and OBP1 on CGB -SetDefaultPalettes: ; 5aeb (1:5aeb) +SetDefaultPalettes: ld a, [wConsole] cp CONSOLE_SGB jr z, .sgb @@ -4278,7 +4173,7 @@ SetDefaultPalettes: ; 5aeb (1:5aeb) jr nz, .copy_de_to_hl ret -CGBDefaultPalettes: ; 5b44 (1:5b44) +CGBDefaultPalettes: ; BGP0 and OBP0 rgb 28, 28, 24 rgb 21, 21, 16 @@ -4306,7 +4201,7 @@ CGBDefaultPalettes: ; 5b44 (1:5b44) rgb 0, 0, 0 ; first and last byte of the packet not contained here (see SetDefaultPalettes.sgb) -Pal01Packet_Default: ; 5b6c (1:5b6c) +Pal01Packet_Default: ; SGB0 rgb 28, 28, 24 rgb 21, 21, 16 @@ -4317,10 +4212,10 @@ Pal01Packet_Default: ; 5b6c (1:5b6c) rgb 28, 0, 0 rgb 0, 0, 0 -JPWriteByteToBGMap0: ; 5b7a (1:5b7a) +JPWriteByteToBGMap0: jp WriteByteToBGMap0 -DisplayCardPage_PokemonOverview: ; 5b7d (1:5b7d) +DisplayCardPage_PokemonOverview: ld a, [wCardPageType] or a ; CARDPAGETYPE_NOT_PLAY_AREA jr nz, .play_area_card_page @@ -4434,7 +4329,7 @@ DisplayCardPage_PokemonOverview: ; 5b7d (1:5b7d) ; input: ; hl: pointer to attack 1 name in a atk_data_struct (which can be inside at card_data_struct) ; e: Y coordinate to start printing the data at -PrintAttackOrPkmnPowerInformation: ; 5c33 (1:5c33) +PrintAttackOrPkmnPowerInformation: ld a, [hli] or [hl] ret z @@ -4514,7 +4409,7 @@ PrintAttackOrPkmnPowerInformation: ; 5c33 (1:5c33) ; print the number of energies required of color (type) e, and return e ++ (next color). ; the requirement of the current color is provided as input in the lower nybble of a. -PrintEnergiesOfColor: ; 5c9c (1:5c9c) +PrintEnergiesOfColor: inc e and $0f ret z @@ -4530,7 +4425,7 @@ PrintEnergiesOfColor: ; 5c9c (1:5c9c) ret ; print the weaknesses or resistances of a Pokemon card, given in a, at b,c -PrintCardPageWeaknessesOrResistances: ; 5cac (1:5cac) +PrintCardPageWeaknessesOrResistances: push bc push de ld d, a @@ -4557,7 +4452,7 @@ PrintCardPageWeaknessesOrResistances: ; 5cac (1:5cac) ; prints surrounding box, card name at 5,1, type, set 2, and rarity. ; used in all CARDPAGE_POKEMON_* and ATTACKPAGE_*, except in ; CARDPAGE_POKEMON_OVERVIEW when wCardPageType is CARDPAGETYPE_PLAY_AREA. -PrintPokemonCardPageGenericInformation: ; 5cc4 (1:5cc4) +PrintPokemonCardPageGenericInformation: call DrawCardPageSurroundingBox lb de, 5, 1 ld hl, wLoadedCard1Name @@ -4578,7 +4473,7 @@ PrintPokemonCardPageGenericInformation: ; 5cc4 (1:5cc4) ret ; draws the 20x18 surrounding box and also colorizes the card image -DrawCardPageSurroundingBox: ; 5cec (1:5cec) +DrawCardPageSurroundingBox: ld hl, wTextBoxFrameType set 7, [hl] ; colorize textbox border also on SGB (with SGB1) push hl @@ -4591,37 +4486,37 @@ DrawCardPageSurroundingBox: ; 5cec (1:5cec) call ApplyBGP6OrSGB3ToCardImage ret -CardPageRetreatWRTextData: ; 5d05 (1:5d05) +CardPageRetreatWRTextData: textitem 1, 14, RetreatCostText textitem 1, 15, WeaknessText textitem 1, 16, ResistanceText db $ff -CardPageLvHPNoTextTileData: ; 5d12 (1:5d12) +CardPageLvHPNoTextTileData: db 11, 2, SYM_Lv, 0 db 15, 2, SYM_HP, 0 ; continues to CardPageNoTextTileData -CardPageNoTextTileData: ; 5d1a (1:5d1a) +CardPageNoTextTileData: db 15, 16, SYM_No, 0 db $ff -DisplayCardPage_PokemonAttack1Page1: ; 5d1f (1:5d1f) +DisplayCardPage_PokemonAttack1Page1: ld hl, wLoadedCard1Atk1Name ld de, wLoadedCard1Atk1Description jr DisplayPokemonAttackCardPage -DisplayCardPage_PokemonAttack1Page2: ; 5d27 (1:5d27) +DisplayCardPage_PokemonAttack1Page2: ld hl, wLoadedCard1Atk1Name ld de, wLoadedCard1Atk1Description + 2 jr DisplayPokemonAttackCardPage -DisplayCardPage_PokemonAttack2Page1: ; 5d2f (1:5d2f) +DisplayCardPage_PokemonAttack2Page1: ld hl, wLoadedCard1Atk2Name ld de, wLoadedCard1Atk2Description jr DisplayPokemonAttackCardPage -DisplayCardPage_PokemonAttack2Page2: ; 5d37 (1:5d37) +DisplayCardPage_PokemonAttack2Page2: ld hl, wLoadedCard1Atk2Name ld de, wLoadedCard1Atk2Description + 2 ; fallthrough @@ -4629,7 +4524,7 @@ DisplayCardPage_PokemonAttack2Page2: ; 5d37 (1:5d37) ; input: ; hl = address of the attack's name (text id) ; de = address of the attack's description (either first or second text id) -DisplayPokemonAttackCardPage: ; 5d3d (1:5d3d) +DisplayPokemonAttackCardPage: push de push hl ; print surrounding box, card name at 5,1, type, set 2, and rarity @@ -4643,7 +4538,7 @@ DisplayPokemonAttackCardPage: ; 5d3d (1:5d3d) ; print, if non-null, the description of the trainer card, energy card, attack, ; or Pokemon power, given as a pointer to text id in hl, starting from 1,11 -PrintAttackOrNonPokemonCardDescription: ; 5d49 (1:5d49) +PrintAttackOrNonPokemonCardDescription: ld a, [hli] or [hl] ret z @@ -4652,7 +4547,7 @@ PrintAttackOrNonPokemonCardDescription: ; 5d49 (1:5d49) call PrintAttackOrCardDescription ret -DisplayCardPage_PokemonDescription: ; 5d54 (1:5d54) +DisplayCardPage_PokemonDescription: ; print surrounding box, card name at 5,1, type, set 2, and rarity call PrintPokemonCardPageGenericInformation call LoadDuelCardSymbolTiles2 @@ -4715,7 +4610,7 @@ DisplayCardPage_PokemonDescription: ; 5d54 (1:5d54) ; given a card rarity constant in a, and CardRarityTextIDs in hl, ; print the text character associated to it at d,e -PrintCardPageRarityIcon: ; 5dd3 (1:5dd3) +PrintCardPageRarityIcon: inc a add a ld c, a @@ -4725,7 +4620,7 @@ PrintCardPageRarityIcon: ; 5dd3 (1:5dd3) ret ; prints the card's set 2 icon and the full width text character of the card's rarity -DrawCardPageSet2AndRarityIcons: ; 5ddd (1:5ddd) +DrawCardPageSet2AndRarityIcons: ld a, [wLoadedCard1Set] call LoadCardSet2Tiles jr c, .icon_done @@ -4743,33 +4638,33 @@ DrawCardPageSet2AndRarityIcons: ; 5ddd (1:5ddd) call nz, PrintCardPageRarityIcon ret -CardPageLengthWeightTextData: ; 5e02 (1:5e02) +CardPageLengthWeightTextData: textitem 1, 11, LengthText textitem 1, 12, WeightText db $ff -CardPageLvHPTextTileData: ; 5e0b (1:5e0b) +CardPageLvHPTextTileData: db 11, 2, SYM_Lv, 0 db 15, 2, SYM_HP, 0 db $ff -CardRarityTextIDs: ; 5e14 (1:5e14) +CardRarityTextIDs: tx PromostarRarityText ; PROMOSTAR (unused) tx CircleRarityText ; CIRCLE tx DiamondRarityText ; DIAMOND tx StarRarityText ; STAR -DisplayCardPage_TrainerPage1: ; 5e1c (1:5e1c) +DisplayCardPage_TrainerPage1: xor a ; HEADER_TRAINER ld hl, wLoadedCard1NonPokemonDescription jr DisplayEnergyOrTrainerCardPage -DisplayCardPage_TrainerPage2: ; 5e22 (1:5e22) +DisplayCardPage_TrainerPage2: xor a ; HEADER_TRAINER ld hl, wLoadedCard1NonPokemonDescription + 2 jr DisplayEnergyOrTrainerCardPage -DisplayCardPage_Energy: ; 5e28 (1:5e28) +DisplayCardPage_Energy: ld a, HEADER_ENERGY ld hl, wLoadedCard1NonPokemonDescription ; fallthrough @@ -4777,7 +4672,7 @@ DisplayCardPage_Energy: ; 5e28 (1:5e28) ; input: ; a = HEADER_ENERGY or HEADER_TRAINER ; hl = address of the card's description (text id) -DisplayEnergyOrTrainerCardPage: ; 5e2d (1:5e2d) +DisplayEnergyOrTrainerCardPage: push hl call LoadCardTypeHeaderTiles ; draw surrounding box @@ -4805,7 +4700,7 @@ DisplayEnergyOrTrainerCardPage: ; 5e2d (1:5e2d) ; display the card details of the card in wLoadedCard1 ; print the text at hl -_DisplayCardDetailScreen: ; 5e5f (1:5e5f) +_DisplayCardDetailScreen: push hl call DrawLargePictureOfCard ld a, 18 @@ -4819,7 +4714,7 @@ _DisplayCardDetailScreen: ; 5e5f (1:5e5f) ; draw a large picture of the card loaded in wLoadedCard1, including its image ; and a header indicating the type of card (TRAINER, ENERGY, PoKéMoN) -DrawLargePictureOfCard: ; 5e75 (1:5e75) +DrawLargePictureOfCard: call ZeroObjectPositionsAndToggleOAMCopy call EmptyScreen call LoadSymbolsFont @@ -4848,7 +4743,7 @@ DrawLargePictureOfCard: ; 5e75 (1:5e75) call ApplyBGP6OrSGB3ToCardImage ret -LargeCardTileData: ; 5eb7 (1:5eb7) +LargeCardTileData: db 5, 0, $d0, $d4, $d4, $d4, $d4, $d4, $d4, $d4, $d4, $d1, 0 ; top border db 5, 1, $d6, $e0, $e1, $e2, $e3, $e4, $e5, $e6, $e7, $d7, 0 ; header top db 5, 2, $d6, $e8, $e9, $ea, $eb, $ec, $ed, $ee, $ef, $d7, 0 ; header bottom @@ -4866,22 +4761,22 @@ LargeCardTileData: ; 5eb7 (1:5eb7) db $ff ; print lines of text with no separation between them -SetNoLineSeparation: ; 5f4a (1:5f4a) +SetNoLineSeparation: ld a, $01 ; fallthrough -SetLineSeparation: ; 5f4c (1:5f4c) +SetLineSeparation: ld [wLineSeparation], a ret ; separate lines of text by an empty line -SetOneLineSeparation: ; 5f50 (1:5f50) +SetOneLineSeparation: xor a jr SetLineSeparation ; given a number in hl, print it divided by 10 at b,c, with decimal part ; separated by a dot (unless it's 0). used to print a Pokemon card's weight. -PrintPokemonCardWeight: ; 5f53 (1:5f53) +PrintPokemonCardWeight: push bc ld de, -1 ld bc, -10 @@ -4936,7 +4831,7 @@ PrintPokemonCardWeight: ; 5f53 (1:5f53) ; given a number in h and another in l, print them formatted as <l>'<h>" at b,c. ; used to print the length (feet and inches) of a Pokemon card. -PrintPokemonCardLength: ; 5f9a (1:5f9a) +PrintPokemonCardLength: push hl ld l, h ld h, $00 @@ -4983,17 +4878,17 @@ PrintPokemonCardLength: ; 5f9a (1:5f9a) ; return carry if the turn holder has any Pokemon with non-zero HP on the bench. ; return how many Pokemon with non-zero HP in b. ; does this by calculating how many Pokemon in play area minus one -HasAlivePokemonInBench: ; 5fd9 (1:5fd9) +HasAlivePokemonInBench: ld a, $01 jr _HasAlivePokemonInPlayArea ; return carry if the turn holder has any Pokemon with non-zero HP in the play area. ; return how many Pokemon with non-zero HP in b. -HasAlivePokemonInPlayArea: ; 5fdd (1:5fdd) +HasAlivePokemonInPlayArea: xor a ; fallthrough -_HasAlivePokemonInPlayArea: ; 5fde (1:5fde) +_HasAlivePokemonInPlayArea: ld [wExcludeArenaPokemon], a ld b, a ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA @@ -5023,15 +4918,15 @@ _HasAlivePokemonInPlayArea: ; 5fde (1:5fde) scf ret -OpenPlayAreaScreenForViewing: ; 6008 (1:6008) +OpenPlayAreaScreenForViewing: ld a, START + A_BUTTON jr DisplayPlayAreaScreen -OpenPlayAreaScreenForSelection: ; 600c (1:600c) +OpenPlayAreaScreenForSelection: ld a, START ; fallthrough -DisplayPlayAreaScreen: ; 600e (1:600e) +DisplayPlayAreaScreen: ld [wNoItemSelectionMenuKeys], a ldh a, [hTempCardIndex_ff98] push af @@ -5122,7 +5017,7 @@ DisplayPlayAreaScreen: ; 600e (1:600e) scf ret -PlayAreaScreenMenuParameters_ActivePokemonIncluded: ; 60be (1:60be) +PlayAreaScreenMenuParameters_ActivePokemonIncluded: db 0, 0 ; cursor x, cursor y db 3 ; y displacement between items db 6 ; number of items @@ -5130,7 +5025,7 @@ PlayAreaScreenMenuParameters_ActivePokemonIncluded: ; 60be (1:60be) db SYM_SPACE ; tile behind cursor dw PlayAreaScreenMenuFunction ; function pointer if non-0 -PlayAreaScreenMenuParameters_ActivePokemonExcluded: ; 60c6 (1:60c6) +PlayAreaScreenMenuParameters_ActivePokemonExcluded: db 0, 3 ; cursor x, cursor y db 3 ; y displacement between items db 6 ; number of items @@ -5138,7 +5033,7 @@ PlayAreaScreenMenuParameters_ActivePokemonExcluded: ; 60c6 (1:60c6) db SYM_SPACE ; tile behind cursor dw PlayAreaScreenMenuFunction ; function pointer if non-0 -PlayAreaScreenMenuFunction: ; 60ce (1:60ce) +PlayAreaScreenMenuFunction: ldh a, [hKeysPressed] and A_BUTTON | B_BUTTON | START ret z @@ -5150,7 +5045,7 @@ PlayAreaScreenMenuFunction: ; 60ce (1:60ce) scf ret -Func_60dd: ; 60dd (1:60dd) +Func_60dd: ld a, [wcbd4] or a ret z @@ -5199,7 +5094,7 @@ Func_60dd: ; 60dd (1:60dd) call OpenTurnHolderHandScreen_Simple jr .asm_60f2 -Func_6137: ; 6137 (1:6137) +Func_6137: ldh a, [hDPadHeld] bit 1, a ret nz @@ -5224,7 +5119,7 @@ Func_6137: ; 6137 (1:6137) call EraseCursor ; fallthrough -Func_615c: ; 615c (1:615c) +Func_615c: ld a, [wCurrentDuelMenuItem] ld d, a add a @@ -5236,7 +5131,7 @@ Func_615c: ; 615c (1:615c) lb bc, SYM_CURSOR_R, SYM_SPACE jp SetCursorParametersForTextBox -Func_616e: ; 616e (1:616e) +Func_616e: ldh [hTempPlayAreaLocation_ff9d], a call ZeroObjectPositionsAndToggleOAMCopy call EmptyScreen @@ -5248,7 +5143,7 @@ Func_616e: ; 616e (1:616e) call EnableLCD ; fallthrough -Func_6186: ; 6186 (1:6186) +Func_6186: ld hl, wCurPlayAreaSlot ldh a, [hTempPlayAreaLocation_ff9d] ld [hli], a @@ -5259,7 +5154,7 @@ Func_6186: ; 6186 (1:6186) call PrintPlayAreaCardInformationAndLocation ret -Func_6194: ; 6194 (1:6194) +Func_6194: call Func_6186 ld a, [wCurPlayAreaY] ld e, a @@ -5267,7 +5162,7 @@ Func_6194: ; 6194 (1:6194) call SetCursorParametersForTextBox_Default ret -Func_61a1: ; 61a1 (1:61a1) +Func_61a1: xor a ld [wExcludeArenaPokemon], a ld a, [wDuelDisplayedScreen] @@ -5284,7 +5179,7 @@ Func_61a1: ; 61a1 (1:61a1) ; symbols (if any), attached energies (if any), and HP bar. ; also print the play area locations (ACT/BPx indicators) for each of the six slots. ; return the value of wNumPlayAreaItems (as returned from PrintPlayAreaCardList) in a. -PrintPlayAreaCardList_EnableLCD: ; 61b8 (1:61b8) +PrintPlayAreaCardList_EnableLCD: ld a, PLAY_AREA_CARD_LIST ld [wDuelDisplayedScreen], a call PrintPlayAreaCardList @@ -5296,7 +5191,7 @@ PrintPlayAreaCardList_EnableLCD: ; 61b8 (1:61b8) ; face down stage card, color symbol, status symbol (if any), pluspower/defender ; symbols (if any), attached energies (if any), and HP bar. ; also print the play area locations (ACT/BPx indicators) for each of the six slots. -PrintPlayAreaCardList: ; 61c7 (1:61c7) +PrintPlayAreaCardList: ld a, PLAY_AREA_CARD_LIST ld [wDuelDisplayedScreen], a ld de, wDuelTempList @@ -5368,7 +5263,7 @@ PrintPlayAreaCardList: ; 61c7 (1:61c7) ; wCurPlayAreaSlot: PLAY_AREA_* of the card to display the information of ; wCurPlayAreaY: Y coordinate of where to print the card's information ; total space occupied is a rectangle of 20x3 tiles -PrintPlayAreaCardInformationAndLocation: ; 622a (1:622a) +PrintPlayAreaCardInformationAndLocation: ld a, [wCurPlayAreaSlot] add DUELVARS_ARENA_CARD call GetTurnDuelistVariable @@ -5378,7 +5273,7 @@ PrintPlayAreaCardInformationAndLocation: ; 622a (1:622a) ; fallthrough ; print a turn holder's play area Pokemon card's location (ACT/BPx indicator) -PrintPlayAreaCardLocation: ; 6238 (1:6238) +PrintPlayAreaCardLocation: ; print the ACT/BPx indicator ld a, [wCurPlayAreaSlot] add a @@ -5410,7 +5305,7 @@ PrintPlayAreaCardLocation: ; 6238 (1:6238) call WriteByteToBGMap0 ret -PlayAreaLocationTileNumbers: ; 6264 (1:6264) +PlayAreaLocationTileNumbers: db $e0, $e1, $e2, $00 ; ACT db $e3, $e4, $e5, $00 ; BP1 db $e3, $e4, $e6, $00 ; BP2 @@ -5425,7 +5320,7 @@ PlayAreaLocationTileNumbers: ; 6264 (1:6264) ; wCurPlayAreaSlot: PLAY_AREA_* of the card to display the information of ; wCurPlayAreaY: Y coordinate of where to print the card's information ; total space occupied is a rectangle of 20x3 tiles -PrintPlayAreaCardInformation: ; 627c (1:627c) +PrintPlayAreaCardInformation: ; print name, level, color, stage, status, pluspower/defender call PrintPlayAreaCardHeader ; print the symbols of the attached energies @@ -5481,7 +5376,7 @@ PrintPlayAreaCardInformation: ; 627c (1:627c) ; input: ; wCurPlayAreaSlot: PLAY_AREA_* of the card to display the information of ; wCurPlayAreaY: Y coordinate of where to print the card's information -PrintPlayAreaCardHeader: ; 62d5 (1:62d5) +PrintPlayAreaCardHeader: ; start by printing the Pokemon's name ld a, [wCurPlayAreaSlot] add DUELVARS_ARENA_CARD @@ -5606,7 +5501,7 @@ PrintPlayAreaCardHeader: ; 62d5 (1:62d5) .not_defender ret -FaceDownCardTileNumbers: ; 63b3 (1:63b3) +FaceDownCardTileNumbers: ; starting tile number, cgb palette (grey, yellow/red, green/blue, pink/orange) db $d0, $02 ; basic db $d4, $02 ; stage 1 @@ -5614,7 +5509,7 @@ FaceDownCardTileNumbers: ; 63b3 (1:63b3) db $dc, $01 ; stage 2 special ; given a card's status in a, print the Poison symbol at bc if it's poisoned -CheckPrintPoisoned: ; 63bb (1:63bb) +CheckPrintPoisoned: push af and POISONED jr z, .print @@ -5626,7 +5521,7 @@ CheckPrintPoisoned: ; 63bb (1:63bb) ret ; given a card's status in a, print the Poison symbol at bc if it's double poisoned -CheckPrintDoublePoisoned: ; 63c7 (1:63c7) +CheckPrintDoublePoisoned: push af and DOUBLE_POISONED & (POISONED ^ $ff) jr nz, CheckPrintPoisoned.poison ; double poisoned (print SYM_POISONED) @@ -5634,7 +5529,7 @@ CheckPrintDoublePoisoned: ; 63c7 (1:63c7) ; given a card's status in a, print the Confusion, Sleep, or Paralysis symbol at bc ; for each of those status that is active -CheckPrintCnfSlpPrz: ; 63ce (1:63ce) +CheckPrintCnfSlpPrz: push af push hl push de @@ -5659,7 +5554,7 @@ CheckPrintCnfSlpPrz: ; 63ce (1:63ce) ; - e: PLAY_AREA_* ; - b, c: where to print (x, y) ; - wAttachedEnergies and wTotalAttachedEnergies -PrintPlayAreaCardAttachedEnergies: ; 63e6 (1:63e6) +PrintPlayAreaCardAttachedEnergies: push bc call GetPlayAreaCardAttachedEnergies ld hl, wDefaultText @@ -5700,7 +5595,7 @@ PrintPlayAreaCardAttachedEnergies: ; 63e6 (1:63e6) call SafeCopyDataHLtoDE ret -Func_6423: ; 6423 (1:6423) +Func_6423: ld hl, wDefaultText ld e, $08 .asm_6428 @@ -5711,7 +5606,7 @@ Func_6423: ; 6423 (1:6423) jr nz, .asm_6428 ret -Func_6431: ; 6431 (1:6431) +Func_6431: xor a ld [wSelectedDuelSubMenuItem], a @@ -5775,7 +5670,7 @@ Func_6435: call OpenCardPage_FromCheckPlayArea jp Func_6435 -Func_64b0: ; 64b0 (1:64b0) +Func_64b0: call ZeroObjectPositionsAndToggleOAMCopy call EmptyScreen call LoadDuelCardSymbolTiles @@ -5814,7 +5709,7 @@ Func_64b0: ; 64b0 (1:64b0) call EnableLCD ret -Func_64fc: ; 64fc (1:64fc) +Func_64fc: ld a, [wLoadedCard1Atk1Category] cp POKEMON_POWER ret nz @@ -5830,7 +5725,7 @@ Func_64fc: ; 64fc (1:64fc) ; Pokemon Power. Includes the card's information above, and the Pokemon Power's ; description below. ; input: hTempPlayAreaLocation_ff9d -DisplayUsePokemonPowerScreen: ; 6510 (1:6510) +DisplayUsePokemonPowerScreen: ldh a, [hTempPlayAreaLocation_ff9d] ld [wCurPlayAreaSlot], a xor a @@ -5852,7 +5747,7 @@ DisplayUsePokemonPowerScreen: ; 6510 (1:6510) ; print the description of an attack, a Pokemon power, or a trainer or energy card ; x,y coordinates of where to start printing the text are given at de ; don't separate lines of text -PrintAttackOrCardDescription: ; 653e (1:653e) +PrintAttackOrCardDescription: call SetNoLineSeparation ld a, [hli] ld h, [hl] @@ -5869,7 +5764,7 @@ PrintAttackOrCardDescription: ; 653e (1:653e) ret ; moves the cards loaded by deck index at hTempRetreatCostCards to the discard pile -DiscardRetreatCostCards: ; 6558 (1:6558) +DiscardRetreatCostCards: ld hl, hTempRetreatCostCards .discard_loop ld a, [hli] @@ -5881,7 +5776,7 @@ DiscardRetreatCostCards: ; 6558 (1:6558) ; moves the discard pile cards that were loaded to hTempRetreatCostCards back to the active Pokemon. ; this exists because they will be discarded again during the call to AttemptRetreat, so ; it prevents the energy cards from being discarded twice. -ReturnRetreatCostCardsToArena: ; 6564 (1:6564) +ReturnRetreatCostCardsToArena: ld hl, hTempRetreatCostCards .loop ld a, [hli] @@ -5898,7 +5793,7 @@ ReturnRetreatCostCardsToArena: ; 6564 (1:6564) ; discard retreat cost energy cards and attempt retreat of the arena card. ; return carry if unable to retreat this turn due to unsuccessful confusion check ; if successful, the retreated card is replaced with a bench Pokemon card -AttemptRetreat: ; 657a (1:657a) +AttemptRetreat: call DiscardRetreatCostCards ldh a, [hTemp_ffa0] and CNF_SLP_PRZ @@ -5922,7 +5817,7 @@ AttemptRetreat: ; 657a (1:657a) ; given a number between 0-255 in a, converts it to TX_SYMBOL format, ; and writes it to wStringBuffer + 2 and to the BGMap0 address at bc. ; leading zeros replaced with SYM_SPACE. -WriteTwoByteNumberInTxSymbolFormat: ; 659f (1:659f) +WriteTwoByteNumberInTxSymbolFormat: push de push bc ld l, a @@ -5941,7 +5836,7 @@ WriteTwoByteNumberInTxSymbolFormat: ; 659f (1:659f) ; given a number between 0-99 in a, converts it to TX_SYMBOL format, ; and writes it to wStringBuffer + 3 and to the BGMap0 address at bc. ; if the number is between 0-9, the first digit is replaced with SYM_SPACE. -WriteTwoDigitNumberInTxSymbolFormat: ; 65b7 (1:65b7) +WriteTwoDigitNumberInTxSymbolFormat: push hl push de push bc @@ -5961,7 +5856,7 @@ WriteTwoDigitNumberInTxSymbolFormat: ; 65b7 (1:65b7) ; convert the number at hl to TX_SYMBOL text format and write it to wStringBuffer ; replace leading zeros with SYM_SPACE -TwoByteNumberToTxSymbol_TrimLeadingZeros_Bank1: ; 65d1 (1:65d1) +TwoByteNumberToTxSymbol_TrimLeadingZeros_Bank1: ld de, wStringBuffer ld bc, -10000 call .get_digit @@ -6005,7 +5900,7 @@ TwoByteNumberToTxSymbol_TrimLeadingZeros_Bank1: ; 65d1 (1:65d1) ret ; input d, e: max. HP, current HP -DrawHPBar: ; 6614 (1:6614) +DrawHPBar: ld a, MAX_HP ld c, SYM_SPACE call .fill_hp_bar ; empty bar @@ -6032,7 +5927,7 @@ DrawHPBar: ; 6614 (1:6614) ; when an opponent's Pokemon card attacks, this displays a screen ; containing the description and information of the used attack -DisplayOpponentUsedAttackScreen: ; 6635 (1:6635) +DisplayOpponentUsedAttackScreen: call ZeroObjectPositionsAndToggleOAMCopy call EmptyScreen call LoadDuelCardSymbolTiles @@ -6058,7 +5953,7 @@ DisplayOpponentUsedAttackScreen: ; 6635 (1:6635) ; display card detail when a trainer card is used, and print "Used xxx" ; hTempCardIndex_ff9f contains the card's deck index -DisplayUsedTrainerCardDetailScreen: ; 666a (1:666a) +DisplayUsedTrainerCardDetailScreen: ldh a, [hTempCardIndex_ff9f] ldtx hl, UsedText call DisplayCardDetailScreen @@ -6067,7 +5962,7 @@ DisplayUsedTrainerCardDetailScreen: ; 666a (1:666a) ; prints the name and description of a trainer card, along with the ; "Used xxx" text in a text box. this function is used to show the player ; the information of a trainer card being used by the opponent. -PrintUsedTrainerCardDescription: ; 6673 (1:6673) +PrintUsedTrainerCardDescription: call EmptyScreen call SetNoLineSeparation lb de, 1, 1 @@ -6087,7 +5982,7 @@ PrintUsedTrainerCardDescription: ; 6673 (1:6673) ; save data of the current duel to sCurrentDuel ; byte 0 is $01, bytes 1 and 2 are the checksum, byte 3 is [wDuelType] ; next $33a bytes come from DuelDataToSave -SaveDuelData: ; 669d (1:669d) +SaveDuelData: farcall CommentedOut_1a6cc ld de, sCurrentDuel ; fallthrough @@ -6095,7 +5990,7 @@ SaveDuelData: ; 669d (1:669d) ; save data of the current duel to de (in SRAM) ; byte 0 is $01, bytes 1 and 2 are the checksum, byte 3 is [wDuelType] ; next $33a bytes come from DuelDataToSave -SaveDuelDataToDE: ; 66a4 (1:66a4) +SaveDuelDataToDE: call EnableSRAM push de inc de @@ -6153,12 +6048,15 @@ SaveDuelDataToDE: ; 66a4 (1:66a4) call DisableSRAM ret -Func_66e9: ; 66e9 (1:66e9) +; loads current Duel data from SRAM and also general save data +; if the data is not valid, returns carry +LoadAndValidateDuelSaveData: ld hl, sCurrentDuel call ValidateSavedDuelData ret c ld de, sCurrentDuel call LoadSavedDuelData + call ValidateGeneralSaveData ret nc call LoadGeneralSaveData @@ -6167,7 +6065,7 @@ Func_66e9: ; 66e9 (1:66e9) ; load the data saved in sCurrentDuelData to WRAM according to the distribution ; of DuelDataToSave. assumes saved data exists and that the checksum is valid. -LoadSavedDuelData: ; 66ff (1:66ff) +LoadSavedDuelData: call EnableSRAM inc de inc de @@ -6205,20 +6103,20 @@ LoadSavedDuelData: ; 66ff (1:66ff) call DisableSRAM ret -DuelDataToSave: ; 6729 (1:6729) -; dw address, number_of_bytes_to_copy - dw wPlayerDuelVariables, wOpponentDuelVariables - wPlayerDuelVariables +DuelDataToSave: +; dw address, number of bytes to copy + dw wPlayerDuelVariables, wOpponentDuelVariables - wPlayerDuelVariables dw wOpponentDuelVariables, wPlayerDeck - wOpponentDuelVariables - dw wPlayerDeck, wDuelTempList - wPlayerDeck - dw wWhoseTurn, wDuelTheme + $1 - wWhoseTurn - dw hWhoseTurn, $1 - dw wRNG1, wRNGCounter + $1 - wRNG1 - dw wcda5, $0010 - dw $0000 + dw wPlayerDeck, wDuelTempList - wPlayerDeck + dw wWhoseTurn, wDuelTheme + $1 - wWhoseTurn + dw hWhoseTurn, $1 + dw wRNG1, wRNGCounter + $1 - wRNG1 + dw wAIDuelVars, wAIDuelVarsEnd - wAIDuelVars + dw NULL ; return carry if there is no data saved at sCurrentDuel or if the checksum isn't correct, ; or if the value saved from wDuelType is DUELTYPE_LINK -ValidateSavedNonLinkDuelData: ; 6747 (1:6747) +ValidateSavedNonLinkDuelData: call EnableSRAM ld hl, sCurrentDuel ld a, [sCurrentDuelData] @@ -6231,7 +6129,7 @@ ValidateSavedNonLinkDuelData: ; 6747 (1:6747) ; return carry if there is no data saved at sCurrentDuel or if the checksum isn't correct ; input: hl = sCurrentDuel -ValidateSavedDuelData: ; 6759 (1:6759) +ValidateSavedDuelData: call EnableSRAM push de ld a, [hli] @@ -6271,7 +6169,7 @@ ValidateSavedDuelData: ; 6759 (1:6759) ; discard data of a duel that was saved by SaveDuelData, by setting the first byte ; of sCurrentDuel to $00, and zeroing the checksum (next two bytes) -DiscardSavedDuelData: ; 6785 (1:6785) +DiscardSavedDuelData: call EnableSRAM ld hl, sCurrentDuel xor a @@ -6283,7 +6181,7 @@ DiscardSavedDuelData: ; 6785 (1:6785) ; loads a player deck (sDeck*Cards) from SRAM to wPlayerDeck ; sCurrentlySelectedDeck determines which sDeck*Cards source (0-3) -LoadPlayerDeck: ; 6793 (1:6793) +LoadPlayerDeck: call EnableSRAM ld a, [sCurrentlySelectedDeck] ld l, a @@ -6304,7 +6202,7 @@ LoadPlayerDeck: ; 6793 (1:6793) ; returns carry if wSkipDelayAllowed is non-0 and B is being held in order to branch ; out of the caller's wait frames loop. probably only used for debugging. -CheckSkipDelayAllowed: ; 67b2 (1:67b2) +CheckSkipDelayAllowed: ld a, [wSkipDelayAllowed] or a ret z @@ -6317,7 +6215,7 @@ CheckSkipDelayAllowed: ; 67b2 (1:67b2) ; related to AI taking their turn in a duel ; called multiple times during one AI turn ; each call results in the execution of an OppActionTable function -AIMakeDecision: ; 67be (1:67be) +AIMakeDecision: ldh [hOppActionTableIndex], a ld hl, wSkipDuelistIsThinkingDelay ld a, [hl] @@ -6353,7 +6251,7 @@ AIMakeDecision: ; 67be (1:67be) scf ret -Func_67fb: ; 67fb (1:67fb) +Func_67fb: ld a, 10 .delay_loop call DoFrame @@ -6389,7 +6287,7 @@ Func_67fb: ; 67fb (1:67fb) call OpenTurnHolderHandScreen_Simple jr .asm_6829 -Func_683e: ; 683e (1:683e) +Func_683e: ldh a, [hDPadHeld] bit 1, a ret nz @@ -6402,7 +6300,7 @@ Func_683e: ; 683e (1:683e) ld [hl], a ; fallthrough -Func_6850: ; 6850 (1:6850) +Func_6850: ld d, 2 ld a, [wCurrentDuelMenuItem] or a @@ -6413,7 +6311,7 @@ Func_6850: ; 6850 (1:6850) lb bc, SYM_CURSOR_R, SYM_SPACE jp SetCursorParametersForTextBox -Func_6862: ; 6862 (1:6862) +Func_6862: ld [wcbff], a ldh a, [hKeysPressed] bit START_F, a @@ -6471,7 +6369,7 @@ Func_6862: ; 6862 (1:6862) call OpenNonTurnHolderDiscardPileScreen jr .return_carry -Func_68c6: ; 68c6 (1:68c6) +Func_68c6: call Func_3b31 ld hl, sp+$00 ld a, l @@ -6485,7 +6383,7 @@ Func_68c6: ; 68c6 (1:68c6) ld [hl], d ret -ResetDoFrameFunction_Bank1: ; 68dd (1:68dd) +ResetDoFrameFunction_Bank1: xor a ld hl, wDoFrameFunction ld [hli], a @@ -6494,7 +6392,7 @@ ResetDoFrameFunction_Bank1: ; 68dd (1:68dd) ; print the AttachedEnergyToPokemonText, given the energy card to attach in hTempCardIndex_ff98, ; and the PLAY_AREA_* of the turn holder's Pokemon to attach the energy to in hTempPlayAreaLocation_ff9d -PrintAttachedEnergyToPokemon: ; 68e4 (1:68e4) +PrintAttachedEnergyToPokemon: ldh a, [hTempPlayAreaLocation_ff9d] add DUELVARS_ARENA_CARD call GetTurnDuelistVariable @@ -6507,7 +6405,7 @@ PrintAttachedEnergyToPokemon: ; 68e4 (1:68e4) ; print the PokemonEvolvedIntoPokemonText, given the Pokemon card to evolve in wPreEvolutionPokemonCard, ; and the evolved Pokemon card in hTempCardIndex_ff98. also play a sound effect. -PrintPokemonEvolvedIntoPokemon: ; 68fa (1:68fa) +PrintPokemonEvolvedIntoPokemon: ld a, SFX_5E call PlaySFX ld a, [wPreEvolutionPokemonCard] @@ -6520,7 +6418,7 @@ PrintPokemonEvolvedIntoPokemon: ; 68fa (1:68fa) ; handle the opponent's turn in a link duel ; loop until either [wOpponentTurnEnded] or [wDuelFinished] is non-0 -DoLinkOpponentTurn: ; 6911 (1:6911) +DoLinkOpponentTurn: xor a ld [wOpponentTurnEnded], a xor a @@ -6560,7 +6458,7 @@ DoLinkOpponentTurn: ; 6911 (1:6911) ; actions for the opponent's turn ; on a link duel, this is referenced by DoLinkOpponentTurn in a loop (on each opponent's HandleTurn) ; on a non-link duel (vs AI opponent), this is referenced by AIMakeDecision -OppActionTable: ; 695e (1:695e) +OppActionTable: dw DuelTransmissionError dw OppAction_PlayBasicPokemonCard dw OppAction_EvolvePokemonCard @@ -6585,12 +6483,12 @@ OppActionTable: ; 695e (1:695e) dw OppAction_6b15 dw OppAction_DrawDuelMainScene -OppAction_DrawCard: ; 698c (1:698c) +OppAction_DrawCard: call DrawCardFromDeck call nc, AddCardToHand ret -OppAction_FinishTurnWithoutAttacking: ; 6993 (1:6993) +OppAction_FinishTurnWithoutAttacking: call DrawDuelMainScene call ClearNonTurnTemporaryDuelvars ldtx hl, FinishedTurnWithoutAttackingText @@ -6600,7 +6498,7 @@ OppAction_FinishTurnWithoutAttacking: ; 6993 (1:6993) ret ; attach an energy card from hand to the arena or a benched Pokemon -OppAction_PlayEnergyCard: ; 69a5 (1:69a5) +OppAction_PlayEnergyCard: ldh a, [hTempPlayAreaLocation_ffa1] ldh [hTempPlayAreaLocation_ff9d], a ld e, a @@ -6617,7 +6515,7 @@ OppAction_PlayEnergyCard: ; 69a5 (1:69a5) ret ; evolve a Pokemon card in the arena or in the bench -OppAction_EvolvePokemonCard: ; 69c5 (1:69c5) +OppAction_EvolvePokemonCard: ldh a, [hTempPlayAreaLocation_ffa1] ldh [hTempPlayAreaLocation_ff9d], a ldh a, [hTemp_ffa0] @@ -6631,7 +6529,7 @@ OppAction_EvolvePokemonCard: ; 69c5 (1:69c5) ret ; place a basic Pokemon card from hand in the bench -OppAction_PlayBasicPokemonCard: ; 69e0 (1:69e0) +OppAction_PlayBasicPokemonCard: ldh a, [hTemp_ffa0] ldh [hTempCardIndex_ff98], a call PutHandPokemonCardInPlayArea @@ -6649,7 +6547,7 @@ OppAction_PlayBasicPokemonCard: ; 69e0 (1:69e0) ; attempt the retreat of the active Pokemon card ; if successful, discard the required energy cards for retreat and ; swap the retreated card with a Pokemon card from the bench -OppAction_AttemptRetreat: ; 69ff (1:69ff) +OppAction_AttemptRetreat: ld a, DUELVARS_ARENA_CARD call GetTurnDuelistVariable push af @@ -6671,7 +6569,7 @@ OppAction_AttemptRetreat: ; 69ff (1:69ff) ret ; play trainer card from hand -OppAction_PlayTrainerCard: ; 6a23 (1:6a23) +OppAction_PlayTrainerCard: call LoadNonPokemonCardEffectCommands call DisplayUsedTrainerCardDetailScreen call PrintUsedTrainerCardDescription @@ -6682,7 +6580,7 @@ OppAction_PlayTrainerCard: ; 6a23 (1:6a23) ; execute the effect commands of the trainer card that is being played ; used only for Trainer cards, as a continuation of OppAction_PlayTrainerCard -OppAction_ExecuteTrainerCardEffectCommands: ; 6a35 (1:6a35) +OppAction_ExecuteTrainerCardEffectCommands: ld a, EFFECTCMDTYPE_DISCARD_ENERGY call TryExecuteEffectCommandFunction ld a, EFFECTCMDTYPE_BEFORE_DAMAGE @@ -6696,7 +6594,7 @@ OppAction_ExecuteTrainerCardEffectCommands: ; 6a35 (1:6a35) ; begin the execution of an attack and handle the attack being ; possibly unsuccessful due to Sand Attack or Smokescreen -OppAction_BeginUseAttack: ; 6a4e (1:6a4e) +OppAction_BeginUseAttack: ldh a, [hTempCardIndex_ff9f] ld d, a ldh a, [hTemp_ffa0] @@ -6732,7 +6630,7 @@ OppAction_BeginUseAttack: ; 6a4e (1:6a4e) ; display the attack used by the opponent, and handle ; EFFECTCMDTYPE_DISCARD_ENERGY and confusion damage to self -OppAction_UseAttack: ; 6a8c (1:6a8c) +OppAction_UseAttack: ld a, EFFECTCMDTYPE_DISCARD_ENERGY call TryExecuteEffectCommandFunction call CheckSelfConfusionDamage @@ -6751,14 +6649,14 @@ OppAction_UseAttack: ; 6a8c (1:6a8c) ld [wOpponentTurnEnded], a ret -OppAction_PlayAttackAnimationDealAttackDamage: ; 6ab1 (1:6ab1) +OppAction_PlayAttackAnimationDealAttackDamage: call PlayAttackAnimation_DealAttackDamage ld a, 1 ld [wOpponentTurnEnded], a ret ; force the player to switch the active Pokemon with a benched Pokemon -OppAction_ForceSwitchActive: ; 6aba (1:6aba) +OppAction_ForceSwitchActive: ldtx hl, SelectPkmnOnBenchToSwitchWithActiveText call DrawWideTextBox_WaitForInput call SwapTurn @@ -6773,7 +6671,7 @@ OppAction_ForceSwitchActive: ; 6aba (1:6aba) call SerialSendByte ret -OppAction_UsePokemonPower: ; 6ad9 (1:6ad9) +OppAction_UsePokemonPower: ldh a, [hTempCardIndex_ff9f] ld d, a ld e, $00 @@ -6796,7 +6694,7 @@ OppAction_UsePokemonPower: ; 6ad9 (1:6ad9) ret ; execute the EFFECTCMDTYPE_BEFORE_DAMAGE command of the used Pokemon Power -OppAction_ExecutePokemonPowerEffect: ; 6b07 (1:6b07) +OppAction_ExecutePokemonPowerEffect: call Func_7415 ld a, EFFECTCMDTYPE_BEFORE_DAMAGE call TryExecuteEffectCommandFunction @@ -6805,25 +6703,25 @@ OppAction_ExecutePokemonPowerEffect: ; 6b07 (1:6b07) ret ; execute the EFFECTCMDTYPE_AFTER_DAMAGE command of the used Pokemon Power -OppAction_6b15: ; 6b15 (1:6b15) +OppAction_6b15: ld a, EFFECTCMDTYPE_AFTER_DAMAGE call TryExecuteEffectCommandFunction ld a, $01 ld [wSkipDuelistIsThinkingDelay], a ret -OppAction_DrawDuelMainScene: ; 6b20 (1:6b20) +OppAction_DrawDuelMainScene: call DrawDuelMainScene ret -OppAction_TossCoinATimes: ; 6b24 (1:6b24) +OppAction_TossCoinATimes: call SerialRecv8Bytes call TossCoinATimes ld a, $01 ld [wSkipDuelistIsThinkingDelay], a ret -OppAction_6b30: ; 6b30 (1:6b30) +OppAction_6b30: ldh a, [hWhoseTurn] push af ldh a, [hTemp_ffa0] @@ -6833,7 +6731,7 @@ OppAction_6b30: ; 6b30 (1:6b30) ldh [hWhoseTurn], a ret -OppAction_UseMetronomeAttack: ; 6b3e (1:6b3e) +OppAction_UseMetronomeAttack: call DrawDuelMainScene ld a, DUELVARS_ARENA_CARD_STATUS call GetTurnDuelistVariable @@ -6862,12 +6760,12 @@ OppAction_UseMetronomeAttack: ; 6b3e (1:6b3e) ld [wMetronomeEnergyCost], a ret -OppAction_NoAction: ; 6b7d (1:6b7d) +OppAction_NoAction: ret ; load the text ID of the card name with deck index given in a to TxRam2 ; also loads the card to wLoadedCard1 -LoadCardNameToTxRam2: ; 6b7e (1:6b7e) +LoadCardNameToTxRam2: call LoadCardDataToBuffer1_FromDeckIndex ld a, [wLoadedCard1Name] ld [wTxRam2], a @@ -6877,7 +6775,7 @@ LoadCardNameToTxRam2: ; 6b7e (1:6b7e) ; load the text ID of the card name with deck index given in a to TxRam2_b ; also loads the card to wLoadedCard1 -LoadCardNameToTxRam2_b: ; 6b8e (1:6b8e) +LoadCardNameToTxRam2_b: call LoadCardDataToBuffer1_FromDeckIndex ld a, [wLoadedCard1Name] ld [wTxRam2_b], a @@ -6885,11 +6783,11 @@ LoadCardNameToTxRam2_b: ; 6b8e (1:6b8e) ld [wTxRam2_b + 1], a ret -DrawWideTextBox_WaitForInput_Bank1: ; 6b9e (1:6b9e) +DrawWideTextBox_WaitForInput_Bank1: call DrawWideTextBox_WaitForInput ret -Func_6ba2: ; 6ba2 (1:6ba2) +Func_6ba2: call DrawWideTextBox_PrintText ld a, [wDuelistType] cp DUELIST_TYPE_LINK_OPP @@ -6898,7 +6796,7 @@ Func_6ba2: ; 6ba2 (1:6ba2) ret ; apply and/or refresh status conditions and other events that trigger between turns -HandleBetweenTurnsEvents: ; 6baf (1:6baf) +HandleBetweenTurnsEvents: call IsArenaPokemonAsleepOrPoisoned jr c, .something_to_handle cp PARALYZED @@ -6975,7 +6873,7 @@ HandleBetweenTurnsEvents: ; 6baf (1:6baf) ret ; discard any PLUSPOWER attached to the turn holder's arena and/or bench Pokemon -DiscardAttachedPluspowers: ; 6c44 (1:6c44) +DiscardAttachedPluspowers: ld a, DUELVARS_ARENA_CARD_ATTACHED_PLUSPOWER call GetTurnDuelistVariable ld e, MAX_PLAY_AREA_POKEMON @@ -6988,7 +6886,7 @@ DiscardAttachedPluspowers: ; 6c44 (1:6c44) jp MoveCardToDiscardPileIfInArena ; discard any DEFENDER attached to the turn holder's arena and/or bench Pokemon -DiscardAttachedDefenders: ; 6c56 (1:6c56) +DiscardAttachedDefenders: ld a, DUELVARS_ARENA_CARD_ATTACHED_DEFENDER call GetTurnDuelistVariable ld e, MAX_PLAY_AREA_POKEMON @@ -7002,7 +6900,7 @@ DiscardAttachedDefenders: ; 6c56 (1:6c56) ; return carry if the turn holder's arena Pokemon card is asleep, poisoned, or double poisoned. ; also, if confused, paralyzed, or asleep, return the status condition in a. -IsArenaPokemonAsleepOrPoisoned: ; 6c68 (1:6c68) +IsArenaPokemonAsleepOrPoisoned: ld a, DUELVARS_ARENA_CARD_STATUS call GetTurnDuelistVariable or a @@ -7021,7 +6919,7 @@ IsArenaPokemonAsleepOrPoisoned: ; 6c68 (1:6c68) scf ret -Func_6c7e: ; 6c7e (1:6c7e) +Func_6c7e: ld a, [wDuelDisplayedScreen] cp DUEL_MAIN_SCENE jr z, .asm_6c98 @@ -7046,7 +6944,7 @@ Func_6c7e: ; 6c7e (1:6c7e) ; input: ; a = animation ID -Func_6cab: ; 6cab (1:6cab) +Func_6cab: push af ld a, [wDuelType] or a @@ -7081,7 +6979,7 @@ Func_6cab: ; 6cab (1:6cab) ret ; prints the name of the card at wTempNonTurnDuelistCardID in a text box -Func_6ce4: ; 6ce4 (1:6ce4) +Func_6ce4: push hl ld a, [wTempNonTurnDuelistCardID] ld e, a @@ -7098,7 +6996,7 @@ Func_6ce4: ; 6ce4 (1:6ce4) ; handles the sleep check for the NonTurn Duelist ; heals sleep status if coin is heads, else ; it plays sleeping animation -HandleSleepCheck: ; 6cfa (1:6cfa) +HandleSleepCheck: ld a, [hl] and CNF_SLP_PRZ cp ASLEEP @@ -7142,7 +7040,7 @@ HandleSleepCheck: ; 6cfa (1:6cfa) call WaitForWideTextBoxInput ret -HandlePoisonDamage: ; 6d3f (1:6d3f) +HandlePoisonDamage: or a bit POISONED_F , [hl] ret z ; quit if not poisoned @@ -7194,7 +7092,7 @@ HandlePoisonDamage: ; 6d3f (1:6d3f) ; and a pointer in hl to the wLoadedCard* buffer where the card data is loaded, ; check if the card is Clefairy Doll or Mysterious Fossil, and, if so, convert it ; to a Pokemon card in the wLoadedCard* buffer, using .trainer_to_pkmn_data. -ConvertSpecialTrainerCardToPokemon: ; 6d84 (1:6d84) +ConvertSpecialTrainerCardToPokemon: ld c, a ld a, [hl] cp TYPE_TRAINER @@ -7250,7 +7148,7 @@ ConvertSpecialTrainerCardToPokemon: ; 6d84 (1:6d84) ; this function applies status conditions to the defending Pokemon, ; returned by the effect functions in wEffectFunctionsFeedback -Func_6df1: ; 6df1 (1:6df1) +Func_6df1: xor a ld [wPlayerArenaCardLastTurnStatus], a ld [wOpponentArenaCardLastTurnStatus], a @@ -7300,7 +7198,7 @@ Func_6df1: ; 6df1 (1:6df1) ; apply the status condition at hl+1 to the arena Pokemon ; discard the arena Pokemon's status conditions contained in the bitmask at hl -ApplyStatusConditionToArenaPokemon: ; 6e38 (1:6e38) +ApplyStatusConditionToArenaPokemon: ld e, DUELVARS_ARENA_CARD_STATUS ld a, [de] and [hl] @@ -7317,11 +7215,11 @@ ApplyStatusConditionToArenaPokemon: ; 6e38 (1:6e38) ld [de], a ret -Func_6e49: ; 6e49 (1:6e49) +Func_6e49: call HandleDestinyBondSubstatus ; fallthrough -Func_6e4c: ; 6e4c (1:6e4c) +Func_6e4c: call ClearDamageReductionSubstatus2OfKnockedOutPokemon xor a ld [wcce8], a @@ -7387,7 +7285,7 @@ Func_6e4c: ; 6e4c (1:6e4c) scf jr .asm_6eb2 -Data_6ed2: ; 6ed2 (1:6ed2) +Data_6ed2: db DUEL_NOT_FINISHED, TURN_PLAYER_LOST, TURN_PLAYER_WON, TURN_PLAYER_TIED db TURN_PLAYER_LOST, TURN_PLAYER_LOST, TURN_PLAYER_TIED, TURN_PLAYER_LOST db TURN_PLAYER_WON, TURN_PLAYER_TIED, TURN_PLAYER_WON, TURN_PLAYER_WON @@ -7395,7 +7293,7 @@ Data_6ed2: ; 6ed2 (1:6ed2) ; clears SUBSTATUS2_REDUCE_BY_20, SUBSTATUS2_POUNCE, SUBSTATUS2_GROWL, ; SUBSTATUS2_TAIL_WAG, and SUBSTATUS2_LEER for each arena Pokemon with 0 HP -ClearDamageReductionSubstatus2OfKnockedOutPokemon: ; 6ee2 (1:6ee2) +ClearDamageReductionSubstatus2OfKnockedOutPokemon: call SwapTurn call .clear call SwapTurn @@ -7407,13 +7305,13 @@ ClearDamageReductionSubstatus2OfKnockedOutPokemon: ; 6ee2 (1:6ee2) call ClearDamageReductionSubstatus2 ret -Func_6ef6: ; 6ef6 (1:6ef6) +Func_6ef6: call Func_6fa5 ld hl, wcce8 rl [hl] ret -Func_6eff: ; 6eff (1:6eff) +Func_6eff: call ReplaceKnockedOutPokemon ld hl, wcce8 rl [hl] @@ -7421,7 +7319,7 @@ Func_6eff: ; 6eff (1:6eff) ; for each Pokemon in the turn holder's play area (arena and bench), ; move that card to the discard pile if its HP is 0 -MoveAllTurnHolderKnockedOutPokemonToDiscardPile: ; 6f08 (1:6f08) +MoveAllTurnHolderKnockedOutPokemonToDiscardPile: ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable ld d, a @@ -7445,7 +7343,7 @@ MoveAllTurnHolderKnockedOutPokemonToDiscardPile: ; 6f08 (1:6f08) ; have the turn holder replace the arena Pokemon card when it's been knocked out. ; if there are no Pokemon cards in the turn holder's bench, return carry. -ReplaceKnockedOutPokemon: ; 6f23 (1:6f23) +ReplaceKnockedOutPokemon: ld a, DUELVARS_ARENA_CARD_HP call GetTurnDuelistVariable or a @@ -7518,7 +7416,7 @@ ReplaceKnockedOutPokemon: ; 6f23 (1:6f23) ldh [hTempPlayAreaLocation_ff9d], a jr .replace_pokemon -Func_6fa5: ; 6fa5 (1:6fa5) +Func_6fa5: call CountKnockedOutPokemon ret nc ; at least one Pokemon knocked out @@ -7539,7 +7437,7 @@ Func_6fa5: ; 6fa5 (1:6fa5) ; play area that are still there despite having 0 HP. ; that is, the number of Pokemon that have just been knocked out. ; Clefairy Doll and Mysterious Fossil don't count. -CountKnockedOutPokemon: ; 6fc7 (1:6fc7) +CountKnockedOutPokemon: ld a, DUELVARS_ARENA_CARD_HP call GetTurnDuelistVariable ld d, h @@ -7574,7 +7472,7 @@ CountKnockedOutPokemon: ; 6fc7 (1:6fc7) scf ret -Func_6ff7: ; 6ff7 (1:6ff7) +Func_6ff7: ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable ld c, a @@ -7593,7 +7491,7 @@ Func_6ff7: ; 6ff7 (1:6ff7) ; print one of the "There was no effect from" texts depending ; on the value at wNoEffectFromWhichStatus (NO_STATUS or a status condition constant) -PrintThereWasNoEffectFromStatusText: ; 700a (1:700a) +PrintThereWasNoEffectFromStatusText: ld a, [wNoEffectFromWhichStatus] or a jr nz, .status @@ -7639,7 +7537,7 @@ PrintThereWasNoEffectFromStatusText: ; 700a (1:700a) ; a = card index in hTempPlayAreaLocation_ff9d; ; d = card index of card one stage below; ; carry set if card is a basic card. -GetCardOneStageBelow: ; 7045 (1:7045) +GetCardOneStageBelow: ldh a, [hTempPlayAreaLocation_ff9d] add DUELVARS_ARENA_CARD call GetTurnDuelistVariable @@ -7711,7 +7609,7 @@ GetCardOneStageBelow: ; 7045 (1:7045) ; initializes variables when a duel begins, such as zeroing wDuelFinished or wDuelTurns, ; and setting wDuelType based on wPlayerDuelistType and wOpponentDuelistType -InitVariablesToBeginDuel: ; 70aa (1:70aa) +InitVariablesToBeginDuel: xor a ld [wDuelFinished], a ld [wDuelTurns], a @@ -7740,7 +7638,7 @@ InitVariablesToBeginDuel: ; 70aa (1:70aa) ret ; init variables that last a single player's turn -InitVariablesToBeginTurn: ; 70e6 (1:70e6) +InitVariablesToBeginTurn: xor a ld [wAlreadyPlayedEnergy], a ld [wGotHeadsFromConfusionCheckDuringRetreat], a @@ -7751,7 +7649,7 @@ InitVariablesToBeginTurn: ; 70e6 (1:70e6) ; make all Pokemon in the turn holder's play area able to evolve. called from the ; player's second turn on, in order to allow evolution of all Pokemon already played. -SetAllPlayAreaPokemonCanEvolve: ; 70f6 (1:70f6) +SetAllPlayAreaPokemonCanEvolve: ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable ld c, a @@ -7767,7 +7665,7 @@ SetAllPlayAreaPokemonCanEvolve: ; 70f6 (1:70f6) ; initializes duel variables such as cards in deck and in hand, or Pokemon in play area ; player turn: [c200, c2ff] ; opponent turn: [c300, c3ff] -InitializeDuelVariables: ; 7107 (1:7107) +InitializeDuelVariables: ldh a, [hWhoseTurn] ld h, a ld l, DUELVARS_DUELIST_TYPE @@ -7809,7 +7707,7 @@ InitializeDuelVariables: ; 7107 (1:7107) ; draw [wDuelInitialPrizes] cards from the turn holder's deck and place them as prizes: ; write their deck indexes to DUELVARS_PRIZE_CARDS, set their location to ; CARD_LOCATION_PRIZE, and set [wDuelInitialPrizes] bits of DUELVARS_PRIZES. -InitTurnDuelistPrizes: ; 7133 (1:7133) +InitTurnDuelistPrizes: ldh a, [hWhoseTurn] ld d, a ld e, DUELVARS_PRIZE_CARDS @@ -7838,12 +7736,12 @@ InitTurnDuelistPrizes: ; 7133 (1:7133) ld [hl], a ret -PrizeBitmasks: ; 715a (1:715a) +PrizeBitmasks: db %0, %1, %11, %111, %1111, %11111, %111111 ; update the turn holder's DUELVARS_PRIZES following that duelist ; drawing a number of prizes equal to register a -TakeAPrizes: ; 7161 (1:7161) +TakeAPrizes: or a ret z ld c, a @@ -7864,7 +7762,7 @@ TakeAPrizes: ; 7161 (1:7161) ; clear the non-turn holder's duelvars starting at DUELVARS_ARENA_CARD_DISABLED_ATTACK_INDEX ; these duelvars only last a two-player turn at most. -ClearNonTurnTemporaryDuelvars: ; 717a (1:717a) +ClearNonTurnTemporaryDuelvars: ld a, DUELVARS_ARENA_CARD_DISABLED_ATTACK_INDEX call GetNonTurnDuelistVariable xor a @@ -7880,7 +7778,7 @@ ClearNonTurnTemporaryDuelvars: ; 717a (1:717a) ; same as ClearNonTurnTemporaryDuelvars, except the non-turn holder's arena ; Pokemon status condition is copied to wccc5 -ClearNonTurnTemporaryDuelvars_CopyStatus: ; 7189 (1:7189) +ClearNonTurnTemporaryDuelvars_CopyStatus: ld a, DUELVARS_ARENA_CARD_STATUS call GetNonTurnDuelistVariable ld [wccc5], a @@ -7890,7 +7788,7 @@ ClearNonTurnTemporaryDuelvars_CopyStatus: ; 7189 (1:7189) ; update non-turn holder's DUELVARS_ARENA_CARD_LAST_TURN_DAMAGE ; if wccef == 0: set to [wDealtDamage] ; if wceef != 0: set to 0 -Func_7195: ; 7195 (1:7195) +Func_7195: ld a, DUELVARS_ARENA_CARD_LAST_TURN_DAMAGE call GetNonTurnDuelistVariable ld a, [wccef] @@ -7907,7 +7805,7 @@ Func_7195: ; 7195 (1:7195) ld [hl], a ret -_TossCoin: ; 71ad (1:71ad) +_TossCoin: ld [wCoinTossTotalNum], a ld a, [wDuelDisplayedScreen] cp COIN_TOSS @@ -8123,7 +8021,7 @@ _TossCoin: ; 71ad (1:71ad) scf ret -Func_72ff: ; 72ff (1:72ff) +Func_72ff: ldh [hff96], a ld a, [wDuelType] cp DUELTYPE_LINK @@ -8133,7 +8031,7 @@ Func_72ff: ; 72ff (1:72ff) call Func_7344 ret -Func_7310: ; 7310 (1:7310) +Func_7310: ldh [hff96], a ld a, [wDuelType] cp DUELTYPE_LINK @@ -8145,7 +8043,7 @@ Func_7310: ; 7310 (1:7310) ldh a, [hff96] ret -Func_7324: ; 7324 (1:7324) +Func_7324: ldh [hff96], a ld a, [wDuelType] cp DUELTYPE_LINK @@ -8160,14 +8058,14 @@ Func_7324: ; 7324 (1:7324) ldh a, [hff96] ret -Func_7338: ; 7338 (1:7338) +Func_7338: call DoFrame call SerialRecvByte jr c, Func_7338 call Func_7344 ret -Func_7344: ; 7344 (1:7344) +Func_7344: push af ld a, [wSerialFlags] or a @@ -8179,7 +8077,7 @@ Func_7344: ; 7344 (1:7344) call DuelTransmissionError ret -BuildVersion: ; 7354 (1:7354) +BuildVersion: db "VER 12/20 09:36", TX_END ; possibly unreferenced, used for testing @@ -8187,7 +8085,7 @@ BuildVersion: ; 7354 (1:7354) ; handles input to select/cancel/scroll through deck IDs ; loads the NPC duel configurations if one was selected ; returns carry if selection was cancelled -Func_7364: ; 7364 (1:7364) +Func_7364: xor a ld [wTileMapFill], a call ZeroObjectPositionsAndToggleOAMCopy @@ -8267,7 +8165,7 @@ Func_7364: ; 7364 (1:7364) ; draws the current opponent to be selected ; (his/her portrait and name) ; and prints text box for selection -DrawOpponentSelectionScreen: ; 73d8 (1:73d8) +DrawOpponentSelectionScreen: ld a, [wOpponentDeckID] ld [wNPCDuelDeckID], a call GetNPCDuelConfigurations @@ -8291,18 +8189,18 @@ DrawOpponentSelectionScreen: ; 73d8 (1:73d8) call WriteTwoByteNumberInTxSymbolFormat ret -SelectComputerOpponentData: ; 7408 (1:7408) +SelectComputerOpponentData: textitem 10, 0, ClearOpponentNameText textitem 10, 10, NumberOfPrizesText textitem 3, 14, SelectComputerOpponentText db $ff -Func_7415: ; 7415 (1:7415) +Func_7415: xor a ld [wce7e], a ret -Func_741a: ; 741a (1:741a) +Func_741a: ld hl, wEffectFunctionsFeedbackIndex ld a, [hl] or a @@ -8354,7 +8252,7 @@ Func_741a: ; 741a (1:741a) ; this is a simple version of PlayAttackAnimation_DealAttackDamage that doesn't ; take into account status conditions, damage modifiers, etc, for damage calculation. ; used for confusion damage to self and for damage to benched Pokemon, for example -PlayAttackAnimation_DealAttackDamageSimple: ; 7469 (1:7469) +PlayAttackAnimation_DealAttackDamageSimple: push hl push de call PlayAttackAnimation @@ -8373,7 +8271,7 @@ PlayAttackAnimation_DealAttackDamageSimple: ; 7469 (1:7469) ret ; if [wLoadedAttackAnimation] != 0, wait until the animation is over -WaitAttackAnimation: ; 7484 (1:7484) +WaitAttackAnimation: ld a, [wLoadedAttackAnimation] or a ret z @@ -8390,7 +8288,7 @@ WaitAttackAnimation: ; 7484 (1:7484) ; - [wLoadedAttackAnimation]: animation to play ; - de: damage dealt by the attack (to display the animation with the number) ; - c: a wDamageEffectiveness constant (to print WEAK or RESIST if necessary) -PlayAttackAnimation: ; 7494 (1:7494) +PlayAttackAnimation: ldh a, [hWhoseTurn] push af push hl @@ -8435,7 +8333,7 @@ PlayAttackAnimation: ; 7494 (1:7494) ldh [hWhoseTurn], a ret -Func_74dc: ; 74dc (1:74dc) +Func_74dc: call EmptyScreen call EnableLCD ld a, GRASS_ENERGY @@ -8486,7 +8384,7 @@ Func_74dc: ; 74dc (1:74dc) ; for starting a duel ; outputs in hl either wPlayerDuelVariables ; or wOpponentDuelVariables depending on wSerialOp -DecideLinkDuelVariables: ; 7528 (1:7528) +DecideLinkDuelVariables: call Func_0e8e ldtx hl, PressStartWhenReadyText call DrawWideTextBox_PrintText @@ -8515,56 +8413,3 @@ DecideLinkDuelVariables: ; 7528 (1:7528) ret ret ; stray ret - -ReceiveDeckConfiguration: ; 755d (1:755d) - farcall _ReceiveDeckConfiguration - ret - -SendDeckConfiguration: ; 7562 (1:7562) - farcall _SendDeckConfiguration - ret - -ReceiveCard: ; 7567 (1:7567) - farcall _ReceiveCard - ret - -SendCard: ; 756c (1:756c) - farcall _SendCard - ret - -; handles all the Card Pop! functionality -DoCardPop: ; 7571 (1:7571) - farcall _DoCardPop - ret - -Func_7576: ; 7576 (1:7576) - farcall Func_1991f - ret - -PreparePrinterConnection: ; 757b (1:757b) - farcall _PreparePrinterConnection - ret - -PrintDeckConfiguration: ; 7580 (1:7580) - farcall _PrintDeckConfiguration - ret - -PrintCardList: ; 7585 (1:7585) - farcall _PrintCardList - ret - -Func_758a: ; 758a (1:758a) - farcall Func_19eb4 - ret - -SetUpAndStartLinkDuel: ; 758f (1:758f) - farcall _SetUpAndStartLinkDuel - ret - -Func_7594: ; 7594 (1:7594) - farcall Func_1a61f - ret - -OpenBoosterPack: ; 7599 (1:7599) - farcall _OpenBoosterPack - ret diff --git a/src/engine/game_loop.asm b/src/engine/game_loop.asm new file mode 100644 index 0000000..c3745b6 --- /dev/null +++ b/src/engine/game_loop.asm @@ -0,0 +1,55 @@ +; continuation of Bank0 Start +; meant as the main loop, but the game never returns from _GameLoop anyway +GameLoop: + di + ld sp, $e000 + call ResetSerial + call EnableInt_VBlank + call EnableInt_Timer + call EnableSRAM + ld a, [sTextSpeed] + ld [wTextSpeed], a + ld a, [sSkipDelayAllowed] + ld [wSkipDelayAllowed], a + call DisableSRAM + ld a, 1 + ld [wUppercaseHalfWidthLetters], a + ei + farcall CommentedOut_1a6cc + ldh a, [hKeysHeld] + cp A_BUTTON | B_BUTTON + jr z, .ask_erase_backup_ram + farcall _GameLoop + jr GameLoop +.ask_erase_backup_ram + call SetupResetBackUpRamScreen + call EmptyScreen + ldtx hl, ResetBackUpRamText + call YesOrNoMenuWithText + jr c, .reset_game +; erase sram + call EnableSRAM + xor a + ld [s0a000], a + call DisableSRAM +.reset_game + jp Reset + +InitSaveDataAndSetUppercase: + farcall InitSaveData + ld a, 1 + ld [wUppercaseHalfWidthLetters], a + ret + +; basic setup to be able to print the ResetBackUpRamText in an empty screen +SetupResetBackUpRamScreen: + xor a ; SYM_SPACE + ld [wTileMapFill], a + call DisableLCD + call LoadSymbolsFont + call SetDefaultPalettes + lb de, $38, $7f + call SetupText + ret + + ret ; stray ret diff --git a/src/engine/menus/card_album.asm b/src/engine/menus/card_album.asm new file mode 100644 index 0000000..87462fe --- /dev/null +++ b/src/engine/menus/card_album.asm @@ -0,0 +1,959 @@ +; fills wFilteredCardList and wOwnedCardsCountList +; with cards IDs and counts, respectively, +; from given Card Set in register a +; a = CARD_SET_* constant +CreateCardSetList: + push af + ld a, DECK_SIZE + ld hl, wFilteredCardList + call ClearNBytesFromHL + ld a, DECK_SIZE + ld hl, wOwnedCardsCountList + call ClearNBytesFromHL + xor a + ld [wOwnedPhantomCardFlags], a + pop af + + ld hl, 0 + lb de, 0, 0 + ld b, a +.loop_all_cards + inc e + call LoadCardDataToBuffer1_FromCardID + jr c, .done_pkmn_cards + ld a, [wLoadedCard1Set] + and $f0 ; set 1 + swap a + cp b + jr nz, .loop_all_cards + +; it's same set as input + ld a, e + cp VENUSAUR1 + jp z, .SetVenusaur1OwnedFlag + cp MEW2 + jp z, .SetMew2OwnedFlag + + push bc + push hl + ld bc, wFilteredCardList + add hl, bc + ld [hl], e ; card ID + + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + pop hl + push hl + ld bc, wOwnedCardsCountList + add hl, bc + ld [hl], a ; card count in collection + pop hl + + inc l + pop bc + jr .loop_all_cards + +.done_pkmn_cards +; for the energy cards, put all basic energy cards in Colosseum +; and Double Colorless energy in Mystery + ld a, b + cp CARD_SET_MYSTERY + jr z, .mystery + or a + jr nz, .skip_energy_cards + +; colosseum +; places all basic energy cards in wFilteredCardList + lb de, 0, 0 +.loop_basic_energy_cards + inc e + ld a, e + cp DOUBLE_COLORLESS_ENERGY + jr z, .skip_energy_cards + push bc + push hl + ld bc, wFilteredCardList + add hl, bc + ld [hl], e + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + pop hl + push hl + ld bc, wOwnedCardsCountList + add hl, bc + ld [hl], a + pop hl + inc l + pop bc + jr .loop_basic_energy_cards + +.mystery +; places double colorless energy card in wFilteredCardList + lb de, 0, 0 +.loop_find_double_colorless + inc e + ld a, e + cp BULBASAUR + jr z, .skip_energy_cards + cp DOUBLE_COLORLESS_ENERGY + jr nz, .loop_find_double_colorless + ; double colorless energy + push bc + push hl + ld bc, wFilteredCardList + add hl, bc + ld [hl], e + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + pop hl + push hl + ld bc, wOwnedCardsCountList + add hl, bc + ld [hl], a + pop hl + inc l + pop bc + jr .loop_find_double_colorless + +.skip_energy_cards + ld a, [wOwnedPhantomCardFlags] + bit VENUSAUR_OWNED_PHANTOM_F, a + jr z, .check_mew + call .PlaceVenusaur1InList +.check_mew + bit MEW_OWNED_PHANTOM_F, a + jr z, .find_first_owned + call .PlaceMew2InList + +.find_first_owned + dec l + ld c, l + ld b, h +.loop_owned_cards + ld hl, wOwnedCardsCountList + add hl, bc + ld a, [hl] + cp CARD_NOT_OWNED + jr nz, .found_owned + dec c + jr .loop_owned_cards + +.found_owned + inc c + ld a, c + ld [wNumEntriesInCurFilter], a + xor a + ld hl, wFilteredCardList + add hl, bc + ld [hl], a + ld a, $ff ; terminator byte + ld hl, wOwnedCardsCountList + add hl, bc + ld [hl], a + ret + +.SetMew2OwnedFlag + ld a, (1 << MEW_OWNED_PHANTOM_F) +; fallthrough + +.SetPhantomOwnedFlag + push hl + push bc + ld b, a + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + cp CARD_NOT_OWNED + jr z, .skip_set_flag + ld a, [wOwnedPhantomCardFlags] + or b + ld [wOwnedPhantomCardFlags], a +.skip_set_flag + pop bc + pop hl + jp .loop_all_cards + +.SetVenusaur1OwnedFlag + ld a, (1 << VENUSAUR_OWNED_PHANTOM_F) + jr .SetPhantomOwnedFlag + +.PlaceVenusaur1InList + push af + push hl + ld e, VENUSAUR1 +; fallthrough + +; places card in register e directly in the list +.PlaceCardInList + ld bc, wFilteredCardList + add hl, bc + ld [hl], e + pop hl + push hl + ld bc, wOwnedCardsCountList + add hl, bc + ld [hl], $01 + pop hl + inc l + pop af + ret + +.PlaceMew2InList + push af + push hl + ld e, MEW2 + jr .PlaceCardInList + +; a = CARD_SET_* constant +CreateCardSetListAndInitListCoords: + push af + ld hl, sCardCollection + ld de, wTempCardCollection + ld b, CARD_COLLECTION_SIZE - 1 + call EnableSRAM + call CopyNBytesFromHLToDE + call DisableSRAM + pop af + + push af + call .GetEntryPrefix + call CreateCardSetList + ld a, NUM_CARD_ALBUM_VISIBLE_CARDS + ld [wNumVisibleCardListEntries], a + lb de, 2, 4 + ld hl, wCardListCoords + ld [hl], e + inc hl + ld [hl], d + pop af + ret + +; places in entry name the prefix associated with the selected Card Set +; a = CARD_SET_* constant +.GetEntryPrefix + push af + cp CARD_SET_PROMOTIONAL + jr nz, .laboratory + lb de, 3, "FW3_P" + jr .got_prefix +.laboratory + cp CARD_SET_LABORATORY + jr nz, .mystery + lb de, 3, "FW3_D" + jr .got_prefix +.mystery + cp CARD_SET_MYSTERY + jr nz, .evolution + lb de, 3, "FW3_C" + jr .got_prefix +.evolution + cp CARD_SET_EVOLUTION + jr nz, .colosseum + lb de, 3, "FW3_B" + jr .got_prefix +.colosseum + lb de, 3, "FW3_A" + +.got_prefix + ld hl, wCurDeckName + ld [hl], d + inc hl + ld [hl], e + pop af + ret + +; prints the cards being shown in the Card Album screen +; for the corresponding Card Set +PrintCardSetListEntries: + push bc + ld hl, wCardListCoords + ld e, [hl] + inc hl + ld d, [hl] + ld b, $13 + ld c, e + dec c + dec c + +; draw up cursor on top right + ld a, [wCardListVisibleOffset] + or a + jr z, .no_up_cursor + ld a, SYM_CURSOR_U + jr .got_up_cursor_tile +.no_up_cursor + ld a, SYM_BOX_TOP_R +.got_up_cursor_tile + call WriteByteToBGMap0 + + ld a, [wCardListVisibleOffset] + ld l, a + ld h, $00 + ld a, [wNumVisibleCardListEntries] +.loop_visible_cards + push de + or a + jr z, .handle_down_cursor + ld b, a + ld de, wFilteredCardList + push hl + add hl, de + ld a, [hl] + pop hl + inc l + or a + jr z, .no_down_cursor + ld e, a + call AddCardIDToVisibleList + call LoadCardDataToBuffer1_FromCardID + push bc + push hl + ld de, wOwnedCardsCountList + add hl, de + dec hl + ld a, [hl] + cp CARD_NOT_OWNED + jr nz, .owned + ld hl, .EmptySlotText + ld de, wDefaultText + call CopyListFromHLToDE + jr .print_text +.owned + ld a, 13 + call CopyCardNameAndLevel +.print_text + pop hl + pop bc + pop de + push hl + call InitTextPrinting + pop hl + push hl + call .AppendCardListIndex + call ProcessText + ld hl, wDefaultText + jr .asm_a76d + + ; this code is never reached + pop de + push hl + call InitTextPrinting + ld hl, Text_9a36 + +.asm_a76d + call ProcessText + pop hl + ld a, b + dec a + inc e + inc e + jr .loop_visible_cards + +.handle_down_cursor + ld de, wFilteredCardList + add hl, de + ld a, [hl] + or a + jr z, .no_down_cursor + pop de + xor a ; FALSE + ld [wUnableToScrollDown], a + ld a, SYM_CURSOR_D + jr .got_down_cursor_tile +.no_down_cursor + pop de + ld a, TRUE + ld [wUnableToScrollDown], a + ld a, SYM_BOX_BTM_R +.got_down_cursor_tile + ld b, 19 + ld c, 17 + call WriteByteToBGMap0 + pop bc + ret + +.EmptySlotText + textfw0 "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-" + done + +; gets the index in the card list and adds it to wCurDeckName +.AppendCardListIndex + push bc + push de + ld de, wFilteredCardList + add hl, de + dec hl + ld a, [hl] + cp DOUBLE_COLORLESS_ENERGY + 1 + jr c, .energy_card + cp VENUSAUR1 + jr z, .phantom_card + cp MEW2 + jr z, .phantom_card + + ld a, [wNumVisibleCardListEntries] + sub b + ld hl, wCardListVisibleOffset + add [hl] + inc a + call CalculateOnesAndTensDigits + ld hl, wOnesAndTensPlace + ld a, [hli] + ld b, a + ld a, [hl] + or a + jr nz, .got_index + ld a, SYM_0 +.got_index + ld hl, wCurDeckName + 2 ; skip prefix + ld [hl], TX_SYMBOL + inc hl + ld [hli], a ; tens place + ld [hl], TX_SYMBOL + inc hl + ld a, b + ld [hli], a ; ones place + ld [hl], TX_SYMBOL + inc hl + xor a ; SYM_SPACE + ld [hli], a + ld [hl], a + ld hl, wCurDeckName + pop de + pop bc + ret + +.energy_card + call CalculateOnesAndTensDigits + ld hl, wOnesAndTensPlace + ld a, [hli] + ld b, a + ld hl, wCurDeckName + 2 + lb de, 3, "FW3_E" + ld [hl], d + inc hl + ld [hl], e + inc hl + ld [hl], TX_SYMBOL + inc hl + ld a, SYM_0 + ld [hli], a + ld [hl], TX_SYMBOL + inc hl + ld a, b + ld [hli], a + ld [hl], TX_SYMBOL + inc hl + xor a ; SYM_SPACE + ld [hli], a + ld [hl], a + ld hl, wCurDeckName + 2 + pop de + pop bc + ret + +.phantom_card +; phantom cards get only "✕✕" in their index number + ld hl, wCurDeckName + 2 + ld [hl], "FW0_✕" + inc hl + ld [hl], "FW0_✕" + inc hl + ld [hl], TX_SYMBOL + inc hl + xor a ; SYM_SPACE + ld [hli], a + ld [hl], a + ld hl, wCurDeckName + pop de + pop bc + ret + +; handles opening card page, and inputs when inside Card Album +HandleCardAlbumCardPage: + ld a, [wCardListCursorPos] + ld b, a + ld a, [wCardListVisibleOffset] + add b + ld c, a + ld b, $00 + ld hl, wOwnedCardsCountList + add hl, bc + ld a, [hl] + cp CARD_NOT_OWNED + jr z, .handle_input + + ld hl, wCurCardListPtr + ld a, [hli] + ld h, [hl] + ld l, a + add hl, bc + ld e, [hl] + ld d, $00 + push de + call LoadCardDataToBuffer1_FromCardID + lb de, $38, $9f + call SetupText + bank1call OpenCardPage_FromCheckHandOrDiscardPile + pop de + +.handle_input + ldh a, [hDPadHeld] + ld b, a + and A_BUTTON | B_BUTTON | SELECT | START + jp nz, .exit + xor a ; FALSE + ld [wPlaysSfx], a + ld a, [wCardListNumCursorPositions] + ld c, a + ld a, [wCardListCursorPos] + bit D_UP_F, b + jr z, .check_d_down + + push af + ld a, TRUE + ld [wPlaysSfx], a + ld a, [wCardListCursorPos] + ld hl, wCardListVisibleOffset + add [hl] + ld hl, wFirstOwnedCardIndex + cp [hl] + jr z, .open_card_page_pop_af_2 + pop af + + dec a + bit 7, a + jr z, .got_new_pos + ld a, [wCardListVisibleOffset] + or a + jr z, .open_card_page + dec a + ld [wCardListVisibleOffset], a + xor a + jr .got_new_pos + +.check_d_down + bit D_DOWN_F, b + jr z, .asm_a8d6 + + push af + ld a, TRUE + ld [wPlaysSfx], a + pop af + + inc a + cp c + jr c, .got_new_pos + push af + ld hl, wCurCardListPtr + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wCardListCursorPos] + ld c, a + ld b, $00 + add hl, bc + ld a, [wCardListVisibleOffset] + inc a + ld c, a + ld b, $00 + add hl, bc + ld a, [hl] + or a + jr z, .open_card_page_pop_af_1 + ld a, [wCardListVisibleOffset] + inc a + ld [wCardListVisibleOffset], a + pop af + dec a +.got_new_pos + ; loop back to the start + ld [wCardListCursorPos], a + ld a, [wPlaysSfx] + or a + jp z, HandleCardAlbumCardPage + call PlaySFX + jp HandleCardAlbumCardPage +.open_card_page_pop_af_1 + pop af + jr .open_card_page + +.asm_a8d6 + ld a, [wced2] + or a + jr z, .open_card_page + bit D_LEFT_F, b + jr z, .check_d_right + call RemoveCardFromDeck + jr .open_card_page +.check_d_right + bit D_RIGHT_F, b + jr z, .open_card_page + call TryAddCardToDeck + +.open_card_page_pop_af_2 + pop af +.open_card_page + push de + bank1call OpenCardPage.input_loop + pop de + jp .handle_input + +.exit + ld a, $01 + ld [wVBlankOAMCopyToggle], a + ld a, [wCardListCursorPos] + ld [wTempCardListCursorPos], a + ret + +GetFirstOwnedCardIndex: + ld hl, wOwnedCardsCountList + ld b, 0 +.loop_cards + ld a, [hli] + cp CARD_NOT_OWNED + jr nz, .owned + inc b + jr .loop_cards +.owned + ld a, b + ld [wFirstOwnedCardIndex], a + ret + +HandleCardAlbumScreen: + ld a, $01 + ld [hffb4], a ; should be ldh + + xor a +.album_card_list + ld hl, .MenuParameters + call InitializeMenuParameters + call .DrawCardAlbumScreen +.loop_input_1 + call DoFrame + call HandleMenuInput + jp nc, .loop_input_1 ; can be jr + ldh a, [hCurMenuItem] + cp $ff + ret z + + ; ignore input if this Card Set is unavailable + ld c, a + ld b, $0 + ld hl, wUnavailableAlbumCardSets + add hl, bc + ld a, [hl] + or a + jr nz, .loop_input_1 + + ld a, c + ld [wSelectedCardSet], a + call CreateCardSetListAndInitListCoords + call .PrintCardCount + xor a + ld [wCardListVisibleOffset], a + call PrintCardSetListEntries + call EnableLCD + ld a, [wNumEntriesInCurFilter] + or a + jr nz, .asm_a968 + +.loop_input_2 + call DoFrame + ldh a, [hKeysPressed] + and B_BUTTON + jr z, .loop_input_2 + ld a, $ff + call PlaySFXConfirmOrCancel + ldh a, [hCurMenuItem] + jp .album_card_list + +.asm_a968 + call .GetNumCardEntries + xor a + ld hl, .CardSelectionParams + call InitCardSelectionParams + ld a, [wNumEntriesInCurFilter] + ld hl, wNumVisibleCardListEntries + cp [hl] + jr nc, .asm_a97e + ld [wCardListNumCursorPositions], a +.asm_a97e + ld hl, PrintCardSetListEntries + ld d, h + ld a, l + ld hl, wCardListUpdateFunction + ld [hli], a + ld [hl], d + + xor a + ld [wced2], a +.loop_input_3 + call DoFrame + call HandleDeckCardSelectionList + jr c, .selection_made + call HandleLeftRightInCardList + jr c, .loop_input_3 + ldh a, [hDPadHeld] + and START + jr z, .loop_input_3 +.open_card_page + ld a, $01 + call PlaySFXConfirmOrCancel + ld a, [wCardListNumCursorPositions] + ld [wTempCardListNumCursorPositions], a + ld a, [wCardListCursorPos] + ld [wTempCardListCursorPos], a + ld c, a + ld a, [wCardListVisibleOffset] + add c + ld hl, wOwnedCardsCountList + ld c, a + ld b, $00 + add hl, bc + ld a, [hl] + cp CARD_NOT_OWNED + jr z, .loop_input_3 + + ; set wFilteredCardList as current card list + ld de, wFilteredCardList + ld hl, wCurCardListPtr + ld [hl], e + inc hl + ld [hl], d + + call GetFirstOwnedCardIndex + call HandleCardAlbumCardPage + call .PrintCardCount + call PrintCardSetListEntries + call EnableLCD + ld hl, .CardSelectionParams + call InitCardSelectionParams + ld a, [wTempCardListNumCursorPositions] + ld [wCardListNumCursorPositions], a + ld a, [wTempCardListCursorPos] + ld [wCardListCursorPos], a + jr .loop_input_3 + +.selection_made + call DrawListCursor_Invisible + ld a, [wCardListCursorPos] + ld [wTempCardListCursorPos], a + ld a, [hffb3] + cp $ff + jr nz, .open_card_page + ldh a, [hCurMenuItem] + jp .album_card_list + +.MenuParameters + db 3, 3 ; cursor x, cursor y + db 2 ; y displacement between items + db 5 ; number of items + db SYM_CURSOR_R ; cursor tile number + db SYM_SPACE ; tile behind cursor + dw NULL ; function pointer if non-0 + +.CardSelectionParams + db 1 ; x pos + db 4 ; y pos + db 2 ; y spacing + db 0 ; x spacing + db NUM_CARD_ALBUM_VISIBLE_CARDS ; num entries + db SYM_CURSOR_R ; visible cursor tile + db SYM_SPACE ; invisible cursor tile + dw NULL ; wCardListHandlerFunction + +.GetNumCardEntries + ld hl, wFilteredCardList + ld b, $00 +.loop_card_ids + ld a, [hli] + or a + jr z, .asm_aa1f + inc b + jr .loop_card_ids +.asm_aa1f + ld a, b + ld [wNumCardListEntries], a + ret + +; prints "X/Y" where X is number of cards owned in the set +; and Y is the total card count of the Card Set +.PrintCardCount + call Set_OBJ_8x8 + xor a + ld [wTileMapFill], a + call ZeroObjectPositions + call EmptyScreen + ld a, $01 + ld [wVBlankOAMCopyToggle], a + call LoadCursorTile + call LoadSymbolsFont + call LoadDuelCardSymbolTiles + bank1call SetDefaultPalettes + lb de, $3c, $ff + call SetupText + lb de, 1, 1 + call InitTextPrinting + +; print the total number of cards that are in the Card Set + ld a, [wSelectedCardSet] + cp CARD_SET_PROMOTIONAL + jr nz, .check_laboratory +; promotional + ldtx hl, Item5PromotionalCardText + ld e, NUM_CARDS_PROMOTIONAL - 2 ; minus the phantom cards + ld a, [wOwnedPhantomCardFlags] + bit VENUSAUR_OWNED_PHANTOM_F, a + jr z, .check_owns_mew + inc e +.check_owns_mew + bit MEW_OWNED_PHANTOM_F, a + jr z, .has_card_set_count + inc e + jr .has_card_set_count +.check_laboratory + cp CARD_SET_LABORATORY + jr nz, .check_mystery + ldtx hl, Item4LaboratoryText + ld e, NUM_CARDS_LABORATORY + jr .has_card_set_count +.check_mystery + cp CARD_SET_MYSTERY + jr nz, .check_evolution + ldtx hl, Item3MysteryText + ld e, NUM_CARDS_MYSTERY + jr .has_card_set_count +.check_evolution + cp CARD_SET_EVOLUTION + jr nz, .colosseum + ldtx hl, Item2EvolutionText + ld e, NUM_CARDS_EVOLUTION + jr .has_card_set_count +.colosseum + ldtx hl, Item1ColosseumText + ld e, NUM_CARDS_COLOSSEUM + +.has_card_set_count + push de + call ProcessTextFromID + call .CountOwnedCardsInSet + lb de, 14, 1 + call InitTextPrinting + + ld a, [wNumOwnedCardsInSet] + ld hl, wDefaultText + call ConvertToNumericalDigits + call CalculateOnesAndTensDigits + ld [hl], TX_SYMBOL + inc hl + ld [hl], SYM_SLASH + inc hl + pop de + + ld a, e + call ConvertToNumericalDigits + ld [hl], TX_END + ld hl, wDefaultText + call ProcessText + lb de, 0, 2 + lb bc, 20, 16 + call DrawRegularTextBox + call EnableLCD + ret + +; counts number of cards in wOwnedCardsCountList +; that is not set as CARD_NOT_OWNED +.CountOwnedCardsInSet + ld hl, wOwnedCardsCountList + ld b, 0 +.loop_card_count + ld a, [hli] + cp $ff + jr z, .got_num_owned_cards + cp CARD_NOT_OWNED + jr z, .loop_card_count + inc b + jr .loop_card_count +.got_num_owned_cards + ld a, b + ld [wNumOwnedCardsInSet], a + ret + +.DrawCardAlbumScreen + xor a + ld [wTileMapFill], a + call EmptyScreen + ld a, [hffb4] + dec a + jr nz, .skip_clear_screen + ld [hffb4], a + call Set_OBJ_8x8 + call ZeroObjectPositions + ld a, $01 + ld [wVBlankOAMCopyToggle], a + call LoadCursorTile + call LoadSymbolsFont + call LoadDuelCardSymbolTiles + bank1call SetDefaultPalettes + lb de, $3c, $ff + call SetupText + +.skip_clear_screen + lb de, 0, 0 + lb bc, 20, 13 + call DrawRegularTextBox + ld hl, .BoosterPacksMenuData + call PlaceTextItems + + ; set all Card Sets as available + ld a, NUM_CARD_SETS + ld hl, wUnavailableAlbumCardSets + call ClearNBytesFromHL + + ; check whether player has had promotional cards + call EnableSRAM + ld a, [sHasPromotionalCards] + call DisableSRAM + or a + jr nz, .has_promotional + + ; doesn't have promotional, check if + ; this is still the case by checking the collection + ld a, CARD_SET_PROMOTIONAL + call CreateCardSetListAndInitListCoords + ld a, [wFilteredCardList] + or a + jr nz, .set_has_promotional + ; still has no promotional, print empty Card Set name + ld a, TRUE + ld [wUnavailableAlbumCardSets + CARD_SET_PROMOTIONAL], a + ld e, 11 + ld d, 5 + call InitTextPrinting + ldtx hl, EmptyPromotionalCardText + call ProcessTextFromID + jr .has_promotional + +.set_has_promotional + call EnableSRAM + ld a, TRUE + ld [sHasPromotionalCards], a + call DisableSRAM +.has_promotional + ldtx hl, ViewWhichCardFileText + call DrawWideTextBox_PrintText + call EnableLCD + ret + +.BoosterPacksMenuData + textitem 7, 1, BoosterPackTitleText + textitem 5, 3, Item1ColosseumText + textitem 5, 5, Item2EvolutionText + textitem 5, 7, Item3MysteryText + textitem 5, 9, Item4LaboratoryText + textitem 5, 11, Item5PromotionalCardText + db $ff diff --git a/src/engine/menus/common.asm b/src/engine/menus/common.asm new file mode 100644 index 0000000..069d168 --- /dev/null +++ b/src/engine/menus/common.asm @@ -0,0 +1,52 @@ +ReceiveDeckConfiguration: + farcall _ReceiveDeckConfiguration + ret + +SendDeckConfiguration: + farcall _SendDeckConfiguration + ret + +ReceiveCard: + farcall _ReceiveCard + ret + +SendCard: + farcall _SendCard + ret + +; handles all the Card Pop! functionality +DoCardPop: + farcall _DoCardPop + ret + +Func_7576: + farcall Func_1991f + ret + +PreparePrinterConnection: + farcall _PreparePrinterConnection + ret + +PrintDeckConfiguration: + farcall _PrintDeckConfiguration + ret + +PrintCardList: + farcall _PrintCardList + ret + +Func_758a: + farcall Func_19eb4 + ret + +SetUpAndStartLinkDuel: + farcall _SetUpAndStartLinkDuel + ret + +Func_7594: + farcall Func_1a61f + ret + +OpenBoosterPack: + farcall _OpenBoosterPack + ret diff --git a/src/engine/menus/deck_check.asm b/src/engine/menus/deck_check.asm new file mode 100644 index 0000000..040e472 --- /dev/null +++ b/src/engine/menus/deck_check.asm @@ -0,0 +1,142 @@ +; handle player input in check menu +; works out which cursor coordinate to go to +; and sets carry flag if A or B are pressed +; returns a = $1 if A pressed +; returns a = $ff if B pressed +HandleCheckMenuInput: + xor a + ld [wPlaysSfx], a + ld a, [wCheckMenuCursorXPosition] + ld d, a + ld a, [wCheckMenuCursorYPosition] + ld e, a + +; d = cursor x position +; e = cursor y position + + ldh a, [hDPadHeld] + or a + jr z, .no_pad + bit D_LEFT_F, a + jr nz, .horizontal + bit D_RIGHT_F, a + jr z, .check_vertical + +; handle horizontal input +.horizontal + ld a, d + xor $1 ; flips x coordinate + ld d, a + jr .okay +.check_vertical + bit D_UP_F, a + jr nz, .vertical + bit D_DOWN_F, a + jr z, .no_pad + +; handle vertical input +.vertical + ld a, e + xor $01 ; flips y coordinate + ld e, a + +.okay + ld a, TRUE + ld [wPlaysSfx], a + push de + call EraseCheckMenuCursor + pop de + +; update x and y cursor positions + ld a, d + ld [wCheckMenuCursorXPosition], a + ld a, e + ld [wCheckMenuCursorYPosition], a + +; reset cursor blink + xor a + ld [wCheckMenuCursorBlinkCounter], a +.no_pad + ldh a, [hKeysPressed] + and A_BUTTON | B_BUTTON + jr z, .no_input + and A_BUTTON + jr nz, .a_press + ld a, $ff ; cancel + call PlaySFXConfirmOrCancel + scf + ret + +.a_press + call DisplayCheckMenuCursor + ld a, $01 + call PlaySFXConfirmOrCancel + scf + ret + +.no_input + ld a, [wPlaysSfx] + or a + jr z, .check_blink + call PlaySFX + +.check_blink + ld hl, wCheckMenuCursorBlinkCounter + ld a, [hl] + inc [hl] + and %00001111 + ret nz ; only update cursor if blink's lower nibble is 0 + + ld a, SYM_CURSOR_R ; cursor byte + bit 4, [hl] ; only draw cursor if blink counter's fourth bit is not set + jr z, DrawCheckMenuCursor + +; draws in the cursor position +EraseCheckMenuCursor: + ld a, SYM_SPACE ; empty cursor +; fallthrough + +; draws in the cursor position +; input: +; a = tile byte to draw +DrawCheckMenuCursor: + ld e, a + ld a, 10 + ld l, a + ld a, [wCheckMenuCursorXPosition] + ld h, a + call HtimesL + + ld a, l + add 1 + ld b, a + ld a, [wCheckMenuCursorYPosition] + sla a + add 14 + ld c, a + + ld a, e + call WriteByteToBGMap0 + or a + ret + +DisplayCheckMenuCursor: + ld a, SYM_CURSOR_R + jr DrawCheckMenuCursor + +; plays sound depending on value in a +; input: +; a = $ff: play cancel sound +; a != $ff: play confirm sound +PlaySFXConfirmOrCancel: + push af + inc a + jr z, .asm_9103 + ld a, SFX_02 ; confirmation sfx + jr .asm_9105 +.asm_9103 + ld a, SFX_03 ; cancellation sfx +.asm_9105 + call PlaySFX + pop af + ret diff --git a/src/engine/menus/deck_configuration.asm b/src/engine/menus/deck_configuration.asm new file mode 100644 index 0000000..e309de2 --- /dev/null +++ b/src/engine/menus/deck_configuration.asm @@ -0,0 +1,3617 @@ +; goes through whole deck in hl +; for each card ID, goes to its corresponding +; entry in sCardCollection and decrements its count +DecrementDeckCardsInCollection: + push hl + ld b, $0 + ld d, DECK_SIZE +.loop_deck + ld a, [hli] + or a + jr z, .done + ld c, a + push hl + ld hl, sCardCollection + add hl, bc + dec [hl] + pop hl + dec d + jr nz, .loop_deck +.done + pop hl + ret + +; like AddDeckToCollection, but takes care to +; check if increasing the collection count would +; go over MAX_AMOUNT_OF_CARD and caps it +; this is because it's used within Gift Center, +; so we cannot assume that the deck configuration +; won't make it go over MAX_AMOUNT_OF_CARD +; hl = deck configuration, with cards to add +AddGiftCenterDeckCardsToCollection: + push hl + ld b, $0 + ld d, DECK_SIZE +.loop_deck + ld a, [hli] + or a + jr z, .done + ld c, a + push hl + push de + push bc + ld a, ALL_DECKS + call CreateCardCollectionListWithDeckCards + pop bc + pop de + ld hl, wTempCardCollection + add hl, bc + ld a, [hl] + cp MAX_AMOUNT_OF_CARD + jr z, .next_card ; capped + call EnableSRAM ; no DisableSRAM + ld hl, sCardCollection + add hl, bc + ld a, [hl] + cp CARD_NOT_OWNED + jr nz, .incr + ; not owned + xor a + ld [hl], a +.incr + inc [hl] +.next_card + pop hl + dec d + jr nz, .loop_deck +.done + pop hl + ret + +; adds all cards in deck in hl to player's collection +; assumes SRAM is enabled +; hl = pointer to deck cards +AddDeckToCollection: + push hl + ld b, $0 + ld d, DECK_SIZE +.loop_deck + ld a, [hli] + or a + jr z, .done + ld c, a + push hl + ld hl, sCardCollection + add hl, bc + inc [hl] + pop hl + dec d + jr nz, .loop_deck +.done + pop hl + ret + +; draws the screen which shows the player's current +; deck configurations +; a = DECK_* flags to pick which deck names to show +DrawDecksScreen: + ld [hffb5], a + call EmptyScreenAndLoadFontDuelAndHandCardsIcons + lb de, 0, 0 + lb bc, 20, 4 + call DrawRegularTextBox + lb de, 0, 3 + lb bc, 20, 4 + call DrawRegularTextBox + lb de, 0, 6 + lb bc, 20, 4 + call DrawRegularTextBox + lb de, 0, 9 + lb bc, 20, 4 + call DrawRegularTextBox + ld hl, DeckNameMenuData + call PlaceTextItems + +; mark all decks as invalid + ld a, NUM_DECKS + ld hl, wDecksValid + call ClearNBytesFromHL + +; for each deck, check if it has cards and if so +; mark is as valid in wDecksValid + +; deck 1 + ld a, [hffb5] ; should be ldh + bit 0, a + jr z, .skip_name_1 + ld hl, sDeck1Name + lb de, 6, 2 + call PrintDeckName +.skip_name_1 + ld hl, sDeck1Cards + call CheckIfDeckHasCards + jr c, .deck_2 + ld a, TRUE + ld [wDeck1Valid], a + +.deck_2 + ld a, [hffb5] ; should be ldh + bit 1, a + jr z, .skip_name_2 + ld hl, sDeck2Name + lb de, 6, 5 + call PrintDeckName +.skip_name_2 + ld hl, sDeck2Cards + call CheckIfDeckHasCards + jr c, .deck_3 + ld a, TRUE + ld [wDeck2Valid], a + +.deck_3 + ld a, [hffb5] ; should be ldh + bit 2, a + jr z, .skip_name_3 + ld hl, sDeck3Name + lb de, 6, 8 + call PrintDeckName +.skip_name_3 + ld hl, sDeck3Cards + call CheckIfDeckHasCards + jr c, .deck_4 + ld a, TRUE + ld [wDeck3Valid], a + +.deck_4 + ld a, [hffb5] ; should be ldh + bit 3, a + jr z, .skip_name_4 + ld hl, sDeck4Name + lb de, 6, 11 + call PrintDeckName +.skip_name_4 + ld hl, sDeck4Cards + call CheckIfDeckHasCards + jr c, .place_cursor + ld a, TRUE + ld [wDeck4Valid], a + +.place_cursor +; places cursor on sCurrentlySelectedDeck +; if it's an empty deck, then advance the cursor +; until it's selecting a valid deck + call EnableSRAM + ld a, [sCurrentlySelectedDeck] + ld c, a + ld b, $0 + ld d, 2 +.check_valid_deck + ld hl, wDecksValid + add hl, bc + ld a, [hl] + or a + jr nz, .valid_selected_deck + inc c + ld a, NUM_DECKS + cp c + jr nz, .check_valid_deck + ld c, 0 ; roll back to deck 1 + dec d + jr z, .valid_selected_deck + jr .check_valid_deck + +.valid_selected_deck + ld a, c + ld [sCurrentlySelectedDeck], a + call DisableSRAM + call DrawHandCardsTileOnCurDeck + call EnableLCD + ret + +DeckNameMenuData: + textitem 4, 2, Deck1Text + textitem 4, 5, Deck2Text + textitem 4, 8, Deck3Text + textitem 4, 11, Deck4Text + db $ff + +; copies text from hl to wDefaultText +; with " deck" appended to the end +; hl = ptr to deck name +CopyDeckName: + ld de, wDefaultText + call CopyListFromHLToDE + ld hl, wDefaultText + call GetTextLengthInTiles + ld b, $0 + ld hl, wDefaultText + add hl, bc + ld d, h + ld e, l + ld hl, DeckNameSuffix + call CopyListFromHLToDE + ret + +; prints deck name given in hl in position de +; if it's an empty deck, print "NEW DECK" instead +; returns carry if it's an empty deck +; hl = deck name (sDeck1Name ~ sDeck4Name) +; de = coordinates to print text +PrintDeckName: + push hl + call CheckIfDeckHasCards + pop hl + jr c, .new_deck + +; print "<deck name> deck" + push de + ld de, wDefaultText + call CopyListFromHLToDEInSRAM + ld hl, wDefaultText + call GetTextLengthInTiles + ld b, $0 + ld hl, wDefaultText + add hl, bc + ld d, h + ld e, l + ld hl, DeckNameSuffix + call CopyListFromHLToDE + pop de + ld hl, wDefaultText + call InitTextPrinting + call ProcessText + or a + ret + +.new_deck +; print "NEW DECK" + call InitTextPrinting + ldtx hl, NewDeckText + call ProcessTextFromID + scf + ret + +DeckNameSuffix: + db " deck" + done + +; copies a $00-terminated list from hl to de +CopyListFromHLToDE: + ld a, [hli] + ld [de], a + or a + ret z + inc de + jr CopyListFromHLToDE + +; same as CopyListFromHLToDE, but for SRAM copying +CopyListFromHLToDEInSRAM: + call EnableSRAM + call CopyListFromHLToDE + call DisableSRAM + ret + +; appends text in hl to wDefaultText +; then adds "deck" to the end +; returns carry if deck has no cards +; hl = text to append +; de = input to InitTextPrinting +AppendDeckName: + push hl + call CheckIfDeckHasCards + pop hl + ret c ; no cards + + push de + ; append the text from hl + ld de, wDefaultText + call CopyListFromHLToDEInSRAM + + ; get string length (up to DECK_NAME_SIZE_WO_SUFFIX) + ld hl, wDefaultText + call GetTextLengthInTiles + ld a, c + cp DECK_NAME_SIZE_WO_SUFFIX + jr c, .got_len + ld c, DECK_NAME_SIZE_WO_SUFFIX +.got_len + ld b, $0 + ld hl, wDefaultText + add hl, bc + ld d, h + ld e, l + ; append "deck" starting from the given length + ld hl, .text_start + ld b, .text_end - .text_start + call CopyNBytesFromHLToDE + xor a ; TX_END + ld [wDefaultText + DECK_NAME_SIZE + 2], a + pop de + ld hl, wDefaultText + call InitTextPrinting + call ProcessText + or a + ret + +.text_start + db " deck " +.text_end + +; returns carry if the deck in hl +; is not valid, that is, has no cards +; alternatively, the direct address of the cards +; can be used, since DECK_SIZE > DECK_NAME_SIZE +; hl = deck name (sDeck1Name ~ sDeck4Name) +; or deck cards (sDeck1Cards ~ sDeck4Cards) +CheckIfDeckHasCards: + ld bc, DECK_NAME_SIZE + add hl, bc + call EnableSRAM + ld a, [hl] + call DisableSRAM + ; being max size means last char + ; is not TX_END, i.e. $0 + or a + jr nz, .max_size + scf + ret +.max_size + or a + ret + +; calculates the y coordinate of the currently selected deck +; and draws the hands card tile at that position +DrawHandCardsTileOnCurDeck: + call EnableSRAM + ld a, [sCurrentlySelectedDeck] + call DisableSRAM + ld h, 3 + ld l, a + call HtimesL + ld e, l + inc e ; (sCurrentlySelectedDeck * 3) + 1 + ld d, 2 +; fallthrough + +; de = coordinates to draw rectangle +DrawHandCardsTileAtDE: + ld a, $38 ; hand cards tile + lb hl, 1, 2 + lb bc, 2, 2 + call FillRectangle + ret + +; handles user input when selecting a card filter +; when building a deck configuration +; the handling of selecting cards themselves from the list +; to add/remove to the deck is done in HandleDeckCardSelectionList +HandleDeckBuildScreen: + call WriteCardListsTerminatorBytes + call CountNumberOfCardsForEachCardType +.skip_count + call DrawCardTypeIconsAndPrintCardCounts + + xor a + ld [wCardListVisibleOffset], a + ld [wCurCardTypeFilter], a ; FILTER_GRASS + call PrintFilteredCardList + +.skip_draw + ld hl, FiltersCardSelectionParams + call InitCardSelectionParams +.wait_input + call DoFrame + ldh a, [hDPadHeld] + and START + jr z, .no_start_btn_1 + ld a, $01 + call PlaySFXConfirmOrCancel + call ConfirmDeckConfiguration + ld a, [wCurCardTypeFilter] + ld [wTempCardTypeFilter], a + jr .wait_input + +.no_start_btn_1 + ld a, [wCurCardTypeFilter] + ld b, a + ld a, [wTempCardTypeFilter] + cp b + jr z, .check_down_btn + ; need to refresh the filtered card list + ld [wCurCardTypeFilter], a + ld hl, wCardListVisibleOffset + ld [hl], 0 + call PrintFilteredCardList + ld a, NUM_FILTERS + ld [wCardListNumCursorPositions], a + +.check_down_btn + ldh a, [hDPadHeld] + and D_DOWN + jr z, .no_down_btn + call ConfirmSelectionAndReturnCarry + jr .jump_to_list + +.no_down_btn + call HandleCardSelectionInput + jr nc, .wait_input + ld a, [hffb3] + cp $ff ; operation cancelled? + jp z, OpenDeckConfigurationMenu + +; input was made to jump to the card list +.jump_to_list + ld a, [wNumEntriesInCurFilter] + or a + jr z, .wait_input + xor a +.wait_list_input + ld hl, FilteredCardListSelectionParams + call InitCardSelectionParams + ld a, [wNumEntriesInCurFilter] + ld [wNumCardListEntries], a + ld hl, wNumVisibleCardListEntries + cp [hl] + jr nc, .ok + ; if total number of entries is greater than or equal to + ; the number of visible entries, then set number of cursor positions + ; as number of visible entries + ld [wCardListNumCursorPositions], a +.ok + ld hl, PrintDeckBuildingCardList + ld d, h + ld a, l + ld hl, wCardListUpdateFunction + ld [hli], a + ld [hl], d + + ld a, $01 + ld [wced2], a +.loop_input + call DoFrame + ldh a, [hDPadHeld] + and START + jr z, .no_start_btn_2 + ld a, $01 + call PlaySFXConfirmOrCancel + + ; temporarily store current cursor position + ; to retrieve it later + ld a, [wCardListCursorPos] + ld [wTempFilteredCardListNumCursorPositions], a + call ConfirmDeckConfiguration + ld a, [wTempFilteredCardListNumCursorPositions] + jr .wait_list_input + +.no_start_btn_2 + call HandleSelectUpAndDownInList + jr c, .loop_input + call HandleDeckCardSelectionList + jr c, .selection_made + jr .loop_input + +.open_card_page + ld a, $01 + call PlaySFXConfirmOrCancel + ld a, [wCardListNumCursorPositions] + ld [wTempCardListNumCursorPositions], a + ld a, [wCardListCursorPos] + ld [wTempCardListCursorPos], a + + ; set wFilteredCardList as current card list + ; and show card page screen + ld de, wFilteredCardList + ld hl, wCurCardListPtr + ld [hl], e + inc hl + ld [hl], d + call OpenCardPageFromCardList + call DrawCardTypeIconsAndPrintCardCounts + + ld hl, FiltersCardSelectionParams + call InitCardSelectionParams + ld a, [wCurCardTypeFilter] + ld [wTempCardTypeFilter], a + call DrawHorizontalListCursor_Visible + call PrintDeckBuildingCardList + ld hl, FilteredCardListSelectionParams + call InitCardSelectionParams + ld a, [wTempCardListNumCursorPositions] + ld [wCardListNumCursorPositions], a + ld a, [wTempCardListCursorPos] + ld [wCardListCursorPos], a + jr .loop_input + +.selection_made + call DrawListCursor_Invisible + ld a, [wCardListCursorPos] + ld [wTempCardListCursorPos], a + ld a, [hffb3] + cp $ff + jr nz, .open_card_page + ; cancelled + ld hl, FiltersCardSelectionParams + call InitCardSelectionParams + ld a, [wCurCardTypeFilter] + ld [wTempCardTypeFilter], a + jp .wait_input + +OpenDeckConfigurationMenu: + xor a + ld [wYourOrOppPlayAreaCurPosition], a + ld de, wDeckConfigurationMenuTransitionTable + ld hl, wMenuInputTablePointer + ld a, [de] + ld [hli], a + inc de + ld a, [de] + ld [hl], a + ld a, $ff + ld [wDuelInitialPrizesUpperBitsSet], a +.skip_init + xor a + ld [wCheckMenuCursorBlinkCounter], a + ld hl, wDeckConfigurationMenuHandlerFunction + ld a, [hli] + ld h, [hl] + ld l, a + jp hl + +HandleDeckConfigurationMenu: + lb de, 0, 0 + lb bc, 20, 6 + call DrawRegularTextBox + ld hl, DeckBuildMenuData + call PlaceTextItems + +.do_frame + ld a, $1 + ld [wVBlankOAMCopyToggle], a + call DoFrame + call YourOrOppPlayAreaScreen_HandleInput + jr nc, .do_frame + ld [wced6], a + cp $ff + jr nz, .asm_94b5 +.draw_icons + call DrawCardTypeIconsAndPrintCardCounts + ld a, [wTempCardListCursorPos] + ld [wCardListCursorPos], a + ld a, [wCurCardTypeFilter] + call PrintFilteredCardList + jp HandleDeckBuildScreen.skip_draw + +.asm_94b5 + push af + call YourOrOppPlayAreaScreen_HandleInput.draw_cursor + ld a, $01 + ld [wVBlankOAMCopyToggle], a + pop af + ld hl, .func_table + call JumpToFunctionInTable + jr OpenDeckConfigurationMenu.skip_init + +.func_table + dw ConfirmDeckConfiguration ; Confirm + dw ModifyDeckConfiguration ; Modify + dw ChangeDeckName ; Name + dw SaveDeckConfiguration ; Save + dw DismantleDeck ; Dismantle + dw CancelDeckModifications ; Cancel + +ConfirmDeckConfiguration: + ld hl, wCardListVisibleOffset + ld a, [hl] + ld hl, wCardListVisibleOffsetBackup + ld [hl], a + call HandleDeckConfirmationMenu + ld hl, wCardListVisibleOffsetBackup + ld a, [hl] + ld hl, wCardListVisibleOffset + ld [hl], a + call DrawCardTypeIconsAndPrintCardCounts + ld hl, FiltersCardSelectionParams + call InitCardSelectionParams + ld a, [wCurCardTypeFilter] + ld [wTempCardTypeFilter], a + call DrawHorizontalListCursor_Visible + ld a, [wCurCardTypeFilter] + call PrintFilteredCardList + ld a, [wced6] + ld [wCardListCursorPos], a + ret + +ModifyDeckConfiguration: + add sp, $2 + jr HandleDeckConfigurationMenu.draw_icons + +; returns carry set if player chose to go back +CancelDeckModifications: +; if deck was not changed, cancel modification immediately + call CheckIfCurrentDeckWasChanged + jr nc, .cancel_modification +; else prompt the player to confirm + ldtx hl, QuitModifyingTheDeckText + call YesOrNoMenuWithText + jr c, SaveDeckConfiguration.go_back +.cancel_modification + add sp, $2 + or a + ret + +SaveDeckConfiguration: +; handle deck configuration size + ld a, [wTotalCardCount] + cp DECK_SIZE + jp z, .ask_to_save_deck ; can be jr + ldtx hl, ThisIsntA60CardDeckText + call DrawWideTextBox_WaitForInput + ldtx hl, ReturnToOriginalConfigurationText + call YesOrNoMenuWithText + jr c, .print_deck_size_warning +; return no carry + add sp, $2 + or a + ret +.print_deck_size_warning + ldtx hl, TheDeckMustInclude60CardsText + call DrawWideTextBox_WaitForInput + jr .go_back + +.ask_to_save_deck + ldtx hl, SaveThisDeckText + call YesOrNoMenuWithText + jr c, .go_back + call CheckIfThereAreAnyBasicCardsInDeck + jr c, .set_carry + ldtx hl, ThereAreNoBasicPokemonInThisDeckText + call DrawWideTextBox_WaitForInput + ldtx hl, YouMustIncludeABasicPokemonInTheDeckText + call DrawWideTextBox_WaitForInput + +.go_back + call DrawCardTypeIconsAndPrintCardCounts + call PrintDeckBuildingCardList + ld a, [wced6] + ld [wCardListCursorPos], a + ret + +.set_carry + add sp, $2 + scf + ret + +DismantleDeck: + ldtx hl, DismantleThisDeckText + call YesOrNoMenuWithText + jr c, SaveDeckConfiguration.go_back + call CheckIfHasOtherValidDecks + jp nc, .Dismantle ; can be jr + ldtx hl, ThereIsOnly1DeckSoCannotBeDismantledText + call DrawWideTextBox_WaitForInput + call EmptyScreen + ld hl, FiltersCardSelectionParams + call InitCardSelectionParams + ld a, [wCurCardTypeFilter] + ld [wTempCardTypeFilter], a + call DrawHorizontalListCursor_Visible + call PrintDeckBuildingCardList + call EnableLCD + ld a, [wced6] + ld [wCardListCursorPos], a + ret + +.Dismantle + call EnableSRAM + call GetPointerToDeckName + ld a, [hl] + or a + jr z, .done_dismantle + ld a, NAME_BUFFER_LENGTH + call ClearNBytesFromHL + call GetPointerToDeckCards + call AddDeckToCollection + ld a, DECK_SIZE + call ClearNBytesFromHL +.done_dismantle + call DisableSRAM + add sp, $2 + ret + +ChangeDeckName: + call InputCurDeckName + add sp, $2 + jp HandleDeckBuildScreen.skip_count + +; returns carry if current deck was changed +; either through its card configuration or its name +CheckIfCurrentDeckWasChanged: + ld a, [wTotalCardCount] + or a + jr z, .skip_size_check + cp DECK_SIZE + jr nz, .set_carry +.skip_size_check + +; copy the selected deck to wCurDeckCardChanges + call GetPointerToDeckCards + ld de, wCurDeckCardChanges + ld b, DECK_SIZE + call EnableSRAM + call CopyNBytesFromHLToDE + call DisableSRAM + +; loops through cards in wCurDeckCards +; then if that card is found in wCurDeckCardChanges +; overwrite it by $0 + ld a, $ff ; terminator byte + ld [wCurDeckCardChanges + DECK_SIZE], a + ld de, wCurDeckCards +.loop_outer + ld a, [de] + or a + jr z, .check_empty + ld b, a + inc de + ld hl, wCurDeckCardChanges +.loop_inner + ld a, [hli] + cp $ff + jr z, .loop_outer + cp b + jr nz, .loop_inner + ; found + dec hl + xor a + ld [hli], a ; remove + jr .loop_outer + +.check_empty + ld hl, wCurDeckCardChanges +.loop_check_empty + ld a, [hli] + cp $ff + jr z, .is_empty + or a + jr nz, .set_carry + jr .loop_check_empty + +.is_empty +; wCurDeckCardChanges is empty (all $0) +; check if name was changed + call GetPointerToDeckName + ld de, wCurDeckName + call EnableSRAM +.loop_name + ld a, [de] + cp [hl] + jr nz, .set_carry + inc de + inc hl + or a + jr nz, .loop_name + call DisableSRAM + ret + +.set_carry + call DisableSRAM + scf + ret + +; returns carry if doesn't have a valid deck +; aside from the current deck +CheckIfHasOtherValidDecks: + ld hl, wDecksValid + lb bc, 0, 0 +.loop + inc b + ld a, NUM_DECKS + cp b + jr c, .check_has_cards + ld a, [hli] + or a + jr z, .loop + ; is valid + inc c + ld a, 1 + cp c + jr nc, .loop ; just 1 valid + ; at least 2 decks are valid +.no_carry + or a + ret + +.check_has_cards +; doesn't have at least 2 valid decks +; check if current deck is the only one +; that is valid (i.e. has cards) + call GetPointerToDeckCards + call EnableSRAM + ld a, [hl] + call DisableSRAM + or a + jr z, .no_carry ; no cards + ; has cards, is the only valid deck! + scf + ret + +; checks if wCurDeckCards has any basics +; returns carry set if there is at least +; 1 Basic Pokemon card +CheckIfThereAreAnyBasicCardsInDeck: + ld hl, wCurDeckCards +.loop_cards + ld a, [hli] + ld e, a + or a + jr z, .no_carry + call LoadCardDataToBuffer1_FromCardID + jr c, .no_carry + ld a, [wLoadedCard1Type] + and TYPE_ENERGY + jr nz, .loop_cards + ld a, [wLoadedCard1Stage] + or a + jr nz, .loop_cards + ; is basic card + scf + ret +.no_carry + or a + ret + +FiltersCardSelectionParams: + db 1 ; x pos + db 1 ; y pos + db 0 ; y spacing + db 2 ; x spacing + db NUM_FILTERS ; num entries + db SYM_CURSOR_D ; visible cursor tile + db SYM_SPACE ; invisible cursor tile + dw NULL ; wCardListHandlerFunction + +FilteredCardListSelectionParams: + db 0 ; x pos + db 7 ; y pos + db 2 ; y spacing + db 0 ; x spacing + db NUM_FILTERED_LIST_VISIBLE_CARDS ; num entries + db SYM_CURSOR_R ; visible cursor tile + db SYM_SPACE ; invisible cursor tile + dw NULL ; wCardListHandlerFunction + +DeckConfigurationMenu_TransitionTable: + cursor_transition $10, $20, $00, $03, $03, $01, $02 + cursor_transition $48, $20, $00, $04, $04, $02, $00 + cursor_transition $80, $20, $00, $05, $05, $00, $01 + cursor_transition $10, $30, $00, $00, $00, $04, $05 + cursor_transition $48, $30, $00, $01, $01, $05, $03 + cursor_transition $80, $30, $00, $02, $02, $03, $04 + +; draws each card type icon in a line +; the respective card counts underneath each icon +; and prints"X/60" in the upper-right corner, +; where X is the total card count +DrawCardTypeIconsAndPrintCardCounts: + call Set_OBJ_8x8 + call Func_8d78 + lb bc, 0, 5 + ld a, SYM_BOX_TOP + call FillBGMapLineWithA + call DrawCardTypeIcons + call PrintCardTypeCounts + lb de, 15, 0 + call PrintTotalCardCount + lb de, 17, 0 + call PrintSlashSixty + call EnableLCD + ret + +; fills one line at coordinate bc in BG Map +; with the byte in register a +; fills the same line with $04 in VRAM1 if in CGB +; bc = coordinates +FillBGMapLineWithA: + call BCCoordToBGMap0Address + ld b, SCREEN_WIDTH + call FillDEWithA + ld a, [wConsole] + cp CONSOLE_CGB + ret nz ; return if not CGB + ld a, $04 + ld b, SCREEN_WIDTH + call BankswitchVRAM1 + call FillDEWithA + call BankswitchVRAM0 + ret + +; saves the count of each type of card that is in wCurDeckCards +; stores these values in wCardFilterCounts +CountNumberOfCardsForEachCardType: + ld hl, wCardFilterCounts + ld de, CardTypeFilters +.loop + ld a, [de] + cp -1 + ret z + inc de + call CountNumberOfCardsOfType + ld [hli], a + jr .loop + +; fills de with b bytes of the value in register a +FillDEWithA: + push hl + ld l, e + ld h, d +.loop + ld [hli], a + dec b + jr nz, .loop + pop hl + ret + +; draws all the card type icons +; in a line specified by .CardTypeIcons +DrawCardTypeIcons: + ld hl, .CardTypeIcons +.loop + ld a, [hli] + or a + ret z ; done + ld d, [hl] ; x coord + inc hl + ld e, [hl] ; y coord + inc hl + call .DrawIcon + jr .loop + +; input: +; de = coordinates +.DrawIcon + push hl + push af + lb hl, 1, 2 + lb bc, 2, 2 + call FillRectangle + pop af + call GetCardTypeIconPalette + ld b, a + ld a, [wConsole] + cp CONSOLE_CGB + jr nz, .not_cgb + ld a, b + lb bc, 2, 2 + lb hl, 0, 0 + call BankswitchVRAM1 + call FillRectangle + call BankswitchVRAM0 +.not_cgb + pop hl + ret + +.CardTypeIcons +; icon tile, x coord, y coord + db ICON_TILE_GRASS, 1, 2 + db ICON_TILE_FIRE, 3, 2 + db ICON_TILE_WATER, 5, 2 + db ICON_TILE_LIGHTNING, 7, 2 + db ICON_TILE_FIGHTING, 9, 2 + db ICON_TILE_PSYCHIC, 11, 2 + db ICON_TILE_COLORLESS, 13, 2 + db ICON_TILE_TRAINER, 15, 2 + db ICON_TILE_ENERGY, 17, 2 + db $00 + +DeckBuildMenuData: + ; x, y, text id + textitem 2, 2, ConfirmText + textitem 9, 2, ModifyText + textitem 16, 2, NameText + textitem 2, 4, SaveText + textitem 9, 4, DismantleText + textitem 16, 4, CancelText + db $ff + +; prints "/60" to the coordinates given in de +PrintSlashSixty: + ld hl, wDefaultText + ld a, TX_SYMBOL + ld [hli], a + ld a, SYM_SLASH + ld [hli], a + ld a, TX_SYMBOL + ld [hli], a + ld a, SYM_6 + ld [hli], a + ld a, TX_SYMBOL + ld [hli], a + ld a, SYM_0 + ld [hli], a + ld [hl], TX_END + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + ret + +; creates two separate lists given the card type in register a +; if a card matches the card type given, then it's added to wFilteredCardList +; if a card has been owned by the player, and its card count is at least 1, +; (or in case it's 0 if it's in any deck configurations saved) +; then its collection count is also added to wOwnedCardsCountList +; if input a is $ff, then all card types are included +CreateFilteredCardList: + push af + push bc + push de + push hl + +; clear wOwnedCardsCountList and wFilteredCardList + push af + ld a, DECK_SIZE + ld hl, wOwnedCardsCountList + call ClearNBytesFromHL + ld a, DECK_SIZE + ld hl, wFilteredCardList + call ClearNBytesFromHL + pop af + +; loops all cards in collection + ld hl, $0 + ld de, $0 + ld b, a ; input card type +.loop_card_ids + inc e + call GetCardType + jr c, .store_count + ld c, a + ld a, b + cp $ff + jr z, .add_card + and FILTER_ENERGY + cp FILTER_ENERGY + jr z, .check_energy + ld a, c + cp b + jr nz, .loop_card_ids + jr .add_card +.check_energy + ld a, c + and TYPE_ENERGY + cp TYPE_ENERGY + jr nz, .loop_card_ids + +.add_card + push bc + push hl + ld bc, wFilteredCardList + add hl, bc + ld [hl], e + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + pop hl + cp CARD_NOT_OWNED + jr z, .next_card ; jump if never seen card + or a + jr nz, .ok ; has at least 1 + call IsCardInAnyDeck + jr c, .next_card ; jump if not in any deck +.ok + push hl + ld bc, wOwnedCardsCountList + add hl, bc + ld [hl], a + pop hl + inc l +.next_card + pop bc + jr .loop_card_ids + +.store_count + ld a, l + ld [wNumEntriesInCurFilter], a +; add terminator bytes in both lists + xor a + ld c, l + ld b, h + ld hl, wFilteredCardList + add hl, bc + ld [hl], a ; $00 + ld a, $ff + ld hl, wOwnedCardsCountList + add hl, bc + ld [hl], a ; $ff + pop hl + pop de + pop bc + pop af + ret + +; returns carry if card ID in register e is not +; found in any of the decks saved in SRAM +IsCardInAnyDeck: + push af + push hl + ld hl, sDeck1Cards + call .FindCardInDeck + jr nc, .found_card + ld hl, sDeck2Cards + call .FindCardInDeck + jr nc, .found_card + ld hl, sDeck3Cards + call .FindCardInDeck + jr nc, .found_card + ld hl, sDeck4Cards + call .FindCardInDeck + jr nc, .found_card + pop hl + pop af + scf + ret +.found_card + pop hl + pop af + or a + ret + +; returns carry if input card ID in register e +; is not found in deck given by hl +.FindCardInDeck + call EnableSRAM + ld b, DECK_SIZE +.loop + ld a, [hli] + cp e + jr z, .not_found + dec b + jr nz, .loop +; not found + call DisableSRAM + scf + ret +.not_found + call DisableSRAM + or a + ret + +; preserves all registers +; hl = start of bytes to set to $0 +; a = number of bytes to set to $0 +ClearNBytesFromHL: + push af + push bc + push hl + ld b, a + xor a +.loop + ld [hli], a + dec b + jr nz, .loop + pop hl + pop bc + pop af + ret + +; returns the number of times that card e +; appears in wCurDeckCards +GetCountOfCardInCurDeck: + push hl + ld hl, wCurDeckCards + ld d, 0 +.loop + ld a, [hli] + or a + jr z, .done + cp e + jr nz, .loop + inc d + jr .loop +.done + ld a, d + pop hl + ret + +; returns total count of card ID e +; looks it up in wFilteredCardList +; then uses the index to retrieve the count +; value from wOwnedCardsCountList +GetOwnedCardCount: + push hl + ld hl, wFilteredCardList + ld d, -1 +.loop + inc d + ld a, [hli] + or a + jr z, .not_found + cp e + jr nz, .loop + ld hl, wOwnedCardsCountList + push de + ld e, d + ld d, $00 + add hl, de + pop de + ld a, [hl] + pop hl + ret +.not_found + xor a + pop hl + ret + +; appends text "X/Y", where X is the number of included cards +; and Y is the total number of cards in storage of a given card ID +; input: +; e = card ID +AppendOwnedCardCountAndStorageCountNumbers: + push af + push bc + push de + push hl +; count how many bytes until $00 +.loop + ld a, [hl] + or a + jr z, .print + inc hl + jr .loop +.print + push de + call GetCountOfCardInCurDeck + call ConvertToNumericalDigits + ld [hl], TX_SYMBOL + inc hl + ld [hl], SYM_SLASH + inc hl + pop de + call GetOwnedCardCount + call ConvertToNumericalDigits + ld [hl], TX_END + pop hl + pop de + pop bc + pop af + ret + +; determines the ones and tens digits in a for printing +; the ones place is added $20 (SYM_0) so that it maps to a numerical character +; if the tens is 0, it maps to an empty character +; a = value to calculate digits +CalculateOnesAndTensDigits: + push af + push bc + push de + push hl + ld c, -1 +.loop + inc c + sub 10 + jr nc, .loop + jr z, .zero1 + add 10 + ; a = a mod 10 + ; c = floor(a / 10) +.zero1 +; ones digit + add SYM_0 + ld hl, wOnesAndTensPlace + ld [hli], a + +; tens digit + ld a, c + or a + jr z, .zero2 + add SYM_0 +.zero2 + ld [hl], a + + pop hl + pop de + pop bc + pop af + ret + +; converts value in register a to +; numerical symbols for ProcessText +; places the symbols in hl +ConvertToNumericalDigits: + call CalculateOnesAndTensDigits + push hl + ld hl, wOnesAndTensPlace + ld a, [hli] + ld b, a + ld a, [hl] + pop hl + ld [hl], TX_SYMBOL + inc hl + ld [hli], a + ld [hl], TX_SYMBOL + inc hl + ld a, b + ld [hli], a + ret + +; counts the number of cards in wCurDeckCards +; that are the same type as input in register a +; if input is $20, counts all energy cards instead +; input: +; - a = card type +; output: +; - a = number of cards of same type +CountNumberOfCardsOfType: + push de + push hl + ld hl, $0 + ld b, a + ld c, 0 +.loop_cards + push hl + push bc + ld bc, wCurDeckCards + add hl, bc + ld a, [hl] + pop bc + pop hl + inc l + or a + jr z, .done ; end of card list + +; get card type and compare it with input type +; if input is FILTER_ENERGY, run a separate comparison +; if it's the same type, increase the count + ld e, a + call GetCardType + jr c, .done + push hl + ld l, a + ld a, b + and FILTER_ENERGY + cp FILTER_ENERGY + jr z, .check_energy + ld a, l + pop hl + cp b + jr nz, .loop_cards + jr .incr_count + +; counts all energy cards as the same +.check_energy + ld a, l + pop hl + and TYPE_ENERGY + cp TYPE_ENERGY + jr nz, .loop_cards +.incr_count + inc c + jr .loop_cards +.done + ld a, c + pop hl + pop de + ret + +; prints the card count of each individual card type +; assumes CountNumberOfCardsForEachCardType was already called +; this is done by processing text in a single line +; and concatenating all digits +PrintCardTypeCounts: + ld bc, $0 + ld hl, wDefaultText +.loop + push hl + ld hl, wCardFilterCounts + add hl, bc + ld a, [hl] + pop hl + push bc + call ConvertToNumericalDigits + pop bc + inc c + ld a, NUM_FILTERS + cp c + jr nz, .loop + ld [hl], TX_END + lb de, 1, 4 + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + ret + +; prints the list of cards, applying the filter from register a +; the counts of each card displayed is taken from wCurDeck +; a = card type filter +PrintFilteredCardList: + push af + ld hl, CardTypeFilters + ld b, $00 + ld c, a + add hl, bc + ld a, [hl] + push af + +; copy sCardCollection to wTempCardCollection + call EnableSRAM + ld hl, sCardCollection + ld de, wTempCardCollection + ld b, CARD_COLLECTION_SIZE - 1 + call CopyNBytesFromHLToDE + call DisableSRAM + + ld a, [wIncludeCardsInDeck] + or a + jr z, .ok + call GetPointerToDeckCards + ld d, h + ld e, l + call IncrementDeckCardsInTempCollection +.ok + pop af + + call CreateFilteredCardList + ld a, NUM_FILTERED_LIST_VISIBLE_CARDS + ld [wNumVisibleCardListEntries], a + lb de, 1, 7 + ld hl, wCardListCoords + ld [hl], e + inc hl + ld [hl], d + call PrintDeckBuildingCardList + pop af + ret + +; used to filter the cards in the deck building/card selection screen +CardTypeFilters: + db FILTER_GRASS + db FILTER_FIRE + db FILTER_WATER + db FILTER_LIGHTNING + db FILTER_FIGHTING + db FILTER_PSYCHIC + db FILTER_COLORLESS + db FILTER_TRAINER + db FILTER_ENERGY + db -1 ; end of list + +; counts all the cards from each card type +; (stored in wCardFilterCounts) and store it in wTotalCardCount +; also prints it in coordinates de +PrintTotalCardCount: + push de + ld bc, $0 + ld hl, wCardFilterCounts +.loop + ld a, [hli] + add b + ld b, a + inc c + ld a, NUM_FILTERS + cp c + jr nz, .loop + ld hl, wDefaultText + ld a, b + ld [wTotalCardCount], a + push bc + call ConvertToNumericalDigits + pop bc + ld [hl], TX_END + pop de + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + ret + +; prints the name, level and storage count of the cards +; that are visible in the list window +; in the form: +; CARD NAME/LEVEL X/Y +; where X is the current count of that card +; and Y is the storage count of that card +PrintDeckBuildingCardList: + push bc + ld hl, wCardListCoords + ld e, [hl] + inc hl + ld d, [hl] + ld b, 19 ; x coord + ld c, e + dec c + ld a, [wCardListVisibleOffset] + or a + jr z, .no_cursor + ld a, SYM_CURSOR_U + jr .got_cursor_tile +.no_cursor + ld a, SYM_SPACE +.got_cursor_tile + call WriteByteToBGMap0 + +; iterates by decreasing value in wNumVisibleCardListEntries +; by 1 until it reaches 0 + ld a, [wCardListVisibleOffset] + ld c, a + ld b, $0 + ld hl, wFilteredCardList + add hl, bc + ld a, [wNumVisibleCardListEntries] +.loop_filtered_cards + push de + or a + jr z, .exit_loop + ld b, a + ld a, [hli] + or a + jr z, .invalid_card ; card ID of 0 + ld e, a + call AddCardIDToVisibleList + call LoadCardDataToBuffer1_FromCardID + ld a, 13 + push bc + push hl + push de + call CopyCardNameAndLevel + pop de + call AppendOwnedCardCountAndStorageCountNumbers + pop hl + pop bc + pop de + push hl + call InitTextPrinting + ld hl, wDefaultText + jr .process_text + +.invalid_card + pop de + push hl + call InitTextPrinting + ld hl, Text_9a30 +.process_text + call ProcessText + pop hl + + ld a, b + dec a + inc e + inc e + jr .loop_filtered_cards + +.exit_loop + ld a, [hli] + or a + jr z, .cannot_scroll + pop de +; draw down cursor because +; there are still more cards +; to be scrolled down + xor a ; FALSE + ld [wUnableToScrollDown], a + ld a, SYM_CURSOR_D + jr .draw_cursor +.cannot_scroll + pop de + ld a, TRUE + ld [wUnableToScrollDown], a + ld a, SYM_SPACE +.draw_cursor + ld b, 19 ; x coord + ld c, e + dec c + dec c + call WriteByteToBGMap0 + pop bc + ret + +Text_9a30: + db TX_SYMBOL, TX_END + +Text_9a32: + db TX_SYMBOL, TX_END + +Text_9a34: + db TX_SYMBOL, TX_END + +Text_9a36: + db TX_SYMBOL, TX_END + +Text_9a38: + db TX_SYMBOL, TX_END + +Text_9a3a: + db TX_SYMBOL, TX_END + +Text_9a3c: + db TX_SYMBOL, TX_END + +Text_9a3e: + db TX_SYMBOL, TX_END + +Text_9a40: + db TX_SYMBOL, TX_END + +Text_9a42: + db TX_SYMBOL, TX_END + +Text_9a44: + db TX_SYMBOL, TX_END + +Text_9a46: + db TX_SYMBOL, TX_END + +Text_9a48: + db TX_SYMBOL, TX_END + +Text_9a4a: + db TX_SYMBOL, TX_END + +Text_9a4c: + db TX_SYMBOL, TX_END + +Text_9a4e: + db TX_SYMBOL, TX_END + +Text_9a50: + db TX_SYMBOL, TX_END + +Text_9a52: + db TX_SYMBOL, TX_END + +Text_9a54: + db TX_SYMBOL, TX_END + +Text_9a56: + db TX_SYMBOL, TX_END + +Text_9a58: + done + +; writes the card ID in register e to wVisibleListCardIDs +; given its position in the list in register b +; input: +; b = list position (starts from bottom) +; e = card ID +AddCardIDToVisibleList: + push af + push bc + push hl + ld hl, wVisibleListCardIDs + ld c, b + ld a, [wNumVisibleCardListEntries] + sub c + ld c, a ; wNumVisibleCardListEntries - b + ld b, $0 + add hl, bc + ld [hl], e + pop hl + pop bc + pop af + ret + +; copies data from hl to: +; wCardListCursorXPos +; wCardListCursorYPos +; wCardListYSpacing +; wCardListXSpacing +; wCardListNumCursorPositions +; wVisibleCursorTile +; wInvisibleCursorTile +; wCardListHandlerFunction +InitCardSelectionParams: + ld [wCardListCursorPos], a + ld [hffb3], a + ld de, wCardListCursorXPos + ld b, $9 +.loop + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .loop + xor a + ld [wCheckMenuCursorBlinkCounter], a + ret + +HandleCardSelectionInput: + xor a ; FALSE + ld [wPlaysSfx], a + ldh a, [hDPadHeld] + or a + jr z, .handle_ab_btns + +; handle d-pad + ld b, a + ld a, [wCardListNumCursorPositions] + ld c, a + ld a, [wCardListCursorPos] + bit D_LEFT_F, b + jr z, .check_d_right + dec a + bit 7, a + jr z, .got_cursor_pos + ; if underflow, set to max cursor pos + ld a, [wCardListNumCursorPositions] + dec a + jr .got_cursor_pos +.check_d_right + bit D_RIGHT_F, b + jr z, .handle_ab_btns + inc a + cp c + jr c, .got_cursor_pos + ; if over max pos, set to pos 0 + xor a +.got_cursor_pos + push af + ld a, TRUE + ld [wPlaysSfx], a + call DrawHorizontalListCursor_Invisible + pop af + ld [wCardListCursorPos], a + xor a + ld [wCheckMenuCursorBlinkCounter], a + +.handle_ab_btns + ld a, [wCardListCursorPos] + ld [hffb3], a + ldh a, [hKeysPressed] + and A_BUTTON | B_BUTTON + jr z, HandleCardSelectionCursorBlink + and A_BUTTON + jr nz, ConfirmSelectionAndReturnCarry + ; b button + ld a, $ff + ld [hffb3], a + call PlaySFXConfirmOrCancel + scf + ret + +; outputs cursor position in e and selection in a +ConfirmSelectionAndReturnCarry: + call DrawHorizontalListCursor_Visible + ld a, $01 + call PlaySFXConfirmOrCancel + ld a, [wCardListCursorPos] + ld e, a + ld a, [hffb3] + scf + ret + +HandleCardSelectionCursorBlink: + ld a, [wPlaysSfx] + or a + jr z, .skip_sfx + call PlaySFX +.skip_sfx + ld hl, wCheckMenuCursorBlinkCounter + ld a, [hl] + inc [hl] + and $0f + ret nz + ld a, [wVisibleCursorTile] + bit 4, [hl] + jr z, DrawHorizontalListCursor + +DrawHorizontalListCursor_Invisible: + ld a, [wInvisibleCursorTile] +; fallthrough + +; like DrawListCursor but only +; for lists with one line, and each entry +; being laid horizontally +; a = tile to write +DrawHorizontalListCursor: + ld e, a + ld a, [wCardListXSpacing] + ld l, a + ld a, [wCardListCursorPos] + ld h, a + call HtimesL + ld a, l + ld hl, wCardListCursorXPos + add [hl] + ld b, a ; x coord + ld hl, wCardListCursorYPos + ld a, [hl] + ld c, a ; y coord + ld a, e + call WriteByteToBGMap0 + or a + ret + +DrawHorizontalListCursor_Visible: + ld a, [wVisibleCursorTile] + jr DrawHorizontalListCursor + +; handles user input when selecting cards to add +; to deck configuration +; returns carry if a selection was made +; (either selected card or cancelled) +; outputs in a the list index if selection was made +; or $ff if operation was cancelled +HandleDeckCardSelectionList: + xor a ; FALSE + ld [wPlaysSfx], a + + ldh a, [hDPadHeld] + or a + jp z, .asm_9bb9 + + ld b, a + ld a, [wCardListNumCursorPositions] + ld c, a + ld a, [wCardListCursorPos] + bit D_UP_F, b + jr z, .check_d_down + push af + ld a, TRUE + ld [wPlaysSfx], a + pop af + dec a + bit 7, a + jr z, .asm_9b8f + ld a, [wCardListVisibleOffset] + or a + jr z, .asm_9b5a + dec a + ld [wCardListVisibleOffset], a + ld hl, wCardListUpdateFunction + call CallIndirect + xor a + jr .asm_9b8f +.asm_9b5a + xor a + ld [wPlaysSfx], a + jr .asm_9b8f + +.check_d_down + bit D_DOWN_F, b + jr z, .asm_9b9d + push af + ld a, TRUE + ld [wPlaysSfx], a + pop af + inc a + cp c + jr c, .asm_9b8f + push af + ld a, [wUnableToScrollDown] + or a + jr nz, .cannot_scroll_down + ld a, [wCardListVisibleOffset] + inc a + ld [wCardListVisibleOffset], a + ld hl, wCardListUpdateFunction + call CallIndirect + pop af + dec a + jr .asm_9b8f + +.cannot_scroll_down + pop af + dec a + push af + xor a ; FALSE + ld [wPlaysSfx], a + pop af + +.asm_9b8f + push af + call DrawListCursor_Invisible + pop af + ld [wCardListCursorPos], a + xor a + ld [wCheckMenuCursorBlinkCounter], a + jr .asm_9bb9 +.asm_9b9d + ld a, [wced2] + or a + jr z, .asm_9bb9 + + bit D_LEFT_F, b + jr z, .check_d_right + call GetSelectedVisibleCardID + call RemoveCardFromDeckAndUpdateCount + jr .asm_9bb9 +.check_d_right + bit D_RIGHT_F, b + jr z, .asm_9bb9 + call GetSelectedVisibleCardID + call AddCardToDeckAndUpdateCount + +.asm_9bb9 + ld a, [wCardListCursorPos] + ld [hffb3], a + ld hl, wCardListHandlerFunction + ld a, [hli] + or [hl] + jr z, .handle_ab_btns + + ; this code seemingly never runs + ; because wCardListHandlerFunction is always NULL + ld a, [hld] + ld l, [hl] + ld h, a + ld a, [hffb3] + call CallHL + jr nc, .handle_blink + +.select_card + call DrawListCursor_Visible + ld a, $01 + call PlaySFXConfirmOrCancel + ld a, [wCardListCursorPos] + ld e, a + ld a, [hffb3] + scf + ret + +.handle_ab_btns + ldh a, [hKeysPressed] + and A_BUTTON | B_BUTTON + jr z, .check_sfx + and A_BUTTON + jr nz, .select_card + ld a, $ff + ld [hffb3], a + call PlaySFXConfirmOrCancel + scf + ret + +.check_sfx + ld a, [wPlaysSfx] + or a + jr z, .handle_blink + call PlaySFX +.handle_blink + ld hl, wCheckMenuCursorBlinkCounter + ld a, [hl] + inc [hl] + and $0f + ret nz + ld a, [wVisibleCursorTile] + bit 4, [hl] + jr z, DrawListCursor +; fallthrough + +DrawListCursor_Invisible: + ld a, [wInvisibleCursorTile] +; fallthrough + +; draws cursor considering wCardListCursorPos +; spaces each entry horizontally by wCardListXSpacing +; and vertically by wCardListYSpacing +; a = tile to write +DrawListCursor: + ld e, a + ld a, [wCardListXSpacing] + ld l, a + ld a, [wCardListCursorPos] + ld h, a + call HtimesL + ld a, l + ld hl, wCardListCursorXPos + add [hl] + ld b, a ; x coord + ld a, [wCardListYSpacing] + ld l, a + ld a, [wCardListCursorPos] + ld h, a + call HtimesL + ld a, l + ld hl, wCardListCursorYPos + add [hl] + ld c, a ; y coord + ld a, e + call WriteByteToBGMap0 + or a + ret + +DrawListCursor_Visible: + ld a, [wVisibleCursorTile] + jr DrawListCursor + +OpenCardPageFromCardList: +; get the card index that is selected +; and open its card page + ld hl, wCurCardListPtr + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wCardListCursorPos] + ld c, a + ld b, $0 + add hl, bc + ld a, [wCardListVisibleOffset] + ld c, a + ld b, $0 + add hl, bc + ld e, [hl] + ld d, $0 + push de + call LoadCardDataToBuffer1_FromCardID + lb de, $38, $9f + call SetupText + bank1call OpenCardPage_FromCheckHandOrDiscardPile + pop de + +.handle_input + ldh a, [hDPadHeld] + ld b, a + and A_BUTTON | B_BUTTON | SELECT | START + jp nz, .exit + +; check d-pad +; if UP or DOWN is pressed, change the +; card that is being shown, given the +; order in the current card list + xor a ; FALSE + ld [wPlaysSfx], a + ld a, [wCardListNumCursorPositions] + ld c, a + ld a, [wCardListCursorPos] + bit D_UP_F, b + jr z, .check_d_down + push af + ld a, TRUE + ld [wPlaysSfx], a + pop af + dec a + bit 7, a + jr z, .reopen_card_page + ld a, [wCardListVisibleOffset] + or a + jr z, .handle_regular_card_page_input + dec a + ld [wCardListVisibleOffset], a + xor a + jr .reopen_card_page + +.check_d_down + bit D_DOWN_F, b + jr z, .handle_regular_card_page_input + push af + ld a, TRUE + ld [wPlaysSfx], a + pop af + inc a + cp c + jr c, .reopen_card_page + push af + ld hl, wCurCardListPtr + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wCardListCursorPos] + ld c, a + ld b, $0 + add hl, bc + ld a, [wCardListVisibleOffset] + inc a + ld c, a + ld b, $0 + add hl, bc + ld a, [hl] + or a + jr z, .skip_change_card + ld a, [wCardListVisibleOffset] + inc a + ld [wCardListVisibleOffset], a + pop af + dec a +.reopen_card_page + ld [wCardListCursorPos], a + ld a, [wPlaysSfx] + or a + jp z, OpenCardPageFromCardList + call PlaySFX + jp OpenCardPageFromCardList + +.skip_change_card + pop af + jr .handle_regular_card_page_input ; unnecessary jr +.handle_regular_card_page_input + push de + bank1call OpenCardPage.input_loop + pop de + jp .handle_input + +.exit + ld a, $1 + ld [wVBlankOAMCopyToggle], a + ld a, [wCardListCursorPos] + ld [wTempCardListCursorPos], a + ret + +; opens card page from the card list +Func_9ced: ; unreferenced + ld hl, wVisibleListCardIDs + ld a, [wCardListCursorPos] + ld c, a + ld b, $00 + add hl, bc + ld e, [hl] + inc hl + ld d, [hl] + call LoadCardDataToBuffer1_FromCardID + ld de, $389f + call SetupText + bank1call OpenCardPage_FromHand + ld a, $01 + ld [wVBlankOAMCopyToggle], a + ret + +; adds card in register e to deck configuration +; and updates the values shown for its count +; in the card selection list +; input: +; e = card ID +AddCardToDeckAndUpdateCount: + call TryAddCardToDeck + ret c ; failed to add card + push de + call PrintCardTypeCounts + lb de, 15, 0 + call PrintTotalCardCount + pop de + call GetCountOfCardInCurDeck + call PrintNumberValueInCursorYPos + ret + +; tries to add card ID in register e to wCurDeckCards +; fails to add card if one of the following conditions are met: +; - total cards are equal to wMaxNumCardsAllowed +; - cards with the same name as it reached the allowed limit +; - player doesn't own more copies in the collection +; returns carry if fails +; otherwise, writes card ID to first empty slot in wCurDeckCards +; input: +; e = card ID +TryAddCardToDeck: + ld a, [wMaxNumCardsAllowed] + ld d, a + ld a, [wTotalCardCount] + cp d + jr nz, .not_equal + ; wMaxNumCardsAllowed == wTotalCardCount + scf + ret + +.not_equal + push de + call .CheckIfCanAddCardWithSameName + pop de + ret c ; cannot add more cards with this name + + push de + call GetCountOfCardInCurDeck + ld b, a + ld hl, wOwnedCardsCountList + ld d, $0 + ld a, [wCardListVisibleOffset] + ld e, a + add hl, de + ld a, [wCardListCursorPos] + ld e, a + add hl, de + ld d, [hl] + ld a, b + cp d + pop de + scf + ret z ; cannot add because player doesn't own more copies + + ld a, SFX_01 + call PlaySFX + push de + call .AddCardToCurDeck + ld a, [wCurCardTypeFilter] + ld c, a + ld b, $0 + ld hl, wCardFilterCounts + add hl, bc + inc [hl] + pop de + or a + ret + +; finds first empty slot in wCurDeckCards +; then writes the value in e to it +.AddCardToCurDeck + ld hl, wCurDeckCards +.loop + ld a, [hl] + or a + jr z, .empty + inc hl + jr .loop +.empty + ld [hl], e + inc hl + xor a + ld [hl], a + ret + +; returns carry if card ID in e cannot be +; added to the current deck configuration +; due to having reached the maximum number +; of cards allowed with that same name +; e = card id +.CheckIfCanAddCardWithSameName + call LoadCardDataToBuffer1_FromCardID + ld a, [wLoadedCard1Type] + cp TYPE_ENERGY_DOUBLE_COLORLESS + jr z, .double_colorless + ; basic energy cards have no limit + and TYPE_ENERGY + cp TYPE_ENERGY + jr z, .exit ; return if basic energy card +.double_colorless + +; compare this card's name to +; the names of cards in list wCurDeckCards + ld a, [wLoadedCard1Name + 0] + ld c, a + ld a, [wLoadedCard1Name + 1] + ld b, a + ld hl, wCurDeckCards + ld d, 0 + push de +.loop_cards + ld a, [hli] + or a + jr z, .exit_pop_de + ld e, a + ld d, $0 + call GetCardName + ld a, e + cp c + jr nz, .loop_cards + ld a, d + cp b + jr nz, .loop_cards + ; has same name + pop de + inc d ; increment counter of cards with this name + ld a, [wSameNameCardsLimit] + cp d + push de + jr nz, .loop_cards + ; reached the maximum number + ; of cards with same name allowed + pop de + scf + ret + +.exit_pop_de + pop de +.exit + or a + ret + +; gets the element in wVisibleListCardIDs +; corresponding to index wCardListCursorPos +GetSelectedVisibleCardID: + ld hl, wVisibleListCardIDs + ld a, [wCardListCursorPos] + ld e, a + ld d, $00 + add hl, de + ld e, [hl] + ret + +; appends the digits of value in register a to wDefaultText +; then prints it in cursor Y position +; a = value to convert to numerical digits +PrintNumberValueInCursorYPos: + ld hl, wDefaultText + call ConvertToNumericalDigits + ld [hl], TX_END + ld a, [wCardListYSpacing] + ld l, a + ld a, [wCardListCursorPos] + ld h, a + call HtimesL + ld a, l + ld hl, wCardListCursorYPos + add [hl] + ld e, a + ld d, 14 + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + ret + +; removes card in register e from deck configuration +; and updates the values shown for its count +; in the card selection list +; input: +; e = card ID +RemoveCardFromDeckAndUpdateCount: + call RemoveCardFromDeck + ret nc + push de + call PrintCardTypeCounts + lb de, 15, 0 + call PrintTotalCardCount + pop de + call GetCountOfCardInCurDeck + call PrintNumberValueInCursorYPos + ret + +; removes card ID in e from wCurDeckCards +RemoveCardFromDeck: + push de + call GetCountOfCardInCurDeck + pop de + or a + ret z ; card is not in deck + ld a, SFX_01 + call PlaySFX + push de + call .RemoveCard + ld a, [wCurCardTypeFilter] + ld c, a + ld b, $0 + ld hl, wCardFilterCounts + add hl, bc + dec [hl] + pop de + scf + ret + +; remove first card instance of card ID in e +; and shift all elements up by one +.RemoveCard + ld hl, wCurDeckCards + ld d, 0 ; unnecessary +.loop_1 + inc d ; unnecessary + ld a, [hli] + cp e + jr nz, .loop_1 + ld c, l + ld b, h + dec bc + +.loop_2 + inc d ; unnecessary + ld a, [hli] + or a + jr z, .done + ld [bc], a + inc bc + jr .loop_2 + +.done + xor a + ld [bc], a + ret + +UpdateConfirmationCardScreen: + ld hl, hffb0 + ld [hl], $01 + call PrintCurDeckNumberAndName + ld hl, hffb0 + ld [hl], $00 + jp PrintConfirmationCardList + +HandleDeckConfirmationMenu: +; if deck is empty, just show deck info header with empty card list + ld a, [wTotalCardCount] + or a + jp z, ShowDeckInfoHeaderAndWaitForBButton + +; create list of all unique cards + call SortCurDeckCardsByID + call CreateCurDeckUniqueCardList + + xor a + ld [wCardListVisibleOffset], a +.init_params + ld hl, .CardSelectionParams + call InitCardSelectionParams + ld a, [wNumUniqueCards] + ld [wNumCardListEntries], a + cp NUM_DECK_CONFIRMATION_VISIBLE_CARDS + jr c, .no_cap + ld a, NUM_DECK_CONFIRMATION_VISIBLE_CARDS +.no_cap + ld [wCardListNumCursorPositions], a + ld [wNumVisibleCardListEntries], a + call ShowConfirmationCardScreen + + ld hl, UpdateConfirmationCardScreen + ld d, h + ld a, l + ld hl, wCardListUpdateFunction + ld [hli], a + ld [hl], d + + xor a + ld [wced2], a +.loop_input + call DoFrame + call HandleDeckCardSelectionList + jr c, .selection_made + call HandleLeftRightInCardList + jr c, .loop_input + ldh a, [hDPadHeld] + and START + jr z, .loop_input + +.selected_card + ld a, $01 + call PlaySFXConfirmOrCancel + ld a, [wCardListCursorPos] + ld [wced7], a + + ; set wOwnedCardsCountList as current card list + ; and show card page screen + ld de, wOwnedCardsCountList + ld hl, wCurCardListPtr + ld [hl], e + inc hl + ld [hl], d + call OpenCardPageFromCardList + jr .init_params + +.selection_made + ld a, [hffb3] + cp $ff + ret z ; operation cancelled + jr .selected_card + +.CardSelectionParams + db 0 ; x pos + db 5 ; y pos + db 2 ; y spacing + db 0 ; x spacing + db 7 ; num entries + db SYM_CURSOR_R ; visible cursor tile + db SYM_SPACE ; invisible cursor tile + dw NULL ; wCardListHandlerFunction + +; handles pressing left/right in card lists +; scrolls up/down a number of wCardListNumCursorPositions +; entries respectively +; returns carry if scrolling happened +HandleLeftRightInCardList: + ld a, [wCardListNumCursorPositions] + ld d, a + ld a, [wCardListVisibleOffset] + ld c, a + ldh a, [hDPadHeld] + cp D_RIGHT + jr z, .right + cp D_LEFT + jr z, .left + or a + ret + +.right + ld a, [wCardListVisibleOffset] + add d + ld b, a + add d + ld hl, wNumCardListEntries + cp [hl] + jr c, .got_new_pos + ld a, [wNumCardListEntries] + sub d + ld b, a + jr .got_new_pos + +.left + ld a, [wCardListVisibleOffset] + sub d + ld b, a + jr nc, .got_new_pos + ld b, 0 ; first index +.got_new_pos + ld a, b + ld [wCardListVisibleOffset], a + cp c + jr z, .asm_9efa + ld a, SFX_01 + call PlaySFX + ld hl, wCardListUpdateFunction + call CallIndirect +.asm_9efa + scf + ret + +; handles scrolling up and down with Select button +; in this case, the cursor position goes up/down +; by wCardListNumCursorPositions entries respectively +; return carry if scrolling happened, otherwise no carry +HandleSelectUpAndDownInList: + ld a, [wCardListNumCursorPositions] + ld d, a + ld a, [wCardListVisibleOffset] + ld c, a + ldh a, [hDPadHeld] + cp SELECT | D_DOWN + jr z, .sel_down + cp SELECT | D_UP + jr z, .sel_up + or a + ret + +.sel_down + ld a, [wCardListVisibleOffset] + add d + ld b, a ; wCardListVisibleOffset + wCardListNumCursorPositions + add d + ld hl, wNumCardListEntries + cp [hl] + jr c, .got_new_pos + ld a, [wNumCardListEntries] + sub d + ld b, a ; wNumCardListEntries - wCardListNumCursorPositions + jr .got_new_pos +.sel_up + ld a, [wCardListVisibleOffset] + sub d + ld b, a ; wCardListVisibleOffset - wCardListNumCursorPositions + jr nc, .got_new_pos + ld b, 0 ; go to first position + +.got_new_pos + ld a, b + ld [wCardListVisibleOffset], a + cp c + jr z, .set_carry + ld a, SFX_01 + call PlaySFX + ld hl, wCardListUpdateFunction + call CallIndirect +.set_carry + scf + ret + +; simply draws the deck info header +; then awaits a b button press to exit +ShowDeckInfoHeaderAndWaitForBButton: + call ShowDeckInfoHeader +.wait_input + call DoFrame + ldh a, [hKeysPressed] + and B_BUTTON + jr z, .wait_input + ld a, $ff + call PlaySFXConfirmOrCancel + ret + +ShowConfirmationCardScreen: + call ShowDeckInfoHeader + lb de, 3, 5 + ld hl, wCardListCoords + ld [hl], e + inc hl + ld [hl], d + call PrintConfirmationCardList + ret + +; counts all values stored in wCardFilterCounts +; if the total count is 0, then +; prints "No cards chosen." +TallyCardsInCardFilterLists: + lb bc, 0, 0 + ld hl, wCardFilterCounts +.loop + ld a, [hli] + add b + ld b, a + inc c + ld a, NUM_FILTERS + cp c + jr nz, .loop + ld a, b + or a + ret nz + lb de, 11, 1 + call InitTextPrinting + ldtx hl, NoCardsChosenText + call ProcessTextFromID + ret + +; draws a box on the top of the screen +; with wCurDeck's number, name and card count +; and draws the Hand Cards icon if it's +; the current dueling deck +ShowDeckInfoHeader: + call EmptyScreenAndLoadFontDuelAndHandCardsIcons + lb de, 0, 0 + lb bc, 20, 4 + call DrawRegularTextBox + ld a, [wCurDeckName] + or a + jp z, .print_card_count ; can be jr + +; draw hand cards icon if it's the current dueling deck + call PrintCurDeckNumberAndName + ld a, [wCurDeck] + ld b, a + call EnableSRAM + ld a, [sCurrentlySelectedDeck] + call DisableSRAM + cp b + jr nz, .print_card_count + lb de, 2, 1 + call DrawHandCardsTileAtDE + +.print_card_count + lb de, 14, 1 + call PrintTotalCardCount + lb de, 16, 1 + call PrintSlashSixty + call TallyCardsInCardFilterLists + call EnableLCD + ret + +; prints the name of wCurDeck in the form +; "X· <deck name> deck", where X is the number +; of the deck in the given menu +; if no current deck, print blank line +PrintCurDeckNumberAndName: + ld a, [wCurDeck] + cp $ff + jr z, .skip_deck_numeral + +; print the deck number in the menu +; in the form "X·" + lb de, 3, 2 + call InitTextPrinting + ld a, [wCurDeck] + bit 7, a + jr z, .incr_by_one + and $7f + jr .got_deck_numeral +.incr_by_one + inc a +.got_deck_numeral + ld hl, wDefaultText + call ConvertToNumericalDigits + ld [hl], "FW0_·" + inc hl + ld [hl], TX_END + ld hl, wDefaultText + call ProcessText + +.skip_deck_numeral + ld hl, wCurDeckName + ld de, wDefaultText + call CopyListFromHLToDE + ld a, [wCurDeck] + cp $ff + jr z, .blank_deck_name + +; print "<deck name> deck" + ld hl, wDefaultText + call GetTextLengthInTiles + ld b, $0 + ld hl, wDefaultText + add hl, bc + ld d, h + ld e, l + ld hl, DeckNameSuffix + call CopyListFromHLToDE + lb de, 6, 2 + ld hl, wDefaultText + call InitTextPrinting + call ProcessText + ret + +.blank_deck_name + lb de, 2, 2 + ld hl, wDefaultText + call InitTextPrinting + call ProcessText + ret + +; sorts wCurDeckCards by ID +SortCurDeckCardsByID: +; wOpponentDeck is used to temporarily store deck's cards +; so that it can be later sorted by ID + ld hl, wCurDeckCards + ld de, wOpponentDeck + ld bc, wDuelTempList + ld a, -1 + ld [bc], a +.loop_copy + inc a ; incr deck index + push af + ld a, [hli] + ld [de], a + inc de + or a + jr z, .sort_cards + pop af + ld [bc], a ; store deck index + inc bc + jr .loop_copy + +.sort_cards + pop af + ld a, $ff ; terminator byte for wDuelTempList + ld [bc], a + +; force Opp Turn so that SortCardsInDuelTempListByID can be used + ldh a, [hWhoseTurn] + push af + ld a, OPPONENT_TURN + ldh [hWhoseTurn], a + call SortCardsInDuelTempListByID + pop af + ldh [hWhoseTurn], a + +; given the ordered cards in wOpponentDeck, +; each entry in it corresponds to its deck index +; (first ordered card is deck index 0, second is deck index 1, etc) +; place these in this order in wCurDeckCards + ld hl, wCurDeckCards + ld de, wDuelTempList +.loop_order_by_deck_index + ld a, [de] + cp $ff + jr z, .done + ld c, a + ld b, $0 + push hl + ld hl, wOpponentDeck + add hl, bc + ld a, [hl] + pop hl + ld [hli], a + inc de + jr .loop_order_by_deck_index + +.done + xor a + ld [hl], a + ret + +; goes through list in wCurDeckCards, and for each card in it +; creates list in wUniqueDeckCardList of all unique cards +; it finds (assuming wCurDeckCards is sorted by ID) +; also counts the total number of the different cards +CreateCurDeckUniqueCardList: + ld b, 0 + ld c, $0 + ld hl, wCurDeckCards + ld de, wUniqueDeckCardList +.loop + ld a, [hli] + cp c + jr z, .loop + ld c, a + ld [de], a + inc de + or a + jr z, .done + inc b + jr .loop +.done + ld a, b + ld [wNumUniqueCards], a + ret + +; prints the list of cards visible in the window +; of the confirmation screen +; card info is presented with name, level and +; its count preceded by "x" +PrintConfirmationCardList: + push bc + ld hl, wCardListCoords + ld e, [hl] + inc hl + ld d, [hl] + ld b, 19 ; x coord + ld c, e + dec c + ld a, [wCardListVisibleOffset] + or a + jr z, .no_cursor + ld a, SYM_CURSOR_U + jr .got_cursor_tile_1 +.no_cursor + ld a, SYM_SPACE +.got_cursor_tile_1 + call WriteByteToBGMap0 + +; iterates by decreasing value in wNumVisibleCardListEntries +; by 1 until it reaches 0 + ld a, [wCardListVisibleOffset] + ld c, a + ld b, $0 + ld hl, wOwnedCardsCountList + add hl, bc + ld a, [wNumVisibleCardListEntries] +.loop_cards + push de + or a + jr z, .exit_loop + ld b, a + ld a, [hli] + or a + jr z, .no_more_cards + ld e, a + call AddCardIDToVisibleList + call LoadCardDataToBuffer1_FromCardID + ; places in wDefaultText the card's name and level + ; then appends at the end "x" with the count of that card + ; draws the card's type icon as well + ld a, 13 + push bc + push hl + push de + call CopyCardNameAndLevel + pop de + call .PrintCardCount + pop hl + pop bc + pop de + call .DrawCardTypeIcon + push hl + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + pop hl + ld a, b + dec a + inc e + inc e + jr .loop_cards + +.exit_loop + ld a, [hli] + or a + jr z, .no_more_cards + pop de + xor a ; FALSE + ld [wUnableToScrollDown], a + ld a, SYM_CURSOR_D + jr .got_cursor_tile_2 + +.no_more_cards + pop de + ld a, TRUE + ld [wUnableToScrollDown], a + ld a, SYM_SPACE +.got_cursor_tile_2 + ld b, 19 ; x coord + ld c, e + dec c + dec c + call WriteByteToBGMap0 + pop bc + ret + +; prints the card count preceded by a cross +; for example "x42" +.PrintCardCount + push af + push bc + push de + push hl +.loop_search + ld a, [hl] + or a + jr z, .found_card_id + inc hl + jr .loop_search +.found_card_id + call GetCountOfCardInCurDeck + ld [hl], TX_SYMBOL + inc hl + ld [hl], SYM_CROSS + inc hl + call ConvertToNumericalDigits + ld [hl], TX_END + pop hl + pop de + pop bc + pop af + ret + +; draws the icon corresponding to the loaded card's type +; can be any of Pokemon stages (basic, 1st and 2nd stage) +; Energy or Trainer +; draws it 2 tiles to the left and 1 up to +; the current coordinate in de +.DrawCardTypeIcon + push hl + push de + push bc + ld a, [wLoadedCard1Type] + cp TYPE_ENERGY + jr nc, .not_pkmn_card + +; pokemon card + ld a, [wLoadedCard1Stage] + ld b, a + add b + add b + add b ; *4 + add ICON_TILE_BASIC_POKEMON + jr .got_tile + +.not_pkmn_card + cp TYPE_TRAINER + jr nc, .trainer_card + +; energy card + sub TYPE_ENERGY + ld b, a + add b + add b + add b ; *4 + add ICON_TILE_FIRE + jr .got_tile + +.trainer_card + ld a, ICON_TILE_TRAINER +.got_tile + dec d + dec d + dec e + push af + lb hl, 1, 2 + lb bc, 2, 2 + call FillRectangle + pop af + + call GetCardTypeIconPalette + ld b, a + ld a, [wConsole] + cp CONSOLE_CGB + jr nz, .skip_pal + ld a, b + lb bc, 2, 2 + lb hl, 0, 0 + call BankswitchVRAM1 + call FillRectangle + call BankswitchVRAM0 +.skip_pal + pop bc + pop de + pop hl + ret + +; returns in a the BG Pal corresponding to the +; card type icon in input register a +; if not found, returns $00 +GetCardTypeIconPalette: + push bc + push hl + ld b, a + ld hl, .CardTypeIconPalettes +.loop + ld a, [hli] + or a + jr z, .done + cp b + jr z, .done + inc hl + jp .loop ; can be jr +.done + ld a, [hl] + pop hl + pop bc + ret + +.CardTypeIconPalettes +; icon tile, BG pal + db ICON_TILE_FIRE, 1 + db ICON_TILE_GRASS, 2 + db ICON_TILE_LIGHTNING, 1 + db ICON_TILE_WATER, 2 + db ICON_TILE_FIGHTING, 3 + db ICON_TILE_PSYCHIC, 3 + db ICON_TILE_COLORLESS, 0 + db ICON_TILE_ENERGY, 2 + db ICON_TILE_BASIC_POKEMON, 2 + db ICON_TILE_STAGE_1_POKEMON, 2 + db ICON_TILE_STAGE_2_POKEMON, 1 + db ICON_TILE_TRAINER, 2 + db $00, $ff + +; inits WRAM vars to start creating deck configuration to send +PrepareToBuildDeckConfigurationToSend: + ld hl, wCurDeckCards + ld a, wCurDeckCardsEnd - wCurDeckCards + call ClearNBytesFromHL + ld a, $ff + ld [wCurDeck], a + ld hl, .text + ld de, wCurDeckName + call CopyListFromHLToDE + ld hl, .DeckConfigurationParams + call InitDeckBuildingParams + call HandleDeckBuildScreen + ret + +.text + text "Cards chosen to send" + done + +.DeckConfigurationParams + db DECK_SIZE ; max number of cards + db 60 ; max number of same name cards + db FALSE ; whether to include deck cards + dw HandleSendDeckConfigurationMenu + dw SendDeckConfigurationMenu_TransitionTable + +SendDeckConfigurationMenu_TransitionTable: + cursor_transition $10, $20, $00, $00, $00, $01, $02 + cursor_transition $48, $20, $00, $01, $01, $02, $00 + cursor_transition $80, $20, $00, $02, $02, $00, $01 + +SendDeckConfigurationMenuData: + textitem 2, 2, ConfirmText + textitem 9, 2, SendText + textitem 16, 2, CancelText + db $ff + +HandleSendDeckConfigurationMenu: + ld de, $0 + lb bc, 20, 6 + call DrawRegularTextBox + ld hl, SendDeckConfigurationMenuData + call PlaceTextItems + ld a, $ff + ld [wDuelInitialPrizesUpperBitsSet], a +.loop_input + ld a, $01 + ld [wVBlankOAMCopyToggle], a + call DoFrame + call YourOrOppPlayAreaScreen_HandleInput + jr nc, .loop_input + ld [wced6], a + cp $ff + jr nz, .asm_a23b + call DrawCardTypeIconsAndPrintCardCounts + ld a, [wTempCardListCursorPos] + ld [wCardListCursorPos], a + ld a, [wCurCardTypeFilter] + call PrintFilteredCardList + jp HandleDeckBuildScreen.skip_draw +.asm_a23b + ld hl, .func_table + call JumpToFunctionInTable + jp OpenDeckConfigurationMenu.skip_init + +.func_table + dw ConfirmDeckConfiguration ; Confirm + dw .SendDeckConfiguration ; Send + dw .CancelSendDeckConfiguration ; Cancel + +.SendDeckConfiguration + ld a, [wCurDeckCards] + or a + jr z, .CancelSendDeckConfiguration + xor a + ld [wCardListVisibleOffset], a + ld hl, Data_b04a + call InitCardSelectionParams + ld hl, wCurDeckCards + ld de, wDuelTempList + call CopyListFromHLToDE + call PrintCardToSendText + call Func_b088 + call EnableLCD + ldtx hl, SendTheseCardsText + call YesOrNoMenuWithText + jr nc, .asm_a279 + add sp, $2 + jp HandleDeckBuildScreen.skip_count +.asm_a279 + add sp, $2 + scf + ret + +.CancelSendDeckConfiguration + add sp, $2 + or a + ret + +; copies b bytes from hl to de +CopyNBytesFromHLToDE: + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, CopyNBytesFromHLToDE + ret + +; handles the screen showing all the player's cards +HandlePlayersCardsScreen: + call WriteCardListsTerminatorBytes + call PrintPlayersCardsHeaderInfo + xor a + ld [wCardListVisibleOffset], a + ld [wCurCardTypeFilter], a + call PrintFilteredCardSelectionList + call EnableLCD + xor a + ld hl, FiltersCardSelectionParams + call InitCardSelectionParams +.wait_input + call DoFrame + ld a, [wCurCardTypeFilter] + ld b, a + ld a, [wTempCardTypeFilter] + cp b + jr z, .check_d_down + ld [wCurCardTypeFilter], a + ld hl, wCardListVisibleOffset + ld [hl], $00 + call PrintFilteredCardSelectionList + + ld hl, hffb0 + ld [hl], $01 + call PrintPlayersCardsText + ld hl, hffb0 + ld [hl], $00 + + ld a, NUM_FILTERS + ld [wCardListNumCursorPositions], a +.check_d_down + ldh a, [hDPadHeld] + and D_DOWN + jr z, .no_d_down + call ConfirmSelectionAndReturnCarry + jr .jump_to_list + +.no_d_down + call HandleCardSelectionInput + jr nc, .wait_input + ld a, [hffb3] + cp $ff ; operation cancelled + jr nz, .jump_to_list + ret + +.jump_to_list + ld a, [wNumEntriesInCurFilter] + or a + jr z, .wait_input + + xor a + ld hl, Data_a396 + call InitCardSelectionParams + ld a, [wNumEntriesInCurFilter] + ld [wNumCardListEntries], a + ld hl, wNumVisibleCardListEntries + cp [hl] + jr nc, .asm_a300 + ld [wCardListNumCursorPositions], a +.asm_a300 + ld hl, PrintCardSelectionList + ld d, h + ld a, l + ld hl, wCardListUpdateFunction + ld [hli], a + ld [hl], d + xor a + ld [wced2], a + +.loop_input + call DoFrame + call HandleSelectUpAndDownInList + jr c, .loop_input + call HandleDeckCardSelectionList + jr c, .asm_a36a + ldh a, [hDPadHeld] + and START + jr z, .loop_input + ; start btn pressed + +.open_card_page + ld a, $01 + call PlaySFXConfirmOrCancel + ld a, [wCardListNumCursorPositions] + ld [wTempCardListNumCursorPositions], a + ld a, [wCardListCursorPos] + ld [wTempCardListCursorPos], a + + ; set wFilteredCardList as current card list + ; and show card page screen + ld de, wFilteredCardList + ld hl, wCurCardListPtr + ld [hl], e + inc hl + ld [hl], d + call OpenCardPageFromCardList + call PrintPlayersCardsHeaderInfo + + ld hl, FiltersCardSelectionParams + call InitCardSelectionParams + ld a, [wCurCardTypeFilter] + ld [wTempCardTypeFilter], a + call DrawHorizontalListCursor_Visible + call PrintCardSelectionList + call EnableLCD + ld hl, Data_a396 + call InitCardSelectionParams + ld a, [wTempCardListNumCursorPositions] + ld [wCardListNumCursorPositions], a + ld a, [wTempCardListCursorPos] + ld [wCardListCursorPos], a + jr .loop_input + +.asm_a36a + call DrawListCursor_Invisible + ld a, [wCardListCursorPos] + ld [wTempCardListCursorPos], a + ld a, [hffb3] + cp $ff + jr nz, .open_card_page + ld hl, FiltersCardSelectionParams + call InitCardSelectionParams + ld a, [wCurCardTypeFilter] + ld [wTempCardTypeFilter], a + ld hl, hffb0 + ld [hl], $01 + call PrintPlayersCardsText + ld hl, hffb0 + ld [hl], $00 + jp .wait_input + +Data_a396: + db 1 ; x pos + db 5 ; y pos + db 2 ; y spacing + db 0 ; x spacing + db 7 ; num entries + db SYM_CURSOR_R ; visible cursor tile + db SYM_SPACE ; invisible cursor tile + dw NULL ; wCardListHandlerFunction + +; a = which card type filter +PrintFilteredCardSelectionList: + push af + ld hl, CardTypeFilters + ld b, $00 + ld c, a + add hl, bc + ld a, [hl] + push af + ld a, ALL_DECKS + call CreateCardCollectionListWithDeckCards + pop af + call CreateFilteredCardList + + ld a, NUM_DECK_CONFIRMATION_VISIBLE_CARDS + ld [wNumVisibleCardListEntries], a + lb de, 2, 5 + ld hl, wCardListCoords + ld [hl], e + inc hl + ld [hl], d + ld a, SYM_SPACE + ld [wCursorAlternateTile], a + call PrintCardSelectionList + pop af + ret + +; outputs in wTempCardCollection all the cards in sCardCollection +; plus the cards that are being used in built decks +; a = DECK_* flags for which decks to include in the collection +CreateCardCollectionListWithDeckCards: + ld [hffb5], a +; copies sCardCollection to wTempCardCollection + ld hl, sCardCollection + ld de, wTempCardCollection + ld b, CARD_COLLECTION_SIZE - 1 + call EnableSRAM + call CopyNBytesFromHLToDE + call DisableSRAM + +; deck_1 + ld a, [hffb5] ; should be ldh + bit DECK_1_F, a + jr z, .deck_2 + ld de, sDeck1Cards + call IncrementDeckCardsInTempCollection +.deck_2 + ld a, [hffb5] ; should be ldh + bit DECK_2_F, a + jr z, .deck_3 + ld de, sDeck2Cards + call IncrementDeckCardsInTempCollection +.deck_3 + ld a, [hffb5] ; should be ldh + bit DECK_3_F, a + jr z, .deck_4 + ld de, sDeck3Cards + call IncrementDeckCardsInTempCollection +.deck_4 + ld a, [hffb5] ; should be ldh + bit DECK_4_F, a + ret z + ld de, sDeck4Cards + call IncrementDeckCardsInTempCollection + ret + +; goes through cards in deck in de +; and for each card ID, increments its corresponding +; entry in wTempCardCollection +IncrementDeckCardsInTempCollection: + call EnableSRAM + ld bc, wTempCardCollection + ld h, DECK_SIZE +.loop + ld a, [de] + inc de + or a + jr z, .done + push hl + ld h, $0 + ld l, a + add hl, bc + inc [hl] + pop hl + dec h + jr nz, .loop +.done + call DisableSRAM + ret + +; prints the name, level and storage count of the cards +; that are visible in the list window +; in the form: +; CARD NAME/LEVEL X +; where X is the current count of that card +PrintCardSelectionList: + push bc + ld hl, wCardListCoords + ld e, [hl] + inc hl + ld d, [hl] + ld b, 19 ; x coord + ld c, e + ld a, [wCardListVisibleOffset] + or a + jr z, .alternate_cursor_tile + ld a, SYM_CURSOR_U + jr .got_cursor_tile_1 +.alternate_cursor_tile + ld a, [wCursorAlternateTile] +.got_cursor_tile_1 + call WriteByteToBGMap0 + +; iterates by decreasing value in wNumVisibleCardListEntries +; by 1 until it reaches 0 + ld a, [wCardListVisibleOffset] + ld c, a + ld b, $0 + ld hl, wFilteredCardList + add hl, bc + ld a, [wNumVisibleCardListEntries] +.loop_filtered_cards + push de + or a + jr z, .exit_loop + ld b, a + ld a, [hli] + or a + jr z, .invalid_card ; card ID of 0 + ld e, a + call AddCardIDToVisibleList + call LoadCardDataToBuffer1_FromCardID + ; places in wDefaultText the card's name and level + ; then appends at the end the count of that card + ; in the card storage + ld a, 14 + push bc + push hl + push de + call CopyCardNameAndLevel + pop de + call AppendOwnedCardCountNumber + pop hl + pop bc + pop de + push hl + call InitTextPrinting + ld hl, wDefaultText + jr .process_text +.invalid_card + pop de + push hl + call InitTextPrinting + ld hl, Text_9a36 +.process_text + call ProcessText + pop hl + + ld a, b + dec a + inc e + inc e + jr .loop_filtered_cards + +.exit_loop + ld a, [hli] + or a + jr z, .cannot_scroll + pop de +; draw down cursor because +; there are still more cards +; to be scrolled down + xor a ; FALSE + ld [wUnableToScrollDown], a + ld a, SYM_CURSOR_D + jr .got_cursor_tile_2 +.cannot_scroll + pop de + ld a, TRUE + ld [wUnableToScrollDown], a + ld a, [wCursorAlternateTile] +.got_cursor_tile_2 + ld b, 19 ; x coord + ld c, e + dec c + dec c + call WriteByteToBGMap0 + pop bc + ret + +; appends the card count given in register e +; to the list in hl, in numerical form +; (i.e. its numeric symbol representation) +AppendOwnedCardCountNumber: + push af + push bc + push de + push hl +; increment hl until end is reached ($00 byte) +.loop + ld a, [hl] + or a + jr z, .end + inc hl + jr .loop +.end + call GetOwnedCardCount + call ConvertToNumericalDigits + ld [hl], $00 ; insert byte terminator + pop hl + pop de + pop bc + pop af + ret + +; print header info (card count and player name) +PrintPlayersCardsHeaderInfo: + call Set_OBJ_8x8 + call Func_8d78 +.skip_empty_screen + lb bc, 0, 4 + ld a, SYM_BOX_TOP + call FillBGMapLineWithA + call PrintTotalNumberOfCardsInCollection + call PrintPlayersCardsText + call DrawCardTypeIcons + ret + +; prints "<PLAYER>'s cards" +PrintPlayersCardsText: + lb de, 1, 0 + call InitTextPrinting + ld de, wDefaultText + call CopyPlayerName + ld hl, wDefaultText + call ProcessText + ld hl, wDefaultText + call GetTextLengthInTiles + inc b + ld d, b + ld e, 0 + call InitTextPrinting + ldtx hl, SCardsText + call ProcessTextFromID + ret + +PrintTotalNumberOfCardsInCollection: + ld a, ALL_DECKS + call CreateCardCollectionListWithDeckCards + +; count all the cards in collection + ld de, wTempCardCollection + 1 + ld b, 0 + ld hl, 0 +.loop_all_cards + ld a, [de] + inc de + and $7f + push bc + ld b, $00 + ld c, a + add hl, bc + pop bc + inc b + ld a, NUM_CARDS + cp b + jr nz, .loop_all_cards + +; hl = total number of cards in collection + call .GetTotalCountDigits + ld hl, wTempCardCollection + ld de, wOnesAndTensPlace + ld b, $00 + call .PlaceNumericalChar + call .PlaceNumericalChar + call .PlaceNumericalChar + call .PlaceNumericalChar + call .PlaceNumericalChar + ld a, $07 + ld [hli], a + ld [hl], TX_END + lb de, 13, 0 + call InitTextPrinting + ld hl, wTempCardCollection + call ProcessText + ret + +; places a numerical character in hl from de +; doesn't place a 0 if no non-0 +; numerical character has been placed before +; this makes it so that there are no +; 0s in more significant digits +.PlaceNumericalChar + ld [hl], TX_SYMBOL + inc hl + ld a, b + or a + jr z, .leading_num + ld a, [de] + inc de + ld [hli], a + ret +.leading_num +; don't place a 0 as a leading number + ld a, [de] + inc de + cp SYM_0 + jr z, .space_char + ld [hli], a + ld b, $01 ; at least one non-0 char was placed + ret +.space_char + xor a ; SYM_SPACE + ld [hli], a + ret + +; gets the digits in decimal form +; of value stored in hl +; stores the result in wOnesAndTensPlace +.GetTotalCountDigits + ld de, wOnesAndTensPlace + ld bc, -10000 + call .GetDigit + ld bc, -1000 + call .GetDigit + ld bc, -100 + call .GetDigit + ld bc, -10 + call .GetDigit + ld bc, -1 + call .GetDigit + ret + +.GetDigit + ld a, SYM_0 - 1 +.loop + inc a + add hl, bc + jr c, .loop + ld [de], a + inc de + ld a, l + sub c + ld l, a + ld a, h + sbc b + ld h, a + ret diff --git a/src/engine/menus/deck_machine.asm b/src/engine/menus/deck_machine.asm new file mode 100644 index 0000000..e5ce983 --- /dev/null +++ b/src/engine/menus/deck_machine.asm @@ -0,0 +1,2296 @@ +; handles printing and player input +; in the card confirmation list shown +; when cards are missing for some deck configuration +; hl = deck name +; de = deck cards +HandleDeckMissingCardsList: +; read deck name from hl and cards from de + push de + ld de, wCurDeckName + call CopyListFromHLToDEInSRAM + pop de + ld hl, wCurDeckCards + call CopyDeckFromSRAM + + ld a, NUM_FILTERS + ld hl, wCardFilterCounts + call ClearNBytesFromHL + ld a, DECK_SIZE + ld [wTotalCardCount], a + ld hl, wCardFilterCounts + ld [hl], a + call .HandleList ; can skip call and fallthrough instead + ret + +.HandleList + call SortCurDeckCardsByID + call CreateCurDeckUniqueCardList + xor a + ld [wCardListVisibleOffset], a +.loop + ld hl, .DeckConfirmationCardSelectionParams + call InitCardSelectionParams + ld a, [wNumUniqueCards] + ld [wNumCardListEntries], a + cp $05 + jr c, .got_num_positions + ld a, $05 +.got_num_positions + ld [wCardListNumCursorPositions], a + ld [wNumVisibleCardListEntries], a + call .PrintTitleAndList + ld hl, wCardConfirmationText + ld a, [hli] + ld h, [hl] + ld l, a + call DrawWideTextBox_PrintText + +; set card update function + ld hl, .CardListUpdateFunction + ld d, h + ld a, l + ld hl, wCardListUpdateFunction + ld [hli], a + ld [hl], d + xor a + ld [wced2], a + +.loop_input + call DoFrame + call HandleDeckCardSelectionList + jr c, .selection_made + call HandleLeftRightInCardList + jr c, .loop_input + ldh a, [hDPadHeld] + and START + jr z, .loop_input + +.open_card_pge + ld a, $01 + call PlaySFXConfirmOrCancel + ld a, [wCardListCursorPos] + ld [wced7], a + + ; set wOwnedCardsCountList as current card list + ; and show card page screen + ld de, wOwnedCardsCountList + ld hl, wCurCardListPtr + ld [hl], e + inc hl + ld [hl], d + call OpenCardPageFromCardList + jr .loop + +.selection_made + ld a, [hffb3] + cp $ff + ret z + jr .open_card_pge + +.DeckConfirmationCardSelectionParams + db 0 ; x pos + db 3 ; y pos + db 2 ; y spacing + db 0 ; x spacing + db 5 ; num entries + db SYM_CURSOR_R ; visible cursor tile + db SYM_SPACE ; invisible cursor tile + dw NULL ; wCardListHandlerFunction + +.CardListUpdateFunction + ld hl, hffb0 + ld [hl], $01 + call .PrintDeckIndexAndName + lb de, 1, 14 + call InitTextPrinting + ld hl, wCardConfirmationText + ld a, [hli] + ld h, [hl] + ld l, a + call ProcessTextFromID + ld hl, hffb0 + ld [hl], $00 + jp PrintConfirmationCardList + +.PrintTitleAndList + call .ClearScreenAndPrintDeckTitle + lb de, 3, 3 + ld hl, wCardListCoords + ld [hl], e + inc hl + ld [hl], d + call PrintConfirmationCardList + ret + +.ClearScreenAndPrintDeckTitle + call EmptyScreenAndLoadFontDuelAndHandCardsIcons + call .PrintDeckIndexAndName + call EnableLCD + ret + +; prints text in the form "X.<DECK NAME> deck" +; where X is the deck index in the list +.PrintDeckIndexAndName + ld a, [wCurDeckName] + or a + ret z ; not a valid deck + lb de, 0, 1 + call InitTextPrinting + ld a, [wCurDeck] + inc a + ld hl, wDefaultText + call ConvertToNumericalDigits + ld [hl], "FW0_·" + inc hl + ld [hl], TX_END + ld hl, wDefaultText + call ProcessText + + ld hl, wCurDeckName + ld de, wDefaultText + call CopyListFromHLToDE + ld hl, wDefaultText + call GetTextLengthInTiles + ld b, $0 + ld hl, wDefaultText + add hl, bc + ld d, h + ld e, l + ld hl, DeckNameSuffix + call CopyListFromHLToDE + lb de, 3, 1 + ld hl, wDefaultText + call InitTextPrinting + call ProcessText + ret + +Func_af1d: + xor a + ld [wTileMapFill], a + call ZeroObjectPositions + call EmptyScreen + ld a, $1 + ld [wVBlankOAMCopyToggle], a + call LoadSymbolsFont + bank1call SetDefaultPalettes + + lb de, $3c, $bf + call SetupText + lb de, 3, 1 + call InitTextPrinting + ldtx hl, ProceduresForSendingCardsText + call ProcessTextFromID + lb de, 1, 3 + call InitTextPrinting + ldtx hl, CardSendingProceduresText + ld a, $01 + ld [wLineSeparation], a + call ProcessTextFromID + xor a + ld [wLineSeparation], a + ldtx hl, PleaseReadTheProceduresForSendingCardsText + call DrawWideTextBox_WaitForInput + + call EnableLCD + call PrepareToBuildDeckConfigurationToSend + jr c, .asm_af6b + ld a, $01 + or a + ret + +.asm_af6b + ld hl, wCurDeckCards + ld de, wDuelTempList + call CopyListFromHLToDE + xor a + ld [wNameBuffer], a + bank1call SendCard + ret c + call EnableSRAM + ld hl, wCurDeckCards + call DecrementDeckCardsInCollection + call DisableSRAM + call SaveGame + ld hl, wNameBuffer + ld de, wDefaultText + call CopyListFromHLToDE + xor a + ret + +; never reached + scf + ret + +Func_af98: + xor a + ld [wDuelTempList], a + ld [wNameBuffer], a + bank1call ReceiveCard + ret c + + call EnableSRAM + ld hl, wDuelTempList + call AddGiftCenterDeckCardsToCollection + call DisableSRAM + call SaveGame + xor a + ld [wCardListVisibleOffset], a + ld hl, Data_b04a + call InitCardSelectionParams + call PrintReceivedTheseCardsText + call Func_b088 + call EnableLCD + ld a, [wNumEntriesInCurFilter] + ld [wNumCardListEntries], a + ld hl, wNumVisibleCardListEntries + cp [hl] + jr nc, .asm_afd4 + ld [wCardListNumCursorPositions], a +.asm_afd4 + ld hl, ShowReceivedCardsList + ld d, h + ld a, l + ld hl, wCardListUpdateFunction + ld [hli], a + ld [hl], d + + xor a + ld [wced2], a +.asm_afe2 + call DoFrame + call HandleDeckCardSelectionList + jr c, .asm_b02f + call HandleLeftRightInCardList + jr c, .asm_afe2 + ldh a, [hDPadHeld] + and START + jr z, .asm_afe2 +.asm_aff5 + ld a, $01 + call PlaySFXConfirmOrCancel + ld a, [wCardListCursorPos] + ld [wTempCardListCursorPos], a + + ; set wFilteredCardList as current card list + ; and show card page screen + ld de, wFilteredCardList + ld hl, wCurCardListPtr + ld [hl], e + inc hl + ld [hl], d + call OpenCardPageFromCardList + call PrintReceivedTheseCardsText + + call PrintCardSelectionList + call EnableLCD + ld hl, Data_b04a + call InitCardSelectionParams + ld a, [wNumEntriesInCurFilter] + ld hl, wNumVisibleCardListEntries + cp [hl] + jr nc, .asm_b027 + ld [wCardListNumCursorPositions], a +.asm_b027 + ld a, [wTempCardListCursorPos] + ld [wCardListCursorPos], a + jr .asm_afe2 +.asm_b02f + call DrawListCursor_Invisible + ld a, [wCardListCursorPos] + ld [wTempCardListCursorPos], a + ld a, [hffb3] + cp $ff + jr nz, .asm_aff5 + ld hl, wNameBuffer + ld de, wDefaultText + call CopyListFromHLToDE + or a + ret + +Data_b04a: + db 1 ; x pos + db 3 ; y pos + db 2 ; y spacing + db 0 ; x spacing + db 5 ; num entries + db SYM_CURSOR_R ; visible cursor tile + db SYM_SPACE ; invisible cursor tile + dw NULL ; wCardListHandlerFunction + +ShowReceivedCardsList: + ld hl, hffb0 + ld [hl], $01 + lb de, 1, 1 + call InitTextPrinting + ldtx hl, CardReceivedText + call ProcessTextFromID + ld hl, wNameBuffer + ld de, wDefaultText + call CopyListFromHLToDE + xor a + ld [wTxRam2 + 0], a + ld [wTxRam2 + 1], a + lb de, 1, 14 + call InitTextPrinting + ldtx hl, ReceivedTheseCardsFromText + call PrintTextNoDelay + ld hl, hffb0 + ld [hl], $00 + jp PrintCardSelectionList + +Func_b088: + ld a, CARD_COLLECTION_SIZE - 1 + ld hl, wTempCardCollection + call ClearNBytesFromHL + ld de, wDuelTempList + call .Func_b0b2 + ld a, $ff + call .Func_b0c0 + ld a, $05 + ld [wNumVisibleCardListEntries], a + lb de, 2, 3 + ld hl, wCardListCoords + ld [hl], e + inc hl + ld [hl], d + ld a, SYM_BOX_RIGHT + ld [wCursorAlternateTile], a + call PrintCardSelectionList + ret + +.Func_b0b2 + ld bc, wTempCardCollection +.loop + ld a, [de] + inc de + or a + ret z + ld h, $00 + ld l, a + add hl, bc + inc [hl] + jr .loop + +.Func_b0c0 + push af + push bc + push de + push hl + push af + ld a, DECK_SIZE + ld hl, wOwnedCardsCountList + call ClearNBytesFromHL + ld a, DECK_SIZE + ld hl, wFilteredCardList + call ClearNBytesFromHL + pop af + ld hl, $0 + ld de, $0 + ld b, a +.asm_b0dd + inc e + call GetCardType + jr c, .asm_b119 + ld c, a + ld a, b + cp $ff + jr z, .asm_b0fc + and FILTER_ENERGY + cp FILTER_ENERGY + jr z, .asm_b0f5 + ld a, c + cp b + jr nz, .asm_b0dd + jr .asm_b0fc +.asm_b0f5 + ld a, c + and TYPE_ENERGY + cp TYPE_ENERGY + jr nz, .asm_b0dd +.asm_b0fc + push bc + push hl + ld bc, wFilteredCardList + add hl, bc + ld [hl], e + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + and $7f + pop hl + or a + jr z, .asm_b116 + push hl + ld bc, wOwnedCardsCountList + add hl, bc + ld [hl], a + pop hl + inc l +.asm_b116 + pop bc + jr .asm_b0dd + +.asm_b119 + ld a, l + ld [wNumEntriesInCurFilter], a + xor a + ld c, l + ld b, h + ld hl, wFilteredCardList + add hl, bc + ld [hl], a + ld a, $ff + ld hl, wOwnedCardsCountList + add hl, bc + ld [hl], a + pop hl + pop de + pop bc + pop af + ret + +PrintCardToSendText: + call EmptyScreenAndDrawTextBox + lb de, 1, 1 + call InitTextPrinting + ldtx hl, CardToSendText + call ProcessTextFromID + ret + +PrintReceivedTheseCardsText: + call EmptyScreenAndDrawTextBox + lb de, 1, 1 + call InitTextPrinting + ldtx hl, CardReceivedText + call ProcessTextFromID + ld hl, wNameBuffer + ld de, wDefaultText + call CopyListFromHLToDE + xor a + ld [wTxRam2 + 0], a + ld [wTxRam2 + 1], a + ldtx hl, ReceivedTheseCardsFromText + call DrawWideTextBox_PrintText + ret + +EmptyScreenAndDrawTextBox: + call Set_OBJ_8x8 + call Func_8d78 + lb de, 0, 0 + lb bc, 20, 13 + call DrawRegularTextBox + ret + +Func_b177: + ld a, [wd10e] + and $03 + ld hl, .FunctionTable + call JumpToFunctionInTable + jr c, .asm_b18f + or a + jr nz, .asm_b18f + xor a + ld [wTxRam2 + 0], a + ld [wTxRam2 + 1], a + ret +.asm_b18f + ld a, $ff + ld [wd10e], a + ret + +.FunctionTable + dw Func_af1d + dw Func_af98 + dw Func_bc04 + dw Func_bc7a + +HandleDeckSaveMachineMenu: + xor a + ld [wCardListVisibleOffset], a + ldtx de, DeckSaveMachineText + ld hl, wDeckMachineTitleText + ld [hl], e + inc hl + ld [hl], d + call ClearScreenAndDrawDeckMachineScreen + ld a, NUM_DECK_SAVE_MACHINE_SLOTS + ld [wNumDeckMachineEntries], a + + xor a +.wait_input + ld hl, DeckMachineSelectionParams + call InitCardSelectionParams + call DrawListScrollArrows + call PrintNumSavedDecks + ldtx hl, PleaseSelectDeckText + call DrawWideTextBox_PrintText + ldtx de, PleaseSelectDeckText + call InitDeckMachineDrawingParams + call HandleDeckMachineSelection + jr c, .wait_input + cp $ff + ret z ; operation cancelled + ; get the index of selected deck + ld b, a + ld a, [wCardListVisibleOffset] + add b + ld [wSelectedDeckMachineEntry], a + + call ResetCheckMenuCursorPositionAndBlink + call DrawWideTextBox + ld hl, .DeckMachineMenuData + call PlaceTextItems +.wait_input_submenu + call DoFrame + call HandleCheckMenuInput + jp nc, .wait_input_submenu + cp $ff + jr nz, .submenu_option_selected + ; return from submenu + ld a, [wTempDeckMachineCursorPos] + jp .wait_input + +.submenu_option_selected + ld a, [wCheckMenuCursorYPosition] + sla a + ld hl, wCheckMenuCursorXPosition + add [hl] + or a + jr nz, .ok_1 + +; Save a Deck + call CheckIfSelectedDeckMachineEntryIsEmpty + jr nc, .prompt_ok_if_deleted + call SaveDeckInDeckSaveMachine + ld a, [wTempDeckMachineCursorPos] + jp c, .wait_input + jr .return_to_list +.prompt_ok_if_deleted + ldtx hl, OKIfFileDeletedText + call YesOrNoMenuWithText + ld a, [wTempDeckMachineCursorPos] + jr c, .wait_input + call SaveDeckInDeckSaveMachine + ld a, [wTempDeckMachineCursorPos] + jp c, .wait_input + jr .return_to_list + +.ok_1 + cp $1 + jr nz, .ok_2 + +; Delete a Deck + call CheckIfSelectedDeckMachineEntryIsEmpty + jr c, .is_empty + call TryDeleteSavedDeck + ld a, [wTempDeckMachineCursorPos] + jp c, .wait_input + jr .return_to_list + +.is_empty + ld hl, WaitForVBlank + call DrawWideTextBox_WaitForInput + ld a, [wTempDeckMachineCursorPos] + jp .wait_input + +.ok_2 + cp $2 + jr nz, .cancel + +; Build a Deck + call CheckIfSelectedDeckMachineEntryIsEmpty + jr c, .is_empty + call TryBuildDeckMachineDeck + ld a, [wTempDeckMachineCursorPos] + jp nc, .wait_input + +.return_to_list + ld a, [wTempCardListVisibleOffset] + ld [wCardListVisibleOffset], a + call ClearScreenAndDrawDeckMachineScreen + call DrawListScrollArrows + call PrintNumSavedDecks + ld a, [wTempDeckMachineCursorPos] + jp .wait_input + +.cancel + ret + +.DeckMachineMenuData + textitem 2, 14, SaveADeckText + textitem 12, 14, DeleteADeckText + textitem 2, 16, BuildADeckText + textitem 12, 16, CancelText + db $ff + +; sets the number of cursor positions for deck machine menu, +; sets the text ID to show given by de +; and sets DrawDeckMachineScreen as the update function +; de = text ID +InitDeckMachineDrawingParams: + ld a, NUM_DECK_MACHINE_SLOTS + ld [wCardListNumCursorPositions], a + ld hl, wDeckMachineText + ld [hl], e + inc hl + ld [hl], d + ld hl, DrawDeckMachineScreen + ld d, h + ld a, l + ld hl, wCardListUpdateFunction + ld [hli], a + ld [hl], d + xor a + ld [wced2], a + ret + +; handles player input inside the Deck Machine screen +; the Start button opens up the deck confirmation menu +; and returns carry +; otherwise, returns no carry and selection made in a +HandleDeckMachineSelection: + call DoFrame + call HandleDeckCardSelectionList + jr c, .selection_made + + call .HandleListJumps + jr c, HandleDeckMachineSelection ; jump back to start + ldh a, [hDPadHeld] + and START + jr z, HandleDeckMachineSelection ; jump back to start + +; start btn + ld a, [wCardListVisibleOffset] + ld [wTempCardListVisibleOffset], a + ld b, a + ld a, [wCardListCursorPos] + ld [wTempDeckMachineCursorPos], a + add b + ld c, a + inc a + or $80 + ld [wCurDeck], a + + ; get pointer to selected deck cards + ; and if it's an empty deck, jump to start + sla c + ld b, $0 + ld hl, wMachineDeckPtrs + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + push hl + ld bc, DECK_NAME_SIZE + add hl, bc + ld d, h + ld e, l + call EnableSRAM + ld a, [hl] + call DisableSRAM + pop hl + or a + jr z, HandleDeckMachineSelection ; jump back to start + +; show deck confirmation screen with deck cards +; and return carry set + ld a, $01 + call PlaySFXConfirmOrCancel + call OpenDeckConfirmationMenu + ld a, [wTempCardListVisibleOffset] + ld [wCardListVisibleOffset], a + call ClearScreenAndDrawDeckMachineScreen + call DrawListScrollArrows + call PrintNumSavedDecks + ld a, [wTempDeckMachineCursorPos] + ld [wCardListCursorPos], a + scf + ret + +.selection_made + call DrawListCursor_Visible + ld a, [wCardListVisibleOffset] + ld [wTempCardListVisibleOffset], a + ld a, [wCardListCursorPos] + ld [wTempDeckMachineCursorPos], a + ld a, [hffb3] + or a + ret + +; handles right and left input for jumping several entries at once +; returns carry if jump was made +.HandleListJumps + ld a, [wCardListVisibleOffset] + ld c, a + ldh a, [hDPadHeld] + cp D_RIGHT + jr z, .d_right + cp D_LEFT + jr z, .d_left + or a + ret + +.d_right + ld a, [wCardListVisibleOffset] + add NUM_DECK_MACHINE_SLOTS + ld b, a + add NUM_DECK_MACHINE_SLOTS + ld hl, wNumDeckMachineEntries + cp [hl] + jr c, .got_new_pos + ld a, [wNumDeckMachineEntries] + sub NUM_DECK_MACHINE_SLOTS + ld b, a + jr .got_new_pos + +.d_left + ld a, [wCardListVisibleOffset] + sub NUM_DECK_MACHINE_SLOTS + ld b, a + jr nc, .got_new_pos + ld b, 0 ; first entry + +.got_new_pos + ld a, b + ld [wCardListVisibleOffset], a + cp c + jr z, .set_carry + ; play SFX if jump was made + ; and update UI + ld a, SFX_01 + call PlaySFX + call DrawDeckMachineScreen + call PrintNumSavedDecks +.set_carry + scf + ret + +; returns carry if deck corresponding to the +; entry selected in the Deck Machine menu is empty +CheckIfSelectedDeckMachineEntryIsEmpty: + ld a, [wSelectedDeckMachineEntry] + sla a + ld l, a + ld h, $0 + ld bc, wMachineDeckPtrs + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld bc, DECK_NAME_SIZE + add hl, bc + call EnableSRAM + ld a, [hl] + call DisableSRAM + or a + ret nz ; is valid + scf + ret; is empty + +ClearScreenAndDrawDeckMachineScreen: + call Set_OBJ_8x8 + xor a + ld [wTileMapFill], a + call ZeroObjectPositions + call EmptyScreen + ld a, $01 + ld [wVBlankOAMCopyToggle], a + call LoadSymbolsFont + call LoadDuelCardSymbolTiles + bank1call SetDefaultPalettes + lb de, $3c, $ff + call SetupText + lb de, 0, 0 + lb bc, 20, 13 + call DrawRegularTextBox + call SetDeckMachineTitleText + call GetSavedDeckPointers + call PrintVisibleDeckMachineEntries + call GetSavedDeckCount + call EnableLCD + ret + +; prints wDeckMachineTitleText as title text +SetDeckMachineTitleText: + lb de, 1, 0 + call InitTextPrinting + ld hl, wDeckMachineTitleText + ld a, [hli] + ld h, [hl] + ld l, a + call ProcessTextFromID + ret + +; save all sSavedDecks pointers in wMachineDeckPtrs +GetSavedDeckPointers: + ld a, NUM_DECK_SAVE_MACHINE_SLOTS + add NUM_DECK_SAVE_MACHINE_SLOTS ; add a is better + ld hl, wMachineDeckPtrs + call ClearNBytesFromHL + ld de, wMachineDeckPtrs + ld hl, sSavedDecks + ld bc, DECK_STRUCT_SIZE + ld a, NUM_DECK_SAVE_MACHINE_SLOTS +.loop_saved_decks + push af + ld a, l + ld [de], a + inc de + ld a, h + ld [de], a + inc de + add hl, bc + pop af + dec a + jr nz, .loop_saved_decks + ret + +; given the cursor position in the deck machine menu +; prints the deck names of all entries that are visible +PrintVisibleDeckMachineEntries: + ld a, [wCardListVisibleOffset] + lb de, 2, 2 + ld b, NUM_DECK_MACHINE_VISIBLE_DECKS +.loop + push af + push bc + push de + call PrintDeckMachineEntry + pop de + pop bc + pop af + ret c ; jump never made? + dec b + ret z ; no more entries + inc a + inc e + inc e + jr .loop + +UpdateDeckMachineScrollArrowsAndEntries: + call DrawListScrollArrows + jr PrintVisibleDeckMachineEntries + +DrawDeckMachineScreen: + call DrawListScrollArrows + ld hl, hffb0 + ld [hl], $01 + call SetDeckMachineTitleText + lb de, 1, 14 + call InitTextPrinting + ld hl, wDeckMachineText + ld a, [hli] + ld h, [hl] + ld l, a + call ProcessTextFromID + ld hl, hffb0 + ld [hl], $00 + jr PrintVisibleDeckMachineEntries + +; prints the deck name of the deck corresponding +; to index in register a, from wMachineDeckPtrs +; also checks whether the deck can be built +; either by dismantling other decks or not, +; and places the corresponding symbol next to the name +PrintDeckMachineEntry: + ld b, a + push bc + ld hl, wDefaultText + inc a + call ConvertToNumericalDigits + ld [hl], "FW0_·" + inc hl + ld [hl], TX_END + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + pop af + +; get the deck corresponding to input index +; and append its name to wDefaultText + push af + sla a + ld l, a + ld h, $0 + ld bc, wMachineDeckPtrs + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + inc d + inc d + inc d + push de + call AppendDeckName + pop de + pop bc + jr nc, .valid_deck + +; invalid deck, give it the default +; empty deck name ("--------------") + call InitTextPrinting + ldtx hl, EmptyDeckNameText + call ProcessTextFromID + ld d, 13 + inc e + call InitTextPrinting + ld hl, .text + call ProcessText + scf + ret + +.valid_deck + push de + push bc + ld d, 18 + call InitTextPrinting + +; print the symbol that symbolizes whether the deck can +; be built, or if another deck has to be dismantled to build it + ld a, $0 ; no decks dismantled + call CheckIfCanBuildSavedDeck + pop bc + ld hl, wDefaultText + jr c, .cannot_build + lb de, 3, "FW3_○" ; can build + jr .asm_b4c2 +.cannot_build + push bc + ld a, ALL_DECKS + call CheckIfCanBuildSavedDeck + jr c, .cannot_build_at_all + pop bc + lb de, 3, "FW3_❄" ; can build by dismantling + jr .asm_b4c2 + +.cannot_build_at_all + lb de, 0, "FW0_✕" ; cannot build even by dismantling + call Func_22ca + pop bc + pop de + +; place in wDefaultText the number of cards +; that are needed in order to build the deck + push bc + ld d, 17 + inc e + call InitTextPrinting + pop bc + call .GetNumCardsMissingToBuildDeck + call CalculateOnesAndTensDigits + ld hl, wOnesAndTensPlace + ld a, [hli] + ld b, a + ld a, [hl] + ld hl, wDefaultText + ld [hl], TX_SYMBOL + inc hl + ld [hli], a + ld [hl], TX_SYMBOL + inc hl + ld a, b + ld [hli], a + ld [hl], TX_END + ld hl, wDefaultText + call ProcessText + or a + ret + +.asm_b4c2 + call Func_22ca + pop de + ld d, 13 + inc e + call InitTextPrinting + ld hl, .text + call ProcessText + or a + ret + +.text + db TX_SYMBOL, TX_END + db TX_SYMBOL, TX_END + db TX_SYMBOL, TX_END + db TX_SYMBOL, TX_END + db TX_SYMBOL, TX_END + db TX_SYMBOL, TX_END + done + +; outputs in a the number of cards that the player does not own +; in order to build the deck entry from wMachineDeckPtrs +; given in register b +.GetNumCardsMissingToBuildDeck + push bc + call SafelySwitchToSRAM0 + call CreateCardCollectionListWithDeckCards + call SafelySwitchToTempSRAMBank + pop bc + +; get address to cards for the corresponding deck entry + sla b + ld c, b + ld b, $00 + ld hl, wMachineDeckPtrs + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld bc, DECK_NAME_SIZE + add hl, bc + + call EnableSRAM + ld de, wTempCardCollection + lb bc, 0, 0 +.loop + inc b + ld a, DECK_SIZE + cp b + jr c, .done + ld a, [hli] + push hl + ld l, a + ld h, $00 + add hl, de + ld a, [hl] + and CARD_COUNT_MASK + or a + jr z, .none + dec a + ld [hl], a + pop hl + jr .loop +.none + inc c + pop hl + jr .loop +.done + ld a, c + call DisableSRAM + ret + +; counts how many decks in sSavedDecks are not empty +; stores value in wNumSavedDecks +GetSavedDeckCount: + call EnableSRAM + ld hl, sSavedDecks + ld bc, DECK_STRUCT_SIZE + ld d, NUM_DECK_SAVE_MACHINE_SLOTS + ld e, 0 +.loop + ld a, [hl] + or a + jr z, .empty_slot + inc e +.empty_slot + dec d + jr z, .got_count + add hl, bc + jr .loop +.got_count + ld a, e + ld [wNumSavedDecks], a + call DisableSRAM + ret + +; prints "[wNumSavedDecks]/60" +PrintNumSavedDecks: + ld a, [wNumSavedDecks] + ld hl, wDefaultText + call ConvertToNumericalDigits + ld a, TX_SYMBOL + ld [hli], a + ld a, SYM_SLASH + ld [hli], a + ld a, NUM_DECK_SAVE_MACHINE_SLOTS + call ConvertToNumericalDigits + ld [hl], TX_END + lb de, 14, 1 + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + ret + +; prints "X/Y" where X is the current list index +; and Y is the total number of saved decks +; unreferenced? +Func_b568: + ld a, [wCardListCursorPos] + ld b, a + ld a, [wCardListVisibleOffset] + add b + inc a + ld hl, wDefaultText + call ConvertToNumericalDigits + ld a, TX_SYMBOL + ld [hli], a + ld a, SYM_SLASH + ld [hli], a + ld a, [wNumSavedDecks] + call ConvertToNumericalDigits + ld [hl], TX_END + lb de, 14, 1 + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + ret + +; handles player choice in what deck to save +; in the Deck Save Machine +; assumes the slot to save was selected and +; is stored in wSelectedDeckMachineEntry +; if operation was successful, return carry +SaveDeckInDeckSaveMachine: + ld a, ALL_DECKS + call DrawDecksScreen + xor a +.wait_input + ld hl, DeckMachineMenuParameters + call InitializeMenuParameters + ldtx hl, ChooseADeckToSaveText + call DrawWideTextBox_PrintText +.wait_submenu_input + call DoFrame + call HandleStartButtonInDeckSelectionMenu + jr c, .wait_input + call HandleMenuInput + jp nc, .wait_submenu_input ; can be jr + ldh a, [hCurMenuItem] + cp $ff + ret z ; operation cancelled + ld [wCurDeck], a + call CheckIfCurDeckIsValid + jp nc, .SaveDeckInSelectedEntry ; can be jr + ; is an empty deck + call PrintThereIsNoDeckHereText + ld a, [wCurDeck] + jr .wait_input + +; overwrites data in the selected deck in SRAM +; with the deck that was chosen, in wCurDeck +; then returns carry +.SaveDeckInSelectedEntry + call GetPointerToDeckName + call GetSelectedSavedDeckPtr + ld b, DECK_STRUCT_SIZE + call EnableSRAM + call CopyNBytesFromHLToDE + call DisableSRAM + + call ClearScreenAndDrawDeckMachineScreen + call DrawListScrollArrows + call PrintNumSavedDecks + ld a, [wTempDeckMachineCursorPos] + ld hl, DeckMachineSelectionParams + call InitCardSelectionParams + call DrawListCursor_Visible + call GetPointerToDeckName + call EnableSRAM + call CopyDeckName + call DisableSRAM + xor a + ld [wTxRam2 + 0], a + ld [wTxRam2 + 1], a + ldtx hl, SavedTheConfigurationForText + call DrawWideTextBox_WaitForInput + scf + ret + +DeckMachineMenuParameters: + db 1, 2 ; cursor x, cursor y + db 3 ; y displacement between items + db 4 ; number of items + db SYM_CURSOR_R ; cursor tile number + db SYM_SPACE ; tile behind cursor + dw NULL ; function pointer if non-0 + +; outputs in de pointer of saved deck +; corresponding to index in wSelectedDeckMachineEntry +GetSelectedSavedDeckPtr: + push af + push hl + ld a, [wSelectedDeckMachineEntry] + sla a + ld e, a + ld d, $00 + ld hl, wMachineDeckPtrs + add hl, de + ld e, [hl] + inc hl + ld d, [hl] + pop hl + pop af + ret + +; checks if it's possible to build saved deck with index b +; includes cards from already built decks from flags in a +; returns carry if cannot build the deck with the given criteria +; a = DECK_* flags for which decks to include in the collection +; b = saved deck index +CheckIfCanBuildSavedDeck: + push bc + call SafelySwitchToSRAM0 + call CreateCardCollectionListWithDeckCards + call SafelySwitchToTempSRAMBank + pop bc + sla b + ld c, b + ld b, $0 + ld hl, wMachineDeckPtrs + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld bc, DECK_NAME_SIZE + add hl, bc + call CheckIfHasEnoughCardsToBuildDeck + ret + +; switches to SRAM bank 0 and stores current SRAM bank in wTempBankSRAM +; skips if current SRAM bank is already 0 +SafelySwitchToSRAM0: + push af + ldh a, [hBankSRAM] + or a + jr z, .skip + ld [wTempBankSRAM], a + xor a + call BankswitchSRAM +.skip + pop af + ret + +; switches to SRAM bank 1 and stores current SRAM bank in wTempBankSRAM +; skips if current SRAM bank is already 1 +SafelySwitchToSRAM1: + push af + ldh a, [hBankSRAM] + cp BANK("SRAM1") + jr z, .skip + ld [wTempBankSRAM], a + ld a, BANK("SRAM1") + call BankswitchSRAM +.skip + pop af + ret + +SafelySwitchToTempSRAMBank: + push af + push bc + ldh a, [hBankSRAM] + ld b, a + ld a, [wTempBankSRAM] + cp b + jr z, .skip + call BankswitchSRAM +.skip + pop bc + pop af + ret + +; returns carry if wTempCardCollection does not +; have enough cards to build deck pointed by hl +; hl = pointer to cards of deck to check +CheckIfHasEnoughCardsToBuildDeck: + call EnableSRAM + ld de, wTempCardCollection + ld b, 0 +.loop + inc b + ld a, DECK_SIZE + cp b + jr c, .no_carry + ld a, [hli] + push hl + ld l, a + ld h, $00 + add hl, de + ld a, [hl] + or a + jr z, .set_carry + cp CARD_NOT_OWNED + jr z, .set_carry + dec a + ld [hl], a + pop hl + jr .loop + +.set_carry + pop hl + call DisableSRAM + scf + ret + +.no_carry + call DisableSRAM + or a + ret + +; outputs in a the first slot that is empty to build a deck +; if no empty slot is found, return carry +FindFirstEmptyDeckSlot: + ld hl, sDeck1Cards + ld a, [hl] + or a + jr nz, .check_deck_2 + xor a + ret + +.check_deck_2 + ld hl, sDeck2Cards + ld a, [hl] + or a + jr nz, .check_deck_3 + ld a, 1 + ret + +.check_deck_3 + ld hl, sDeck3Cards + ld a, [hl] + or a + jr nz, .check_deck_4 + ld a, 2 + ret + +.check_deck_4 + ld hl, sDeck4Cards + ld a, [hl] + or a + jr nz, .set_carry + ld a, 3 + ret + +.set_carry + scf + ret + +; prompts the player whether to delete selected saved deck +; if player selects yes, clears memory in SRAM +; corresponding to that saved deck slot +; if player selects no, return carry +TryDeleteSavedDeck: + ldtx hl, DoYouReallyWishToDeleteText + call YesOrNoMenuWithText + jr c, .no + call GetSelectedSavedDeckPtr + ld l, e + ld h, d + push hl + call EnableSRAM + call CopyDeckName + pop hl + ld a, DECK_STRUCT_SIZE + call ClearNBytesFromHL + call DisableSRAM + xor a + ld [wTxRam2 + 0], a + ld [wTxRam2 + 1], a + ldtx hl, DeletedTheConfigurationForText + call DrawWideTextBox_WaitForInput + or a + ret + +.no + ld a, [wCardListCursorPos] + scf + ret + +DeckMachineSelectionParams: + db 1 ; x pos + db 2 ; y pos + db 2 ; y spacing + db 0 ; x spacing + db 5 ; num entries + db SYM_CURSOR_R ; visible cursor tile + db SYM_SPACE ; invisible cursor tile + dw NULL ; wCardListHandlerFunction + +DrawListScrollArrows: + ld a, [wCardListVisibleOffset] + or a + jr z, .no_up_cursor + ld a, SYM_CURSOR_U + jr .got_tile_1 +.no_up_cursor + ld a, SYM_BOX_RIGHT +.got_tile_1 + lb bc, 19, 1 + call WriteByteToBGMap0 + + ld a, [wCardListVisibleOffset] + add NUM_DECK_MACHINE_VISIBLE_DECKS + 1 + ld b, a + ld a, [wNumDeckMachineEntries] + cp b + jr c, .no_down_cursor + xor a ; FALSE + ld [wUnableToScrollDown], a + ld a, SYM_CURSOR_D + jr .got_tile_2 +.no_down_cursor + ld a, TRUE + ld [wUnableToScrollDown], a + ld a, SYM_BOX_RIGHT +.got_tile_2 + lb bc, 19, 11 + call WriteByteToBGMap0 + ret + +; handles the deck menu for when the player +; needs to make space for new deck to build +HandleDismantleDeckToMakeSpace: + ldtx hl, YouMayOnlyCarry4DecksText + call DrawWideTextBox_WaitForInput + call SafelySwitchToSRAM0 + ld a, ALL_DECKS + call DrawDecksScreen + xor a +.init_menu_params + ld hl, DeckMachineMenuParameters + call InitializeMenuParameters + ldtx hl, ChooseADeckToDismantleText + call DrawWideTextBox_PrintText +.loop_input + call DoFrame + call HandleStartButtonInDeckSelectionMenu + jr c, .init_menu_params + call HandleMenuInput + jp nc, .loop_input ; can be jr + ldh a, [hCurMenuItem] + cp $ff + jr nz, .selected_deck + ; operation was cancelled + call SafelySwitchToTempSRAMBank + scf + ret + +.selected_deck + ld [wCurDeck], a + ldtx hl, DismantleThisDeckText + call YesOrNoMenuWithText + jr nc, .dismantle + ld a, [wCurDeck] + jr .init_menu_params + +.dismantle + call GetPointerToDeckName + push hl + ld de, wDismantledDeckName + call EnableSRAM + call CopyListFromHLToDE + pop hl + push hl + ld bc, DECK_NAME_SIZE + add hl, bc + call AddDeckToCollection + pop hl + ld a, DECK_STRUCT_SIZE + call ClearNBytesFromHL + call DisableSRAM + + ; redraw deck screen + ld a, ALL_DECKS + call DrawDecksScreen + ld a, [wCurDeck] + ld hl, DeckMachineMenuParameters + call InitializeMenuParameters + call DrawCursor2 + call SafelySwitchToTempSRAMBank + ld hl, wDismantledDeckName + call CopyDeckName + xor a + ld [wTxRam2 + 0], a + ld [wTxRam2 + 1], a + ldtx hl, DismantledDeckText + call DrawWideTextBox_WaitForInput + ld a, [wCurDeck] + ret + +; tries to build the deck in wSelectedDeckMachineEntry +; will check if can be built with or without dismantling +; prompts the player in case a deck has to be dismantled +; or, if it's impossible to build deck, shows missing cards list +TryBuildDeckMachineDeck: + ld a, [wSelectedDeckMachineEntry] + ld b, a + push bc + ld a, $0 + call CheckIfCanBuildSavedDeck + pop bc + jr nc, .build_deck + ld a, ALL_DECKS + call CheckIfCanBuildSavedDeck + jr c, .do_not_own_all_cards_needed + ; can only be built by dismantling some deck + ldtx hl, ThisDeckCanOnlyBeBuiltIfYouDismantleText + call DrawWideTextBox_WaitForInput + call .DismantleDecksNeededToBuild + jr nc, .build_deck + ; player chose not to dismantle + +.set_carry_and_return + ld a, [wCardListCursorPos] + scf + ret + +.do_not_own_all_cards_needed + ldtx hl, YouDoNotOwnAllCardsNeededToBuildThisDeckText + call DrawWideTextBox_WaitForInput + jp .ShowMissingCardList + +.build_deck + call EnableSRAM + call SafelySwitchToSRAM0 + call FindFirstEmptyDeckSlot + call SafelySwitchToTempSRAMBank + call DisableSRAM + jr nc, .got_deck_slot + call HandleDismantleDeckToMakeSpace + jr nc, .got_deck_slot + scf + ret + +.got_deck_slot + ld [wDeckSlotForNewDeck], a + ld a, [wSelectedDeckMachineEntry] + ld c, a + ld b, $0 + sla c + ld hl, wMachineDeckPtrs + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + + ; copy deck to buffer + ld de, wDeckToBuild + ld b, DECK_STRUCT_SIZE + call EnableSRAM + call CopyNBytesFromHLToDE + + ; remove the needed cards from collection + ld hl, wDeckToBuild + DECK_NAME_SIZE + call SafelySwitchToSRAM0 + call DecrementDeckCardsInCollection + + ; copy the deck cards from the buffer + ; to the deck slot that was chosen + ld a, [wDeckSlotForNewDeck] + ld l, a + ld h, DECK_STRUCT_SIZE + call HtimesL + ld bc, sBuiltDecks + add hl, bc + ld d, h + ld e, l + ld hl, wDeckToBuild + ld b, DECK_STRUCT_SIZE + call CopyNBytesFromHLToDE + call DisableSRAM + + ; draw Decks screen + ld a, ALL_DECKS + call DrawDecksScreen + ld a, [wDeckSlotForNewDeck] + ld [wCurDeck], a + ld hl, DeckMachineMenuParameters + call InitializeMenuParameters + call DrawCursor2 + call GetPointerToDeckName + call EnableSRAM + call CopyDeckName + call DisableSRAM + call SafelySwitchToTempSRAMBank + xor a + ld [wTxRam2 + 0], a + ld [wTxRam2 + 1], a + ldtx hl, BuiltDeckText + call DrawWideTextBox_WaitForInput + scf + ret + +; asks the player for confirmation to dismantle decks +; needed to build the selected deck from the Deck Save Machine +; returns carry set if player selected "no" +; if player selected "yes", dismantle decks +.DismantleDecksNeededToBuild +; shows Decks screen with the names +; of the decks to be dismantled + farcall CheckWhichDecksToDismantleToBuildSavedDeck + call SafelySwitchToSRAM0 + call DrawDecksScreen + ldtx hl, DismantleTheseDecksText + call YesOrNoMenuWithText + jr nc, .yes +; no + call SafelySwitchToTempSRAMBank + scf + ret + +.yes + call EnableSRAM + ld a, [wDecksToBeDismantled] + bit DECK_1_F, a + jr z, .deck_2 + ld a, DECK_1_F + call .DismantleDeck +.deck_2 + ld a, [wDecksToBeDismantled] + bit DECK_2_F, a + jr z, .deck_3 + ld a, DECK_2_F + call .DismantleDeck +.deck_3 + ld a, [wDecksToBeDismantled] + bit DECK_3_F, a + jr z, .deck_4 + ld a, DECK_3_F + call .DismantleDeck +.deck_4 + ld a, [wDecksToBeDismantled] + bit DECK_4_F, a + jr z, .done_dismantling + ld a, DECK_4_F + call .DismantleDeck + +.done_dismantling + call DisableSRAM + ld a, [wDecksToBeDismantled] + call DrawDecksScreen + call SafelySwitchToTempSRAMBank + ldtx hl, DismantledTheDeckText + call DrawWideTextBox_WaitForInput + or a + ret + +; dismantles built deck given by a +; and adds its cards to the collection +; a = DECK_*_F to dismantle +.DismantleDeck + ld l, a + ld h, DECK_STRUCT_SIZE + call HtimesL + ld bc, sBuiltDecks + add hl, bc + push hl + ld bc, DECK_NAME_SIZE + add hl, bc + call AddDeckToCollection + pop hl + ld a, DECK_STRUCT_SIZE + call ClearNBytesFromHL + ret + +; collects cards missing from player's collection +; and shows its confirmation list +.ShowMissingCardList +; copy saved deck card from SRAM to wCurDeckCards +; and make unique card list sorted by ID + ld a, [wSelectedDeckMachineEntry] + ld [wCurDeck], a + call GetSelectedSavedDeckPtr + ld hl, DECK_NAME_SIZE + add hl, de + ld de, wCurDeckCards + ld b, DECK_SIZE + call EnableSRAM + call CopyNBytesFromHLToDE + call DisableSRAM + xor a ; terminator byte for deck + ld [wCurDeckCards + DECK_SIZE], a + call SortCurDeckCardsByID + call CreateCurDeckUniqueCardList + +; create collection card list, including +; the cards from all built decks + ld a, ALL_DECKS + call SafelySwitchToSRAM0 + call CreateCardCollectionListWithDeckCards + call SafelySwitchToTempSRAMBank + +; creates list in wFilteredCardList with +; cards that are missing to build this deck + ld hl, wUniqueDeckCardList + ld de, wFilteredCardList +.loop_deck_configuration + ld a, [hli] + or a + jr z, .finish_missing_card_list + ld b, a + push bc + push de + push hl + ld hl, wCurDeckCards + call .CheckIfCardIsMissing + pop hl + pop de + pop bc + jr nc, .loop_deck_configuration + ; this card is missing + ; store in wFilteredCardList this card ID + ; a number of times equal to the amount still needed + ld c, a + ld a, b +.loop_number_missing + ld [de], a + inc de + dec c + jr nz, .loop_number_missing + jr .loop_deck_configuration + +.finish_missing_card_list + xor a ; terminator byte + ld [de], a + + ldtx bc, TheseCardsAreNeededToBuildThisDeckText + ld hl, wCardConfirmationText + ld a, c + ld [hli], a + ld a, b + ld [hl], a + + call GetSelectedSavedDeckPtr + ld h, d + ld l, e + ld de, wFilteredCardList + call HandleDeckMissingCardsList + jp .set_carry_and_return + +; checks if player has enough cards with ID given in register a +; in the collection to build the deck and, if not, returns +; carry set and outputs in a the difference +; a = card ID +; hl = deck cards +.CheckIfCardIsMissing + call .GetCardCountFromDeck + ld hl, wTempCardCollection + push de + call .GetCardCountFromCollection + ld a, e + pop de + + ; d = card count in deck + ; a = card count in collection + cp d + jr c, .not_enough + or a + ret + +.not_enough +; needs more cards than player owns in collection +; return carry set and the number of cards needed + ld e, a + ld a, d + sub e + scf + ret z + +; returns in d the card count of card ID given in register a +; that is found in the card list in hl +; a = card ID +; hl = deck cards +.GetCardCountFromDeck + push af + ld e, a + ld d, 0 +.loop_deck_cards + ld a, [hli] + or a + jr z, .done_deck_cards + cp e + jr nz, .loop_deck_cards + inc d + jr .loop_deck_cards +.done_deck_cards + pop af + ret + +; returns in e the card count of card ID given in register a +; that is found in the card collection +; a = card ID +; hl = card collection +.GetCardCountFromCollection + push af + ld e, a + ld d, $0 + add hl, de + ld a, [hl] + and CARD_COUNT_MASK + ld e, a + pop af + ret + +PrinterMenu_DeckConfiguration: + xor a + ld [wCardListVisibleOffset], a + call ClearScreenAndDrawDeckMachineScreen + ld a, DECK_SIZE + ld [wNumDeckMachineEntries], a + + xor a +.asm_b99e + ld hl, DeckMachineSelectionParams + call InitCardSelectionParams + call DrawListScrollArrows + call PrintNumSavedDecks + ldtx hl, PleaseChooseDeckConfigurationToPrintText + call DrawWideTextBox_PrintText + ldtx de, PleaseChooseDeckConfigurationToPrintText + call InitDeckMachineDrawingParams +.asm_b9b6 + call HandleDeckMachineSelection + jr c, .asm_b99e + cp $ff + ret z + + ld b, a + ld a, [wCardListVisibleOffset] + add b + ld [wSelectedDeckMachineEntry], a + call CheckIfSelectedDeckMachineEntryIsEmpty + jr c, .asm_b9b6 + call DrawWideTextBox + ldtx hl, PrintThisDeckText + call YesOrNoMenuWithText + jr c, .no + call GetSelectedSavedDeckPtr + ld hl, $18 + add hl, de + ld de, wCurDeckCards + ld b, DECK_SIZE + call EnableSRAM + call CopyNBytesFromHLToDE + call DisableSRAM + xor a ; terminator byte for deck + ld [wCurDeckCards + DECK_SIZE], a + call SortCurDeckCardsByID + ld a, [wSelectedDeckMachineEntry] + bank1call PrintDeckConfiguration + call ClearScreenAndDrawDeckMachineScreen + +.no + ld a, [wTempDeckMachineCursorPos] + ld [wCardListCursorPos], a + jp .asm_b99e + +HandleAutoDeckMenu: + ld a, [wCurAutoDeckMachine] + ld hl, .DeckMachineTitleTextList + sla a + ld c, a + ld b, $0 + add hl, bc + ld de, wDeckMachineTitleText + ld a, [hli] + ld [de], a + inc de + ld a, [hl] + ld [de], a + xor a + ld [wCardListVisibleOffset], a + call .InitAutoDeckMenu + ld a, NUM_DECK_MACHINE_SLOTS + ld [wNumDeckMachineEntries], a + xor a + +.please_select_deck + ld hl, .MenuParameters + call InitializeMenuParameters + ldtx hl, PleaseSelectDeckText + call DrawWideTextBox_PrintText + ld a, NUM_DECK_MACHINE_SLOTS + ld [wCardListNumCursorPositions], a + ld hl, UpdateDeckMachineScrollArrowsAndEntries + ld d, h + ld a, l + ld hl, wCardListUpdateFunction + ld [hli], a + ld [hl], d +.wait_input + call DoFrame + call HandleMenuInput + jr c, .deck_selection_made + +; the following lines do nothing + ldh a, [hDPadHeld] + and D_UP | D_DOWN + jr z, .asm_ba4e +.asm_ba4e + +; check whether to show deck confirmation list + ldh a, [hDPadHeld] + and START + jr z, .wait_input + + ld a, [wCardListVisibleOffset] + ld [wTempCardListVisibleOffset], a + ld b, a + ld a, [wCurMenuItem] + ld [wTempDeckMachineCursorPos], a + add b + ld c, a + inc a + or $80 + ld [wCurDeck], a + sla c + ld b, $0 + ld hl, wMachineDeckPtrs + add hl, bc + call SafelySwitchToSRAM1 + ld a, [hli] + ld h, [hl] + ld l, a + push hl + ld bc, DECK_NAME_SIZE + add hl, bc + ld d, h + ld e, l + ld a, [hl] + pop hl + call SafelySwitchToSRAM0 + or a + jr z, .wait_input ; invalid deck + + ; show confirmation list + ld a, $1 + call PlaySFXConfirmOrCancel + call SafelySwitchToSRAM1 + call OpenDeckConfirmationMenu + call SafelySwitchToSRAM0 + ld a, [wTempCardListVisibleOffset] + ld [wCardListVisibleOffset], a + call .InitAutoDeckMenu + ld a, [wTempDeckMachineCursorPos] + jp .please_select_deck + +.deck_selection_made + call DrawCursor2 + ld a, [wCardListVisibleOffset] + ld [wTempCardListVisibleOffset], a + ld a, [wCurMenuItem] + ld [wTempDeckMachineCursorPos], a + ldh a, [hCurMenuItem] + cp $ff + jp z, .exit ; operation cancelled + ld [wSelectedDeckMachineEntry], a + call ResetCheckMenuCursorPositionAndBlink + xor a + ld [wce5e], a + call DrawWideTextBox + ld hl, .DeckMachineMenuData + call PlaceTextItems +.wait_submenu_input + call DoFrame + call HandleCheckMenuInput_YourOrOppPlayArea + jp nc, .wait_submenu_input + cp $ff + jr nz, .submenu_option_selected + ld a, [wTempDeckMachineCursorPos] + jp .please_select_deck + +.submenu_option_selected + ld a, [wCheckMenuCursorYPosition] + sla a + ld hl, wCheckMenuCursorXPosition + add [hl] + or a + jr nz, .asm_bb09 + +; Build a Deck + call SafelySwitchToSRAM1 + call TryBuildDeckMachineDeck + call SafelySwitchToSRAM0 + ld a, [wTempDeckMachineCursorPos] + jp nc, .please_select_deck + ld a, [wTempCardListVisibleOffset] + ld [wCardListVisibleOffset], a + call .InitAutoDeckMenu + ld a, [wTempDeckMachineCursorPos] + jp .please_select_deck + +.asm_bb09 + cp $1 + jr nz, .read_the_instructions +.exit + xor a + ld [wTempBankSRAM], a + ret + +.read_the_instructions +; show card confirmation list + ld a, [wCardListVisibleOffset] + ld [wTempCardListVisibleOffset], a + ld b, a + ld a, [wCurMenuItem] + ld [wTempDeckMachineCursorPos], a + add b + ld c, a + ld [wCurDeck], a + sla c + ld b, $0 + ld hl, wMachineDeckPtrs + add hl, bc + + ; set the description text in text box + push hl + ld hl, wAutoDeckMachineTextDescriptions + add hl, bc + ld bc, wCardConfirmationText + ld a, [hli] + ld [bc], a + inc bc + ld a, [hl] + ld [bc], a + pop hl + + call SafelySwitchToSRAM1 + ld a, [hli] + ld h, [hl] + ld l, a + push hl + ld bc, DECK_NAME_SIZE + add hl, bc + ld d, h + ld e, l + ld a, [hl] + pop hl + call SafelySwitchToSRAM0 + or a + jp z, .wait_input ; invalid deck + + ; show confirmation list + ld a, $1 + call PlaySFXConfirmOrCancel + call SafelySwitchToSRAM1 + xor a + call HandleDeckMissingCardsList + call SafelySwitchToSRAM0 + ld a, [wTempCardListVisibleOffset] + ld [wCardListVisibleOffset], a + call .InitAutoDeckMenu + ld a, [wTempDeckMachineCursorPos] + jp .please_select_deck + +.MenuParameters + db 1, 2 ; cursor x, cursor y + db 2 ; y displacement between items + db 5 ; number of items + db SYM_CURSOR_R ; cursor tile number + db SYM_SPACE ; tile behind cursor + dw NULL ; function pointer if non-0 + +.DeckMachineMenuData + textitem 2, 14, BuildADeckText + textitem 12, 14, CancelText + textitem 2, 16, ReadTheInstructionsText + db $ff + +.DeckMachineTitleTextList + tx FightingMachineText + tx RockMachineText + tx WaterMachineText + tx LightningMachineText + tx GrassMachineText + tx PsychicMachineText + tx ScienceMachineText + tx FireMachineText + tx AutoMachineText + tx LegendaryMachineText + +; clears screen, loads the proper tiles +; prints the Auto Deck title and deck entries +; and creates the auto deck configurations +.InitAutoDeckMenu + call Set_OBJ_8x8 + xor a + ld [wTileMapFill], a + call ZeroObjectPositions + call EmptyScreen + ld a, $01 + ld [wVBlankOAMCopyToggle], a + call LoadSymbolsFont + call LoadDuelCardSymbolTiles + bank1call SetDefaultPalettes + lb de, $3c, $ff + call SetupText + lb de, 0, 0 + lb bc, 20, 13 + call DrawRegularTextBox + lb de, 1, 0 + call InitTextPrinting + ld hl, wDeckMachineTitleText + ld a, [hli] + ld h, [hl] + ld l, a + call ProcessTextFromID + call SafelySwitchToSRAM1 + farcall ReadAutoDeckConfiguration + call .CreateAutoDeckPointerList + call PrintVisibleDeckMachineEntries + call SafelySwitchToSRAM0 + call EnableLCD + ret + +; writes to wMachineDeckPtrs the pointers +; to the Auto Decks in sAutoDecks +.CreateAutoDeckPointerList + ld a, 2 * NUM_DECK_MACHINE_SLOTS + ld hl, wMachineDeckPtrs + call ClearNBytesFromHL + ld de, wMachineDeckPtrs + ld hl, sAutoDecks + ld bc, DECK_STRUCT_SIZE + ld a, NUM_DECK_MACHINE_SLOTS +.loop + push af + ld a, l + ld [de], a + inc de + ld a, h + ld [de], a + inc de + add hl, bc + pop af + dec a + jr nz, .loop + ret + +Func_bc04: + xor a + ld [wCardListVisibleOffset], a + ldtx de, DeckSaveMachineText + ld hl, wDeckMachineTitleText + ld [hl], e + inc hl + ld [hl], d + call ClearScreenAndDrawDeckMachineScreen + ld a, DECK_SIZE + ld [wNumDeckMachineEntries], a + xor a +.asm_bc1a + ld hl, DeckMachineSelectionParams + call InitCardSelectionParams + call DrawListScrollArrows + call PrintNumSavedDecks + ldtx hl, PleaseChooseADeckConfigurationToSendText + call DrawWideTextBox_PrintText + ldtx de, PleaseChooseADeckConfigurationToSendText + call InitDeckMachineDrawingParams +.asm_bc32 + call HandleDeckMachineSelection + jr c, .asm_bc1a + cp $ff + jr nz, .asm_bc3f + ld a, $01 + or a + ret +.asm_bc3f + ld b, a + ld a, [wCardListVisibleOffset] + add b + ld [wSelectedDeckMachineEntry], a + call CheckIfSelectedDeckMachineEntryIsEmpty + jr c, .asm_bc32 + + call GetSelectedSavedDeckPtr + ld l, e + ld h, d + ld de, wDuelTempList + ld b, DECK_STRUCT_SIZE + call EnableSRAM + call CopyNBytesFromHLToDE + call DisableSRAM + + xor a + ld [wNameBuffer], a + bank1call SendDeckConfiguration + ret c + + call GetSelectedSavedDeckPtr + ld l, e + ld h, d + ld de, wDefaultText + call EnableSRAM + call CopyListFromHLToDE + call DisableSRAM + or a + ret + +Func_bc7a: + xor a + ld [wCardListVisibleOffset], a + ldtx de, DeckSaveMachineText + ld hl, wDeckMachineTitleText + ld [hl], e + inc hl + ld [hl], d + call ClearScreenAndDrawDeckMachineScreen + ld a, DECK_SIZE + ld [wNumDeckMachineEntries], a + xor a +.asm_bc90 + ld hl, DeckMachineSelectionParams + call InitCardSelectionParams + call DrawListScrollArrows + call PrintNumSavedDecks + ldtx hl, PleaseChooseASaveSlotText + call DrawWideTextBox_PrintText + ldtx de, PleaseChooseASaveSlotText + call InitDeckMachineDrawingParams + call HandleDeckMachineSelection + jr c, .asm_bc90 + cp $ff + jr nz, .asm_bcb5 + ld a, $01 + or a + ret +.asm_bcb5 + ld b, a + ld a, [wCardListVisibleOffset] + add b + ld [wSelectedDeckMachineEntry], a + call CheckIfSelectedDeckMachineEntryIsEmpty + jr nc, .asm_bcc4 + jr .asm_bcd1 +.asm_bcc4 + ldtx hl, OKIfFileDeletedText + call YesOrNoMenuWithText + jr nc, .asm_bcd1 + ld a, [wCardListCursorPos] + jr .asm_bc90 +.asm_bcd1 + xor a + ld [wDuelTempList], a + ld [wNameBuffer], a + bank1call ReceiveDeckConfiguration + ret c + call EnableSRAM + ld hl, wDuelTempList + call GetSelectedSavedDeckPtr + ld b, DECK_STRUCT_SIZE + call CopyNBytesFromHLToDE + call DisableSRAM + call SaveGame + call ClearScreenAndDrawDeckMachineScreen + ld a, [wCardListCursorPos] + ld hl, DeckMachineSelectionParams + call InitCardSelectionParams + call DrawListScrollArrows + call PrintNumSavedDecks + call DrawListCursor_Visible + ld hl, wNameBuffer + ld de, wDefaultText + call CopyListFromHLToDE + xor a + ld [wTxRam2 + 0], a + ld [wTxRam2 + 1], a + ldtx hl, ReceivedADeckConfigurationFromText + call DrawWideTextBox_WaitForInput + call GetSelectedSavedDeckPtr + ld l, e + ld h, d + ld de, wDefaultText + call EnableSRAM + call CopyListFromHLToDE + call DisableSRAM + xor a + ret diff --git a/src/engine/menus/deck_selection.asm b/src/engine/menus/deck_selection.asm new file mode 100644 index 0000000..83de8d0 --- /dev/null +++ b/src/engine/menus/deck_selection.asm @@ -0,0 +1,546 @@ +INCLUDE "data/glossary_menu_transitions.asm" + +; copies DECK_SIZE number of cards from de to hl in SRAM +CopyDeckFromSRAM: + push bc + call EnableSRAM + ld b, DECK_SIZE +.loop + ld a, [de] + inc de + ld [hli], a + dec b + jr nz, .loop + xor a + ld [hl], a + call DisableSRAM + pop bc + ret + +; clears some WRAM addresses to act as +; terminator bytes to wFilteredCardList and wCurDeckCards +WriteCardListsTerminatorBytes: + xor a + ld hl, wFilteredCardList + ld bc, DECK_SIZE + add hl, bc + ld [hl], a ; wcf16 + ld hl, wCurDeckCards + ld bc, DECK_CONFIG_BUFFER_SIZE + add hl, bc + ld [hl], a ; wCurDeckCardsTerminator + ret + +; inits some SRAM addresses +InitPromotionalCardAndDeckCounterSaveData: + call EnableSRAM + xor a + ld hl, sHasPromotionalCards + ld [hli], a + inc a ; $1 + ld [hli], a ; sb704 + ld [hli], a + ld [hl], a + ld [sUnnamedDeckCounter], a + call DisableSRAM +; ret missing +; unintentional fallthrough + +; loads the Hard Cards icon gfx to v0Tiles2 +LoadHandCardsIcon: + ld hl, HandCardsGfx + ld de, v0Tiles2 + $38 tiles + call CopyListFromHLToDE + ret + +HandCardsGfx: + INCBIN "gfx/hand_cards.2bpp" + db $00 ; end of data + +EmptyScreenAndLoadFontDuelAndHandCardsIcons: + xor a + ld [wTileMapFill], a + call EmptyScreen + call ZeroObjectPositions + ld a, $1 + ld [wVBlankOAMCopyToggle], a + call LoadSymbolsFont + call LoadDuelCardSymbolTiles + call LoadHandCardsIcon + bank1call SetDefaultPalettes + lb de, $3c, $bf + call SetupText + ret + +; empties screen, zeroes object positions, +; loads cursor tile, symbol fonts, duel card symbols +; hand card icon and sets default palettes +Func_8d78: + xor a + ld [wTileMapFill], a + call ZeroObjectPositions + call EmptyScreen + ld a, $1 + ld [wVBlankOAMCopyToggle], a + call LoadCursorTile + call LoadSymbolsFont + call LoadDuelCardSymbolTiles + call LoadHandCardsIcon + bank1call SetDefaultPalettes + lb de, $3c, $bf + call SetupText + ret + +; inits the following deck building params from hl: +; wMaxNumCardsAllowed +; wSameNameCardsLimit +; wIncludeCardsInDeck +; wDeckConfigurationMenuHandlerFunction +; wDeckConfigurationMenuTransitionTable +InitDeckBuildingParams: + ld de, wMaxNumCardsAllowed + ld b, $7 +.loop + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .loop + ret + +DeckBuildingParams: + db DECK_CONFIG_BUFFER_SIZE ; max number of cards + db MAX_NUM_SAME_NAME_CARDS ; max number of same name cards + db TRUE ; whether to include deck cards + dw HandleDeckConfigurationMenu + dw DeckConfigurationMenu_TransitionTable + +DeckSelectionMenu: + ld hl, DeckBuildingParams + call InitDeckBuildingParams + ld a, ALL_DECKS + call DrawDecksScreen + xor a + +.init_menu_params + ld hl, .DeckSelectionMenuParameters + call InitializeMenuParameters + ldtx hl, PleaseSelectDeckText + call DrawWideTextBox_PrintText +.loop_input + call DoFrame + jr c, .init_menu_params ; reinit menu parameters + call HandleStartButtonInDeckSelectionMenu + jr c, .init_menu_params + call HandleMenuInput + jr nc, .loop_input + ldh a, [hCurMenuItem] + cp $ff + ret z ; B btn returns +; A btn pressed on a deck + ld [wCurDeck], a + jp DeckSelectionSubMenu + +.DeckSelectionMenuParameters + db 1, 2 ; cursor x, cursor y + db 3 ; y displacement between items + db 4 ; number of items + db SYM_CURSOR_R ; cursor tile number + db SYM_SPACE ; tile behind cursor + dw NULL ; function pointer if non-0 + +; handles START button press when in deck selection menu +; does nothing if START button isn't pressed +; if a press was handled, returns carry +; prints "There is no deck here!" if the selected deck is empty +HandleStartButtonInDeckSelectionMenu: + ldh a, [hDPadHeld] + and START + ret z ; skip + +; set menu item as current deck + ld a, [wCurMenuItem] + ld [wCurDeck], a + call CheckIfCurDeckIsValid + jp nc, .valid_deck ; can be jr + +; not a valid deck, cancel + ld a, $ff ; cancel + call PlaySFXConfirmOrCancel + call PrintThereIsNoDeckHereText + scf + ret + +.valid_deck + ld a, $1 + call PlaySFXConfirmOrCancel + call GetPointerToDeckCards + push hl + call GetPointerToDeckName + pop de + call OpenDeckConfirmationMenu + ld a, ALL_DECKS + call DrawDecksScreen + ld a, [wCurDeck] + scf + ret + +OpenDeckConfirmationMenu: +; copy deck name + push de + ld de, wCurDeckName + call CopyListFromHLToDEInSRAM + pop de + +; copy deck cards + ld hl, wCurDeckCards + call CopyDeckFromSRAM + + ld a, NUM_FILTERS + ld hl, wCardFilterCounts + call ClearNBytesFromHL + ld a, DECK_SIZE + ld [wTotalCardCount], a + ld hl, wCardFilterCounts + ld [hl], a + call HandleDeckConfirmationMenu + ret + +; handles the submenu when selecting a deck +; (Modify Deck, Select Deck, Change Name and Cancel) +DeckSelectionSubMenu: + call DrawWideTextBox + ld hl, DeckSelectionData + call PlaceTextItems + call ResetCheckMenuCursorPositionAndBlink +.loop_input + call DoFrame + call HandleCheckMenuInput + jp nc, .loop_input + cp $ff + jr nz, .option_selected +; B btn pressed +; erase cursor and go back +; to deck selection handling + call EraseCheckMenuCursor + ld a, [wCurDeck] + jp DeckSelectionMenu.init_menu_params + +.option_selected + ld a, [wCheckMenuCursorXPosition] + or a + jp nz, DeckSelectionSubMenu_SelectOrCancel + ld a, [wCheckMenuCursorYPosition] + or a + jp nz, .ChangeName + +; Modify Deck +; read deck from SRAM +; TODO + call GetPointerToDeckCards + ld e, l + ld d, h + ld hl, wCurDeckCards + call CopyDeckFromSRAM + ld a, 20 + ld hl, wCurDeckName + call ClearNBytesFromHL + ld de, wCurDeckName + call GetPointerToDeckName + call CopyListFromHLToDEInSRAM + + call HandleDeckBuildScreen + jr nc, .asm_8ec4 + call EnableSRAM + ld hl, wCurDeckCards + call DecrementDeckCardsInCollection + call GetPointerToDeckCards + call AddDeckToCollection + ld e, l + ld d, h + ld hl, wCurDeckCards + ld b, DECK_SIZE +.asm_8ea9 + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .asm_8ea9 + call GetPointerToDeckName + ld d, h + ld e, l + ld hl, wCurDeckName + call CopyListFromHLToDE + call GetPointerToDeckName + ld a, [hl] + call DisableSRAM + or a + jr z, .get_input_deck_name +.asm_8ec4 + ld a, ALL_DECKS + call DrawDecksScreen + ld a, [wCurDeck] + jp DeckSelectionMenu.init_menu_params + +.ChangeName + call CheckIfCurDeckIsValid + jp nc, .get_input_deck_name + call PrintThereIsNoDeckHereText + jp DeckSelectionMenu.init_menu_params +.get_input_deck_name + ld a, 20 + ld hl, wCurDeckName + call ClearNBytesFromHL + ld de, wCurDeckName + call GetPointerToDeckName + call CopyListFromHLToDEInSRAM + call InputCurDeckName + call GetPointerToDeckName + ld d, h + ld e, l + ld hl, wCurDeckName + call CopyListFromHLToDEInSRAM + ld a, ALL_DECKS + call DrawDecksScreen + ld a, [wCurDeck] + jp DeckSelectionMenu.init_menu_params + +; gets current deck's name from user input +InputCurDeckName: + ld a, [wCurDeck] + or a + jr nz, .deck_2 + ld hl, Deck1Data + jr .got_deck_ptr +.deck_2 + dec a + jr nz, .deck_3 + ld hl, Deck2Data + jr .got_deck_ptr +.deck_3 + dec a + jr nz, .deck_4 + ld hl, Deck3Data + jr .got_deck_ptr +.deck_4 + ld hl, Deck4Data +.got_deck_ptr + ld a, MAX_DECK_NAME_LENGTH + lb bc, 4, 1 + ld de, wCurDeckName + farcall InputDeckName + ld a, [wCurDeckName] + or a + ret nz + ; empty name + call .UnnamedDeck + ret + +; handles the naming of unnamed decks +; inputs as the deck name "DECK XXX" +; where XXX is the current unnamed deck counter +.UnnamedDeck +; read the current unnamed deck number +; and convert it to text + ld hl, sUnnamedDeckCounter + call EnableSRAM + ld a, [hli] + ld h, [hl] + call DisableSRAM + ld l, a + ld de, wDefaultText + call TwoByteNumberToText + + ld hl, wCurDeckName + ld [hl], $6 + inc hl + ld [hl], "D" + inc hl + ld [hl], "e" + inc hl + ld [hl], "c" + inc hl + ld [hl], "k" + inc hl + ld [hl], " " + inc hl + ld de, wDefaultText + 2 + ld a, [de] + inc de + ld [hli], a + ld a, [de] + inc de + ld [hli], a + ld a, [de] + ld [hli], a + xor a + ld [hl], a + +; increment the unnamed deck counter + ld hl, sUnnamedDeckCounter + call EnableSRAM + ld e, [hl] + inc hl + ld d, [hl] +; capped at 999 + ld a, HIGH(MAX_UNNAMED_DECK_NUM) + cp d + jr nz, .incr_counter + ld a, LOW(MAX_UNNAMED_DECK_NUM) + cp e + jr nz, .incr_counter + ; reset counter + ld de, 0 +.incr_counter + inc de + ld [hl], d + dec hl + ld [hl], e + call DisableSRAM + ret + +; handle deck selection sub-menu +; the option is either "Select Deck" or "Cancel" +; depending on the cursor Y pos +DeckSelectionSubMenu_SelectOrCancel: + ld a, [wCheckMenuCursorYPosition] + or a + jp nz, CancelDeckSelectionSubMenu + +; select deck + call CheckIfCurDeckIsValid + jp nc, .SelectDeck + ; invalid deck + call PrintThereIsNoDeckHereText + jp DeckSelectionMenu.init_menu_params + +.SelectDeck + call EnableSRAM + ld a, [sCurrentlySelectedDeck] + call DisableSRAM + +; draw empty rectangle on currently selected deck +; i.e. erase the Hand Cards Gfx icon + ld h, $3 + ld l, a + call HtimesL + ld e, l + inc e + ld d, 2 + xor a + lb hl, 0, 0 + lb bc, 2, 2 + call FillRectangle + +; set current deck as the selected deck +; and draw the Hand Cards Gfx icon + ld a, [wCurDeck] + call EnableSRAM + ld [sCurrentlySelectedDeck], a + call DisableSRAM + call DrawHandCardsTileOnCurDeck + +; print "<DECK> was chosen as the dueling deck!" + call GetPointerToDeckName + call EnableSRAM + call CopyDeckName + call DisableSRAM + xor a + ld [wTxRam2], a + ld [wTxRam2 + 1], a + ldtx hl, ChosenAsDuelingDeckText + call DrawWideTextBox_WaitForInput + ld a, [wCurDeck] + jp DeckSelectionMenu.init_menu_params + +PrintThereIsNoDeckHereText: + ldtx hl, ThereIsNoDeckHereText + call DrawWideTextBox_WaitForInput + ld a, [wCurDeck] + ret + +; returns carry if deck in wCurDeck +; is not a valid deck +CheckIfCurDeckIsValid: + ld a, [wCurDeck] + ld hl, wDecksValid + ld b, $0 + ld c, a + add hl, bc + ld a, [hl] + or a + ret nz ; is valid + scf + ret ; is not valid + +; write to $d00a the decimal representation (number characters) +; of the value in hl +; unreferenced? +Func_9001: + ld de, $d00a + ld bc, -100 + call .GetNumberChar + ld bc, -10 + call .GetNumberChar + ld bc, -1 + call .GetNumberChar + ret + +.GetNumberChar + ld a, SYM_0 - 1 +.loop + inc a + add hl, bc + jr c, .loop + ld [de], a + inc de + ld a, l + sub c + ld l, a + ld a, h + sbc b + ld h, a + ret + +CancelDeckSelectionSubMenu: + ret + +DeckSelectionData: + textitem 2, 14, ModifyDeckText + textitem 12, 14, SelectDeckText + textitem 2, 16, ChangeNameText + textitem 12, 16, CancelText + db $ff + +; return, in hl, the pointer to sDeckXName where X is [wCurDeck] + 1 +GetPointerToDeckName: + ld a, [wCurDeck] + ld h, a + ld l, DECK_STRUCT_SIZE + call HtimesL + push de + ld de, sDeck1Name + add hl, de + pop de + ret + +; return, in hl, the pointer to sDeckXCards where X is [wCurDeck] + 1 +GetPointerToDeckCards: + push af + ld a, [wCurDeck] + ld h, a + ld l, sDeck2Cards - sDeck1Cards + call HtimesL + push de + ld de, sDeck1Cards + add hl, de + pop de + pop af + ret + +ResetCheckMenuCursorPositionAndBlink: + xor a + ld [wCheckMenuCursorXPosition], a + ld [wCheckMenuCursorYPosition], a + ld [wCheckMenuCursorBlinkCounter], a + ret diff --git a/src/engine/menus/duel.asm b/src/engine/menus/duel.asm new file mode 100644 index 0000000..672bd73 --- /dev/null +++ b/src/engine/menus/duel.asm @@ -0,0 +1,2180 @@ +_OpenDuelCheckMenu: + call ResetCheckMenuCursorPositionAndBlink + xor a + ld [wce5e], a + call DrawWideTextBox + +; reset cursor blink + xor a + ld [wCheckMenuCursorBlinkCounter], a + ld hl, CheckMenuData + call PlaceTextItems +.loop + call DoFrame + call HandleCheckMenuInput + jr nc, .loop + cp $ff + ret z ; B pressed + +; A was pressed + ld a, [wCheckMenuCursorYPosition] + sla a + ld b, a + ld a, [wCheckMenuCursorXPosition] + add b + ld hl, .jump_table + call JumpToFunctionInTable + jr _OpenDuelCheckMenu + +.jump_table + dw DuelCheckMenu_InPlayArea + dw DuelCheckMenu_Glossary + dw DuelCheckMenu_YourPlayArea + dw DuelCheckMenu_OppPlayArea + +; opens the In Play Area submenu +DuelCheckMenu_InPlayArea: + xor a + ld [wInPlayAreaFromSelectButton], a + farcall OpenInPlayAreaScreen + ret + +; opens the Glossary submenu +DuelCheckMenu_Glossary: + farcall OpenGlossaryScreen + ret + +; opens the Your Play Area submenu +DuelCheckMenu_YourPlayArea: + call ResetCheckMenuCursorPositionAndBlink + xor a + ld [wce5e], a + ldh a, [hWhoseTurn] +.draw + ld h, a + ld l, a + call DrawYourOrOppPlayAreaScreen + + ld a, [wCheckMenuCursorYPosition] + sla a + ld b, a + ld a, [wCheckMenuCursorXPosition] + add b + ld [wYourOrOppPlayAreaLastCursorPosition], a + ld b, $f8 ; black arrow tile + call DrawYourOrOppPlayArea_DrawArrows + + call DrawWideTextBox + +; reset cursor blink + xor a + ld [wCheckMenuCursorBlinkCounter], a + ld hl, YourPlayAreaMenuData + call PlaceTextItems + +.loop + call DoFrame + xor a + call DrawYourOrOppPlayArea_RefreshArrows + call HandleCheckMenuInput_YourOrOppPlayArea + jr nc, .loop + + call DrawYourOrOppPlayArea_EraseArrows + cp $ff + ret z + + ld a, [wCheckMenuCursorYPosition] + sla a + ld b, a + ld a, [wCheckMenuCursorXPosition] + add b + ld hl, .jump_table + call JumpToFunctionInTable + jr .draw + +.jump_table + dw OpenYourOrOppPlayAreaScreen_TurnHolderPlayArea + dw OpenYourOrOppPlayAreaScreen_TurnHolderHand + dw OpenYourOrOppPlayAreaScreen_TurnHolderDiscardPile + +OpenYourOrOppPlayAreaScreen_TurnHolderPlayArea: + ldh a, [hWhoseTurn] + push af + bank1call OpenTurnHolderPlayAreaScreen + pop af + ldh [hWhoseTurn], a + ret + +OpenYourOrOppPlayAreaScreen_NonTurnHolderPlayArea: + ldh a, [hWhoseTurn] + push af + bank1call OpenNonTurnHolderPlayAreaScreen + pop af + ldh [hWhoseTurn], a + ret + +OpenYourOrOppPlayAreaScreen_TurnHolderHand: + ldh a, [hWhoseTurn] + push af + bank1call OpenTurnHolderHandScreen_Simple + pop af + ldh [hWhoseTurn], a + ret + +OpenYourOrOppPlayAreaScreen_NonTurnHolderHand: + ldh a, [hWhoseTurn] + push af + bank1call OpenNonTurnHolderHandScreen_Simple + pop af + ldh [hWhoseTurn], a + ret + +OpenYourOrOppPlayAreaScreen_TurnHolderDiscardPile: + ldh a, [hWhoseTurn] + push af + bank1call OpenTurnHolderDiscardPileScreen + pop af + ldh [hWhoseTurn], a + ret + +OpenYourOrOppPlayAreaScreen_NonTurnHolderDiscardPile: + ldh a, [hWhoseTurn] + push af + bank1call OpenNonTurnHolderDiscardPileScreen + pop af + ldh [hWhoseTurn], a + ret + +; opens the Opp. Play Area submenu +; if clairvoyance is active, add the option to check +; opponent's hand +DuelCheckMenu_OppPlayArea: + call ResetCheckMenuCursorPositionAndBlink + call IsClairvoyanceActive + jr c, .clairvoyance1 + + ld a, %10000000 + ld [wce5e], a + jr .begin +.clairvoyance1 + xor a + ld [wce5e], a + +.begin + ldh a, [hWhoseTurn] +.turns + ld l, a + cp PLAYER_TURN + jr nz, .opponent + ld a, OPPONENT_TURN + ld h, a + jr .cursor +.opponent + ld a, PLAYER_TURN + ld h, a + +.cursor + call DrawYourOrOppPlayAreaScreen + +; convert cursor position and +; store it in wYourOrOppPlayAreaLastCursorPosition + ld a, [wCheckMenuCursorYPosition] + sla a + ld b, a + ld a, [wCheckMenuCursorXPosition] + add b + add 3 + ld [wYourOrOppPlayAreaLastCursorPosition], a + +; draw black arrows in the Play Area + ld b, $f8 ; black arrow tile + call DrawYourOrOppPlayArea_DrawArrows + call DrawWideTextBox + +; reset cursor blink + xor a + ld [wCheckMenuCursorBlinkCounter], a + +; place text items depending on clairvoyance +; when active, allows to look at opp. hand + call IsClairvoyanceActive + jr c, .clairvoyance2 + ld hl, OppPlayAreaMenuData + call PlaceTextItems + jr .loop +.clairvoyance2 + ld hl, OppPlayAreaMenuData_WithClairvoyance + call PlaceTextItems + +; handle input +.loop + call DoFrame + ld a, 1 + call DrawYourOrOppPlayArea_RefreshArrows + call HandleCheckMenuInput_YourOrOppPlayArea + jr nc, .loop + call DrawYourOrOppPlayArea_EraseArrows + cp $ff + ret z ; B was pressed + +; A was pressed +; jump to function corresponding to cursor position + ld a, [wCheckMenuCursorYPosition] + sla a + ld b, a + ld a, [wCheckMenuCursorXPosition] + add b + ld hl, .jump_table + call JumpToFunctionInTable + jr .turns + +.jump_table + dw OpenYourOrOppPlayAreaScreen_NonTurnHolderPlayArea + dw OpenYourOrOppPlayAreaScreen_NonTurnHolderHand + dw OpenYourOrOppPlayAreaScreen_NonTurnHolderDiscardPile + +CheckMenuData: + textitem 2, 14, InPlayAreaText + textitem 2, 16, YourPlayAreaText + textitem 12, 14, GlossaryText + textitem 12, 16, OppPlayAreaText + db $ff + +YourPlayAreaMenuData: + textitem 2, 14, YourPokemonText + textitem 12, 14, YourHandText + textitem 2, 16, YourDiscardPileText2 + db $ff + +OppPlayAreaMenuData: + textitem 2, 14, OpponentsPokemonText + textitem 2, 16, OpponentsDiscardPileText2 + db $ff + +OppPlayAreaMenuData_WithClairvoyance: + textitem 2, 14, OpponentsPokemonText + textitem 12, 14, OpponentsHandText + textitem 2, 16, OpponentsDiscardPileText2 + db $ff + +; checks if arrows need to be erased in Your Play Area or Opp. Play Area +; and draws new arrows upon cursor position change +; input: +; a = an initial offset applied to the cursor position (used to adjust +; for the different layouts of the Your Play Area and Opp. Play Area screens) +DrawYourOrOppPlayArea_RefreshArrows: + push af + ld b, a + add b + add b + ld c, a + ld a, [wCheckMenuCursorYPosition] + sla a + ld b, a + ld a, [wCheckMenuCursorXPosition] + add b + add c +; a = 2 * cursor ycoord + cursor xcoord + 3*a + +; if cursor position is different than +; last position, then update arrows + ld hl, wYourOrOppPlayAreaLastCursorPosition + cp [hl] + jr z, .unchanged + +; erase and draw arrows + call DrawYourOrOppPlayArea_EraseArrows + ld [wYourOrOppPlayAreaLastCursorPosition], a + ld b, $f8 ; black arrow tile byte + call DrawYourOrOppPlayArea_DrawArrows + +.unchanged + pop af + ret + +; write SYM_SPACE to positions tabulated in +; YourOrOppPlayAreaArrowPositions, with offset calculated from the +; cursor x and y positions in [wYourOrOppPlayAreaLastCursorPosition] +; input: +; [wYourOrOppPlayAreaLastCursorPosition]: cursor position (2*y + x) +DrawYourOrOppPlayArea_EraseArrows: + push af + ld a, [wYourOrOppPlayAreaLastCursorPosition] + ld b, SYM_SPACE ; white tile + call DrawYourOrOppPlayArea_DrawArrows + pop af + ret + +; writes tile in b to positions tabulated in +; YourOrOppPlayAreaArrowPositions, with offset calculated from the +; cursor x and y positions in a +; input: +; a = cursor position (2*y + x) +; b = byte to draw +DrawYourOrOppPlayArea_DrawArrows: + push bc + ld hl, YourOrOppPlayAreaArrowPositions + sla a + ld c, a + ld b, $00 + add hl, bc +; hl points to YourOrOppPlayAreaArrowPositions +; plus offset corresponding to a + +; load hl with draw position pointer + ld a, [hli] + ld h, [hl] + ld l, a + pop de + +.loop + ld a, [hli] + cp $ff + jr z, .done + ld b, a + ld a, [hli] + ld c, a + ld a, d + call WriteByteToBGMap0 + jr .loop +.done + ret + +YourOrOppPlayAreaArrowPositions: + dw YourOrOppPlayAreaArrowPositions_PlayerPokemon + dw YourOrOppPlayAreaArrowPositions_PlayerHand + dw YourOrOppPlayAreaArrowPositions_PlayerDiscardPile + dw YourOrOppPlayAreaArrowPositions_OpponentPokemon + dw YourOrOppPlayAreaArrowPositions_OpponentHand + dw YourOrOppPlayAreaArrowPositions_OpponentDiscardPile + +YourOrOppPlayAreaArrowPositions_PlayerPokemon: +; x and y coordinates to draw byte + db 5, 5 + db 0, 10 + db 4, 10 + db 8, 10 + db 12, 10 + db 16, 10 + db $ff + +YourOrOppPlayAreaArrowPositions_PlayerHand: + db 14, 7 + db $ff + +YourOrOppPlayAreaArrowPositions_PlayerDiscardPile: + db 14, 5 + db $ff + +YourOrOppPlayAreaArrowPositions_OpponentPokemon: + db 5, 7 + db 0, 3 + db 4, 3 + db 8, 3 + db 12, 3 + db 16, 3 + db $ff + +YourOrOppPlayAreaArrowPositions_OpponentHand: + db 0, 5 + db $ff + +YourOrOppPlayAreaArrowPositions_OpponentDiscardPile: + db 0, 8 + db $ff + +; loads tiles and icons to display Your Play Area / Opp. Play Area screen, +; and draws the screen according to the turn player +; input: h -> [wCheckMenuPlayAreaWhichDuelist] and l -> [wCheckMenuPlayAreaWhichLayout] +DrawYourOrOppPlayAreaScreen: +; loads the turn holders + ld a, h + ld [wCheckMenuPlayAreaWhichDuelist], a + ld a, l + ld [wCheckMenuPlayAreaWhichLayout], a +; fallthrough + +; loads tiles and icons to display Your Play Area / Opp. Play Area screen, +; and draws the screen according to the turn player +; input: [wCheckMenuPlayAreaWhichDuelist] and [wCheckMenuPlayAreaWhichLayout] +_DrawYourOrOppPlayAreaScreen: + xor a + ld [wTileMapFill], a + call ZeroObjectPositions + + ld a, $01 + ld [wVBlankOAMCopyToggle], a + + call DoFrame + call EmptyScreen + call Set_OBJ_8x8 + call LoadCursorTile + call LoadSymbolsFont + call LoadDeckAndDiscardPileIcons + + ld a, [wCheckMenuPlayAreaWhichDuelist] + cp PLAYER_TURN + jr nz, .opp_turn1 + +; print <RAMNAME>'s Play Area + ld de, wDefaultText + call CopyPlayerName + jr .get_text_length +.opp_turn1 + ld de, wDefaultText + call CopyOpponentName +.get_text_length + ld hl, wDefaultText + + call GetTextLengthInTiles + ld a, 6 ; max name size in tiles + sub b + srl a + add 4 +; a = (6 - name text in tiles) / 2 + 4 + ld d, a ; text horizontal alignment + + ld e, 0 + call InitTextPrinting + ldtx hl, DuelistsPlayAreaText + ldh a, [hWhoseTurn] + cp PLAYER_TURN + jr nz, .opp_turn2 + ld a, [wCheckMenuPlayAreaWhichDuelist] + cp PLAYER_TURN + jr nz, .swap +.opp_turn2 + call PrintTextNoDelay + jr .draw +.swap + call SwapTurn + call PrintTextNoDelay + call SwapTurn + +.draw + ld a, [wCheckMenuPlayAreaWhichDuelist] + ld b, a + ld a, [wCheckMenuPlayAreaWhichLayout] + cp b + jr nz, .not_equal + + ld hl, PrizeCardsCoordinateData_YourOrOppPlayArea.player + call DrawPlayArea_PrizeCards + lb de, 6, 2 ; coordinates of player's active card + call DrawYourOrOppPlayArea_ActiveCardGfx + lb de, 1, 9 ; coordinates of player's bench cards + ld c, 4 ; spacing + call DrawPlayArea_BenchCards + xor a + call DrawYourOrOppPlayArea_Icons + jr .done + +.not_equal + ld hl, PrizeCardsCoordinateData_YourOrOppPlayArea.opponent + call DrawPlayArea_PrizeCards + lb de, 6, 5 ; coordinates of opponent's active card + call DrawYourOrOppPlayArea_ActiveCardGfx + lb de, 1, 2 ; coordinates of opponent's bench cards + ld c, 4 ; spacing + call DrawPlayArea_BenchCards + ld a, $01 + call DrawYourOrOppPlayArea_Icons + +.done + call EnableLCD + ret + +Func_82b6: + ld a, [wCheckMenuPlayAreaWhichDuelist] + ld b, a + ld a, [wCheckMenuPlayAreaWhichLayout] + cp b + jr nz, .not_equal + + ld hl, PrizeCardsCoordinateData_YourOrOppPlayArea.player + call DrawPlayArea_PrizeCards + ret + +.not_equal + ld hl, PrizeCardsCoordinateData_YourOrOppPlayArea.opponent + call DrawPlayArea_PrizeCards + ret + +; loads tiles and icons to display the In Play Area screen, +; and draws the screen +DrawInPlayAreaScreen: + xor a + ld [wTileMapFill], a + call ZeroObjectPositions + + ld a, $01 + ld [wVBlankOAMCopyToggle], a + call DoFrame + call EmptyScreen + + ld a, CHECK_PLAY_AREA + ld [wDuelDisplayedScreen], a + call Set_OBJ_8x8 + call LoadCursorTile + call LoadSymbolsFont + call LoadDeckAndDiscardPileIcons + + lb de, $80, $9f + call SetupText + +; reset turn holders + ldh a, [hWhoseTurn] + ld [wCheckMenuPlayAreaWhichDuelist], a + ld [wCheckMenuPlayAreaWhichLayout], a + +; player prize cards + ld hl, PrizeCardsCoordinateData_InPlayArea.player + call DrawPlayArea_PrizeCards + +; player bench cards + lb de, 3, 15 + ld c, 3 + call DrawPlayArea_BenchCards + + ld hl, PlayAreaIconCoordinates.player2 + call DrawInPlayArea_Icons + + call SwapTurn + ldh a, [hWhoseTurn] + ld [wCheckMenuPlayAreaWhichDuelist], a + call SwapTurn + +; opponent prize cards + ld hl, PrizeCardsCoordinateData_InPlayArea.opponent + call DrawPlayArea_PrizeCards + +; opponent bench cards + lb de, 3, 0 + ld c, 3 + call DrawPlayArea_BenchCards + + call SwapTurn + ld hl, PlayAreaIconCoordinates.opponent2 + call DrawInPlayArea_Icons + + call SwapTurn + call DrawInPlayArea_ActiveCardGfx + ret + +; draws players prize cards and bench cards +_DrawPlayersPrizeAndBenchCards: + xor a + ld [wTileMapFill], a + call ZeroObjectPositions + ld a, $01 + ld [wVBlankOAMCopyToggle], a + call DoFrame + call EmptyScreen + call LoadSymbolsFont + call LoadDeckAndDiscardPileIcons + +; player cards + ld a, PLAYER_TURN + ld [wCheckMenuPlayAreaWhichDuelist], a + ld [wCheckMenuPlayAreaWhichLayout], a + ld hl, PrizeCardsCoordinateData_2.player + call DrawPlayArea_PrizeCards + lb de, 5, 10 ; coordinates + ld c, 3 ; spacing + call DrawPlayArea_BenchCards + +; opponent cards + ld a, OPPONENT_TURN + ld [wCheckMenuPlayAreaWhichDuelist], a + ld hl, PrizeCardsCoordinateData_2.opponent + call DrawPlayArea_PrizeCards + lb de, 1, 0 ; coordinates + ld c, 3 ; spacing + call DrawPlayArea_BenchCards + ret + +; draws the active card gfx at coordinates de +; of the player (or opponent) depending on wCheckMenuPlayAreaWhichDuelist +; input: +; de = coordinates +DrawYourOrOppPlayArea_ActiveCardGfx: + push de + ld a, DUELVARS_ARENA_CARD + ld l, a + ld a, [wCheckMenuPlayAreaWhichDuelist] + ld h, a + ld a, [hl] + cp -1 + jr z, .no_pokemon + + ld d, a + ld a, [wCheckMenuPlayAreaWhichDuelist] + ld b, a + ldh a, [hWhoseTurn] + cp b + jr nz, .swap + ld a, d + call LoadCardDataToBuffer1_FromDeckIndex + jr .draw +.swap + call SwapTurn + ld a, d + call LoadCardDataToBuffer1_FromDeckIndex + call SwapTurn + +.draw + ld de, v0Tiles1 + $20 tiles ; destination offset of loaded gfx + ld hl, wLoadedCard1Gfx + ld a, [hli] + ld h, [hl] + ld l, a + lb bc, $30, TILE_SIZE + call LoadCardGfx + bank1call SetBGP6OrSGB3ToCardPalette + bank1call FlushAllPalettesOrSendPal23Packet + pop de + +; draw card gfx + ld a, $a0 + lb hl, 6, 1 + lb bc, 8, 6 + call FillRectangle + bank1call ApplyBGP6OrSGB3ToCardImage + ret + +.no_pokemon + pop de + ret + +; draws player and opponent arena card graphics +; in the "In Play Area" screen +DrawInPlayArea_ActiveCardGfx: + xor a + ld [wArenaCardsInPlayArea], a + + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + cp -1 ; no pokemon + jr z, .opponent1 + + push af + ld a, [wArenaCardsInPlayArea] + or %00000001 ; set the player arena Pokemon bit + ld [wArenaCardsInPlayArea], a + pop af + +; load card gfx + call LoadCardDataToBuffer1_FromDeckIndex + lb de, $8a, $00 + ld hl, wLoadedCard1Gfx + ld a, [hli] + ld h, [hl] + ld l, a + lb bc, $30, TILE_SIZE + call LoadCardGfx + bank1call SetBGP6OrSGB3ToCardPalette + +.opponent1 + ld a, DUELVARS_ARENA_CARD + call GetNonTurnDuelistVariable + cp -1 ; no pokemon + jr z, .draw + + push af + ld a, [wArenaCardsInPlayArea] + or %00000010 ; set the opponent arena Pokemon bit + ld [wArenaCardsInPlayArea], a + pop af + +; load card gfx + call SwapTurn + call LoadCardDataToBuffer1_FromDeckIndex + lb de, $95, $00 + ld hl, wLoadedCard1Gfx + ld a, [hli] + ld h, [hl] + ld l, a + lb bc, $30, TILE_SIZE + call LoadCardGfx + bank1call SetBGP7OrSGB2ToCardPalette + call SwapTurn + +.draw + ld a, [wArenaCardsInPlayArea] + or a + ret z ; no arena cards in play + + bank1call FlushAllPalettesOrSendPal23Packet + ld a, [wArenaCardsInPlayArea] + and %00000001 ; test player arena card bit + jr z, .opponent2 + +; draw player arena card + ld a, $a0 + lb de, 6, 9 + lb hl, 6, 1 + lb bc, 8, 6 + call FillRectangle + bank1call ApplyBGP6OrSGB3ToCardImage + +.opponent2 + ld a, [wArenaCardsInPlayArea] + and %00000010 ; test opponent arena card bit + ret z + +; draw opponent arena card + call SwapTurn + ld a, $50 + lb de, 6, 2 + lb hl, 6, 1 + lb bc, 8, 6 + call FillRectangle + bank1call ApplyBGP7OrSGB2ToCardImage + call SwapTurn + ret + +; draws prize cards depending on the turn +; loaded in wCheckMenuPlayAreaWhichDuelist +; input: +; hl = pointer to coordinates +DrawPlayArea_PrizeCards: + push hl + call GetDuelInitialPrizesUpperBitsSet + ld a, [wCheckMenuPlayAreaWhichDuelist] + ld h, a + ld l, DUELVARS_PRIZES + ld a, [hl] + + pop hl + ld b, 0 + push af +; loop each prize card +.loop + inc b + ld a, [wDuelInitialPrizes] + inc a + cp b + jr z, .done + + pop af + srl a ; right shift prize cards left + push af + jr c, .not_taken + ld a, $e0 ; tile byte for empty slot + jr .draw +.not_taken + ld a, $dc ; tile byte for card +.draw + ld e, [hl] + inc hl + ld d, [hl] + inc hl + + push hl + push bc + lb hl, $01, $02 ; card tile gfx + lb bc, 2, 2 ; rectangle size + call FillRectangle + + ld a, [wConsole] + cp CONSOLE_CGB + jr nz, .not_cgb + ld a, $02 ; blue colour + lb bc, 2, 2 + lb hl, 0, 0 + call BankswitchVRAM1 + call FillRectangle + call BankswitchVRAM0 +.not_cgb + pop bc + pop hl + jr .loop +.done + pop af + ret + +PrizeCardsCoordinateData_YourOrOppPlayArea: +; x and y coordinates for player prize cards +.player + db 2, 1 + db 2, 3 + db 4, 1 + db 4, 3 + db 6, 1 + db 6, 3 +; x and y coordinates for opponent prize cards +.opponent + db 9, 17 + db 9, 15 + db 7, 17 + db 7, 15 + db 5, 17 + db 5, 15 + +; used by Func_833c +PrizeCardsCoordinateData_2: +; x and y coordinates for player prize cards +.player + db 6, 0 + db 6, 2 + db 8, 0 + db 8, 2 + db 10, 0 + db 10, 2 +; x and y coordinates for opponent prize cards +.opponent + db 4, 18 + db 4, 16 + db 2, 18 + db 2, 16 + db 0, 18 + db 0, 16 + +PrizeCardsCoordinateData_InPlayArea: +; x and y coordinates for player prize cards +.player + db 9, 1 + db 9, 3 + db 11, 1 + db 11, 3 + db 13, 1 + db 13, 3 +; x and y coordinates for opponent prize cards +.opponent + db 6, 17 + db 6, 15 + db 4, 17 + db 4, 15 + db 2, 17 + db 2, 15 + +; calculates bits set up to the number of initial prizes, with upper 2 bits set, i.e: +; 6 prizes: a = %11111111 +; 4 prizes: a = %11001111 +; 3 prizes: a = %11000111 +; 2 prizes: a = %11000011 +GetDuelInitialPrizesUpperBitsSet: + ld a, [wDuelInitialPrizes] + ld b, $01 +.loop + or a + jr z, .done + sla b + dec a + jr .loop +.done + dec b + ld a, b + or %11000000 + ld [wDuelInitialPrizesUpperBitsSet], a + ret + +; draws filled and empty bench slots depending on the turn loaded in wCheckMenuPlayAreaWhichDuelist +; if wCheckMenuPlayAreaWhichDuelist is different from wCheckMenuPlayAreaWhichLayout adjusts coordinates of the bench slots +; input: +; de = coordinates to draw bench +; c = spacing between slots +DrawPlayArea_BenchCards: + ld a, [wCheckMenuPlayAreaWhichLayout] + ld b, a + ld a, [wCheckMenuPlayAreaWhichDuelist] + cp b + jr z, .skip + +; adjust the starting bench position for opponent + ld a, d + add c + add c + add c + add c + ld d, a + ; d = d + 4 * c + +; have the spacing go to the left instead of right + xor a + sub c + ld c, a + ; c = $ff - c + 1 + + ld a, [wCheckMenuPlayAreaWhichDuelist] +.skip + ld h, a + ld l, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + ld b, [hl] + ld l, DUELVARS_BENCH1_CARD_STAGE +.loop_1 + dec b ; num of Bench Pokemon left + jr z, .done + + ld a, [hli] + push hl + push bc + sla a + sla a + add $e4 +; a holds the correct stage gfx tile + ld b, a + push bc + + lb hl, 1, 2 + lb bc, 2, 2 + call FillRectangle + + ld a, [wConsole] + cp CONSOLE_CGB + pop bc + jr nz, .next + + ld a, b + cp $ec ; tile offset of 2 stage + jr z, .two_stage + cp $f0 ; tile offset of 2 stage with no 1 stage + jr z, .two_stage + + ld a, $02 ; blue colour + jr .palette +.two_stage + ld a, $01 ; red colour +.palette + lb bc, 2, 2 + lb hl, 0, 0 + call BankswitchVRAM1 + call FillRectangle + call BankswitchVRAM0 + +.next ; adjust coordinates for next card + pop bc + pop hl + ld a, d + add c + ld d, a + ; d = d + c + jr .loop_1 + +.done + ld a, [wCheckMenuPlayAreaWhichDuelist] + ld h, a + ld l, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + ld b, [hl] + ld a, MAX_PLAY_AREA_POKEMON + sub b + ret z ; return if already full + + ld b, a + inc b +.loop_2 + dec b + ret z + + push bc + ld a, $f4 ; empty bench slot tile + lb hl, 1, 2 + lb bc, 2, 2 + call FillRectangle + + ld a, [wConsole] + cp CONSOLE_CGB + jr nz, .not_cgb + + ld a, $02 ; colour + lb bc, 2, 2 + lb hl, 0, 0 + call BankswitchVRAM1 + call FillRectangle + call BankswitchVRAM0 + +.not_cgb + pop bc + ld a, d + add c + ld d, a + jr .loop_2 + +; draws Your/Opp Play Area icons depending on value in a +; the icons correspond to Deck, Discard Pile, and Hand +; the corresponding number of cards is printed alongside each icon +; for "Hand", text is displayed rather than an icon +; input: +; a = $00: draws player icons +; a = $01: draws opponent icons +DrawYourOrOppPlayArea_Icons: + or a + jr nz, .opponent + ld hl, PlayAreaIconCoordinates.player1 + jr .draw +.opponent + ld hl, PlayAreaIconCoordinates.opponent1 + +.draw +; hand icon and value + ld a, [wCheckMenuPlayAreaWhichDuelist] + ld d, a + ld e, DUELVARS_NUMBER_OF_CARDS_IN_HAND + ld a, [de] + ld b, a + ld a, $d0 ; hand icon, unused? + call DrawPlayArea_HandText + +; deck icon and value + ld a, [wCheckMenuPlayAreaWhichDuelist] + ld d, a + ld e, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK + ld a, [de] + ld b, a + ld a, DECK_SIZE + sub b + ld b, a + ld a, $d4 ; deck icon + call DrawPlayArea_IconWithValue + +; discard pile icon and value + ld a, [wCheckMenuPlayAreaWhichDuelist] + ld d, a + ld e, DUELVARS_NUMBER_OF_CARDS_IN_DISCARD_PILE + ld a, [de] + ld b, a + ld a, $d8 ; discard pile icon + call DrawPlayArea_IconWithValue + ret + +; draws the interface icon corresponding to the gfx tile in a +; also prints the number in decimal corresponding to the value in b +; the coordinates in screen are given by [hl] +; input: +; a = tile for the icon +; b = value to print alongside icon +; hl = pointer to coordinates +DrawPlayArea_IconWithValue: +; drawing the icon + ld d, [hl] + inc hl + ld e, [hl] + inc hl + push hl + push bc + lb hl, 1, 2 + lb bc, 2, 2 + call FillRectangle + + ld a, [wConsole] + cp CONSOLE_CGB + jr nz, .skip + + ld a, $02 + lb bc, 2, 2 + lb hl, 0, 0 + call BankswitchVRAM1 + call FillRectangle + call BankswitchVRAM0 + +.skip +; adjust coordinate to the lower right + inc d + inc d + inc e + call InitTextPrinting + pop bc + ld a, b + call CalculateOnesAndTensDigits + + ld hl, wOnesAndTensPlace + ld a, [hli] + ld b, a + ld a, [hl] + +; loading numerical and cross symbols + ld hl, wDefaultText + ld [hl], TX_SYMBOL + inc hl + ld [hl], SYM_CROSS + inc hl + ld [hl], TX_SYMBOL + inc hl + ld [hli], a ; tens place + ld [hl], TX_SYMBOL + inc hl + ld a, b + ld [hli], a ; ones place + ld [hl], TX_END + +; printing the decimal value + ld hl, wDefaultText + call ProcessText + pop hl + ret + +PlayAreaIconCoordinates: +; used for "Your/Opp. Play Area" screen +.player1 + db 15, 7 ; hand + db 15, 2 ; deck + db 15, 4 ; discard pile +.opponent1 + db 1, 5 ; hand + db 1, 9 ; deck + db 1, 7 ; discard pile + +; used for "In Play Area" screen +.player2 + db 15, 14 + db 15, 9 + db 15, 11 +.opponent2 + db 0, 2 + db 0, 6 + db 0, 4 + +; draws In Play Area icons depending on value in a +; the icons correspond to Deck, Discard Pile, and Hand +; the corresponding number of cards is printed alongside each icon +; for "Hand", text is displayed rather than an icon +; input: +; a = $00: draws player icons +; a = $01: draws opponent icons +DrawInPlayArea_Icons: + ldh a, [hWhoseTurn] + ld d, a + ld e, DUELVARS_NUMBER_OF_CARDS_IN_HAND + ld a, [de] + ld b, a + ld a, $d0 ; hand icon, unused? + call DrawPlayArea_HandText + +; deck + ldh a, [hWhoseTurn] + ld d, a + ld e, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK + ld a, [de] + ld b, a + ld a, DECK_SIZE + sub b + ld b, a + ld a, $d4 ; deck tile + call DrawPlayArea_IconWithValue + +; discard pile + ldh a, [hWhoseTurn] + ld d, a + ld e, $ed + ld a, [de] + ld b, a + ld a, $d8 ; discard pile tile + call DrawPlayArea_IconWithValue + ret + +; prints text HandText_2 and a cross with decimal value of b +; input +; b = value to print alongside text +DrawPlayArea_HandText: + ld d, [hl] + inc hl + ld e, [hl] + inc hl + +; text + push hl + push bc + call InitTextPrinting + ldtx hl, HandText_2 + call ProcessTextFromID + pop bc + +; decimal value + ld a, b + call CalculateOnesAndTensDigits + ld hl, wOnesAndTensPlace + ld a, [hli] + ld b, a + ld a, [hl] + + ld hl, wDefaultText + ld [hl], TX_SYMBOL + inc hl + ld [hl], SYM_CROSS + inc hl + ld [hl], TX_SYMBOL + inc hl + ld [hli], a + ld [hl], TX_SYMBOL + inc hl + +; draw to screen + ld a, b + ld [hli], a + ld [hl], TX_END + ld hl, wDefaultText + call ProcessText + pop hl + ret + +; handle player input in menu in Your or Opp. Play Area +; works out which cursor coordinate to go to +; and sets carry flag if A or B are pressed +; returns a = $1 if A pressed +; returns a = $ff if B pressed +HandleCheckMenuInput_YourOrOppPlayArea: + xor a + ld [wPlaysSfx], a + ld a, [wCheckMenuCursorXPosition] + ld d, a + ld a, [wCheckMenuCursorYPosition] + ld e, a + +; d = cursor x position +; e = cursor y position + + ldh a, [hDPadHeld] + or a + jr z, .skip + +; pad is pressed + ld a, [wce5e] + and %10000000 + ldh a, [hDPadHeld] + jr nz, .check_vertical + bit D_LEFT_F, a ; test left button + jr nz, .horizontal + bit D_RIGHT_F, a ; test right button + jr z, .check_vertical + +; handle horizontal input +.horizontal + ld a, [wce5e] + and %01111111 + or a + jr nz, .asm_86dd ; jump if wce5e's lower 7 bits aren't set + ld a, e + or a + jr z, .flip_x ; jump if y is 0 + +; wce5e = %10000000 +; e = 1 + dec e ; change y position + jr .flip_x + +.asm_86dd + ld a, e + or a + jr nz, .flip_x ; jump if y is not 0 + inc e ; change y position +.flip_x + ld a, d + xor $01 ; flip x position + ld d, a + jr .erase + +.check_vertical + bit D_UP_F, a + jr nz, .vertical + bit D_DOWN_F, a + jr z, .skip + +; handle vertical input +.vertical + ld a, d + or a + jr z, .flip_y ; jump if x is 0 + dec d +.flip_y + ld a, e + xor $01 ; flip y position + ld e, a + +.erase + ld a, TRUE + ld [wPlaysSfx], a + push de + call EraseCheckMenuCursor_YourOrOppPlayArea + pop de + +; update x and y cursor positions + ld a, d + ld [wCheckMenuCursorXPosition], a + ld a, e + ld [wCheckMenuCursorYPosition], a + +; reset cursor blink + xor a + ld [wCheckMenuCursorBlinkCounter], a + +.skip + ldh a, [hKeysPressed] + and A_BUTTON | B_BUTTON + jr z, .sfx + and A_BUTTON + jr nz, .a_pressed + +; B pressed + ld a, $ff ; cancel + call PlaySFXConfirmOrCancel + scf + ret + +.a_pressed + call DisplayCheckMenuCursor_YourOrOppPlayArea + ld a, $01 + call PlaySFXConfirmOrCancel + scf + ret + +.sfx + ld a, [wPlaysSfx] + or a + jr z, .draw_cursor + call PlaySFX + +.draw_cursor + ld hl, wCheckMenuCursorBlinkCounter + ld a, [hl] + inc [hl] + and %00001111 + ret nz ; only update cursor if blink's lower nibble is 0 + + ld a, SYM_CURSOR_R ; cursor byte + bit 4, [hl] ; only draw cursor if blink counter's fourth bit is not set + jr z, DrawCheckMenuCursor_YourOrOppPlayArea +; fallthrough + +; transforms cursor position into coordinates +; in order to draw byte on menu cursor +EraseCheckMenuCursor_YourOrOppPlayArea: + ld a, SYM_SPACE ; white tile +; fallthrough + +; draws in the cursor position +; input: +; a = tile byte to draw +DrawCheckMenuCursor_YourOrOppPlayArea: + ld e, a + ld a, 10 + ld l, a + ld a, [wCheckMenuCursorXPosition] + ld h, a + call HtimesL +; h = 10 * cursor x pos + + ld a, l + add 1 + ld b, a + ld a, [wCheckMenuCursorYPosition] + sla a + add 14 + ld c, a +; c = 11 + 2 * cursor y pos + 14 + +; draw tile loaded in e + ld a, e + call WriteByteToBGMap0 + or a + ret + +DisplayCheckMenuCursor_YourOrOppPlayArea: + ld a, SYM_CURSOR_R ; load cursor byte + jr DrawCheckMenuCursor_YourOrOppPlayArea + +; handles Peek Pkmn Power selection menus +_HandlePeekSelection: + call Set_OBJ_8x8 + call LoadCursorTile +; reset wce5c and wIsSwapTurnPending + xor a + ld [wce5c], a + ld [wIsSwapTurnPending], a + +; draw play area screen for the turn player + ldh a, [hWhoseTurn] + ld h, a + ld l, a + call DrawYourOrOppPlayAreaScreen + +.check_swap + ld a, [wIsSwapTurnPending] + or a + jr z, .draw_menu_1 +; if wIsSwapTurnPending is TRUE, swap turn + call SwapTurn + xor a + ld [wIsSwapTurnPending], a + +; prompt player to choose either own Play Area or opponent's +.draw_menu_1 + xor a + ld hl, .PlayAreaMenuParameters + call InitializeMenuParameters + call DrawWideTextBox + ld hl, .YourOrOppPlayAreaData + call PlaceTextItems + +.loop_input_1 + call DoFrame + call HandleMenuInput + jr nc, .loop_input_1 + cp -1 + jr z, .loop_input_1 ; can't use B btn + + call EraseCursor + ldh a, [hCurMenuItem] + or a + jp nz, .PrepareYourPlayAreaSelection ; jump if not Opp Play Area + +; own Play Area was chosen + ld a, [wCheckMenuPlayAreaWhichDuelist] + ld b, a + ldh a, [hWhoseTurn] + cp b + jr z, .text_1 + +; switch the play area to draw + ld h, a + ld l, a + call DrawYourOrOppPlayAreaScreen + xor a + ld [wIsSwapTurnPending], a + +.text_1 + call DrawWideTextBox + lb de, 1, 14 + call InitTextPrinting + ldtx hl, WhichCardWouldYouLikeToSeeText + call ProcessTextFromID + + xor a + ld [wYourOrOppPlayAreaCurPosition], a + ld de, PeekYourPlayAreaTransitionTable + ld hl, wTransitionTablePtr + ld [hl], e + inc hl + ld [hl], d + +.loop_input_2 + ld a, $01 + ld [wVBlankOAMCopyToggle], a + call DoFrame + call YourOrOppPlayAreaScreen_HandleInput + jr c, .selection_cancelled + jr .loop_input_2 +.selection_cancelled + cp -1 + jr nz, .selection_made + call ZeroObjectPositionsWithCopyToggleOn + jr .check_swap +.selection_made + ld hl, .SelectionFunctionTable + call JumpToFunctionInTable + jr .loop_input_2 + +.SelectionFunctionTable +rept 6 + dw .SelectedPrize +endr + dw .SelectedOppsHand + dw .SelectedDeck + +.YourOrOppPlayAreaData ; 8808 (2:4808) + textitem 2, 14, YourPlayAreaText + textitem 2, 16, OppPlayAreaText + db $ff + +.PlayAreaMenuParameters ; 8811 (2:4811) + db 1, 14 ; cursor x, cursor y + db 2 ; y displacement between items + db 2 ; number of items + db SYM_CURSOR_R ; cursor tile number + db SYM_SPACE ; tile behind cursor + dw NULL ; function pointer if non-0 + +.SelectedPrize ; 8819 (2:4819) + ld a, [wYourOrOppPlayAreaCurPosition] + ld c, a + ld b, $1 + +; left-shift b a number of times +; corresponding to this prize card +.loop_prize_bitmask + or a + jr z, .got_prize_bitmask + sla b + dec a + jr .loop_prize_bitmask + +.got_prize_bitmask + ld a, DUELVARS_PRIZES + call GetTurnDuelistVariable + and b + ret z ; return if prize card taken + + ld a, c + add $40 + ld [wce5c], a + ld a, c + add DUELVARS_PRIZE_CARDS + call GetTurnDuelistVariable + jr .ShowSelectedCard + +.SelectedOppsHand ; 883c (2:483c) + call CreateHandCardList + ret c + ld hl, wDuelTempList + call ShuffleCards + ld a, [hl] + jr .ShowSelectedCard + +.SelectedDeck ; 8849 (2:4849) + call CreateDeckCardList + ret c + ld a, %01111111 + ld [wce5c], a + ld a, [wDuelTempList] +; fallthrough + +; input: +; a = deck index of card to be loaded +; output: +; a = wce5c +; with upper bit set if turn was swapped +.ShowSelectedCard ; 8855 (2:4855) + ld b, a + ld a, [wce5c] + or a + jr nz, .display + ; if wce5c is not set, set it as input deck index + ld a, b + ld [wce5c], a +.display + ld a, b + call LoadCardDataToBuffer1_FromDeckIndex + call Set_OBJ_8x16 + bank1call OpenCardPage_FromHand + ld a, $01 + ld [wVBlankOAMCopyToggle], a + pop af + +; if wIsSwapTurnPending is TRUE, swap turn + ld a, [wIsSwapTurnPending] + or a + jr z, .dont_swap + call SwapTurn + ld a, [wce5c] + or %10000000 + ret +.dont_swap + ld a, [wce5c] + ret + +; prepare menu parameters to handle selection +; of player's own Play Area +.PrepareYourPlayAreaSelection: + ld a, [wCheckMenuPlayAreaWhichDuelist] + ld b, a + ldh a, [hWhoseTurn] + cp b + jr nz, .text_2 + + ld l, a + cp PLAYER_TURN + jr nz, .opponent + ld a, OPPONENT_TURN + jr .draw_menu_2 +.opponent + ld a, PLAYER_TURN + +.draw_menu_2 + ld h, a + call DrawYourOrOppPlayAreaScreen + +.text_2 + call DrawWideTextBox + lb de, 1, 14 + call InitTextPrinting + ldtx hl, WhichCardWouldYouLikeToSeeText + call ProcessTextFromID + + xor a + ld [wYourOrOppPlayAreaCurPosition], a + ld de, PeekOppPlayAreaTransitionTable + ld hl, wTransitionTablePtr + ld [hl], e + inc hl + ld [hl], d + + call SwapTurn + ld a, TRUE + ld [wIsSwapTurnPending], a ; mark pending to swap turn + jp .loop_input_2 + +PeekYourPlayAreaTransitionTable: + cursor_transition $08, $28, $00, $04, $02, $01, $07 + cursor_transition $30, $28, $20, $05, $03, $07, $00 + cursor_transition $08, $38, $00, $00, $04, $03, $07 + cursor_transition $30, $38, $20, $01, $05, $07, $02 + cursor_transition $08, $48, $00, $02, $00, $05, $07 + cursor_transition $30, $48, $20, $03, $01, $07, $04 + cursor_transition $78, $50, $00, $07, $07, $00, $01 + cursor_transition $78, $28, $00, $07, $07, $00, $01 + +PeekOppPlayAreaTransitionTable: + cursor_transition $a0, $60, $20, $02, $04, $07, $01 + cursor_transition $78, $60, $00, $03, $05, $00, $07 + cursor_transition $a0, $50, $20, $04, $00, $06, $03 + cursor_transition $78, $50, $00, $05, $01, $02, $06 + cursor_transition $a0, $40, $20, $00, $02, $06, $05 + cursor_transition $78, $40, $00, $01, $03, $04, $06 + cursor_transition $08, $38, $00, $07, $07, $05, $04 + cursor_transition $08, $60, $00, $06, $06, $01, $00 + +_DrawAIPeekScreen: + push bc + call Set_OBJ_8x8 + call LoadCursorTile + xor a + ld [wIsSwapTurnPending], a + ldh a, [hWhoseTurn] + ld l, a + ld de, PeekYourPlayAreaTransitionTable + pop bc + bit AI_PEEK_TARGET_HAND_F, b + jr z, .draw_play_area + +; AI chose the hand + call SwapTurn + ld a, TRUE + ld [wIsSwapTurnPending], a ; mark pending to swap turn + ldh a, [hWhoseTurn] + ld de, PeekOppPlayAreaTransitionTable +.draw_play_area + ld h, a + push bc + push de + call DrawYourOrOppPlayAreaScreen + pop de + pop bc + +; get the right cursor position +; depending on what action the AI chose +; (prize card, hand, deck) + ld hl, wMenuInputTablePointer + ld [hl], e + inc hl + ld [hl], d + ld a, b + and $7f + cp $7f + jr nz, .prize_card +; cursor on the deck + ld a, $7 + ld [wYourOrOppPlayAreaCurPosition], a + jr .got_cursor_position +.prize_card + bit AI_PEEK_TARGET_PRIZE_F, a + jr z, .hand + and $3f + ld [wYourOrOppPlayAreaCurPosition], a + jr .got_cursor_position +.hand + ld a, $6 + ld [wYourOrOppPlayAreaCurPosition], a +.got_cursor_position + call YourOrOppPlayAreaScreen_HandleInput.draw_cursor + + ld a, $1 + ld [wVBlankOAMCopyToggle], a + ld a, [wIsSwapTurnPending] + or a + ret z + call SwapTurn + ret + +LoadCursorTile: + ld de, v0Tiles0 + ld hl, .tile_data + ld b, 16 + call SafeCopyDataHLtoDE + ret + +.tile_data: + db $e0, $c0, $98, $b0, $84, $8c, $83, $82 + db $86, $8f, $9d, $be, $f4, $f8, $50, $60 + +; handles input inside the "Your Play Area" or "Opp Play Area" screens +; returns carry if either A or B button were pressed +; returns -1 in a if B button was pressed +YourOrOppPlayAreaScreen_HandleInput: + xor a + ld [wPlaysSfx], a + +; get the transition data for the prize card with cursor + ld hl, wTransitionTablePtr + ld e, [hl] + inc hl + ld d, [hl] + ld a, [wYourOrOppPlayAreaCurPosition] + ld [wPrizeCardCursorTemporaryPosition], a + ld l, a + ld h, 7 ; length of each transition table item + call HtimesL + add hl, de + +; get the transition index related to the directional input + ldh a, [hDPadHeld] + or a + jp z, .check_button + inc hl + inc hl + inc hl + + bit D_UP_F, a + jr z, .else_if_down + + ; up + ld a, [hl] + jr .process_dpad + +.else_if_down + inc hl + bit D_DOWN_F, a + jr z, .else_if_right + + ; down + ld a, [hl] + jr .process_dpad + +.else_if_right + inc hl + bit D_RIGHT_F, a + jr z, .else_if_left + + ; right + ld a, [hl] + jr .process_dpad + +.else_if_left + inc hl + bit D_LEFT_F, a + jr z, .check_button + + ; left + ld a, [hl] +.process_dpad + ld [wYourOrOppPlayAreaCurPosition], a + cp $8 ; if a >= 0x8 + jr nc, .next + ld b, $1 + +; this loop equals to +; b = (1 << a) +.make_bitmask_loop + or a + jr z, .make_bitmask_done + sla b + dec a + jr .make_bitmask_loop + +.make_bitmask_done +; check if the moved cursor refers to an existing item. +; it's always true when this function was called from the glossary procedure. + ld a, [wDuelInitialPrizesUpperBitsSet] + and b + jr nz, .next + +; when no cards exist at the cursor, + ld a, [wPrizeCardCursorTemporaryPosition] + cp $06 + jr nz, YourOrOppPlayAreaScreen_HandleInput + ; move once more in the direction (recursively) until it reaches an existing item. + +; check if one of the dpad, left or right, is pressed. +; if not, just go back to the start. + ldh a, [hDPadHeld] + bit D_RIGHT_F, a + jr nz, .left_or_right + bit D_LEFT_F, a + jr z, YourOrOppPlayAreaScreen_HandleInput + +.left_or_right + ; if started with 5 or 6 prize cards + ; can switch sides normally, + ld a, [wDuelInitialPrizes] + cp PRIZES_5 + jr nc, .next + ; else if it's last card, + ld a, [wYourOrOppPlayAreaCurPosition] + cp 5 + jr nz, .not_last_card + ; place it at pos 3 + ld a, 3 + ld [wYourOrOppPlayAreaCurPosition], a + jr .ok +.not_last_card + ; otherwise place at pos 2 + ld a, 2 + ld [wYourOrOppPlayAreaCurPosition], a + +.ok + ld a, [wDuelInitialPrizes] + cp PRIZES_3 + jr nc, .handled_cursor_pos + ; in this case can just sub 2 from pos + ld a, [wYourOrOppPlayAreaCurPosition] + sub 2 + ld [wYourOrOppPlayAreaCurPosition], a + +.handled_cursor_pos + ld a, [wYourOrOppPlayAreaCurPosition] + ld [wPrizeCardCursorTemporaryPosition], a + ld b, $1 + jr .make_bitmask_loop + +.next + ld a, TRUE + ld [wPlaysSfx], a + +; reset cursor blink + xor a + ld [wCheckMenuCursorBlinkCounter], a +.check_button + ldh a, [hKeysPressed] + and A_BUTTON | B_BUTTON + jr z, .return + + and A_BUTTON + jr nz, .a_button + + ld a, -1 ; cancel + call PlaySFXConfirmOrCancel + scf + ret + +.a_button + call .draw_cursor + ld a, $01 + call PlaySFXConfirmOrCancel + ld a, [wYourOrOppPlayAreaCurPosition] + scf + ret + +.return + ld a, [wPlaysSfx] + or a + jr z, .skip_sfx + call PlaySFX +.skip_sfx + ld hl, wCheckMenuCursorBlinkCounter + ld a, [hl] + inc [hl] + and (1 << 4) - 1 + ret nz + bit 4, [hl] + jr nz, ZeroObjectPositionsWithCopyToggleOn + +.draw_cursor + call ZeroObjectPositions + ld hl, wTransitionTablePtr + ld e, [hl] + inc hl + ld d, [hl] + ld a, [wYourOrOppPlayAreaCurPosition] + ld l, a + ld h, 7 + call HtimesL + add hl, de +; hl = [wTransitionTablePtr] + 7 * wce52 + + ld d, [hl] + inc hl + ld e, [hl] + inc hl + ld b, [hl] + ld c, $00 + call SetOneObjectAttributes + or a + ret + +ZeroObjectPositionsWithCopyToggleOn: + call ZeroObjectPositions + + ld a, $01 + ld [wVBlankOAMCopyToggle], a + ret + +; handles the screen for Player to select prize card(s) +_SelectPrizeCards: + xor a + call GetFirstSetPrizeCard + ld [wYourOrOppPlayAreaCurPosition], a + ld de, hTempPlayAreaLocation_ffa1 + ld hl, wSelectedPrizeCardListPtr + ld [hl], e + inc hl + ld [hl], d + +.check_prize_cards_to_select + ld a, [wNumberOfPrizeCardsToSelect] + or a + jr z, .done_selection + ld a, DUELVARS_PRIZES + call GetTurnDuelistVariable + or a + jr nz, .got_prizes + +.done_selection + ld a, DUELVARS_PRIZES + call GetTurnDuelistVariable + ldh [hTemp_ffa0], a + ld a, [wSelectedPrizeCardListPtr + 0] + ld l, a + ld a, [wSelectedPrizeCardListPtr + 1] + ld h, a + ld [hl], $ff + ret + +.got_prizes + ldh a, [hWhoseTurn] + ld h, a + ld l, a + call DrawYourOrOppPlayAreaScreen + call DrawWideTextBox + lb de, 1, 14 + call InitTextPrinting + ldtx hl, PleaseChooseAPrizeText + call ProcessTextFromID + ld de, .cursor_transition_table + ld hl, wMenuInputTablePointer + ld [hl], e + inc hl + ld [hl], d +.loop_handle_input + ld a, $1 + ld [wVBlankOAMCopyToggle], a + call DoFrame + call YourOrOppPlayAreaScreen_HandleInput + jr nc, .loop_handle_input + cp $ff + jr z, .loop_handle_input + + call ZeroObjectPositionsWithCopyToggleOn + +; get prize bit mask that corresponds +; to the one pointed by the cursor + ld a, [wYourOrOppPlayAreaCurPosition] + ld c, a + ld b, $1 +.loop + or a + jr z, .got_prize_mask + sla b + dec a + jr .loop + +.got_prize_mask + ; if cursor prize is not set, + ; then return to input loop + ld a, DUELVARS_PRIZES + call GetTurnDuelistVariable + and b + jp z, .loop_handle_input ; can be jr + + ; remove prize + ld a, DUELVARS_PRIZES + call GetTurnDuelistVariable + sub b + ld [hl], a + + ; get its deck index + ld a, c + add DUELVARS_PRIZE_CARDS + call GetTurnDuelistVariable + + ld hl, wSelectedPrizeCardListPtr + ld e, [hl] + inc hl + ld d, [hl] + ld [de], a ; store deck index + inc de + ld [hl], d + dec hl + ld [hl], e + + ; add prize card to hand + call AddCardToHand + call LoadCardDataToBuffer1_FromDeckIndex + call Set_OBJ_8x16 + bank1call OpenCardPage_FromHand + ld a, [wNumberOfPrizeCardsToSelect] + dec a + ld [wNumberOfPrizeCardsToSelect], a + ld a, [wYourOrOppPlayAreaCurPosition] + call GetFirstSetPrizeCard + ld [wYourOrOppPlayAreaCurPosition], a + jp .check_prize_cards_to_select + +.cursor_transition_table + cursor_transition $08, $28, $00, $04, $02, $01, $01 + cursor_transition $30, $28, $20, $05, $03, $00, $00 + cursor_transition $08, $38, $00, $00, $04, $03, $03 + cursor_transition $30, $38, $20, $01, $05, $02, $02 + cursor_transition $08, $48, $00, $02, $00, $05, $05 + cursor_transition $30, $48, $20, $03, $01, $04, $04 + +_DrawPlayAreaToPlacePrizeCards: + xor a + ld [wTileMapFill], a + call ZeroObjectPositions + call EmptyScreen + call LoadSymbolsFont + call LoadPlacingThePrizesScreenTiles + + ldh a, [hWhoseTurn] + ld [wCheckMenuPlayAreaWhichLayout], a + ld [wCheckMenuPlayAreaWhichDuelist], a + + lb de, 0, 10 + ld c, 3 + call DrawPlayArea_BenchCards + ld hl, .player_icon_coordinates + call DrawYourOrOppPlayArea_Icons.draw + lb de, 8, 6 + ld a, $a0 + lb hl, 1, 4 + lb bc, 4, 3 + call FillRectangle + + call SwapTurn + ld a, TRUE + ld [wIsSwapTurnPending], a ; mark pending to swap turn + ldh a, [hWhoseTurn] + ld [wCheckMenuPlayAreaWhichDuelist], a + lb de, 6, 0 + ld c, 3 + call DrawPlayArea_BenchCards + ld hl, .opp_icon_coordinates + call DrawYourOrOppPlayArea_Icons.draw + lb de, 8, 3 + ld a, $a0 + lb hl, 1, 4 + lb bc, 4, 3 + call FillRectangle + call SwapTurn + ret + +.player_icon_coordinates + db 15, 11 + db 15, 6 + db 15, 8 + +.opp_icon_coordinates + db 0, 0 + db 0, 4 + db 0, 2 + +; seems like a function to draw prize cards +; given a list of coordinates in hl +; hl = pointer to coords +Func_8bf2: ; unreferenced + push hl + ld a, [wCheckMenuPlayAreaWhichDuelist] + ld h, a + ld l, DUELVARS_PRIZES + ld a, [hl] + pop hl + + ld b, 0 + push af +.loop_prize_cards + inc b + ld a, [wDuelInitialPrizes] + inc a + cp b + jr z, .done + pop af + srl a + push af + jr c, .not_taken + ; same tile whether the prize card is taken or not + ld a, $ac + jr .got_tile +.not_taken + ld a, $ac +.got_tile + ld e, [hl] + inc hl + ld d, [hl] + inc hl + push hl + push bc + lb hl, 0, 0 + lb bc, 1, 1 + call FillRectangle + ld a, [wConsole] + cp CONSOLE_CGB + jr nz, .skip_pal + ld a, $02 + lb bc, 1, 1 + lb hl, 0, 0 + call BankswitchVRAM1 + call FillRectangle + call BankswitchVRAM0 +.skip_pal + pop bc + pop hl + jr .loop_prize_cards +.done + pop af + ret + +; unknown data +Data_8c3f: ; unreferenced + db $06, $05, $06, $06, $07, $05, $07, $06 + db $08, $05, $08, $06, $05, $0e, $05, $0d + db $04, $0e, $04, $0d, $03, $0e, $03, $0d + +; gets the first prize card index that is set +; beginning from index in register a +; a = prize card index +GetFirstSetPrizeCard: + push bc + push de + push hl + ld e, PRIZES_6 + ld c, a + ldh a, [hWhoseTurn] + ld h, a + ld l, DUELVARS_PRIZES + ld d, [hl] +.loop_prizes + call .GetPrizeMask + and d + jr nz, .done ; prize is set + dec e + jr nz, .next_prize + ld c, 0 + jr .done +.next_prize + inc c + ld a, PRIZES_6 + cp c + jr nz, .loop_prizes + ld c, 0 + jr .loop_prizes + +.done + ld a, c ; first prize index that is set + pop hl + pop de + pop bc + ret + +; returns 1 shifted left by c bits +.GetPrizeMask + push bc + ld a, c + ld b, $1 +.loop + or a + jr z, .got_mask + sla b + dec a + jr .loop +.got_mask + ld a, b + pop bc + ret diff --git a/src/engine/menus/printer.asm b/src/engine/menus/printer.asm new file mode 100644 index 0000000..4ac4001 --- /dev/null +++ b/src/engine/menus/printer.asm @@ -0,0 +1,317 @@ +PrinterMenu_PokemonCards: + call WriteCardListsTerminatorBytes + call PrintPlayersCardsHeaderInfo + xor a + ld [wCardListVisibleOffset], a + ld [wCurCardTypeFilter], a + call PrintFilteredCardSelectionList + call EnableLCD + xor a + ld hl, FiltersCardSelectionParams + call InitCardSelectionParams + +.loop_frame_1 + call DoFrame + ld a, [wCurCardTypeFilter] + ld b, a + ld a, [wTempCardTypeFilter] + cp b + jr z, .handle_input + ld [wCurCardTypeFilter], a + ld hl, wCardListVisibleOffset + ld [hl], $00 + call PrintFilteredCardSelectionList + ld hl, hffb0 + ld [hl], $01 + call PrintPlayersCardsText + ld hl, hffb0 + ld [hl], $00 + ld a, NUM_FILTERS + ld [wCardListNumCursorPositions], a +.handle_input + ldh a, [hDPadHeld] + and D_DOWN + jr z, .asm_abca +; d_down + call ConfirmSelectionAndReturnCarry + jr .asm_abd7 +.asm_abca + call HandleCardSelectionInput + jr nc, .loop_frame_1 + ld a, [hffb3] + cp $ff + jr nz, .asm_abd7 + ret + +.asm_abd7 + ld a, [wNumEntriesInCurFilter] + or a + jr z, .loop_frame_1 + + xor a + ld hl, Data_a396 + call InitCardSelectionParams + ld a, [wNumEntriesInCurFilter] + ld [wNumCardListEntries], a + ld hl, wNumVisibleCardListEntries + cp [hl] + jr nc, .asm_abf6 + ld [wCardListNumCursorPositions], a + ld [wTempCardListNumCursorPositions], a +.asm_abf6 + ld hl, PrintCardSelectionList + ld d, h + ld a, l + ld hl, wCardListUpdateFunction + ld [hli], a + ld [hl], d + xor a + ld [wced2], a + +.loop_frame_2 + call DoFrame + call HandleSelectUpAndDownInList + jr c, .loop_frame_2 + call HandleDeckCardSelectionList + jr c, .asm_ac60 + ldh a, [hDPadHeld] + and START + jr z, .loop_frame_2 +; start btn + ld a, $01 + call PlaySFXConfirmOrCancel + ld a, [wCardListNumCursorPositions] + ld [wTempCardListNumCursorPositions], a + ld a, [wCardListCursorPos] + ld [wTempCardListCursorPos], a + + ; set wFilteredCardList as current card list + ; and show card page screen + ld de, wFilteredCardList + ld hl, wCurCardListPtr + ld [hl], e + inc hl + ld [hl], d + call OpenCardPageFromCardList + call PrintPlayersCardsHeaderInfo + +.asm_ac37 + ld hl, FiltersCardSelectionParams + call InitCardSelectionParams + ld a, [wCurCardTypeFilter] + ld [wTempCardTypeFilter], a + call DrawHorizontalListCursor_Visible + call PrintCardSelectionList + call EnableLCD + ld hl, Data_a396 + call InitCardSelectionParams + ld a, [wTempCardListNumCursorPositions] + ld [wCardListNumCursorPositions], a + ld a, [wTempCardListCursorPos] + ld [wCardListCursorPos], a + jr .loop_frame_2 + +.asm_ac60 + call DrawListCursor_Invisible + ld a, [wCardListNumCursorPositions] + ld [wTempCardListNumCursorPositions], a + ld a, [wCardListCursorPos] + ld [wTempCardListCursorPos], a + ld a, [hffb3] + cp $ff + jr nz, .asm_ac92 + + ld hl, FiltersCardSelectionParams + call InitCardSelectionParams + ld a, [wCurCardTypeFilter] + ld [wTempCardTypeFilter], a + ld hl, hffb0 + ld [hl], $01 + call PrintPlayersCardsText + ld hl, hffb0 + ld [hl], $00 + jp .loop_frame_1 + +.asm_ac92 + call DrawListCursor_Visible + call .Func_acde + lb de, 1, 1 + call InitTextPrinting + ldtx hl, PrintThisCardYesNoText + call ProcessTextFromID + ld a, $01 + ld hl, Data_ad05 + call InitCardSelectionParams +.loop_frame + call DoFrame + call HandleCardSelectionInput + jr nc, .loop_frame + ld a, [hffb3] + or a + jr nz, .asm_acd5 + ld hl, wFilteredCardList + ld a, [wTempCardListCursorPos] + ld c, a + ld b, $00 + add hl, bc + ld a, [wCardListVisibleOffset] + ld c, a + ld b, $00 + add hl, bc + ld a, [hl] + bank1call Func_758a + call PrintPlayersCardsHeaderInfo + jp .asm_ac37 + +.asm_acd5 + call .Func_acde + call PrintPlayersCardsHeaderInfo.skip_empty_screen + jp .asm_ac37 + +.Func_acde + xor a + lb hl, 0, 0 + lb de, 0, 0 + lb bc, 20, 4 + call FillRectangle + ld a, [wConsole] + cp CONSOLE_CGB + ret nz ; exit if not CGB + + xor a + lb hl, 0, 0 + lb de, 0, 0 + lb bc, 20, 4 + call BankswitchVRAM1 + call FillRectangle + call BankswitchVRAM0 + ret + +Data_ad05: + db 3 ; x pos + db 3 ; y pos + db 0 ; y spacing + db 4 ; x spacing + db 2 ; num entries + db SYM_CURSOR_R ; visible cursor tile + db SYM_SPACE ; invisible cursor tile + dw NULL ; wCardListHandlerFunction + +PrinterMenu_CardList: + call WriteCardListsTerminatorBytes + call Set_OBJ_8x8 + call Func_8d78 + lb bc, 0, 4 + ld a, SYM_BOX_TOP + call FillBGMapLineWithA + + xor a + ld [wCardListVisibleOffset], a + ld [wCurCardTypeFilter], a + call PrintFilteredCardSelectionList + call EnableLCD + lb de, 1, 1 + call InitTextPrinting + ld hl, EnableLCD + call ProcessTextFromID + ld a, $01 + ld hl, Data_ad05 + call InitCardSelectionParams +.loop_frame + call DoFrame + call HandleCardSelectionInput + jr nc, .loop_frame + ld a, [hffb3] + or a + ret nz + bank1call PrintCardList + ret + +HandlePrinterMenu: + bank1call PreparePrinterConnection + ret c + xor a +.loop + ld hl, PrinterMenuParameters + call InitializeMenuParameters + call EmptyScreenAndLoadFontDuelAndHandCardsIcons + lb de, 4, 0 + lb bc, 12, 12 + call DrawRegularTextBox + lb de, 6, 2 + call InitTextPrinting + ldtx hl, PrintMenuItemsText + call ProcessTextFromID + ldtx hl, WhatWouldYouLikeToPrintText + call DrawWideTextBox_PrintText + call EnableLCD +.loop_input + call DoFrame + call HandleMenuInput + jr nc, .loop_input + ldh a, [hCurMenuItem] + cp $ff + call z, PrinterMenu_QuitPrint + ld [wSelectedPrinterMenuItem], a + ld hl, PrinterMenuFunctionTable + call JumpToFunctionInTable + ld a, [wSelectedPrinterMenuItem] + jr .loop + +PrinterMenu_QuitPrint: + add sp, $2 ; exit menu + ldtx hl, PleaseMakeSureToTurnGameBoyPrinterOffText + call DrawWideTextBox_WaitForInput + ret + +PrinterMenuFunctionTable: + dw PrinterMenu_PokemonCards + dw PrinterMenu_DeckConfiguration + dw PrinterMenu_CardList + dw PrinterMenu_PrintQuality + dw PrinterMenu_QuitPrint + +PrinterMenuParameters: + db 5, 2 ; cursor x, cursor y + db 2 ; y displacement between items + db 5 ; number of items + db SYM_CURSOR_R ; cursor tile number + db SYM_SPACE ; tile behind cursor + dw NULL ; function pointer if non-0 + +PrinterMenu_PrintQuality: + ldtx hl, PleaseSetTheContrastText + call DrawWideTextBox_PrintText + call EnableSRAM + ld a, [sPrinterContrastLevel] + call DisableSRAM + ld hl, Data_adf5 + call InitCardSelectionParams +.loop_frame + call DoFrame + call HandleCardSelectionInput + jr nc, .loop_frame + ld a, [hffb3] + cp $ff + jr z, .asm_ade2 + call EnableSRAM + ld [sPrinterContrastLevel], a + call DisableSRAM +.asm_ade2 + add sp, $2 ; exit menu + ld a, [wSelectedPrinterMenuItem] + ld hl, PrinterMenuParameters + call InitializeMenuParameters + ldtx hl, WhatWouldYouLikeToPrintText + call DrawWideTextBox_PrintText + jr HandlePrinterMenu.loop_input + +Data_adf5: + db 5 ; x pos + db 16 ; y pos + db 0 ; y spacing + db 2 ; x spacing + db 5 ; num entries + db SYM_CURSOR_R ; visible cursor tile + db SYM_SPACE ; invisible cursor tile + dw NULL ; wCardListHandlerFunction diff --git a/src/gfx.asm b/src/gfx.asm index c952593..6df6203 100644 --- a/src/gfx.asm +++ b/src/gfx.asm @@ -1429,13 +1429,13 @@ FightingGfx:: ; a8e12 (2a:4e12) INCBIN "gfx/titlescreen/energies/fighting.2bpp" SECTION "Anims 1", ROMX - INCLUDE "data/anims1.asm" + INCLUDE "data/duel/animations/anims1.asm" SECTION "Anims 2", ROMX - INCLUDE "data/anims2.asm" + INCLUDE "data/duel/animations/anims2.asm" SECTION "Anims 3", ROMX - INCLUDE "data/anims3.asm" + INCLUDE "data/duel/animations/anims3.asm" Palette31:: ; b3feb (2c:7feb) db 1, %11010010 @@ -1456,7 +1456,7 @@ Palette119:: ; b3ff6 (2c:7ff6) rgb 0, 0, 8 SECTION "Anims 4", ROMX - INCLUDE "data/anims4.asm" + INCLUDE "data/duel/animations/anims4.asm" SECTION "Palettes1", ROMX INCLUDE "data/palettes1.asm" diff --git a/src/home/clear_sram.asm b/src/home/clear_sram.asm index a899b08..63aac1a 100644 --- a/src/home/clear_sram.asm +++ b/src/home/clear_sram.asm @@ -18,7 +18,7 @@ ValidateSRAM: jr nz, .check_pattern_loop call RestartSRAM scf - call Func_4050 + call InitSaveDataAndSetUppercase call DisableSRAM ret .check_sequence @@ -36,7 +36,7 @@ ValidateSRAM: .restart_sram call RestartSRAM or a - call Func_4050 + call InitSaveDataAndSetUppercase call DisableSRAM ret diff --git a/src/home/script.asm b/src/home/script.asm index 229eb65..aee96ff 100644 --- a/src/home/script.asm +++ b/src/home/script.asm @@ -158,11 +158,11 @@ Func_3b31: ld a, BANK(Func_1cb18) call BankswitchROM call Func_1cb18 - jr c, .asm_3b45 + jr c, .skip_clear_frame_func xor a - ld [wDoFrameFunction], a + ld [wDoFrameFunction + 0], a ld [wDoFrameFunction + 1], a -.asm_3b45 +.skip_clear_frame_func call ZeroObjectPositions ld a, 1 ld [wVBlankOAMCopyToggle], a diff --git a/src/layout.link b/src/layout.link index 1347891..f2d8f2b 100644 --- a/src/layout.link +++ b/src/layout.link @@ -32,9 +32,11 @@ ROM0 org $3fe0 "Audio Callback" ROMX $01 - "Bank 1" + "Game Loop" + "Duel Core" + "Menus Common" ROMX $02 - "Bank 2" + "Menus" ROMX $03 "Bank 3" ROMX $04 diff --git a/src/main.asm b/src/main.asm index 8c36282..66be305 100644 --- a/src/main.asm +++ b/src/main.asm @@ -3,11 +3,23 @@ INCLUDE "constants.asm" INCLUDE "engine/home.asm" -SECTION "Bank 1", ROMX -INCLUDE "engine/bank01.asm" - -SECTION "Bank 2", ROMX -INCLUDE "engine/bank02.asm" +SECTION "Game Loop", ROMX +INCLUDE "engine/game_loop.asm" + +SECTION "Duel Core", ROMX +INCLUDE "engine/duel/core.asm" + +SECTION "Menus Common", ROMX +INCLUDE "engine/menus/common.asm" + +SECTION "Menus", ROMX +INCLUDE "engine/menus/duel.asm" +INCLUDE "engine/menus/deck_selection.asm" +INCLUDE "engine/menus/deck_check.asm" +INCLUDE "engine/menus/deck_configuration.asm" +INCLUDE "engine/menus/card_album.asm" +INCLUDE "engine/menus/printer.asm" +INCLUDE "engine/menus/deck_machine.asm" SECTION "Bank 3", ROMX INCLUDE "engine/bank03.asm" diff --git a/src/wram.asm b/src/wram.asm index 292e473..4ee7c73 100644 --- a/src/wram.asm +++ b/src/wram.asm @@ -1327,7 +1327,10 @@ wCoinTossNumTossed:: ; cd9f ds $5 -wcda5:: ; cda5 +wAIDuelVars:: +; saves the prizes that the AI already used Peek on +; each bit corresponds to a Prize card +wAIPeekedPrizes:: ; cda5 ds $1 ; this is used by AI in order to determine whether @@ -1394,6 +1397,8 @@ wAICardListEnergyBonus:: ; cdb2 wcdb4:: ; cdb4 ds $1 +wAIDuelVarsEnd:: + ; information about various properties of ; loaded attack for AI calculations wTempLoadedAttackEnergyCost:: ; cdb5 |