summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Harding <33dannye@gmail.com>2021-09-26 23:07:03 -0500
committerGitHub <noreply@github.com>2021-09-26 23:07:03 -0500
commit40dc6651c4f56c067e4237a46ea38a5c8f6f55b4 (patch)
treebdf4be22a2176e19aeffba4cbadd736d767381f8
parentdf67aac83b466dadf5f74c881bf84dd9ef19bdfc (diff)
parent48f83527c769441b6c123f3382d90e2e962ef9a0 (diff)
Merge pull request #111 from ElectroDeoxys/master
Split bank1 & bank2
-rw-r--r--src/data/duel/ai_trainer_card_logic.asm (renamed from src/data/ai_trainer_card_logic.asm)0
-rw-r--r--src/data/duel/animations/anims1.asm (renamed from src/data/anims1.asm)0
-rw-r--r--src/data/duel/animations/anims2.asm (renamed from src/data/anims2.asm)0
-rw-r--r--src/data/duel/animations/anims3.asm (renamed from src/data/anims3.asm)0
-rw-r--r--src/data/duel/animations/anims4.asm (renamed from src/data/anims4.asm)0
-rw-r--r--src/data/duel/animations/attack_animations.asm (renamed from src/data/attack_animations.asm)0
-rw-r--r--src/data/duel/animations/duel_animations.asm (renamed from src/data/duel_animations.asm)0
-rw-r--r--src/data/duel/effect_commands.asm (renamed from src/data/effect_commands.asm)0
-rw-r--r--src/data/duel/practice_text.asm66
-rw-r--r--src/data/glossary_menu_transitions.asm11
-rw-r--r--src/engine/ai/init.asm6
-rw-r--r--src/engine/ai/pkmn_powers.asm2
-rw-r--r--src/engine/ai/trainer_cards.asm2
-rw-r--r--src/engine/bank02.asm10076
-rw-r--r--src/engine/bank04.asm2
-rw-r--r--src/engine/bank06.asm59
-rw-r--r--src/engine/bank07.asm35
-rw-r--r--src/engine/duel/core.asm (renamed from src/engine/bank01.asm)1031
-rw-r--r--src/engine/game_loop.asm55
-rw-r--r--src/engine/menus/card_album.asm959
-rw-r--r--src/engine/menus/common.asm52
-rw-r--r--src/engine/menus/deck_check.asm142
-rw-r--r--src/engine/menus/deck_configuration.asm3617
-rw-r--r--src/engine/menus/deck_machine.asm2296
-rw-r--r--src/engine/menus/deck_selection.asm546
-rw-r--r--src/engine/menus/duel.asm2180
-rw-r--r--src/engine/menus/printer.asm317
-rw-r--r--src/gfx.asm8
-rw-r--r--src/home/clear_sram.asm4
-rw-r--r--src/home/script.asm6
-rw-r--r--src/layout.link6
-rw-r--r--src/main.asm22
-rw-r--r--src/wram.asm7
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