summaryrefslogtreecommitdiff
path: root/src/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/auto_deck_machines.asm191
-rw-r--r--src/engine/bank04.asm4
-rw-r--r--src/engine/bank06.asm5974
-rw-r--r--src/engine/bank07.asm1863
-rw-r--r--src/engine/bank20.asm1205
-rw-r--r--src/engine/copy_card_name.asm152
-rw-r--r--src/engine/credits.asm189
-rw-r--r--src/engine/duel/ai/attacks.asm (renamed from src/engine/ai/attacks.asm)0
-rw-r--r--src/engine/duel/ai/boss_deck_set_up.asm (renamed from src/engine/ai/boss_deck_set_up.asm)0
-rw-r--r--src/engine/duel/ai/common.asm (renamed from src/engine/ai/common.asm)0
-rw-r--r--src/engine/duel/ai/core.asm (renamed from src/engine/ai/core.asm)20
-rw-r--r--src/engine/duel/ai/damage_calculation.asm (renamed from src/engine/ai/damage_calculation.asm)0
-rw-r--r--src/engine/duel/ai/deck_ai.asm (renamed from src/engine/ai/deck_ai.asm)38
-rw-r--r--src/engine/duel/ai/decks/fire_charge.asm (renamed from src/engine/ai/decks/fire_charge.asm)0
-rw-r--r--src/engine/duel/ai/decks/first_strike.asm (renamed from src/engine/ai/decks/first_strike.asm)0
-rw-r--r--src/engine/duel/ai/decks/flower_power.asm (renamed from src/engine/ai/decks/flower_power.asm)0
-rw-r--r--src/engine/duel/ai/decks/general.asm (renamed from src/engine/ai/decks/general.asm)0
-rw-r--r--src/engine/duel/ai/decks/general_no_retreat.asm (renamed from src/engine/ai/decks/general_no_retreat.asm)0
-rw-r--r--src/engine/duel/ai/decks/go_go_rain_dance.asm (renamed from src/engine/ai/decks/go_go_rain_dance.asm)0
-rw-r--r--src/engine/duel/ai/decks/im_ronald.asm (renamed from src/engine/ai/decks/im_ronald.asm)0
-rw-r--r--src/engine/duel/ai/decks/invincible_ronald.asm (renamed from src/engine/ai/decks/invincible_ronald.asm)0
-rw-r--r--src/engine/duel/ai/decks/legendary_articuno.asm (renamed from src/engine/ai/decks/legendary_articuno.asm)0
-rw-r--r--src/engine/duel/ai/decks/legendary_dragonite.asm (renamed from src/engine/ai/decks/legendary_dragonite.asm)0
-rw-r--r--src/engine/duel/ai/decks/legendary_moltres.asm (renamed from src/engine/ai/decks/legendary_moltres.asm)0
-rw-r--r--src/engine/duel/ai/decks/legendary_ronald.asm (renamed from src/engine/ai/decks/legendary_ronald.asm)0
-rw-r--r--src/engine/duel/ai/decks/legendary_zapdos.asm (renamed from src/engine/ai/decks/legendary_zapdos.asm)0
-rw-r--r--src/engine/duel/ai/decks/powerful_ronald.asm (renamed from src/engine/ai/decks/powerful_ronald.asm)0
-rw-r--r--src/engine/duel/ai/decks/rock_crusher.asm (renamed from src/engine/ai/decks/rock_crusher.asm)0
-rw-r--r--src/engine/duel/ai/decks/sams_practice.asm (renamed from src/engine/ai/decks/sams_practice.asm)0
-rw-r--r--src/engine/duel/ai/decks/strange_psyshock.asm (renamed from src/engine/ai/decks/strange_psyshock.asm)0
-rw-r--r--src/engine/duel/ai/decks/unreferenced.asm (renamed from src/engine/ai/decks/unreferenced.asm)0
-rw-r--r--src/engine/duel/ai/decks/wonders_of_science.asm (renamed from src/engine/ai/decks/wonders_of_science.asm)0
-rw-r--r--src/engine/duel/ai/decks/zapping_selfdestruct.asm (renamed from src/engine/ai/decks/zapping_selfdestruct.asm)0
-rw-r--r--src/engine/duel/ai/energy.asm (renamed from src/engine/ai/energy.asm)0
-rw-r--r--src/engine/duel/ai/hand_pokemon.asm (renamed from src/engine/ai/hand_pokemon.asm)0
-rw-r--r--src/engine/duel/ai/init.asm (renamed from src/engine/ai/init.asm)0
-rw-r--r--src/engine/duel/ai/pkmn_powers.asm (renamed from src/engine/ai/pkmn_powers.asm)0
-rw-r--r--src/engine/duel/ai/retreat.asm (renamed from src/engine/ai/retreat.asm)0
-rw-r--r--src/engine/duel/ai/special_attacks.asm (renamed from src/engine/ai/special_attacks.asm)0
-rw-r--r--src/engine/duel/ai/trainer_cards.asm (renamed from src/engine/ai/trainer_cards.asm)0
-rw-r--r--src/engine/duel/animations/commands.asm354
-rw-r--r--src/engine/duel/animations/core.asm661
-rw-r--r--src/engine/duel/animations/screen_effects.asm286
-rw-r--r--src/engine/duel/core.asm2
-rw-r--r--src/engine/duel/effect_commands.asm1619
-rw-r--r--src/engine/duel/effect_functions.asm (renamed from src/engine/effect_functions.asm)0
-rw-r--r--src/engine/game_loop.asm2
-rw-r--r--src/engine/gfx/gfx_table_pointers.asm6
-rw-r--r--src/engine/gfx/palettes.asm170
-rw-r--r--src/engine/gfx/sprite_animations.asm224
-rw-r--r--src/engine/gfx/sprite_vblank.asm39
-rw-r--r--src/engine/gfx/sprites.asm122
-rw-r--r--src/engine/gfx/tilemaps.asm114
-rw-r--r--src/engine/gfx/tilesets.asm95
-rw-r--r--src/engine/input_name.asm1417
-rw-r--r--src/engine/intro.asm114
-rw-r--r--src/engine/link/card_pop.asm399
-rw-r--r--src/engine/link/ir_core.asm531
-rw-r--r--src/engine/link/ir_functions.asm323
-rw-r--r--src/engine/link/link_duel.asm179
-rw-r--r--src/engine/link/printer.asm1124
-rw-r--r--src/engine/menus/booster_pack.asm42
-rw-r--r--src/engine/menus/common.asm8
-rw-r--r--src/engine/menus/glossary.asm221
-rw-r--r--src/engine/menus/play_area.asm570
-rw-r--r--src/engine/menus/start.asm418
-rw-r--r--src/engine/menus/unknown.asm103
-rw-r--r--src/engine/overworld/scripting.asm2
-rw-r--r--src/engine/promotional_card.asm61
-rw-r--r--src/engine/sequences/credits_sequence_commands.asm4
-rw-r--r--src/engine/sequences/intro_sequence_commands.asm (renamed from src/engine/sequences/opening_sequence_commands.asm)159
-rw-r--r--src/engine/sgb.asm (renamed from src/engine/bank1c.asm)210
-rw-r--r--src/engine/starter_deck.asm182
-rw-r--r--src/engine/unused_copyright.asm26
-rw-r--r--src/engine/unused_save_validation.asm96
75 files changed, 10377 insertions, 9142 deletions
diff --git a/src/engine/auto_deck_machines.asm b/src/engine/auto_deck_machines.asm
new file mode 100644
index 0000000..0f84cef
--- /dev/null
+++ b/src/engine/auto_deck_machines.asm
@@ -0,0 +1,191 @@
+INCLUDE "data/auto_deck_card_lists.asm"
+INCLUDE "data/auto_deck_machines.asm"
+
+; writes to sAutoDecks all the deck configurations
+; from the Auto Deck Machine in wCurAutoDeckMachine
+ReadAutoDeckConfiguration:
+ call EnableSRAM
+ ld a, [wCurAutoDeckMachine]
+ ld l, a
+ ld h, 6 * NUM_DECK_MACHINE_SLOTS
+ call HtimesL
+ ld bc, AutoDeckMachineEntries
+ add hl, bc
+ ld b, 0
+.loop_decks
+ call .GetPointerToSRAMAutoDeck
+ call .ReadDeckConfiguration
+ call .ReadDeckName
+
+ ; store deck description text ID
+ push hl
+ ld de, wAutoDeckMachineTextDescriptions
+ ld h, b
+ ld l, 2
+ call HtimesL
+ add hl, de
+ ld d, h
+ ld e, l
+ pop hl
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ inc b
+ ld a, b
+ cp NUM_DECK_MACHINE_SLOTS
+ jr nz, .loop_decks
+ call DisableSRAM
+ ret
+
+; outputs in de the saved deck with index b
+.GetPointerToSRAMAutoDeck
+ push hl
+ ld l, b
+ ld h, DECK_STRUCT_SIZE
+ call HtimesL
+ ld de, sAutoDecks
+ add hl, de
+ ld d, h
+ ld e, l
+ pop hl
+ ret
+
+; writes the deck configuration in SRAM
+; by reading the given deck card list
+.ReadDeckConfiguration
+ push hl
+ push bc
+ push de
+ push de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ pop hl
+ ld bc, DECK_NAME_SIZE
+ add hl, bc
+.loop_create_deck
+ ld a, [de]
+ inc de
+ ld b, a ; card count
+ or a
+ jr z, .done_create_deck
+ ld a, [de]
+ inc de
+ ld c, a ; card ID
+.loop_card_count
+ ld [hl], c
+ inc hl
+ dec b
+ jr nz, .loop_card_count
+ jr .loop_create_deck
+.done_create_deck
+ pop de
+ pop bc
+ pop hl
+ inc hl
+ inc hl
+ ret
+
+.ReadDeckName
+ push hl
+ push bc
+ push de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wDismantledDeckName
+ call CopyText
+ pop hl
+ ld de, wDismantledDeckName
+.loop_copy_name
+ ld a, [de]
+ ld [hli], a
+ or a
+ jr z, .done_copy_name
+ inc de
+ jr .loop_copy_name
+.done_copy_name
+ pop bc
+ pop hl
+ inc hl
+ inc hl
+ ret
+
+; tries out all combinations of dismantling the player's decks
+; in order to build the deck in wSelectedDeckMachineEntry
+; if none of the combinations work, return carry set
+; otherwise, return in a which deck flags should be dismantled
+CheckWhichDecksToDismantleToBuildSavedDeck:
+ xor a
+ ld [wDecksToBeDismantled], a
+
+; first check if it can be built by
+; only dismantling a single deck
+ ld a, DECK_1
+.loop_single_built_decks
+ call .CheckIfCanBuild
+ ret nc
+ sla a ; next deck
+ cp (1 << NUM_DECKS)
+ jr z, .two_deck_combinations
+ jr .loop_single_built_decks
+
+.two_deck_combinations
+; next check all two deck combinations
+ ld a, DECK_1 | DECK_2
+ call .CheckIfCanBuild
+ ret nc
+ ld a, DECK_1 | DECK_3
+ call .CheckIfCanBuild
+ ret nc
+ ld a, DECK_1 | DECK_4
+ call .CheckIfCanBuild
+ ret nc
+ ld a, DECK_2 | DECK_3
+ call .CheckIfCanBuild
+ ret nc
+ ld a, DECK_2 | DECK_4
+ call .CheckIfCanBuild
+ ret nc
+ ld a, DECK_3 | DECK_4
+ call .CheckIfCanBuild
+ ret nc
+
+; all but one deck combinations
+ ld a, $ff ^ DECK_4
+.loop_three_deck_combinations
+ call .CheckIfCanBuild
+ ret nc
+ sra a
+ cp $ff
+ jr z, .all_decks
+ jr .loop_three_deck_combinations
+
+.all_decks
+; finally check if can be built by dismantling all decks
+ call .CheckIfCanBuild
+ ret nc
+
+; none of the combinations work
+ scf
+ ret
+
+; returns carry if wSelectedDeckMachineEntry cannot be built
+; by dismantling the decks given by register a
+; a = DECK_* flags
+.CheckIfCanBuild
+ push af
+ ld hl, wSelectedDeckMachineEntry
+ ld b, [hl]
+ farcall CheckIfCanBuildSavedDeck
+ jr c, .cannot_build
+ pop af
+ ld [wDecksToBeDismantled], a
+ or a
+ ret
+.cannot_build
+ pop af
+ scf
+ ret
diff --git a/src/engine/bank04.asm b/src/engine/bank04.asm
index 5781e73..add4bb3 100644
--- a/src/engine/bank04.asm
+++ b/src/engine/bank04.asm
@@ -5255,7 +5255,7 @@ Unknown_127fb: ; 127fb (4:67fb)
db BOOSTER_ENERGY_LIGHTNING_FIRE
DebugCredits: ; 12800 (4:6800)
- farcall Credits_1d6ad
+ farcall PlayCreditsSequence
scf
ret
@@ -5337,7 +5337,7 @@ Func_12871: ; 12871 (4:6871)
ldh [hSCY], a
ldh [hWX], a
ldh [hWY], a
- call Set_WD_off
+ call SetWindowOff
ret
Func_1288c: ; 1288c (4:688c)
diff --git a/src/engine/bank06.asm b/src/engine/bank06.asm
deleted file mode 100644
index fa181f3..0000000
--- a/src/engine/bank06.asm
+++ /dev/null
@@ -1,5974 +0,0 @@
-; copy the name and level of the card at wLoadedCard1 to wDefaultText
-; a = length in number of tiles (the resulting string will be padded with spaces to match it)
-_CopyCardNameAndLevel: ; 18000 (6:4000)
- push bc
- push de
- ld [wCardNameLength], a
- ld hl, wLoadedCard1Name
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld de, wDefaultText
- push de
- call CopyText ; copy card name to wDefaultText
- pop hl
- ld a, [hli]
- cp TX_HALFWIDTH
- jp z, _CopyCardNameAndLevel_HalfwidthText
-
-; the name doesn't start with TX_HALFWIDTH
-; this doesn't appear to be ever the case (unless caller manipulates wLoadedCard1Name)
- ld a, [wCardNameLength]
- ld c, a
- ld a, [wLoadedCard1Type]
- cp TYPE_ENERGY
- jr nc, .level_done ; jump if energy or trainer
- ld a, [wLoadedCard1Level]
- or a
- jr z, .level_done
- inc c
- inc c
- ld a, [wLoadedCard1Level]
- cp 10
- jr c, .level_done
- inc c ; second digit
-.level_done
- ld hl, wLoadedCard1Name
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld de, wDefaultText
- push de
- call CopyText
- pop hl
- push de
- ld e, c
- call GetTextLengthInTiles
- add e
- ld c, a
- pop hl
- push hl
-.fill_loop
- ld a, $70
- ld [hli], a
- dec c
- jr nz, .fill_loop
- ld [hl], TX_END
- pop hl
- ld a, [wLoadedCard1Type]
- cp TYPE_ENERGY
- jr nc, .done
- ld a, [wLoadedCard1Level]
- or a
- jr z, .done
- ld a, TX_SYMBOL
- ld [hli], a
- ld [hl], SYM_Lv
- inc hl
- ld a, [wLoadedCard1Level]
- cp 10
- jr c, .one_digit
- ld [hl], TX_SYMBOL
- inc hl
- ld b, SYM_0 - 1
-.first_digit_loop
- inc b
- sub 10
- jr nc, .first_digit_loop
- add 10
- ld [hl], b ; first digit
- inc hl
-.one_digit
- ld [hl], TX_SYMBOL
- inc hl
- add SYM_0
- ld [hl], a ; last (or only) digit
- inc hl
-.done
- pop de
- pop bc
- ret
-
-; the name starts with TX_HALFWIDTH
-_CopyCardNameAndLevel_HalfwidthText: ; 18086 (6:4086)
- ld a, [wCardNameLength]
- inc a
- add a
- ld b, a
- ld hl, wDefaultText
-.find_end_text_loop
- dec b
- ld a, [hli]
- or a ; TX_END
- jr nz, .find_end_text_loop
- dec hl
- ld a, [wLoadedCard1Type]
- cp TYPE_ENERGY
- jr nc, .level_done
- ld a, [wLoadedCard1Level]
- or a
- jr z, .level_done
- ld c, a
- ld a, " "
- ld [hli], a
- dec b
- ld a, "L"
- ld [hli], a
- dec b
- ld a, "v"
- ld [hli], a
- dec b
- ld a, c
- cp 10
- jr c, .got_level
- push bc
- ld b, "0" - 1
-.first_digit_loop
- inc b
- sub 10
- jr nc, .first_digit_loop
- add 10
- ld [hl], b ; first digit
- inc hl
- pop bc
- ld c, a
- dec b
-.got_level
- ld a, c
- add "0"
- ld [hli], a ; last (or only) digit
- dec b
-.level_done
- push hl
- ld a, " "
-.fill_spaces_loop
- ld [hli], a
- dec b
- jr nz, .fill_spaces_loop
- ld [hl], TX_END
- pop hl
- pop de
- pop bc
- ret
-
-; this function is called when the player is shown the "In Play Area" screen.
-; it can be called with either the select button (DuelMenuShortcut_BothActivePokemon),
-; or via the "In Play Area" item of the Check menu (DuelCheckMenu_InPlayArea)
-OpenInPlayAreaScreen: ; 180d5 (6:40d5)
- ld a, INPLAYAREA_PLAYER_ACTIVE
- ld [wInPlayAreaCurPosition], a
-.start
- xor a
- ld [wCheckMenuCursorBlinkCounter], a
- farcall DrawInPlayAreaScreen
- call EnableLCD
- call IsClairvoyanceActive
- jr c, .clairvoyance_on
-
- ld de, OpenInPlayAreaScreen_TransitionTable1
- jr .clairvoyance_off
-
-.clairvoyance_on
- ld de, OpenInPlayAreaScreen_TransitionTable2
-.clairvoyance_off
- ld hl, wMenuInputTablePointer
- ld [hl], e
- inc hl
- ld [hl], d
- ld a, [wInPlayAreaCurPosition]
- call .print_associated_text
-.on_frame
- ld a, $01
- ld [wVBlankOAMCopyToggle], a
- call DoFrame
-
- ldh a, [hDPadHeld]
- and START
- jr nz, .selection
-
- ; if this function's been called from 'select' button,
- ; wInPlayAreaFromSelectButton is on.
- ld a, [wInPlayAreaFromSelectButton]
- or a
- jr z, .handle_input ; if it's from the Check menu, jump.
-
- ldh a, [hDPadHeld]
- and SELECT
- jr nz, .skip_input
-
-.handle_input
- ld a, [wInPlayAreaCurPosition]
- ld [wInPlayAreaTemporaryPosition], a
- call OpenInPlayAreaScreen_HandleInput
- jr c, .pressed
-
- ld a, [wInPlayAreaCurPosition]
- cp INPLAYAREA_PLAYER_PLAY_AREA
- jp z, .show_turn_holder_play_area
- cp INPLAYAREA_OPP_PLAY_AREA
- jp z, .show_non_turn_holder_play_area
-
- ; check if the cursor moved.
- ld hl, wInPlayAreaTemporaryPosition
- cp [hl]
- call nz, .print_associated_text
-
- jr .on_frame
-
-.pressed
- cp -1
- jr nz, .selection
-
- ; pressed b button.
- call ZeroObjectPositionsAndToggleOAMCopy_Bank6
- lb de, $38, $9f
- call SetupText
- scf
- ret
-
-.skip_input
- call ZeroObjectPositionsAndToggleOAMCopy_Bank6
- lb de, $38, $9f
- call SetupText
- or a
- ret
-
-.selection ; pressed a button or start button.
- call ZeroObjectPositionsAndToggleOAMCopy_Bank6
- lb de, $38, $9f
- call SetupText
- ld a, [wInPlayAreaCurPosition]
- ld [wInPlayAreaPreservedPosition], a
- ld hl, .jump_table
- call JumpToFunctionInTable
- ld a, [wInPlayAreaPreservedPosition]
- ld [wInPlayAreaCurPosition], a
-
- jp .start
-
-.print_associated_text ; 18171 (6:4171)
-; each position has a text associated to it,
-; which is printed at the bottom of the screen
- push af
- lb de, 1, 17
- call InitTextPrinting
- ldtx hl, EmptyLineText
- call ProcessTextFromID
-
- ld hl, hffb0
- ld [hl], $01
- ldtx hl, HandText_2
- call ProcessTextFromID
-
- ld hl, hffb0
- ld [hl], $00
- lb de, 1, 17
- call InitTextPrinting
- pop af
- ld hl, OpenInPlayAreaScreen_TextTable
- ld b, 0
- sla a
- ld c, a
- add hl, bc
-
- ; hl = OpenInPlayAreaScreen_TextTable + 2 * (wInPlayAreaCurPosition)
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld a, h
-
- ; jump ahead if entry does not contain null text (it's not active pokemon)
- or a
- jr nz, .print_hand_or_discard_pile
-
- ld a, l
- ; bench slots have dummy text IDs assigned to them, which are never used.
- ; these are secretly not text id's, but rather, 2-byte PLAY_AREA_BENCH_* constants
- ; check if the value at register l is one of those, and jump ahead if not
- cp PLAY_AREA_BENCH_5 + $01
- jr nc, .print_hand_or_discard_pile
-
-; if we make it here, we need to print a Pokemon card name.
-; wInPlayAreaCurPosition determines which duelist
-; and l contains the PLAY_AREA_* location of the card.
- ld a, [wInPlayAreaCurPosition]
- cp INPLAYAREA_PLAYER_HAND
- jr nc, .opponent_side
-
- ld a, l
- add DUELVARS_ARENA_CARD
- call GetTurnDuelistVariable
- cp -1
- ret z
-
- call GetCardIDFromDeckIndex
- call LoadCardDataToBuffer1_FromCardID
- jr .display_card_name
-
-.opponent_side
- ld a, l
- add DUELVARS_ARENA_CARD
- call GetNonTurnDuelistVariable
- cp -1
- ret z
-
- call SwapTurn
- call GetCardIDFromDeckIndex
- call LoadCardDataToBuffer1_FromCardID
- call SwapTurn
-
-.display_card_name
- ld a, 18
- call CopyCardNameAndLevel
- ld hl, wDefaultText
- call ProcessText
- ret
-
-.print_hand_or_discard_pile
-; if we make it here, cursor position is to Hand or Discard Pile
-; so DuelistHandText_2 or DuelistDiscardPileText will be printed
-
- ld a, [wInPlayAreaCurPosition]
- cp INPLAYAREA_OPP_ACTIVE
- jr nc, .opp_side_print_hand_or_discard_pile
- call PrintTextNoDelay
- ret
-
-.opp_side_print_hand_or_discard_pile
- call SwapTurn
- call PrintTextNoDelay
- call SwapTurn
- ret
-
-.show_turn_holder_play_area
- lb de, $38, $9f
- call SetupText
- ldh a, [hWhoseTurn]
- push af
- bank1call OpenTurnHolderPlayAreaScreen
- pop af
- ldh [hWhoseTurn], a
- ld a, [wInPlayAreaPreservedPosition]
- ld [wInPlayAreaCurPosition], a
- jp .start
-
-.show_non_turn_holder_play_area
- lb de, $38, $9f
- call SetupText
- ldh a, [hWhoseTurn]
- push af
- bank1call OpenNonTurnHolderPlayAreaScreen
- pop af
- ldh [hWhoseTurn], a
- ld a, [wInPlayAreaPreservedPosition]
- ld [wInPlayAreaCurPosition], a
- jp .start
-
-.jump_table ; (6:4228)
- dw OpenInPlayAreaScreen_TurnHolderPlayArea ; 0x00: INPLAYAREA_PLAYER_BENCH_1
- dw OpenInPlayAreaScreen_TurnHolderPlayArea ; 0x01: INPLAYAREA_PLAYER_BENCH_2
- dw OpenInPlayAreaScreen_TurnHolderPlayArea ; 0x02: INPLAYAREA_PLAYER_BENCH_3
- dw OpenInPlayAreaScreen_TurnHolderPlayArea ; 0x03: INPLAYAREA_PLAYER_BENCH_4
- dw OpenInPlayAreaScreen_TurnHolderPlayArea ; 0x04: INPLAYAREA_PLAYER_BENCH_5
- dw OpenInPlayAreaScreen_TurnHolderPlayArea ; 0x05: INPLAYAREA_PLAYER_ACTIVE
- dw OpenInPlayAreaScreen_TurnHolderHand ; 0x06: INPLAYAREA_PLAYER_HAND
- dw OpenInPlayAreaScreen_TurnHolderDiscardPile ; 0x07: INPLAYAREA_PLAYER_DISCARD_PILE
- dw OpenInPlayAreaScreen_NonTurnHolderPlayArea ; 0x08: INPLAYAREA_OPP_ACTIVE
- dw OpenInPlayAreaScreen_NonTurnHolderHand ; 0x09: INPLAYAREA_OPP_HAND
- dw OpenInPlayAreaScreen_NonTurnHolderDiscardPile ; 0x0a: INPLAYAREA_OPP_DISCARD_PILE
- dw OpenInPlayAreaScreen_NonTurnHolderPlayArea ; 0x0b: INPLAYAREA_OPP_BENCH_1
- dw OpenInPlayAreaScreen_NonTurnHolderPlayArea ; 0x0c: INPLAYAREA_OPP_BENCH_2
- dw OpenInPlayAreaScreen_NonTurnHolderPlayArea ; 0x0d: INPLAYAREA_OPP_BENCH_3
- dw OpenInPlayAreaScreen_NonTurnHolderPlayArea ; 0x0e: INPLAYAREA_OPP_BENCH_4
- dw OpenInPlayAreaScreen_NonTurnHolderPlayArea ; 0x0f: INPLAYAREA_OPP_BENCH_5
-
-OpenInPlayAreaScreen_TurnHolderPlayArea: ; 18248 (6:4248)
- ; wInPlayAreaCurPosition constants conveniently map to (PLAY_AREA_* constants - 1)
- ; for bench locations. this mapping is taken for granted in the following code.
- ld a, [wInPlayAreaCurPosition]
- inc a
- cp INPLAYAREA_PLAYER_ACTIVE + $01
- jr nz, .on_bench
- xor a ; PLAY_AREA_ARENA
-.on_bench
- ld [wCurPlayAreaSlot], a
- add DUELVARS_ARENA_CARD
- call GetTurnDuelistVariable
- cp -1
- ret z
- call GetCardIDFromDeckIndex
- call LoadCardDataToBuffer1_FromCardID
- xor a
- ld [wCurPlayAreaY], a
- bank1call OpenCardPage_FromCheckPlayArea
- ret
-
-OpenInPlayAreaScreen_NonTurnHolderPlayArea: ; 1826a (6:426a)
- ld a, [wInPlayAreaCurPosition]
- sub INPLAYAREA_OPP_ACTIVE
- or a
- jr z, .active
- ; convert INPLAYAREA_OPP_BENCH_* constant to PLAY_AREA_BENCH_* constant
- sub INPLAYAREA_OPP_BENCH_1 - INPLAYAREA_OPP_ACTIVE - PLAY_AREA_BENCH_1
-.active
- ld [wCurPlayAreaSlot], a
- add DUELVARS_ARENA_CARD
- call GetNonTurnDuelistVariable
- cp -1
- ret z
- call SwapTurn
- call GetCardIDFromDeckIndex
- call LoadCardDataToBuffer1_FromCardID
- xor a
- ld [wCurPlayAreaY], a
- bank1call OpenCardPage_FromCheckPlayArea
- call SwapTurn
- ret
-
-OpenInPlayAreaScreen_TurnHolderHand: ; 18293 (6:4293)
- ldh a, [hWhoseTurn]
- push af
- bank1call OpenTurnHolderHandScreen_Simple
- pop af
- ldh [hWhoseTurn], a
- ret
-
-OpenInPlayAreaScreen_NonTurnHolderHand: ; 1829d (6:429d)
- ldh a, [hWhoseTurn]
- push af
- bank1call OpenNonTurnHolderHandScreen_Simple
- pop af
- ldh [hWhoseTurn], a
- ret
-
-OpenInPlayAreaScreen_TurnHolderDiscardPile: ; 182a7 (6:42a7)
- ldh a, [hWhoseTurn]
- push af
- bank1call OpenTurnHolderDiscardPileScreen
- pop af
- ldh [hWhoseTurn], a
- ret
-
-OpenInPlayAreaScreen_NonTurnHolderDiscardPile: ; 182b1 (6:42b1)
- ldh a, [hWhoseTurn]
- push af
- bank1call OpenNonTurnHolderDiscardPileScreen
- pop af
- ldh [hWhoseTurn], a
- ret
-
-OpenInPlayAreaScreen_TextTable:
-; note that for bench slots, the entries are
-; PLAY_AREA_BENCH_* constants in practice
- tx HandText ; INPLAYAREA_PLAYER_BENCH_1
- tx CheckText ; INPLAYAREA_PLAYER_BENCH_2
- tx AttackText ; INPLAYAREA_PLAYER_BENCH_3
- tx PKMNPowerText ; INPLAYAREA_PLAYER_BENCH_4
- tx DoneText ; INPLAYAREA_PLAYER_BENCH_5
- dw NULL ; INPLAYAREA_PLAYER_ACTIVE
- tx DuelistHandText_2 ; INPLAYAREA_PLAYER_HAND
- tx DuelistDiscardPileText ; INPLAYAREA_PLAYER_DISCARD_PILE
- dw NULL ; INPLAYAREA_OPP_ACTIVE
- tx DuelistHandText_2 ; INPLAYAREA_OPP_HAND
- tx DuelistDiscardPileText ; INPLAYAREA_OPP_DISCARD_PILE
- tx HandText ; INPLAYAREA_OPP_BENCH_1
- tx CheckText ; INPLAYAREA_OPP_BENCH_2
- tx AttackText ; INPLAYAREA_OPP_BENCH_3
- tx PKMNPowerText ; INPLAYAREA_OPP_BENCH_4
- tx DoneText ; INPLAYAREA_OPP_BENCH_5
-
-in_play_area_cursor_transition: MACRO
- cursor_transition \1, \2, \3, INPLAYAREA_\4, INPLAYAREA_\5, INPLAYAREA_\6, INPLAYAREA_\7
-ENDM
-
-; it's related to wMenuInputTablePointer.
-; with this table, the cursor moves into the proper location by the input.
-; note that the unit of the position is not a 8x8 tile.
-OpenInPlayAreaScreen_TransitionTable1:
- in_play_area_cursor_transition $18, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_2, PLAYER_BENCH_5
- in_play_area_cursor_transition $30, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_3, PLAYER_BENCH_1
- in_play_area_cursor_transition $48, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_4, PLAYER_BENCH_2
- in_play_area_cursor_transition $60, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_5, PLAYER_BENCH_3
- in_play_area_cursor_transition $78, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_1, PLAYER_BENCH_4
- in_play_area_cursor_transition $30, $6c, $00, OPP_ACTIVE, PLAYER_BENCH_1, PLAYER_DISCARD_PILE, PLAYER_DISCARD_PILE
- in_play_area_cursor_transition $78, $80, $00, PLAYER_DISCARD_PILE, PLAYER_BENCH_1, PLAYER_ACTIVE, PLAYER_ACTIVE
- in_play_area_cursor_transition $78, $70, $00, OPP_ACTIVE, PLAYER_HAND, PLAYER_ACTIVE, PLAYER_ACTIVE
- in_play_area_cursor_transition $78, $34, 1 << OAM_X_FLIP, OPP_BENCH_1, PLAYER_ACTIVE, OPP_DISCARD_PILE, OPP_DISCARD_PILE
- in_play_area_cursor_transition $30, $20, 1 << OAM_X_FLIP, OPP_BENCH_1, OPP_DISCARD_PILE, OPP_ACTIVE, OPP_ACTIVE
- in_play_area_cursor_transition $30, $38, 1 << OAM_X_FLIP, OPP_BENCH_1, PLAYER_ACTIVE, OPP_ACTIVE, OPP_ACTIVE
- in_play_area_cursor_transition $90, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_5, OPP_BENCH_2
- in_play_area_cursor_transition $78, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_1, OPP_BENCH_3
- in_play_area_cursor_transition $60, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_2, OPP_BENCH_4
- in_play_area_cursor_transition $48, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_3, OPP_BENCH_5
- in_play_area_cursor_transition $30, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_4, OPP_BENCH_1
-
-OpenInPlayAreaScreen_TransitionTable2:
- in_play_area_cursor_transition $18, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_2, PLAYER_BENCH_5
- in_play_area_cursor_transition $30, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_3, PLAYER_BENCH_1
- in_play_area_cursor_transition $48, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_4, PLAYER_BENCH_2
- in_play_area_cursor_transition $60, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_5, PLAYER_BENCH_3
- in_play_area_cursor_transition $78, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_1, PLAYER_BENCH_4
- in_play_area_cursor_transition $30, $6c, $00, OPP_ACTIVE, PLAYER_BENCH_1, PLAYER_DISCARD_PILE, PLAYER_DISCARD_PILE
- in_play_area_cursor_transition $78, $80, $00, PLAYER_DISCARD_PILE, PLAYER_BENCH_1, PLAYER_ACTIVE, PLAYER_ACTIVE
- in_play_area_cursor_transition $78, $70, $00, OPP_ACTIVE, PLAYER_HAND, PLAYER_ACTIVE, PLAYER_ACTIVE
- in_play_area_cursor_transition $78, $34, 1 << OAM_X_FLIP, OPP_BENCH_1, PLAYER_ACTIVE, OPP_DISCARD_PILE, OPP_DISCARD_PILE
- in_play_area_cursor_transition $30, $20, 1 << OAM_X_FLIP, OPP_BENCH_1, OPP_DISCARD_PILE, OPP_ACTIVE, OPP_ACTIVE
- in_play_area_cursor_transition $30, $38, 1 << OAM_X_FLIP, OPP_HAND, PLAYER_ACTIVE, OPP_ACTIVE, OPP_ACTIVE
- in_play_area_cursor_transition $90, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_5, OPP_BENCH_2
- in_play_area_cursor_transition $78, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_1, OPP_BENCH_3
- in_play_area_cursor_transition $60, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_2, OPP_BENCH_4
- in_play_area_cursor_transition $48, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_3, OPP_BENCH_5
- in_play_area_cursor_transition $30, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_4, OPP_BENCH_1
-
-OpenInPlayAreaScreen_HandleInput: ; 183bb (6:43bb)
- xor a
- ld [wPlaysSfx], a
- ld hl, wMenuInputTablePointer
- ld e, [hl]
- inc hl
- ld d, [hl]
- ld a, [wInPlayAreaCurPosition]
- ld l, a
- ld h, $07
- call HtimesL
- add hl, de
-
- ldh a, [hDPadHeld]
- or a
- jp z, .check_button
-
- inc hl
- inc hl
- inc hl
-
- ; check d-pad
- 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
- push af
- ld a, [wInPlayAreaCurPosition]
- ld [wInPlayAreaPreservedPosition], a
- pop af
-
- ld [wInPlayAreaCurPosition], a
- cp INPLAYAREA_PLAYER_ACTIVE
- jr c, .player_area
- cp INPLAYAREA_OPP_BENCH_1
- jr c, .next
- cp INPLAYAREA_PLAYER_PLAY_AREA
- jr c, .opponent_area
-
- jr .next
-
-.player_area
- ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
- call GetTurnDuelistVariable
- dec a
- jr nz, .bench_pokemon_exists
-
- ; no pokemon in player's bench.
- ; then move to player's play area.
- ld a, INPLAYAREA_PLAYER_PLAY_AREA
- ld [wInPlayAreaCurPosition], a
- jr .next
-
-.bench_pokemon_exists
- ld b, a
- ld a, [wInPlayAreaCurPosition]
- cp b
- jr c, .next
-
- ; handle index overflow
- ldh a, [hDPadHeld]
- bit D_RIGHT_F, a
- jr z, .on_left
-
- xor a
- ld [wInPlayAreaCurPosition], a
- jr .next
-
-.on_left
- ld a, b
- dec a
- ld [wInPlayAreaCurPosition], a
- jr .next
-
-.opponent_area
- ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
- call GetNonTurnDuelistVariable
- dec a
- jr nz, .bench_pokemon_exists_2
-
- ld a, INPLAYAREA_OPP_PLAY_AREA
- ld [wInPlayAreaCurPosition], a
- jr .next
-
-.bench_pokemon_exists_2
- ld b, a
- ld a, [wInPlayAreaCurPosition]
- sub INPLAYAREA_OPP_BENCH_1
- cp b
- jr c, .next
-
- ldh a, [hDPadHeld]
- bit D_LEFT_F, a
- jr z, .on_right
-
- ld a, INPLAYAREA_OPP_BENCH_1
- ld [wInPlayAreaCurPosition], a
- jr .next
-
-.on_right
- ld a, b
- add INPLAYAREA_OPP_DISCARD_PILE
- ld [wInPlayAreaCurPosition], a
-.next
- ld a, $01
- ld [wPlaysSfx], a
- 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
-
- ; pressed b button
- ld a, -1
- farcall PlaySFXConfirmOrCancel
- scf
- ret
-
-.a_button
- call .draw_cursor
- ld a, $01
- farcall PlaySFXConfirmOrCancel
- ld a, [wInPlayAreaCurPosition]
- 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 $10 - 1
- ret nz
-
- bit 4, [hl] ; = and $10
- jr nz, ZeroObjectPositionsAndToggleOAMCopy_Bank6
-
-.draw_cursor ; 184a0 (6:44a0)
- call ZeroObjectPositions
- ld hl, wMenuInputTablePointer
- ld e, [hl]
- inc hl
- ld d, [hl]
- ld a, [wInPlayAreaCurPosition]
- ld l, a
- ld h, $07
- call HtimesL
- add hl, de
-
- ld d, [hl] ; x position.
- inc hl
- ld e, [hl] ; y position.
- inc hl
- ld b, [hl] ; attribute.
- ld c, $00
- call SetOneObjectAttributes
- or a
- ret
-
-ZeroObjectPositionsAndToggleOAMCopy_Bank6: ; 184bf (6:44bf)
- call ZeroObjectPositions
- ld a, $01
- ld [wVBlankOAMCopyToggle], a
- ret
-
-OpenGlossaryScreen: ; 184c8 (6:44c8)
- xor a
- ld [wGlossaryPageNo], a
- call .display_menu
-
- xor a
- ld [wInPlayAreaCurPosition], a
- ld de, OpenGlossaryScreen_TransitionTable ; this data is stored in bank 2.
- ld hl, wMenuInputTablePointer
- ld [hl], e
- inc hl
- ld [hl], d
- ld a, $ff
- ld [wDuelInitialPrizesUpperBitsSet], a
- xor a
- ld [wCheckMenuCursorBlinkCounter], a
-.next
- ld a, $01
- ld [wVBlankOAMCopyToggle], a
- call DoFrame
- ldh a, [hKeysPressed]
- and SELECT
- jr nz, .on_select
-
- farcall YourOrOppPlayAreaScreen_HandleInput
- jr nc, .next
-
- cp -1 ; b button
- jr nz, .check_button
-
- farcall ZeroObjectPositionsWithCopyToggleOn
- ret
-
-.check_button
- push af
- farcall ZeroObjectPositionsWithCopyToggleOn
- pop af
-
- cp $09 ; $09: next page or prev page
- jr z, .change_page
-
- call .print_description
- call .display_menu
- xor a
- ld [wCheckMenuCursorBlinkCounter], a
- jr .next
-
-.on_select
- ld a, $01
- farcall PlaySFXConfirmOrCancel
-.change_page
- ld a, [wGlossaryPageNo]
- xor $01 ; swap page
- ld [wGlossaryPageNo], a
- call .print_menu
- jr .next
-
-; display glossary menu.
-.display_menu ; 1852b (6:452b)
- xor a
- ld [wTileMapFill], a
- call ZeroObjectPositions
- ld a, $01
- ld [wVBlankOAMCopyToggle], a
- call DoFrame
- call EmptyScreen
- call Set_OBJ_8x8
- farcall LoadCursorTile
-
- lb de, 5, 0
- call InitTextPrinting
- ldtx hl, PokemonCardGlossaryText
- call ProcessTextFromID
- call .print_menu
- ldtx hl, ChooseWordAndPressAButtonText
- call DrawWideTextBox_PrintText
- ret
-
-; print texts in glossary menu.
-.print_menu ; 1855a (6:455a)
- ld hl, wDefaultText
-
- ld a, TX_SYMBOL
- ld [hli], a
-
- ld a, [wGlossaryPageNo]
- add SYM_1
- ld [hli], a
-
- ld a, TX_SYMBOL
- ld [hli], a
-
- ld a, SYM_SLASH
- ld [hli], a
-
- ld a, TX_SYMBOL
- ld [hli], a
-
- ld a, SYM_2
- ld [hli], a
-
- ld [hl], TX_END
-
- lb de, 16, 1
- call InitTextPrinting
- ld hl, wDefaultText
- call ProcessText
-
- lb de, 1, 3
- call InitTextPrinting
- ld a, [wGlossaryPageNo]
- or a
- jr nz, .page_two
-
- ldtx hl, GlossaryMenuPage1Text
- jr .page_one
-
-.page_two
- ldtx hl, GlossaryMenuPage2Text
-.page_one
- call ProcessTextFromID
- ret
-
-; display glossary description.
-.print_description ; 18598 (6:4598)
- push af
- xor a
- ld [wTileMapFill], a
- call EmptyScreen
- lb de, 5, 0
- call InitTextPrinting
- ldtx hl, PokemonCardGlossaryText
- call ProcessTextFromID
- lb de, 0, 4
- lb bc, 20, 14
- call DrawRegularTextBox
-
- ld a, [wGlossaryPageNo]
- or a
- jr nz, .back_page
-
- ld hl, GlossaryData1
- jr .front_page
-
-.back_page
- ld hl, GlossaryData2
-.front_page
- pop af
- ; hl += (a + (a << 2)).
- ; that is,
- ; hl += (5 * a).
- ld c, a
- ld b, 0
- add hl, bc
- sla a
- sla a
- ld c, a
- add hl, bc
- ld a, [hli]
- push hl
- ld d, a
- ld e, $02
- call InitTextPrinting
- ld a, [hli]
- ld h, [hl]
- ld l, a
- call ProcessTextFromID
- pop hl
- lb de, 1, 5
- call InitTextPrinting
- inc hl
- inc hl
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld a, $01
- ld [wLineSeparation], a
- call ProcessTextFromID
- xor a
- ld [wLineSeparation], a
- call EnableLCD
-.loop
- call DoFrame
- ldh a, [hKeysPressed]
- and B_BUTTON
- jr z, .loop
-
- ld a, -1
- farcall PlaySFXConfirmOrCancel
- ret
-
-; unit: 5 bytes.
-; [structure]
-; horizontal align (1) / title text id (2) / desc. text id (2)
-glossary_entry: MACRO
- db \1
- tx \2
- tx \3
-ENDM
-
-GlossaryData1:
- glossary_entry 7, AboutTheDeckText, DeckDescriptionText
- glossary_entry 5, AboutTheDiscardPileText, DiscardPileDescriptionText
- glossary_entry 7, AboutTheHandText, HandDescriptionText
- glossary_entry 6, AboutTheArenaText, ArenaDescriptionText
- glossary_entry 6, AboutTheBenchText, BenchDescriptionText
- glossary_entry 4, AboutTheActivePokemonText, ActivePokemonDescriptionText
- glossary_entry 5, AboutBenchPokemonText, BenchPokemonDescriptionText
- glossary_entry 7, AboutPrizesText, PrizesDescriptionText
- glossary_entry 5, AboutDamageCountersText, DamageCountersDescriptionText
-
-GlossaryData2:
- glossary_entry 5, AboutEnergyCardsText, EnergyCardsDescriptionText
- glossary_entry 5, AboutTrainerCardsText, TrainerCardsDescriptionText
- glossary_entry 5, AboutBasicPokemonText, BasicPokemonDescriptionText
- glossary_entry 5, AboutEvolutionCardsText, EvolutionCardsDescriptionText
- glossary_entry 6, AboutAttackingText, AttackingDescriptionText
- glossary_entry 5, AboutPokemonPowerText, PokemonPowerDescriptionText
- glossary_entry 6, AboutWeaknessText, WeaknessDescriptionText
- glossary_entry 6, AboutResistanceText, ResistanceDescriptionText
- glossary_entry 6, AboutRetreatingText, RetreatingDescriptionText
-
-Func_18661: ; 18661 (6:4661)
- xor a
- ld [wPlaysSfx], a
- ld a, [wCheckMenuCursorXPosition]
- ld d, a
- ld a, [wCheckMenuCursorYPosition]
- ld e, a
- ldh a, [hDPadHeld]
- or a
- jr z, .check_button
-; check input from dpad
- bit D_LEFT_F, a
- jr nz, .left_or_right
- bit D_RIGHT_F, a
- jr z, .check_up_and_down
-.left_or_right
-; swap the lsb of x position value.
- ld a, d
- xor $1
- ld d, a
- jr .cursor_moved
-
-.check_up_and_down
- bit D_UP_F, a
- jr nz, .up_or_down
- bit D_DOWN_F, a
- jr z, .check_button
-.up_or_down
- ld a, e
- xor $1
- ld e, a
-.cursor_moved
- ld a, $1
- ld [wPlaysSfx], a
- push de
- call .draw_blank_cursor
- pop de
- ld a, d
- ld [wCheckMenuCursorXPosition], a
- ld a, e
- ld [wCheckMenuCursorYPosition], a
- xor a
- ld [wCheckMenuCursorBlinkCounter], a
-.check_button
- ldh a, [hKeysPressed]
- and A_BUTTON | B_BUTTON
- jr z, .check_cursor_moved
- and A_BUTTON
- jr nz, .a_button
-
-; b button
- ld a, -1
- call Func_190fb
- scf
- ret
-
-; a button
-.a_button
- call .draw_cursor
- ld a, 1
- call Func_190fb
- scf
- ret
-
-.check_cursor_moved
- ld a, [wPlaysSfx]
- or a
- jr z, .check_cursor_blink
- call PlaySFX
-.check_cursor_blink
- ld hl, wCheckMenuCursorBlinkCounter
- ld a, [hl]
- inc [hl]
- and %00001111
- ret nz
- ld a, SYM_CURSOR_R
- bit D_RIGHT_F, [hl]
- jr z, .draw_tile
-.draw_blank_cursor ; 186d4 (6:46d4)
- ld a, SYM_SPACE
-.draw_tile
- 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
- ; b = 11, c = y_pos * 2 + 14
- ; h = x_pos * 10, l = 10
- call WriteByteToBGMap0
- or a
- ret
-.draw_cursor ; 186f3 (6:46f3)
- ld a, SYM_CURSOR_R
- jr .draw_tile
-
-INCLUDE "data/duel/effect_commands.asm"
-
-; reads the animation commands from PointerTable_AttackAnimation
-; of attack in wLoadedAttackAnimation and plays them
-PlayAttackAnimationCommands: ; 18f9c (6:4f9c)
- ld a, [wLoadedAttackAnimation]
- or a
- ret z
-
- ld l, a
- ld h, 0
- add hl, hl
- ld de, PointerTable_AttackAnimation
- add hl, de
- ld e, [hl]
- inc hl
- ld d, [hl]
-
- push de
- ld hl, wce7e
- ld a, [hl]
- or a
- jr nz, .read_command
- ld [hl], $01
- call Func_3b21
- pop de
-
- push de
- ld a, DUEL_ANIM_SCREEN_MAIN_SCENE
- ld [wDuelAnimationScreen], a
- ld a, $01
- ld [wd4b3], a
- xor a
- ld [wDuelAnimLocationParam], a
- ld a, [de]
- cp $04
- jr z, .read_command
- ld a, DUEL_ANIM_150
- call PlayDuelAnimation
-.read_command
- pop de
- ; fallthrough
-
-PlayAttackAnimationCommands_NextCommand: ; 18fd4 (6:4fd4)
- ld a, [de]
- inc de
- ld hl, AnimationCommandPointerTable
- jp JumpToFunctionInTable
-
-AnimationCommand_AnimEnd: ; 18fdc (6:4fdc)
- ret
-
-AnimationCommand_AnimPlayer: ; 18fdd (6:4fdd)
- ldh a, [hWhoseTurn]
- ld [wDuelAnimDuelistSide], a
- ld a, [wDuelType]
- cp $00
- jr nz, AnimationCommand_AnimNormal
- ld a, PLAYER_TURN
- ld [wDuelAnimDuelistSide], a
- jr AnimationCommand_AnimNormal
-
-AnimationCommand_AnimOpponent: ; 18ff0 (6:4ff0)
- call SwapTurn
- ldh a, [hWhoseTurn]
- ld [wDuelAnimDuelistSide], a
- call SwapTurn
- ld a, [wDuelType]
- cp $00
- jr nz, AnimationCommand_AnimNormal
- ld a, OPPONENT_TURN
- ld [wDuelAnimDuelistSide], a
- jr AnimationCommand_AnimNormal
-
-AnimationCommand_AnimUnknown2: ; 19009 (6:5009)
- ld a, [wce82]
- and $7f
- ld [wDuelAnimLocationParam], a
- jr AnimationCommand_AnimNormal
-
-AnimationCommand_AnimEnd2: ; 19013 (6:5013)
- ret
-
-AnimationCommand_AnimNormal: ; 19014 (6:5014)
- ld a, [de]
- inc de
- cp DUEL_ANIM_SHOW_DAMAGE
- jr z, .show_damage
- cp DUEL_ANIM_SHAKE1
- jr z, .shake_1
- cp DUEL_ANIM_SHAKE2
- jr z, .shake_2
- cp DUEL_ANIM_SHAKE3
- jr z, .shake_3
-
-.play_anim
- call PlayDuelAnimation
- jr PlayAttackAnimationCommands_NextCommand
-
-.show_damage
- ld a, DUEL_ANIM_PRINT_DAMAGE
- call PlayDuelAnimation
- ld a, [wce81]
- ld [wd4b3], a
-
- push de
- ld hl, wce7f
- ld de, wDuelAnimDamage
- ld a, [hli]
- ld [de], a
- inc de
- ld a, [hli]
- ld [de], a
- pop de
-
- ld a, $8c
- call PlayDuelAnimation
- ld a, [wDuelDisplayedScreen]
- cp DUEL_MAIN_SCENE
- jr nz, .skip_update_hud
- ld a, DUEL_ANIM_UPDATE_HUD
- call PlayDuelAnimation
-.skip_update_hud
- jp PlayAttackAnimationCommands_NextCommand
-
-; screen shake happens differently
-; depending on whose turn it is
-.shake_1
- ld c, DUEL_ANIM_SMALL_SHAKE_X
- ld b, DUEL_ANIM_SMALL_SHAKE_Y
- jr .check_duelist
-
-.shake_2
- ld c, DUEL_ANIM_BIG_SHAKE_X
- ld b, DUEL_ANIM_BIG_SHAKE_Y
- jr .check_duelist
-
-.shake_3
- ld c, DUEL_ANIM_SMALL_SHAKE_Y
- ld b, DUEL_ANIM_SMALL_SHAKE_X
-
-.check_duelist
- ldh a, [hWhoseTurn]
- cp PLAYER_TURN
- ld a, c
- jr z, .play_anim
- ld a, [wDuelType]
- cp $00
- ld a, c
- jr z, .play_anim
- ld a, b
- jr .play_anim
-
-AnimationCommand_AnimUnknown: ; 19079 (6:5079)
- ld a, [de]
- inc de
- ld [wd4b3], a
- ld a, [wce82]
- ld [wDuelAnimLocationParam], a
- call SetDuelAnimationScreen
- ld a, DUEL_ANIM_150
- call PlayDuelAnimation
- jp PlayAttackAnimationCommands_NextCommand
-
-AnimationCommandPointerTable: ; 1908f (6:508f)
- dw AnimationCommand_AnimEnd ; anim_end
- dw AnimationCommand_AnimNormal ; anim_normal
- dw AnimationCommand_AnimPlayer ; anim_player
- dw AnimationCommand_AnimOpponent ; anim_opponent
- dw AnimationCommand_AnimUnknown ; anim_unknown
- dw AnimationCommand_AnimUnknown2 ; anim_unknown2
- dw AnimationCommand_AnimEnd2 ; anim_end2 (unused)
-
-; sets wDuelAnimationScreen according to wd4b3
-; if wd4b3 == $01, set it to Main Scene
-; if wd4b3 == $04, st it to Play Area scene
-SetDuelAnimationScreen: ; 1909d (6:509d)
- ld a, [wd4b3]
- cp $04
- jr z, .set_play_area_screen
- cp $01
- ret nz
- ld a, DUEL_ANIM_SCREEN_MAIN_SCENE
- ld [wDuelAnimationScreen], a
- ret
-
-.set_play_area_screen
- ld a, [wDuelAnimLocationParam]
- ld l, a
- ld a, [wWhoseTurn]
- ld h, a
- cp PLAYER_TURN
- jr z, .player
-
-; opponent
- ld a, [wDuelType]
- cp $00
- jr z, .asm_50c6
-
-; link duel or vs. AI
- bit 7, l
- jr z, .asm_50e2
- jr .asm_50d2
-
-.asm_50c6
- bit 7, l
- jr z, .asm_50da
- jr .asm_50ea
-
-.player
- bit 7, l
- jr z, .asm_50d2
- jr .asm_50e2
-
-.asm_50d2
- ld l, UNKNOWN_SCREEN_4
- ld h, PLAYER_TURN
- ld a, DUEL_ANIM_SCREEN_PLAYER_PLAY_AREA
- jr .ok
-.asm_50da
- ld l, UNKNOWN_SCREEN_4
- ld h, OPPONENT_TURN
- ld a, DUEL_ANIM_SCREEN_PLAYER_PLAY_AREA
- jr .ok
-.asm_50e2
- ld l, UNKNOWN_SCREEN_5
- ld h, OPPONENT_TURN
- ld a, DUEL_ANIM_SCREEN_OPP_PLAY_AREA
- jr .ok
-.asm_50ea
- ld l, UNKNOWN_SCREEN_5
- ld h, PLAYER_TURN
- ld a, DUEL_ANIM_SCREEN_OPP_PLAY_AREA
-
-.ok
- ld [wDuelAnimationScreen], a
- ret
-
-Func_190f4: ; 190f4 (6:50f4)
- ld a, [wd4b3]
- cp $04
- jr z, Func_1910f
- ; fallthrough
-
-Func_190fb: ; 190fb (6:50fb)
- cp $01
- jr nz, .asm_510e
- ld a, DUEL_ANIM_SCREEN_MAIN_SCENE
- ld [wDuelAnimationScreen], a
- ld a, [wDuelDisplayedScreen]
- cp $01
- jr z, .asm_510e
- bank1call DrawDuelMainScene
-.asm_510e
- ret
-
-Func_1910f: ; 1910f (6:510f)
- call SetDuelAnimationScreen
- ld a, [wDuelDisplayedScreen]
- cp l
- jr z, .skip_change_screen
- ld a, l
- push af
- ld l, PLAYER_TURN
- ld a, [wDuelType]
- cp $00
- jr nz, .asm_5127
- ld a, [wWhoseTurn]
- ld l, a
-.asm_5127
- call DrawYourOrOppPlayAreaScreen_Bank0
- pop af
- ld [wDuelDisplayedScreen], a
-.skip_change_screen
- call DrawWideTextBox
- ret
-
-; prints text related to the damage received
-; by card stored in wTempNonTurnDuelistCardID
-; takes into account type effectiveness
-PrintDamageText: ; 19132 (6:5132)
- push hl
- push bc
- push de
- ld a, [wLoadedAttackAnimation]
- cp ATK_ANIM_HEAL
- jr z, .skip
- cp ATK_ANIM_HEALING_WIND_PLAY_AREA
- jr z, .skip
-
- ld a, [wTempNonTurnDuelistCardID]
- ld e, a
- ld d, $00
- call LoadCardDataToBuffer1_FromCardID
- ld a, 18
- call CopyCardNameAndLevel
- ld [hl], TX_END
- ld hl, wTxRam2
- xor a
- ld [hli], a
- ld [hl], a
- ld hl, wce7f
- ld a, [hli]
- ld h, [hl]
- ld l, a
- call GetDamageText
- ld a, l
- or h
- call nz, DrawWideTextBox_PrintText
-.skip
- pop de
- pop bc
- pop hl
- ret
-
-; returns in hl the text id associated with
-; the damage in hl and its effectiveness
-GetDamageText: ; 19168 (6:5168)
- ld a, l
- or h
- jr z, .no_damage
- call LoadTxRam3
- ld a, [wce81]
- ldtx hl, AttackDamageText
- and (1 << RESISTANCE) | (1 << WEAKNESS)
- ret z ; not weak or resistant
- ldtx hl, WeaknessMoreDamage2Text
- cp (1 << RESISTANCE) | (1 << WEAKNESS)
- ret z ; weak and resistant
- and (1 << WEAKNESS)
- ldtx hl, WeaknessMoreDamageText
- ret nz ; weak
- ldtx hl, ResistanceLessDamageText
- ret ; resistant
-
-.no_damage
- call CheckNoDamageOrEffect
- ret c
- ldtx hl, NoDamageText
- ld a, [wce81]
- and (1 << RESISTANCE)
- ret z ; not resistant
- ldtx hl, ResistanceNoDamageText
- ret ; resistant
-
-UpdateMainSceneHUD: ; 19199 (6:5199)
- ld a, [wDuelDisplayedScreen]
- cp DUEL_MAIN_SCENE
- ret nz
- bank1call DrawDuelHUDs
- ret
-
-Func_191a3: ; 191a3 (6:51a3)
- ret
-
-INCLUDE "data/duel/animations/attack_animations.asm"
-
-; if carry flag is set, only delays
-; if carry not set:
-; - set rRP to $c1, wait;
-; - set rRP to $c0, wait;
-; - return
-Func_19674: ; 19674 (6:5674)
- jr c, .delay_once
- ld [hl], $c1
- ld a, 5
- jr .loop_delay_1 ; jump to possibly to add more cycles?
-.loop_delay_1
- dec a
- jr nz, .loop_delay_1
- ld [hl], $c0
- ld a, 14
- jr .loop_delay_2 ; jump to possibly to add more cycles?
-.loop_delay_2
- dec a
- jr nz, .loop_delay_2
- ret
-
-.delay_once
- ld a, 21
- jr .loop_delay_3 ; jump to possibly to add more cycles?
-.loop_delay_3
- dec a
- jr nz, .loop_delay_3
- nop
- ret
-
-; input a = byte to transmit through IR
-TransmitByteThroughIR: ; 19692 (6:5692)
- push hl
- ld hl, rRP
- push de
- push bc
- ld b, a
- scf ; carry set
- call Func_19674
- or a ; carry not set
- call Func_19674
- ld c, 8
- ld c, 8 ; number of input bits
-.loop
- ld a, $00
- rr b
- call Func_19674
- dec c
- jr nz, .loop
- pop bc
- pop de
- pop hl
- ldh a, [rJOYP]
- bit 1, a ; P11
- jr z, ReturnZFlagUnsetAndCarryFlagSet
- xor a ; return z set
- ret
-
-; same as ReceiveByteThroughIR but
-; returns $0 in a if there's an error in IR
-ReceiveByteThroughIR_ZeroIfUnsuccessful: ; 196ba (6:56ba)
- call ReceiveByteThroughIR
- ret nc
- xor a
- ret
-
-; returns carry if there's some time out
-; and output in register a of $ff
-; otherwise returns in a some sequence of bits
-; related to how rRP sets/unsets bit 1
-ReceiveByteThroughIR: ; 196c0 (6:56c0)
- push de
- push bc
- push hl
-
-; waits for bit 1 in rRP to be unset
-; up to $100 loops
- ld b, 0
- ld hl, rRP
-.wait_ir
- bit 1, [hl]
- jr z, .ok
- dec b
- jr nz, .wait_ir
- ; looped around $100 times
- ; return $ff and carry set
- pop hl
- pop bc
- pop de
- scf
- ld a, $ff
- ret
-
-.ok
-; delay for some cycles
- ld a, 15
-.loop_delay
- dec a
- jr nz, .loop_delay
-
-; loop for each bit
- ld e, 8
-.loop
- ld a, $01
- ; possibly delay cycles?
- ld b, 9
- ld b, 9
- ld b, 9
- ld b, 9
-
-; checks for bit 1 in rRP
-; if in any of the checks it is unset,
-; then a is set to 0
-; this is done a total of 9 times
- bit 1, [hl]
- jr nz, .asm_196ec
- xor a
-.asm_196ec
- bit 1, [hl]
- jr nz, .asm_196f1
- xor a
-.asm_196f1
- dec b
- jr nz, .asm_196ec
- ; one bit received
- rrca
- rr d
- dec e
- jr nz, .loop
- ld a, d ; has bits set for each "cycle" that bit 1 was not unset
- pop hl
- pop bc
- pop de
- or a
- ret
-
-ReturnZFlagUnsetAndCarryFlagSet: ; 19700 (6:5700)
- ld a, $ff
- or a ; z not set
- scf ; carry set
- ret
-
-; called when expecting to transmit data
-Func_19705: ; 19705 (6:5705)
- ld hl, rRP
-.asm_19708
- ldh a, [rJOYP]
- bit 1, a
- jr z, ReturnZFlagUnsetAndCarryFlagSet
- ld a, $aa ; request
- call TransmitByteThroughIR
- push hl
- pop hl
- call ReceiveByteThroughIR_ZeroIfUnsuccessful
- cp $33 ; acknowledge
- jr nz, .asm_19708
- xor a
- ret
-
-; called when expecting to receive data
-Func_1971e: ; 1971e (6:571e)
- ld hl, rRP
-.asm_19721
- ldh a, [rJOYP]
- bit 1, a
- jr z, ReturnZFlagUnsetAndCarryFlagSet
- call ReceiveByteThroughIR_ZeroIfUnsuccessful
- cp $aa ; request
- jr nz, .asm_19721
- ld a, $33 ; acknowledge
- call TransmitByteThroughIR
- xor a
- ret
-
-ReturnZFlagUnsetAndCarryFlagSet2: ; 19735 (6:5735)
- jp ReturnZFlagUnsetAndCarryFlagSet
-
-TransmitIRDataBuffer: ; 19738 (6:5738)
- call Func_19705
- jr c, ReturnZFlagUnsetAndCarryFlagSet2
- ld a, $49
- call TransmitByteThroughIR
- ld a, $52
- call TransmitByteThroughIR
- ld hl, wIRDataBuffer
- ld c, 8
- jr TransmitNBytesFromHLThroughIR
-
-ReceiveIRDataBuffer: ; 1974e (6:5738)
- call Func_1971e
- jr c, ReturnZFlagUnsetAndCarryFlagSet2
- call ReceiveByteThroughIR
- cp $49
- jr nz, ReceiveIRDataBuffer
- call ReceiveByteThroughIR
- cp $52
- jr nz, ReceiveIRDataBuffer
- ld hl, wIRDataBuffer
- ld c, 8
- jr ReceiveNBytesToHLThroughIR
-
-; hl = start of data to transmit
-; c = number of bytes to transmit
-TransmitNBytesFromHLThroughIR: ; 19768 (6:5768)
- ld b, $0
-.loop_data_bytes
- ld a, b
- add [hl]
- ld b, a
- ld a, [hli]
- call TransmitByteThroughIR
- jr c, .asm_1977c
- dec c
- jr nz, .loop_data_bytes
- ld a, b
- cpl
- inc a
- call TransmitByteThroughIR
-.asm_1977c
- ret
-
-; hl = address to write received data
-; c = number of bytes to be received
-ReceiveNBytesToHLThroughIR: ; 1977d (6:577d)
- ld b, 0
-.loop_data_bytes
- call ReceiveByteThroughIR
- jr c, ReturnZFlagUnsetAndCarryFlagSet2
- ld [hli], a
- add b
- ld b, a
- dec c
- jr nz, .loop_data_bytes
- call ReceiveByteThroughIR
- add b
- or a
- jr nz, ReturnZFlagUnsetAndCarryFlagSet2
- ret
-
-; disables interrupts, and sets joypad and IR communication port
-; switches to CGB normal speed
-StartIRCommunications: ; 19792 (6:5792)
- di
- call SwitchToCGBNormalSpeed
- ld a, P14
- ldh [rJOYP], a
- ld a, $c0
- ldh [rRP], a
- ret
-
-; reenables interrupts, and switches CGB back to double speed
-CloseIRCommunications: ; 1979f (6:579f)
- ld a, P14 | P15
- ldh [rJOYP], a
-.wait_vblank_on
- ldh a, [rSTAT]
- and STAT_LCDC_STATUS
- cp STAT_ON_VBLANK
- jr z, .wait_vblank_on
-.wait_vblank_off
- ldh a, [rSTAT]
- and STAT_LCDC_STATUS
- cp STAT_ON_VBLANK
- jr nz, .wait_vblank_off
- call SwitchToCGBDoubleSpeed
- ei
- ret
-
-; set rRP to 0
-ClearRP: ; 197b8 (6:57b8)
- ld a, $00
- ldh [rRP], a
- ret
-
-; expects to receive a command (IRCMD_* constant)
-; in wIRDataBuffer + 1, then calls the subroutine
-; corresponding to that command
-ExecuteReceivedIRCommands: ; 197bd (6:57bd)
- call StartIRCommunications
-.loop_commands
- call ReceiveIRDataBuffer
- jr c, .error
- jr nz, .loop_commands
- ld hl, wIRDataBuffer + 1
- ld a, [hl]
- ld hl, .CmdPointerTable
- cp NUM_IR_COMMANDS
- jr nc, .loop_commands ; invalid command
- call .JumpToCmdPointer ; execute command
- jr .loop_commands
-.error
- call CloseIRCommunications
- xor a
- scf
- ret
-
-.JumpToCmdPointer
- add a ; *2
- add l
- ld l, a
- ld a, 0
- adc h
- ld h, a
- ld a, [hli]
- ld h, [hl]
- ld l, a
-.jp_hl
- jp hl
-
-.CmdPointerTable
- dw .Close ; IRCMD_CLOSE
- dw .ReturnWithoutClosing ; IRCMD_RETURN_WO_CLOSING
- dw .TransmitData ; IRCMD_TRANSMIT_DATA
- dw .ReceiveData ; IRCMD_RECEIVE_DATA
- dw .CallFunction ; IRCMD_CALL_FUNCTION
-
-; closes the IR communications
-; pops hl so that the sp points
-; to the return address of ExecuteReceivedIRCommands
-.Close
- pop hl
- call CloseIRCommunications
- or a
- ret
-
-; returns without closing the IR communications
-; will continue the command loop
-.ReturnWithoutClosing
- or a
- ret
-
-; receives an address and number of bytes
-; and transmits starting at that address
-.TransmitData
- call Func_19705
- ret c
- call LoadRegistersFromIRDataBuffer
- jp TransmitNBytesFromHLThroughIR
-
-; receives an address and number of bytes
-; and writes the data received to that address
-.ReceiveData
- call LoadRegistersFromIRDataBuffer
- ld l, e
- ld h, d
- call ReceiveNBytesToHLThroughIR
- jr c, .asm_19812
- sub b
- call TransmitByteThroughIR
-.asm_19812
- ret
-
-; receives an address to call, then stores
-; the registers in the IR data buffer
-.CallFunction
- call LoadRegistersFromIRDataBuffer
- call .jp_hl
- call StoreRegistersInIRDataBuffer
- ret
-
-; returns carry set if request sent was not acknowledged
-TrySendIRRequest: ; 1981d (6:581d)
- call StartIRCommunications
- ld hl, rRP
- ld c, 4
-.send_request
- ld a, $aa ; request
- push bc
- call TransmitByteThroughIR
- push bc
- pop bc
- call ReceiveByteThroughIR_ZeroIfUnsuccessful
- pop bc
- cp $33 ; acknowledgement
- jr z, .received_ack
- dec c
- jr nz, .send_request
- scf
- jr .close
-
-.received_ack
- xor a
-.close
- push af
- call CloseIRCommunications
- pop af
- ret
-
-; returns carry set if request was not received
-TryReceiveIRRequest: ; 19842 (6:5842)
- call StartIRCommunications
- ld hl, rRP
-.wait_request
- call ReceiveByteThroughIR_ZeroIfUnsuccessful
- cp $aa ; request
- jr z, .send_ack
- ldh a, [rJOYP]
- cpl
- and P10 | P11
- jr z, .wait_request
- scf
- jr .close
-
-.send_ack
- ld a, $33 ; acknowledgement
- call TransmitByteThroughIR
- xor a
-.close
- push af
- call CloseIRCommunications
- pop af
- ret
-
-; sends request for other device to close current communication
-RequestCloseIRCommunication: ; 19865 (6:5865)
- call StartIRCommunications
- ld a, IRCMD_CLOSE
- ld [wIRDataBuffer + 1], a
- call TransmitIRDataBuffer
-; fallthrough
-
-; calls CloseIRCommunications while preserving af
-SafelyCloseIRCommunications: ; 19870 (6:5870)
- push af
- call CloseIRCommunications
- pop af
- ret
-
-; sends a request for data to be transmitted
-; from the other device
-; hl = start of data to request to transmit
-; de = address to write data received
-; c = length of data
-RequestDataTransmissionThroughIR: ; 19876 (6:5876)
- ld a, IRCMD_TRANSMIT_DATA
- call TransmitRegistersThroughIR
- push de
- push bc
- call Func_1971e
- pop bc
- pop hl
- jr c, SafelyCloseIRCommunications
- call ReceiveNBytesToHLThroughIR
- jr SafelyCloseIRCommunications
-
-; transmits data to be written in the other device
-; hl = start of data to transmit
-; de = address for other device to write data
-; c = length of data
-RequestDataReceivalThroughIR: ; 19889 (6:5889)
- ld a, IRCMD_RECEIVE_DATA
- call TransmitRegistersThroughIR
- call TransmitNBytesFromHLThroughIR
- jr c, SafelyCloseIRCommunications
- call ReceiveByteThroughIR
- jr c, SafelyCloseIRCommunications
- add b
- jr nz, .asm_1989e
- xor a
- jr SafelyCloseIRCommunications
-.asm_1989e
- call ReturnZFlagUnsetAndCarryFlagSet
- jr SafelyCloseIRCommunications
-
-; first stores all the current registers in wIRDataBuffer
-; then transmits it through IR
-TransmitRegistersThroughIR: ; 198a3 (6:58a3)
- push hl
- push de
- push bc
- call StoreRegistersInIRDataBuffer
- call StartIRCommunications
- call TransmitIRDataBuffer
- pop bc
- pop de
- pop hl
- ret nc
- inc sp
- inc sp
- jr SafelyCloseIRCommunications
-
-; stores af, hl, de and bc in wIRDataBuffer
-StoreRegistersInIRDataBuffer: ; 198b7 (6:58b7)
- push de
- push hl
- push af
- ld hl, wIRDataBuffer
- pop de
- ld [hl], e ; <- f
- inc hl
- ld [hl], d ; <- a
- inc hl
- pop de
- ld [hl], e ; <- l
- inc hl
- ld [hl], d ; <- h
- inc hl
- pop de
- ld [hl], e ; <- e
- inc hl
- ld [hl], d ; <- d
- inc hl
- ld [hl], c ; <- c
- inc hl
- ld [hl], b ; <- b
- ret
-
-; loads all the registers that were stored
-; from StoreRegistersInIRDataBuffer
-LoadRegistersFromIRDataBuffer: ; 198d0 (6:58d0)
- ld hl, wIRDataBuffer
- ld e, [hl]
- inc hl
- ld d, [hl]
- inc hl
- push de
- ld e, [hl]
- inc hl
- ld d, [hl]
- inc hl
- push de
- ld e, [hl]
- inc hl
- ld d, [hl]
- inc hl
- ld c, [hl]
- inc hl
- ld b, [hl]
- pop hl
- pop af
- ret
-
-; empties screen and replaces
-; wVBlankFunctionTrampoline with HandleAllSpriteAnimations
-Func_198e7: ; 198e7 (6:58e7)
- call EmptyScreen
- call Set_OBJ_8x8
- call Func_3ca4
- lb de, $38, $7f
- call SetupText
- ld hl, wVBlankFunctionTrampoline + 1
- ld de, wVBlankFunctionTrampolineBackup
- call BackupVBlankFunctionTrampoline
- di
- ld [hl], LOW(HandleAllSpriteAnimations)
- inc hl
- ld [hl], HIGH(HandleAllSpriteAnimations)
- ei
- ret
-
-; sets backup VBlank function as wVBlankFunctionTrampoline
-RestoreVBlankFunction: ; 19907 (6:5907)
- ld hl, wVBlankFunctionTrampolineBackup
- ld de, wVBlankFunctionTrampoline + 1
- call BackupVBlankFunctionTrampoline
- call Func_3ca4
- bank1call ZeroObjectPositionsAndToggleOAMCopy
- ret
-
-; copies 2 bytes from hl to de while interrupts are disabled
-; used to load or store wVBlankFunctionTrampoline
-; to wVBlankFunctionTrampolineBackup
-BackupVBlankFunctionTrampoline: ; 19917 (6:5917)
- di
- ld a, [hli]
- ld [de], a
- inc de
- ld a, [hld]
- ld [de], a
- ei
- ret
-
-Func_1991f: ; 1991f (6:591f)
- add a
- ld e, a
- ld d, 0
- ld hl, .data
- add hl, de
- ld a, PLAYER_TURN
- ldh [hWhoseTurn], a
- ld a, [hli]
- add $02
- push hl
- ld hl, sDeck1Name
- call CopyDeckNameAndCards
- pop hl
- call SwapTurn
- ld a, [hli]
- add $02
- call LoadDeck
- call SwapTurn
- call EnableSRAM
- ld h, $a1
- ld de, wPlayerDeck
- ld c, $3c
-.asm_594c
- ld a, [de]
- inc de
- ld l, a
- res 7, [hl]
- dec c
- jr nz, .asm_594c
-
- ld h, $a1
- ld de, wOpponentDeck
- ld c, $1e
-.asm_595b
- ld a, [de]
- inc de
- ld l, a
- res 7, [hl]
- inc [hl]
- dec c
- jr nz, .asm_595b
-
- call DisableSRAM
- ret
-.data
- db $03, $04, $05, $06, $07, $08
-
-; 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, sCardAndDeckSaveData
- ld bc, sCardAndDeckSaveDataEnd - sCardAndDeckSaveData
-.loop_clear
- xor a
- ld [hli], a
- dec bc
- ld a, c
- or b
- jr nz, .loop_clear
-
-; add the starter decks
- ld a, CHARMANDER_AND_FRIENDS_DECK
- ld hl, sSavedDeck1
- call CopyDeckNameAndCards
- ld a, SQUIRTLE_AND_FRIENDS_DECK
- ld hl, sSavedDeck2
- call CopyDeckNameAndCards
- ld a, BULBASAUR_AND_FRIENDS_DECK
- ld hl, sSavedDeck3
- call CopyDeckNameAndCards
-
-; marks all cards in Collection to not owned
- call EnableSRAM
- ld hl, sCardCollection
- ld a, CARD_NOT_OWNED
-.loop_collection
- ld [hl], a
- inc l
- jr nz, .loop_collection
-
- ld hl, sCurrentDuel
- xor 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
- ld [hl], $0
- ld de, NAME_BUFFER_LENGTH
- add hl, de
- 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 InitPromotionalCardAndDeckCounterSaveData
- call DisableSRAM
- ret
-
-; input:
-; a = Deck ID
-; hl = destination to copy
-CopyDeckNameAndCards: ; 199e0 (6:59e0)
- push de
- push bc
- push hl
- call LoadDeck
- jr c, .done
- call .CopyDeckName
- pop hl
- call EnableSRAM
- push hl
- ld de, wDefaultText
-.loop_write_name
- ld a, [de]
- inc de
- ld [hli], a
- or a
- jr nz, .loop_write_name
- pop hl
-
- push hl
- ld de, DECK_NAME_SIZE
- add hl, de
- ld de, wPlayerDeck
- ld c, DECK_SIZE
-.loop_write_cards
- ld a, [de]
- inc de
- ld [hli], a
- dec c
- jr nz, .loop_write_cards
- call DisableSRAM
- or a
-.done
- pop hl
- pop bc
- pop de
- ret
-
-.CopyDeckName
- ld hl, wDeckName
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld de, wDefaultText
- call CopyText
- ret
-
-; hl = text ID
-LoadLinkConnectingScene: ; 19a1f (6:5a1f)
- push hl
- call Func_198e7
- ld a, SCENE_GAMEBOY_LINK_CONNECTING
- lb bc, 0, 0
- call LoadScene
- pop hl
- call DrawWideTextBox_PrintText
- call EnableLCD
- ret
-
-; shows Link Not Connected scene
-; then asks the player whether they want to try again
-; if the player selects "no", return carry
-; input:
-; - hl = text ID
-LoadLinkNotConnectedSceneAndAskWhetherToTryAgain: ; 19a33 (6:5a33)
- push hl
- call RestoreVBlankFunction
- call Func_198e7
- ld a, SCENE_GAMEBOY_LINK_NOT_CONNECTED
- lb bc, 0, 0
- call LoadScene
- pop hl
- call DrawWideTextBox_WaitForInput
- ldtx hl, WouldYouLikeToTryAgainText
- call YesOrNoMenuWithText_SetCursorToYes
-; fallthrough
-
-ClearRPAndRestoreVBlankFunction: ; 19a4c (6:5a4c)
- push af
- call ClearRP
- call RestoreVBlankFunction
- pop af
- ret
-
-; prepares IR communication parameter data
-; a = a IRPARAM_* constant for the function of this connection
-InitIRCommunications: ; 19a55 (6:5a55)
- ld hl, wOwnIRCommunicationParams
- ld [hl], a
- inc hl
- ld [hl], $50
- inc hl
- ld [hl], $4b
- inc hl
- ld [hl], $31
- ld a, $ff
- ld [wIRCommunicationErrorCode], a
- ld a, PLAYER_TURN
- ldh [hWhoseTurn], a
-; clear wNameBuffer and wOpponentName
- xor a
- ld [wNameBuffer], a
- ld hl, wOpponentName
- ld [hli], a
- ld [hl], a
-; loads player's name from SRAM
-; to wDefaultText
- call EnableSRAM
- ld hl, sPlayerName
- ld de, wDefaultText
- ld c, NAME_BUFFER_LENGTH
-.loop
- ld a, [hli]
- ld [de], a
- inc de
- dec c
- jr nz, .loop
- call DisableSRAM
- ret
-
-; returns carry if communication was unsuccessful
-; if a = 0, then it was a communication error
-; if a = 1, then operation was cancelled by the player
-PrepareSendCardOrDeckConfigurationThroughIR: ; 19a89 (6:5a89)
- call InitIRCommunications
-
-; pressing A button triggers request for IR communication
-.loop_frame
- call DoFrame
- ldh a, [hKeysPressed]
- bit B_BUTTON_F, a
- jr nz, .b_btn
- ldh a, [hKeysHeld]
- bit A_BUTTON_F, a
- jr z, .loop_frame
-; a btn
- call TrySendIRRequest
- jr nc, .request_success
- or a
- jr z, .loop_frame
- xor a
- scf
- ret
-
-.b_btn
- ; cancelled by the player
- ld a, $01
- scf
- ret
-
-.request_success
- call ExchangeIRCommunicationParameters
- ret c
- ld a, [wOtherIRCommunicationParams + 3]
- cp $31
- jr nz, SetIRCommunicationErrorCode_Error
- or a
- ret
-
-; exchanges player names and IR communication parameters
-; checks whether parameters for communication match
-; and if they don't, an error is issued
-ExchangeIRCommunicationParameters: ; 19ab7 (6:5ab7)
- ld hl, wOwnIRCommunicationParams
- ld de, wOtherIRCommunicationParams
- ld c, 4
- call RequestDataTransmissionThroughIR
- jr c, .error
- ld hl, wOtherIRCommunicationParams + 1
- ld a, [hli]
- cp $50
- jr nz, .error
- ld a, [hli]
- cp $4b
- jr nz, .error
- ld a, [wOwnIRCommunicationParams]
- ld hl, wOtherIRCommunicationParams
- cp [hl] ; do parameters match?
- jr nz, SetIRCommunicationErrorCode_Error
-
-; receives wDefaultText from other device
-; and writes it to wNameBuffer
- ld hl, wDefaultText
- ld de, wNameBuffer
- ld c, NAME_BUFFER_LENGTH
- call RequestDataTransmissionThroughIR
- jr c, .error
-; transmits wDefaultText to be
-; written in wNameBuffer in the other device
- ld hl, wDefaultText
- ld de, wNameBuffer
- ld c, NAME_BUFFER_LENGTH
- call RequestDataReceivalThroughIR
- jr c, .error
- or a
- ret
-
-.error
- xor a
- scf
- ret
-
-SetIRCommunicationErrorCode_Error: ; 19af9 (6:5af9)
- ld hl, wIRCommunicationErrorCode
- ld [hl], $01
- ld de, wIRCommunicationErrorCode
- ld c, 1
- call RequestDataReceivalThroughIR
- call RequestCloseIRCommunication
- ld a, $01
- scf
- ret
-
-SetIRCommunicationErrorCode_NoError: ; 19b0d (6:5b0d)
- ld hl, wOwnIRCommunicationParams
- ld [hl], $00
- ld de, wIRCommunicationErrorCode
- ld c, 1
- call RequestDataReceivalThroughIR
- ret c
- call RequestCloseIRCommunication
- or a
- ret
-
-; makes device receptive to receive data from other device
-; to write in wDuelTempList (either list of cards or a deck configuration)
-; returns carry if some error occurred
-TryReceiveCardOrDeckConfigurationThroughIR: ; 19b20 (6:5b20)
- call InitIRCommunications
-.loop_receive_request
- xor a
- ld [wDuelTempList], a
- call TryReceiveIRRequest
- jr nc, .receive_data
- bit 1, a
- jr nz, .cancelled
- jr .loop_receive_request
-.receive_data
- call ExecuteReceivedIRCommands
- ld a, [wIRCommunicationErrorCode]
- or a
- ret z ; no error
- xor a
- scf
- ret
-
-.cancelled
- ld a, $01
- scf
- ret
-
-; returns carry if card(s) wasn't successfully sent
-_SendCard: ; 19b41 (6:5b41)
- call StopMusic
- ldtx hl, SendingACardText
- call LoadLinkConnectingScene
- ld a, IRPARAM_SEND_CARDS
- call PrepareSendCardOrDeckConfigurationThroughIR
- jr c, .fail
-
- ; send cards
- xor a
- ld [wDuelTempList + DECK_SIZE], a
- ld hl, wDuelTempList
- ld e, l
- ld d, h
- ld c, DECK_SIZE + 1
- call RequestDataReceivalThroughIR
- jr c, .fail
- call SetIRCommunicationErrorCode_NoError
- jr c, .fail
- call ExecuteReceivedIRCommands
- jr c, .fail
- ld a, [wOwnIRCommunicationParams + 1]
- cp $4f
- jr nz, .fail
- call PlayCardPopSong
- xor a
- call ClearRPAndRestoreVBlankFunction
- ret
-
-.fail
- call PlayCardPopSong
- ldtx hl, CardTransferWasntSuccessful1Text
- call LoadLinkNotConnectedSceneAndAskWhetherToTryAgain
- jr nc, _SendCard ; loop back and try again
- ; failed
- scf
- ret
-
-PlayCardPopSong: ; 19b87 (6:5b87)
- ld a, MUSIC_CARD_POP
- jp PlaySong
-
-_ReceiveCard: ; 19b8c (6:5b8c)
- call StopMusic
- ldtx hl, ReceivingACardText
- call LoadLinkConnectingScene
- ld a, IRPARAM_SEND_CARDS
- call TryReceiveCardOrDeckConfigurationThroughIR
- ld a, $4f
- ld [wOwnIRCommunicationParams + 1], a
- ld hl, wOwnIRCommunicationParams
- ld e, l
- ld d, h
- ld c, 4
- call RequestDataReceivalThroughIR
- jr c, .fail
- call RequestCloseIRCommunication
- jr c, .fail
- call PlayCardPopSong
- or a
- call ClearRPAndRestoreVBlankFunction
- ret
-
-.fail
- call PlayCardPopSong
- ldtx hl, CardTransferWasntSuccessful2Text
- call LoadLinkNotConnectedSceneAndAskWhetherToTryAgain
- jr nc, _ReceiveCard
- scf
- ret
-
-_SendDeckConfiguration: ; 19bc5 (6:5bc5)
- call StopMusic
- ldtx hl, SendingADeckConfigurationText
- call LoadLinkConnectingScene
- ld a, IRPARAM_SEND_DECK
- call PrepareSendCardOrDeckConfigurationThroughIR
- jr c, .fail
- ld hl, wDuelTempList
- ld e, l
- ld d, h
- ld c, DECK_STRUCT_SIZE
- call RequestDataReceivalThroughIR
- jr c, .fail
- call SetIRCommunicationErrorCode_NoError
- jr c, .fail
- call PlayCardPopSong
- call ClearRPAndRestoreVBlankFunction
- or a
- ret
-
-.fail
- call PlayCardPopSong
- ldtx hl, DeckConfigurationTransferWasntSuccessful1Text
- call LoadLinkNotConnectedSceneAndAskWhetherToTryAgain
- jr nc, _SendDeckConfiguration
- scf
- ret
-
-_ReceiveDeckConfiguration: ; 19bfb (6:5bfb)
- call StopMusic
- ldtx hl, ReceivingDeckConfigurationText
- call LoadLinkConnectingScene
- ld a, IRPARAM_SEND_DECK
- call TryReceiveCardOrDeckConfigurationThroughIR
- jr c, .fail
- call PlayCardPopSong
- call ClearRPAndRestoreVBlankFunction
- or a
- ret
-
-.fail
- call PlayCardPopSong
- ldtx hl, DeckConfigurationTransferWasntSuccessful2Text
- call LoadLinkNotConnectedSceneAndAskWhetherToTryAgain
- jr nc, _ReceiveDeckConfiguration ; loop back and try again
- scf
- ret
-
-_DoCardPop: ; 19c20 (6:5c20)
-; loads scene for Card Pop! screen
-; then checks if console is SGB
-; and issues an error message in case it is
- call Func_198e7
- ld a,SCENE_CARD_POP
- lb bc, 0, 0
- call LoadScene
- ldtx hl, AreYouBothReadyToCardPopText
- call PrintScrollableText_NoTextBoxLabel
- call RestoreVBlankFunction
- ldtx hl, CardPopCannotBePlayedWithTheGameBoyText
- ld a, [wConsole]
- cp CONSOLE_SGB
- jr z, .error
-
-; initiate the communications
- call PauseSong
- call Func_198e7
- ld a, SCENE_GAMEBOY_LINK_CONNECTING
- lb bc, 0, 0
- call LoadScene
- ldtx hl, PositionGameBoyColorsAndPressAButtonText
- call DrawWideTextBox_PrintText
- call EnableLCD
- call HandleCardPopCommunications
- push af
- push hl
- call ClearRP
- call RestoreVBlankFunction
- pop hl
- pop af
- jr c, .error
-
-; show the received card detail page
-; and play the corresponding song
- ld a, [wLoadedCard1ID]
- call AddCardToCollectionAndUpdateAlbumProgress
- ld hl, wLoadedCard1Name
- ld a, [hli]
- ld h, [hl]
- ld l, a
- call LoadTxRam2
- ld a, PLAYER_TURN
- ldh [hWhoseTurn], a
- ld a, SFX_5D
- call PlaySFX
-.wait_sfx
- call AssertSFXFinished
- or a
- jr nz, .wait_sfx
- ld a, [wCardPopCardObtainSong]
- call PlaySong
- ldtx hl, ReceivedThroughCardPopText
- bank1call _DisplayCardDetailScreen
- call ResumeSong
- lb de, $38, $9f
- call SetupText
- bank1call OpenCardPage_FromHand
- ret
-
-.error
-; show Card Pop! error scene
-; and print text in hl
- push hl
- call ResumeSong
- call Func_198e7
- ld a, SCENE_CARD_POP_ERROR
- lb bc, 0, 0
- call LoadScene
- pop hl
- call PrintScrollableText_NoTextBoxLabel
- call RestoreVBlankFunction
- ret
-
-; handles all communications to the other device to do Card Pop!
-; returns carry if Card Pop! is unsuccessful
-; and returns in hl the corresponding error text ID
-HandleCardPopCommunications: ; 19cb2 (6:5cb2)
-; copy CardPopNameList from SRAM to WRAM
- call EnableSRAM
- ld hl, sCardPopNameList
- ld de, wCardPopNameList
- ld bc, CARDPOP_NAME_LIST_SIZE
- call CopyDataHLtoDE
- call DisableSRAM
-
- ld a, IRPARAM_CARD_POP
- call InitIRCommunications
-.asm_19cc9
- call TryReceiveIRRequest ; receive request
- jr nc, .asm_19d05
- bit 1, a
- jr nz, .fail
- call TrySendIRRequest ; send request
- jr c, .asm_19cc9
-
-; do the player name search, then transmit the result
- call ExchangeIRCommunicationParameters
- jr c, .fail
- ld hl, wCardPopNameList
- ld de, wOtherPlayerCardPopNameList
- ld c, 0 ; $100 bytes = CARDPOP_NAME_LIST_SIZE
- call RequestDataTransmissionThroughIR
- jr c, .fail
- call LookUpNameInCardPopNameList
- ld hl, wCardPopNameSearchResult
- ld de, wCardPopNameSearchResult
- ld c, 1
- call RequestDataReceivalThroughIR
- jr c, .fail
- call SetIRCommunicationErrorCode_NoError
- jr c, .fail
- call ExecuteReceivedIRCommands
- jr c, .fail
- jr .check_search_result
-
-.asm_19d05
- call ExecuteReceivedIRCommands
- ld a, [wIRCommunicationErrorCode]
- or a
- jr nz, .fail
- call RequestCloseIRCommunication
- jr c, .fail
-
-.check_search_result
- ld a, [wCardPopNameSearchResult]
- or a
- jr z, .success
- ; not $00, means the name was found in the list
- ldtx hl, CannotCardPopWithFriendPreviouslyPoppedWithText
- scf
- ret
-
-.success
- call DecideCardToReceiveFromCardPop
-
-; increment number of times Card Pop! was done
-; and write the other player's name to sCardPopNameList
-; the spot where this is written in the list is derived
-; from the lower nybble of sTotalCardPopsDone
-; that means that after 16 Card Pop!, the older
-; names start to get overwritten
- call EnableSRAM
- ld hl, sTotalCardPopsDone
- ld a, [hl]
- inc [hl]
- and $0f
- swap a ; *NAME_BUFFER_LENGTH
- ld l, a
- ld h, $0
- ld de, sCardPopNameList
- add hl, de
- ld de, wNameBuffer
- ld c, NAME_BUFFER_LENGTH
-.loop_write_name
- ld a, [de]
- inc de
- ld [hli], a
- dec c
- jr nz, .loop_write_name
- call DisableSRAM
- or a
- ret
-
-.fail
- ldtx hl, ThePopWasntSuccessfulText
- scf
- ret
-
-; looks up the name in wNameBuffer in wCardPopNameList
-; used to know whether this save file has done Card Pop!
-; with the other player already
-; returns carry and wCardPopNameSearchResult = $ff if the name was found;
-; returns no carry and wCardPopNameSearchResult = $00 otherwise
-LookUpNameInCardPopNameList: ; 19d49 (6:5d49)
-; searches for other player's name in this game's name list
- ld hl, wCardPopNameList
- ld c, CARDPOP_NAME_LIST_MAX_ELEMS
-.loop_own_card_pop_name_list
- push hl
- ld de, wNameBuffer
- call .CompareNames
- pop hl
- jr nc, .found_name
- ld de, NAME_BUFFER_LENGTH
- add hl, de
- dec c
- jr nz, .loop_own_card_pop_name_list
-
-; name was not found in wCardPopNameList
-
-; searches for this player's name in the other game's name list
-; this is useless since it discards the result from the name comparisons
-; as a result this loop will always return no carry
- call EnableSRAM
- ld hl, wOtherPlayerCardPopNameList
- ld c, CARDPOP_NAME_LIST_MAX_ELEMS
-.loop_other_card_pop_name_list
- push hl
- ld de, sPlayerName
- call .CompareNames ; discards result from comparison
- pop hl
- ld de, NAME_BUFFER_LENGTH
- add hl, de
- dec c
- jr nz, .loop_other_card_pop_name_list
- xor a
- jr .no_carry
-
-.found_name
- ld a, $ff
- scf
-.no_carry
- call DisableSRAM
- ld [wCardPopNameSearchResult], a ; $00 if name was not found, $ff otherwise
- ret
-
-; compares names in hl and de
-; if they are different, return carry
-.CompareNames
- ld b, NAME_BUFFER_LENGTH
-.loop_chars
- ld a, [de]
- inc de
- cp [hl]
- jr nz, .not_same
- inc hl
- dec b
- jr nz, .loop_chars
- or a
- ret
-.not_same
- scf
- ret
-
-; loads in wLoadedCard1 a random card to be received
-; this selection is done based on the rarity that is
-; decided from the names of both participants
-; the card will always be a Pokemon card that is not
-; from a Promotional set, with the exception
-; of Venusaur1 and Mew2
-; output:
-; - e = card ID chosen
-DecideCardToReceiveFromCardPop: ; 19d92 (6:5d92)
- ld a, PLAYER_TURN
- ldh [hWhoseTurn], a
- call EnableSRAM
- ld hl, sPlayerName
- call CalculateNameHash
- call DisableSRAM
- push de
- ld hl, wNameBuffer
- call CalculateNameHash
- pop bc
-
-; de = other player's name hash
-; bc = this player's name hash
-
-; updates RNG values to subtraction of these two hashes
- ld hl, wRNG1
- ld a, b
- sub d
- ld d, a ; b - d
- ld [hli], a ; wRNG1
- ld a, c
- sub e
- ld e, a ; c - e
- ld [hli], a ; wRNG2
- ld [hl], $0 ; wRNGCounter
-
-; depending on the values obtained from the hashes,
-; determine which rarity card to give to the player
-; along with the song to play with each rarity
-; the probabilities of each possibility can be calculated
-; as follows (given 2 random player names):
-; 101/256 ~ 39% for Circle
-; 90/256 ~ 35% for Diamond
-; 63/256 ~ 25% for Star
-; 1/256 ~ .4% for Venusaur1 or Mew2
- ld a, e
- cp 5
- jr z, .venusaur1_or_mew2
- cp 64
- jr c, .star_rarity ; < 64
- cp 154
- jr c, .diamond_rarity ; < 154
- ; >= 154
-
- ld a, MUSIC_BOOSTER_PACK
- ld b, CIRCLE
- jr .got_rarity
-.diamond_rarity
- ld a, MUSIC_BOOSTER_PACK
- ld b, DIAMOND
- jr .got_rarity
-.star_rarity
- ld a, MUSIC_MATCH_VICTORY
- ld b, STAR
-.got_rarity
- ld [wCardPopCardObtainSong], a
- ld a, b
- call CreateCardPopCandidateList
- ; shuffle candidates and pick first from list
- call ShuffleCards
- ld a, [hl]
- ld e, a
-.got_card_id
- ld d, $0
- call LoadCardDataToBuffer1_FromCardID
- ld a, e
- ret
-
-.venusaur1_or_mew2
-; choose either Venusaur1 or Mew2
-; depending on whether the lower
-; bit of d is unset or set, respectively
- ld a, MUSIC_MEDAL
- ld [wCardPopCardObtainSong], a
- ld e, VENUSAUR1
- ld a, d
- and $1 ; get lower bit
- jr z, .got_card_id
- ld e, MEW2
- jr .got_card_id
-
-; lists in wCardPopCardCandidates all cards that:
-; - are Pokemon cards;
-; - have the same rarity as input register a;
-; - are not from Promotional set.
-; input:
-; - a = card rarity
-; output:
-; - a = number of candidates
-CreateCardPopCandidateList: ; 19df7 (6:5df7)
- ld hl, wPlayerDeck
- push hl
- push de
- push bc
- ld b, a
-
- lb de, 0, GRASS_ENERGY
-.loop_card_ids
- call LoadCardDataToBuffer1_FromCardID
- jr c, .count ; no more card IDs
- ld a, [wLoadedCard1Type]
- and TYPE_ENERGY
- jr nz, .next_card_id ; not Pokemon card
- ld a, [wLoadedCard1Rarity]
- cp b
- jr nz, .next_card_id ; not equal rarity
- ld a, [wLoadedCard1Set]
- and $f0
- cp PROMOTIONAL
- jr z, .next_card_id ; no promos
- ld [hl], e
- inc hl
-.next_card_id
- inc de
- jr .loop_card_ids
-
-; count all the cards that were listed
-; and return it in a
-.count
- ld [hl], $00 ; invalid card ID as end of list
- ld hl, wPlayerDeck
- ld c, -1
-.loop_count
- inc c
- ld a, [hli]
- or a
- jr nz, .loop_count
- ld a, c
- pop bc
- pop de
- pop hl
- ret
-
-; creates a unique two-byte hash from the name given in hl
-; the low byte is calculated by simply adding up all characters
-; the high byte is calculated by xoring all characters together
-; input:
-; - hl = points to the start of the name buffer
-; output:
-; - de = hash
-CalculateNameHash: ; 19e32 (6:5e32)
- ld c, NAME_BUFFER_LENGTH
- ld de, $0
-.loop
- ld a, e
- add [hl]
- ld e, a
- ld a, d
- xor [hl]
- ld d, a
- inc hl
- dec c
- jr nz, .loop
- ret
-
-; sends serial data to printer
-; if there's an error in connection,
-; show Printer Not Connected scene with error message
-_PreparePrinterConnection: ; 19e42 (6:5e42)
- ld bc, $0
- lb de, PRINTERPKT_DATA, $0
- call SendPrinterPacket
- ret nc ; return if no error
-
- ld hl, wPrinterStatus
- ld a, [hl]
- or a
- jr nz, .asm_19e55
- ld [hl], $ff
-.asm_19e55
- ld a, [hl]
- cp $ff
- jr z, ShowPrinterIsNotConnected
-; fallthrough
-
-; shows message on screen depending on wPrinterStatus
-; also shows SCENE_GAMEBOY_PRINTER_NOT_CONNECTED.
-HandlePrinterError: ; 19e5a (6:5e5a)
- ld a, [wPrinterStatus]
- cp $ff
- jr z, .cable_or_printer_switch
- or a
- jr z, .interrupted
- bit PRINTER_ERROR_BATTERIES_LOST_CHARGE, a
- jr nz, .batteries_lost_charge
- bit PRINTER_ERROR_CABLE_PRINTER_SWITCH, a
- jr nz, .cable_or_printer_switch
- bit PRINTER_ERROR_PAPER_JAMMED, a
- jr nz, .jammed_printer
-
- ldtx hl, PrinterPacketErrorText
- ld a, $04
- jr ShowPrinterConnectionErrorScene
-.cable_or_printer_switch
- ldtx hl, CheckCableOrPrinterSwitchText
- ld a, $02
- jr ShowPrinterConnectionErrorScene
-.jammed_printer
- ldtx hl, PrinterPaperIsJammedText
- ld a, $03
- jr ShowPrinterConnectionErrorScene
-.batteries_lost_charge
- ldtx hl, BatteriesHaveLostTheirChargeText
- ld a, $01
- jr ShowPrinterConnectionErrorScene
-.interrupted
- ldtx hl, PrintingWasInterruptedText
- call DrawWideTextBox_WaitForInput
- scf
- ret
-
-ShowPrinterIsNotConnected: ; 19e94 (6:5e94)
- ldtx hl, PrinterIsNotConnectedText
- ld a, $02
-; fallthrough
-
-; a = error code
-; hl = text ID to print in text box
-ShowPrinterConnectionErrorScene: ; 19e99 (6:5e99)
- push hl
- ; unnecessary loading TxRam, since the text data
- ; already incorporate the error number
- ld l, a
- ld h, $00
- call LoadTxRam3
-
- call Func_198e7
- ld a, SCENE_GAMEBOY_PRINTER_NOT_CONNECTED
- lb bc, 0, 0
- call LoadScene
- pop hl
- call DrawWideTextBox_WaitForInput
- call RestoreVBlankFunction
- scf
- ret
-
-; main card printer function
-Func_19eb4: ; 19eb4 (6:5eb4)
- ld e, a
- ld d, $0
- call LoadCardDataToBuffer1_FromCardID
- call Func_198e7
- ld a, SCENE_GAMEBOY_PRINTER_TRANSMITTING
- lb bc, 0, 0
- call LoadScene
- ld a, 20
- call CopyCardNameAndLevel
- ld [hl], TX_END
- ld hl, $0
- call LoadTxRam2
- ldtx hl, NowPrintingText
- call DrawWideTextBox_PrintText
- call EnableLCD
- call PrepareForPrinterCommunications
- call DrawTopCardInfoInSRAMGfxBuffer0
- call Func_19f87
- call DrawCardPicInSRAMGfxBuffer2
- call Func_19f99
- jr c, .error
- call DrawBottomCardInfoInSRAMGfxBuffer0
- call Func_1a011
- jr c, .error
- call RestoreVBlankFunction
- call ResetPrinterCommunicationSettings
- or a
- ret
-.error
- call RestoreVBlankFunction
- call ResetPrinterCommunicationSettings
- jp HandlePrinterError
-
-DrawCardPicInSRAMGfxBuffer2: ; 19f05 (6:5f05)
- ld hl, wLoadedCard1Gfx
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld de, sGfxBuffer2
- call Func_37a5
- ; draw card's picture in sGfxBuffer2
- ld a, $40
- lb hl, 12, 1
- lb de, 2, 68
- lb bc, 16, 12
- call FillRectangle
- ret
-
-; writes the tiles necessary to draw
-; the card's information in sGfxBuffer0
-; this includes card's type, lv, HP and attacks if Pokemon card
-; or otherwise just the card's name and type symbol
-DrawTopCardInfoInSRAMGfxBuffer0: ; 19f20 (6:5f20)
- call Func_1a025
- call Func_212f
-
- ; draw empty text box frame
- ld hl, sGfxBuffer0
- ld a, $34
- lb de, $30, $31
- ld b, 20
- call CopyLine
- ld c, 15
-.loop_lines
- xor a ; SYM_SPACE
- lb de, $36, $37
- ld b, 20
- call CopyLine
- dec c
- jr nz, .loop_lines
-
- ; draw card type symbol
- ld a, $38
- lb hl, 1, 2
- lb de, 1, 65
- lb bc, 2, 2
- call FillRectangle
- ; print card's name
- lb de, 4, 65
- ld hl, wLoadedCard1Name
- call InitTextPrinting_ProcessTextFromPointerToID
-
-; prints card's type, lv, HP and attacks if it's a Pokemon card
- ld a, [wLoadedCard1Type]
- cp TYPE_ENERGY
- jr nc, .skip_pokemon_data
- inc a ; symbol corresponding to card's type (color)
- lb bc, 18, 65
- call WriteByteToBGMap0
- ld a, SYM_Lv
- lb bc, 11, 66
- call WriteByteToBGMap0
- ld a, [wLoadedCard1Level]
- lb bc, 12, 66
- bank1call WriteTwoDigitNumberInTxSymbolFormat
- ld a, SYM_HP
- lb bc, 15, 66
- call WriteByteToBGMap0
- ld a, [wLoadedCard1EffectCommands]
- inc b
- bank1call WriteTwoByteNumberInTxSymbolFormat
-.skip_pokemon_data
- ret
-
-Func_19f87: ; 19f87 (6:5f87)
- call TryInitPrinterCommunications
- ret c
- ld hl, sGfxBuffer0
- call Func_1a0cc
- ret c
- call Func_1a0cc
- call Func_1a111
- ret
-
-Func_19f99: ; 19f99 (6:5f99)
- call TryInitPrinterCommunications
- ret c
- ld hl, sGfxBuffer0 + $8 tiles
- ld c, $06
-.asm_19fa2
- call Func_1a0cc
- ret c
- dec c
- jr nz, .asm_19fa2
- call Func_1a111
- ret
-
-; writes the tiles necessary to draw
-; the card's information in sGfxBuffer0
-; this includes card's Retreat cost, Weakness, Resistance,
-; and attack if it's Pokemon card
-; or otherwise just the card's description.
-DrawBottomCardInfoInSRAMGfxBuffer0: ; 19fad (6:5fad)
- call Func_1a025
- xor a
- ld [wCardPageType], a
- ld hl, sGfxBuffer0
- ld b, 20
- ld c, 9
-.loop_lines
- xor a ; SYM_SPACE
- lb de, $36, $37
- call CopyLine
- dec c
- jr nz, .loop_lines
- ld a, $35
- lb de, $32, $33
- call CopyLine
-
- ld a, [wLoadedCard1Type]
- cp TYPE_ENERGY
- jr nc, .not_pkmn_card
- ld hl, RetreatWeakResistData
- call PlaceTextItems
- ld c, 66
- bank1call DisplayCardPage_PokemonOverview.attacks
- ld a, SYM_No
- lb bc, 15, 72
- call WriteByteToBGMap0
- inc b
- ld a, [wLoadedCard1PokedexNumber]
- bank1call WriteTwoByteNumberInTxSymbolFormat
- ret
-
-.not_pkmn_card
- bank1call SetNoLineSeparation
- lb de, 1, 66
- ld a, SYM_No
- call InitTextPrintingInTextbox
- ld hl, wLoadedCard1NonPokemonDescription
- call ProcessTextFromPointerToID
- bank1call SetOneLineSeparation
- ret
-
-RetreatWeakResistData: ; 1a004 (6:6004)
- textitem 1, 70, RetreatText
- textitem 1, 71, WeaknessText
- textitem 1, 72, ResistanceText
- db $ff
-
-Func_1a011: ; 1a011 (6:6011)
- call TryInitPrinterCommunications
- ret c
- ld hl, sGfxBuffer0
- ld c, $05
-.asm_1a01a
- call Func_1a0cc
- ret c
- dec c
- jr nz, .asm_1a01a
- call Func_1a108
- ret
-
-; calls setup text and sets wTilePatternSelector
-Func_1a025: ; 1a025 (6:6025)
- lb de, $40, $bf
- call SetupText
- ld a, $a4
- ld [wTilePatternSelector], a
- xor a
- ld [wTilePatternSelectorCorrection], a
- ret
-
-; switches to CGB normal speed, resets serial
-; enables SRAM and switches to SRAM1
-; and clears sGfxBuffer0
-PrepareForPrinterCommunications: ; 1a035 (6:6035)
- call SwitchToCGBNormalSpeed
- call ResetSerial
- ld a, $10
- ld [wce9b], a
- call EnableSRAM
- ld a, [sPrinterContrastLevel]
- ld [wPrinterContrastLevel], a
- call DisableSRAM
- ldh a, [hBankSRAM]
- ld [wce8f], a
- ld a, BANK("SRAM1")
- call BankswitchSRAM
- call EnableSRAM
-; fallthrough
-
-ClearPrinterGfxBuffer: ; 1a035 (6:6035)
- ld hl, sGfxBuffer0
- ld bc, $400
-.loop
- xor a
- ld [hli], a
- dec bc
- ld a, c
- or b
- jr nz, .loop
- xor a
- ld [wce9f], a
- ret
-
-; reverts settings changed by PrepareForPrinterCommunications
-ResetPrinterCommunicationSettings: ; 1a06b (6:606b)
- push af
- call SwitchToCGBDoubleSpeed
- ld a, [wce8f]
- call BankswitchSRAM
- call DisableSRAM
- lb de, $30, $bf
- call SetupText
- pop af
- ret
-
-; unreferenced
-; send some bytes through serial
-Func_1a080: ; 1a080 (6:6080)
- ld bc, $0
- lb de, PRINTERPKT_NUL, $0
- jp SendPrinterPacket
-
-; tries initiating the communications for
-; sending data to printer
-; returns carry if operation was cancelled
-; by pressing B button or serial transfer took long
-TryInitPrinterCommunications: ; 1a089 (6:6089)
- xor a
- ld [wPrinterInitAttempts], a
-.wait_input
- call DoFrame
- ldh a, [hKeysHeld]
- and B_BUTTON
- jr nz, .b_button
- ld bc, $0
- lb de, PRINTERPKT_NUL, $0
- call SendPrinterPacket
- jr c, .delay
- and (1 << PRINTER_STATUS_BUSY) | (1 << PRINTER_STATUS_PRINTING)
- jr nz, .wait_input
-
-.init
- ld bc, $0
- lb de, PRINTERPKT_INIT, $0
- call SendPrinterPacket
- jr nc, .no_carry
- ld hl, wPrinterInitAttempts
- inc [hl]
- ld a, [hl]
- cp 3
- jr c, .wait_input
- ; time out
- scf
- ret
-.no_carry
- ret
-
-.b_button
- xor a
- ld [wPrinterStatus], a
- scf
- ret
-
-.delay
- ld c, 10
-.delay_loop
- call DoFrame
- dec c
- jr nz, .delay_loop
- jr .init
-
-; loads tiles given by map in hl to sGfxBuffer5
-; copies first 20 tiles, then offsets by 2 tiles
-; and copies another 20
-Func_1a0cc: ; 1a0cc (6:60cc)
- push bc
- ld de, sGfxBuffer5
- call .Copy20Tiles
- call .Copy20Tiles
- push hl
- call CompressDataForPrinterSerialTransfer
- call SendPrinterPacket
- pop hl
- pop bc
- ret
-
-; copies 20 tiles given by hl to de
-; then adds 2 tiles to hl
-.Copy20Tiles ; 1a0e0 (6:60e0)
- push hl
- ld c, 20
-.loop_tiles
- ld a, [hli]
- call .CopyTile
- dec c
- jr nz, .loop_tiles
- pop hl
- ld bc, 2 tiles
- add hl, bc
- ret
-
-; copies a tile to de
-; a = tile to get from sGfxBuffer1
-.CopyTile ; 1a0f0 (6:60f0)
- push hl
- push bc
- ld l, a
- ld h, $00
- add hl, hl
- add hl, hl
- add hl, hl
- add hl, hl ; *TILE_SIZE
- ld bc, sGfxBuffer1
- add hl, bc
- ld c, TILE_SIZE
-.loop_copy
- ld a, [hli]
- ld [de], a
- inc de
- dec c
- jr nz, .loop_copy
- pop bc
- pop hl
- ret
-
-Func_1a108: ; 1a108 (6:6108)
- call GetPrinterContrastSerialData
- push hl
- lb hl, $3, $1
- jr SendPrinterInstructionPacket
-
-Func_1a111: ; 1a111 (6:6111)
- call GetPrinterContrastSerialData
- push hl
- ld hl, wce9b
- ld a, [hl]
- ld [hl], $00
- ld h, a
- ld l, $01
-; fallthrough
-
-SendPrinterInstructionPacket: ; 1a11e (6:611e)
- push hl
- ld bc, $0
- lb de, PRINTERPKT_DATA, $0
- call SendPrinterPacket
- jr c, .asm_1a135
- ld hl, sp+$00 ; contrast level bytes
- ld bc, $4 ; instruction packets are 4 bytes in size
- lb de, PRINTERPKT_PRINT_INSTRUCTION, $0
- call SendPrinterPacket
-.asm_1a135
- pop hl
- pop hl
- ret
-
-; returns in h and l the bytes
-; to be sent through serial to the printer
-; for the set contrast level
-GetPrinterContrastSerialData: ; 1a138 (6:6138)
- ld a, [wPrinterContrastLevel]
- ld e, a
- ld d, $00
- ld hl, .contrast_level_data
- add hl, de
- ld h, [hl]
- ld l, $e4
- ret
-
-.contrast_level_data
- db $00, $20, $40, $60, $7f
-
-; unreferenced
-Func_1a14b: ; 1a14b (6:614b)
- ld a, $01
- jr .asm_1a15d
- ld a, $02
- jr .asm_1a15d
- ld a, $03
- jr .asm_1a15d
- ld a, $04
- jr .asm_1a15d
- ld a, $05
-.asm_1a15d
- ld [wce9d], a
- scf
- ret
-
-; a = saved deck index to print
-_PrintDeckConfiguration: ; 1a162 (6:6162)
-; copies selected deck from SRAM to wDuelTempList
- call EnableSRAM
- ld l, a
- ld h, DECK_STRUCT_SIZE
- call HtimesL
- ld de, sSavedDeck1
- add hl, de
- ld de, wDuelTempList
- ld bc, DECK_STRUCT_SIZE
- call CopyDataHLtoDE
- call DisableSRAM
-
- call ShowPrinterTransmitting
- call PrepareForPrinterCommunications
- call Func_1a025
- call Func_212f
- lb de, 0, 64
- lb bc, 20, 4
- call DrawRegularTextBoxDMG
- lb de, 4, 66
- call InitTextPrinting
- ld hl, wDuelTempList ; print deck name
- call ProcessText
- ldtx hl, DeckPrinterText
- call ProcessTextFromID
-
- ld a, 5
- ld [wPrinterHorizontalOffset], a
- ld hl, wPrinterTotalCardCount
- xor a
- ld [hli], a
- ld [hl], a
- ld [wPrintOnlyStarRarity], a
-
- ld hl, wCurDeckCards
-.loop_cards
- ld a, [hl]
- or a
- jr z, .asm_1a1d6
- ld e, a
- ld d, $00
- call LoadCardDataToBuffer1_FromCardID
-
- ; find out this card's count
- ld a, [hli]
- ld b, a
- ld c, 1
-.loop_card_count
- cp [hl]
- jr nz, .got_card_count
- inc hl
- inc c
- jr .loop_card_count
-
-.got_card_count
- ld a, c
- ld [wPrinterCardCount], a
- call LoadCardInfoForPrinter
- call AddToPrinterGfxBuffer
- jr c, .printer_error
- jr .loop_cards
-
-.asm_1a1d6
- call SendCardListToPrinter
- jr c, .printer_error
- call ResetPrinterCommunicationSettings
- call RestoreVBlankFunction
- or a
- ret
-
-.printer_error
- call ResetPrinterCommunicationSettings
- call RestoreVBlankFunction
- jp HandlePrinterError
-
-SendCardListToPrinter: ; 1a1ec (6:61ec)
- ld a, [wPrinterHorizontalOffset]
- cp 1
- jr z, .skip_load_gfx
- call LoadGfxBufferForPrinter
- ret c
-.skip_load_gfx
- call TryInitPrinterCommunications
- ret c
- call Func_1a108
- ret
-; 0z1a1ff
-
-; increases printer horizontal offset by 2
-AddToPrinterGfxBuffer: ; 1a1ff (6:61ff)
- push hl
- ld hl, wPrinterHorizontalOffset
- inc [hl]
- inc [hl]
- ld a, [hl]
- pop hl
- ; return no carry if below 18
- cp 18
- ccf
- ret nc
- ; >= 18
-; fallthrough
-
-; copies Gfx to Gfx buffer and sends some serial data
-; returns carry set if unsuccessful
-LoadGfxBufferForPrinter: ; 1a20b (6:620b)
- push hl
- call TryInitPrinterCommunications
- jr c, .set_carry
- ld a, [wPrinterHorizontalOffset]
- srl a
- ld c, a
- ld hl, sGfxBuffer0
-.loop_gfx_buffer
- call Func_1a0cc
- jr c, .set_carry
- dec c
- jr nz, .loop_gfx_buffer
- call Func_1a111
- jr c, .set_carry
-
- call ClearPrinterGfxBuffer
- ld a, 1
- ld [wPrinterHorizontalOffset], a
- pop hl
- or a
- ret
-
-.set_carry
- pop hl
- scf
- ret
-
-; load symbol, name, level and card count to buffer
-LoadCardInfoForPrinter: ; 1a235 (6:6235)
- push hl
- ld a, [wPrinterHorizontalOffset]
- or %1000000
- ld e, a
- ld d, 3
- ld a, [wPrintOnlyStarRarity]
- or a
- jr nz, .skip_card_symbol
- ld hl, wPrinterTotalCardCount
- ld a, [hli]
- or [hl]
- call z, DrawCardSymbol
-.skip_card_symbol
- ld a, 14
- call CopyCardNameAndLevel
- call InitTextPrinting
- ld hl, wDefaultText
- call ProcessText
- ld a, [wPrinterHorizontalOffset]
- or %1000000
- ld c, a
- ld b, 16
- ld a, SYM_CROSS
- call WriteByteToBGMap0
- inc b
- ld a, [wPrinterCardCount]
- bank1call WriteTwoDigitNumberInTxSymbolFormat
- pop hl
- ret
-
-_PrintCardList: ; 1a270 (6:6270)
-; if Select button is held when printing card list
-; only print cards with Star rarity (excluding Promotional cards)
-; even if it's not marked as seen in the collection
- ld e, FALSE
- ldh a, [hKeysHeld]
- and SELECT
- jr z, .no_select
- inc e ; TRUE
-.no_select
- ld a, e
- ld [wPrintOnlyStarRarity], a
-
- call ShowPrinterTransmitting
- call CreateTempCardCollection
- ld de, wDefaultText
- call CopyPlayerName
- call PrepareForPrinterCommunications
- call Func_1a025
- call Func_212f
-
- lb de, 0, 64
- lb bc, 20, 4
- call DrawRegularTextBoxDMG
- ld a, PLAYER_TURN
- ldh [hWhoseTurn], a
- lb de, 2, 66
- call InitTextPrinting
- ld hl, wDefaultText
- call ProcessText
- ldtx hl, AllCardsOwnedText
- call ProcessTextFromID
- ld a, [wPrintOnlyStarRarity]
- or a
- jr z, .asm_1a2c2
- ld a, TX_HALF2FULL
- call ProcessSpecialTextCharacter
- lb de, 3, 84
- call Func_22ca
-.asm_1a2c2
- ld a, $ff
- ld [wCurPrinterCardType], a
- xor a
- ld hl, wPrinterTotalCardCount
- ld [hli], a
- ld [hl], a
- ld [wPrinterNumCardTypes], a
- ld a, 5
- ld [wPrinterHorizontalOffset], a
-
- ld e, GRASS_ENERGY
-.loop_cards
- push de
- ld d, $00
- call LoadCardDataToBuffer1_FromCardID
- jr c, .done_card_loop
- ld d, HIGH(wTempCardCollection)
- ld a, [de] ; card ID count in collection
- ld [wPrinterCardCount], a
- call .LoadCardTypeEntry
- jr c, .printer_error_pop_de
-
- ld a, [wPrintOnlyStarRarity]
- or a
- jr z, .all_owned_cards_mode
- ld a, [wLoadedCard1Set]
- and %11110000
- cp PROMOTIONAL
- jr z, .next_card
- ld a, [wLoadedCard1Rarity]
- cp STAR
- jr nz, .next_card
- ; not Promotional, and Star rarity
- ld hl, wPrinterCardCount
- res CARD_NOT_OWNED_F, [hl]
- jr .got_card_count
-
-.all_owned_cards_mode
- ld a, [wPrinterCardCount]
- or a
- jr z, .next_card
- cp CARD_NOT_OWNED
- jr z, .next_card ; ignore not owned cards
-
-.got_card_count
- ld a, [wPrinterCardCount]
- and CARD_COUNT_MASK
- ld c, a
-
- ; add to total card count
- ld hl, wPrinterTotalCardCount
- add [hl]
- ld [hli], a
- ld a, 0
- adc [hl]
- ld [hl], a
-
- ; add to current card type count
- ld hl, wPrinterCurCardTypeCount
- ld a, c
- add [hl]
- ld [hli], a
- ld a, 0
- adc [hl]
- ld [hl], a
-
- ld hl, wPrinterNumCardTypes
- inc [hl]
- ld hl, wce98
- inc [hl]
- call LoadCardInfoForPrinter
- call AddToPrinterGfxBuffer
- jr c, .printer_error_pop_de
-.next_card
- pop de
- inc e
- jr .loop_cards
-
-.printer_error_pop_de
- pop de
-.printer_error
- call ResetPrinterCommunicationSettings
- call RestoreVBlankFunction
- jp HandlePrinterError
-
-.done_card_loop
- pop de
- ; add separator line
- ld a, [wPrinterHorizontalOffset]
- dec a
- or $40
- ld c, a
- ld b, 0
- call BCCoordToBGMap0Address
- ld a, $35
- lb de, $35, $35
- ld b, 20
- call CopyLine
- call AddToPrinterGfxBuffer
- jr c, .printer_error
-
- ld hl, wPrinterTotalCardCount
- ld c, [hl]
- inc hl
- ld b, [hl]
- ldtx hl, TotalNumberOfCardsText
- call .PrintTextWithNumber
- jr c, .printer_error
- ld a, [wPrintOnlyStarRarity]
- or a
- jr nz, .done
- ld a, [wPrinterNumCardTypes]
- ld c, a
- ld b, 0
- ldtx hl, TypesOfCardsText
- call .PrintTextWithNumber
- jr c, .printer_error
-
-.done
- call SendCardListToPrinter
- jr c, .printer_error
- call ResetPrinterCommunicationSettings
- call RestoreVBlankFunction
- or a
- ret
-
-; prints text ID given in hl
-; with decimal representation of
-; the number given in bc
-; hl = text ID
-; bc = number
-.PrintTextWithNumber
- push bc
- ld a, [wPrinterHorizontalOffset]
- dec a
- or $40
- ld e, a
- ld d, 2
- call InitTextPrinting
- call ProcessTextFromID
- ld d, 14
- call InitTextPrinting
- pop hl
- call TwoByteNumberToTxSymbol_TrimLeadingZeros
- ld hl, wStringBuffer
- call ProcessText
- call AddToPrinterGfxBuffer
- ret
-
-; loads this card's type icon and text
-; if it's a new card type that hasn't been printed yet
-.LoadCardTypeEntry
- ld a, [wLoadedCard1Type]
- ld c, a
- cp TYPE_ENERGY
- jr c, .got_type ; jump if Pokemon card
- ld c, $08
- cp TYPE_TRAINER
- jr nc, .got_type ; jump if Trainer card
- ld c, $07
-.got_type
- ld hl, wCurPrinterCardType
- ld a, [hl]
- cp c
- ret z ; already handled this card type
-
- ; show corresponding icon and text
- ; for this new card type
- ld a, c
- ld [hl], a ; set it as current card type
- add a
- add c ; *3
- ld c, a
- ld b, $00
- ld hl, .IconTextList
- add hl, bc
- ld a, [wPrinterHorizontalOffset]
- dec a
- or %1000000
- ld e, a
- ld d, 1
- ld a, [hli]
- push hl
- lb bc, 2, 2
- lb hl, 1, 2
- call FillRectangle
- pop hl
- ld d, 3
- inc e
- call InitTextPrinting
- ld a, [hli]
- ld h, [hl]
- ld l, a
- call ProcessTextFromID
-
- call AddToPrinterGfxBuffer
- ld hl, wPrinterCurCardTypeCount
- xor a
- ld [hli], a
- ld [hl], a
- ld [wce98], a
- ret
-
-.IconTextList
- ; Fire
- db $e0 ; icon tile
- tx FirePokemonText
-
- ; Grass
- db $e4 ; icon tile
- tx GrassPokemonText
-
- ; Lightning
- db $e8 ; icon tile
- tx LightningPokemonText
-
- ; Water
- db $ec ; icon tile
- tx WaterPokemonText
-
- ; Fighting
- db $f0 ; icon tile
- tx FightingPokemonText
-
- ; Psychic
- db $f4 ; icon tile
- tx PsychicPokemonText
-
- ; Colorless
- db $f8 ; icon tile
- tx ColorlessPokemonText
-
- ; Energy
- db $fc ; icon tile
- tx EnergyCardText
-
- ; Trainer
- db $dc ; icon tile
- tx TrainerCardText
-
-ShowPrinterTransmitting: ; 1a420 (6:6420)
- call Func_198e7
- ld a, SCENE_GAMEBOY_PRINTER_TRANSMITTING
- lb bc, 0, 0
- call LoadScene
- ldtx hl, NowPrintingPleaseWaitText
- call DrawWideTextBox_PrintText
- call EnableLCD
- ret
-
-; compresses $28 tiles in sGfxBuffer5
-; and writes it in sGfxBuffer5 + $28 tiles.
-; compressed data has 2 commands to instruct on how to decompress it.
-; - a command byte with bit 7 not set, means to copy that many + 1
-; bytes that are following it literally.
-; - a command byte with bit 7 set, means to copy the following byte
-; that many times + 2 (after masking the top bit of command byte).
-; returns in bc the size of the compressed data and
-; in de the packet type data.
-CompressDataForPrinterSerialTransfer: ; 1a435 (6:6435)
- ld hl, sGfxBuffer5
- ld de, sGfxBuffer5 + $28 tiles
- ld bc, $28 tiles
-.loop_remaining_data
- ld a, $ff
- inc b
- dec b
- jr nz, .check_compression
- ld a, c
-.check_compression
- push bc
- push de
- ld c, a
- call CheckDataCompression
- ld a, e
- ld c, e
- pop de
- jr c, .copy_byte
- ld a, c
- ld b, c
- dec a
- ld [de], a ; number of bytes to copy literally - 1
- inc de
-.copy_literal_sequence
- ld a, [hli]
- ld [de], a
- inc de
- dec c
- jr nz, .copy_literal_sequence
- ld c, b
- jr .sub_added_bytes
-
-.copy_byte
- ld a, c
- dec a
- dec a
- or %10000000 ; set high bit
- ld [de], a ; = (n times to copy - 2) | %10000000
- inc de
- ld a, [hl] ; byte to copy n times
- ld [de], a
- inc de
- ld b, $0
- add hl, bc
-
-.sub_added_bytes
- ld a, c
- cpl
- inc a
- pop bc
- add c
- ld c, a
- ld a, $ff
- adc b
- ld b, a
- or c
- jr nz, .loop_remaining_data
-
- ld hl, $10000 - (sGfxBuffer5 + $28 tiles)
- add hl, de ; gets the size of the compressed data
- ld c, l
- ld b, h
- ld hl, sGfxBuffer5 + $28 tiles
- lb de, PRINTERPKT_DATA, $1
- ret
-
-; checks whether the next byte sequence in hl, up to c bytes, can be compressed
-; returns carry if the next sequence of bytes can be compressed,
-; i.e. has at least 3 consecutive bytes with the same value.
-; in that case, returns in e the number of consecutive
-; same value bytes that were found.
-; if there are no bytes with same value, then count as many bytes left
-; as possible until either there are no more remaining data bytes,
-; or until a sequence of 3 bytes with the same value are found.
-; in that case, the number of bytes in this sequence is returned in e.
-CheckDataCompression: ; 1a485 (6:6485)
- push hl
- ld e, c
- ld a, c
-; if number of remaining bytes is less than 4
-; then no point in compressing
- cp 4
- jr c, .no_carry
-
-; check first if there are at least
-; 3 consecutive bytes with the same value
- ld b, c
- ld a, [hli]
- cp [hl]
- inc hl
- jr nz, .literal_copy ; not same
- cp [hl]
- inc hl
- jr nz, .literal_copy ; not same
-
-; 3 consecutive bytes were found with same value
-; keep track of how many consecutive bytes
-; with the same value there are in e
- dec c
- dec c
- dec c
- ld e, 3
-.loop_same_value
- cp [hl]
- jr nz, .set_carry ; exit when a different byte is found
- inc hl
- inc e
- dec c
- jr z, .set_carry ; exit when there is no more remaining data
- bit 5, e
- ; exit if number of consecutive bytes >= $20
- jr z, .loop_same_value
-.set_carry
- pop hl
- scf
- ret
-
-.literal_copy
-; consecutive bytes are not the same value
-; count the number of bytes there are left
-; until a sequence of 3 bytes with the same value is found
- pop hl
- push hl
- ld c, b ; number of remaining bytes
- ld e, 1
- ld a, [hli]
- dec c
- jr z, .no_carry ; exit if no more data
-.reset_same_value_count
- ld d, 2 ; number of consecutive same value bytes to exit
-.next_byte
- inc e
- dec c
- jr z, .no_carry
- bit 7, e
- jr nz, .no_carry ; exit if >= $80
- cp [hl]
- jr z, .same_consecutive_value
- ld a, [hli]
- jr .reset_same_value_count
-.no_carry
- pop hl
- or a
- ret
-
-.same_consecutive_value
- inc hl
- dec d
- jr nz, .next_byte
- ; 3 consecutive bytes with same value found
- ; discard the last 3 bytes in the sequence
- dec e
- dec e
- dec e
- jr .no_carry
-
-; sets up to start a link duel
-; decides which device will pick the number of prizes
-; then exchanges names and duels between the players
-; and starts the main duel routine
-_SetUpAndStartLinkDuel: ; 1a4cf (6:64cf)
- ld hl, sp+$00
- ld a, l
- ld [wDuelReturnAddress + 0], a
- ld a, h
- ld [wDuelReturnAddress + 1], a
- call Func_198e7
-
- ld a, SCENE_GAMEBOY_LINK_TRANSMITTING
- lb bc, 0, 0
- call LoadScene
-
- bank1call LoadPlayerDeck
- call SwitchToCGBNormalSpeed
- bank1call DecideLinkDuelVariables
- push af
- call RestoreVBlankFunction
- pop af
- jp c, .error
-
- ld a, DUELIST_TYPE_PLAYER
- ld [wPlayerDuelistType], a
- ld a, DUELIST_TYPE_LINK_OPP
- ld [wOpponentDuelistType], a
- ld a, DUELTYPE_LINK
- ld [wDuelType], a
-
- call EmptyScreen
- ld a, [wSerialOp]
- cp $29
- jr nz, .asm_1a540
-
- ld a, PLAYER_TURN
- ldh [hWhoseTurn], a
- call .ExchangeNamesAndDecks
- jr c, .error
- lb de, 6, 2
- lb bc, 8, 6
- call DrawRegularTextBox
- lb de, 7, 4
- call InitTextPrinting
- ldtx hl, PrizesCardsText
- call ProcessTextFromID
- ldtx hl, ChooseTheNumberOfPrizesText
- call DrawWideTextBox_PrintText
- call EnableLCD
- call .PickNumberOfPrizeCards
- ld a, [wNPCDuelPrizes]
- call SerialSend8Bytes
- jr .prizes_decided
-
-.asm_1a540
- ld a, OPPONENT_TURN
- ldh [hWhoseTurn], a
- call .ExchangeNamesAndDecks
- jr c, .error
- ldtx hl, PleaseWaitDecidingNumberOfPrizesText
- call DrawWideTextBox_PrintText
- call EnableLCD
- call SerialRecv8Bytes
- ld [wNPCDuelPrizes], a
-
-.prizes_decided
- call ExchangeRNG
- ld a, LINK_OPP_PIC
- ld [wOpponentPortrait], a
- ldh a, [hWhoseTurn]
- push af
- call EmptyScreen
- bank1call SetDefaultPalettes
- ld a, SHUFFLE_DECK
- ld [wDuelDisplayedScreen], a
- bank1call DrawDuelistPortraitsAndNames
- ld a, OPPONENT_TURN
- ldh [hWhoseTurn], a
- ld a, [wNPCDuelPrizes]
- ld l, a
- ld h, $00
- call LoadTxRam3
- ldtx hl, BeginAPrizeDuelWithText
- call DrawWideTextBox_WaitForInput
- pop af
- ldh [hWhoseTurn], a
- call ExchangeRNG
- bank1call StartDuel_VSLinkOpp
- call SwitchToCGBDoubleSpeed
- ret
-
-.error
- ld a, -1
- ld [wDuelResult], a
- call Func_198e7
-
- ld a, SCENE_GAMEBOY_LINK_NOT_CONNECTED
- lb bc, 0, 0
- call LoadScene
-
- ldtx hl, TransmissionErrorText
- call DrawWideTextBox_WaitForInput
- call RestoreVBlankFunction
- call ResetSerial
- ret
-
-.ExchangeNamesAndDecks
- ld de, wDefaultText
- push de
- call CopyPlayerName
- pop hl
- ld de, wNameBuffer
- ld c, NAME_BUFFER_LENGTH
- call SerialExchangeBytes
- ret c
- xor a
- ld hl, wOpponentName
- ld [hli], a
- ld [hl], a
- ld hl, wPlayerDeck
- ld de, wOpponentDeck
- ld c, DECK_SIZE
- call SerialExchangeBytes
- ret
-
-; handles player choice of number of prize cards
-; pressing left/right makes it decrease/increase respectively
-; selection is confirmed by pressing A button
-.PickNumberOfPrizeCards
- ld a, PRIZES_4
- ld [wNPCDuelPrizes], a
- xor a
- ld [wPrizeCardSelectionFrameCounter], a
-.loop_input
- call DoFrame
- ld a, [wNPCDuelPrizes]
- add SYM_0
- ld e, a
- ; check frame counter so that it
- ; either blinks or shows number
- ld hl, wPrizeCardSelectionFrameCounter
- ld a, [hl]
- inc [hl]
- and $10
- jr z, .no_blink
- ld e, SYM_SPACE
-.no_blink
- ld a, e
- lb bc, 9, 6
- call WriteByteToBGMap0
-
- ldh a, [hDPadHeld]
- ld b, a
- ld a, [wNPCDuelPrizes]
- bit D_LEFT_F, b
- jr z, .check_d_right
- dec a
- cp PRIZES_2
- jr nc, .got_prize_count
- ld a, PRIZES_6 ; wrap around to 6
- jr .got_prize_count
-
-.check_d_right
- bit D_RIGHT_F, b
- jr z, .check_a_btn
- inc a
- cp PRIZES_6 + 1
- jr c, .got_prize_count
- ld a, PRIZES_2
-.got_prize_count
- ld [wNPCDuelPrizes], a
- xor a
- ld [wPrizeCardSelectionFrameCounter], a
-
-.check_a_btn
- bit A_BUTTON_F, b
- jr z, .loop_input
- ret
-
-Func_1a61f: ; 1a61f (6:661f)
- push af
- lb de, $38, $9f
- call SetupText
- pop af
- or a
- jr nz, .else
- ld a, MOLTRES2
- call .legendary_card_text
- ld a, ARTICUNO2
- call .legendary_card_text
- ld a, ZAPDOS3
- call .legendary_card_text
- ld a, DRAGONITE1
-.legendary_card_text
- ldtx hl, ReceivedLegendaryCardText
- jr .print_text
-.else
- ldtx hl, ReceivedCardText
- cp VILEPLUME
- jr z, .print_text
- cp BLASTOISE
- jr z, .print_text
- ldtx hl, ReceivedPromotionalFlyingPikachuText
- cp FLYING_PIKACHU
- jr z, .print_text
- ldtx hl, ReceivedPromotionalSurfingPikachuText
- cp SURFING_PIKACHU1
- jr z, .print_text
- cp SURFING_PIKACHU2
- jr z, .print_text
- ldtx hl, ReceivedPromotionalCardText
-.print_text
- push hl
- ld e, a
- ld d, $0
- call LoadCardDataToBuffer1_FromCardID
- call PauseSong
- ld a, MUSIC_MEDAL
- call PlaySong
- ld hl, wLoadedCard1Name
- ld a, [hli]
- ld h, [hl]
- ld l, a
- bank1call LoadTxRam2 ; switch to bank 1, but call a home func
- ld a, PLAYER_TURN
- ldh [hWhoseTurn], a
- pop hl
- bank1call _DisplayCardDetailScreen
-.loop
- call AssertSongFinished
- or a
- jr nz, .loop
-
- call ResumeSong
- bank1call OpenCardPage_FromHand
- ret
-
-_OpenBoosterPack: ; 1a68d (6:668d)
- ld a, PLAYER_TURN
- ldh [hWhoseTurn], a
- ld h, a
- ld l, $00
-.asm_6694
- xor a
- ld [hli], a
- ld a, l
- cp $3c
- jr c, .asm_6694
- xor a
- ld hl, wBoosterCardsDrawn
- ld de, wDuelTempList
- ld c, $00
-.asm_66a4
- ld a, [hli]
- or a
- jr z, .asm_66ae
- ld a, c
- ld [de], a
- inc de
- inc c
- jr .asm_66a4
-.asm_66ae
- ld a, $ff
- ld [de], a
- lb de, $38, $9f
- call SetupText
- bank1call InitAndDrawCardListScreenLayout
- ldtx hl, ChooseTheCardYouWishToExamineText
- ldtx de, BoosterPackText
- bank1call SetCardListHeaderText
- ld a, A_BUTTON | START
- ld [wNoItemSelectionMenuKeys], a
- bank1call DisplayCardList
- ret
-
-CommentedOut_1a6cc: ; 1a6cc (6:66cc)
- ret
-
-Func_1a6cd: ; 1a6cd (6:66cd)
- ldh a, [hBankSRAM]
- or a
- ret nz
- push hl
- push de
- push bc
- ld hl, sCardCollection
- ld bc, $0250
- ld a, [s0a000 + $b]
- ld e, a
-.asm_66de
- ld a, [hli]
- xor e
- ld e, a
- dec bc
- ld a, c
- or b
- jr nz, .asm_66de
- ld a, e
- pop bc
- pop de
- pop hl
- or a
- ret z
- xor a
- ld [wTileMapFill], a
- ld hl, wDoFrameFunction
- ld [hli], a
- ld [hl], a
- ldh [hSCX], a
- ldh [hSCY], a
- bank1call ZeroObjectPositionsAndToggleOAMCopy
- call EmptyScreen
- call LoadSymbolsFont
- bank1call SetDefaultPalettes
- ld a, [wConsole]
- cp $01
- jr nz, .asm_6719
- ld a, $e4
- ld [wOBP0], a
- ld [wBGP], a
- ld a, $01
- ld [wFlushPaletteFlags], a
-.asm_6719
- lb de, $38, $9f
- call SetupText
- ld hl, $00a3
- bank1call DrawWholeScreenTextBox
- ld a, $0a
- ld [MBC3SRamEnable], a
- xor a
- ldh [hBankSRAM], a
- ld [MBC3SRamBank], a
- ld [MBC3RTC], a
- ld [MBC3SRamEnable], a
- jp Reset
- ret
-
-Func_1a73a: ; 1a73a (6:673a)
- ldh a, [hBankSRAM]
- or a
- ret nz
- push hl
- push de
- push bc
- ld hl, sCardCollection
- ld bc, $0250
- ld e, $00
-.asm_6749
- ld a, [hli]
- xor e
- ld e, a
- dec bc
- ld a, c
- or b
- jr nz, .asm_6749
- ld a, $0a
- ld [MBC3SRamEnable], a
- ld a, e
- ld [s0a00b], a
- pop bc
- pop de
- pop hl
- ret
-
-WhatIsYourNameData: ; 1a75e (6:675e)
- textitem 1, 1, WhatIsYourNameText
- db $ff
-; [Deck1Data ~ Deck4Data]
-; These are directed from around (2:4f05),
-; without any bank description.
-; That is, the developers hard-coded it. -_-;;
-Deck1Data: ; 1a763 (6:6763)
- textitem 2, 1, Deck1Text
- textitem 14, 1, DeckText
- db $ff
-Deck2Data: ; 1a76c (6:676c)
- textitem 2, 1, Deck2Text
- textitem 14, 1, DeckText
- db $ff
-Deck3Data: ; 1a775 (6:6775)
- textitem 2, 1, Deck3Text
- textitem 14, 1, DeckText
- db $ff
-Deck4Data: ; 1a77e (6:677e)
- textitem 2, 1, Deck4Text
- textitem 14, 1, DeckText
- db $ff
-
-; set each byte zero from hl for b bytes.
-ClearMemory: ; 1a787 (6:6787)
- 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
-
-; play different sfx by a.
-; if a is 0xff play SFX_03 (usually following a B press),
-; else play SFX_02 (usually following an A press).
-PlayAcceptOrDeclineSFX: ; 1a794 (6:6794)
- push af
- inc a
- jr z, .sfx_decline
- ld a, SFX_02
- jr .sfx_accept
-.sfx_decline
- ld a, SFX_03
-.sfx_accept
- call PlaySFX
- pop af
- ret
-
-; get player name from the user
-; into hl
-InputPlayerName: ; 1a7a3 (6:67a3)
- ld e, l
- ld d, h
- ld a, MAX_PLAYER_NAME_LENGTH
- ld hl, WhatIsYourNameData
- lb bc, 12, 1
- call InitializeInputName
- call Set_OBJ_8x8
- xor a
- ld [wTileMapFill], a
- call EmptyScreen
- call ZeroObjectPositions
- ld a, $01
- ld [wVBlankOAMCopyToggle], a
- call LoadSymbolsFont
- lb de, $38, $bf
- call SetupText
- call LoadTextCursorTile
- ld a, $02
- ld [wd009], a
- call DrawNamingScreenBG
- xor a
- ld [wNamingScreenCursorX], a
- ld [wNamingScreenCursorY], a
- ld a, $09
- ld [wNamingScreenNumColumns], a
- ld a, $06
- ld [wNamingScreenKeyboardHeight], a
- ld a, $0f
- ld [wVisibleCursorTile], a
- ld a, $00
- ld [wInvisibleCursorTile], a
-.loop
- ld a, $01
- ld [wVBlankOAMCopyToggle], a
- call DoFrame
- call UpdateRNGSources
- ldh a, [hDPadHeld]
- and START
- jr z, .else
- ; if pressed start button.
- ld a, $01
- call PlayAcceptOrDeclineSFX
- call Func_1aa07
- ld a, 6
- ld [wNamingScreenCursorX], a
- ld a, 5
- ld [wNamingScreenCursorY], a
- call Func_1aa23
- jr .loop
-.else
- call NamingScreen_CheckButtonState
- jr nc, .loop ; if not pressed, go back to the loop.
- cp $ff
- jr z, .on_b_button
- ; on A button.
- call NamingScreen_ProcessInput
- jr nc, .loop
- ; if the player selected the end button,
- ; end its naming.
- call FinalizeInputName
- ret
-.on_b_button
- ld a, [wNamingScreenBufferLength]
- or a
- jr z, .loop ; empty string?
- ; erase one character.
- ld e, a
- ld d, 0
- ld hl, wNamingScreenBuffer
- add hl, de
- dec hl
- dec hl
- ld [hl], TX_END
- ld hl, wNamingScreenBufferLength ; note that its unit is byte, not word.
- dec [hl]
- dec [hl]
- call PrintPlayerNameFromInput
- jr .loop
-
-; it's called when naming(either player's or deck's) starts.
-; a: maximum length of name(depending on whether player's or deck's).
-; bc: position of name.
-; de: dest. pointer.
-; hl: pointer to text item of the question.
-InitializeInputName: ; 1a846 (6:6846)
- ld [wNamingScreenBufferMaxLength], a
- push hl
- ld hl, wNamingScreenNamePosition
- ld [hl], b
- inc hl
- ld [hl], c
- pop hl
- ld b, h
- ld c, l
- ; set the question string.
- ld hl, wNamingScreenQuestionPointer
- ld [hl], c
- inc hl
- ld [hl], b
- ; set the destination buffer.
- ld hl, wNamingScreenDestPointer
- ld [hl], e
- inc hl
- ld [hl], d
- ; clear the name buffer.
- ld a, NAMING_SCREEN_BUFFER_LENGTH
- ld hl, wNamingScreenBuffer
- call ClearMemory
- ld hl, wNamingScreenBuffer
- ld a, [wNamingScreenBufferMaxLength]
- ld b, a
- inc b
-.loop
- ; copy data from de to hl
- ; for b bytes.
- ld a, [de]
- inc de
- ld [hli], a
- dec b
- jr nz, .loop
- ld hl, wNamingScreenBuffer
- call GetTextLengthInTiles
- ld a, c
- ld [wNamingScreenBufferLength], a
- ret
-
-FinalizeInputName: ; 1a880 (6:6880)
- ld hl, wNamingScreenDestPointer
- ld e, [hl]
- inc hl
- ld d, [hl]
- ld l, e
- ld h, d
- ld de, wNamingScreenBuffer
- ld a, [wNamingScreenBufferMaxLength]
- ld b, a
- inc b
- jr InitializeInputName.loop
-
-; draws the keyboard frame
-; and the question if it exists.
-DrawNamingScreenBG: ; 1a892 (6:6892)
- call DrawTextboxForKeyboard
- call PrintPlayerNameFromInput
- ld hl, wNamingScreenQuestionPointer
- ld c, [hl]
- inc hl
- ld a, [hl]
- ld h, a
- or c
- jr z, .put_text_end
- ; print the question string.
- ; ex) "What is your name?"
- ld l, c
- call PlaceTextItems
-.put_text_end
- ; print "End".
- ld hl, .data
- call PlaceTextItems
- ldtx hl, PlayerNameKeyboardText
- lb de, 2, 4
- call InitTextPrinting
- call ProcessTextFromID
- call EnableLCD
- ret
-.data
- textitem $0f, $10, EndText ; "End"
- db $ff
-
-DrawTextboxForKeyboard: ; 1a8c1 (6:68c1)
- lb de, 0, 3 ; x, y
- lb bc, 20, 15 ; w, h
- call DrawRegularTextBox
- ret
-
-PrintPlayerNameFromInput: ; 1a8cb (6:68cb)
- ld hl, wNamingScreenNamePosition
- ld d, [hl]
- inc hl
- ld e, [hl]
- push de
- call InitTextPrinting
- ld a, [wNamingScreenBufferMaxLength]
- ld e, a
- ld a, $14
- sub e
- inc a
- ld e, a
- ld d, 0
- ; print the underbars
- ; before print the input.
- ld hl, .char_underbar
- add hl, de
- call ProcessText
- pop de
- call InitTextPrinting
- ; print the input from the user.
- ld hl, wNamingScreenBuffer
- call ProcessText
- ret
-.char_underbar
- db $56
-rept 10
- textfw3 "_"
-endr
- done
-
-; check if button pressed.
-; if pressed, set the carry bit on.
-NamingScreen_CheckButtonState: ; 1a908 (6:6908)
- xor a
- ld [wPlaysSfx], a
- ldh a, [hDPadHeld]
- or a
- jp z, .no_press
- ; detected any button press.
- ld b, a
- ld a, [wNamingScreenKeyboardHeight]
- ld c, a
- ld a, [wNamingScreenCursorX]
- ld h, a
- ld a, [wNamingScreenCursorY]
- ld l, a
- bit D_UP_F, b
- jr z, .asm_692c
- ; up
- dec a
- bit D_DOWN_F, a
- jr z, .asm_69a7
- ld a, c
- dec a
- jr .asm_69a7
-.asm_692c
- bit D_DOWN_F, b
- jr z, .asm_6937
- ; down
- inc a
- cp c
- jr c, .asm_69a7
- xor a
- jr .asm_69a7
-.asm_6937
- ld a, [wNamingScreenNumColumns]
- ld c, a
- ld a, h
- bit D_LEFT_F, b
- jr z, .asm_6974
- ; left
- ld d, a
- ld a, $06
- cp l
- ld a, d
- jr nz, .asm_696b
- push hl
- push bc
- push af
- call GetCharInfoFromPos_Player
- inc hl
- inc hl
- inc hl
- inc hl
- inc hl
- ld a, [hl]
- dec a
- ld d, a
- pop af
- pop bc
- pop hl
- sub d
- cp $ff
- jr nz, .asm_6962
- ld a, c
- sub $02
- jr .asm_69aa
-.asm_6962
- cp $fe
- jr nz, .asm_696b
- ld a, c
- sub $03
- jr .asm_69aa
-.asm_696b
- dec a
- bit D_DOWN_F, a
- jr z, .asm_69aa
- ld a, c
- dec a
- jr .asm_69aa
-.asm_6974
- bit D_RIGHT_F, b
- jr z, .no_press
- ld d, a
- ld a, $06
- cp l
- ld a, d
- jr nz, .asm_6990
- push hl
- push bc
- push af
- call GetCharInfoFromPos_Player
- inc hl
- inc hl
- inc hl
- inc hl
- ld a, [hl]
- dec a
- ld d, a
- pop af
- pop bc
- pop hl
- add d
-.asm_6990
- inc a
- cp c
- jr c, .asm_69aa
- inc c
- cp c
- jr c, .asm_69a4
- inc c
- cp c
- jr c, .asm_69a0
- ld a, $02
- jr .asm_69aa
-.asm_69a0
- ld a, $01
- jr .asm_69aa
-.asm_69a4
- xor a
- jr .asm_69aa
-.asm_69a7
- ld l, a
- jr .asm_69ab
-.asm_69aa
- ld h, a
-.asm_69ab
- push hl
- call GetCharInfoFromPos_Player
- inc hl
- inc hl
- inc hl
- ld a, [wd009]
- cp $02
- jr nz, .asm_69bb
- inc hl
- inc hl
-.asm_69bb
- ld d, [hl]
- push de
- call Func_1aa07
- pop de
- pop hl
- ld a, l
- ld [wNamingScreenCursorY], a
- ld a, h
- ld [wNamingScreenCursorX], a
- xor a
- ld [wCheckMenuCursorBlinkCounter], a
- ld a, $06
- cp d
- jp z, NamingScreen_CheckButtonState
- ld a, $01
- ld [wPlaysSfx], a
-.no_press
- ldh a, [hKeysPressed]
- and A_BUTTON | B_BUTTON
- jr z, .asm_69ef
- and A_BUTTON
- jr nz, .asm_69e5
- ld a, $ff
-.asm_69e5
- call PlayAcceptOrDeclineSFX
- push af
- call Func_1aa23
- pop af
- scf
- ret
-.asm_69ef
- ld a, [wPlaysSfx]
- or a
- jr z, .asm_69f8
- call PlaySFX
-.asm_69f8
- ld hl, wCheckMenuCursorBlinkCounter
- ld a, [hl]
- inc [hl]
- and $0f
- ret nz
- ld a, [wVisibleCursorTile]
- bit 4, [hl]
- jr z, Func_1aa07.asm_6a0a
-
-Func_1aa07: ; 1aa07 (6:6a07)
- ld a, [wInvisibleCursorTile]
-.asm_6a0a
- ld e, a
- ld a, [wNamingScreenCursorX]
- ld h, a
- ld a, [wNamingScreenCursorY]
- ld l, a
- call GetCharInfoFromPos_Player
- ld a, [hli]
- ld c, a
- ld b, [hl]
- dec b
- ld a, e
- call Func_1aa28
- call WriteByteToBGMap0
- or a
- ret
-
-Func_1aa23: ; 1aa23 (6:6a23)
- ld a, [wVisibleCursorTile]
- jr Func_1aa07.asm_6a0a
-
-Func_1aa28: ; 1aa28 (6:6a28)
- push af
- push bc
- push de
- push hl
- push af
- call ZeroObjectPositions
- pop af
- ld b, a
- ld a, [wInvisibleCursorTile]
- cp b
- jr z, .asm_6a60
- ld a, [wNamingScreenBufferLength]
- srl a
- ld d, a
- ld a, [wNamingScreenBufferMaxLength]
- srl a
- ld e, a
- ld a, d
- cp e
- jr nz, .asm_6a49
- dec a
-.asm_6a49
- ld hl, wNamingScreenNamePosition
- add [hl]
- ld d, a
- ld h, $08
- ld l, d
- call HtimesL
- ld a, l
- add $08
- ld d, a
- ld e, $18
- ld bc, $0000
- call SetOneObjectAttributes
-.asm_6a60
- pop hl
- pop de
- pop bc
- pop af
- ret
-
-; load, to the first tile of v0Tiles0, the graphics for the
-; blinking black square used in name input screens.
-; for inputting full width text.
-LoadTextCursorTile: ; 1aa65 (6:6a65)
- ld hl, v0Tiles0 + $00 tiles
- ld de, .data
- ld b, 0
-.loop
- ld a, TILE_SIZE
- cp b
- ret z
- inc b
- ld a, [de]
- inc de
- ld [hli], a
- jr .loop
-
-.data
-rept TILE_SIZE
- db $ff
-endr
-
-; set the carry bit on,
-; if "End" was selected.
-NamingScreen_ProcessInput: ; 1aa87 (6:6a87)
- ld a, [wNamingScreenCursorX]
- ld h, a
- ld a, [wNamingScreenCursorY]
- ld l, a
- call GetCharInfoFromPos_Player
- inc hl
- inc hl
- ; load types into de.
- ld e, [hl]
- inc hl
- ld a, [hli]
- ld d, a
- cp $09
- jp z, .on_end
- cp $07
- jr nz, .asm_6ab8
- ld a, [wd009]
- or a
- jr nz, .asm_6aac
- ld a, $01
- jp .asm_6ace
-.asm_6aac
- dec a
- jr nz, .asm_6ab4
- ld a, $02
- jp .asm_6ace
-.asm_6ab4
- xor a
- jp .asm_6ace
-.asm_6ab8
- cp $08
- jr nz, .asm_6ad6
- ld a, [wd009]
- or a
- jr nz, .asm_6ac6
- ld a, $02
- jr .asm_6ace
-.asm_6ac6
- dec a
- jr nz, .asm_6acc
- xor a
- jr .asm_6ace
-.asm_6acc
- ld a, $01
-.asm_6ace
- ld [wd009], a
- call DrawNamingScreenBG
- or a
- ret
-.asm_6ad6
- ld a, [wd009]
- cp $02
- jr z, .read_char
- ldfw3 bc, "“"
- ld a, d
- cp b
- jr nz, .asm_6af4
- ld a, e
- cp c
- jr nz, .asm_6af4
- push hl
- ld hl, TransitionTable1 ; from 55th.
- call TransformCharacter
- pop hl
- jr c, .nothing
- jr .asm_6b09
-.asm_6af4
- ldfw3 bc, "º(2)"
- ld a, d
- cp b
- jr nz, .asm_6b1d
- ld a, e
- cp c
- jr nz, .asm_6b1d
- push hl
- ld hl, TransitionTable2 ; from 72th.
- call TransformCharacter
- pop hl
- jr c, .nothing
-.asm_6b09
- ld a, [wNamingScreenBufferLength]
- dec a
- dec a
- ld [wNamingScreenBufferLength], a
- ld hl, wNamingScreenBuffer
- push de
- ld d, 0
- ld e, a
- add hl, de
- pop de
- ld a, [hl]
- jr .asm_6b37
-.asm_6b1d
- ld a, d
- or a
- jr nz, .asm_6b37
- ld a, [wd009]
- or a
- jr nz, .asm_6b2b
- ld a, TX_HIRAGANA
- jr .asm_6b37
-.asm_6b2b
- ld a, TX_KATAKANA
- jr .asm_6b37
-; read character code from info. to register.
-; hl: pointer.
-.read_char
- ld e, [hl]
- inc hl
- ld a, [hl] ; a: first byte of the code.
- or a
- ; if 2 bytes code, jump.
- jr nz, .asm_6b37
- ; if 1 byte code(ascii),
- ; set first byte to $0e.
- ld a, $0e
-; on 2 bytes code.
-.asm_6b37
- ld d, a ; de: character code.
- ld hl, wNamingScreenBufferLength
- ld a, [hl]
- ld c, a
- push hl
- ld hl, wNamingScreenBufferMaxLength
- cp [hl]
- pop hl
- jr nz, .asm_6b4c
- ; if the buffer is full
- ; just change the last character of it.
- ld hl, wNamingScreenBuffer
- dec hl
- dec hl
- jr .asm_6b51
-; increase name length before add the character.
-.asm_6b4c
- inc [hl]
- inc [hl]
- ld hl, wNamingScreenBuffer
-; write 2 bytes character codes to the name buffer.
-; de: 2 bytes character codes.
-; hl: dest.
-.asm_6b51
- ld b, 0
- add hl, bc
- ld [hl], d
- inc hl
- ld [hl], e
- inc hl
- ld [hl], TX_END ; null terminator.
- call PrintPlayerNameFromInput
-.nothing
- or a
- ret
-.on_end
- scf
- ret
-
-; this transforms the last japanese character
-; in the name buffer into its dakuon shape or something.
-; it seems to have been deprecated as the game was translated into english.
-; but it can still be applied to english, such as upper-lower case transition.
-; hl: info. pointer.
-TransformCharacter: ; 1ab61 (6:6b61)
- ld a, [wNamingScreenBufferLength]
- or a
- jr z, .return ; if the length is zero, just return.
- dec a
- dec a
- push hl
- ld hl, wNamingScreenBuffer
- ld d, 0
- ld e, a
- add hl, de
- ld e, [hl]
- inc hl
- ld d, [hl]
- ; de: last character in the buffer,
- ; but byte-wise swapped.
- ld a, TX_KATAKANA
- cp e
- jr nz, .hiragana
- ; if it's katakana,
- ; make it hiragana by decreasing its high byte.
- dec e
-.hiragana
- pop hl
-.loop
- ld a, [hli]
- or a
- jr z, .return
- cp d
- jr nz, .next
- ld a, [hl]
- cp e
- jr nz, .next
- inc hl
- ld e, [hl]
- inc hl
- ld d, [hl]
- or a
- ret
-.next
- inc hl
- inc hl
- inc hl
- jr .loop
-.return
- scf
- ret
-
-; given the position of the current cursor,
-; it returns the pointer to the proper information.
-; h: position x.
-; l: position y.
-GetCharInfoFromPos_Player: ; 1ab93 (6:6b93)
- push de
- ; (information index) = (x) * (height) + (y)
- ; (height) = 0x05(Deck) or 0x06(Player)
- ld e, l
- ld d, h
- ld a, [wNamingScreenKeyboardHeight]
- ld l, a
- call HtimesL
- ld a, l
- add e
- ld hl, KeyboardData_Player
- pop de
- or a
- ret z
-.loop
- inc hl
- inc hl
- inc hl
- inc hl
- inc hl
- inc hl
- dec a
- jr nz, .loop
- ret
-
-; a set of keyboard datum.
-; unit: 6 bytes.
-; structure:
-; abs. y pos. (1) / abs. x pos. (1) / type 1 (1) / type 2 (1) / char. code (2)
-; unused data contains its character code as zero.
-kbitem: MACRO
- db \1, \2, \3, \4
-if (_NARG == 5)
- dw \5
-elif (\5 == TX_FULLWIDTH3)
- dw (\5 << 8) | STRCAT("FW3_", \6)
-else
- dw (\5 << 8) | \6
-endc
-ENDM
-
-KeyboardData_Player: ; 1abaf (6:6baf)
- kbitem $04, $02, $11, $00, TX_FULLWIDTH3, "A"
- kbitem $06, $02, $12, $00, TX_FULLWIDTH3, "J"
- kbitem $08, $02, $13, $00, TX_FULLWIDTH3, "S"
- kbitem $0a, $02, $14, $00, "o"
- kbitem $0c, $02, $15, $00, "d"
- kbitem $10, $0f, $01, $09, $0000
-
- kbitem $04, $04, $16, $00, TX_FULLWIDTH3, "B"
- kbitem $06, $04, $17, $00, TX_FULLWIDTH3, "K"
- kbitem $08, $04, $18, $00, TX_FULLWIDTH3, "T"
- kbitem $0a, $04, $19, $00, TX_FULLWIDTH3, "&"
- kbitem $0c, $04, $1a, $00, "e"
- kbitem $10, $0f, $01, $09, $0000
-
- kbitem $04, $06, $1b, $00, TX_FULLWIDTH3, "C"
- kbitem $06, $06, $1c, $00, TX_FULLWIDTH3, "L"
- kbitem $08, $06, $1d, $00, TX_FULLWIDTH3, "U"
- kbitem $0a, $06, $1e, $00, "j"
- kbitem $0c, $06, $1f, $00, "f"
- kbitem $10, $0f, $01, $09, $0000
-
- kbitem $04, $08, $20, $00, TX_FULLWIDTH3, "D"
- kbitem $06, $08, $21, $00, TX_FULLWIDTH3, "M"
- kbitem $08, $08, $22, $00, TX_FULLWIDTH3, "V"
- kbitem $0a, $08, $23, $00, "k"
- kbitem $0c, $08, $24, $00, "g"
- kbitem $10, $0f, $01, $09, $0000
-
- kbitem $04, $0a, $25, $00, TX_FULLWIDTH3, "E"
- kbitem $06, $0a, $26, $00, TX_FULLWIDTH3, "N"
- kbitem $08, $0a, $27, $00, TX_FULLWIDTH3, "W"
- kbitem $0a, $0a, $28, $00, "w"
- kbitem $0c, $0a, $29, $00, "h"
- kbitem $10, $0f, $01, $09, $0000
-
- kbitem $04, $0c, $2a, $00, TX_FULLWIDTH3, "F"
- kbitem $06, $0c, $2b, $00, TX_FULLWIDTH3, "O"
- kbitem $08, $0c, $2c, $00, TX_FULLWIDTH3, "X"
- kbitem $0a, $0c, $2d, $00, "`"
- kbitem $0c, $0c, $2e, $00, "i"
- kbitem $10, $0f, $01, $09, $0000
-
- kbitem $04, $0e, $2f, $00, TX_FULLWIDTH3, "G"
- kbitem $06, $0e, $30, $00, TX_FULLWIDTH3, "P"
- kbitem $08, $0e, $31, $00, TX_FULLWIDTH3, "Y"
- kbitem $0a, $0e, $32, $00, "a"
- kbitem $0c, $0e, $33, $00, TX_SYMBOL, SYM_No
- kbitem $10, $0f, $01, $09, $0000
-
- kbitem $04, $10, $34, $00, TX_FULLWIDTH3, "H"
- kbitem $06, $10, $35, $00, TX_FULLWIDTH3, "Q"
- kbitem $08, $10, $36, $00, TX_FULLWIDTH3, "Z"
- kbitem $0a, $10, $3c, $00, "b"
- kbitem $0c, $10, $3d, $00, TX_SYMBOL, SYM_Lv
- kbitem $10, $0f, $01, $09, $0000
-
- kbitem $04, $12, $37, $00, TX_FULLWIDTH3, "I"
- kbitem $06, $12, $38, $00, TX_FULLWIDTH3, "R"
- kbitem $08, $12, $39, $00, "n"
- kbitem $0a, $12, $3a, $00, "c"
- kbitem $0c, $12, $3b, $00, "p"
- kbitem $10, $0f, $01, $09, $0000
- kbitem $00, $00, $00, $00, $0000
-
-; a set of transition datum.
-; unit: 4 bytes.
-; structure:
-; previous char. code (2) / translated char. code (2)
-; - the former char. code contains 0x0e in high byte.
-; - the latter char. code contains only low byte.
-TransitionTable1:
- dw $0e16, $003e
- dw $0e17, $003f
- dw $0e18, $0040
- dw $0e19, $0041
- dw $0e1a, $0042
- dw $0e1b, $0043
- dw $0e1c, $0044
- dw $0e1d, $0045
- dw $0e1e, $0046
- dw $0e1f, $0047
- dw $0e20, $0048
- dw $0e21, $0049
- dw $0e22, $004a
- dw $0e23, $004b
- dw $0e24, $004c
- dw $0e2a, $004d
- dw $0e2b, $004e
- dw $0e2c, $004f
- dw $0e2d, $0050
- dw $0e2e, $0051
- dw $0e52, $004d
- dw $0e53, $004e
- dw $0e54, $004f
- dw $0e55, $0050
- dw $0e56, $0051
- dw $0000
-
-TransitionTable2:
- dw $0e2a, $0052
- dw $0e2b, $0053
- dw $0e2c, $0054
- dw $0e2d, $0055
- dw $0e2e, $0056
- dw $0e4d, $0052
- dw $0e4e, $0053
- dw $0e4f, $0054
- dw $0e50, $0055
- dw $0e51, $0056
- dw $0000
-
-; get deck name from the user into de.
-; function description is similar to the player's.
-; refer to 'InputPlayerName'.
-InputDeckName: ; 1ad89 (6:6d89)
- push af
- ; check if the buffer is empty.
- ld a, [de]
- or a
- jr nz, .not_empty
- ; this buffer will contain half-width chars.
- ld a, TX_HALFWIDTH
- ld [de], a
-.not_empty
- pop af
- inc a
- call InitializeInputName
- call Set_OBJ_8x8
-
- xor a
- ld [wTileMapFill], a
- call EmptyScreen
- call ZeroObjectPositions
-
- ld a, $01
- ld [wVBlankOAMCopyToggle], a
- call LoadSymbolsFont
-
- lb de, $38, $bf
- call SetupText
- call LoadHalfWidthTextCursorTile
-
- xor a
- ld [wd009], a
- call Func_1ae99
-
- xor a
- ld [wNamingScreenCursorX], a
- ld [wNamingScreenCursorY], a
-
- ld a, $09
- ld [wNamingScreenNumColumns], a
- ld a, $07
- ld [wNamingScreenKeyboardHeight], a
- ld a, $0f
- ld [wVisibleCursorTile], a
- ld a, $00
- ld [wInvisibleCursorTile], a
-.loop
- ld a, $01
- ld [wVBlankOAMCopyToggle], a
- call DoFrame
-
- call UpdateRNGSources
-
- ldh a, [hDPadHeld]
- and START
- jr z, .on_start
-
- ld a, $01
- call PlayAcceptOrDeclineSFX
- call Func_1afa1
-
- ld a, 6
- ld [wNamingScreenCursorX], a
- ld [wNamingScreenCursorY], a
- call Func_1afbd
-
- jr .loop
-.on_start
- call Func_1aefb
- jr nc, .loop
-
- cp $ff
- jr z, .asm_6e1c
-
- call Func_1aec3
- jr nc, .loop
-
- call FinalizeInputName
-
- ld hl, wNamingScreenDestPointer
- ld a, [hli]
- ld h, [hl]
- ld l, a
- inc hl
-
- ld a, [hl]
- or a
- jr nz, .return
-
- dec hl
- ld [hl], TX_END
-.return
- ret
-.asm_6e1c
- ld a, [wNamingScreenBufferLength]
- cp $02
- jr c, .loop
-
- ld e, a
- ld d, 0
- ld hl, wNamingScreenBuffer
- add hl, de
- dec hl
- ld [hl], TX_END
-
- ld hl, wNamingScreenBufferLength
- dec [hl]
- call ProcessTextWithUnderbar
-
- jp .loop
-
-; load, to the first tile of v0Tiles0, the graphics for the
-; blinking black square used in name input screens.
-; for inputting half width text.
-LoadHalfWidthTextCursorTile: ; 1ae37 (6:6e37)
- ld hl, v0Tiles0 + $00 tiles
- ld de, .data
- ld b, 0
-.loop
- ld a, TILE_SIZE
- cp b
- ret z
- inc b
- ld a, [de]
- inc de
- ld [hli], a
- jr .loop
-
-.data
-rept TILE_SIZE
- db $f0
-endr
-
-; it's only for naming the deck.
-ProcessTextWithUnderbar: ; 1ae59 (6:6e59)
- ld hl, wNamingScreenNamePosition
- ld d, [hl]
- inc hl
- ld e, [hl]
- call InitTextPrinting
- ld hl, .underbar_data
- ld de, wDefaultText
-.loop ; copy the underbar string.
- ld a, [hli]
- ld [de], a
- inc de
- or a
- jr nz, .loop
-
- ld hl, wNamingScreenBuffer
- ld de, wDefaultText
-.loop2 ; copy the input from the user.
- ld a, [hli]
- or a
- jr z, .print_name
- ld [de], a
- inc de
- jr .loop2
-.print_name
- ld hl, wDefaultText
- call ProcessText
- ret
-.underbar_data
- db TX_HALFWIDTH
-rept MAX_DECK_NAME_LENGTH
- db "_"
-endr
- db TX_END
-
-Func_1ae99: ; 1ae99 (6:6e99)
- call DrawTextboxForKeyboard
- call ProcessTextWithUnderbar
- ld hl, wNamingScreenQuestionPointer
- ld c, [hl]
- inc hl
- ld a, [hl]
- ld h, a
- or c
- jr z, .print
- ; print the question string.
- ld l, c
- call PlaceTextItems
-.print
- ; print "End"
- ld hl, DrawNamingScreenBG.data
- call PlaceTextItems
- ; print the keyboard characters.
- ldtx hl, DeckNameKeyboardText ; "A B C D..."
- lb de, 2, 4
- call InitTextPrinting
- call ProcessTextFromID
- call EnableLCD
- ret
-
-Func_1aec3: ; 1aec3 (6:6ec3)
- ld a, [wNamingScreenCursorX]
- ld h, a
- ld a, [wNamingScreenCursorY]
- ld l, a
- call GetCharInfoFromPos_Deck
- inc hl
- inc hl
- ld a, [hl]
- cp $01
- jr nz, .asm_6ed7
- scf
- ret
-.asm_6ed7
- ld d, a
- ld hl, wNamingScreenBufferLength
- ld a, [hl]
- ld c, a
- push hl
- ld hl, wNamingScreenBufferMaxLength
- cp [hl]
- pop hl
- jr nz, .asm_6eeb
- ld hl, wNamingScreenBuffer
- dec hl
- jr .asm_6eef
-.asm_6eeb
- inc [hl]
- ld hl, wNamingScreenBuffer
-.asm_6eef
- ld b, 0
- add hl, bc
- ld [hl], d
- inc hl
- ld [hl], TX_END
- call ProcessTextWithUnderbar
- or a
- ret
-
-Func_1aefb: ; 1aefb (6:6efb)
- xor a
- ld [wPlaysSfx], a
- ldh a, [hDPadHeld]
- or a
- jp z, .asm_6f73
- ld b, a
- ld a, [wNamingScreenKeyboardHeight]
- ld c, a
- ld a, [wNamingScreenCursorX]
- ld h, a
- ld a, [wNamingScreenCursorY]
- ld l, a
- bit 6, b
- jr z, .asm_6f1f
- dec a
- bit 7, a
- jr z, .asm_6f4b
- ld a, c
- dec a
- jr .asm_6f4b
-.asm_6f1f
- bit 7, b
- jr z, .asm_6f2a
- inc a
- cp c
- jr c, .asm_6f4b
- xor a
- jr .asm_6f4b
-.asm_6f2a
- cp $06
- jr z, .asm_6f73
- ld a, [wNamingScreenNumColumns]
- ld c, a
- ld a, h
- bit 5, b
- jr z, .asm_6f40
- dec a
- bit 7, a
- jr z, .asm_6f4e
- ld a, c
- dec a
- jr .asm_6f4e
-.asm_6f40
- bit 4, b
- jr z, .asm_6f73
- inc a
- cp c
- jr c, .asm_6f4e
- xor a
- jr .asm_6f4e
-.asm_6f4b
- ld l, a
- jr .asm_6f4f
-.asm_6f4e
- ld h, a
-.asm_6f4f
- push hl
- call GetCharInfoFromPos_Deck
- inc hl
- inc hl
- ld d, [hl]
- push de
- call Func_1afa1
- pop de
- pop hl
- ld a, l
- ld [wNamingScreenCursorY], a
- ld a, h
- ld [wNamingScreenCursorX], a
- xor a
- ld [wCheckMenuCursorBlinkCounter], a
- ld a, $02
- cp d
- jp z, Func_1aefb
- ld a, $01
- ld [wPlaysSfx], a
-.asm_6f73
- ldh a, [hKeysPressed]
- and $03
- jr z, .asm_6f89
- and $01
- jr nz, .asm_6f7f
- ld a, $ff
-.asm_6f7f
- call PlayAcceptOrDeclineSFX
- push af
- call Func_1afbd
- pop af
- scf
- ret
-.asm_6f89
- ld a, [wPlaysSfx]
- or a
- jr z, .asm_6f92
- call PlaySFX
-.asm_6f92
- ld hl, wCheckMenuCursorBlinkCounter
- ld a, [hl]
- inc [hl]
- and $0f
- ret nz
- ld a, [wVisibleCursorTile]
- bit 4, [hl]
- jr z, Func_1afa1.asm_6fa4
-
-Func_1afa1: ; 1afa1 (6:6fa1)
- ld a, [wInvisibleCursorTile]
-.asm_6fa4
- ld e, a
- ld a, [wNamingScreenCursorX]
- ld h, a
- ld a, [wNamingScreenCursorY]
- ld l, a
- call GetCharInfoFromPos_Deck
- ld a, [hli]
- ld c, a
- ld b, [hl]
- dec b
- ld a, e
- call Func_1afc2
- call WriteByteToBGMap0
- or a
- ret
-
-Func_1afbd: ; 1afbd (6:6fbd)
- ld a, [wVisibleCursorTile]
- jr Func_1afa1.asm_6fa4
-
-Func_1afc2: ; 1afc2 (6:6fc2)
- push af
- push bc
- push de
- push hl
- push af
- call ZeroObjectPositions
- pop af
- ld b, a
- ld a, [wInvisibleCursorTile]
- cp b
- jr z, .asm_6ffb
- ld a, [wNamingScreenBufferLength]
- ld d, a
- ld a, [wNamingScreenBufferMaxLength]
- ld e, a
- ld a, d
- cp e
- jr nz, .asm_6fdf
- dec a
-.asm_6fdf
- dec a
- ld d, a
- ld hl, wNamingScreenNamePosition
- ld a, [hl]
- sla a
- add d
- ld d, a
- ld h, $04
- ld l, d
- call HtimesL
- ld a, l
- add $08
- ld d, a
- ld e, $18
- ld bc, $0000
- call SetOneObjectAttributes
-.asm_6ffb
- pop hl
- pop de
- pop bc
- pop af
- ret
-
-; given the cursor position,
-; returns the character information which the cursor directs.
-; it's similar to "GetCharInfoFromPos_Player",
-; but the data structure is different in its unit size.
-; its unit size is 3, and player's is 6.
-; h: x
-; l: y
-GetCharInfoFromPos_Deck: ; 1b000 (6:7000)
- push de
- ld e, l
- ld d, h
- ld a, [wNamingScreenKeyboardHeight]
- ld l, a
- call HtimesL
- ld a, l
- add e
- ; x * h + y
- ld hl, KeyboardData_Deck
- pop de
- or a
- ret z
-.loop
- inc hl
- inc hl
- inc hl
- dec a
- jr nz, .loop
- ret
-
-KeyboardData_Deck: ; 1b019 (6:7019)
- db $04, $02, "A"
- db $06, $02, "J"
- db $08, $02, "S"
- db $0a, $02, "?"
- db $0c, $02, "4"
- db $0e, $02, $02
- db $10, $0f, $01
-
- db $04, $04, "B"
- db $06, $04, "K"
- db $08, $04, "T"
- db $0a, $04, "&"
- db $0c, $04, "5"
- db $0e, $04, $02
- db $10, $0f, $01
-
- db $04, $06, "C"
- db $06, $06, "L"
- db $08, $06, "U"
- db $0a, $06, "+"
- db $0c, $06, "6"
- db $0e, $06, $02
- db $10, $0f, $01
-
- db $04, $08, "D"
- db $06, $08, "M"
- db $08, $08, "V"
- db $0a, $08, "-"
- db $0c, $08, "7"
- db $0e, $08, $02
- db $10, $0f, $01
-
- db $04, $0a, "E"
- db $06, $0a, "N"
- db $08, $0a, "W"
- db $0a, $0a, "'"
- db $0c, $0a, "8"
- db $0e, $0a, $02
- db $10, $0f, $01
-
- db $04, $0c, "F"
- db $06, $0c, "O"
- db $08, $0c, "X"
- db $0a, $0c, "0"
- db $0c, $0c, "9"
- db $0e, $0c, $02
- db $10, $0f, $01
-
- db $04, $0e, "G"
- db $06, $0e, "P"
- db $08, $0e, "Y"
- db $0a, $0e, "1"
- db $0c, $0e, " "
- db $0e, $0e, $02
- db $10, $0f, $01
-
- db $04, $10, "H"
- db $06, $10, "Q"
- db $08, $10, "Z"
- db $0a, $10, "2"
- db $0c, $10, " "
- db $0e, $10, $02
- db $10, $0f, $01
-
- db $04, $12, "I"
- db $06, $12, "R"
- db $08, $12, "!"
- db $0a, $12, "3"
- db $0c, $12, " "
- db $0e, $12, $02
- db $10, $0f, $01
-
- ds 4 ; empty
-
-INCLUDE "data/auto_deck_card_lists.asm"
-INCLUDE "data/auto_deck_machines.asm"
-
-; writes to sAutoDecks all the deck configurations
-; from the Auto Deck Machine in wCurAutoDeckMachine
-ReadAutoDeckConfiguration: ; 1ba14 (6:7a14)
- call EnableSRAM
- ld a, [wCurAutoDeckMachine]
- ld l, a
- ld h, 6 * NUM_DECK_MACHINE_SLOTS
- call HtimesL
- ld bc, AutoDeckMachineEntries
- add hl, bc
- ld b, 0
-.loop_decks
- call .GetPointerToSRAMAutoDeck
- call .ReadDeckConfiguration
- call .ReadDeckName
-
- ; store deck description text ID
- push hl
- ld de, wAutoDeckMachineTextDescriptions
- ld h, b
- ld l, 2
- call HtimesL
- add hl, de
- ld d, h
- ld e, l
- pop hl
- ld a, [hli]
- ld [de], a
- inc de
- ld a, [hli]
- ld [de], a
- inc b
- ld a, b
- cp NUM_DECK_MACHINE_SLOTS
- jr nz, .loop_decks
- call DisableSRAM
- ret
-
-; outputs in de the saved deck with index b
-.GetPointerToSRAMAutoDeck
- push hl
- ld l, b
- ld h, DECK_STRUCT_SIZE
- call HtimesL
- ld de, sAutoDecks
- add hl, de
- ld d, h
- ld e, l
- pop hl
- ret
-
-; writes the deck configuration in SRAM
-; by reading the given deck card list
-.ReadDeckConfiguration
- push hl
- push bc
- push de
- push de
- ld e, [hl]
- inc hl
- ld d, [hl]
- pop hl
- ld bc, DECK_NAME_SIZE
- add hl, bc
-.loop_create_deck
- ld a, [de]
- inc de
- ld b, a ; card count
- or a
- jr z, .done_create_deck
- ld a, [de]
- inc de
- ld c, a ; card ID
-.loop_card_count
- ld [hl], c
- inc hl
- dec b
- jr nz, .loop_card_count
- jr .loop_create_deck
-.done_create_deck
- pop de
- pop bc
- pop hl
- inc hl
- inc hl
- ret
-
-.ReadDeckName
- push hl
- push bc
- push de
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld de, wDismantledDeckName
- call CopyText
- pop hl
- ld de, wDismantledDeckName
-.loop_copy_name
- ld a, [de]
- ld [hli], a
- or a
- jr z, .done_copy_name
- inc de
- jr .loop_copy_name
-.done_copy_name
- pop bc
- pop hl
- inc hl
- inc hl
- ret
-
-; tries out all combinations of dismantling the player's decks
-; in order to build the deck in wSelectedDeckMachineEntry
-; if none of the combinations work, return carry set
-; otherwise, return in a which deck flags should be dismantled
-CheckWhichDecksToDismantleToBuildSavedDeck: ; 1ba9a (6:7a9a)
- xor a
- ld [wDecksToBeDismantled], a
-
-; first check if it can be built by
-; only dismantling a single deck
- ld a, DECK_1
-.loop_single_built_decks
- call .CheckIfCanBuild
- ret nc
- sla a ; next deck
- cp (1 << NUM_DECKS)
- jr z, .two_deck_combinations
- jr .loop_single_built_decks
-
-.two_deck_combinations
-; next check all two deck combinations
- ld a, DECK_1 | DECK_2
- call .CheckIfCanBuild
- ret nc
- ld a, DECK_1 | DECK_3
- call .CheckIfCanBuild
- ret nc
- ld a, DECK_1 | DECK_4
- call .CheckIfCanBuild
- ret nc
- ld a, DECK_2 | DECK_3
- call .CheckIfCanBuild
- ret nc
- ld a, DECK_2 | DECK_4
- call .CheckIfCanBuild
- ret nc
- ld a, DECK_3 | DECK_4
- call .CheckIfCanBuild
- ret nc
-
-; all but one deck combinations
- ld a, $ff ^ DECK_4
-.loop_three_deck_combinations
- call .CheckIfCanBuild
- ret nc
- sra a
- cp $ff
- jr z, .all_decks
- jr .loop_three_deck_combinations
-
-.all_decks
-; finally check if can be built by dismantling all decks
- call .CheckIfCanBuild
- ret nc
-
-; none of the combinations work
- scf
- ret
-
-; returns carry if wSelectedDeckMachineEntry cannot be built
-; by dismantling the decks given by register a
-; a = DECK_* flags
-.CheckIfCanBuild
- push af
- ld hl, wSelectedDeckMachineEntry
- ld b, [hl]
- farcall CheckIfCanBuildSavedDeck
- jr c, .cannot_build
- pop af
- ld [wDecksToBeDismantled], a
- or a
- ret
-.cannot_build
- pop af
- scf
- ret
diff --git a/src/engine/bank07.asm b/src/engine/bank07.asm
index d0172e5..cf9da13 100644
--- a/src/engine/bank07.asm
+++ b/src/engine/bank07.asm
@@ -1,24 +1,24 @@
-Func_1c000: ; 1c000 (7:4000)
- jp Set_WD_off
+JumpSetWindowOff:
+ jp SetWindowOff
-; unreferenced debug function
+; debug function
; prints player's coordinates by pressing B
; and draws palettes by pressing A
-Func_1c003: ; 1c003 (7:4003)
+Func_1c003: ; unreferenced
ld a, [wCurMap]
or a
- jr z, Func_1c000
+ jr z, JumpSetWindowOff
ld a, [wOverworldMode]
cp OWMODE_START_SCRIPT
- jr nc, Func_1c000
+ jr nc, JumpSetWindowOff
ldh a, [hKeysHeld]
ld b, a
and A_BUTTON | B_BUTTON
cp b
- jr nz, Func_1c000
+ jr nz, JumpSetWindowOff
and B_BUTTON
- jr z, Func_1c000
+ jr z, JumpSetWindowOff
ld bc, $20
ld a, [wPlayerXCoord]
@@ -46,10 +46,10 @@ Func_1c003: ; 1c003 (7:4003)
ld a, $68
ldh [hWY], a
.set_wd_on
- call Set_WD_on
+ call SetWindowOn
ret
-Func_1c056: ; 1c056 (7:4056)
+Func_1c056:
push hl
push bc
push de
@@ -100,7 +100,7 @@ Func_1c056: ; 1c056 (7:4056)
INCLUDE "data/warps.asm"
; loads data from the map header of wCurMap
-LoadMapHeader: ; 1c33b (7:433b)
+LoadMapHeader:
push hl
push bc
push de
@@ -143,7 +143,7 @@ LoadMapHeader: ; 1c33b (7:433b)
INCLUDE "data/map_headers.asm"
-ClearNPCs: ; 1c440 (7:4440)
+ClearNPCs:
push hl
push bc
ld hl, wLoadedNPCs
@@ -159,7 +159,7 @@ ClearNPCs: ; 1c440 (7:4440)
pop hl
ret
-GetNPCDirection: ; 1c455 (7:4455)
+GetNPCDirection:
push hl
ld a, [wLoadedNPCTempIndex]
ld l, LOADED_NPC_DIRECTION
@@ -171,7 +171,7 @@ GetNPCDirection: ; 1c455 (7:4455)
; sets new position to active NPC
; and updates its tile permissions
; bc = new coords
-SetNPCPosition: ; 1c461 (7:4461)
+SetNPCPosition:
push hl
push bc
call UpdateNPCsTilePermission
@@ -186,7 +186,7 @@ SetNPCPosition: ; 1c461 (7:4461)
pop hl
ret
-GetNPCPosition: ; 1c477 (7:4477)
+GetNPCPosition:
push hl
ld a, [wLoadedNPCTempIndex]
ld l, LOADED_NPC_COORD_X
@@ -198,7 +198,7 @@ GetNPCPosition: ; 1c477 (7:4477)
ret
; Loads NPC Sprite Data
-LoadNPC: ; 1c485 (7:4485)
+LoadNPC:
push hl
push bc
push de
@@ -265,7 +265,7 @@ LoadNPC: ; 1c485 (7:4485)
ret
; returns carry if input NPC ID in register a is Ronald
-CheckIfNPCIsRonald: ; 1c4fa (7:44fa)
+CheckIfNPCIsRonald:
cp NPC_RONALD1
jr z, .set_carry
cp NPC_RONALD2
@@ -278,7 +278,7 @@ CheckIfNPCIsRonald: ; 1c4fa (7:44fa)
scf
ret
-UnloadNPC: ; 1c50a (7:450a)
+UnloadNPC:
push hl
call UpdateNPCsTilePermission
ld a, [wLoadedNPCTempIndex]
@@ -303,7 +303,7 @@ UnloadNPC: ; 1c50a (7:450a)
pop hl
ret
-Func_1c52e: ; 1c52e (7:452e)
+Func_1c52e:
push hl
push af
ld a, [wLoadedNPCTempIndex]
@@ -315,7 +315,7 @@ Func_1c52e: ; 1c52e (7:452e)
pop hl
ret
-Func_1c53f: ; 1c53f (7:453f)
+Func_1c53f:
push hl
push bc
ld a, [wLoadedNPCTempIndex]
@@ -332,7 +332,7 @@ Func_1c53f: ; 1c53f (7:453f)
pop hl
ret
-Func_1c557: ; 1c557 (7:4557)
+Func_1c557:
push bc
ld c, a
ld a, [wLoadedNPCTempIndex]
@@ -357,7 +357,7 @@ Func_1c557: ; 1c557 (7:4557)
ret
; a = NPC animation
-SetNPCAnimation: ; 1c57b (7:457b)
+SetNPCAnimation:
push hl
push bc
push af
@@ -371,7 +371,7 @@ SetNPCAnimation: ; 1c57b (7:457b)
pop hl
ret
-UpdateNPCAnimation: ; 1c58e (7:458e)
+UpdateNPCAnimation:
push hl
push bc
ld a, [wWhichSprite]
@@ -404,7 +404,7 @@ UpdateNPCAnimation: ; 1c58e (7:458e)
; give it a random initial value
; this makes it so that all NPCs are out of phase
; when they are loaded into a map
-ApplyRandomCountToNPCAnim: ; 1c5b9 (7:45b9)
+ApplyRandomCountToNPCAnim:
push hl
push bc
ld a, [wWhichSprite]
@@ -438,7 +438,7 @@ ApplyRandomCountToNPCAnim: ; 1c5b9 (7:45b9)
; sets the loaded NPC's direction
; to the direction that is in LOADED_NPC_DIRECTION_BACKUP
-Func_1c5e9: ; 1c5e9 (7:45e9)
+Func_1c5e9:
push hl
push bc
ld a, [wLoadedNPCTempIndex]
@@ -454,7 +454,7 @@ Func_1c5e9: ; 1c5e9 (7:45e9)
ret
; a = new direction
-SetNPCDirection: ; 1c5ff (7:45ff)
+SetNPCDirection:
push hl
push af
ld a, [wLoadedNPCTempIndex]
@@ -466,7 +466,7 @@ SetNPCDirection: ; 1c5ff (7:45ff)
pop hl
ret
-HandleAllNPCMovement: ; 1c610 (7:4610)
+HandleAllNPCMovement:
push hl
push bc
push de
@@ -527,7 +527,7 @@ HandleAllNPCMovement: ; 1c610 (7:4610)
pop hl
ret
-UpdateNPCSpritePosition: ; 1c665 (7:4665)
+UpdateNPCSpritePosition:
push hl
push bc
push de
@@ -623,7 +623,7 @@ UpdateNPCSpritePosition: ; 1c665 (7:4665)
; ands wIsAnNPCMoving with the current
; NPC's NPC_FLAG_MOVING_F
-UpdateIsAnNPCMovingFlag: ; 1c6d3 (7:46d3)
+UpdateIsAnNPCMovingFlag:
push hl
push bc
ld bc, LOADED_NPC_FLAGS
@@ -635,7 +635,7 @@ UpdateIsAnNPCMovingFlag: ; 1c6d3 (7:46d3)
pop hl
ret
-SetNPCsTilePermission: ; 1c6e3 (7:46e3)
+SetNPCsTilePermission:
push hl
push bc
ld a, [wLoadedNPCTempIndex]
@@ -650,7 +650,7 @@ SetNPCsTilePermission: ; 1c6e3 (7:46e3)
pop hl
ret
-SetAllNPCTilePermissions: ; 1c6f8 (7:46f8)
+SetAllNPCTilePermissions:
push hl
push bc
push de
@@ -675,7 +675,7 @@ SetAllNPCTilePermissions: ; 1c6f8 (7:46f8)
pop hl
ret
-UpdateNPCsTilePermission: ; 1c719 (7:4719)
+UpdateNPCsTilePermission:
push hl
push bc
ld a, [wLoadedNPCTempIndex]
@@ -691,7 +691,7 @@ UpdateNPCsTilePermission: ; 1c719 (7:4719)
ret
; Find NPC at coords b (x) c (y)
-FindNPCAtLocation: ; 1c72e (7:472e)
+FindNPCAtLocation:
push hl
push bc
push de
@@ -742,7 +742,7 @@ FindNPCAtLocation: ; 1c72e (7:472e)
; Probably needs a new name. Loads data for NPC that the next Script is for
; Sets direction, Loads Image data for it, loads name, and more
-SetNewScriptNPC: ; 1c768 (7:4768)
+SetNewScriptNPC:
push hl
ld a, [wLoadedNPCTempIndex]
ld l, LOADED_NPC_DIRECTION
@@ -760,7 +760,7 @@ SetNewScriptNPC: ; 1c768 (7:4768)
pop hl
ret
-StartNPCMovement: ; 1c78d (7:478d)
+StartNPCMovement:
push hl
; set NPC as moving
ld a, [wLoadedNPCTempIndex]
@@ -825,7 +825,7 @@ StartNPCMovement: ; 1c78d (7:478d)
ret
; returns nz if there is an NPC currently moving
-CheckIsAnNPCMoving: ; 1c7de (7:47de)
+CheckIsAnNPCMoving:
ld a, [wIsAnNPCMoving]
and NPC_FLAG_MOVING
ret
@@ -833,7 +833,7 @@ CheckIsAnNPCMoving: ; 1c7de (7:47de)
; while the NPC is moving, increment its movement step by 1
; once it reaches a value greater than 16, update
; its tile permission and its position and start next movement
-UpdateNPCMovementStep: ; 1c7e4 (7:47e4)
+UpdateNPCMovementStep:
push hl
push bc
push de
@@ -861,7 +861,7 @@ UpdateNPCMovementStep: ; 1c7e4 (7:47e4)
pop hl
ret
-UpdateNPCPosition: ; 1c80d (7:480d)
+UpdateNPCPosition:
push hl
push bc
ld a, [wLoadedNPCTempIndex]
@@ -888,7 +888,7 @@ UpdateNPCPosition: ; 1c80d (7:480d)
pop hl
ret
-ClearMasterBeatenList: ; 1c82e (7:482e)
+ClearMasterBeatenList:
push hl
push bc
ld c, $a
@@ -904,7 +904,7 @@ ClearMasterBeatenList: ; 1c82e (7:482e)
; writes Master in register a to
; first empty slot in wMastersBeatenList
-AddMasterBeatenToList: ; 1c83d (7:483d)
+AddMasterBeatenToList:
push hl
push bc
ld b, a
@@ -933,7 +933,7 @@ AddMasterBeatenToList: ; 1c83d (7:483d)
; iterates all masters and attempts to
; add each of them to wMastersBeatenList
-AddAllMastersToMastersBeatenList: ; 1c858 (7:4858)
+AddAllMastersToMastersBeatenList:
ld a, $01
.loop
push af
@@ -944,13 +944,13 @@ AddAllMastersToMastersBeatenList: ; 1c858 (7:4858)
jr c, .loop
ret
-Func_1c865: ; 1c865 (7:4865)
+Func_1c865:
ret
-; unreferenced debug function
+; debug function
; adjusts hSCX and hSCY by using the arrow keys
; pressing B makes it scroll faster
-Func_1c866: ; 1c866 (7:4866)
+Func_1c866: ; unreferenced
ldh a, [hKeysHeld]
and B_BUTTON
call nz, .asm_1c86d ; executes following part twice
@@ -982,9 +982,8 @@ Func_1c866: ; 1c866 (7:4866)
ldh [hSCY], a
ret
-; unreferenced
; sets some flags on a given sprite
-Func_1c890: ; 1c890 (7:4890)
+Func_1c890: ; unreferenced
ld a, [wVBlankCounter]
and %111111
ret nz
@@ -1012,1775 +1011,3 @@ Func_1c890: ; 1c890 (7:4890)
set SPRITE_ANIM_FLAG_SPEED, [hl]
.asm_1c8bb
ret
-
-Func_1c8bc: ; 1c8bc (7:48bc)
- push hl
- push bc
- call Set_OBJ_8x8
- ld a, LOW(Func_3ba2)
- ld [wDoFrameFunction], a
- ld a, HIGH(Func_3ba2)
- ld [wDoFrameFunction + 1], a
- ld a, $ff
- ld hl, wAnimationQueue
- ld c, ANIMATION_QUEUE_LENGTH
-.fill_queue
- ld [hli], a
- dec c
- jr nz, .fill_queue
- ld [wd42a], a
- ld [wd4c0], a
- xor a
- ld [wDuelAnimBufferCurPos], a
- ld [wDuelAnimBufferSize], a
- ld [wd4b3], a
- call DefaultScreenAnimationUpdate
- call Func_3ca0
- pop bc
- pop hl
- ret
-
-PlayLoadedDuelAnimation: ; 1c8ef (7:48ef)
- ld a, [wDoFrameFunction + 0]
- cp LOW(Func_3ba2)
- jr nz, .error
- ld a, [wDoFrameFunction + 1]
- cp HIGH(Func_3ba2)
- jr z, .okay
-.error
- debug_nop
- ret
-
-.okay
- ld a, [wTempAnimation]
- ld [wd4bf], a
- cp DUEL_SPECIAL_ANIMS
- jp nc, Func_1cb5e
-
- push hl
- push bc
- push de
- call GetAnimationData
-; hl: pointer
-
- ld a, [wAnimationsDisabled]
- or a
- jr z, .check_to_play_sfx
- ; animations are disabled
- push hl
- ld bc, ANIM_SPRITE_ANIM_FLAGS
- add hl, bc
- ld a, [hl]
- ; if flag is set, play animation anyway
- and (1 << SPRITE_ANIM_FLAG_UNSKIPPABLE)
- pop hl
- jr z, .return
-
-.check_to_play_sfx
- push hl
- ld bc, ANIM_SOUND_FX_ID
- add hl, bc
- ld a, [hl]
- pop hl
- or a
- jr z, .calc_addr
- call PlaySFX
-
-.calc_addr
-; this data field is always $00,
-; so this calculation is unnecessary
-; seems like there was supposed to be
-; more than 1 function to handle animation
- push hl
- ld bc, ANIM_HANDLER_FUNCTION
- add hl, bc
- ld a, [hl]
- rlca
- add LOW(.address) ; $48
- ld l, a ; LO
- ld a, HIGH(.address) ; $49
- adc 0
- ld h, a ; HI
-; hl: pointer
- ld a, [hli]
- ld b, [hl]
- ld c, a
- pop hl
-
- call CallBC
-.return
- pop de
- pop bc
- pop hl
- ret
-
-.address
- dw .handler_func
-
-.handler_func ; 1c94a (7:494a)
-; if any of ANIM_SPRITE_ID, ANIM_PALETTE_ID and ANIM_SPRITE_ANIM_ID
-; are 0, then return
- ld e, l
- ld d, h
- ld c, ANIM_SPRITE_ANIM_ID + 1
-.loop
- ld a, [de]
- or a
- jr z, .return_with_carry
- inc de
- dec c
- jr nz, .loop
-
- ld a, [hli] ; ANIM_SPRITE_ID
- farcall CreateSpriteAndAnimBufferEntry
- ld a, [wWhichSprite]
- ld [wAnimationQueue], a ; push an animation to the queue
-
- xor a
- ld [wVRAMTileOffset], a
- ld [wd4cb], a
-
- ld a, [hli] ; ANIM_PALETTE_ID
- farcall LoadPaletteData
- ld a, [hli] ; ANIM_SPRITE_ANIM_ID
-
- push af
- ld a, [hli] ; ANIM_SPRITE_ANIM_FLAGS
- ld [wAnimFlags], a
- call LoadAnimCoordsAndFlags
- pop af
-
- farcall StartNewSpriteAnimation
- or a
- jr .done
-
-.return_with_carry
- scf
-.done
- ret
-
-; loads the correct coordinates/flags for
-; sprite animation in wAnimationQueue
-LoadAnimCoordsAndFlags: ; 1c980 (7:4980)
- push hl
- push bc
- ld a, [wAnimationQueue]
- ld c, SPRITE_ANIM_ATTRIBUTES
- call GetSpriteAnimBufferProperty_SpriteInA
- call GetAnimCoordsAndFlags
-
- push af
- and (1 << SPRITE_ANIM_FLAG_6) | (1 << SPRITE_ANIM_FLAG_5)
- or [hl]
- ld [hli], a
- ld a, b
- ld [hli], a ; SPRITE_ANIM_COORD_X
- ld [hl], c ; SPRITE_ANIM_COORD_Y
- pop af
-
- ld bc, SPRITE_ANIM_FLAGS - SPRITE_ANIM_COORD_Y
- add hl, bc
- ld c, a ; useless
- and (1 << SPRITE_ANIM_FLAG_Y_SUBTRACT) | (1 << SPRITE_ANIM_FLAG_X_SUBTRACT)
- or [hl]
- ld [hl], a
- pop bc
- pop hl
- ret
-
-; outputs x and y coordinates for the sprite animation
-; taking into account who the turn duelist is.
-; also returns in a the allowed animation flags of
-; the configuration that is selected.
-; output:
-; a = anim flags
-; b = x coordinate
-; c = y coordinate
-GetAnimCoordsAndFlags: ; 1c9a2 (7:49a2)
- push hl
- ld c, 0
- ld a, [wAnimFlags]
- and (1 << SPRITE_ANIM_FLAG_SPEED)
- jr nz, .calc_addr
-
- ld a, [wDuelAnimationScreen]
- add a ; 2 * [wDuelAnimationScreen]
- ld c, a
- add a ; 4 * [wDuelAnimationScreen]
- add c ; 6 * [wDuelAnimationScreen]
- add a ; 12 * [wDuelAnimationScreen]
- ld c, a
-
- ld a, [wDuelAnimDuelistSide]
- cp PLAYER_TURN
- jr z, .player_side
-; opponent side
- ld a, 6
- add c
- ld c, a
-.player_side
- ld a, [wDuelAnimLocationParam]
- add c ; a = [wDuelAnimLocationParam] + c
- ld c, a
- ld b, 0
- ld hl, AnimationCoordinatesIndex
- add hl, bc
- ld c, [hl]
-
-.calc_addr
- ld a, c
- add a ; a = c * 2
- add c ; a = c * 3
- ld c, a
- ld b, 0
- ld hl, AnimationCoordinates
- add hl, bc
- ld b, [hl] ; x coord
- inc hl
- ld c, [hl] ; y coord
- inc hl
- ld a, [wAnimFlags]
- and [hl] ; flags
- pop hl
- ret
-
-AnimationCoordinatesIndex:
-; animations in the Duel Main Scene
- db $01, $01, $01, $01, $01, $01 ; player
- db $02, $02, $02, $02, $02, $02 ; opponent
-
-; animations in the Player's Play Area, for each Play Area Pokemon
- db $03, $04, $05, $06, $07, $08 ; player
- db $03, $04, $05, $06, $07, $08 ; opponent
-
-; animations in the Opponent's Play Area, for each Play Area Pokemon
- db $09, $0a, $0b, $0c, $0d, $0e ; player
- db $09, $0a, $0b, $0c, $0d, $0e ; opponent
-
-anim_coords: MACRO
- db \1
- db \2
- db \3
-ENDM
-
-AnimationCoordinates:
-; x coord, y coord, animation flags
- anim_coords 88, 88, (1 << SPRITE_ANIM_FLAG_3)
-
-; animations in the Duel Main Scene
- anim_coords 40, 80, $00
- anim_coords 136, 48, (1 << SPRITE_ANIM_FLAG_6) | (1 << SPRITE_ANIM_FLAG_5) | (1 << SPRITE_ANIM_FLAG_Y_SUBTRACT) | (1 << SPRITE_ANIM_FLAG_X_SUBTRACT)
-
-; animations in the Player's Play Area, for each Play Area Pokemon
- anim_coords 88, 72, $00
- anim_coords 24, 96, $00
- anim_coords 56, 96, $00
- anim_coords 88, 96, $00
- anim_coords 120, 96, $00
- anim_coords 152, 96, $00
-
-; animations in the Opponent's Play Area, for each Play Area Pokemon
- anim_coords 88, 80, $00
- anim_coords 152, 40, $00
- anim_coords 120, 40, $00
- anim_coords 88, 40, $00
- anim_coords 56, 40, $00
- anim_coords 24, 40, $00
-
-; appends to end of wDuelAnimBuffer
-; the current duel animation
-LoadDuelAnimationToBuffer: ; 1ca31 (7:4a31)
- push hl
- push bc
- ld a, [wDuelAnimBufferCurPos]
- ld b, a
- ld hl, wDuelAnimBufferSize
- ld a, [hl]
- ld c, a
- add DUEL_ANIM_STRUCT_SIZE
- and %01111111
- cp b
- jp z, .skip
- ld [hl], a
-
- ld b, $00
- ld hl, wDuelAnimBuffer
- add hl, bc
- ld a, [wTempAnimation]
- ld [hli], a
- ld a, [wDuelAnimationScreen]
- ld [hli], a
- ld a, [wDuelAnimDuelistSide]
- ld [hli], a
- ld a, [wDuelAnimLocationParam]
- ld [hli], a
- ld a, [wDuelAnimDamage]
- ld [hli], a
- ld a, [wDuelAnimDamage + 1]
- ld [hli], a
- ld a, [wd4b3]
- ld [hli], a
- ld a, [wDuelAnimReturnBank]
- ld [hl], a
-
-.skip
- pop bc
- pop hl
- ret
-
-; loads the animations from wDuelAnimBuffer
-; in ascending order, starting at wDuelAnimBufferCurPos
-PlayBufferedDuelAnimations: ; 1ca6e (7:4a6e)
- push hl
- push bc
-.next_duel_anim
- ld a, [wDuelAnimBufferSize]
- ld b, a
- ld a, [wDuelAnimBufferCurPos]
- cp b
- jr z, .skip
-
- ld c, a
- add DUEL_ANIM_STRUCT_SIZE
- and %01111111
- ld [wDuelAnimBufferCurPos], a
-
- ld b, $00
- ld hl, wDuelAnimBuffer
- add hl, bc
- ld a, [hli]
- ld [wTempAnimation], a
- ld a, [hli]
- ld [wDuelAnimationScreen], a
- ld a, [hli]
- ld [wDuelAnimDuelistSide], a
- ld a, [hli]
- ld [wDuelAnimLocationParam], a
- ld a, [hli]
- ld [wDuelAnimDamage], a
- ld a, [hli]
- ld [wDuelAnimDamage + 1], a
- ld a, [hli]
- ld [wd4b3], a
- ld a, [hl]
- ld [wDuelAnimReturnBank], a
-
- call PlayLoadedDuelAnimation
- call CheckAnyAnimationPlaying
- jr nc, .next_duel_anim
-
-.skip
- pop bc
- pop hl
- ret
-
-; gets data from Animations for anim ID in a
-; outputs the pointer to the data in hl
-GetAnimationData: ; 1cab3 (7:4ab3)
- push bc
- ld a, [wTempAnimation]
- ld l, a
- ld h, 0
- add hl, hl ; hl = anim * 2
- ld b, h
- ld c, l
- add hl, hl ; hl = anim * 4
- add hl, bc ; hl = anim * 6
- ld bc, Animations
- add hl, bc
- pop bc
- ret
-
-Func_1cac5: ; 1cac5 (7:4ac5)
- ld a, [wd42a]
- cp $ff
- jr nz, .asm_1cb03
-
- ld a, [wd4c0]
- or a
- jr z, .asm_1cafb
- cp $80
- jr z, .asm_1cb11
- ld hl, wAnimationQueue
- ld c, ANIMATION_QUEUE_LENGTH
-.loop_queue
- push af
- push bc
- ld a, [hl]
- cp $ff
- jr z, .next
- ld [wWhichSprite], a
- farcall GetSpriteAnimCounter
- cp $ff
- jr nz, .next
- farcall DisableCurSpriteAnim
- ld a, $ff
- ld [hl], a
-
-.next
- pop bc
- pop af
- and [hl]
- inc hl
- dec c
- jr nz, .loop_queue
-
-.asm_1cafb
- cp $ff
- jr nz, .skip_play_anims
- call PlayBufferedDuelAnimations
-.skip_play_anims
- ret
-
-.asm_1cb03
- ld hl, wScreenAnimUpdatePtr
- ld a, [hli]
- ld h, [hl]
- ld l, a
- call CallHL2
- ld a, [wd42a]
- jr .asm_1cafb
-
-.asm_1cb11
- ld a, $ff
- ld [wd4c0], a
- jr .asm_1cafb
-
-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, .carry
- ld a, [wDoFrameFunction + 1]
- cp HIGH(Func_3ba2)
- jr nz, .carry
-
- ld a, $ff
- ld [wd4c0], a
- ld a, [wd42a]
- cp $ff
- call nz, DoScreenAnimationUpdate
-
-; clear all queued animations
-; and disable their sprite anims
- ld hl, wAnimationQueue
- ld c, ANIMATION_QUEUE_LENGTH
-.loop_queue
- push bc
- ld a, [hl]
- cp $ff
- jr z, .next_queued
- ld [wWhichSprite], a
- farcall DisableCurSpriteAnim
- ld a, $ff
- ld [hl], a
-.next_queued
- pop bc
- inc hl
- dec c
- jr nz, .loop_queue
-
- xor a
- ld [wDuelAnimBufferCurPos], a
- ld [wDuelAnimBufferSize], a
-.done
- pop de
- pop bc
- pop hl
- ret
-.carry
- scf
- jr .done
-
-Func_1cb5e: ; 1cb5e (7:4b5e)
- cp $96
- jp nc, Func_1ce03
- cp $8c
- jp nz, InitScreenAnimation
- jr .asm_1cb6a ; redundant
-.asm_1cb6a
- ld a, [wDuelAnimDamage + 1]
- cp $03
- jr nz, .asm_1cb76
- ld a, [wDuelAnimDamage]
- cp $e8
-.asm_1cb76
- ret nc
-
- xor a
- ld [wd4b8], a
- ld [wVRAMTileOffset], a
- ld [wd4cb], a
-
- ld a, PALETTE_37
- farcall LoadPaletteData
- call Func_1cba6
-
- ld hl, wd4b3
- bit 0, [hl]
- call nz, Func_1cc3e
-
- ld a, $12
- ld [wd4b8], a
- bit 1, [hl]
- call nz, Func_1cc4e
-
- bit 2, [hl]
- call nz, Func_1cc66
-
- xor a
- ld [wd4b3], a
- ret
-
-Func_1cba6: ; 1cba6 (7:4ba6)
- call Func_1cc03
- xor a
- ld [wd4b7], a
-
- ld hl, wd4b4
- ld de, wAnimationQueue + 1
-.asm_1cbb3
- push hl
- push de
- ld a, [hl]
- or a
- jr z, .asm_1cbbc
- call Func_1cbcc
-
-.asm_1cbbc
- pop de
- pop hl
- inc hl
- inc de
- ld a, [wd4b7]
- inc a
- ld [wd4b7], a
- cp $03
- jr c, .asm_1cbb3
- ret
-
-Func_1cbcc: ; 1cbcc (7:4bcc)
- push af
- ld a, SPRITE_DUEL_4
- farcall CreateSpriteAndAnimBufferEntry
- ld a, [wWhichSprite]
- ld [de], a
- ld a, (1 << SPRITE_ANIM_FLAG_UNSKIPPABLE)
- ld [wAnimFlags], a
- ld c, SPRITE_ANIM_COORD_X
- call GetSpriteAnimBufferProperty
- call GetAnimCoordsAndFlags
-
- ld a, [wd4b7]
- add LOW(Unknown_1cbfd)
- ld e, a
- ld a, HIGH(Unknown_1cbfd)
- adc 0
- ld d, a
- ld a, [de]
- add b
-
- ld [hli], a ; SPRITE_ANIM_COORD_X
- ld [hl], c ; SPRITE_ANIM_COORD_Y
-
- ld a, [wd4b8]
- ld c, a
- pop af
- farcall Func_12ac9
- ret
-
-Unknown_1cbfd: ; 1cbfd (7:4bfd)
- db -$10, -$8, $0, $8, -$8, -$10
-
-Func_1cc03: ; 1cc03 (7:4c03)
- ld a, [wDuelAnimDamage]
- ld l, a
- ld a, [wDuelAnimDamage + 1]
- ld h, a
-
- ld de, wd4b4
- ld bc, -100
- call .Func_1cc2f
- ld bc, -10
- call .Func_1cc2f
-
- ld a, l
- add $4f
- ld [de], a
- ld hl, wd4b4
- ld c, 2
-.asm_1cc23
- ld a, [hl]
- cp $4f
- jr nz, .asm_1cc2e
- ld [hl], $00
- inc hl
- dec c
- jr nz, .asm_1cc23
-.asm_1cc2e
- ret
-
-.Func_1cc2f
- ld a, $4e
-.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
-
-Func_1cc3e: ; 1cc3e (7:4c3e)
- push hl
- ld a, $03
- ld [wd4b7], a
- ld de, wAnimationQueue + 4
- ld a, SPRITE_ANIM_91
- call Func_1cbcc
- pop hl
- ret
-
-Func_1cc4e: ; 1cc4e (7:4c4e)
- push hl
- ld a, $04
- ld [wd4b7], a
- ld de, wAnimationQueue + 5
- ld a, SPRITE_ANIM_90
- call Func_1cbcc
- ld a, [wd4b8]
- add $12
- ld [wd4b8], a
- pop hl
- ret
-
-Func_1cc66: ; 1cc66 (7:4c66)
- push hl
- ld a, $05
- ld [wd4b7], a
- ld de, wAnimationQueue + 6
- ld a, SPRITE_ANIM_89
- call Func_1cbcc
- pop hl
- ret
-
-; initializes a screen animation from wTempAnimation
-; loads a function pointer for updating a frame
-; and initializes the duration of the animation.
-InitScreenAnimation: ; 1cc76 (7:4c76)
- ld a, [wAnimationsDisabled]
- or a
- jr nz, .skip
- ld a, [wTempAnimation]
- ld [wd42a], a
- sub DUEL_SCREEN_ANIMS
- add a
- add a
- ld c, a
- ld b, $00
- ld hl, Data_1cc9f
- add hl, bc
- ld a, [hli]
- ld [wScreenAnimUpdatePtr], a
- ld c, a
- ld a, [hli]
- ld [wScreenAnimUpdatePtr + 1], a
- ld b, a
- ld a, [hl]
- ld [wScreenAnimDuration], a
- call CallBC
-.skip
- ret
-
-; for the following animations, these functions
-; are run with the corresponding duration.
-; this duration decides different effects,
-; depending on which function runs
-; and is decreased by one each time.
-; when it is down to 0, the animation is done.
-
-screen_effect: MACRO
- dw \1 ; function pointer
- db \2 ; duration
- db $00 ; padding
-ENDM
-
-Data_1cc9f: ; 1cc9f (7:4c9f)
-; function pointer, duration
- screen_effect ShakeScreenX_Small, 24 ; DUEL_ANIM_SMALL_SHAKE_X
- screen_effect ShakeScreenX_Big, 32 ; DUEL_ANIM_BIG_SHAKE_X
- screen_effect ShakeScreenY_Small, 24 ; DUEL_ANIM_SMALL_SHAKE_Y
- screen_effect ShakeScreenY_Big, 32 ; DUEL_ANIM_BIG_SHAKE_Y
- screen_effect WhiteFlashScreen, 8 ; DUEL_ANIM_FLASH
- screen_effect DistortScreen, 63 ; DUEL_ANIM_DISTORT
-
-; checks if screen animation duration is over
-; and if so, loads the default update function
-LoadDefaultScreenAnimationUpdateWhenFinished: ; 1ccb7 (7:4cb7)
- ld a, [wScreenAnimDuration]
- or a
- ret nz
- ; fallthrough
-
-; function called for the screen animation update when it is over
-DefaultScreenAnimationUpdate: ; 1ccbc (7:4cbc)
- ld a, $ff
- ld [wd42a], a
- call DisableInt_LYCoincidence
- xor a
- ldh [hSCX], a
- ldh [rSCX], a
- ldh [hSCY], a
- ld hl, wScreenAnimUpdatePtr
- ld [hl], LOW(DefaultScreenAnimationUpdate)
- inc hl
- ld [hl], HIGH(DefaultScreenAnimationUpdate)
- ret
-
-; runs the screen update function set in wScreenAnimUpdatePtr
-DoScreenAnimationUpdate: ; 1ccd4 (7:4cd4)
- ld a, 1
- ld [wScreenAnimDuration], a
- ld hl, wScreenAnimUpdatePtr
- ld a, [hli]
- ld h, [hl]
- ld l, a
- call CallHL2
- jr DefaultScreenAnimationUpdate
-
-ShakeScreenX_Small: ; 1cce4 (7:4ce4)
- ld hl, SmallShakeOffsets
- jr ShakeScreenX
-
-ShakeScreenX_Big: ; 1cce9 (7:4ce9)
- ld hl, BigShakeOffsets
- jr ShakeScreenX
-
-ShakeScreenX: ; 1ccee (7:4cee)
- ld a, l
- ld [wd4bc], a
- ld a, h
- ld [wd4bc + 1], a
-
- ld hl, wScreenAnimUpdatePtr
- ld [hl], LOW(.update)
- inc hl
- ld [hl], HIGH(.update)
- ret
-
-.update
- call DecrementScreenAnimDuration
- call UpdateShakeOffset
- jp nc, LoadDefaultScreenAnimationUpdateWhenFinished
- ldh a, [hSCX]
- add [hl]
- ldh [hSCX], a
- jp LoadDefaultScreenAnimationUpdateWhenFinished
-
-ShakeScreenY_Small: ; 1cd10 (7:4d10)
- ld hl, SmallShakeOffsets
- jr ShakeScreenY
-
-ShakeScreenY_Big: ; 1cd15 (7:4d15)
- ld hl, BigShakeOffsets
- jr ShakeScreenY
-
-ShakeScreenY: ; 1cd1a (7:4d1a)
- ld a, l
- ld [wd4bc], a
- ld a, h
- ld [wd4bc + 1], a
- ld hl, wScreenAnimUpdatePtr
- ld [hl], LOW(.update)
- inc hl
- ld [hl], HIGH(.update)
- ret
-
-.update
- call DecrementScreenAnimDuration
- call UpdateShakeOffset
- jp nc, LoadDefaultScreenAnimationUpdateWhenFinished
- ldh a, [hSCY]
- add [hl]
- ldh [hSCY], a
- jp LoadDefaultScreenAnimationUpdateWhenFinished
-
-; get the displacement of the current frame
-; depending on the value of wScreenAnimDuration
-; returns carry if displacement was updated
-UpdateShakeOffset: ; 1cd3c (7:4d3c)
- ld hl, wd4bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld a, [wScreenAnimDuration]
- cp [hl]
- ret nc
- inc hl
- push hl
- inc hl
- ld a, l
- ld [wd4bc], a
- ld a, h
- ld [wd4bc + 1], a
- pop hl
- scf
- ret
-
-SmallShakeOffsets: ; 1cd55 (7:4d55)
- db 21, 2
- db 17, -2
- db 13, 2
- db 9, -2
- db 5, 1
- db 1, -1
-
-BigShakeOffsets: ; 1cd61 (7:4d61)
- db 29, 4
- db 25, -4
- db 21, 4
- db 17, -4
- db 13, 3
- db 9, -3
- db 5, 2
- db 1, -2
-
-DecrementScreenAnimDuration: ; 1cd71 (7:4d71)
- ld hl, wScreenAnimDuration
- dec [hl]
- ret
-
-WhiteFlashScreen: ; 1cd76 (7:4d76)
- ld hl, wScreenAnimUpdatePtr
- ld [hl], LOW(.update)
- inc hl
- ld [hl], HIGH(.update)
- ld a, [wBGP]
- ld [wd4bc], a
- ; backup the current background pals
- ld hl, wBackgroundPalettesCGB
- ld de, wTempBackgroundPalettesCGB
- ld bc, 8 palettes
- call CopyDataHLtoDE_SaveRegisters
- ld de, PALRGB_WHITE
- ld hl, wBackgroundPalettesCGB
- ld bc, (8 palettes) / 2
- call FillMemoryWithDE
- xor a
- call SetBGP
- call FlushAllPalettes
-
-.update
- call DecrementScreenAnimDuration
- ld a, [wScreenAnimDuration]
- or a
- ret nz
- ; retrieve the previous background pals
- ld hl, wTempBackgroundPalettesCGB
- ld de, wBackgroundPalettesCGB
- ld bc, 8 palettes
- call CopyDataHLtoDE_SaveRegisters
- ld a, [wd4bc]
- call SetBGP
- call FlushAllPalettes
- jp DefaultScreenAnimationUpdate
-
-DistortScreen: ; 1cdc3 (7:4dc3)
- ld hl, wScreenAnimUpdatePtr
- ld [hl], LOW(.update)
- inc hl
- ld [hl], HIGH(.update)
- xor a
- ld [wApplyBGScroll], a
- ld hl, wLCDCFunctionTrampoline + 1
- ld [hl], LOW(ApplyBackgroundScroll)
- inc hl
- ld [hl], HIGH(ApplyBackgroundScroll)
- ld a, 1
- ld [wBGScrollMod], a
- call EnableInt_LYCoincidence
-
-.update
- ld a, [wScreenAnimDuration]
- srl a
- srl a
- srl a
- and %00000111
- ld c, a
- ld b, $00
- ld hl, .BGScrollModData
- add hl, bc
- ld a, [hl]
- ld [wBGScrollMod], a
- call DecrementScreenAnimDuration
- jp LoadDefaultScreenAnimationUpdateWhenFinished
-
-; each value is applied for 8 "ticks" of wScreenAnimDuration
-; starting from the last and running backwards
-.BGScrollModData
- db 4, 3, 2, 1, 1, 1, 1, 2
-
-Func_1ce03: ; 1ce03 (7:4e03)
- cp DUEL_ANIM_158
- jr z, .asm_1ce17
- sub $96
- add a
- ld c, a
- ld b, $00
- ld hl, .pointer_table
- add hl, bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
- jp Func_3bb5
-
-.asm_1ce17
- ld a, [wDuelAnimDamage]
- ld l, a
- ld a, [wDuelAnimDamage + 1]
- ld h, a
- jp Func_3bb5
-
-.pointer_table
- dw Func_190f4 ; DUEL_ANIM_150
- dw PrintDamageText ; DUEL_ANIM_PRINT_DAMAGE
- dw UpdateMainSceneHUD ; DUEL_ANIM_UPDATE_HUD
- dw Func_191a3 ; DUEL_ANIM_153
- dw Func_191a3 ; DUEL_ANIM_154
- dw Func_191a3 ; DUEL_ANIM_155
- dw Func_191a3 ; DUEL_ANIM_156
- dw Func_191a3 ; DUEL_ANIM_157
-
-INCLUDE "data/duel/animations/duel_animations.asm"
-
-; plays the Opening sequence, and handles player selection
-; in the Title Screen and Start Menu
-HandleTitleScreen: ; 1d078 (7:5078)
-; if last selected item in Start Menu is 0 (Card Pop!)
-; then skip straight to the Start Menu
-; this makes it so that returning from Card Pop!
-; doesn't play the Opening sequence
- ld a, [wLastSelectedStartMenuItem]
- or a
- jr z, .start_menu
-
-.play_opening
- ld a, MUSIC_STOP
- call PlaySong
- call Func_3ca0
- call PlayOpeningSequence
- call LoadTitleScreenSprites
-
- xor a
- ld [wd635], a
- ld a, $3c
- ld [wTitleScreenIgnoreInputCounter], a
-.loop
- call DoFrameIfLCDEnabled
- call UpdateRNGSources
- call AnimateRandomTitleScreenOrb
- ld hl, wd635
- inc [hl]
- call AssertSongFinished
- or a
- jr nz, .song_playing
- ; reset back to the opening sequence
- farcall Func_10ab4
- jr .play_opening
-
-.song_playing
- ; should we ignore user input?
- ld hl, wTitleScreenIgnoreInputCounter
- ld a, [hl]
- or a
- jr z, .check_keys
- ; ignore input, decrement the counter
- dec [hl]
- jr .loop
-
-.check_keys
- ldh a, [hKeysPressed]
- and A_BUTTON | START
- jr z, .loop
- ld a, SFX_02
- call PlaySFX
- farcall Func_10ab4
-
-.start_menu
- call CheckIfHasSaveData
- call HandleStartMenu
-
-; new game
- ld a, [wStartMenuChoice]
- cp START_MENU_NEW_GAME
- jr nz, .continue_from_diary
- call DeleteSaveDataForNewGame
- jr c, HandleTitleScreen
- jr .card_pop
-.continue_from_diary
- ld a, [wStartMenuChoice]
- cp START_MENU_CONTINUE_FROM_DIARY
- jr nz, .card_pop
- call AskToContinueFromDiaryWithDuelData
- jr c, HandleTitleScreen
-.card_pop
- ld a, [wStartMenuChoice]
- cp START_MENU_CARD_POP
- jr nz, .continue_duel
- call ShowCardPopCGBDisclaimer
- jr c, HandleTitleScreen
-.continue_duel
- call ResetDoFrameFunction
- call Func_3ca0
- ret
-
-; updates wHasSaveData and wHasDuelSaveData
-; depending on whether the save data is valid or not
-CheckIfHasSaveData: ; 1d0fa (7:50fa)
- farcall ValidateBackupGeneralSaveData
- ld a, TRUE
- jr c, .no_error
- ld a, FALSE
-.no_error
- ld [wHasSaveData], a
- cp $00 ; or a
- jr z, .write_has_duel_data
- bank1call ValidateSavedNonLinkDuelData
- ld a, TRUE
- jr nc, .write_has_duel_data
- ld a, FALSE
-.write_has_duel_data
- ld [wHasDuelSaveData], a
- farcall ValidateBackupGeneralSaveData
- ret
-
-; handles printing the Start Menu
-; and getting player input and choice
-HandleStartMenu: ; 1d11c (7:511c)
- ld a, MUSIC_PC_MAIN_MENU
- call PlaySong
- call DisableLCD
- farcall Func_10000
- lb de, $30, $8f
- call SetupText
- call Func_3ca0
- xor a
- ld [wLineSeparation], a
- call .DrawPlayerPortrait
- call .SetStartMenuParams
-
- ld a, $ff
- ld [wTitleScreenIgnoreInputCounter], a
- ld a, [wLastSelectedStartMenuItem]
- cp $4
- jr c, .init_menu
- ld a, [wHasSaveData]
- or a
- jr z, .init_menu
- ld a, 1 ; start at second menu option
-.init_menu
- ld hl, wStartMenuParams
- farcall InitAndPrintPauseMenu
- farcall FlashWhiteScreen
-
-.wait_input
- call DoFrameIfLCDEnabled
- call UpdateRNGSources
- call HandleMenuInput
- push af
- call PrintStartMenuDescriptionText
- pop af
- jr nc, .wait_input
- ldh a, [hCurMenuItem]
- cp e
- jr nz, .wait_input
-
- ld [wLastSelectedStartMenuItem], a
- ld a, [wHasSaveData]
- or a
- jr nz, .no_adjustment
- ; New Game is 3rd option
- ; but when there's no save data,
- ; it's the 1st in menu list, so adjust it
- inc e
- inc e
-.no_adjustment
- ld a, e
- ld [wStartMenuChoice], a
- ret
-
-.SetStartMenuParams
- ld hl, .StartMenuParams
- ld de, wStartMenuParams
- ld bc, .StartMenuParamsEnd - .StartMenuParams
- call CopyDataHLtoDE
-
- ld e, 0
- ld a, [wHasSaveData]
- or a
- jr z, .get_text_id ; New Game
- inc e
- ld a, 2
- call .AddItems
- ld a, [wHasDuelSaveData]
- or a
- jr z, .get_text_id ; Continue From Diary
- inc e
- ld a, 1
- call .AddItems
- ; Continue Duel
-
-.get_text_id
- sla e
- ld d, $00
- ld hl, .StartMenuTextIDs
- add hl, de
- ; set text ID as Start Menu param
- ld a, [hli]
- ld [wStartMenuParams + 6], a
- ld a, [hl]
- ld [wStartMenuParams + 7], a
- ret
-
-; adds c items to start menu list
-; this means adding 2 units per item to the text box height
-; and adding to the number of items
-.AddItems
- push bc
- ld c, a
- ; number of items in menu
- ld a, [wStartMenuParams + 12]
- add c
- ld [wStartMenuParams + 12], a
- ; height of text box
- sla c
- ld a, [wStartMenuParams + 3]
- add c
- ld [wStartMenuParams + 3], a
- pop bc
- ret
-
-.StartMenuParams
- db 0, 0 ; start menu coords
- db 14, 4 ; start menu text box dimensions
-
- db 2, 2 ; text alignment for InitTextPrinting
- tx NewGameText
- db $ff
-
- db 1, 2 ; cursor x, cursor y
- db 2 ; y displacement between items
- db 1 ; number of items
- db SYM_CURSOR_R ; cursor tile number
- db SYM_SPACE ; tile behind cursor
- dw NULL ; function pointer if non-0
-.StartMenuParamsEnd
-
-.StartMenuTextIDs
- tx NewGameText
- tx CardPopContinueDiaryNewGameText
- tx CardPopContinueDiaryNewGameContinueDuelText
-
-.DrawPlayerPortrait
- lb bc, 14, 1
- farcall $4, DrawPlayerPortrait
- ret
-
-; prints the description for the current selected item
-; in the Start Menu in the text box
-PrintStartMenuDescriptionText: ; 1d1e9 (7:51e9)
- push hl
- push bc
- push de
- ; don't print if it's already showing
- ld a, [wCurMenuItem]
- ld e, a
- ld a, [wCurHighlightedStartMenuItem]
- cp e
- jr z, .skip
- ld a, [wHasSaveData]
- or a
- jr nz, .has_data
- ; New Game option is 3rd element
- ; in function table, so add 2
- inc e
- inc e
-.has_data
-
- ld a, e
- push af
- lb de, 0, 10
- lb bc, 20, 8
- call DrawRegularTextBox
- pop af
- ld hl, .StartMenuDescriptionFunctionTable
- call JumpToFunctionInTable
-.skip
- ld a, [wCurMenuItem]
- ld [wCurHighlightedStartMenuItem], a
- pop de
- pop bc
- pop hl
- ret
-
-.StartMenuDescriptionFunctionTable
- dw .CardPop
- dw .ContinueFromDiary
- dw .NewGame
- dw .ContinueDuel
-
-.CardPop
- lb de, 1, 12
- call InitTextPrinting
- ldtx hl, WhenYouCardPopWithFriendText
- call PrintTextNoDelay
- ret
-
-.ContinueDuel
- lb de, 1, 12
- call InitTextPrinting
- ldtx hl, TheGameWillContinueFromThePointInTheDuelText
- call PrintTextNoDelay
- ret
-
-.NewGame
- lb de, 1, 12
- call InitTextPrinting
- ldtx hl, StartANewGameText
- call PrintTextNoDelay
- ret
-
-.ContinueFromDiary
- ; get OW map name
- ld a, [wCurOverworldMap]
- add a
- ld c, a
- ld b, $00
- ld hl, OverworldMapNames
- add hl, bc
- ld a, [hli]
- ld [wTxRam2 + 0], a
- ld a, [hl]
- ld [wTxRam2 + 1], a
-
- ; get medal count
- ld a, [wMedalCount]
- ld [wTxRam3 + 0], a
- xor a
- ld [wTxRam3 + 1], a
-
- ; print text
- lb de, 1, 10
- call InitTextPrinting
- ldtx hl, ContinueFromDiarySummaryText
- call PrintTextNoDelay
-
- ld a, [wTotalNumCardsCollected]
- ld d, a
- ld a, [wTotalNumCardsToCollect]
- ld e, a
- ld bc, $90e
- farcall Func_1024f
- ld bc, $a10
- farcall Func_101df
- ret
-
-; asks the player whether it's okay to delete
-; the save data in order to create a new one
-; if player answers "yes", delete it
-DeleteSaveDataForNewGame: ; 1d289 (7:5289)
-; exit if there no save data
- ld a, [wHasSaveData]
- or a
- ret z
-
- call DisableLCD
- farcall Func_10000
- call Func_3ca0
- farcall FlashWhiteScreen
- call DoFrameIfLCDEnabled
- ldtx hl, SavedDataAlreadyExistsText
- call PrintScrollableText_NoTextBoxLabel
- ldtx hl, OKToDeleteTheDataText
- call YesOrNoMenuWithText
- ret c ; quit if chose "no"
- farcall InvalidateSaveData
- ldtx hl, AllDataWasDeletedText
- call PrintScrollableText_NoTextBoxLabel
- or a
- ret
-
-; asks the player if the game should resume
-; from diary even though there is Duel save data
-; returns carry if "no" was selected
-AskToContinueFromDiaryWithDuelData: ; 1d2b8 (7:52b8)
-; return if there's no duel save data
- ld a, [wHasDuelSaveData]
- or a
- ret z
-
- call DisableLCD
- farcall Func_10000
- call Func_3ca0
- farcall FlashWhiteScreen
- call DoFrameIfLCDEnabled
- ldtx hl, DataExistsWhenPowerWasTurnedOFFDuringDuelText
- call PrintScrollableText_NoTextBoxLabel
- ldtx hl, ContinueFromDiaryText
- call YesOrNoMenuWithText
- ret c
- or a
- ret
-
-; shows disclaimer for Card Pop!
-; in case player is not playing in CGB
-; return carry if disclaimer was shown
-ShowCardPopCGBDisclaimer: ; 1d2dd (7:52dd)
-; return if playing in CGB
- ld a, [wConsole]
- cp CONSOLE_CGB
- ret z
-
- lb de, 0, 10
- lb bc, 20, 8
- call DrawRegularTextBox
- lb de, 1,12
- call InitTextPrinting
- ldtx hl, YouCanAccessCardPopOnlyWithGameBoyColorsText
- call PrintTextNoDelay
- lb bc, SYM_CURSOR_D, SYM_BOX_BOTTOM
- lb de, 18, 17
- call SetCursorParametersForTextBox
- call WaitForButtonAorB
- scf
- ret
-
-DrawPlayerPortraitAndPrintNewGameText: ; 1d306 (7:5306)
- call DisableLCD
- farcall Func_10a9b
- farcall Func_10000
- call Func_3ca0
- ld hl, HandleAllSpriteAnimations
- call SetDoFrameFunction
- lb bc, 7, 3
- farcall $4, DrawPlayerPortrait
- farcall Func_10af9
- call DoFrameIfLCDEnabled
- ldtx hl, IsCrazyAboutPokemonAndPokemonCardCollectingText
- call PrintScrollableText_NoTextBoxLabel
- call ResetDoFrameFunction
- call Func_3ca0
- ret
-
-PlayOpeningSequence: ; 1d335 (7:5335)
- call DisableLCD
- farcall Func_10a9b
- farcall Func_10000
- call Func_3ca0
- ld hl, HandleAllSpriteAnimations
- call SetDoFrameFunction
- call LoadTitleScreenSprites
-
- ld a, LOW(OpeningSequence)
- ld [wSequenceCmdPtr + 0], a
- ld a, HIGH(OpeningSequence)
- ld [wSequenceCmdPtr + 1], a
-
- xor a
- ld [wd317], a
- ld [wOpeningSequencePalsNeedUpdate], a
- ld [wSequenceDelay], a
- farcall FlashWhiteScreen
-
-.loop_cmds
- call DoFrameIfLCDEnabled
- call UpdateRNGSources
- ldh a, [hKeysPressed]
- and A_BUTTON | START
- jr nz, .jump_to_title_screen
- ld a, [wOpeningSequencePalsNeedUpdate]
- or a
- jr z, .no_pal_update
- farcall Func_10d74
-.no_pal_update
- call ExecuteOpeningSequenceCmd
- ld a, [wSequenceDelay]
- cp $ff
- jr nz, .loop_cmds
- jr .asm_1d39f
-
-.jump_to_title_screen
- call AssertSongFinished
- or a
- jr nz, .asm_1d39f
- call DisableLCD
- ld a, MUSIC_TITLESCREEN
- call PlaySong
- lb bc, 0, 0
- ld a, SCENE_TITLE_SCREEN
- call LoadScene
- call OpeningSequenceEmptyFunc
-.asm_1d39f
- call Func_3ca0
- call .ShowPressStart
- call EnableLCD
- ret
-
-.ShowPressStart
- ld a, SPRITE_PRESS_START
- farcall CreateSpriteAndAnimBufferEntry
- ld c, SPRITE_ANIM_COORD_X
- call GetSpriteAnimBufferProperty
- ld a, 48
- ld [hli], a ; x
- ld a, 112
- ld [hl], a ; y
- ld c, SPRITE_ANIM_190
- ld a, [wConsole]
- cp CONSOLE_CGB
- jr nz, .asm_1d3c5
- ld c, SPRITE_ANIM_191
-.asm_1d3c5
- ld a, c
- ld bc, 60
- farcall Func_12ac9
- ret
-
-LoadTitleScreenSprites: ; 1d3ce (7:53ce)
- xor a
- ld [wd4ca], a
- ld [wd4cb], a
- ld a, PALETTE_30
- farcall LoadPaletteData
-
- ld bc, 0
- ld de, wTitleScreenSprites
-.loop_load_sprites
- push bc
- push de
- ld hl, .TitleScreenSpriteList
- add hl, bc
- ld a, [hl]
- farcall CreateSpriteAndAnimBufferEntry
- ld a, [wWhichSprite]
- ld [de], a
- call GetFirstSpriteAnimBufferProperty
- inc hl
- ld a, [hl] ; SPRITE_ANIM_ATTRIBUTES
- or c
- ld [hl], a
- pop de
- pop bc
- inc de
- inc c
- ld a, c
- cp $7
- jr c, .loop_load_sprites
- ret
-
-.TitleScreenSpriteList
- db SPRITE_GRASS
- db SPRITE_FIRE
- db SPRITE_WATER
- db SPRITE_COLORLESS
- db SPRITE_LIGHTNING
- db SPRITE_PSYCHIC
- db SPRITE_FIGHTING
-
-; TODO place in main.asm when possible
-INCLUDE "engine/sequences/opening_sequence_commands.asm"
-INCLUDE "data/sequences/opening_sequence.asm"
-
-; once every 63 frames randomly choose an orb sprite
-; to animate, i.e. circle around the screen
-AnimateRandomTitleScreenOrb: ; 1d614 (7:5614)
- ld a, [wConsole]
- cp CONSOLE_CGB
- call z, .UpdateSpriteAttributes
- ld a, [wd635]
- and 63
- ret nz ; don't pick an orb now
-
-.pick_orb
- ld a, $7
- call Random
- ld c, a
- ld b, $00
- ld hl, wTitleScreenSprites
- add hl, bc
- ld a, [hl]
- ld [wWhichSprite], a
- farcall GetSpriteAnimCounter
- cp $ff
- jr nz, .pick_orb
-
- ld c, SPRITE_ANIM_ATTRIBUTES
- call GetSpriteAnimBufferProperty
- ld a, [wConsole]
- cp CONSOLE_CGB
- jr nz, .set_coords
- set SPRITE_ANIM_FLAG_UNSKIPPABLE, [hl]
-
-.set_coords
- inc hl
- ld a, 248
- ld [hli], a ; SPRITE_ANIM_COORD_X
- ld a, 14
- ld [hl], a ; SPRITE_ANIM_COORD_Y
- ld a, [wConsole]
- cp CONSOLE_CGB
- ld a, SPRITE_ANIM_215
- jr nz, .start_anim
- ld a, SPRITE_ANIM_216
-.start_anim
- farcall StartSpriteAnimation
- ret
-
-.UpdateSpriteAttributes
- ld c, $7
- ld de, wTitleScreenSprites
-.loop_orbs
- push bc
- ld a, [de]
- ld [wWhichSprite], a
- ld c, SPRITE_ANIM_COORD_X
- call GetSpriteAnimBufferProperty
- ld a, [hld]
- cp 152
- jr nz, .skip
- res SPRITE_ANIM_FLAG_UNSKIPPABLE, [hl]
-.skip
- pop bc
- inc de
- dec c
- jr nz, .loop_orbs
- ret
-
-; unreferenced
-; shows Copyright information for 300 frames
-; or until Start button is pressed
-Func_1d67b: ; 1d67b (7:567b)
- call DisableLCD
- farcall Func_10a9b
- farcall Func_10000
- ld bc, $0
- ld a, SCENE_COPYRIGHT
- call LoadScene
- farcall Func_10af9
- ld bc, 300
-.loop_frame
- push bc
- call DoFrameIfLCDEnabled
- call UpdateRNGSources
- pop bc
- ldh a, [hKeysPressed]
- and START
- jr nz, .exit
- dec bc
- ld a, b
- or c
- jr nz, .loop_frame
-.exit
- farcall Func_10ab4
- ret
-
-Credits_1d6ad: ; 1d6ad (7:56ad)
- ld a, MUSIC_STOP
- call PlaySong
- call Func_1d705
- call AddAllMastersToMastersBeatenList
- xor a
- ld [wOWMapEvents + 1], a
- ld a, MUSIC_CREDITS
- call PlaySong
- farcall FlashWhiteScreen
- call SetCreditsSequenceCmdPtr
-.asm_1d6c8
- call DoFrameIfLCDEnabled
- call Func_1d765
- call ExecuteCreditsSequenceCmd
- ld a, [wSequenceDelay]
- cp $ff
- jr nz, .asm_1d6c8
- call WaitForSongToFinish
- ld a, $8
- farcall Func_12863
- ld a, MUSIC_STOP
- call PlaySong
- farcall Func_10ab4
- call Func_3ca4
- call Set_WD_off
- call Func_1d758
- call EnableLCD
- call DoFrameIfLCDEnabled
- call DisableLCD
- ld hl, wLCDC
- set 1, [hl]
- call ResetDoFrameFunction
- ret
-
-Func_1d705: ; 1d705 (7:5705)
- call DisableLCD
- farcall Func_10a9b
- call Func_3ca0
- farcall Func_10000
- call Func_1d7ee
- ld hl, Func_3e31
- call SetDoFrameFunction
- call .Func_1d720 ; can be fallthrough
- ret
-
-.Func_1d720
- ld a, $91
- ld [wd647], a
- ld [wd649], a
- ld a, $01
- ld [wd648], a
- ld [wd64a], a
- call Func_1d765
- call Set_WD_on
- call .Func_1d73a ; can bee fallthrough
- ret
-
-.Func_1d73a
- push hl
- di
- xor a
- ld [wd657], a
- ld hl, wLCDCFunctionTrampoline + 1
- ld [hl], LOW(Func_3e44)
- inc hl
- ld [hl], HIGH(Func_3e44)
- ei
-
- ld hl, rSTAT
- set STAT_LYC, [hl]
- xor a
- ldh [rLYC], a
- ld hl, rIE
- set INT_LCD_STAT, [hl]
- pop hl
- ret
-
-Func_1d758: ; 1d758 (7:5758)
- push hl
- ld hl, rSTAT
- res STAT_LYC, [hl]
- ld hl, rIE
- res INT_LCD_STAT, [hl]
- pop hl
- ret
-
-Func_1d765: ; 1d765 (7:5765)
- push hl
- push bc
- push de
- xor a
- ldh [hWY], a
-
- ld hl, wd659
- ld de, wd65f
- ld a, [wd648]
- or a
- jr nz, .asm_1d785
- ld a, $a7
- ldh [hWX], a
- ld [hli], a
- push hl
- ld hl, wLCDC
- set 1, [hl]
- pop hl
- jr .asm_1d7e2
-
-.asm_1d785
- ld a, [wd647]
- or a
- jr z, .asm_1d79e
- dec a
- ld [de], a
- inc de
- ld a, $a7
- ldh [hWX], a
- ld [hli], a
- push hl
- ld hl, wLCDC
- set 1, [hl]
- pop hl
- ld a, $07
- jr .asm_1d7a9
-
-.asm_1d79e
- ld a, $07
- ldh [hWX], a
- push hl
- ld hl, wLCDC
- res 1, [hl]
- pop hl
-.asm_1d7a9
- ld [hli], a
- ld a, [wd647]
- dec a
- ld c, a
- ld a, [wd648]
- add c
- ld c, a
- ld a, [wd649]
- dec a
- cp c
- jr c, .asm_1d7d4
- jr z, .asm_1d7d4
- ld a, c
- ld [de], a
- inc de
- push af
- ld a, $a7
- ld [hli], a
- pop bc
- ld a, [wd64a]
- or a
- jr z, .asm_1d7e2
- ld a, [wd649]
- dec a
- ld [de], a
- inc de
- ld a, $07
- ld [hli], a
-
-.asm_1d7d4
- ld a, [wd649]
- dec a
- ld c, a
- ld a, [wd64a]
- add c
- ld [de], a
- inc de
- ld a, $a7
- ld [hli], a
-.asm_1d7e2
- ld a, $ff
- ld [de], a
- ld a, $01
- ld [wd665], a
- pop de
- pop bc
- pop hl
- ret
-
-Func_1d7ee: ; 1d7ee (7:57ee)
- xor a
- lb de, 0, 32
- lb bc, 20, 18
- lb hl, 0, 0
- call FillRectangle
- ret
diff --git a/src/engine/bank20.asm b/src/engine/bank20.asm
index a8c03cc..bc71842 100644
--- a/src/engine/bank20.asm
+++ b/src/engine/bank20.asm
@@ -2,7 +2,7 @@
; according to its Map Header configurations
; if it's the Overworld Map, also prints the map name
; and sets up the volcano animation
-LoadMapGfxAndPermissions: ; 80000 (20:4000)
+LoadMapGfxAndPermissions:
call ClearSRAMBGMaps
xor a
ld [wTextBoxFrameType], a
@@ -20,7 +20,7 @@ LoadMapGfxAndPermissions: ; 80000 (20:4000)
; reloads the map tiles and permissions
; after a textbox has been closed
-ReloadMapAfterTextClose: ; 80028 (20:4028)
+ReloadMapAfterTextClose:
call ClearSRAMBGMaps
lb bc, 0, 0
call LoadTilemap_ToSRAM
@@ -29,7 +29,7 @@ ReloadMapAfterTextClose: ; 80028 (20:4028)
farcall Func_c3ee
ret
-LoadMapTilesAndPals: ; 8003d (20:403d)
+LoadMapTilesAndPals:
farcall LoadMapHeader
farcall SetSGB2AndSGB3MapPalette
lb bc, 0, 0
@@ -58,14 +58,14 @@ LoadMapTilesAndPals: ; 8003d (20:403d)
; loads the BG map corresponding to wCurTilemap to SRAM
; bc = starting coordinates
-LoadTilemap_ToSRAM: ; 80077 (20:4077)
+LoadTilemap_ToSRAM:
ld a, TRUE
ld [wWriteBGMapToSRAM], a
jr LoadTilemap
; loads the BG map corresponding to wCurTilemap to VRAM
; bc = starting coordinates
-LoadTilemap_ToVRAM: ; 8007e (20:407e)
+LoadTilemap_ToVRAM:
xor a ; FALSE
ld [wWriteBGMapToSRAM], a
; fallthrough
@@ -74,7 +74,7 @@ LoadTilemap_ToVRAM: ; 8007e (20:407e)
; either loads them in VRAM or SRAM,
; depending on wWriteBGMapToSRAM
; bc = starting coordinates
-LoadTilemap: ; 80082 (20:4082)
+LoadTilemap:
push hl
push bc
push de
@@ -213,7 +213,7 @@ LoadTilemap: ; 80082 (20:4082)
pop hl
ret
-Func_80148: ; 80148 (20:4148)
+Func_80148:
ld a, [wd291]
or a
ret z
@@ -255,7 +255,7 @@ Func_80148: ; 80148 (20:4148)
; if SRAM is the target address to copy,
; copies data to sGfxBuffer0 or sGfxBuffer1
; for VRAM0 or VRAM1 respectively
-CopyBGDataToVRAMOrSRAM: ; 8016e (20:416e)
+CopyBGDataToVRAMOrSRAM:
ld a, [wWriteBGMapToSRAM]
or a
jp z, SafeCopyDataHLtoDE
@@ -296,7 +296,7 @@ CopyBGDataToVRAMOrSRAM: ; 8016e (20:416e)
; safely copies $20 bytes at a time
; sGfxBuffer0 -> v0BGMap0
; sGfxBuffer1 -> v0BGMap1 (if in CGB)
-SafelyCopyBGMapFromSRAMToVRAM: ; 801a1 (20:41a1)
+SafelyCopyBGMapFromSRAMToVRAM:
push hl
push bc
push de
@@ -348,7 +348,7 @@ SafelyCopyBGMapFromSRAMToVRAM: ; 801a1 (20:41a1)
ret
; clears sGfxBuffer0 and sGfxBuffer1
-ClearSRAMBGMaps: ; 801f1 (20:41f1)
+ClearSRAMBGMaps:
push hl
push bc
ldh a, [hBankSRAM]
@@ -368,10 +368,10 @@ ClearSRAMBGMaps: ; 801f1 (20:41f1)
; l - map data offset (0,2,4,6,8 for banks 0,1,2,3,4)
; a - map index (inside of the given bank)
-GetMapDataPointer: ; 8020f (20:420f)
+GetMapDataPointer:
push bc
push af
- ld bc, MapDataPointers
+ ld bc, GfxTablePointers
ld h, $0
add hl, bc
ld c, [hl]
@@ -389,18 +389,17 @@ GetMapDataPointer: ; 8020f (20:420f)
ret
; Loads a pointer from [hl] to wTempPointer. Adds the graphics bank offset ($20)
-LoadGraphicsPointerFromHL: ; 80229 (20:4229)
+LoadGraphicsPointerFromHL:
ld a, [hli]
ld [wTempPointer], a
ld a, [hli]
ld [wTempPointer + 1], a
ld a, [hli]
- add BANK(MapDataPointers)
+ add BANK(GfxTablePointers)
ld [wTempPointerBank], a
ret
-; unreferenced?
-Func_80238: ; 80238 (20:4238)
+Func_80238: ; unreferenced
push hl
ld l, $2 ; Tilesets
ld a, [wCurTileset]
@@ -423,7 +422,7 @@ Func_80238: ; 80238 (20:4238)
; a = sprite index within the data map
; output:
; a = number of tiles in sprite
-Func_8025b: ; 8025b (20:425b)
+Func_8025b:
push hl
ld l, $4 ; Sprites
call GetMapDataPointer
@@ -440,17 +439,17 @@ Func_8025b: ; 8025b (20:425b)
; loads graphics data pointed by wTempPointer in wTempPointerBank
; to the VRAM bank according to wd4cb, in address pointed by wVRAMPointer
-LoadGfxDataFromTempPointerToVRAMBank: ; 80274 (20:4274)
+LoadGfxDataFromTempPointerToVRAMBank:
call GetTileOffsetPointerAndSwitchVRAM
jr LoadGfxDataFromTempPointer
-LoadGfxDataFromTempPointerToVRAMBank_Tiles0ToTiles2: ; 80279 (20:4279)
+LoadGfxDataFromTempPointerToVRAMBank_Tiles0ToTiles2:
call GetTileOffsetPointerAndSwitchVRAM_Tiles0ToTiles2
; fallthrough
; loads graphics data pointed by wTempPointer in wTempPointerBank
; to wVRAMPointer
-LoadGfxDataFromTempPointer: ; 8027c (20:427c)
+LoadGfxDataFromTempPointer:
push hl
push bc
push de
@@ -478,7 +477,7 @@ LoadGfxDataFromTempPointer: ; 8027c (20:427c)
; convert wVRAMTileOffset to address in VRAM
; and stores it in wVRAMPointer
; switches VRAM according to wd4cb
-GetTileOffsetPointerAndSwitchVRAM: ; 8029f (20:429f)
+GetTileOffsetPointerAndSwitchVRAM:
; address of the tile offset is wVRAMTileOffset * $10 + $8000
ld a, [wVRAMTileOffset]
swap a
@@ -502,7 +501,7 @@ GetTileOffsetPointerAndSwitchVRAM: ; 8029f (20:429f)
; switches VRAM according to wd4cb
; then changes wVRAMPointer such that
; addresses to Tiles0 is changed to Tiles2
-GetTileOffsetPointerAndSwitchVRAM_Tiles0ToTiles2: ; 802bb (20:42bb)
+GetTileOffsetPointerAndSwitchVRAM_Tiles0ToTiles2:
ld a, [wVRAMTileOffset]
push af
xor $80 ; toggle top bit
@@ -516,7 +515,7 @@ GetTileOffsetPointerAndSwitchVRAM_Tiles0ToTiles2: ; 802bb (20:42bb)
ret
; loads tileset gfx to VRAM corresponding to wCurTileset
-LoadTilesetGfx: ; 802d4 (20:42d4)
+LoadTilesetGfx:
push hl
ld l, $02 ; Tilesets
ld a, [wCurTileset]
@@ -679,7 +678,7 @@ LoadTilesetGfx: ; 802d4 (20:42d4)
ret
; gets pointer to BG map with ID from wCurTilemap
-Func_803b9: ; 803b9 (20:43b9)
+Func_803b9:
ld l, $00 ; Tilemaps
ld a, [wCurTilemap]
call GetMapDataPointer
@@ -691,7 +690,7 @@ Func_803b9: ; 803b9 (20:43b9)
; sets BGP in wLoadedPalData (if any)
; then loads the rest of the palette data
; a = palette index to load
-SetBGPAndLoadedPal: ; 803c9 (20:43c9)
+SetBGPAndLoadedPal:
push hl
push bc
push de
@@ -724,7 +723,7 @@ SetBGPAndLoadedPal: ; 803c9 (20:43c9)
; b = palette index
; c = palette size
; hl = palette data to copy
-LoadPaletteDataFromHL: ; 803ec (20:43ec)
+LoadPaletteDataFromHL:
push hl
push bc
push de
@@ -768,7 +767,7 @@ LoadPaletteDataFromHL: ; 803ec (20:43ec)
ret
; loads palette index a
-LoadPaletteData: ; 80418 (20:4418)
+LoadPaletteData:
push hl
push bc
push de
@@ -824,7 +823,7 @@ LoadPaletteData: ; 80418 (20:4418)
ret
; copies palette data of index in a to wLoadedPalData
-LoadPaletteDataToBuffer: ; 80456 (20:4456)
+LoadPaletteDataToBuffer:
push hl
push bc
push de
@@ -853,14 +852,14 @@ LoadPaletteDataToBuffer: ; 80456 (20:4456)
pop hl
ret
-ClearNumLoadedFramesetSubgroups: ; 8047b (20:447b)
+ClearNumLoadedFramesetSubgroups:
xor a
ld [wNumLoadedFramesetSubgroups], a
ret
; for the current map, process the animation
; data of its corresponding OW tiles
-DoMapOWFrame: ; 80480 (20:4480)
+DoMapOWFrame:
push hl
push bc
ld a, [wCurMap]
@@ -887,7 +886,7 @@ DoMapOWFrame: ; 80480 (20:4480)
ret
; processes the OW frameset pointed by hl
-ProcessOWFrameset: ; 804a2 (20:44a2)
+ProcessOWFrameset:
push hl
push bc
ld a, l
@@ -920,7 +919,7 @@ ProcessOWFrameset: ; 804a2 (20:44a2)
; for each of the loaded frameset subgroups
; load their tiles and advance their durations
-DoLoadedFramesetSubgroupsFrame: ; 804d8 (20:44d8)
+DoLoadedFramesetSubgroupsFrame:
ld a, [wNumLoadedFramesetSubgroups]
or a
ret z
@@ -941,7 +940,7 @@ DoLoadedFramesetSubgroupsFrame: ; 804d8 (20:44d8)
; from subgroup in register c, get
; from OW frameset in hl its corresponding
; data offset and duration
-GetOWFramesetSubgroupData: ; 804f3 (20:44f3)
+GetOWFramesetSubgroupData:
push hl
push bc
push hl
@@ -965,7 +964,7 @@ GetOWFramesetSubgroupData: ; 804f3 (20:44f3)
; if wCurOWFrameDuration == 0, processes next frame for OW map
; by loading the tiles corresponding to current frame
; if wCurOWFrameDuration != 0, then simply decrements it and returns
-LoadOWFrameTiles: ; 8050c (20:450c)
+LoadOWFrameTiles:
ld a, [wCurOWFrameDuration]
or a
jr z, .next_frame
@@ -1083,7 +1082,7 @@ LoadOWFrameTiles: ; 8050c (20:450c)
ret
; fills wOWFramesetSubgroups with $ff
-ClearOWFramesetSubgroups: ; 8059a (20:459a)
+ClearOWFramesetSubgroups:
push hl
push bc
ld hl, wOWFramesetSubgroups
@@ -1100,7 +1099,7 @@ ClearOWFramesetSubgroups: ; 8059a (20:459a)
; copies wOWFramesetSubgroups + 2*c
; to wCurOWFrameDataOffset and wCurOWFrameDuration
; also returns its current duration
-LoadOWFramesetSubgroup: ; 805aa (20:45aa)
+LoadOWFramesetSubgroup:
push hl
push bc
ld hl, wOWFramesetSubgroups
@@ -1119,7 +1118,7 @@ LoadOWFramesetSubgroup: ; 805aa (20:45aa)
; copies wCurOWFrameDataOffset and wCurOWFrameDuration
; to wOWFramesetSubgroups + 2*c
-StoreOWFramesetSubgroup: ; 805c1 (20:45c1)
+StoreOWFramesetSubgroup:
push hl
push bc
ld hl, wOWFramesetSubgroups
@@ -1137,7 +1136,7 @@ StoreOWFramesetSubgroup: ; 805c1 (20:45c1)
INCLUDE "data/map_ow_framesets.asm"
; clears wOWMapEvents
-Func_80b7a: ; 80b7a (20:4b7a)
+Func_80b7a:
push hl
push bc
ld c, $b
@@ -1152,7 +1151,7 @@ Func_80b7a: ; 80b7a (20:4b7a)
ret
; a = MAP_EVENT_* constant
-Func_80b89: ; 80b89 (20:4b89)
+Func_80b89:
push hl
push bc
push af
@@ -1173,14 +1172,14 @@ Func_80b89: ; 80b89 (20:4b89)
pop hl
ret
-Func_80ba4: ; 80ba4 (20:4ba4)
+Func_80ba4:
push af
xor a
ld [wWriteBGMapToSRAM], a
pop af
; fallthrough
-Func_80baa: ; 80baa (20:4baa)
+Func_80baa:
push hl
push bc
push de
@@ -1294,10 +1293,9 @@ Func_80baa: ; 80baa (20:4baa)
.ChallengeMachine
db $0a, $00, TILEMAP_CHALLENGE_MACHINE_MAP_EVENT, TILEMAP_CHALLENGE_MACHINE_MAP_EVENT_CGB
- ret ; unreferenced stray ret?
+ ret ; stray ret
-; unreferenced?
-Func_80c64: ; 80c64 (20:4c64)
+Func_80c64: ; unreferenced
ld a, [wLineSeparation]
push af
ld a, $01 ; no line separator
@@ -1346,9 +1344,8 @@ Func_80c64: ; 80c64 (20:4c64)
db SYM_SPACE ; tile behind cursor
dw NULL ; function pointer if non-0
-; unreferenced?
; fills Tiles0 with random bytes
-Func_80cc3: ; 80cc3 (20:4cc3)
+Func_80cc3: ; unreferenced
call DisableLCD
ld hl, v0Tiles0
ld bc, $800
@@ -1361,12 +1358,12 @@ Func_80cc3: ; 80cc3 (20:4cc3)
jr nz, .loop
ret
-Func_80cd6: ; 80cd6 (20:4cd6)
+Func_80cd6:
ret
; seems to be used to look at each OW NPC sprites
; with functions to rotate NPC and animate them
-Func_80cd7: ; 80cd7 (20:4cd7)
+Func_80cd7:
call DisableLCD
call EmptyScreen
call Func_3ca4
@@ -1557,1118 +1554,8 @@ Func_80cd7: ; 80cd7 (20:4cd7)
db SPRITE_OW_GRANNY, SPRITE_ANIM_LIGHT_NPC_UP, SPRITE_ANIM_YELLOW_NPC_UP ; $2b
db SPRITE_OW_AMY, SPRITE_ANIM_SGB_AMY_LAYING, SPRITE_ANIM_CGB_AMY_LAYING ; $2c
-SpriteNullAnimationPointer: ; 80e5a (20:4e5a)
+SpriteNullAnimationPointer:
dw SpriteNullAnimationFrame
SpriteNullAnimationFrame:
db 0
-
-; might be closer to "screen specific data" than map data
-MapDataPointers: ; 80e5d (20:4e5d)
- dw Tilemaps
- dw Tilesets
- dw Sprites
- dw SpriteAnimations
- dw Palettes
-
-; \1 = pointer
-; \2 = tileset
-tilemap: MACRO
- dwb \1, BANK(\1) - BANK(Tilemaps)
- db \2
-ENDM
-
-Tilemaps: ; 80e67 (20:4e67)
- tilemap OverworldMapTilemap, TILESET_OVERWORLD_MAP ; TILEMAP_OVERWORLD_MAP
- tilemap OverworldMapCGBTilemap, TILESET_OVERWORLD_MAP ; TILEMAP_OVERWORLD_MAP_CGB
- tilemap MasonLaboratoryTilemap, TILESET_MASON_LABORATORY ; TILEMAP_MASON_LABORATORY
- tilemap MasonLaboratoryCGBTilemap, TILESET_MASON_LABORATORY ; TILEMAP_MASON_LABORATORY_CGB
- tilemap ChallengeMachineMapEventTilemap, TILESET_MASON_LABORATORY ; TILEMAP_CHALLENGE_MACHINE_MAP_EVENT
- tilemap ChallengeMachineMapEventCGBTilemap,TILESET_MASON_LABORATORY ; TILEMAP_CHALLENGE_MACHINE_MAP_EVENT_CGB
- tilemap DeckMachineRoomTilemap, TILESET_MASON_LABORATORY ; TILEMAP_DECK_MACHINE_ROOM
- tilemap DeckMachineRoomCGBTilemap, TILESET_MASON_LABORATORY ; TILEMAP_DECK_MACHINE_ROOM_CGB
- tilemap DeckMachineMapEventTilemap, TILESET_MASON_LABORATORY ; TILEMAP_DECK_MACHINE_MAP_EVENT
- tilemap DeckMachineMapEventCGBTilemap, TILESET_MASON_LABORATORY ; TILEMAP_DECK_MACHINE_MAP_EVENT_CGB
- tilemap IshiharaTilemap, TILESET_ISHIHARA ; TILEMAP_ISHIHARA
- tilemap IshiharaCGBTilemap, TILESET_ISHIHARA ; TILEMAP_ISHIHARA_CGB
- tilemap FightingClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_FIGHTING_CLUB_ENTRANCE
- tilemap FightingClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_FIGHTING_CLUB_ENTRANCE_CGB
- tilemap RockClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_ROCK_CLUB_ENTRANCE
- tilemap RockClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_ROCK_CLUB_ENTRANCE_CGB
- tilemap WaterClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_WATER_CLUB_ENTRANCE
- tilemap WaterClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_WATER_CLUB_ENTRANCE_CGB
- tilemap LightningClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_LIGHTNING_CLUB_ENTRANCE
- tilemap LightningClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_LIGHTNING_CLUB_ENTRANCE_CGB
- tilemap GrassClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_GRASS_CLUB_ENTRANCE
- tilemap GrassClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_GRASS_CLUB_ENTRANCE_CGB
- tilemap PsychicClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_PSYCHIC_CLUB_ENTRANCE
- tilemap PsychicClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_PSYCHIC_CLUB_ENTRANCE_CGB
- tilemap ScienceClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_SCIENCE_CLUB_ENTRANCE
- tilemap ScienceClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_SCIENCE_CLUB_ENTRANCE_CGB
- tilemap FireClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_FIRE_CLUB_ENTRANCE
- tilemap FireClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_FIRE_CLUB_ENTRANCE_CGB
- tilemap ChallengeHallEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_CHALLENGE_HALL_ENTRANCE
- tilemap ChallengeHallEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_CHALLENGE_HALL_ENTRANCE_CGB
- tilemap ClubLobbyTilemap, TILESET_CLUB_LOBBY ; TILEMAP_CLUB_LOBBY
- tilemap ClubLobbyCGBTilemap, TILESET_CLUB_LOBBY ; TILEMAP_CLUB_LOBBY_CGB
- tilemap FightingClubTilemap, TILESET_FIGHTING_CLUB ; TILEMAP_FIGHTING_CLUB
- tilemap FightingClubCGBTilemap, TILESET_FIGHTING_CLUB ; TILEMAP_FIGHTING_CLUB_CGB
- tilemap RockClubTilemap, TILESET_ROCK_CLUB ; TILEMAP_ROCK_CLUB
- tilemap RockClubCGBTilemap, TILESET_ROCK_CLUB ; TILEMAP_ROCK_CLUB_CGB
- tilemap WaterClubTilemap, TILESET_WATER_CLUB ; TILEMAP_WATER_CLUB
- tilemap WaterClubCGBTilemap, TILESET_WATER_CLUB ; TILEMAP_WATER_CLUB_CGB
- tilemap LightningClubTilemap, TILESET_LIGHTNING_CLUB ; TILEMAP_LIGHTNING_CLUB
- tilemap LightningClubCGBTilemap, TILESET_LIGHTNING_CLUB ; TILEMAP_LIGHTNING_CLUB_CGB
- tilemap GrassClubTilemap, TILESET_GRASS_CLUB ; TILEMAP_GRASS_CLUB
- tilemap GrassClubCGBTilemap, TILESET_GRASS_CLUB ; TILEMAP_GRASS_CLUB_CGB
- tilemap PsychicClubTilemap, TILESET_PSYCHIC_CLUB ; TILEMAP_PSYCHIC_CLUB
- tilemap PsychicClubCGBTilemap, TILESET_PSYCHIC_CLUB ; TILEMAP_PSYCHIC_CLUB_CGB
- tilemap ScienceClubTilemap, TILESET_SCIENCE_CLUB ; TILEMAP_SCIENCE_CLUB
- tilemap ScienceClubCGBTilemap, TILESET_SCIENCE_CLUB ; TILEMAP_SCIENCE_CLUB_CGB
- tilemap FireClubTilemap, TILESET_FIRE_CLUB ; TILEMAP_FIRE_CLUB
- tilemap FireClubCGBTilemap, TILESET_FIRE_CLUB ; TILEMAP_FIRE_CLUB_CGB
- tilemap ChallengeHallTilemap, TILESET_CHALLENGE_HALL ; TILEMAP_CHALLENGE_HALL
- tilemap ChallengeHallCGBTilemap, TILESET_CHALLENGE_HALL ; TILEMAP_CHALLENGE_HALL_CGB
- tilemap PokemonDomeEntranceTilemap, TILESET_POKEMON_DOME_ENTRANCE ; TILEMAP_POKEMON_DOME_ENTRANCE
- tilemap PokemonDomeEntranceCGBTilemap, TILESET_POKEMON_DOME_ENTRANCE ; TILEMAP_POKEMON_DOME_ENTRANCE_CGB
- tilemap PokemonDomeDoorMapEventTilemap, TILESET_POKEMON_DOME_ENTRANCE ; TILEMAP_POKEMON_DOME_DOOR_MAP_EVENT
- tilemap PokemonDomeDoorMapEventCGBTilemap, TILESET_POKEMON_DOME_ENTRANCE ; TILEMAP_POKEMON_DOME_DOOR_MAP_EVENT_CGB
- tilemap PokemonDomeTilemap, TILESET_POKEMON_DOME ; TILEMAP_POKEMON_DOME
- tilemap PokemonDomeCGBTilemap, TILESET_POKEMON_DOME ; TILEMAP_POKEMON_DOME_CGB
- tilemap HallOfHonorDoorMapEventTilemap, TILESET_POKEMON_DOME ; TILEMAP_HALL_OF_HONOR_DOOR_MAP_EVENT
- tilemap HallOfHonorDoorMapEventCGBTilemap, TILESET_POKEMON_DOME ; TILEMAP_HALL_OF_HONOR_DOOR_MAP_EVENT_CGB
- tilemap HallOfHonorTilemap, TILESET_HALL_OF_HONOR ; TILEMAP_HALL_OF_HONOR
- tilemap HallOfHonorCGBTilemap, TILESET_HALL_OF_HONOR ; TILEMAP_HALL_OF_HONOR_CGB
- tilemap CardPopCGBTilemap, TILESET_CARD_POP ; TILEMAP_CARD_POP_CGB
- tilemap CardPopTilemap, TILESET_CARD_POP ; TILEMAP_CARD_POP
- tilemap GrassMedalTilemap, TILESET_MEDAL ; TILEMAP_GRASS_MEDAL
- tilemap ScienceMedalTilemap, TILESET_MEDAL ; TILEMAP_SCIENCE_MEDAL
- tilemap FireMedalTilemap, TILESET_MEDAL ; TILEMAP_FIRE_MEDAL
- tilemap WaterMedalTilemap, TILESET_MEDAL ; TILEMAP_WATER_MEDAL
- tilemap LightningMedalTilemap, TILESET_MEDAL ; TILEMAP_LIGHTNING_MEDAL
- tilemap FightingMedalTilemap, TILESET_MEDAL ; TILEMAP_FIGHTING_MEDAL
- tilemap RockMedalTilemap, TILESET_MEDAL ; TILEMAP_ROCK_MEDAL
- tilemap PsychicMedalTilemap, TILESET_MEDAL ; TILEMAP_PSYCHIC_MEDAL
- tilemap GameBoyLinkCGBTilemap, TILESET_GAMEBOY_LINK ; TILEMAP_GAMEBOY_LINK_CGB
- tilemap GameBoyLinkTilemap, TILESET_GAMEBOY_LINK ; TILEMAP_GAMEBOY_LINK
- tilemap GameBoyLinkConnectingCGBTilemap, TILESET_GAMEBOY_LINK ; TILEMAP_GAMEBOY_LINK_CONNECTING_CGB
- tilemap GameBoyLinkConnectingTilemap, TILESET_GAMEBOY_LINK ; TILEMAP_GAMEBOY_LINK_CONNECTING
- tilemap GameBoyPrinterCGBTilemap, TILESET_GAMEBOY_PRINTER ; TILEMAP_GAMEBOY_PRINTER_CGB
- tilemap GameBoyPrinterTilemap, TILESET_GAMEBOY_PRINTER ; TILEMAP_GAMEBOY_PRINTER
- tilemap ColosseumTilemap, TILESET_COLOSSEUM_1 ; TILEMAP_COLOSSEUM
- tilemap ColosseumCGBTilemap, TILESET_COLOSSEUM_2 ; TILEMAP_COLOSSEUM_CGB
- tilemap EvolutionTilemap, TILESET_EVOLUTION_1 ; TILEMAP_EVOLUTION
- tilemap EvolutionCGBTilemap, TILESET_EVOLUTION_2 ; TILEMAP_EVOLUTION_CGB
- tilemap MysteryTilemap, TILESET_MYSTERY_1 ; TILEMAP_MYSTERY
- tilemap MysteryCGBTilemap, TILESET_MYSTERY_2 ; TILEMAP_MYSTERY_CGB
- tilemap LaboratoryTilemap, TILESET_LABORATORY_1 ; TILEMAP_LABORATORY
- tilemap LaboratoryCGBTilemap, TILESET_LABORATORY_2 ; TILEMAP_LABORATORY_CGB
- tilemap CharizardIntroTilemap, TILESET_CHARIZARD_INTRO_1 ; TILEMAP_CHARIZARD_INTRO
- tilemap CharizardIntroCGBTilemap, TILESET_CHARIZARD_INTRO_2 ; TILEMAP_CHARIZARD_INTRO_CGB
- tilemap ScytherIntroTilemap, TILESET_SCYTHER_INTRO_1 ; TILEMAP_SCYTHER_INTRO
- tilemap ScytherIntroCGBTilemap, TILESET_SCYTHER_INTRO_2 ; TILEMAP_SCYTHER_INTRO_CGB
- tilemap AerodactylIntroTilemap, TILESET_AERODACTYL_INTRO_1 ; TILEMAP_AERODACTYL_INTRO
- tilemap AerodactylIntroCGBTilemap, TILESET_AERODACTYL_INTRO_2 ; TILEMAP_AERODACTYL_INTRO_CGB
- tilemap JapaneseTitleScreenTilemap, TILESET_JAPANESE_TITLE_SCREEN ; TILEMAP_JAPANESE_TITLE_SCREEN
- tilemap JapaneseTitleScreenCGBTilemap, TILESET_JAPANESE_TITLE_SCREEN_CGB ; TILEMAP_JAPANESE_TITLE_SCREEN_CGB
- tilemap SolidTiles1Tilemap, TILESET_SOLID_TILES_1 ; TILEMAP_SOLID_TILES_1
- tilemap SolidTiles2Tilemap, TILESET_SOLID_TILES_1 ; TILEMAP_SOLID_TILES_2
- tilemap SolidTiles3Tilemap, TILESET_SOLID_TILES_1 ; TILEMAP_SOLID_TILES_3
- tilemap JapaneseTitleScreen2Tilemap, TILESET_JAPANESE_TITLE_SCREEN_2 ; TILEMAP_JAPANESE_TITLE_SCREEN_2
- tilemap JapaneseTitleScreen2CGBTilemap, TILESET_JAPANESE_TITLE_SCREEN_2_CGB ; TILEMAP_JAPANESE_TITLE_SCREEN_2_CGB
- tilemap SolidTiles4Tilemap, TILESET_SOLID_TILES_2 ; TILEMAP_SOLID_TILES_4
- tilemap PlayerTilemap, TILESET_PLAYER ; TILEMAP_PLAYER
- tilemap OpponentTilemap, TILESET_RONALD ; TILEMAP_OPPONENT
- tilemap TitleScreenTilemap, TILESET_TITLE_SCREEN ; TILEMAP_TITLE_SCREEN
- tilemap TitleScreenCGBTilemap, TILESET_TITLE_SCREEN_CGB ; TILEMAP_TITLE_SCREEN_CGB
- tilemap CopyrightTilemap, TILESET_COPYRIGHT ; TILEMAP_COPYRIGHT
- tilemap CopyrightCGBTilemap, TILESET_COPYRIGHT ; TILEMAP_COPYRIGHT_CGB
- tilemap NintendoTilemap, TILESET_NINTENDO ; TILEMAP_NINTENDO
- tilemap CompaniesTilemap, TILESET_COMPANIES ; TILEMAP_COMPANIES
-
-; \1 = pointer
-; \2 = number of tiles
-tileset: MACRO
- dwb \1, BANK(\1) - BANK(Tilesets)
- db \2
-ENDM
-
-Tilesets: ; 8100f (20:500f)
- tileset OverworldMapTiles, 193 ; TILESET_OVERWORLD_MAP
- tileset MasonLaboratoryTilesetGfx, 151 ; TILESET_MASON_LABORATORY
- tileset IshiharaTilesetGfx, 77 ; TILESET_ISHIHARA
- tileset ClubEntranceTilesetGfx, 129 ; TILESET_CLUB_ENTRANCE
- tileset ClubLobbyTilesetGfx, 120 ; TILESET_CLUB_LOBBY
- tileset FightingClubTilesetGfx, 99 ; TILESET_FIGHTING_CLUB
- tileset RockClubTilesetGfx, 60 ; TILESET_ROCK_CLUB
- tileset WaterClubTilesetGfx, 161 ; TILESET_WATER_CLUB
- tileset LightningClubTilesetGfx, 131 ; TILESET_LIGHTNING_CLUB
- tileset GrassClubTilesetGfx, 87 ; TILESET_GRASS_CLUB
- tileset PsychicClubTilesetGfx, 58 ; TILESET_PSYCHIC_CLUB
- tileset ScienceClubTilesetGfx, 82 ; TILESET_SCIENCE_CLUB
- tileset FireClubTilesetGfx, 87 ; TILESET_FIRE_CLUB
- tileset ChallengeHallTilesetGfx, 157 ; TILESET_CHALLENGE_HALL
- tileset PokemonDomeEntranceTilesetGfx, 78 ; TILESET_POKEMON_DOME_ENTRANCE
- tileset PokemonDomeTilesetGfx, 207 ; TILESET_POKEMON_DOME
- tileset HallOfHonorTilesetGfx, 121 ; TILESET_HALL_OF_HONOR
- tileset CardPopGfx, 189 ; TILESET_CARD_POP
- tileset MedalGfx, 72 ; TILESET_MEDAL
- tileset GameBoyLinkGfx, 109 ; TILESET_GAMEBOY_LINK
- tileset GameBoyPrinterGfx, 93 ; TILESET_GAMEBOY_PRINTER
- tileset Colosseum1Gfx, 96 ; TILESET_COLOSSEUM_1
- tileset Colosseum2Gfx, 86 ; TILESET_COLOSSEUM_2
- tileset Evolution1Gfx, 96 ; TILESET_EVOLUTION_1
- tileset Evolution2Gfx, 86 ; TILESET_EVOLUTION_2
- tileset Mystery1Gfx, 96 ; TILESET_MYSTERY_1
- tileset Mystery2Gfx, 86 ; TILESET_MYSTERY_2
- tileset Laboratory1Gfx, 96 ; TILESET_LABORATORY_1
- tileset Laboratory2Gfx, 86 ; TILESET_LABORATORY_2
- tileset CharizardIntro1Gfx, 96 ; TILESET_CHARIZARD_INTRO_1
- tileset CharizardIntro2Gfx, 96 ; TILESET_CHARIZARD_INTRO_2
- tileset ScytherIntro1Gfx, 96 ; TILESET_SCYTHER_INTRO_1
- tileset ScytherIntro2Gfx, 96 ; TILESET_SCYTHER_INTRO_2
- tileset AerodactylIntro1Gfx, 96 ; TILESET_AERODACTYL_INTRO_1
- tileset AerodactylIntro2Gfx, 96 ; TILESET_AERODACTYL_INTRO_2
- tileset JapaneseTitleScreenGfx, 97 ; TILESET_JAPANESE_TITLE_SCREEN
- tileset JapaneseTitleScreenCGBGfx, 97 ; TILESET_JAPANESE_TITLE_SCREEN_CGB
- tileset SolidTiles1, 4 ; TILESET_SOLID_TILES_1
- tileset JapaneseTitleScreen2Gfx, 244 ; TILESET_JAPANESE_TITLE_SCREEN_2
- tileset JapaneseTitleScreen2CGBGfx, 59 ; TILESET_JAPANESE_TITLE_SCREEN_2_CGB
- tileset SolidTiles2, 4 ; TILESET_SOLID_TILES_2
- tileset PlayerGfx, 36 ; TILESET_PLAYER
- tileset RonaldGfx, 36 ; TILESET_RONALD
- tileset TitleScreenGfx, 220 ; TILESET_TITLE_SCREEN
- tileset TitleScreenCGBGfx, 212 ; TILESET_TITLE_SCREEN_CGB
- tileset CopyrightGfx, 36 ; TILESET_COPYRIGHT
- tileset NintendoGfx, 24 ; TILESET_NINTENDO
- tileset CompaniesGfx, 49 ; TILESET_COMPANIES
- tileset SamGfx, 36 ; TILESET_SAM
- tileset ImakuniGfx, 36 ; TILESET_IMAKUNI
- tileset NikkiGfx, 36 ; TILESET_NIKKI
- tileset RickGfx, 36 ; TILESET_RICK
- tileset KenGfx, 36 ; TILESET_KEN
- tileset AmyGfx, 36 ; TILESET_AMY
- tileset IsaacGfx, 36 ; TILESET_ISAAC
- tileset MitchGfx, 36 ; TILESET_MITCH
- tileset GeneGfx, 36 ; TILESET_GENE
- tileset MurrayGfx, 36 ; TILESET_MURRAY
- tileset CourtneyGfx, 36 ; TILESET_COURTNEY
- tileset SteveGfx, 36 ; TILESET_STEVE
- tileset JackGfx, 36 ; TILESET_JACK
- tileset RodGfx, 36 ; TILESET_ROD
- tileset JosephGfx, 36 ; TILESET_JOSEPH
- tileset DavidGfx, 36 ; TILESET_DAVID
- tileset ErikGfx, 36 ; TILESET_ERIK
- tileset JohnGfx, 36 ; TILESET_JOHN
- tileset AdamGfx, 36 ; TILESET_ADAM
- tileset JonathanGfx, 36 ; TILESET_JONATHAN
- tileset JoshuaGfx, 36 ; TILESET_JOSHUA
- tileset NicholasGfx, 36 ; TILESET_NICHOLAS
- tileset BrandonGfx, 36 ; TILESET_BRANDON
- tileset MatthewGfx, 36 ; TILESET_MATTHEW
- tileset RyanGfx, 36 ; TILESET_RYAN
- tileset AndrewGfx, 36 ; TILESET_ANDREW
- tileset ChrisGfx, 36 ; TILESET_CHRIS
- tileset MichaelGfx, 36 ; TILESET_MICHAEL
- tileset DanielGfx, 36 ; TILESET_DANIEL
- tileset RobertGfx, 36 ; TILESET_ROBERT
- tileset BrittanyGfx, 36 ; TILESET_BRITTANY
- tileset KristinGfx, 36 ; TILESET_KRISTIN
- tileset HeatherGfx, 36 ; TILESET_HEATHER
- tileset SaraGfx, 36 ; TILESET_SARA
- tileset AmandaGfx, 36 ; TILESET_AMANDA
- tileset JenniferGfx, 36 ; TILESET_JENNIFER
- tileset JessicaGfx, 36 ; TILESET_JESSICA
- tileset StephanieGfx, 36 ; TILESET_STEPHANIE
- tileset AaronGfx, 36 ; TILESET_AARON
-
-; \1 = gfx pointer
-; \2 = number of tiles
-gfx_pointer: MACRO
- dwb \1, BANK(\1) - BANK(Sprites)
- db \2
-ENDM
-
-Sprites: ; 8116b (20:516b)
- gfx_pointer OWPlayerGfx, $14 ; SPRITE_OW_PLAYER
- gfx_pointer OWRonaldGfx, $14 ; SPRITE_OW_RONALD
- gfx_pointer OWDrMasonGfx, $14 ; SPRITE_OW_DRMASON
- gfx_pointer OWIshiharaGfx, $14 ; SPRITE_OW_ISHIHARA
- gfx_pointer OWImakuniGfx, $14 ; SPRITE_OW_IMAKUNI
- gfx_pointer OWNikkiGfx, $14 ; SPRITE_OW_NIKKI
- gfx_pointer OWRickGfx, $14 ; SPRITE_OW_RICK
- gfx_pointer OWKenGfx, $14 ; SPRITE_OW_KEN
- gfx_pointer OWAmyGfx, $1b ; SPRITE_OW_AMY
- gfx_pointer OWIsaacGfx, $14 ; SPRITE_OW_ISAAC
- gfx_pointer OWMitchGfx, $14 ; SPRITE_OW_MITCH
- gfx_pointer OWGeneGfx, $14 ; SPRITE_OW_GENE
- gfx_pointer OWMurrayGfx, $14 ; SPRITE_OW_MURRAY
- gfx_pointer OWCourtneyGfx, $14 ; SPRITE_OW_COURTNEY
- gfx_pointer OWSteveGfx, $14 ; SPRITE_OW_STEVE
- gfx_pointer OWJackGfx, $14 ; SPRITE_OW_JACK
- gfx_pointer OWRodGfx, $14 ; SPRITE_OW_ROD
- gfx_pointer OWBoyGfx, $14 ; SPRITE_OW_BOY
- gfx_pointer OWLadGfx, $14 ; SPRITE_OW_LAD
- gfx_pointer OWSpecsGfx, $14 ; SPRITE_OW_SPECS
- gfx_pointer OWButchGfx, $14 ; SPRITE_OW_BUTCH
- gfx_pointer OWManiaGfx, $14 ; SPRITE_OW_MANIA
- gfx_pointer OWJoshuaGfx, $14 ; SPRITE_OW_JOSHUA
- gfx_pointer OWHoodGfx, $14 ; SPRITE_OW_HOOD
- gfx_pointer OWTechGfx, $14 ; SPRITE_OW_TECH
- gfx_pointer OWChapGfx, $14 ; SPRITE_OW_CHAP
- gfx_pointer OWManGfx, $14 ; SPRITE_OW_MAN
- gfx_pointer OWPappyGfx, $14 ; SPRITE_OW_PAPPY
- gfx_pointer OWGirlGfx, $14 ; SPRITE_OW_GIRL
- gfx_pointer OWLass1Gfx, $14 ; SPRITE_OW_LASS1
- gfx_pointer OWLass2Gfx, $14 ; SPRITE_OW_LASS2
- gfx_pointer OWLass3Gfx, $14 ; SPRITE_OW_LASS3
- gfx_pointer OWSwimmerGfx, $14 ; SPRITE_OW_SWIMMER
- gfx_pointer OWClerkGfx, $08 ; SPRITE_OW_CLERK
- gfx_pointer OWGalGfx, $14 ; SPRITE_OW_GAL
- gfx_pointer OWWomanGfx, $14 ; SPRITE_OW_WOMAN
- gfx_pointer OWGrannyGfx, $14 ; SPRITE_OW_GRANNY
- gfx_pointer OverworldMapOAMGfx, $08 ; SPRITE_OW_MAP_OAM
- gfx_pointer Duel0Gfx, $16 ; SPRITE_DUEL_0
- gfx_pointer Duel63Gfx, $0a ; SPRITE_DUEL_63
- gfx_pointer DuelGlowGfx, $0b ; SPRITE_DUEL_GLOW
- gfx_pointer Duel1Gfx, $06 ; SPRITE_DUEL_1
- gfx_pointer Duel2Gfx, $08 ; SPRITE_DUEL_2
- gfx_pointer Duel55Gfx, $02 ; SPRITE_DUEL_55
- gfx_pointer Duel58Gfx, $04 ; SPRITE_DUEL_58
- gfx_pointer Duel3Gfx, $09 ; SPRITE_DUEL_3
- gfx_pointer Duel4Gfx, $12 ; SPRITE_DUEL_4
- gfx_pointer Duel5Gfx, $09 ; SPRITE_DUEL_5
- gfx_pointer Duel6Gfx, $11 ; SPRITE_DUEL_6
- gfx_pointer Duel59Gfx, $03 ; SPRITE_DUEL_59
- gfx_pointer Duel7Gfx, $2d ; SPRITE_DUEL_7
- gfx_pointer Duel8Gfx, $0d ; SPRITE_DUEL_8
- gfx_pointer Duel9Gfx, $1c ; SPRITE_DUEL_9
- gfx_pointer Duel10Gfx, $4c ; SPRITE_DUEL_10
- gfx_pointer Duel61Gfx, $03 ; SPRITE_DUEL_61
- gfx_pointer Duel11Gfx, $1b ; SPRITE_DUEL_11
- gfx_pointer Duel12Gfx, $07 ; SPRITE_DUEL_12
- gfx_pointer Duel13Gfx, $0c ; SPRITE_DUEL_13
- gfx_pointer Duel62Gfx, $01 ; SPRITE_DUEL_62
- gfx_pointer Duel14Gfx, $22 ; SPRITE_DUEL_14
- gfx_pointer Duel15Gfx, $20 ; SPRITE_DUEL_15
- gfx_pointer Duel16Gfx, $0a ; SPRITE_DUEL_16
- gfx_pointer Duel17Gfx, $25 ; SPRITE_DUEL_17
- gfx_pointer Duel18Gfx, $18 ; SPRITE_DUEL_18
- gfx_pointer Duel19Gfx, $1b ; SPRITE_DUEL_19
- gfx_pointer Duel20Gfx, $08 ; SPRITE_DUEL_20
- gfx_pointer Duel21Gfx, $0d ; SPRITE_DUEL_21
- gfx_pointer Duel22Gfx, $22 ; SPRITE_DUEL_22
- gfx_pointer Duel23Gfx, $0c ; SPRITE_DUEL_23
- gfx_pointer Duel24Gfx, $25 ; SPRITE_DUEL_24
- gfx_pointer Duel25Gfx, $22 ; SPRITE_DUEL_25
- gfx_pointer Duel26Gfx, $0c ; SPRITE_DUEL_26
- gfx_pointer Duel27Gfx, $4c ; SPRITE_DUEL_27
- gfx_pointer Duel28Gfx, $08 ; SPRITE_DUEL_28
- gfx_pointer Duel29Gfx, $07 ; SPRITE_DUEL_29
- gfx_pointer Duel56Gfx, $01 ; SPRITE_DUEL_56
- gfx_pointer Duel30Gfx, $1a ; SPRITE_DUEL_30
- gfx_pointer Duel31Gfx, $0a ; SPRITE_DUEL_31
- gfx_pointer Duel32Gfx, $2e ; SPRITE_DUEL_32
- gfx_pointer Duel33Gfx, $08 ; SPRITE_DUEL_33
- gfx_pointer Duel34Gfx, $07 ; SPRITE_DUEL_34
- gfx_pointer Duel35Gfx, $1c ; SPRITE_DUEL_35
- gfx_pointer Duel66Gfx, $04 ; SPRITE_DUEL_66
- gfx_pointer Duel36Gfx, $08 ; SPRITE_DUEL_36
- gfx_pointer Duel37Gfx, $0b ; SPRITE_DUEL_37
- gfx_pointer Duel57Gfx, $01 ; SPRITE_DUEL_57
- gfx_pointer Duel38Gfx, $1c ; SPRITE_DUEL_38
- gfx_pointer Duel39Gfx, $16 ; SPRITE_DUEL_39
- gfx_pointer Duel40Gfx, $10 ; SPRITE_DUEL_40
- gfx_pointer Duel41Gfx, $0f ; SPRITE_DUEL_41
- gfx_pointer Duel42Gfx, $07 ; SPRITE_DUEL_42
- gfx_pointer Duel43Gfx, $0a ; SPRITE_DUEL_43
- gfx_pointer Duel44Gfx, $09 ; SPRITE_DUEL_44
- gfx_pointer Duel60Gfx, $02 ; SPRITE_DUEL_60
- gfx_pointer Duel64Gfx, $02 ; SPRITE_DUEL_64
- gfx_pointer Duel45Gfx, $03 ; SPRITE_DUEL_45
- gfx_pointer Duel46Gfx, $08 ; SPRITE_DUEL_46
- gfx_pointer Duel47Gfx, $0f ; SPRITE_DUEL_47
- gfx_pointer Duel48Gfx, $03 ; SPRITE_DUEL_48
- gfx_pointer Duel49Gfx, $05 ; SPRITE_DUEL_49
- gfx_pointer Duel50Gfx, $17 ; SPRITE_DUEL_50
- gfx_pointer Duel51Gfx, $36 ; SPRITE_DUEL_WON_LOST_DRAW
- gfx_pointer Duel52Gfx, $0b ; SPRITE_DUEL_52
- gfx_pointer Duel53Gfx, $06 ; SPRITE_DUEL_53
- gfx_pointer Duel54Gfx, $16 ; SPRITE_DUEL_54
- gfx_pointer BoosterPackOAMGfx, $20 ; SPRITE_BOOSTER_PACK_OAM
- gfx_pointer PressStartGfx, $14 ; SPRITE_PRESS_START
- gfx_pointer GrassGfx, $04 ; SPRITE_GRASS
- gfx_pointer FireGfx, $04 ; SPRITE_FIRE
- gfx_pointer WaterGfx, $04 ; SPRITE_WATER
- gfx_pointer ColorlessGfx, $04 ; SPRITE_COLORLESS
- gfx_pointer LightningGfx, $04 ; SPRITE_LIGHTNING
- gfx_pointer PsychicGfx, $04 ; SPRITE_PSYCHIC
- gfx_pointer FightingGfx, $04 ; SPRITE_FIGHTING
-
-; \1 = anim data pointer
-anim_data_pointer: MACRO
- dwb \1, BANK(\1) - BANK(SpriteAnimations)
- db $00 ; unused (padding?)
-ENDM
-
-SpriteAnimations: ; 81333 (20:5333)
- anim_data_pointer AnimData0 ; SPRITE_ANIM_LIGHT_NPC_UP
- anim_data_pointer AnimData1 ; SPRITE_ANIM_LIGHT_NPC_RIGHT
- anim_data_pointer AnimData2 ; SPRITE_ANIM_LIGHT_NPC_DOWN
- anim_data_pointer AnimData3 ; SPRITE_ANIM_LIGHT_NPC_LEFT
- anim_data_pointer AnimData4 ; SPRITE_ANIM_DARK_NPC_UP
- anim_data_pointer AnimData5 ; SPRITE_ANIM_DARK_NPC_RIGHT
- anim_data_pointer AnimData6 ; SPRITE_ANIM_DARK_NPC_DOWN
- anim_data_pointer AnimData7 ; SPRITE_ANIM_DARK_NPC_LEFT
- anim_data_pointer AnimData8 ; SPRITE_ANIM_SGB_AMY_LAYING
- anim_data_pointer AnimData9 ; SPRITE_ANIM_SGB_AMY_STAND
- anim_data_pointer AnimData10 ; SPRITE_ANIM_SGB_CLERK_NPC_UP
- anim_data_pointer AnimData11 ; SPRITE_ANIM_SGB_CLERK_NPC_RIGHT
- anim_data_pointer AnimData12 ; SPRITE_ANIM_SGB_CLERK_NPC_DOWN
- anim_data_pointer AnimData13 ; SPRITE_ANIM_SGB_CLERK_NPC_LEFT
- anim_data_pointer AnimData14 ; SPRITE_ANIM_BLUE_NPC_UP
- anim_data_pointer AnimData15 ; SPRITE_ANIM_BLUE_NPC_RIGHT
- anim_data_pointer AnimData16 ; SPRITE_ANIM_BLUE_NPC_DOWN
- anim_data_pointer AnimData17 ; SPRITE_ANIM_BLUE_NPC_LEFT
- anim_data_pointer AnimData18 ; SPRITE_ANIM_PINK_NPC_UP
- anim_data_pointer AnimData19 ; SPRITE_ANIM_PINK_NPC_RIGHT
- anim_data_pointer AnimData20 ; SPRITE_ANIM_PINK_NPC_DOWN
- anim_data_pointer AnimData21 ; SPRITE_ANIM_PINK_NPC_LEFT
- anim_data_pointer AnimData22 ; SPRITE_ANIM_YELLOW_NPC_UP
- anim_data_pointer AnimData23 ; SPRITE_ANIM_YELLOW_NPC_RIGHT
- anim_data_pointer AnimData24 ; SPRITE_ANIM_YELLOW_NPC_DOWN
- anim_data_pointer AnimData25 ; SPRITE_ANIM_YELLOW_NPC_LEFT
- anim_data_pointer AnimData26 ; SPRITE_ANIM_GREEN_NPC_UP
- anim_data_pointer AnimData27 ; SPRITE_ANIM_GREEN_NPC_RIGHT
- anim_data_pointer AnimData28 ; SPRITE_ANIM_GREEN_NPC_DOWN
- anim_data_pointer AnimData29 ; SPRITE_ANIM_GREEN_NPC_LEFT
- anim_data_pointer AnimData30 ; SPRITE_ANIM_RED_NPC_UP
- anim_data_pointer AnimData31 ; SPRITE_ANIM_RED_NPC_RIGHT
- anim_data_pointer AnimData32 ; SPRITE_ANIM_RED_NPC_DOWN
- anim_data_pointer AnimData33 ; SPRITE_ANIM_RED_NPC_LEFT
- anim_data_pointer AnimData34 ; SPRITE_ANIM_PURPLE_NPC_UP
- anim_data_pointer AnimData35 ; SPRITE_ANIM_PURPLE_NPC_RIGHT
- anim_data_pointer AnimData36 ; SPRITE_ANIM_PURPLE_NPC_DOWN
- anim_data_pointer AnimData37 ; SPRITE_ANIM_PURPLE_NPC_LEFT
- anim_data_pointer AnimData38 ; SPRITE_ANIM_WHITE_NPC_UP
- anim_data_pointer AnimData39 ; SPRITE_ANIM_WHITE_NPC_RIGHT
- anim_data_pointer AnimData40 ; SPRITE_ANIM_WHITE_NPC_DOWN
- anim_data_pointer AnimData41 ; SPRITE_ANIM_WHITE_NPC_LEFT
- anim_data_pointer AnimData42 ; SPRITE_ANIM_INDIGO_NPC_UP
- anim_data_pointer AnimData43 ; SPRITE_ANIM_INDIGO_NPC_RIGHT
- anim_data_pointer AnimData44 ; SPRITE_ANIM_INDIGO_NPC_DOWN
- anim_data_pointer AnimData45 ; SPRITE_ANIM_INDIGO_NPC_LEFT
- anim_data_pointer AnimData46 ; SPRITE_ANIM_CGB_AMY_LAYING
- anim_data_pointer AnimData47 ; SPRITE_ANIM_CGB_AMY_STAND
- anim_data_pointer AnimData48 ; SPRITE_ANIM_CGB_CLERK_NPC_UP
- anim_data_pointer AnimData49 ; SPRITE_ANIM_CGB_CLERK_NPC_RIGHT
- anim_data_pointer AnimData50 ; SPRITE_ANIM_CGB_CLERK_NPC_DOWN
- anim_data_pointer AnimData51 ; SPRITE_ANIM_CGB_CLERK_NPC_LEFT
- anim_data_pointer AnimData52 ; SPRITE_ANIM_SGB_VOLCANO_SMOKE
- anim_data_pointer AnimData53 ; SPRITE_ANIM_SGB_OWMAP_CURSOR
- anim_data_pointer AnimData54 ; SPRITE_ANIM_SGB_OWMAP_CURSOR_FAST
- anim_data_pointer AnimData55 ; SPRITE_ANIM_CGB_VOLCANO_SMOKE
- anim_data_pointer AnimData56 ; SPRITE_ANIM_CGB_OWMAP_CURSOR
- anim_data_pointer AnimData57 ; SPRITE_ANIM_CGB_OWMAP_CURSOR_FAST
- anim_data_pointer AnimData58 ; SPRITE_ANIM_TORCH
- anim_data_pointer AnimData59 ; SPRITE_ANIM_SGB_CARD_TOP_LEFT
- anim_data_pointer AnimData60 ; SPRITE_ANIM_SGB_CARD_TOP_RIGHT
- anim_data_pointer AnimData61 ; SPRITE_ANIM_SGB_CARD_LEFT_SPARK
- anim_data_pointer AnimData62 ; SPRITE_ANIM_SGB_CARD_BOTTOM_LEFT
- anim_data_pointer AnimData63 ; SPRITE_ANIM_SGB_CARD_BOTTOM_RIGHT
- anim_data_pointer AnimData64 ; SPRITE_ANIM_SGB_CARD_RIGHT_SPARK
- anim_data_pointer AnimData65 ; SPRITE_ANIM_CGB_CARD_TOP_LEFT
- anim_data_pointer AnimData66 ; SPRITE_ANIM_CGB_CARD_TOP_RIGHT
- anim_data_pointer AnimData67 ; SPRITE_ANIM_CGB_CARD_LEFT_SPARK
- anim_data_pointer AnimData68 ; SPRITE_ANIM_CGB_CARD_BOTTOM_LEFT
- anim_data_pointer AnimData69 ; SPRITE_ANIM_CGB_CARD_BOTTOM_RIGHT
- anim_data_pointer AnimData70 ; SPRITE_ANIM_CGB_CARD_RIGHT_SPARK
- anim_data_pointer AnimData71 ; SPRITE_ANIM_71
- anim_data_pointer AnimData72 ; SPRITE_ANIM_72
- anim_data_pointer AnimData73 ; SPRITE_ANIM_73
- anim_data_pointer AnimData74 ; SPRITE_ANIM_74
- anim_data_pointer AnimData75 ; SPRITE_ANIM_75
- anim_data_pointer AnimData76 ; SPRITE_ANIM_76
- anim_data_pointer AnimData77 ; SPRITE_ANIM_77
- anim_data_pointer AnimData78 ; SPRITE_ANIM_78
- anim_data_pointer AnimData79 ; SPRITE_ANIM_79
- anim_data_pointer AnimData80 ; SPRITE_ANIM_80
- anim_data_pointer AnimData81 ; SPRITE_ANIM_81
- anim_data_pointer AnimData82 ; SPRITE_ANIM_82
- anim_data_pointer AnimData83 ; SPRITE_ANIM_83
- anim_data_pointer AnimData84 ; SPRITE_ANIM_84
- anim_data_pointer AnimData85 ; SPRITE_ANIM_85
- anim_data_pointer AnimData86 ; SPRITE_ANIM_86
- anim_data_pointer AnimData87 ; SPRITE_ANIM_87
- anim_data_pointer AnimData88 ; SPRITE_ANIM_88
- anim_data_pointer AnimData89 ; SPRITE_ANIM_89
- anim_data_pointer AnimData90 ; SPRITE_ANIM_90
- anim_data_pointer AnimData91 ; SPRITE_ANIM_91
- anim_data_pointer AnimData92 ; SPRITE_ANIM_92
- anim_data_pointer AnimData93 ; SPRITE_ANIM_93
- anim_data_pointer AnimData94 ; SPRITE_ANIM_94
- anim_data_pointer AnimData95 ; SPRITE_ANIM_95
- anim_data_pointer AnimData96 ; SPRITE_ANIM_96
- anim_data_pointer AnimData97 ; SPRITE_ANIM_97
- anim_data_pointer AnimData98 ; SPRITE_ANIM_98
- anim_data_pointer AnimData99 ; SPRITE_ANIM_99
- anim_data_pointer AnimData100 ; SPRITE_ANIM_100
- anim_data_pointer AnimData101 ; SPRITE_ANIM_101
- anim_data_pointer AnimData102 ; SPRITE_ANIM_102
- anim_data_pointer AnimData103 ; SPRITE_ANIM_103
- anim_data_pointer AnimData104 ; SPRITE_ANIM_104
- anim_data_pointer AnimData105 ; SPRITE_ANIM_105
- anim_data_pointer AnimData106 ; SPRITE_ANIM_106
- anim_data_pointer AnimData107 ; SPRITE_ANIM_107
- anim_data_pointer AnimData108 ; SPRITE_ANIM_108
- anim_data_pointer AnimData109 ; SPRITE_ANIM_109
- anim_data_pointer AnimData110 ; SPRITE_ANIM_110
- anim_data_pointer AnimData111 ; SPRITE_ANIM_111
- anim_data_pointer AnimData112 ; SPRITE_ANIM_112
- anim_data_pointer AnimData113 ; SPRITE_ANIM_113
- anim_data_pointer AnimData114 ; SPRITE_ANIM_114
- anim_data_pointer AnimData115 ; SPRITE_ANIM_115
- anim_data_pointer AnimData116 ; SPRITE_ANIM_116
- anim_data_pointer AnimData117 ; SPRITE_ANIM_117
- anim_data_pointer AnimData118 ; SPRITE_ANIM_118
- anim_data_pointer AnimData119 ; SPRITE_ANIM_119
- anim_data_pointer AnimData120 ; SPRITE_ANIM_120
- anim_data_pointer AnimData121 ; SPRITE_ANIM_121
- anim_data_pointer AnimData122 ; SPRITE_ANIM_122
- anim_data_pointer AnimData123 ; SPRITE_ANIM_123
- anim_data_pointer AnimData124 ; SPRITE_ANIM_124
- anim_data_pointer AnimData125 ; SPRITE_ANIM_125
- anim_data_pointer AnimData126 ; SPRITE_ANIM_126
- anim_data_pointer AnimData127 ; SPRITE_ANIM_127
- anim_data_pointer AnimData128 ; SPRITE_ANIM_128
- anim_data_pointer AnimData129 ; SPRITE_ANIM_129
- anim_data_pointer AnimData130 ; SPRITE_ANIM_130
- anim_data_pointer AnimData131 ; SPRITE_ANIM_131
- anim_data_pointer AnimData132 ; SPRITE_ANIM_132
- anim_data_pointer AnimData133 ; SPRITE_ANIM_133
- anim_data_pointer AnimData134 ; SPRITE_ANIM_134
- anim_data_pointer AnimData135 ; SPRITE_ANIM_135
- anim_data_pointer AnimData136 ; SPRITE_ANIM_136
- anim_data_pointer AnimData137 ; SPRITE_ANIM_137
- anim_data_pointer AnimData138 ; SPRITE_ANIM_138
- anim_data_pointer AnimData139 ; SPRITE_ANIM_139
- anim_data_pointer AnimData140 ; SPRITE_ANIM_140
- anim_data_pointer AnimData141 ; SPRITE_ANIM_141
- anim_data_pointer AnimData142 ; SPRITE_ANIM_142
- anim_data_pointer AnimData143 ; SPRITE_ANIM_143
- anim_data_pointer AnimData144 ; SPRITE_ANIM_144
- anim_data_pointer AnimData145 ; SPRITE_ANIM_145
- anim_data_pointer AnimData146 ; SPRITE_ANIM_146
- anim_data_pointer AnimData147 ; SPRITE_ANIM_147
- anim_data_pointer AnimData148 ; SPRITE_ANIM_148
- anim_data_pointer AnimData149 ; SPRITE_ANIM_149
- anim_data_pointer AnimData150 ; SPRITE_ANIM_150
- anim_data_pointer AnimData151 ; SPRITE_ANIM_151
- anim_data_pointer AnimData152 ; SPRITE_ANIM_152
- anim_data_pointer AnimData153 ; SPRITE_ANIM_153
- anim_data_pointer AnimData154 ; SPRITE_ANIM_154
- anim_data_pointer AnimData155 ; SPRITE_ANIM_155
- anim_data_pointer AnimData156 ; SPRITE_ANIM_156
- anim_data_pointer AnimData157 ; SPRITE_ANIM_157
- anim_data_pointer AnimData158 ; SPRITE_ANIM_158
- anim_data_pointer AnimData159 ; SPRITE_ANIM_159
- anim_data_pointer AnimData160 ; SPRITE_ANIM_160
- anim_data_pointer AnimData161 ; SPRITE_ANIM_161
- anim_data_pointer AnimData162 ; SPRITE_ANIM_162
- anim_data_pointer AnimData163 ; SPRITE_ANIM_163
- anim_data_pointer AnimData164 ; SPRITE_ANIM_164
- anim_data_pointer AnimData165 ; SPRITE_ANIM_165
- anim_data_pointer AnimData166 ; SPRITE_ANIM_166
- anim_data_pointer AnimData167 ; SPRITE_ANIM_167
- anim_data_pointer AnimData168 ; SPRITE_ANIM_168
- anim_data_pointer AnimData169 ; SPRITE_ANIM_169
- anim_data_pointer AnimData170 ; SPRITE_ANIM_170
- anim_data_pointer AnimData171 ; SPRITE_ANIM_171
- anim_data_pointer AnimData172 ; SPRITE_ANIM_172
- anim_data_pointer AnimData173 ; SPRITE_ANIM_173
- anim_data_pointer AnimData174 ; SPRITE_ANIM_174
- anim_data_pointer AnimData175 ; SPRITE_ANIM_175
- anim_data_pointer AnimData176 ; SPRITE_ANIM_176
- anim_data_pointer AnimData177 ; SPRITE_ANIM_177
- anim_data_pointer AnimData178 ; SPRITE_ANIM_178
- anim_data_pointer AnimData179 ; SPRITE_ANIM_179
- anim_data_pointer AnimData180 ; SPRITE_ANIM_180
- anim_data_pointer AnimData181 ; SPRITE_ANIM_181
- anim_data_pointer AnimData182 ; SPRITE_ANIM_182
- anim_data_pointer AnimData183 ; SPRITE_ANIM_183
- anim_data_pointer AnimData184 ; SPRITE_ANIM_184
- anim_data_pointer AnimData185 ; SPRITE_ANIM_185
- anim_data_pointer AnimData186 ; SPRITE_ANIM_186
- anim_data_pointer AnimData187 ; SPRITE_ANIM_187
- anim_data_pointer AnimData188 ; SPRITE_ANIM_188
- anim_data_pointer AnimData189 ; SPRITE_ANIM_189
- anim_data_pointer AnimData190 ; SPRITE_ANIM_190
- anim_data_pointer AnimData191 ; SPRITE_ANIM_191
- anim_data_pointer AnimData192 ; SPRITE_ANIM_192
- anim_data_pointer AnimData193 ; SPRITE_ANIM_193
- anim_data_pointer AnimData194 ; SPRITE_ANIM_194
- anim_data_pointer AnimData195 ; SPRITE_ANIM_195
- anim_data_pointer AnimData196 ; SPRITE_ANIM_196
- anim_data_pointer AnimData197 ; SPRITE_ANIM_197
- anim_data_pointer AnimData198 ; SPRITE_ANIM_198
- anim_data_pointer AnimData199 ; SPRITE_ANIM_199
- anim_data_pointer AnimData200 ; SPRITE_ANIM_200
- anim_data_pointer AnimData201 ; SPRITE_ANIM_201
- anim_data_pointer AnimData202 ; SPRITE_ANIM_202
- anim_data_pointer AnimData203 ; SPRITE_ANIM_203
- anim_data_pointer AnimData204 ; SPRITE_ANIM_204
- anim_data_pointer AnimData205 ; SPRITE_ANIM_205
- anim_data_pointer AnimData206 ; SPRITE_ANIM_206
- anim_data_pointer AnimData207 ; SPRITE_ANIM_207
- anim_data_pointer AnimData208 ; SPRITE_ANIM_208
- anim_data_pointer AnimData209 ; SPRITE_ANIM_209
- anim_data_pointer AnimData210 ; SPRITE_ANIM_210
- anim_data_pointer AnimData211 ; SPRITE_ANIM_211
- anim_data_pointer AnimData212 ; SPRITE_ANIM_212
- anim_data_pointer AnimData213 ; SPRITE_ANIM_213
- anim_data_pointer AnimData214 ; SPRITE_ANIM_214
- anim_data_pointer AnimData215 ; SPRITE_ANIM_215
- anim_data_pointer AnimData216 ; SPRITE_ANIM_216
-
-; \1 = palette pointer
-; \2 = number of palettes
-; \3 = number of OBJ colors
-palette_pointer: MACRO
- dwb \1, BANK(\1) - BANK(Palettes)
- db (\2 << 4) + \3
-ENDM
-
-Palettes: ; 81697 (20:5697)
- palette_pointer Palette0, 8, 1 ; PALETTE_0
- palette_pointer Palette1, 8, 0 ; PALETTE_1
- palette_pointer Palette2, 8, 0 ; PALETTE_2
- palette_pointer Palette3, 8, 0 ; PALETTE_3
- palette_pointer Palette4, 8, 0 ; PALETTE_4
- palette_pointer Palette5, 8, 0 ; PALETTE_5
- palette_pointer Palette6, 8, 0 ; PALETTE_6
- palette_pointer Palette7, 8, 0 ; PALETTE_7
- palette_pointer Palette8, 8, 0 ; PALETTE_8
- palette_pointer Palette9, 8, 0 ; PALETTE_9
- palette_pointer Palette10, 8, 0 ; PALETTE_10
- palette_pointer Palette11, 8, 0 ; PALETTE_11
- palette_pointer Palette12, 8, 0 ; PALETTE_12
- palette_pointer Palette13, 8, 0 ; PALETTE_13
- palette_pointer Palette14, 8, 0 ; PALETTE_14
- palette_pointer Palette15, 8, 0 ; PALETTE_15
- palette_pointer Palette16, 8, 0 ; PALETTE_16
- palette_pointer Palette17, 8, 0 ; PALETTE_17
- palette_pointer Palette18, 8, 0 ; PALETTE_18
- palette_pointer Palette19, 8, 0 ; PALETTE_19
- palette_pointer Palette20, 8, 0 ; PALETTE_20
- palette_pointer Palette21, 8, 0 ; PALETTE_21
- palette_pointer Palette22, 8, 0 ; PALETTE_22
- palette_pointer Palette23, 8, 0 ; PALETTE_23
- palette_pointer Palette24, 8, 0 ; PALETTE_24
- palette_pointer Palette25, 8, 0 ; PALETTE_25
- palette_pointer Palette26, 8, 0 ; PALETTE_26
- palette_pointer Palette27, 8, 0 ; PALETTE_27
- palette_pointer Palette28, 8, 0 ; PALETTE_28
- palette_pointer Palette29, 8, 2 ; PALETTE_29
- palette_pointer Palette30, 8, 2 ; PALETTE_30
- palette_pointer Palette31, 1, 1 ; PALETTE_31
- palette_pointer Palette32, 1, 1 ; PALETTE_32
- palette_pointer Palette33, 1, 1 ; PALETTE_33
- palette_pointer Palette34, 1, 1 ; PALETTE_34
- palette_pointer Palette35, 1, 1 ; PALETTE_35
- palette_pointer Palette36, 1, 1 ; PALETTE_36
- palette_pointer Palette37, 1, 1 ; PALETTE_37
- palette_pointer Palette38, 1, 1 ; PALETTE_38
- palette_pointer Palette39, 1, 1 ; PALETTE_39
- palette_pointer Palette40, 1, 1 ; PALETTE_40
- palette_pointer Palette41, 1, 1 ; PALETTE_41
- palette_pointer Palette42, 1, 1 ; PALETTE_42
- palette_pointer Palette43, 1, 1 ; PALETTE_43
- palette_pointer Palette44, 1, 1 ; PALETTE_44
- palette_pointer Palette45, 1, 1 ; PALETTE_45
- palette_pointer Palette46, 1, 1 ; PALETTE_46
- palette_pointer Palette47, 1, 1 ; PALETTE_47
- palette_pointer Palette48, 1, 1 ; PALETTE_48
- palette_pointer Palette49, 1, 1 ; PALETTE_49
- palette_pointer Palette50, 1, 1 ; PALETTE_50
- palette_pointer Palette51, 1, 1 ; PALETTE_51
- palette_pointer Palette52, 1, 1 ; PALETTE_52
- palette_pointer Palette53, 1, 1 ; PALETTE_53
- palette_pointer Palette54, 1, 1 ; PALETTE_54
- palette_pointer Palette55, 1, 1 ; PALETTE_55
- palette_pointer Palette56, 1, 1 ; PALETTE_56
- palette_pointer Palette57, 1, 1 ; PALETTE_57
- palette_pointer Palette58, 1, 1 ; PALETTE_58
- palette_pointer Palette59, 1, 1 ; PALETTE_59
- palette_pointer Palette60, 1, 1 ; PALETTE_60
- palette_pointer Palette61, 1, 1 ; PALETTE_61
- palette_pointer Palette62, 1, 1 ; PALETTE_62
- palette_pointer Palette63, 1, 1 ; PALETTE_63
- palette_pointer Palette64, 1, 1 ; PALETTE_64
- palette_pointer Palette65, 1, 1 ; PALETTE_65
- palette_pointer Palette66, 1, 1 ; PALETTE_66
- palette_pointer Palette67, 1, 1 ; PALETTE_67
- palette_pointer Palette68, 1, 1 ; PALETTE_68
- palette_pointer Palette69, 1, 1 ; PALETTE_69
- palette_pointer Palette70, 1, 1 ; PALETTE_70
- palette_pointer Palette71, 1, 1 ; PALETTE_71
- palette_pointer Palette72, 1, 1 ; PALETTE_72
- palette_pointer Palette73, 1, 1 ; PALETTE_73
- palette_pointer Palette74, 1, 1 ; PALETTE_74
- palette_pointer Palette75, 1, 1 ; PALETTE_75
- palette_pointer Palette76, 1, 1 ; PALETTE_76
- palette_pointer Palette77, 1, 1 ; PALETTE_77
- palette_pointer Palette78, 1, 1 ; PALETTE_78
- palette_pointer Palette79, 1, 1 ; PALETTE_79
- palette_pointer Palette80, 1, 1 ; PALETTE_80
- palette_pointer Palette81, 1, 1 ; PALETTE_81
- palette_pointer Palette82, 1, 1 ; PALETTE_82
- palette_pointer Palette83, 1, 1 ; PALETTE_83
- palette_pointer Palette84, 1, 1 ; PALETTE_84
- palette_pointer Palette85, 1, 1 ; PALETTE_85
- palette_pointer Palette86, 1, 1 ; PALETTE_86
- palette_pointer Palette87, 1, 1 ; PALETTE_87
- palette_pointer Palette88, 1, 1 ; PALETTE_88
- palette_pointer Palette89, 1, 1 ; PALETTE_89
- palette_pointer Palette90, 1, 1 ; PALETTE_90
- palette_pointer Palette91, 1, 1 ; PALETTE_91
- palette_pointer Palette92, 1, 1 ; PALETTE_92
- palette_pointer Palette93, 1, 1 ; PALETTE_93
- palette_pointer Palette94, 8, 0 ; PALETTE_94
- palette_pointer Palette95, 8, 0 ; PALETTE_95
- palette_pointer Palette96, 8, 0 ; PALETTE_96
- palette_pointer Palette97, 8, 0 ; PALETTE_97
- palette_pointer Palette98, 8, 0 ; PALETTE_98
- palette_pointer Palette99, 8, 0 ; PALETTE_99
- palette_pointer Palette100, 8, 0 ; PALETTE_100
- palette_pointer Palette101, 7, 0 ; PALETTE_101
- palette_pointer Palette102, 7, 0 ; PALETTE_102
- palette_pointer Palette103, 7, 0 ; PALETTE_103
- palette_pointer Palette104, 7, 0 ; PALETTE_104
- palette_pointer Palette105, 7, 0 ; PALETTE_105
- palette_pointer Palette106, 7, 0 ; PALETTE_106
- palette_pointer Palette107, 7, 0 ; PALETTE_107
- palette_pointer Palette108, 0, 1 ; PALETTE_108
- palette_pointer Palette109, 0, 1 ; PALETTE_109
- palette_pointer Palette110, 0, 0 ; PALETTE_110
- palette_pointer Palette111, 8, 1 ; PALETTE_111
- palette_pointer Palette112, 8, 1 ; PALETTE_112
- palette_pointer Palette113, 8, 1 ; PALETTE_113
- palette_pointer Palette114, 4, 2 ; PALETTE_114
- palette_pointer Palette115, 4, 2 ; PALETTE_115
- palette_pointer Palette116, 4, 2 ; PALETTE_116
- palette_pointer Palette117, 1, 0 ; PALETTE_117
- palette_pointer Palette118, 6, 0 ; PALETTE_118
- palette_pointer Palette119, 1, 0 ; PALETTE_119
- palette_pointer Palette120, 1, 0 ; PALETTE_120
- palette_pointer Palette121, 1, 0 ; PALETTE_121
- palette_pointer Palette122, 1, 0 ; PALETTE_122
- palette_pointer Palette123, 1, 0 ; PALETTE_123
- palette_pointer Palette124, 1, 0 ; PALETTE_124
- palette_pointer Palette125, 1, 0 ; PALETTE_125
- palette_pointer Palette126, 1, 0 ; PALETTE_126
- palette_pointer Palette127, 1, 0 ; PALETTE_127
- palette_pointer Palette128, 1, 0 ; PALETTE_128
- palette_pointer Palette129, 1, 0 ; PALETTE_129
- palette_pointer Palette130, 1, 0 ; PALETTE_130
- palette_pointer Palette131, 1, 0 ; PALETTE_131
- palette_pointer Palette132, 1, 0 ; PALETTE_132
- palette_pointer Palette133, 1, 0 ; PALETTE_133
- palette_pointer Palette134, 1, 0 ; PALETTE_134
- palette_pointer Palette135, 1, 0 ; PALETTE_135
- palette_pointer Palette136, 1, 0 ; PALETTE_136
- palette_pointer Palette137, 1, 0 ; PALETTE_137
- palette_pointer Palette138, 1, 0 ; PALETTE_138
- palette_pointer Palette139, 1, 0 ; PALETTE_139
- palette_pointer Palette140, 1, 0 ; PALETTE_140
- palette_pointer Palette141, 1, 0 ; PALETTE_141
- palette_pointer Palette142, 1, 0 ; PALETTE_142
- palette_pointer Palette143, 1, 0 ; PALETTE_143
- palette_pointer Palette144, 1, 0 ; PALETTE_144
- palette_pointer Palette145, 1, 0 ; PALETTE_145
- palette_pointer Palette146, 1, 0 ; PALETTE_146
- palette_pointer Palette147, 1, 0 ; PALETTE_147
- palette_pointer Palette148, 1, 0 ; PALETTE_148
- palette_pointer Palette149, 1, 0 ; PALETTE_149
- palette_pointer Palette150, 1, 0 ; PALETTE_150
- palette_pointer Palette151, 1, 0 ; PALETTE_151
- palette_pointer Palette152, 1, 0 ; PALETTE_152
- palette_pointer Palette153, 1, 0 ; PALETTE_153
- palette_pointer Palette154, 1, 0 ; PALETTE_154
- palette_pointer Palette155, 1, 0 ; PALETTE_155
- palette_pointer Palette156, 1, 0 ; PALETTE_156
- palette_pointer Palette157, 1, 0 ; PALETTE_157
- palette_pointer Palette158, 1, 0 ; PALETTE_158
- palette_pointer Palette159, 1, 0 ; PALETTE_159
- palette_pointer Palette160, 1, 0 ; PALETTE_160
-
-OverworldMapTilemap:: ; 8191b (20:591b)
- db $14 ; width
- db $12 ; height
- dw NULL
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/overworld_map.bin"
-
-OverworldMapCGBTilemap:: ; 81a22 (20:5a22)
- db $14 ; width
- db $12 ; height
- dw NULL
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/overworld_map_cgb.bin"
-
-MasonLaboratoryTilemap:: ; 81c13 (20:5c13)
- db $1c ; width
- db $1e ; height
- dw MasonLaboratoryPermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/mason_laboratory.bin"
-MasonLaboratoryPermissions:
- INCBIN "data/maps/permissions/mason_laboratory.bin"
-
-MasonLaboratoryCGBTilemap:: ; 81d2e (20:5d2e)
- db $1c ; width
- db $1e ; height
- dw MasonLaboratoryCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/mason_laboratory_cgb.bin"
-MasonLaboratoryCGBPermissions:
- INCBIN "data/maps/permissions/mason_laboratory_cgb.bin"
-
-ChallengeMachineMapEventTilemap:: ; 81ed1 (20:5ed1)
- db $04 ; width
- db $06 ; height
- dw ChallengeMachineMapEventPermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/challenge_machine_map_event.bin"
-ChallengeMachineMapEventPermissions:
- INCBIN "data/maps/permissions/challenge_machine_map_event.bin"
-
-ChallengeMachineMapEventCGBTilemap:: ; 81ef5 (20:5ef5)
- db $04 ; width
- db $06 ; height
- dw ChallengeMachineMapEventCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/challenge_machine_map_event_cgb.bin"
-ChallengeMachineMapEventCGBPermissions:
- INCBIN "data/maps/permissions/challenge_machine_map_event_cgb.bin"
-
-DeckMachineRoomTilemap:: ; 81f26 (20:5f26)
- db $18 ; width
- db $1e ; height
- dw DeckMachineRoomPermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/deck_machine_room.bin"
-DeckMachineRoomPermissions:
- INCBIN "data/maps/permissions/deck_machine_room.bin"
-
-DeckMachineRoomCGBTilemap:: ; 81feb (20:5feb)
- db $18 ; width
- db $1e ; height
- dw DeckMachineRoomCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/deck_machine_room_cgb.bin"
-DeckMachineRoomCGBPermissions:
- INCBIN "data/maps/permissions/deck_machine_room_cgb.bin"
-
-DeckMachineMapEventTilemap:: ; 82143 (20:6143)
- db $04 ; width
- db $01 ; height
- dw DeckMachineMapEventPermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/deck_machine_map_event.bin"
-DeckMachineMapEventPermissions:
- INCBIN "data/maps/permissions/deck_machine_map_event.bin"
-
-DeckMachineMapEventCGBTilemap:: ; 82150 (20:6150)
- db $04 ; width
- db $01 ; height
- dw DeckMachineMapEventCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/deck_machine_map_event_cgb.bin"
-DeckMachineMapEventCGBPermissions:
- INCBIN "data/maps/permissions/deck_machine_map_event_cgb.bin"
-
-IshiharaTilemap:: ; 82160 (20:6160)
- db $14 ; width
- db $18 ; height
- dw IshiharaPermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/ishihara.bin"
-IshiharaPermissions:
- INCBIN "data/maps/permissions/ishihara.bin"
-
-IshiharaCGBTilemap:: ; 82222 (20:6222)
- db $14 ; width
- db $18 ; height
- dw IshiharaCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/ishihara_cgb.bin"
-IshiharaCGBPermissions:
- INCBIN "data/maps/permissions/ishihara_cgb.bin"
-
-FightingClubEntranceTilemap:: ; 82336 (20:6336)
- db $14 ; width
- db $12 ; height
- dw FightingClubEntrancePermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/fighting_club_entrance.bin"
-FightingClubEntrancePermissions:
- INCBIN "data/maps/permissions/fighting_club_entrance.bin"
-
-FightingClubEntranceCGBTilemap:: ; 82400 (20:6400)
- db $14 ; width
- db $12 ; height
- dw FightingClubEntranceCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/fighting_club_entrance_cgb.bin"
-FightingClubEntranceCGBPermissions:
- INCBIN "data/maps/permissions/fighting_club_entrance_cgb.bin"
-
-RockClubEntranceTilemap:: ; 8251d (20:651d)
- db $14 ; width
- db $12 ; height
- dw RockClubEntrancePermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/rock_club_entrance.bin"
-RockClubEntrancePermissions:
- INCBIN "data/maps/permissions/rock_club_entrance.bin"
-
-RockClubEntranceCGBTilemap:: ; 825e7 (20:65e7)
- db $14 ; width
- db $12 ; height
- dw RockClubEntranceCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/rock_club_entrance_cgb.bin"
-RockClubEntranceCGBPermissions:
- INCBIN "data/maps/permissions/rock_club_entrance_cgb.bin"
-
-WaterClubEntranceTilemap:: ; 82704 (20:6704)
- db $14 ; width
- db $12 ; height
- dw WaterClubEntrancePermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/water_club_entrance.bin"
-WaterClubEntrancePermissions:
- INCBIN "data/maps/permissions/water_club_entrance.bin"
-
-WaterClubEntranceCGBTilemap:: ; 827ce (20:67ce)
- db $14 ; width
- db $12 ; height
- dw WaterClubEntranceCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/water_club_entrance_cgb.bin"
-WaterClubEntranceCGBPermissions:
- INCBIN "data/maps/permissions/water_club_entrance_cgb.bin"
-
-LightningClubEntranceTilemap:: ; 828eb (20:68eb)
- db $14 ; width
- db $12 ; height
- dw LightningClubEntrancePermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/lightning_club_entrance.bin"
-LightningClubEntrancePermissions:
- INCBIN "data/maps/permissions/lightning_club_entrance.bin"
-
-LightningClubEntranceCGBTilemap:: ; 829b5 (20:69b5)
- db $14 ; width
- db $12 ; height
- dw LightningClubEntranceCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/lightning_club_entrance_cgb.bin"
-LightningClubEntranceCGBPermissions:
- INCBIN "data/maps/permissions/lightning_club_entrance_cgb.bin"
-
-GrassClubEntranceTilemap:: ; 82ad2 (20:6ad2)
- db $14 ; width
- db $12 ; height
- dw GrassClubEntrancePermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/grass_club_entrance.bin"
-GrassClubEntrancePermissions:
- INCBIN "data/maps/permissions/grass_club_entrance.bin"
-
-GrassClubEntranceCGBTilemap:: ; 82b9c (20:6b9c)
- db $14 ; width
- db $12 ; height
- dw GrassClubEntranceCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/grass_club_entrance_cgb.bin"
-GrassClubEntranceCGBPermissions:
- INCBIN "data/maps/permissions/grass_club_entrance_cgb.bin"
-
-PsychicClubEntranceTilemap:: ; 82cb9 (20:6cb9)
- db $14 ; width
- db $12 ; height
- dw PsychicClubEntrancePermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/psychic_club_entrance.bin"
-PsychicClubEntrancePermissions:
- INCBIN "data/maps/permissions/psychic_club_entrance.bin"
-
-PsychicClubEntranceCGBTilemap:: ; 82d83 (20:6d83)
- db $14 ; width
- db $12 ; height
- dw PsychicClubEntranceCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/psychic_club_entrance_cgb.bin"
-PsychicClubEntranceCGBPermissions:
- INCBIN "data/maps/permissions/psychic_club_entrance_cgb.bin"
-
-ScienceClubEntranceTilemap:: ; 82ea0 (20:6ea0)
- db $14 ; width
- db $12 ; height
- dw ScienceClubEntrancePermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/science_club_entrance.bin"
-ScienceClubEntrancePermissions:
- INCBIN "data/maps/permissions/science_club_entrance.bin"
-
-ScienceClubEntranceCGBTilemap:: ; 82f6a (20:6f6a)
- db $14 ; width
- db $12 ; height
- dw ScienceClubEntranceCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/science_club_entrance_cgb.bin"
-ScienceClubEntranceCGBPermissions:
- INCBIN "data/maps/permissions/science_club_entrance_cgb.bin"
-
-FireClubEntranceTilemap:: ; 83087 (20:7087)
- db $14 ; width
- db $12 ; height
- dw FireClubEntrancePermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/fire_club_entrance.bin"
-FireClubEntrancePermissions:
- INCBIN "data/maps/permissions/fire_club_entrance.bin"
-
-FireClubEntranceCGBTilemap:: ; 83151 (20:7151)
- db $14 ; width
- db $12 ; height
- dw FireClubEntranceCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/fire_club_entrance_cgb.bin"
-FireClubEntranceCGBPermissions:
- INCBIN "data/maps/permissions/fire_club_entrance_cgb.bin"
-
-ChallengeHallEntranceTilemap:: ; 8326e (20:726e)
- db $14 ; width
- db $12 ; height
- dw ChallengeHallEntrancePermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/challenge_hall_entrance.bin"
-ChallengeHallEntrancePermissions:
- INCBIN "data/maps/permissions/challenge_hall_entrance.bin"
-
-ChallengeHallEntranceCGBTilemap:: ; 83321 (20:7321)
- db $14 ; width
- db $12 ; height
- dw ChallengeHallEntranceCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/challenge_hall_entrance_cgb.bin"
-ChallengeHallEntranceCGBPermissions:
- INCBIN "data/maps/permissions/challenge_hall_entrance_cgb.bin"
-
-ClubLobbyTilemap:: ; 83424 (20:7424)
- db $1c ; width
- db $1a ; height
- dw ClubLobbyPermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/club_lobby.bin"
-ClubLobbyPermissions:
- INCBIN "data/maps/permissions/club_lobby.bin"
-
-ClubLobbyCGBTilemap:: ; 83545 (20:7545)
- db $1c ; width
- db $1a ; height
- dw ClubLobbyCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/club_lobby_cgb.bin"
-ClubLobbyCGBPermissions:
- INCBIN "data/maps/permissions/club_lobby_cgb.bin"
-
-FightingClubTilemap:: ; 836db (20:76db)
- db $18 ; width
- db $12 ; height
- dw FightingClubPermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/fighting_club.bin"
-FightingClubPermissions:
- INCBIN "data/maps/permissions/fighting_club.bin"
-
-FightingClubCGBTilemap:: ; 8378c (20:778c)
- db $18 ; width
- db $12 ; height
- dw FightingClubCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/fighting_club_cgb.bin"
-FightingClubCGBPermissions:
- INCBIN "data/maps/permissions/fighting_club_cgb.bin"
-
-RockClubTilemap:: ; 8388d (20:788d)
- db $1c ; width
- db $1e ; height
- dw RockClubPermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/rock_club.bin"
-RockClubPermissions:
- INCBIN "data/maps/permissions/rock_club.bin"
-
-RockClubCGBTilemap:: ; 839d6 (20:79d6)
- db $1c ; width
- db $1e ; height
- dw RockClubCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/rock_club_cgb.bin"
-RockClubCGBPermissions:
- INCBIN "data/maps/permissions/rock_club_cgb.bin"
-
-PokemonDomeDoorMapEventTilemap:: ; 83bf1 (20:7bf1)
- db $04 ; width
- db $03 ; height
- dw PokemonDomeDoorMapEventPermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/pokemon_dome_door_map_event.bin"
-PokemonDomeDoorMapEventPermissions:
- INCBIN "data/maps/permissions/pokemon_dome_door_map_event.bin"
-
-PokemonDomeDoorMapEventCGBTilemap:: ; 83c03 (20:7c03)
- db $04 ; width
- db $03 ; height
- dw PokemonDomeDoorMapEventCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/pokemon_dome_door_map_event_cgb.bin"
-PokemonDomeDoorMapEventCGBPermissions:
- INCBIN "data/maps/permissions/pokemon_dome_door_map_event_cgb.bin"
-
-HallOfHonorDoorMapEventTilemap:: ; 83c1a (20:7c1a)
- db $04 ; width
- db $03 ; height
- dw HallOfHonorDoorMapEventPermissions
- db FALSE ; cgb mode
- INCBIN "data/maps/tiles/hall_of_honor_door_map_event.bin"
-HallOfHonorDoorMapEventPermissions:
- INCBIN "data/maps/permissions/hall_of_honor_door_map_event.bin"
-
-HallOfHonorDoorMapEventCGBTilemap:: ; 83c26 (20:7c26)
- db $04 ; width
- db $03 ; height
- dw HallOfHonorDoorMapEventCGBPermissions
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/hall_of_honor_door_map_event_cgb.bin"
-HallOfHonorDoorMapEventCGBPermissions:
- INCBIN "data/maps/permissions/hall_of_honor_door_map_event_cgb.bin"
-
-GrassMedalTilemap:: ; 83c36 (20:7c36)
- db $03 ; width
- db $03 ; height
- dw NULL
- db TRUE ; cgb mode
- INCBIN "data/maps/tiles/grass_medal.bin"
-
-AnimData1:: ; 83c4c (20:7c4c)
- frame_table AnimFrameTable0
- frame_data 3, 16, 0, 0
- frame_data 4, 16, 0, 0
- frame_data 0, 0, 0, 0
-
-Palette110:: ; 83c5b (20:7c5b)
- db $00, $00
diff --git a/src/engine/copy_card_name.asm b/src/engine/copy_card_name.asm
new file mode 100644
index 0000000..feb33ca
--- /dev/null
+++ b/src/engine/copy_card_name.asm
@@ -0,0 +1,152 @@
+; copy the name and level of the card at wLoadedCard1 to wDefaultText
+; a = length in number of tiles (the resulting string will be padded with spaces to match it)
+_CopyCardNameAndLevel:
+ push bc
+ push de
+ ld [wCardNameLength], a
+ ld hl, wLoadedCard1Name
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wDefaultText
+ push de
+ call CopyText ; copy card name to wDefaultText
+ pop hl
+ ld a, [hli]
+ cp TX_HALFWIDTH
+ jp z, _CopyCardNameAndLevel_HalfwidthText
+
+; the name doesn't start with TX_HALFWIDTH
+; this doesn't appear to be ever the case (unless caller manipulates wLoadedCard1Name)
+ ld a, [wCardNameLength]
+ ld c, a
+ ld a, [wLoadedCard1Type]
+ cp TYPE_ENERGY
+ jr nc, .level_done ; jump if energy or trainer
+ ld a, [wLoadedCard1Level]
+ or a
+ jr z, .level_done
+ inc c
+ inc c
+ ld a, [wLoadedCard1Level]
+ cp 10
+ jr c, .level_done
+ inc c ; second digit
+.level_done
+ ld hl, wLoadedCard1Name
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wDefaultText
+ push de
+ call CopyText
+ pop hl
+ push de
+ ld e, c
+ call GetTextLengthInTiles
+ add e
+ ld c, a
+ pop hl
+ push hl
+.fill_loop
+ ld a, $70
+ ld [hli], a
+ dec c
+ jr nz, .fill_loop
+ ld [hl], TX_END
+ pop hl
+ ld a, [wLoadedCard1Type]
+ cp TYPE_ENERGY
+ jr nc, .done
+ ld a, [wLoadedCard1Level]
+ or a
+ jr z, .done
+ ld a, TX_SYMBOL
+ ld [hli], a
+ ld [hl], SYM_Lv
+ inc hl
+ ld a, [wLoadedCard1Level]
+ cp 10
+ jr c, .one_digit
+ ld [hl], TX_SYMBOL
+ inc hl
+ ld b, SYM_0 - 1
+.first_digit_loop
+ inc b
+ sub 10
+ jr nc, .first_digit_loop
+ add 10
+ ld [hl], b ; first digit
+ inc hl
+.one_digit
+ ld [hl], TX_SYMBOL
+ inc hl
+ add SYM_0
+ ld [hl], a ; last (or only) digit
+ inc hl
+.done
+ pop de
+ pop bc
+ ret
+
+; the name starts with TX_HALFWIDTH
+_CopyCardNameAndLevel_HalfwidthText:
+ ld a, [wCardNameLength]
+ inc a
+ add a
+ ld b, a
+ ld hl, wDefaultText
+.find_end_text_loop
+ dec b
+ ld a, [hli]
+ or a ; TX_END
+ jr nz, .find_end_text_loop
+ dec hl
+ ld a, [wLoadedCard1Type]
+ cp TYPE_ENERGY
+ jr nc, .level_done
+ ld a, [wLoadedCard1Level]
+ or a
+ jr z, .level_done
+ ld c, a
+ ld a, " "
+ ld [hli], a
+ dec b
+ ld a, "L"
+ ld [hli], a
+ dec b
+ ld a, "v"
+ ld [hli], a
+ dec b
+ ld a, c
+ cp 10
+ jr c, .got_level
+ push bc
+ ld b, "0" - 1
+.first_digit_loop
+ inc b
+ sub 10
+ jr nc, .first_digit_loop
+ add 10
+ ld [hl], b ; first digit
+ inc hl
+ pop bc
+ ld c, a
+ dec b
+.got_level
+ ld a, c
+ add "0"
+ ld [hli], a ; last (or only) digit
+ dec b
+.level_done
+ push hl
+ ld a, " "
+.fill_spaces_loop
+ ld [hli], a
+ dec b
+ jr nz, .fill_spaces_loop
+ ld [hl], TX_END
+ pop hl
+ pop de
+ pop bc
+ ret
diff --git a/src/engine/credits.asm b/src/engine/credits.asm
new file mode 100644
index 0000000..8ead323
--- /dev/null
+++ b/src/engine/credits.asm
@@ -0,0 +1,189 @@
+PlayCreditsSequence:
+ ld a, MUSIC_STOP
+ call PlaySong
+ call Func_1d705
+ call AddAllMastersToMastersBeatenList
+ xor a
+ ld [wOWMapEvents + 1], a
+ ld a, MUSIC_CREDITS
+ call PlaySong
+ farcall FlashWhiteScreen
+ call SetCreditsSequenceCmdPtr
+.asm_1d6c8
+ call DoFrameIfLCDEnabled
+ call Func_1d765
+ call ExecuteCreditsSequenceCmd
+ ld a, [wSequenceDelay]
+ cp $ff
+ jr nz, .asm_1d6c8
+ call WaitForSongToFinish
+ ld a, $8
+ farcall Func_12863
+ ld a, MUSIC_STOP
+ call PlaySong
+ farcall Func_10ab4
+ call Func_3ca4
+ call SetWindowOff
+ call Func_1d758
+ call EnableLCD
+ call DoFrameIfLCDEnabled
+ call DisableLCD
+ ld hl, wLCDC
+ set 1, [hl]
+ call ResetDoFrameFunction
+ ret
+
+Func_1d705:
+ call DisableLCD
+ farcall Func_10a9b
+ call Func_3ca0
+ farcall Func_10000
+ call Func_1d7ee
+ ld hl, Func_3e31
+ call SetDoFrameFunction
+ call .Func_1d720 ; can be fallthrough
+ ret
+
+.Func_1d720
+ ld a, $91
+ ld [wd647], a
+ ld [wd649], a
+ ld a, $01
+ ld [wd648], a
+ ld [wd64a], a
+ call Func_1d765
+ call SetWindowOn
+ call .Func_1d73a ; can be fallthrough
+ ret
+
+.Func_1d73a
+ push hl
+ di
+ xor a
+ ld [wd657], a
+ ld hl, wLCDCFunctionTrampoline + 1
+ ld [hl], LOW(Func_3e44)
+ inc hl
+ ld [hl], HIGH(Func_3e44)
+ ei
+
+ ld hl, rSTAT
+ set STAT_LYC, [hl]
+ xor a
+ ldh [rLYC], a
+ ld hl, rIE
+ set INT_LCD_STAT, [hl]
+ pop hl
+ ret
+
+Func_1d758:
+ push hl
+ ld hl, rSTAT
+ res STAT_LYC, [hl]
+ ld hl, rIE
+ res INT_LCD_STAT, [hl]
+ pop hl
+ ret
+
+Func_1d765:
+ push hl
+ push bc
+ push de
+ xor a
+ ldh [hWY], a
+
+ ld hl, wd659
+ ld de, wd65f
+ ld a, [wd648]
+ or a
+ jr nz, .asm_1d785
+ ld a, $a7
+ ldh [hWX], a
+ ld [hli], a
+ push hl
+ ld hl, wLCDC
+ set 1, [hl]
+ pop hl
+ jr .asm_1d7e2
+
+.asm_1d785
+ ld a, [wd647]
+ or a
+ jr z, .asm_1d79e
+ dec a
+ ld [de], a
+ inc de
+ ld a, $a7
+ ldh [hWX], a
+ ld [hli], a
+ push hl
+ ld hl, wLCDC
+ set 1, [hl]
+ pop hl
+ ld a, $07
+ jr .asm_1d7a9
+
+.asm_1d79e
+ ld a, $07
+ ldh [hWX], a
+ push hl
+ ld hl, wLCDC
+ res 1, [hl]
+ pop hl
+.asm_1d7a9
+ ld [hli], a
+ ld a, [wd647]
+ dec a
+ ld c, a
+ ld a, [wd648]
+ add c
+ ld c, a
+ ld a, [wd649]
+ dec a
+ cp c
+ jr c, .asm_1d7d4
+ jr z, .asm_1d7d4
+ ld a, c
+ ld [de], a
+ inc de
+ push af
+ ld a, $a7
+ ld [hli], a
+ pop bc
+ ld a, [wd64a]
+ or a
+ jr z, .asm_1d7e2
+ ld a, [wd649]
+ dec a
+ ld [de], a
+ inc de
+ ld a, $07
+ ld [hli], a
+
+.asm_1d7d4
+ ld a, [wd649]
+ dec a
+ ld c, a
+ ld a, [wd64a]
+ add c
+ ld [de], a
+ inc de
+ ld a, $a7
+ ld [hli], a
+.asm_1d7e2
+ ld a, $ff
+ ld [de], a
+ ld a, $01
+ ld [wd665], a
+ pop de
+ pop bc
+ pop hl
+ ret
+
+Func_1d7ee:
+ xor a
+ lb de, 0, 32
+ lb bc, 20, 18
+ lb hl, 0, 0
+ call FillRectangle
+ ret
diff --git a/src/engine/ai/attacks.asm b/src/engine/duel/ai/attacks.asm
index 69ae2e1..69ae2e1 100644
--- a/src/engine/ai/attacks.asm
+++ b/src/engine/duel/ai/attacks.asm
diff --git a/src/engine/ai/boss_deck_set_up.asm b/src/engine/duel/ai/boss_deck_set_up.asm
index ebcd2ea..ebcd2ea 100644
--- a/src/engine/ai/boss_deck_set_up.asm
+++ b/src/engine/duel/ai/boss_deck_set_up.asm
diff --git a/src/engine/ai/common.asm b/src/engine/duel/ai/common.asm
index d4f1da4..d4f1da4 100644
--- a/src/engine/ai/common.asm
+++ b/src/engine/duel/ai/common.asm
diff --git a/src/engine/ai/core.asm b/src/engine/duel/ai/core.asm
index f182375..9604322 100644
--- a/src/engine/ai/core.asm
+++ b/src/engine/duel/ai/core.asm
@@ -1,4 +1,4 @@
-INCLUDE "engine/ai/decks/unreferenced.asm"
+INCLUDE "engine/duel/ai/decks/unreferenced.asm"
; returns carry if damage dealt from any of
; a card's attacks KOs defending Pokémon
@@ -707,13 +707,13 @@ LookForCardIDInHand: ; 143bf (5:43bf)
or a
ret
-INCLUDE "engine/ai/damage_calculation.asm"
+INCLUDE "engine/duel/ai/damage_calculation.asm"
AIProcessHandTrainerCards: ; 14663 (5:4663)
farcall _AIProcessHandTrainerCards
ret
-INCLUDE "engine/ai/deck_ai.asm"
+INCLUDE "engine/duel/ai/deck_ai.asm"
; return carry if card ID loaded in a is found in hand
; and outputs in a the deck index of that card
@@ -815,7 +815,7 @@ AIAttachEnergyInHandToCardInBench: ; 1562b (5:562b)
ld b, PLAY_AREA_BENCH_1
jr AIAttachEnergyInHandToCardInPlayArea.attach
-INCLUDE "engine/ai/init.asm"
+INCLUDE "engine/duel/ai/init.asm"
; load selected attack from Pokémon in hTempPlayAreaLocation_ff9d,
; gets an energy card to discard and subsequently
@@ -1306,7 +1306,7 @@ Func_15886: ; 15886 (5:5886)
inc hl
jr .loop_energy_cards
-INCLUDE "engine/ai/retreat.asm"
+INCLUDE "engine/duel/ai/retreat.asm"
; Copy cards from wDuelTempList in hl to wHandTempList in de
CopyHandCardList: ; 15ea6 (5:5ea6)
@@ -1317,7 +1317,7 @@ CopyHandCardList: ; 15ea6 (5:5ea6)
inc de
jr CopyHandCardList
-INCLUDE "engine/ai/hand_pokemon.asm"
+INCLUDE "engine/duel/ai/hand_pokemon.asm"
; check if player's active Pokémon is Mr Mime
; if it isn't, set carry
@@ -1804,11 +1804,11 @@ CheckForEvolutionInDeck: ; 16451 (5:6451)
scf
ret
-INCLUDE "engine/ai/energy.asm"
+INCLUDE "engine/duel/ai/energy.asm"
-INCLUDE "engine/ai/attacks.asm"
+INCLUDE "engine/duel/ai/attacks.asm"
-INCLUDE "engine/ai/special_attacks.asm"
+INCLUDE "engine/duel/ai/special_attacks.asm"
; checks in other Play Area for non-basic cards.
; afterwards, that card is checked for damage,
@@ -2285,7 +2285,7 @@ CheckCardEvolutionInHandOrDeck: ; 17274 (5:7274)
scf
ret
-INCLUDE "engine/ai/boss_deck_set_up.asm"
+INCLUDE "engine/duel/ai/boss_deck_set_up.asm"
; returns carry if Pokemon at PLAY_AREA* in a
; can damage defending Pokémon with any of its attacks
diff --git a/src/engine/ai/damage_calculation.asm b/src/engine/duel/ai/damage_calculation.asm
index 97c24b6..97c24b6 100644
--- a/src/engine/ai/damage_calculation.asm
+++ b/src/engine/duel/ai/damage_calculation.asm
diff --git a/src/engine/ai/deck_ai.asm b/src/engine/duel/ai/deck_ai.asm
index c330418..b46de01 100644
--- a/src/engine/ai/deck_ai.asm
+++ b/src/engine/duel/ai/deck_ai.asm
@@ -61,22 +61,22 @@ ENDM
; wAICardListRetreatBonus : scores given to certain cards for retreat;
; wAICardListEnergyBonus : max number of energy cards and card scores.
-INCLUDE "engine/ai/decks/general.asm"
-INCLUDE "engine/ai/decks/sams_practice.asm"
-INCLUDE "engine/ai/decks/general_no_retreat.asm"
-INCLUDE "engine/ai/decks/legendary_moltres.asm"
-INCLUDE "engine/ai/decks/legendary_zapdos.asm"
-INCLUDE "engine/ai/decks/legendary_articuno.asm"
-INCLUDE "engine/ai/decks/legendary_dragonite.asm"
-INCLUDE "engine/ai/decks/first_strike.asm"
-INCLUDE "engine/ai/decks/rock_crusher.asm"
-INCLUDE "engine/ai/decks/go_go_rain_dance.asm"
-INCLUDE "engine/ai/decks/zapping_selfdestruct.asm"
-INCLUDE "engine/ai/decks/flower_power.asm"
-INCLUDE "engine/ai/decks/strange_psyshock.asm"
-INCLUDE "engine/ai/decks/wonders_of_science.asm"
-INCLUDE "engine/ai/decks/fire_charge.asm"
-INCLUDE "engine/ai/decks/im_ronald.asm"
-INCLUDE "engine/ai/decks/powerful_ronald.asm"
-INCLUDE "engine/ai/decks/invincible_ronald.asm"
-INCLUDE "engine/ai/decks/legendary_ronald.asm"
+INCLUDE "engine/duel/ai/decks/general.asm"
+INCLUDE "engine/duel/ai/decks/sams_practice.asm"
+INCLUDE "engine/duel/ai/decks/general_no_retreat.asm"
+INCLUDE "engine/duel/ai/decks/legendary_moltres.asm"
+INCLUDE "engine/duel/ai/decks/legendary_zapdos.asm"
+INCLUDE "engine/duel/ai/decks/legendary_articuno.asm"
+INCLUDE "engine/duel/ai/decks/legendary_dragonite.asm"
+INCLUDE "engine/duel/ai/decks/first_strike.asm"
+INCLUDE "engine/duel/ai/decks/rock_crusher.asm"
+INCLUDE "engine/duel/ai/decks/go_go_rain_dance.asm"
+INCLUDE "engine/duel/ai/decks/zapping_selfdestruct.asm"
+INCLUDE "engine/duel/ai/decks/flower_power.asm"
+INCLUDE "engine/duel/ai/decks/strange_psyshock.asm"
+INCLUDE "engine/duel/ai/decks/wonders_of_science.asm"
+INCLUDE "engine/duel/ai/decks/fire_charge.asm"
+INCLUDE "engine/duel/ai/decks/im_ronald.asm"
+INCLUDE "engine/duel/ai/decks/powerful_ronald.asm"
+INCLUDE "engine/duel/ai/decks/invincible_ronald.asm"
+INCLUDE "engine/duel/ai/decks/legendary_ronald.asm"
diff --git a/src/engine/ai/decks/fire_charge.asm b/src/engine/duel/ai/decks/fire_charge.asm
index f5b347b..f5b347b 100644
--- a/src/engine/ai/decks/fire_charge.asm
+++ b/src/engine/duel/ai/decks/fire_charge.asm
diff --git a/src/engine/ai/decks/first_strike.asm b/src/engine/duel/ai/decks/first_strike.asm
index 2e636e1..2e636e1 100644
--- a/src/engine/ai/decks/first_strike.asm
+++ b/src/engine/duel/ai/decks/first_strike.asm
diff --git a/src/engine/ai/decks/flower_power.asm b/src/engine/duel/ai/decks/flower_power.asm
index 4d423a3..4d423a3 100644
--- a/src/engine/ai/decks/flower_power.asm
+++ b/src/engine/duel/ai/decks/flower_power.asm
diff --git a/src/engine/ai/decks/general.asm b/src/engine/duel/ai/decks/general.asm
index 039e101..039e101 100644
--- a/src/engine/ai/decks/general.asm
+++ b/src/engine/duel/ai/decks/general.asm
diff --git a/src/engine/ai/decks/general_no_retreat.asm b/src/engine/duel/ai/decks/general_no_retreat.asm
index 20d84e3..20d84e3 100644
--- a/src/engine/ai/decks/general_no_retreat.asm
+++ b/src/engine/duel/ai/decks/general_no_retreat.asm
diff --git a/src/engine/ai/decks/go_go_rain_dance.asm b/src/engine/duel/ai/decks/go_go_rain_dance.asm
index 23547e2..23547e2 100644
--- a/src/engine/ai/decks/go_go_rain_dance.asm
+++ b/src/engine/duel/ai/decks/go_go_rain_dance.asm
diff --git a/src/engine/ai/decks/im_ronald.asm b/src/engine/duel/ai/decks/im_ronald.asm
index b002d83..b002d83 100644
--- a/src/engine/ai/decks/im_ronald.asm
+++ b/src/engine/duel/ai/decks/im_ronald.asm
diff --git a/src/engine/ai/decks/invincible_ronald.asm b/src/engine/duel/ai/decks/invincible_ronald.asm
index 463560b..463560b 100644
--- a/src/engine/ai/decks/invincible_ronald.asm
+++ b/src/engine/duel/ai/decks/invincible_ronald.asm
diff --git a/src/engine/ai/decks/legendary_articuno.asm b/src/engine/duel/ai/decks/legendary_articuno.asm
index 6409330..6409330 100644
--- a/src/engine/ai/decks/legendary_articuno.asm
+++ b/src/engine/duel/ai/decks/legendary_articuno.asm
diff --git a/src/engine/ai/decks/legendary_dragonite.asm b/src/engine/duel/ai/decks/legendary_dragonite.asm
index 597f72c..597f72c 100644
--- a/src/engine/ai/decks/legendary_dragonite.asm
+++ b/src/engine/duel/ai/decks/legendary_dragonite.asm
diff --git a/src/engine/ai/decks/legendary_moltres.asm b/src/engine/duel/ai/decks/legendary_moltres.asm
index c2a3882..c2a3882 100644
--- a/src/engine/ai/decks/legendary_moltres.asm
+++ b/src/engine/duel/ai/decks/legendary_moltres.asm
diff --git a/src/engine/ai/decks/legendary_ronald.asm b/src/engine/duel/ai/decks/legendary_ronald.asm
index 3356838..3356838 100644
--- a/src/engine/ai/decks/legendary_ronald.asm
+++ b/src/engine/duel/ai/decks/legendary_ronald.asm
diff --git a/src/engine/ai/decks/legendary_zapdos.asm b/src/engine/duel/ai/decks/legendary_zapdos.asm
index cc99f0c..cc99f0c 100644
--- a/src/engine/ai/decks/legendary_zapdos.asm
+++ b/src/engine/duel/ai/decks/legendary_zapdos.asm
diff --git a/src/engine/ai/decks/powerful_ronald.asm b/src/engine/duel/ai/decks/powerful_ronald.asm
index 096fbea..096fbea 100644
--- a/src/engine/ai/decks/powerful_ronald.asm
+++ b/src/engine/duel/ai/decks/powerful_ronald.asm
diff --git a/src/engine/ai/decks/rock_crusher.asm b/src/engine/duel/ai/decks/rock_crusher.asm
index 41a50fa..41a50fa 100644
--- a/src/engine/ai/decks/rock_crusher.asm
+++ b/src/engine/duel/ai/decks/rock_crusher.asm
diff --git a/src/engine/ai/decks/sams_practice.asm b/src/engine/duel/ai/decks/sams_practice.asm
index dddce61..dddce61 100644
--- a/src/engine/ai/decks/sams_practice.asm
+++ b/src/engine/duel/ai/decks/sams_practice.asm
diff --git a/src/engine/ai/decks/strange_psyshock.asm b/src/engine/duel/ai/decks/strange_psyshock.asm
index ef378b0..ef378b0 100644
--- a/src/engine/ai/decks/strange_psyshock.asm
+++ b/src/engine/duel/ai/decks/strange_psyshock.asm
diff --git a/src/engine/ai/decks/unreferenced.asm b/src/engine/duel/ai/decks/unreferenced.asm
index 8722a27..8722a27 100644
--- a/src/engine/ai/decks/unreferenced.asm
+++ b/src/engine/duel/ai/decks/unreferenced.asm
diff --git a/src/engine/ai/decks/wonders_of_science.asm b/src/engine/duel/ai/decks/wonders_of_science.asm
index 706a7e6..706a7e6 100644
--- a/src/engine/ai/decks/wonders_of_science.asm
+++ b/src/engine/duel/ai/decks/wonders_of_science.asm
diff --git a/src/engine/ai/decks/zapping_selfdestruct.asm b/src/engine/duel/ai/decks/zapping_selfdestruct.asm
index da5e7c6..da5e7c6 100644
--- a/src/engine/ai/decks/zapping_selfdestruct.asm
+++ b/src/engine/duel/ai/decks/zapping_selfdestruct.asm
diff --git a/src/engine/ai/energy.asm b/src/engine/duel/ai/energy.asm
index ce8c037..ce8c037 100644
--- a/src/engine/ai/energy.asm
+++ b/src/engine/duel/ai/energy.asm
diff --git a/src/engine/ai/hand_pokemon.asm b/src/engine/duel/ai/hand_pokemon.asm
index 27a4176..27a4176 100644
--- a/src/engine/ai/hand_pokemon.asm
+++ b/src/engine/duel/ai/hand_pokemon.asm
diff --git a/src/engine/ai/init.asm b/src/engine/duel/ai/init.asm
index 33132cf..33132cf 100644
--- a/src/engine/ai/init.asm
+++ b/src/engine/duel/ai/init.asm
diff --git a/src/engine/ai/pkmn_powers.asm b/src/engine/duel/ai/pkmn_powers.asm
index 8ae629a..8ae629a 100644
--- a/src/engine/ai/pkmn_powers.asm
+++ b/src/engine/duel/ai/pkmn_powers.asm
diff --git a/src/engine/ai/retreat.asm b/src/engine/duel/ai/retreat.asm
index 768a48b..768a48b 100644
--- a/src/engine/ai/retreat.asm
+++ b/src/engine/duel/ai/retreat.asm
diff --git a/src/engine/ai/special_attacks.asm b/src/engine/duel/ai/special_attacks.asm
index 770324e..770324e 100644
--- a/src/engine/ai/special_attacks.asm
+++ b/src/engine/duel/ai/special_attacks.asm
diff --git a/src/engine/ai/trainer_cards.asm b/src/engine/duel/ai/trainer_cards.asm
index 4bee001..4bee001 100644
--- a/src/engine/ai/trainer_cards.asm
+++ b/src/engine/duel/ai/trainer_cards.asm
diff --git a/src/engine/duel/animations/commands.asm b/src/engine/duel/animations/commands.asm
new file mode 100644
index 0000000..46b1ea1
--- /dev/null
+++ b/src/engine/duel/animations/commands.asm
@@ -0,0 +1,354 @@
+; reads the animation commands from PointerTable_AttackAnimation
+; of attack in wLoadedAttackAnimation and plays them
+PlayAttackAnimationCommands:
+ ld a, [wLoadedAttackAnimation]
+ or a
+ ret z
+
+ ld l, a
+ ld h, 0
+ add hl, hl
+ ld de, PointerTable_AttackAnimation
+ add hl, de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+
+ push de
+ ld hl, wce7e
+ ld a, [hl]
+ or a
+ jr nz, .read_command
+ ld [hl], $01
+ call Func_3b21
+ pop de
+
+ push de
+ ld a, DUEL_ANIM_SCREEN_MAIN_SCENE
+ ld [wDuelAnimationScreen], a
+ ld a, $01
+ ld [wd4b3], a
+ xor a
+ ld [wDuelAnimLocationParam], a
+ ld a, [de]
+ cp $04
+ jr z, .read_command
+ ld a, DUEL_ANIM_150
+ call PlayDuelAnimation
+.read_command
+ pop de
+ ; fallthrough
+
+PlayAttackAnimationCommands_NextCommand:
+ ld a, [de]
+ inc de
+ ld hl, AnimationCommandPointerTable
+ jp JumpToFunctionInTable
+
+AnimationCommand_AnimEnd:
+ ret
+
+AnimationCommand_AnimPlayer:
+ ldh a, [hWhoseTurn]
+ ld [wDuelAnimDuelistSide], a
+ ld a, [wDuelType]
+ cp $00
+ jr nz, AnimationCommand_AnimNormal
+ ld a, PLAYER_TURN
+ ld [wDuelAnimDuelistSide], a
+ jr AnimationCommand_AnimNormal
+
+AnimationCommand_AnimOpponent:
+ call SwapTurn
+ ldh a, [hWhoseTurn]
+ ld [wDuelAnimDuelistSide], a
+ call SwapTurn
+ ld a, [wDuelType]
+ cp $00
+ jr nz, AnimationCommand_AnimNormal
+ ld a, OPPONENT_TURN
+ ld [wDuelAnimDuelistSide], a
+ jr AnimationCommand_AnimNormal
+
+AnimationCommand_AnimUnknown2:
+ ld a, [wce82]
+ and $7f
+ ld [wDuelAnimLocationParam], a
+ jr AnimationCommand_AnimNormal
+
+AnimationCommand_AnimEnd2:
+ ret
+
+AnimationCommand_AnimNormal:
+ ld a, [de]
+ inc de
+ cp DUEL_ANIM_SHOW_DAMAGE
+ jr z, .show_damage
+ cp DUEL_ANIM_SHAKE1
+ jr z, .shake_1
+ cp DUEL_ANIM_SHAKE2
+ jr z, .shake_2
+ cp DUEL_ANIM_SHAKE3
+ jr z, .shake_3
+
+.play_anim
+ call PlayDuelAnimation
+ jr PlayAttackAnimationCommands_NextCommand
+
+.show_damage
+ ld a, DUEL_ANIM_PRINT_DAMAGE
+ call PlayDuelAnimation
+ ld a, [wce81]
+ ld [wd4b3], a
+
+ push de
+ ld hl, wce7f
+ ld de, wDuelAnimDamage
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ pop de
+
+ ld a, $8c
+ call PlayDuelAnimation
+ ld a, [wDuelDisplayedScreen]
+ cp DUEL_MAIN_SCENE
+ jr nz, .skip_update_hud
+ ld a, DUEL_ANIM_UPDATE_HUD
+ call PlayDuelAnimation
+.skip_update_hud
+ jp PlayAttackAnimationCommands_NextCommand
+
+; screen shake happens differently
+; depending on whose turn it is
+.shake_1
+ ld c, DUEL_ANIM_SMALL_SHAKE_X
+ ld b, DUEL_ANIM_SMALL_SHAKE_Y
+ jr .check_duelist
+
+.shake_2
+ ld c, DUEL_ANIM_BIG_SHAKE_X
+ ld b, DUEL_ANIM_BIG_SHAKE_Y
+ jr .check_duelist
+
+.shake_3
+ ld c, DUEL_ANIM_SMALL_SHAKE_Y
+ ld b, DUEL_ANIM_SMALL_SHAKE_X
+
+.check_duelist
+ ldh a, [hWhoseTurn]
+ cp PLAYER_TURN
+ ld a, c
+ jr z, .play_anim
+ ld a, [wDuelType]
+ cp $00
+ ld a, c
+ jr z, .play_anim
+ ld a, b
+ jr .play_anim
+
+AnimationCommand_AnimUnknown:
+ ld a, [de]
+ inc de
+ ld [wd4b3], a
+ ld a, [wce82]
+ ld [wDuelAnimLocationParam], a
+ call SetDuelAnimationScreen
+ ld a, DUEL_ANIM_150
+ call PlayDuelAnimation
+ jp PlayAttackAnimationCommands_NextCommand
+
+AnimationCommandPointerTable:
+ dw AnimationCommand_AnimEnd ; anim_end
+ dw AnimationCommand_AnimNormal ; anim_normal
+ dw AnimationCommand_AnimPlayer ; anim_player
+ dw AnimationCommand_AnimOpponent ; anim_opponent
+ dw AnimationCommand_AnimUnknown ; anim_unknown
+ dw AnimationCommand_AnimUnknown2 ; anim_unknown2
+ dw AnimationCommand_AnimEnd2 ; anim_end2 (unused)
+
+; sets wDuelAnimationScreen according to wd4b3
+; if wd4b3 == $01, set it to Main Scene
+; if wd4b3 == $04, st it to Play Area scene
+SetDuelAnimationScreen:
+ ld a, [wd4b3]
+ cp $04
+ jr z, .set_play_area_screen
+ cp $01
+ ret nz
+ ld a, DUEL_ANIM_SCREEN_MAIN_SCENE
+ ld [wDuelAnimationScreen], a
+ ret
+
+.set_play_area_screen
+ ld a, [wDuelAnimLocationParam]
+ ld l, a
+ ld a, [wWhoseTurn]
+ ld h, a
+ cp PLAYER_TURN
+ jr z, .player
+
+; opponent
+ ld a, [wDuelType]
+ cp $00
+ jr z, .asm_50c6
+
+; link duel or vs. AI
+ bit 7, l
+ jr z, .asm_50e2
+ jr .asm_50d2
+
+.asm_50c6
+ bit 7, l
+ jr z, .asm_50da
+ jr .asm_50ea
+
+.player
+ bit 7, l
+ jr z, .asm_50d2
+ jr .asm_50e2
+
+.asm_50d2
+ ld l, UNKNOWN_SCREEN_4
+ ld h, PLAYER_TURN
+ ld a, DUEL_ANIM_SCREEN_PLAYER_PLAY_AREA
+ jr .ok
+.asm_50da
+ ld l, UNKNOWN_SCREEN_4
+ ld h, OPPONENT_TURN
+ ld a, DUEL_ANIM_SCREEN_PLAYER_PLAY_AREA
+ jr .ok
+.asm_50e2
+ ld l, UNKNOWN_SCREEN_5
+ ld h, OPPONENT_TURN
+ ld a, DUEL_ANIM_SCREEN_OPP_PLAY_AREA
+ jr .ok
+.asm_50ea
+ ld l, UNKNOWN_SCREEN_5
+ ld h, PLAYER_TURN
+ ld a, DUEL_ANIM_SCREEN_OPP_PLAY_AREA
+
+.ok
+ ld [wDuelAnimationScreen], a
+ ret
+
+Func_190f4:
+ ld a, [wd4b3]
+ cp $04
+ jr z, Func_1910f
+ ; fallthrough
+
+Func_190fb:
+ cp $01
+ jr nz, .done
+ ld a, DUEL_ANIM_SCREEN_MAIN_SCENE
+ ld [wDuelAnimationScreen], a
+ ld a, [wDuelDisplayedScreen]
+ cp $01
+ jr z, .done
+ bank1call DrawDuelMainScene
+.done
+ ret
+
+Func_1910f:
+ call SetDuelAnimationScreen
+ ld a, [wDuelDisplayedScreen]
+ cp l
+ jr z, .skip_change_screen
+ ld a, l
+ push af
+ ld l, PLAYER_TURN
+ ld a, [wDuelType]
+ cp $00
+ jr nz, .asm_5127
+ ld a, [wWhoseTurn]
+ ld l, a
+.asm_5127
+ call DrawYourOrOppPlayAreaScreen_Bank0
+ pop af
+ ld [wDuelDisplayedScreen], a
+.skip_change_screen
+ call DrawWideTextBox
+ ret
+
+; prints text related to the damage received
+; by card stored in wTempNonTurnDuelistCardID
+; takes into account type effectiveness
+PrintDamageText:
+ push hl
+ push bc
+ push de
+ ld a, [wLoadedAttackAnimation]
+ cp ATK_ANIM_HEAL
+ jr z, .skip
+ cp ATK_ANIM_HEALING_WIND_PLAY_AREA
+ jr z, .skip
+
+ ld a, [wTempNonTurnDuelistCardID]
+ ld e, a
+ ld d, $00
+ call LoadCardDataToBuffer1_FromCardID
+ ld a, 18
+ call CopyCardNameAndLevel
+ ld [hl], TX_END
+ ld hl, wTxRam2
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld hl, wce7f
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call GetDamageText
+ ld a, l
+ or h
+ call nz, DrawWideTextBox_PrintText
+.skip
+ pop de
+ pop bc
+ pop hl
+ ret
+
+; returns in hl the text id associated with
+; the damage in hl and its effectiveness
+GetDamageText:
+ ld a, l
+ or h
+ jr z, .no_damage
+ call LoadTxRam3
+ ld a, [wce81]
+ ldtx hl, AttackDamageText
+ and (1 << RESISTANCE) | (1 << WEAKNESS)
+ ret z ; not weak or resistant
+ ldtx hl, WeaknessMoreDamage2Text
+ cp (1 << RESISTANCE) | (1 << WEAKNESS)
+ ret z ; weak and resistant
+ and (1 << WEAKNESS)
+ ldtx hl, WeaknessMoreDamageText
+ ret nz ; weak
+ ldtx hl, ResistanceLessDamageText
+ ret ; resistant
+
+.no_damage
+ call CheckNoDamageOrEffect
+ ret c
+ ldtx hl, NoDamageText
+ ld a, [wce81]
+ and (1 << RESISTANCE)
+ ret z ; not resistant
+ ldtx hl, ResistanceNoDamageText
+ ret ; resistant
+
+UpdateMainSceneHUD:
+ ld a, [wDuelDisplayedScreen]
+ cp DUEL_MAIN_SCENE
+ ret nz
+ bank1call DrawDuelHUDs
+ ret
+
+Func_191a3:
+ ret
+
+INCLUDE "data/duel/animations/attack_animations.asm"
diff --git a/src/engine/duel/animations/core.asm b/src/engine/duel/animations/core.asm
new file mode 100644
index 0000000..5da9a0a
--- /dev/null
+++ b/src/engine/duel/animations/core.asm
@@ -0,0 +1,661 @@
+Func_1c8bc:
+ push hl
+ push bc
+ call Set_OBJ_8x8
+ ld a, LOW(Func_3ba2)
+ ld [wDoFrameFunction], a
+ ld a, HIGH(Func_3ba2)
+ ld [wDoFrameFunction + 1], a
+ ld a, $ff
+ ld hl, wAnimationQueue
+ ld c, ANIMATION_QUEUE_LENGTH
+.fill_queue
+ ld [hli], a
+ dec c
+ jr nz, .fill_queue
+ ld [wd42a], a
+ ld [wd4c0], a
+ xor a
+ ld [wDuelAnimBufferCurPos], a
+ ld [wDuelAnimBufferSize], a
+ ld [wd4b3], a
+ call DefaultScreenAnimationUpdate
+ call Func_3ca0
+ pop bc
+ pop hl
+ ret
+
+PlayLoadedDuelAnimation:
+ ld a, [wDoFrameFunction + 0]
+ cp LOW(Func_3ba2)
+ jr nz, .error
+ ld a, [wDoFrameFunction + 1]
+ cp HIGH(Func_3ba2)
+ jr z, .okay
+.error
+ debug_nop
+ ret
+
+.okay
+ ld a, [wTempAnimation]
+ ld [wd4bf], a
+ cp DUEL_SPECIAL_ANIMS
+ jp nc, Func_1cb5e
+
+ push hl
+ push bc
+ push de
+ call GetAnimationData
+; hl: pointer
+
+ ld a, [wAnimationsDisabled]
+ or a
+ jr z, .check_to_play_sfx
+ ; animations are disabled
+ push hl
+ ld bc, ANIM_SPRITE_ANIM_FLAGS
+ add hl, bc
+ ld a, [hl]
+ ; if flag is set, play animation anyway
+ and (1 << SPRITE_ANIM_FLAG_UNSKIPPABLE)
+ pop hl
+ jr z, .return
+
+.check_to_play_sfx
+ push hl
+ ld bc, ANIM_SOUND_FX_ID
+ add hl, bc
+ ld a, [hl]
+ pop hl
+ or a
+ jr z, .calc_addr
+ call PlaySFX
+
+.calc_addr
+; this data field is always $00,
+; so this calculation is unnecessary
+; seems like there was supposed to be
+; more than 1 function to handle animation
+ push hl
+ ld bc, ANIM_HANDLER_FUNCTION
+ add hl, bc
+ ld a, [hl]
+ rlca
+ add LOW(.address) ; $48
+ ld l, a ; LO
+ ld a, HIGH(.address) ; $49
+ adc 0
+ ld h, a ; HI
+; hl: pointer
+ ld a, [hli]
+ ld b, [hl]
+ ld c, a
+ pop hl
+
+ call CallBC
+.return
+ pop de
+ pop bc
+ pop hl
+ ret
+
+.address
+ dw .handler_func
+
+.handler_func ; 1c94a (7:494a)
+; if any of ANIM_SPRITE_ID, ANIM_PALETTE_ID and ANIM_SPRITE_ANIM_ID
+; are 0, then return
+ ld e, l
+ ld d, h
+ ld c, ANIM_SPRITE_ANIM_ID + 1
+.loop
+ ld a, [de]
+ or a
+ jr z, .return_with_carry
+ inc de
+ dec c
+ jr nz, .loop
+
+ ld a, [hli] ; ANIM_SPRITE_ID
+ farcall CreateSpriteAndAnimBufferEntry
+ ld a, [wWhichSprite]
+ ld [wAnimationQueue], a ; push an animation to the queue
+
+ xor a
+ ld [wVRAMTileOffset], a
+ ld [wd4cb], a
+
+ ld a, [hli] ; ANIM_PALETTE_ID
+ farcall LoadPaletteData
+ ld a, [hli] ; ANIM_SPRITE_ANIM_ID
+
+ push af
+ ld a, [hli] ; ANIM_SPRITE_ANIM_FLAGS
+ ld [wAnimFlags], a
+ call LoadAnimCoordsAndFlags
+ pop af
+
+ farcall StartNewSpriteAnimation
+ or a
+ jr .done
+
+.return_with_carry
+ scf
+.done
+ ret
+
+; loads the correct coordinates/flags for
+; sprite animation in wAnimationQueue
+LoadAnimCoordsAndFlags:
+ push hl
+ push bc
+ ld a, [wAnimationQueue]
+ ld c, SPRITE_ANIM_ATTRIBUTES
+ call GetSpriteAnimBufferProperty_SpriteInA
+ call GetAnimCoordsAndFlags
+
+ push af
+ and (1 << SPRITE_ANIM_FLAG_6) | (1 << SPRITE_ANIM_FLAG_5)
+ or [hl]
+ ld [hli], a
+ ld a, b
+ ld [hli], a ; SPRITE_ANIM_COORD_X
+ ld [hl], c ; SPRITE_ANIM_COORD_Y
+ pop af
+
+ ld bc, SPRITE_ANIM_FLAGS - SPRITE_ANIM_COORD_Y
+ add hl, bc
+ ld c, a ; useless
+ and (1 << SPRITE_ANIM_FLAG_Y_SUBTRACT) | (1 << SPRITE_ANIM_FLAG_X_SUBTRACT)
+ or [hl]
+ ld [hl], a
+ pop bc
+ pop hl
+ ret
+
+; outputs x and y coordinates for the sprite animation
+; taking into account who the turn duelist is.
+; also returns in a the allowed animation flags of
+; the configuration that is selected.
+; output:
+; a = anim flags
+; b = x coordinate
+; c = y coordinate
+GetAnimCoordsAndFlags:
+ push hl
+ ld c, 0
+ ld a, [wAnimFlags]
+ and (1 << SPRITE_ANIM_FLAG_SPEED)
+ jr nz, .calc_addr
+
+ ld a, [wDuelAnimationScreen]
+ add a ; 2 * [wDuelAnimationScreen]
+ ld c, a
+ add a ; 4 * [wDuelAnimationScreen]
+ add c ; 6 * [wDuelAnimationScreen]
+ add a ; 12 * [wDuelAnimationScreen]
+ ld c, a
+
+ ld a, [wDuelAnimDuelistSide]
+ cp PLAYER_TURN
+ jr z, .player_side
+; opponent side
+ ld a, 6
+ add c
+ ld c, a
+.player_side
+ ld a, [wDuelAnimLocationParam]
+ add c ; a = [wDuelAnimLocationParam] + c
+ ld c, a
+ ld b, 0
+ ld hl, AnimationCoordinatesIndex
+ add hl, bc
+ ld c, [hl]
+
+.calc_addr
+ ld a, c
+ add a ; a = c * 2
+ add c ; a = c * 3
+ ld c, a
+ ld b, 0
+ ld hl, AnimationCoordinates
+ add hl, bc
+ ld b, [hl] ; x coord
+ inc hl
+ ld c, [hl] ; y coord
+ inc hl
+ ld a, [wAnimFlags]
+ and [hl] ; flags
+ pop hl
+ ret
+
+AnimationCoordinatesIndex:
+; animations in the Duel Main Scene
+ db $01, $01, $01, $01, $01, $01 ; player
+ db $02, $02, $02, $02, $02, $02 ; opponent
+
+; animations in the Player's Play Area, for each Play Area Pokemon
+ db $03, $04, $05, $06, $07, $08 ; player
+ db $03, $04, $05, $06, $07, $08 ; opponent
+
+; animations in the Opponent's Play Area, for each Play Area Pokemon
+ db $09, $0a, $0b, $0c, $0d, $0e ; player
+ db $09, $0a, $0b, $0c, $0d, $0e ; opponent
+
+anim_coords: MACRO
+ db \1
+ db \2
+ db \3
+ENDM
+
+AnimationCoordinates:
+; x coord, y coord, animation flags
+ anim_coords 88, 88, (1 << SPRITE_ANIM_FLAG_3)
+
+; animations in the Duel Main Scene
+ anim_coords 40, 80, $00
+ anim_coords 136, 48, (1 << SPRITE_ANIM_FLAG_6) | (1 << SPRITE_ANIM_FLAG_5) | (1 << SPRITE_ANIM_FLAG_Y_SUBTRACT) | (1 << SPRITE_ANIM_FLAG_X_SUBTRACT)
+
+; animations in the Player's Play Area, for each Play Area Pokemon
+ anim_coords 88, 72, $00
+ anim_coords 24, 96, $00
+ anim_coords 56, 96, $00
+ anim_coords 88, 96, $00
+ anim_coords 120, 96, $00
+ anim_coords 152, 96, $00
+
+; animations in the Opponent's Play Area, for each Play Area Pokemon
+ anim_coords 88, 80, $00
+ anim_coords 152, 40, $00
+ anim_coords 120, 40, $00
+ anim_coords 88, 40, $00
+ anim_coords 56, 40, $00
+ anim_coords 24, 40, $00
+
+; appends to end of wDuelAnimBuffer
+; the current duel animation
+LoadDuelAnimationToBuffer:
+ push hl
+ push bc
+ ld a, [wDuelAnimBufferCurPos]
+ ld b, a
+ ld hl, wDuelAnimBufferSize
+ ld a, [hl]
+ ld c, a
+ add DUEL_ANIM_STRUCT_SIZE
+ and %01111111
+ cp b
+ jp z, .skip
+ ld [hl], a
+
+ ld b, $00
+ ld hl, wDuelAnimBuffer
+ add hl, bc
+ ld a, [wTempAnimation]
+ ld [hli], a
+ ld a, [wDuelAnimationScreen]
+ ld [hli], a
+ ld a, [wDuelAnimDuelistSide]
+ ld [hli], a
+ ld a, [wDuelAnimLocationParam]
+ ld [hli], a
+ ld a, [wDuelAnimDamage]
+ ld [hli], a
+ ld a, [wDuelAnimDamage + 1]
+ ld [hli], a
+ ld a, [wd4b3]
+ ld [hli], a
+ ld a, [wDuelAnimReturnBank]
+ ld [hl], a
+
+.skip
+ pop bc
+ pop hl
+ ret
+
+; loads the animations from wDuelAnimBuffer
+; in ascending order, starting at wDuelAnimBufferCurPos
+PlayBufferedDuelAnimations:
+ push hl
+ push bc
+.next_duel_anim
+ ld a, [wDuelAnimBufferSize]
+ ld b, a
+ ld a, [wDuelAnimBufferCurPos]
+ cp b
+ jr z, .skip
+
+ ld c, a
+ add DUEL_ANIM_STRUCT_SIZE
+ and %01111111
+ ld [wDuelAnimBufferCurPos], a
+
+ ld b, $00
+ ld hl, wDuelAnimBuffer
+ add hl, bc
+ ld a, [hli]
+ ld [wTempAnimation], a
+ ld a, [hli]
+ ld [wDuelAnimationScreen], a
+ ld a, [hli]
+ ld [wDuelAnimDuelistSide], a
+ ld a, [hli]
+ ld [wDuelAnimLocationParam], a
+ ld a, [hli]
+ ld [wDuelAnimDamage], a
+ ld a, [hli]
+ ld [wDuelAnimDamage + 1], a
+ ld a, [hli]
+ ld [wd4b3], a
+ ld a, [hl]
+ ld [wDuelAnimReturnBank], a
+
+ call PlayLoadedDuelAnimation
+ call CheckAnyAnimationPlaying
+ jr nc, .next_duel_anim
+
+.skip
+ pop bc
+ pop hl
+ ret
+
+; gets data from Animations for anim ID in a
+; outputs the pointer to the data in hl
+GetAnimationData:
+ push bc
+ ld a, [wTempAnimation]
+ ld l, a
+ ld h, 0
+ add hl, hl ; hl = anim * 2
+ ld b, h
+ ld c, l
+ add hl, hl ; hl = anim * 4
+ add hl, bc ; hl = anim * 6
+ ld bc, Animations
+ add hl, bc
+ pop bc
+ ret
+
+Func_1cac5:
+ ld a, [wd42a]
+ cp $ff
+ jr nz, .asm_1cb03
+
+ ld a, [wd4c0]
+ or a
+ jr z, .asm_1cafb
+ cp $80
+ jr z, .asm_1cb11
+ ld hl, wAnimationQueue
+ ld c, ANIMATION_QUEUE_LENGTH
+.loop_queue
+ push af
+ push bc
+ ld a, [hl]
+ cp $ff
+ jr z, .next
+ ld [wWhichSprite], a
+ farcall GetSpriteAnimCounter
+ cp $ff
+ jr nz, .next
+ farcall DisableCurSpriteAnim
+ ld a, $ff
+ ld [hl], a
+
+.next
+ pop bc
+ pop af
+ and [hl]
+ inc hl
+ dec c
+ jr nz, .loop_queue
+
+.asm_1cafb
+ cp $ff
+ jr nz, .skip_play_anims
+ call PlayBufferedDuelAnimations
+.skip_play_anims
+ ret
+
+.asm_1cb03
+ ld hl, wScreenAnimUpdatePtr
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call CallHL2
+ ld a, [wd42a]
+ jr .asm_1cafb
+
+.asm_1cb11
+ ld a, $ff
+ ld [wd4c0], a
+ jr .asm_1cafb
+
+Func_1cb18:
+ 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, .carry
+ ld a, [wDoFrameFunction + 1]
+ cp HIGH(Func_3ba2)
+ jr nz, .carry
+
+ ld a, $ff
+ ld [wd4c0], a
+ ld a, [wd42a]
+ cp $ff
+ call nz, DoScreenAnimationUpdate
+
+; clear all queued animations
+; and disable their sprite anims
+ ld hl, wAnimationQueue
+ ld c, ANIMATION_QUEUE_LENGTH
+.loop_queue
+ push bc
+ ld a, [hl]
+ cp $ff
+ jr z, .next_queued
+ ld [wWhichSprite], a
+ farcall DisableCurSpriteAnim
+ ld a, $ff
+ ld [hl], a
+.next_queued
+ pop bc
+ inc hl
+ dec c
+ jr nz, .loop_queue
+
+ xor a
+ ld [wDuelAnimBufferCurPos], a
+ ld [wDuelAnimBufferSize], a
+.done
+ pop de
+ pop bc
+ pop hl
+ ret
+.carry
+ scf
+ jr .done
+
+Func_1cb5e:
+ cp $96
+ jp nc, Func_1ce03
+ cp $8c
+ jp nz, InitScreenAnimation
+ jr .asm_1cb6a ; redundant
+.asm_1cb6a
+ ld a, [wDuelAnimDamage + 1]
+ cp $03
+ jr nz, .asm_1cb76
+ ld a, [wDuelAnimDamage]
+ cp $e8
+.asm_1cb76
+ ret nc
+
+ xor a
+ ld [wd4b8], a
+ ld [wVRAMTileOffset], a
+ ld [wd4cb], a
+
+ ld a, PALETTE_37
+ farcall LoadPaletteData
+ call Func_1cba6
+
+ ld hl, wd4b3
+ bit 0, [hl]
+ call nz, Func_1cc3e
+
+ ld a, $12
+ ld [wd4b8], a
+ bit 1, [hl]
+ call nz, Func_1cc4e
+
+ bit 2, [hl]
+ call nz, Func_1cc66
+
+ xor a
+ ld [wd4b3], a
+ ret
+
+Func_1cba6:
+ call Func_1cc03
+ xor a
+ ld [wd4b7], a
+
+ ld hl, wd4b4
+ ld de, wAnimationQueue + 1
+.asm_1cbb3
+ push hl
+ push de
+ ld a, [hl]
+ or a
+ jr z, .asm_1cbbc
+ call Func_1cbcc
+
+.asm_1cbbc
+ pop de
+ pop hl
+ inc hl
+ inc de
+ ld a, [wd4b7]
+ inc a
+ ld [wd4b7], a
+ cp $03
+ jr c, .asm_1cbb3
+ ret
+
+Func_1cbcc:
+ push af
+ ld a, SPRITE_DUEL_4
+ farcall CreateSpriteAndAnimBufferEntry
+ ld a, [wWhichSprite]
+ ld [de], a
+ ld a, (1 << SPRITE_ANIM_FLAG_UNSKIPPABLE)
+ ld [wAnimFlags], a
+ ld c, SPRITE_ANIM_COORD_X
+ call GetSpriteAnimBufferProperty
+ call GetAnimCoordsAndFlags
+
+ ld a, [wd4b7]
+ add LOW(Unknown_1cbfd)
+ ld e, a
+ ld a, HIGH(Unknown_1cbfd)
+ adc 0
+ ld d, a
+ ld a, [de]
+ add b
+
+ ld [hli], a ; SPRITE_ANIM_COORD_X
+ ld [hl], c ; SPRITE_ANIM_COORD_Y
+
+ ld a, [wd4b8]
+ ld c, a
+ pop af
+ farcall Func_12ac9
+ ret
+
+Unknown_1cbfd:
+ db -$10, -$8, $0, $8, -$8, -$10
+
+Func_1cc03:
+ ld a, [wDuelAnimDamage]
+ ld l, a
+ ld a, [wDuelAnimDamage + 1]
+ ld h, a
+
+ ld de, wd4b4
+ ld bc, -100
+ call .Func_1cc2f
+ ld bc, -10
+ call .Func_1cc2f
+
+ ld a, l
+ add $4f
+ ld [de], a
+ ld hl, wd4b4
+ ld c, 2
+.asm_1cc23
+ ld a, [hl]
+ cp $4f
+ jr nz, .asm_1cc2e
+ ld [hl], $00
+ inc hl
+ dec c
+ jr nz, .asm_1cc23
+.asm_1cc2e
+ ret
+
+.Func_1cc2f
+ ld a, $4e
+.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
+
+Func_1cc3e:
+ push hl
+ ld a, $03
+ ld [wd4b7], a
+ ld de, wAnimationQueue + 4
+ ld a, SPRITE_ANIM_91
+ call Func_1cbcc
+ pop hl
+ ret
+
+Func_1cc4e:
+ push hl
+ ld a, $04
+ ld [wd4b7], a
+ ld de, wAnimationQueue + 5
+ ld a, SPRITE_ANIM_90
+ call Func_1cbcc
+ ld a, [wd4b8]
+ add $12
+ ld [wd4b8], a
+ pop hl
+ ret
+
+Func_1cc66:
+ push hl
+ ld a, $05
+ ld [wd4b7], a
+ ld de, wAnimationQueue + 6
+ ld a, SPRITE_ANIM_89
+ call Func_1cbcc
+ pop hl
+ ret
diff --git a/src/engine/duel/animations/screen_effects.asm b/src/engine/duel/animations/screen_effects.asm
new file mode 100644
index 0000000..9058071
--- /dev/null
+++ b/src/engine/duel/animations/screen_effects.asm
@@ -0,0 +1,286 @@
+; initializes a screen animation from wTempAnimation
+; loads a function pointer for updating a frame
+; and initializes the duration of the animation.
+InitScreenAnimation:
+ ld a, [wAnimationsDisabled]
+ or a
+ jr nz, .skip
+ ld a, [wTempAnimation]
+ ld [wd42a], a
+ sub DUEL_SCREEN_ANIMS
+ add a
+ add a
+ ld c, a
+ ld b, $00
+ ld hl, Data_1cc9f
+ add hl, bc
+ ld a, [hli]
+ ld [wScreenAnimUpdatePtr], a
+ ld c, a
+ ld a, [hli]
+ ld [wScreenAnimUpdatePtr + 1], a
+ ld b, a
+ ld a, [hl]
+ ld [wScreenAnimDuration], a
+ call CallBC
+.skip
+ ret
+
+; for the following animations, these functions
+; are run with the corresponding duration.
+; this duration decides different effects,
+; depending on which function runs
+; and is decreased by one each time.
+; when it is down to 0, the animation is done.
+
+screen_effect: MACRO
+ dw \1 ; function pointer
+ db \2 ; duration
+ db $00 ; padding
+ENDM
+
+Data_1cc9f:
+; function pointer, duration
+ screen_effect ShakeScreenX_Small, 24 ; DUEL_ANIM_SMALL_SHAKE_X
+ screen_effect ShakeScreenX_Big, 32 ; DUEL_ANIM_BIG_SHAKE_X
+ screen_effect ShakeScreenY_Small, 24 ; DUEL_ANIM_SMALL_SHAKE_Y
+ screen_effect ShakeScreenY_Big, 32 ; DUEL_ANIM_BIG_SHAKE_Y
+ screen_effect WhiteFlashScreen, 8 ; DUEL_ANIM_FLASH
+ screen_effect DistortScreen, 63 ; DUEL_ANIM_DISTORT
+
+; checks if screen animation duration is over
+; and if so, loads the default update function
+LoadDefaultScreenAnimationUpdateWhenFinished:
+ ld a, [wScreenAnimDuration]
+ or a
+ ret nz
+ ; fallthrough
+
+; function called for the screen animation update when it is over
+DefaultScreenAnimationUpdate:
+ ld a, $ff
+ ld [wd42a], a
+ call DisableInt_LYCoincidence
+ xor a
+ ldh [hSCX], a
+ ldh [rSCX], a
+ ldh [hSCY], a
+ ld hl, wScreenAnimUpdatePtr
+ ld [hl], LOW(DefaultScreenAnimationUpdate)
+ inc hl
+ ld [hl], HIGH(DefaultScreenAnimationUpdate)
+ ret
+
+; runs the screen update function set in wScreenAnimUpdatePtr
+DoScreenAnimationUpdate:
+ ld a, 1
+ ld [wScreenAnimDuration], a
+ ld hl, wScreenAnimUpdatePtr
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call CallHL2
+ jr DefaultScreenAnimationUpdate
+
+ShakeScreenX_Small:
+ ld hl, SmallShakeOffsets
+ jr ShakeScreenX
+
+ShakeScreenX_Big:
+ ld hl, BigShakeOffsets
+ jr ShakeScreenX
+
+ShakeScreenX:
+ ld a, l
+ ld [wd4bc], a
+ ld a, h
+ ld [wd4bc + 1], a
+
+ ld hl, wScreenAnimUpdatePtr
+ ld [hl], LOW(.update)
+ inc hl
+ ld [hl], HIGH(.update)
+ ret
+
+.update
+ call DecrementScreenAnimDuration
+ call UpdateShakeOffset
+ jp nc, LoadDefaultScreenAnimationUpdateWhenFinished
+ ldh a, [hSCX]
+ add [hl]
+ ldh [hSCX], a
+ jp LoadDefaultScreenAnimationUpdateWhenFinished
+
+ShakeScreenY_Small:
+ ld hl, SmallShakeOffsets
+ jr ShakeScreenY
+
+ShakeScreenY_Big:
+ ld hl, BigShakeOffsets
+ jr ShakeScreenY
+
+ShakeScreenY:
+ ld a, l
+ ld [wd4bc], a
+ ld a, h
+ ld [wd4bc + 1], a
+ ld hl, wScreenAnimUpdatePtr
+ ld [hl], LOW(.update)
+ inc hl
+ ld [hl], HIGH(.update)
+ ret
+
+.update
+ call DecrementScreenAnimDuration
+ call UpdateShakeOffset
+ jp nc, LoadDefaultScreenAnimationUpdateWhenFinished
+ ldh a, [hSCY]
+ add [hl]
+ ldh [hSCY], a
+ jp LoadDefaultScreenAnimationUpdateWhenFinished
+
+; get the displacement of the current frame
+; depending on the value of wScreenAnimDuration
+; returns carry if displacement was updated
+UpdateShakeOffset:
+ ld hl, wd4bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wScreenAnimDuration]
+ cp [hl]
+ ret nc
+ inc hl
+ push hl
+ inc hl
+ ld a, l
+ ld [wd4bc], a
+ ld a, h
+ ld [wd4bc + 1], a
+ pop hl
+ scf
+ ret
+
+SmallShakeOffsets:
+ db 21, 2
+ db 17, -2
+ db 13, 2
+ db 9, -2
+ db 5, 1
+ db 1, -1
+
+BigShakeOffsets:
+ db 29, 4
+ db 25, -4
+ db 21, 4
+ db 17, -4
+ db 13, 3
+ db 9, -3
+ db 5, 2
+ db 1, -2
+
+DecrementScreenAnimDuration:
+ ld hl, wScreenAnimDuration
+ dec [hl]
+ ret
+
+WhiteFlashScreen:
+ ld hl, wScreenAnimUpdatePtr
+ ld [hl], LOW(.update)
+ inc hl
+ ld [hl], HIGH(.update)
+ ld a, [wBGP]
+ ld [wd4bc], a
+ ; backup the current background pals
+ ld hl, wBackgroundPalettesCGB
+ ld de, wTempBackgroundPalettesCGB
+ ld bc, 8 palettes
+ call CopyDataHLtoDE_SaveRegisters
+ ld de, PALRGB_WHITE
+ ld hl, wBackgroundPalettesCGB
+ ld bc, (8 palettes) / 2
+ call FillMemoryWithDE
+ xor a
+ call SetBGP
+ call FlushAllPalettes
+
+.update
+ call DecrementScreenAnimDuration
+ ld a, [wScreenAnimDuration]
+ or a
+ ret nz
+ ; retrieve the previous background pals
+ ld hl, wTempBackgroundPalettesCGB
+ ld de, wBackgroundPalettesCGB
+ ld bc, 8 palettes
+ call CopyDataHLtoDE_SaveRegisters
+ ld a, [wd4bc]
+ call SetBGP
+ call FlushAllPalettes
+ jp DefaultScreenAnimationUpdate
+
+DistortScreen:
+ ld hl, wScreenAnimUpdatePtr
+ ld [hl], LOW(.update)
+ inc hl
+ ld [hl], HIGH(.update)
+ xor a
+ ld [wApplyBGScroll], a
+ ld hl, wLCDCFunctionTrampoline + 1
+ ld [hl], LOW(ApplyBackgroundScroll)
+ inc hl
+ ld [hl], HIGH(ApplyBackgroundScroll)
+ ld a, 1
+ ld [wBGScrollMod], a
+ call EnableInt_LYCoincidence
+
+.update
+ ld a, [wScreenAnimDuration]
+ srl a
+ srl a
+ srl a
+ and %00000111
+ ld c, a
+ ld b, $00
+ ld hl, .BGScrollModData
+ add hl, bc
+ ld a, [hl]
+ ld [wBGScrollMod], a
+ call DecrementScreenAnimDuration
+ jp LoadDefaultScreenAnimationUpdateWhenFinished
+
+; each value is applied for 8 "ticks" of wScreenAnimDuration
+; starting from the last and running backwards
+.BGScrollModData
+ db 4, 3, 2, 1, 1, 1, 1, 2
+
+Func_1ce03:
+ cp DUEL_ANIM_158
+ jr z, .asm_1ce17
+ sub $96
+ add a
+ ld c, a
+ ld b, $00
+ ld hl, .pointer_table
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp Func_3bb5
+
+.asm_1ce17
+ ld a, [wDuelAnimDamage]
+ ld l, a
+ ld a, [wDuelAnimDamage + 1]
+ ld h, a
+ jp Func_3bb5
+
+.pointer_table
+ dw Func_190f4 ; DUEL_ANIM_150
+ dw PrintDamageText ; DUEL_ANIM_PRINT_DAMAGE
+ dw UpdateMainSceneHUD ; DUEL_ANIM_UPDATE_HUD
+ dw Func_191a3 ; DUEL_ANIM_153
+ dw Func_191a3 ; DUEL_ANIM_154
+ dw Func_191a3 ; DUEL_ANIM_155
+ dw Func_191a3 ; DUEL_ANIM_156
+ dw Func_191a3 ; DUEL_ANIM_157
diff --git a/src/engine/duel/core.asm b/src/engine/duel/core.asm
index acf5add..10ccdee 100644
--- a/src/engine/duel/core.asm
+++ b/src/engine/duel/core.asm
@@ -5983,7 +5983,7 @@ PrintUsedTrainerCardDescription:
; byte 0 is $01, bytes 1 and 2 are the checksum, byte 3 is [wDuelType]
; next $33a bytes come from DuelDataToSave
SaveDuelData:
- farcall CommentedOut_1a6cc
+ farcall StubbedUnusedSaveDataValidation
ld de, sCurrentDuel
; fallthrough
diff --git a/src/engine/duel/effect_commands.asm b/src/engine/duel/effect_commands.asm
new file mode 100644
index 0000000..e96ef7e
--- /dev/null
+++ b/src/engine/duel/effect_commands.asm
@@ -0,0 +1,1619 @@
+EffectCommands: ; 186f7 (6:46f7)
+; Each attack has a two-byte effect pointer (attack's 7th param) that points to one of these structures.
+; Similarly, trainer cards have a two-byte pointer (7th param) to one of these structures, which determines the card's function.
+; Energy cards also point to one of these, but their data is just $00.
+; db EFFECTCMDTYPE_* ($01 - $0a)
+; dw Function
+; ...
+; db $00
+
+; Commands are associated to a time or a scope (EFFECTCMDTYPE_*) that determines when their function is executed during the turn.
+; - EFFECTCMDTYPE_INITIAL_EFFECT_1: Executed right after attack or trainer card is used. Bypasses Smokescreen and Sand Attack effects.
+; - EFFECTCMDTYPE_INITIAL_EFFECT_2: Executed right after attack, Pokemon Power, or trainer card is used.
+; - EFFECTCMDTYPE_DISCARD_ENERGY: For attacks or trainer cards that require putting one or more attached energy cards into the discard pile.
+; - EFFECTCMDTYPE_REQUIRE_SELECTION: For attacks, Pokemon Powers, or trainer cards requiring the user to select a card (from e.g. play area screen or card list).
+; - EFFECTCMDTYPE_BEFORE_DAMAGE: Effect command of an attack executed prior to the damage step. For trainer card or Pokemon Power, usually the main effect.
+; - EFFECTCMDTYPE_AFTER_DAMAGE: Effect command executed after the damage step.
+; - EFFECTCMDTYPE_AI_SWITCH_DEFENDING_PKMN: For attacks that may result in the defending Pokemon being switched out. Called only for AI-executed attacks.
+; - EFFECTCMDTYPE_PKMN_POWER_TRIGGER: Pokemon Power effects that trigger the moment the Pokemon card is played.
+; - EFFECTCMDTYPE_AI: Used for AI scoring.
+; - EFFECTCMDTYPE_AI_SELECTION: When AI is required to select a card
+
+; Attacks that have an EFFECTCMDTYPE_REQUIRE_SELECTION also must have either an EFFECTCMDTYPE_AI_SWITCH_DEFENDING_PKMN or an
+; EFFECTCMDTYPE_AI_SELECTION (for anything not involving switching the defending Pokemon), to handle selections involving the AI.
+
+; Similar attack effects of different Pokemon cards all point to a different command list,
+; even though in some cases their commands and function pointers match.
+
+; Function name examples
+; PoisonEffect ; generic effect shared by multiple attacks.
+; Paralysis50PercentEffect ;
+; KakunaStiffenEffect ; unique effect from an attack known by multiple cards.
+; MetapodStiffenEffect ;
+; AcidEffect ; unique effect from an attack known by a single card
+; FoulOdorEffect ;
+; SpitPoison_Poison50PercentEffect ; unique effect made of more than one command.
+; SpitPoison_AIEffect ;
+
+EkansSpitPoisonEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SpitPoison_Poison50PercentEffect
+ dbw EFFECTCMDTYPE_AI, SpitPoison_AIEffect
+ db $00
+
+EkansWrapEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+ArbokTerrorStrikeEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, TerrorStrike_SwitchDefendingPokemon
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, TerrorStrike_50PercentSelectSwitchPokemon
+ dbw EFFECTCMDTYPE_AI_SWITCH_DEFENDING_PKMN, TerrorStrike_50PercentSelectSwitchPokemon
+ db $00
+
+ArbokPoisonFangEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PoisonEffect
+ dbw EFFECTCMDTYPE_AI, PoisonFang_AIEffect
+ db $00
+
+WeepinbellPoisonPowderEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Poison50PercentEffect
+ dbw EFFECTCMDTYPE_AI, WeepinbellPoisonPowder_AIEffect
+ db $00
+
+VictreebelLureEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, VictreebelLure_AssertPokemonInBench
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, VictreebelLure_SwitchDefendingPokemon
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, VictreebelLure_SelectSwitchPokemon
+ dbw EFFECTCMDTYPE_AI_SELECTION, VictreebelLure_GetBenchPokemonWithLowestHP
+ db $00
+
+VictreebelAcidEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, AcidEffect
+ db $00
+
+PinsirIronGripEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+CaterpieStringShotEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+GloomPoisonPowderEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PoisonEffect
+ dbw EFFECTCMDTYPE_AI, GloomPoisonPowder_AIEffect
+ db $00
+
+GloomFoulOdorEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, FoulOdorEffect
+ db $00
+
+KakunaStiffenEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, KakunaStiffenEffect
+ db $00
+
+KakunaPoisonPowderEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Poison50PercentEffect
+ dbw EFFECTCMDTYPE_AI, KakunaPoisonPowder_AIEffect
+ db $00
+
+GolbatLeechLifeEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, GolbatLeechLifeEffect
+ db $00
+
+VenonatStunSporeEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+VenonatLeechLifeEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, VenonatLeechLifeEffect
+ db $00
+
+ScytherSwordsDanceEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SwordsDanceEffect
+ db $00
+
+ZubatSupersonicEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ZubatSupersonicEffect
+ db $00
+
+ZubatLeechLifeEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, ZubatLeechLifeEffect
+ db $00
+
+BeedrillTwineedleEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Twineedle_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, Twineedle_AIEffect
+ db $00
+
+BeedrillPoisonStingEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Poison50PercentEffect
+ dbw EFFECTCMDTYPE_AI, BeedrillPoisonSting_AIEffect
+ db $00
+
+ExeggcuteHypnosisEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SleepEffect
+ db $00
+
+ExeggcuteLeechSeedEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, ExeggcuteLeechSeedEffect
+ db $00
+
+KoffingFoulGasEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, FoulGas_PoisonOrConfusionEffect
+ dbw EFFECTCMDTYPE_AI, FoulGas_AIEffect
+ db $00
+
+MetapodStiffenEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, MetapodStiffenEffect
+ db $00
+
+MetapodStunSporeEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+OddishStunSporeEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+OddishSproutEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Sprout_CheckDeckAndPlayArea
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Sprout_PutInPlayAreaEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Sprout_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, Sprout_AISelectEffect
+ db $00
+
+ExeggutorTeleportEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Teleport_CheckBench
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Teleport_SwitchEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Teleport_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, Teleport_AISelectEffect
+ db $00
+
+ExeggutorBigEggsplosionEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, BigEggsplosion_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, BigEggsplosion_AIEffect
+ db $00
+
+NidokingThrashEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Thrash_ModifierEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Thrash_RecoilEffect
+ dbw EFFECTCMDTYPE_AI, Thrash_AIEffect
+ db $00
+
+NidokingToxicEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Toxic_DoublePoisonEffect
+ dbw EFFECTCMDTYPE_AI, Toxic_AIEffect
+ db $00
+
+NidoqueenBoyfriendsEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, BoyfriendsEffect
+ db $00
+
+NidoranFFurySwipesEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, NidoranFFurySwipes_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, NidoranFFurySwipes_AIEffect
+ db $00
+
+NidoranFCallForFamilyEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, NidoranFCallForFamily_CheckDeckAndPlayArea
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, NidoranFCallForFamily_PutInPlayAreaEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, NidoranFCallForFamily_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, NidoranFCallForFamily_AISelectEffect
+ db $00
+
+NidoranMHornHazardEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, HornHazard_NoDamage50PercentEffect
+ dbw EFFECTCMDTYPE_AI, HornHazard_AIEffect
+ db $00
+
+NidorinaSupersonicEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, NidorinaSupersonicEffect
+ db $00
+
+NidorinaDoubleKickEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, NidorinaDoubleKick_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, NidorinaDoubleKick_AIEffect
+ db $00
+
+NidorinoDoubleKickEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, NidorinoDoubleKick_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, NidorinoDoubleKick_AIEffect
+ db $00
+
+ButterfreeWhirlwindEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, ButterfreeWhirlwind_SwitchEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, ButterfreeWhirlwind_CheckBench
+ dbw EFFECTCMDTYPE_AI_SWITCH_DEFENDING_PKMN, ButterfreeWhirlwind_CheckBench
+ db $00
+
+ButterfreeMegaDrainEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, ButterfreeMegaDrainEffect
+ db $00
+
+ParasSporeEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SleepEffect
+ db $00
+
+ParasectSporeEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SleepEffect
+ db $00
+
+WeedlePoisonStingEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Poison50PercentEffect
+ dbw EFFECTCMDTYPE_AI, WeedlePoisonSting_AIEffect
+ db $00
+
+IvysaurPoisonPowderEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PoisonEffect
+ dbw EFFECTCMDTYPE_AI, IvysaurPoisonPowder_AIEffect
+ db $00
+
+BulbasaurLeechSeedEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, BulbasaurLeechSeedEffect
+ db $00
+
+VenusaurEnergyTransEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, EnergyTrans_CheckPlayArea
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, EnergyTrans_TransferEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, EnergyTrans_AIEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, EnergyTrans_PrintProcedure
+ db $00
+
+GrimerNastyGooEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+GrimerMinimizeEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, GrimerMinimizeEffect
+ db $00
+
+MukToxicGasEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, ToxicGasEffect
+ db $00
+
+MukSludgeEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Poison50PercentEffect
+ dbw EFFECTCMDTYPE_AI, Sludge_AIEffect
+ db $00
+
+BellsproutCallForFamilyEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, BellsproutCallForFamily_CheckDeckAndPlayArea
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, BellsproutCallForFamily_PutInPlayAreaEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, BellsproutCallForFamily_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, BellsproutCallForFamily_AISelectEffect
+ db $00
+
+WeezingSmogEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Poison50PercentEffect
+ dbw EFFECTCMDTYPE_AI, WeezingSmog_AIEffect
+ db $00
+
+WeezingSelfdestructEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, WeezingSelfdestructEffect
+ db $00
+
+VenomothShiftEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Shift_OncePerTurnCheck
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Shift_ChangeColorEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Shift_PlayerSelectEffect
+ db $00
+
+VenomothVenomPowderEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, VenomPowder_PoisonConfusion50PercentEffect
+ dbw EFFECTCMDTYPE_AI, VenomPowder_AIEffect
+ db $00
+
+TangelaBindEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+TangelaPoisonPowderEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PoisonEffect
+ dbw EFFECTCMDTYPE_AI, TangelaPoisonPowder_AIEffect
+ db $00
+
+VileplumeHealEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Heal_OncePerTurnCheck
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Heal_RemoveDamageEffect
+ db $00
+
+VileplumePetalDanceEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PetalDance_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, PetalDance_AIEffect
+ db $00
+
+TangelaStunSporeEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+TangelaPoisonWhipEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PoisonEffect
+ dbw EFFECTCMDTYPE_AI, PoisonWhip_AIEffect
+ db $00
+
+VenusaurSolarPowerEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, SolarPower_CheckUse
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SolarPower_RemoveStatusEffect
+ db $00
+
+VenusaurMegaDrainEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, VenusaurMegaDrainEffect
+ db $00
+
+OmastarWaterGunEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, OmastarWaterGunEffect
+ dbw EFFECTCMDTYPE_AI, OmastarWaterGunEffect
+ db $00
+
+OmastarSpikeCannonEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, OmastarSpikeCannon_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, OmastarSpikeCannon_AIEffect
+ db $00
+
+OmanyteClairvoyanceEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, ClairvoyanceEffect
+ db $00
+
+OmanyteWaterGunEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, OmanyteWaterGunEffect
+ dbw EFFECTCMDTYPE_AI, OmanyteWaterGunEffect
+ db $00
+
+WartortleWithdrawEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, WartortleWithdrawEffect
+ db $00
+
+BlastoiseRainDanceEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, RainDanceEffect
+ db $00
+
+BlastoiseHydroPumpEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, HydroPumpEffect
+ dbw EFFECTCMDTYPE_AI, HydroPumpEffect
+ db $00
+
+GyaradosBubblebeamEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+KinglerFlailEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, KinglerFlail_HPCheck
+ dbw EFFECTCMDTYPE_AI, KinglerFlail_AIEffect
+ db $00
+
+KrabbyCallForFamilyEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, KrabbyCallForFamily_CheckDeckAndPlayArea
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, KrabbyCallForFamily_PutInPlayAreaEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, KrabbyCallForFamily_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, KrabbyCallForFamily_AISelectEffect
+ db $00
+
+MagikarpFlailEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, MagikarpFlail_HPCheck
+ dbw EFFECTCMDTYPE_AI, MagikarpFlail_AIEffect
+ db $00
+
+PsyduckHeadacheEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, HeadacheEffect
+ db $00
+
+PsyduckFurySwipesEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PsyduckFurySwipes_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, PsyduckFurySwipes_AIEffect
+ db $00
+
+GolduckPsyshockEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+GolduckHyperBeamEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, GolduckHyperBeam_DiscardEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, GolduckHyperBeam_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, GolduckHyperBeam_AISelectEffect
+ db $00
+
+SeadraWaterGunEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SeadraWaterGunEffect
+ dbw EFFECTCMDTYPE_AI, SeadraWaterGunEffect
+ db $00
+
+SeadraAgilityEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SeadraAgilityEffect
+ db $00
+
+ShellderSupersonicEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ShellderSupersonicEffect
+ db $00
+
+ShellderHideInShellEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, HideInShellEffect
+ db $00
+
+VaporeonQuickAttackEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, VaporeonQuickAttack_DamageBoostEffect
+ dbw EFFECTCMDTYPE_AI, VaporeonQuickAttack_AIEffect
+ db $00
+
+VaporeonWaterGunEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, VaporeonWaterGunEffect
+ dbw EFFECTCMDTYPE_AI, VaporeonWaterGunEffect
+ db $00
+
+DewgongIceBeamEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+StarmieRecoverEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, StarmieRecover_CheckEnergyHP
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, StarmieRecover_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, StarmieRecover_HealEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, StarmieRecover_DiscardEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, StarmieRecover_AISelectEffect
+ db $00
+
+StarmieStarFreezeEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+SquirtleBubbleEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+SquirtleWithdrawEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SquirtleWithdrawEffect
+ db $00
+
+HorseaSmokescreenEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, HorseaSmokescreenEffect
+ db $00
+
+TentacruelSupersonicEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, TentacruelSupersonicEffect
+ db $00
+
+TentacruelJellyfishStingEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PoisonEffect
+ dbw EFFECTCMDTYPE_AI, JellyfishSting_AIEffect
+ db $00
+
+PoliwhirlAmnesiaEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, PoliwhirlAmnesia_CheckAttacks
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, PoliwhirlAmnesia_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PoliwhirlAmnesia_DisableEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, PoliwhirlAmnesia_AISelectEffect
+ db $00
+
+PoliwhirlDoubleslapEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PoliwhirlDoubleslap_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, PoliwhirlDoubleslap_AIEffect
+ db $00
+
+PoliwrathWaterGunEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PoliwrathWaterGunEffect
+ dbw EFFECTCMDTYPE_AI, PoliwrathWaterGunEffect
+ db $00
+
+PoliwrathWhirlpoolEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Whirlpool_DiscardEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Whirlpool_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, Whirlpool_AISelectEffect
+ db $00
+
+PoliwagWaterGunEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PoliwagWaterGunEffect
+ dbw EFFECTCMDTYPE_AI, PoliwagWaterGunEffect
+ db $00
+
+CloysterClampEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ClampEffect
+ db $00
+
+CloysterSpikeCannonEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, CloysterSpikeCannon_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, CloysterSpikeCannon_AIEffect
+ db $00
+
+ArticunoFreezeDryEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+ArticunoBlizzardEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Blizzard_BenchDamage50PercentEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Blizzard_BenchDamageEffect
+ db $00
+
+TentacoolCowardiceEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Cowardice_Check
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Cowardice_RemoveFromPlayAreaEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Cowardice_PlayerSelectEffect
+ db $00
+
+LaprasWaterGunEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, LaprasWaterGunEffect
+ dbw EFFECTCMDTYPE_AI, LaprasWaterGunEffect
+ db $00
+
+LaprasConfuseRayEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Confusion50PercentEffect
+ db $00
+
+ArticunoQuickfreezeEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Quickfreeze_InitialEffect
+ dbw EFFECTCMDTYPE_PKMN_POWER_TRIGGER, Quickfreeze_Paralysis50PercentEffect
+ db $00
+
+ArticunoIceBreathEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, IceBreath_ZeroDamage
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, IceBreath_RandomPokemonDamageEffect
+ db $00
+
+VaporeonFocusEnergyEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, FocusEnergyEffect
+ db $00
+
+ArcanineFlamethrowerEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, ArcanineFlamethrower_CheckEnergy
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, ArcanineFlamethrower_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, ArcanineFlamethrower_DiscardEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, ArcanineFlamethrower_AISelectEffect
+ db $00
+
+ArcanineTakeDownEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, TakeDownEffect
+ db $00
+
+ArcanineQuickAttackEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ArcanineQuickAttack_DamageBoostEffect
+ dbw EFFECTCMDTYPE_AI, ArcanineQuickAttack_AIEffect
+ db $00
+
+ArcanineFlamesOfRageEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, FlamesOfRage_CheckEnergy
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, FlamesOfRage_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, FlamesOfRage_DamageBoostEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, FlamesOfRage_DiscardEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, FlamesOfRage_AISelectEffect
+ dbw EFFECTCMDTYPE_AI, FlamesOfRage_AIEffect
+ db $00
+
+RapidashStompEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, RapidashStomp_DamageBoostEffect
+ dbw EFFECTCMDTYPE_AI, RapidashStomp_AIEffect
+ db $00
+
+RapidashAgilityEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, RapidashAgilityEffect
+ db $00
+
+NinetalesLureEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, NinetalesLure_CheckBench
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, NinetalesLure_SwitchEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, NinetalesLure_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, NinetalesLure_AISelectEffect
+ db $00
+
+NinetalesFireBlastEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, FireBlast_CheckEnergy
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, FireBlast_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, FireBlast_DiscardEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, FireBlast_AISelectEffect
+ db $00
+
+CharmanderEmberEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Ember_CheckEnergy
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Ember_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, Ember_DiscardEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, Ember_AISelectEffect
+ db $00
+
+MoltresWildfireEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Wildfire_CheckEnergy
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Wildfire_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Wildfire_DiscardDeckEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, Wildfire_DiscardEnergyEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, Wildfire_AISelectEffect
+ db $00
+
+Moltres1DiveBombEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Moltres1DiveBomb_Success50PercentEffect
+ dbw EFFECTCMDTYPE_AI, Moltres1DiveBomb_AIEffect
+ db $00
+
+FlareonQuickAttackEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, FlareonQuickAttack_DamageBoostEffect
+ dbw EFFECTCMDTYPE_AI, FlareonQuickAttack_AIEffect
+ db $00
+
+FlareonFlamethrowerEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, FlareonFlamethrower_CheckEnergy
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, FlareonFlamethrower_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, FlareonFlamethrower_DiscardEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, FlareonFlamethrower_AISelectEffect
+ db $00
+
+MagmarFlamethrowerEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, MagmarFlamethrower_CheckEnergy
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, MagmarFlamethrower_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, MagmarFlamethrower_DiscardEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, MagmarFlamethrower_AISelectEffect
+ db $00
+
+MagmarSmokescreenEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, MagmarSmokescreenEffect
+ db $00
+
+MagmarSmogEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Poison50PercentEffect
+ dbw EFFECTCMDTYPE_AI, MagmarSmog_AIEffect
+ db $00
+
+CharmeleonFlamethrowerEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, CharmeleonFlamethrower_CheckEnergy
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, CharmeleonFlamethrower_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, CharmeleonFlamethrower_DiscardEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, CharmeleonFlamethrower_AISelectEffect
+ db $00
+
+CharizardEnergyBurnEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, EnergyBurnEffect
+ db $00
+
+CharizardFireSpinEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, FireSpin_CheckEnergy
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, FireSpin_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, FireSpin_DiscardEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, FireSpin_AISelectEffect
+ db $00
+
+VulpixConfuseRayEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Confusion50PercentEffect
+ db $00
+
+FlareonRageEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, FlareonRage_DamageBoostEffect
+ dbw EFFECTCMDTYPE_AI, FlareonRage_AIEffect
+ db $00
+
+NinetalesMixUpEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, MixUpEffect
+ db $00
+
+NinetalesDancingEmbersEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, DancingEmbers_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, DancingEmbers_AIEffect
+ db $00
+
+MoltresFiregiverEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Firegiver_InitialEffect
+ dbw EFFECTCMDTYPE_PKMN_POWER_TRIGGER, Firegiver_AddToHandEffect
+ db $00
+
+Moltres2DiveBombEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Moltres2DiveBomb_Success50PercentEffect
+ dbw EFFECTCMDTYPE_AI, Moltres2DiveBomb_AIEffect
+ db $00
+
+AbraPsyshockEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+GengarCurseEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Curse_CheckDamageAndBench
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Curse_TransferDamageEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Curse_PlayerSelectEffect
+ db $00
+
+GengarDarkMindEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, GengarDarkMind_DamageBenchEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, GengarDarkMind_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, GengarDarkMind_AISelectEffect
+ db $00
+
+GastlySleepingGasEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SleepingGasEffect
+ db $00
+
+GastlyDestinyBondEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, DestinyBond_CheckEnergy
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, DestinyBond_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, DestinyBond_DestinyBondEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, DestinyBond_DiscardEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, DestinyBond_AISelectEffect
+ db $00
+
+GastlyLickEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+GastlyEnergyConversionEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, EnergyConversion_CheckEnergy
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, EnergyConversion_AddToHandEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, EnergyConversion_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, EnergyConversion_AISelectEffect
+ db $00
+
+HaunterHypnosisEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SleepEffect
+ db $00
+
+HaunterDreamEaterEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, DreamEaterEffect
+ db $00
+
+HaunterTransparencyEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, TransparencyEffect
+ db $00
+
+HaunterNightmareEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SleepEffect
+ db $00
+
+HypnoProphecyEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Prophecy_CheckDeck
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Prophecy_ReorderDeckEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Prophecy_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, Prophecy_AISelectEffect
+ db $00
+
+HypnoDarkMindEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, HypnoDarkMind_DamageBenchEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, HypnoDarkMind_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, HypnoDarkMind_AISelectEffect
+ db $00
+
+DrowzeeConfuseRayEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Confusion50PercentEffect
+ db $00
+
+MrMimeInvisibleWallEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, InvisibleWallEffect
+ db $00
+
+MrMimeMeditateEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, MrMimeMeditate_DamageBoostEffect
+ dbw EFFECTCMDTYPE_AI, MrMimeMeditate_AIEffect
+ db $00
+
+AlakazamDamageSwapEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, DamageSwap_CheckDamage
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, DamageSwap_SelectAndSwapEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, DamageSwap_SwapEffect
+ db $00
+
+AlakazamConfuseRayEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Confusion50PercentEffect
+ db $00
+
+MewPsywaveEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PsywaveEffect
+ db $00
+
+MewDevolutionBeamEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, DevolutionBeam_CheckPlayArea
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, DevolutionBeam_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, DevolutionBeam_LoadAnimation
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, DevolutionBeam_DevolveEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, DevolutionBeam_AISelectEffect
+ db $00
+
+MewNeutralizingShieldEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, NeutralizingShieldEffect
+ db $00
+
+MewPsyshockEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+MewtwoPsychicEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Psychic_DamageBoostEffect
+ dbw EFFECTCMDTYPE_AI, Psychic_AIEffect
+ db $00
+
+MewtwoBarrierEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Barrier_CheckEnergy
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Barrier_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Barrier_BarrierEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, Barrier_DiscardEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, Barrier_AISelectEffect
+ db $00
+
+Mewtwo3EnergyAbsorptionEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Mewtwo3EnergyAbsorption_CheckDiscardPile
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Mewtwo3EnergyAbsorption_AddToHandEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Mewtwo3EnergyAbsorption_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, Mewtwo3EnergyAbsorption_AISelectEffect
+ db $00
+
+Mewtwo2EnergyAbsorptionEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Mewtwo2EnergyAbsorption_CheckDiscardPile
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Mewtwo2EnergyAbsorption_AddToHandEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Mewtwo2EnergyAbsorption_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, Mewtwo2EnergyAbsorption_AISelectEffect
+ db $00
+
+SlowbroStrangeBehaviorEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, StrangeBehavior_CheckDamage
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, StrangeBehavior_SelectAndSwapEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, StrangeBehavior_SwapEffect
+ db $00
+
+SlowbroPsyshockEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+SlowpokeSpacingOutEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, SpacingOut_CheckDamage
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SpacingOut_Success50PercentEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, SpacingOut_HealEffect
+ db $00
+
+SlowpokeScavengeEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Scavenge_CheckDiscardPile
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Scavenge_PlayerSelectEnergyEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Scavenge_AddToHandEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Scavenge_PlayerSelectTrainerEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, Scavenge_DiscardEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, Scavenge_AISelectEffect
+ db $00
+
+SlowpokeAmnesiaEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, SlowpokeAmnesia_CheckAttacks
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, SlowpokeAmnesia_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SlowpokeAmnesia_DisableEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, SlowpokeAmnesia_AISelectEffect
+ db $00
+
+KadabraRecoverEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, KadabraRecover_CheckEnergyHP
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, KadabraRecover_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, KadabraRecover_HealEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, KadabraRecover_DiscardEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, KadabraRecover_AISelectEffect
+ db $00
+
+JynxDoubleslapEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, JynxDoubleslap_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, JynxDoubleslap_AIEffect
+ db $00
+
+JynxMeditateEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, JynxMeditate_DamageBoostEffect
+ dbw EFFECTCMDTYPE_AI, JynxMeditate_AIEffect
+ db $00
+
+MewMysteryAttackEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, MysteryAttack_RandomEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, MysteryAttack_RecoverEffect
+ dbw EFFECTCMDTYPE_AI, MysteryAttack_AIEffect
+ db $00
+
+GeodudeStoneBarrageEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, StoneBarrage_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, StoneBarrage_AIEffect
+ db $00
+
+OnixHardenEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, OnixHardenEffect
+ db $00
+
+PrimeapeFurySwipesEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PrimeapeFurySwipes_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, PrimeapeFurySwipes_AIEffect
+ db $00
+
+PrimeapeTantrumEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, TantrumEffect
+ db $00
+
+MachampStrikesBackEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, StrikesBackEffect
+ db $00
+
+KabutoKabutoArmorEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, KabutoArmorEffect
+ db $00
+
+KabutopsAbsorbEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, AbsorbEffect
+ db $00
+
+CuboneSnivelEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SnivelEffect
+ db $00
+
+CuboneRageEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, CuboneRage_DamageBoostEffect
+ dbw EFFECTCMDTYPE_AI, CuboneRage_AIEffect
+ db $00
+
+MarowakBonemerangEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Bonemerang_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, Bonemerang_AIEffect
+ db $00
+
+MarowakCallforFriendEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, MarowakCallForFamily_CheckDeckAndPlayArea
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, MarowakCallForFamily_PutInPlayAreaEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, MarowakCallForFamily_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, MarowakCallForFamily_AISelectEffect
+ db $00
+
+MachokeKarateChopEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, KarateChop_DamageSubtractionEffect
+ dbw EFFECTCMDTYPE_AI, KarateChop_AIEffect
+ db $00
+
+MachokeSubmissionEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, SubmissionEffect
+ db $00
+
+GolemSelfdestructEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, GolemSelfdestructEffect
+ db $00
+
+GravelerHardenEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, GravelerHardenEffect
+ db $00
+
+RhydonRamEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Ram_RecoilSwitchEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Ram_SelectSwitchEffect
+ dbw EFFECTCMDTYPE_AI_SWITCH_DEFENDING_PKMN, Ram_SelectSwitchEffect
+ db $00
+
+RhyhornLeerEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, LeerEffect
+ db $00
+
+HitmonleeStretchKickEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, StretchKick_CheckBench
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, StretchKick_BenchDamageEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, StretchKick_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, StretchKick_AISelectEffect
+ db $00
+
+SandshrewSandAttackEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SandAttackEffect
+ db $00
+
+SandslashFurySwipesEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SandslashFurySwipes_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, SandslashFurySwipes_AIEffect
+ db $00
+
+DugtrioEarthquakeEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, EarthquakeEffect
+ db $00
+
+AerodactylPrehistoricPowerEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, PrehistoricPowerEffect
+ db $00
+
+MankeyPeekEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Peek_OncePerTurnCheck
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Peek_SelectEffect
+ db $00
+
+MarowakBoneAttackEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, BoneAttackEffect
+ db $00
+
+MarowakWailEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Wail_BenchCheck
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Wail_FillBenchEffect
+ db $00
+
+ElectabuzzThundershockEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+ElectabuzzThunderpunchEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Thunderpunch_ModifierEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Thunderpunch_RecoilEffect
+ dbw EFFECTCMDTYPE_AI, Thunderpunch_AIEffect
+ db $00
+
+ElectabuzzLightScreenEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, LightScreenEffect
+ db $00
+
+ElectabuzzQuickAttackEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ElectabuzzQuickAttack_DamageBoostEffect
+ dbw EFFECTCMDTYPE_AI, ElectabuzzQuickAttack_AIEffect
+ db $00
+
+MagnemiteThunderWaveEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+MagnemiteSelfdestructEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, MagnemiteSelfdestructEffect
+ db $00
+
+ZapdosThunderEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ZapdosThunder_Recoil50PercentEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, ZapdosThunder_RecoilEffect
+ db $00
+
+ZapdosThunderboltEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ThunderboltEffect
+ db $00
+
+ZapdosThunderstormEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, ThunderstormEffect
+ db $00
+
+JolteonQuickAttackEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, JolteonQuickAttack_DamageBoostEffect
+ dbw EFFECTCMDTYPE_AI, JolteonQuickAttack_AIEffect
+ db $00
+
+JolteonPinMissileEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PinMissile_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, PinMissile_AIEffect
+ db $00
+
+FlyingPikachuThundershockEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+FlyingPikachuFlyEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Fly_Success50PercentEffect
+ dbw EFFECTCMDTYPE_AI, Fly_AIEffect
+ db $00
+
+PikachuThunderJoltEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ThunderJolt_Recoil50PercentEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, ThunderJolt_RecoilEffect
+ db $00
+
+PikachuSparkEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Spark_BenchDamageEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Spark_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, Spark_AISelectEffect
+ db $00
+
+Pikachu3GrowlEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Pikachu3GrowlEffect
+ db $00
+
+Pikachu3ThundershockEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+Pikachu4GrowlEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Pikachu4GrowlEffect
+ db $00
+
+Pikachu4ThundershockEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+ElectrodeChainLightningEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, ChainLightningEffect
+ db $00
+
+RaichuAgilityEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, RaichuAgilityEffect
+ db $00
+
+RaichuThunderEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, RaichuThunder_Recoil50PercentEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, RaichuThunder_RecoilEffect
+ db $00
+
+RaichuGigashockEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Gigashock_BenchDamageEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Gigashock_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, Gigashock_AISelectEffect
+ db $00
+
+MagnetonThunderWaveEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+Magneton1SelfdestructEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Magneton1SelfdestructEffect
+ db $00
+
+MagnetonSonicboomEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, MagnetonSonicboom_UnaffectedByColorEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, MagnetonSonicboom_NullEffect
+ dbw EFFECTCMDTYPE_AI, MagnetonSonicboom_UnaffectedByColorEffect
+ db $00
+
+Magneton2SelfdestructEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Magneton2SelfdestructEffect
+ db $00
+
+ZapdosPealOfThunderEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, PealOfThunder_InitialEffect
+ dbw EFFECTCMDTYPE_PKMN_POWER_TRIGGER, PealOfThunder_RandomlyDamageEffect
+ db $00
+
+ZapdosBigThunderEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, BigThunderEffect
+ db $00
+
+MagnemiteMagneticStormEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, MagneticStormEffect
+ db $00
+
+ElectrodeSonicboomEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ElectrodeSonicboom_UnaffectedByColorEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, ElectrodeSonicboom_NullEffect
+ dbw EFFECTCMDTYPE_AI, ElectrodeSonicboom_UnaffectedByColorEffect
+ db $00
+
+ElectrodeEnergySpikeEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, EnergySpike_DeckCheck
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, EnergySpike_AttachEnergyEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, EnergySpike_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, EnergySpike_AISelectEffect
+ db $00
+
+JolteonDoubleKickEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, JolteonDoubleKick_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, JolteonDoubleKick_AIEffect
+ db $00
+
+JolteonStunNeedleEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+EeveeTailWagEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, TailWagEffect
+ db $00
+
+EeveeQuickAttackEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, EeveeQuickAttack_DamageBoostEffect
+ dbw EFFECTCMDTYPE_AI, EeveeQuickAttack_AIEffect
+ db $00
+
+SpearowMirrorMoveEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, SpearowMirrorMove_InitialEffect1
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, SpearowMirrorMove_InitialEffect2
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SpearowMirrorMove_BeforeDamage
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, SpearowMirrorMove_AfterDamage
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, SpearowMirrorMove_PlayerSelection
+ dbw EFFECTCMDTYPE_AI_SELECTION, SpearowMirrorMove_AISelection
+ dbw EFFECTCMDTYPE_AI, SpearowMirrorMove_AIEffect
+ db $00
+
+FearowAgilityEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, FearowAgilityEffect
+ db $00
+
+DragoniteStepInEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, StepIn_BenchCheck
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, StepIn_SwitchEffect
+ db $00
+
+Dragonite2SlamEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Dragonite2Slam_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, Dragonite2Slam_AIEffect
+ db $00
+
+SnorlaxThickSkinnedEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, ThickSkinnedEffect
+ db $00
+
+SnorlaxBodySlamEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+FarfetchdLeekSlapEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, LeekSlap_OncePerDuelCheck
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, LeekSlap_NoDamage50PercentEffect
+ dbw EFFECTCMDTYPE_DISCARD_ENERGY, LeekSlap_SetUsedThisDuelFlag
+ dbw EFFECTCMDTYPE_AI, LeekSlap_AIEffect
+ db $00
+
+KangaskhanFetchEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, FetchEffect
+ db $00
+
+KangaskhanCometPunchEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, CometPunch_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, CometPunch_AIEffect
+ db $00
+
+TaurosStompEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, TaurosStomp_DamageBoostEffect
+ dbw EFFECTCMDTYPE_AI, TaurosStomp_AIEffect
+ db $00
+
+TaurosRampageEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Rampage_Confusion50PercentEffect
+ dbw EFFECTCMDTYPE_AI, Rampage_AIEffect
+ db $00
+
+DoduoFuryAttackEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, FuryAttack_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, FuryAttack_AIEffect
+ db $00
+
+DodrioRetreatAidEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, RetreatAidEffect
+ db $00
+
+DodrioRageEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, DodrioRage_DamageBoostEffect
+ dbw EFFECTCMDTYPE_AI, DodrioRage_AIEffect
+ db $00
+
+MeowthPayDayEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, PayDayEffect
+ db $00
+
+DragonairSlamEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, DragonairSlam_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, DragonairSlam_AIEffect
+ db $00
+
+DragonairHyperBeamEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, DragonairHyperBeam_DiscardEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, DragonairHyperBeam_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, DragonairHyperBeam_AISelectEffect
+ db $00
+
+ClefableMetronomeEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, ClefableMetronome_CheckAttacks
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, ClefableMetronome_UseAttackEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, ClefableMetronome_AISelectEffect
+ db $00
+
+ClefableMinimizeEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ClefableMinimizeEffect
+ db $00
+
+PidgeotHurricaneEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, HurricaneEffect
+ db $00
+
+PidgeottoWhirlwindEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, PidgeottoWhirlwind_SwitchEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, PidgeottoWhirlwind_SelectEffect
+ dbw EFFECTCMDTYPE_AI_SWITCH_DEFENDING_PKMN, PidgeottoWhirlwind_SelectEffect
+ db $00
+
+PidgeottoMirrorMoveEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, PidgeottoMirrorMove_InitialEffect1
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, PidgeottoMirrorMove_InitialEffect2
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PidgeottoMirrorMove_BeforeDamage
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, PidgeottoMirrorMove_AfterDamage
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, PidgeottoMirrorMove_PlayerSelection
+ dbw EFFECTCMDTYPE_AI_SELECTION, PidgeottoMirrorMove_AISelection
+ dbw EFFECTCMDTYPE_AI, PidgeottoMirrorMove_AIEffect
+ db $00
+
+ClefairySingEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SingEffect
+ db $00
+
+ClefairyMetronomeEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, ClefairyMetronome_CheckAttacks
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, ClefairyMetronome_UseAttackEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, ClefairyMetronome_AISelectEffect
+ db $00
+
+WigglytuffLullabyEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SleepEffect
+ db $00
+
+WigglytuffDoTheWaveEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, DoTheWaveEffect
+ dbw EFFECTCMDTYPE_AI, DoTheWaveEffect
+ db $00
+
+JigglypuffLullabyEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SleepEffect
+ db $00
+
+JigglypuffFirstAidEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, FirstAid_DamageCheck
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, FirstAid_HealEffect
+ db $00
+
+JigglypuffDoubleEdgeEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, JigglypuffDoubleEdgeEffect
+ db $00
+
+PersianPounceEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PounceEffect
+ db $00
+
+LickitungTongueWrapEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Paralysis50PercentEffect
+ db $00
+
+LickitungSupersonicEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, LickitungSupersonicEffect
+ db $00
+
+PidgeyWhirlwindEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, PidgeyWhirlwind_SwitchEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, PidgeyWhirlwind_SelectEffect
+ dbw EFFECTCMDTYPE_AI_SWITCH_DEFENDING_PKMN, PidgeyWhirlwind_SelectEffect
+ db $00
+
+PorygonConversion1EffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Conversion1_WeaknessCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Conversion1_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Conversion1_ChangeWeaknessEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, Conversion1_AISelectEffect
+ db $00
+
+PorygonConversion2EffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Conversion2_ResistanceCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Conversion2_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Conversion2_ChangeResistanceEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, Conversion2_AISelectEffect
+ db $00
+
+ChanseyScrunchEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ScrunchEffect
+ db $00
+
+ChanseyDoubleEdgeEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, ChanseyDoubleEdgeEffect
+ db $00
+
+RaticateSuperFangEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SuperFang_HalfHPEffect
+ dbw EFFECTCMDTYPE_AI, SuperFang_AIEffect
+ db $00
+
+TrainerCardAsPokemonEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, TrainerCardAsPokemon_BenchCheck
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, TrainerCardAsPokemon_DiscardEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, TrainerCardAsPokemon_PlayerSelectSwitch
+ db $00
+
+DragoniteHealingWindEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, HealingWind_InitialEffect
+ dbw EFFECTCMDTYPE_PKMN_POWER_TRIGGER, HealingWind_PlayAreaHealEffect
+ db $00
+
+Dragonite1SlamEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Dragonite1Slam_MultiplierEffect
+ dbw EFFECTCMDTYPE_AI, Dragonite1Slam_AIEffect
+ db $00
+
+MeowthCatPunchEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, CatPunchEffect
+ db $00
+
+DittoMorphEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, MorphEffect
+ db $00
+
+PidgeotSlicingWindEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, SlicingWindEffect
+ db $00
+
+PidgeotGaleEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Gale_LoadAnimation
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, Gale_SwitchEffect
+ db $00
+
+JigglypuffFriendshipSongEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, FriendshipSong_BenchCheck
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, FriendshipSong_AddToBench50PercentEffect
+ db $00
+
+JigglypuffExpandEffectCommands:
+ dbw EFFECTCMDTYPE_AFTER_DAMAGE, ExpandEffect
+ db $00
+
+DoubleColorlessEnergyEffectCommands:
+ db $00
+
+PsychicEnergyEffectCommands:
+ db $00
+
+FightingEnergyEffectCommands:
+ db $00
+
+LightningEnergyEffectCommands:
+ db $00
+
+WaterEnergyEffectCommands:
+ db $00
+
+FireEnergyEffectCommands:
+ db $00
+
+GrassEnergyEffectCommands:
+ db $00
+
+SuperPotionEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, SuperPotion_DamageEnergyCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, SuperPotion_PlayerSelectEffect
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SuperPotion_HealEffect
+ db $00
+
+ImakuniEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ImakuniEffect
+ db $00
+
+EnergyRemovalEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, EnergyRemoval_EnergyCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, EnergyRemoval_PlayerSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, EnergyRemoval_DiscardEffect
+ dbw EFFECTCMDTYPE_AI_SELECTION, EnergyRemoval_AISelection
+ db $00
+
+EnergyRetrievalEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, EnergyRetrieval_HandEnergyCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, EnergyRetrieval_PlayerHandSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, EnergyRetrieval_DiscardAndAddToHandEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, EnergyRetrieval_PlayerDiscardPileSelection
+ db $00
+
+EnergySearchEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, EnergySearch_DeckCheck
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, EnergySearch_AddToHandEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, EnergySearch_PlayerSelection
+ db $00
+
+ProfessorOakEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ProfessorOakEffect
+ db $00
+
+PotionEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Potion_DamageCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Potion_PlayerSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Potion_HealEffect
+ db $00
+
+GamblerEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, GamblerEffect
+ db $00
+
+ItemFinderEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, ItemFinder_HandDiscardPileCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, ItemFinder_PlayerSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ItemFinder_DiscardAddToHandEffect
+ db $00
+
+DefenderEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Defender_PlayerSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Defender_AttachDefenderEffect
+ db $00
+
+MysteriousFossilEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, MysteriousFossil_BenchCheck
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, MysteriousFossil_PlaceInPlayAreaEffect
+ db $00
+
+FullHealEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, FullHeal_StatusCheck
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, FullHeal_ClearStatusEffect
+ db $00
+
+ImposterProfessorOakEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ImposterProfessorOakEffect
+ db $00
+
+ComputerSearchEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, ComputerSearch_HandDeckCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, ComputerSearch_PlayerDiscardHandSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ComputerSearch_DiscardAddToHandEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, ComputerSearch_PlayerDeckSelection
+ db $00
+
+ClefairyDollEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, ClefairyDoll_BenchCheck
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ClefairyDoll_PlaceInPlayAreaEffect
+ db $00
+
+MrFujiEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, MrFuji_BenchCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, MrFuji_PlayerSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, MrFuji_ReturnToDeckEffect
+ db $00
+
+PlusPowerEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PlusPowerEffect
+ db $00
+
+SwitchEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Switch_BenchCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Switch_PlayerSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Switch_SwitchEffect
+ db $00
+
+PokemonCenterEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, PokemonCenter_DamageCheck
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PokemonCenter_HealDiscardEnergyEffect
+ db $00
+
+PokemonFluteEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, PokemonFlute_BenchCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, PokemonFlute_PlayerSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PokemonFlute_PlaceInPlayAreaText
+ db $00
+
+PokemonBreederEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, PokemonBreeder_HandPlayAreaCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, PokemonBreeder_PlayerSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PokemonBreeder_EvolveEffect
+ db $00
+
+ScoopUpEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, ScoopUp_BenchCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, ScoopUp_PlayerSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, ScoopUp_ReturnToHandEffect
+ db $00
+
+PokemonTraderEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, PokemonTrader_HandDeckCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, PokemonTrader_PlayerHandSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PokemonTrader_TradeCardsEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, PokemonTrader_PlayerDeckSelection
+ db $00
+
+PokedexEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Pokedex_DeckCheck
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Pokedex_OrderDeckCardsEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Pokedex_PlayerSelection
+ db $00
+
+BillEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, BillEffect
+ db $00
+
+LassEffectCommands:
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, LassEffect
+ db $00
+
+MaintenanceEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Maintenance_HandCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Maintenance_PlayerSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Maintenance_ReturnToDeckAndDrawEffect
+ db $00
+
+PokeBallEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, PokeBall_DeckCheck
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, PokeBall_AddToHandEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, PokeBall_PlayerSelection
+ db $00
+
+RecycleEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Recycle_DiscardPileCheck
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Recycle_AddToHandEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, Recycle_PlayerSelection
+ db $00
+
+ReviveEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, Revive_BenchCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, Revive_PlayerSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, Revive_PlaceInPlayAreaEffect
+ db $00
+
+DevolutionSprayEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, DevolutionSpray_PlayAreaEvolutionCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, DevolutionSpray_PlayerSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, DevolutionSpray_DevolutionEffect
+ db $00
+
+SuperEnergyRemovalEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, SuperEnergyRemoval_EnergyCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, SuperEnergyRemoval_PlayerSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SuperEnergyRemoval_DiscardEffect
+ db $00
+
+SuperEnergyRetrievalEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, SuperEnergyRetrieval_HandEnergyCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, SuperEnergyRetrieval_PlayerHandSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, SuperEnergyRetrieval_DiscardAndAddToHandEffect
+ dbw EFFECTCMDTYPE_REQUIRE_SELECTION, SuperEnergyRetrieval_PlayerDiscardPileSelection
+ db $00
+
+GustOfWindEffectCommands:
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_1, GustOfWind_BenchCheck
+ dbw EFFECTCMDTYPE_INITIAL_EFFECT_2, GustOfWind_PlayerSelection
+ dbw EFFECTCMDTYPE_BEFORE_DAMAGE, GustOfWind_SwitchEffect
+ db $00
diff --git a/src/engine/effect_functions.asm b/src/engine/duel/effect_functions.asm
index ce3a517..ce3a517 100644
--- a/src/engine/effect_functions.asm
+++ b/src/engine/duel/effect_functions.asm
diff --git a/src/engine/game_loop.asm b/src/engine/game_loop.asm
index c3745b6..d6e4fab 100644
--- a/src/engine/game_loop.asm
+++ b/src/engine/game_loop.asm
@@ -15,7 +15,7 @@ GameLoop:
ld a, 1
ld [wUppercaseHalfWidthLetters], a
ei
- farcall CommentedOut_1a6cc
+ farcall StubbedUnusedSaveDataValidation
ldh a, [hKeysHeld]
cp A_BUTTON | B_BUTTON
jr z, .ask_erase_backup_ram
diff --git a/src/engine/gfx/gfx_table_pointers.asm b/src/engine/gfx/gfx_table_pointers.asm
new file mode 100644
index 0000000..370ed15
--- /dev/null
+++ b/src/engine/gfx/gfx_table_pointers.asm
@@ -0,0 +1,6 @@
+GfxTablePointers:
+ dw Tilemaps
+ dw Tilesets
+ dw Sprites
+ dw SpriteAnimations
+ dw Palettes
diff --git a/src/engine/gfx/palettes.asm b/src/engine/gfx/palettes.asm
new file mode 100644
index 0000000..8a0d71a
--- /dev/null
+++ b/src/engine/gfx/palettes.asm
@@ -0,0 +1,170 @@
+; \1 = palette pointer
+; \2 = number of palettes
+; \3 = number of OBJ colors
+palette_pointer: MACRO
+ dwb \1, BANK(\1) - BANK(Palettes)
+ db (\2 << 4) + \3
+ENDM
+
+Palettes:
+ palette_pointer Palette0, 8, 1 ; PALETTE_0
+ palette_pointer Palette1, 8, 0 ; PALETTE_1
+ palette_pointer Palette2, 8, 0 ; PALETTE_2
+ palette_pointer Palette3, 8, 0 ; PALETTE_3
+ palette_pointer Palette4, 8, 0 ; PALETTE_4
+ palette_pointer Palette5, 8, 0 ; PALETTE_5
+ palette_pointer Palette6, 8, 0 ; PALETTE_6
+ palette_pointer Palette7, 8, 0 ; PALETTE_7
+ palette_pointer Palette8, 8, 0 ; PALETTE_8
+ palette_pointer Palette9, 8, 0 ; PALETTE_9
+ palette_pointer Palette10, 8, 0 ; PALETTE_10
+ palette_pointer Palette11, 8, 0 ; PALETTE_11
+ palette_pointer Palette12, 8, 0 ; PALETTE_12
+ palette_pointer Palette13, 8, 0 ; PALETTE_13
+ palette_pointer Palette14, 8, 0 ; PALETTE_14
+ palette_pointer Palette15, 8, 0 ; PALETTE_15
+ palette_pointer Palette16, 8, 0 ; PALETTE_16
+ palette_pointer Palette17, 8, 0 ; PALETTE_17
+ palette_pointer Palette18, 8, 0 ; PALETTE_18
+ palette_pointer Palette19, 8, 0 ; PALETTE_19
+ palette_pointer Palette20, 8, 0 ; PALETTE_20
+ palette_pointer Palette21, 8, 0 ; PALETTE_21
+ palette_pointer Palette22, 8, 0 ; PALETTE_22
+ palette_pointer Palette23, 8, 0 ; PALETTE_23
+ palette_pointer Palette24, 8, 0 ; PALETTE_24
+ palette_pointer Palette25, 8, 0 ; PALETTE_25
+ palette_pointer Palette26, 8, 0 ; PALETTE_26
+ palette_pointer Palette27, 8, 0 ; PALETTE_27
+ palette_pointer Palette28, 8, 0 ; PALETTE_28
+ palette_pointer Palette29, 8, 2 ; PALETTE_29
+ palette_pointer Palette30, 8, 2 ; PALETTE_30
+ palette_pointer Palette31, 1, 1 ; PALETTE_31
+ palette_pointer Palette32, 1, 1 ; PALETTE_32
+ palette_pointer Palette33, 1, 1 ; PALETTE_33
+ palette_pointer Palette34, 1, 1 ; PALETTE_34
+ palette_pointer Palette35, 1, 1 ; PALETTE_35
+ palette_pointer Palette36, 1, 1 ; PALETTE_36
+ palette_pointer Palette37, 1, 1 ; PALETTE_37
+ palette_pointer Palette38, 1, 1 ; PALETTE_38
+ palette_pointer Palette39, 1, 1 ; PALETTE_39
+ palette_pointer Palette40, 1, 1 ; PALETTE_40
+ palette_pointer Palette41, 1, 1 ; PALETTE_41
+ palette_pointer Palette42, 1, 1 ; PALETTE_42
+ palette_pointer Palette43, 1, 1 ; PALETTE_43
+ palette_pointer Palette44, 1, 1 ; PALETTE_44
+ palette_pointer Palette45, 1, 1 ; PALETTE_45
+ palette_pointer Palette46, 1, 1 ; PALETTE_46
+ palette_pointer Palette47, 1, 1 ; PALETTE_47
+ palette_pointer Palette48, 1, 1 ; PALETTE_48
+ palette_pointer Palette49, 1, 1 ; PALETTE_49
+ palette_pointer Palette50, 1, 1 ; PALETTE_50
+ palette_pointer Palette51, 1, 1 ; PALETTE_51
+ palette_pointer Palette52, 1, 1 ; PALETTE_52
+ palette_pointer Palette53, 1, 1 ; PALETTE_53
+ palette_pointer Palette54, 1, 1 ; PALETTE_54
+ palette_pointer Palette55, 1, 1 ; PALETTE_55
+ palette_pointer Palette56, 1, 1 ; PALETTE_56
+ palette_pointer Palette57, 1, 1 ; PALETTE_57
+ palette_pointer Palette58, 1, 1 ; PALETTE_58
+ palette_pointer Palette59, 1, 1 ; PALETTE_59
+ palette_pointer Palette60, 1, 1 ; PALETTE_60
+ palette_pointer Palette61, 1, 1 ; PALETTE_61
+ palette_pointer Palette62, 1, 1 ; PALETTE_62
+ palette_pointer Palette63, 1, 1 ; PALETTE_63
+ palette_pointer Palette64, 1, 1 ; PALETTE_64
+ palette_pointer Palette65, 1, 1 ; PALETTE_65
+ palette_pointer Palette66, 1, 1 ; PALETTE_66
+ palette_pointer Palette67, 1, 1 ; PALETTE_67
+ palette_pointer Palette68, 1, 1 ; PALETTE_68
+ palette_pointer Palette69, 1, 1 ; PALETTE_69
+ palette_pointer Palette70, 1, 1 ; PALETTE_70
+ palette_pointer Palette71, 1, 1 ; PALETTE_71
+ palette_pointer Palette72, 1, 1 ; PALETTE_72
+ palette_pointer Palette73, 1, 1 ; PALETTE_73
+ palette_pointer Palette74, 1, 1 ; PALETTE_74
+ palette_pointer Palette75, 1, 1 ; PALETTE_75
+ palette_pointer Palette76, 1, 1 ; PALETTE_76
+ palette_pointer Palette77, 1, 1 ; PALETTE_77
+ palette_pointer Palette78, 1, 1 ; PALETTE_78
+ palette_pointer Palette79, 1, 1 ; PALETTE_79
+ palette_pointer Palette80, 1, 1 ; PALETTE_80
+ palette_pointer Palette81, 1, 1 ; PALETTE_81
+ palette_pointer Palette82, 1, 1 ; PALETTE_82
+ palette_pointer Palette83, 1, 1 ; PALETTE_83
+ palette_pointer Palette84, 1, 1 ; PALETTE_84
+ palette_pointer Palette85, 1, 1 ; PALETTE_85
+ palette_pointer Palette86, 1, 1 ; PALETTE_86
+ palette_pointer Palette87, 1, 1 ; PALETTE_87
+ palette_pointer Palette88, 1, 1 ; PALETTE_88
+ palette_pointer Palette89, 1, 1 ; PALETTE_89
+ palette_pointer Palette90, 1, 1 ; PALETTE_90
+ palette_pointer Palette91, 1, 1 ; PALETTE_91
+ palette_pointer Palette92, 1, 1 ; PALETTE_92
+ palette_pointer Palette93, 1, 1 ; PALETTE_93
+ palette_pointer Palette94, 8, 0 ; PALETTE_94
+ palette_pointer Palette95, 8, 0 ; PALETTE_95
+ palette_pointer Palette96, 8, 0 ; PALETTE_96
+ palette_pointer Palette97, 8, 0 ; PALETTE_97
+ palette_pointer Palette98, 8, 0 ; PALETTE_98
+ palette_pointer Palette99, 8, 0 ; PALETTE_99
+ palette_pointer Palette100, 8, 0 ; PALETTE_100
+ palette_pointer Palette101, 7, 0 ; PALETTE_101
+ palette_pointer Palette102, 7, 0 ; PALETTE_102
+ palette_pointer Palette103, 7, 0 ; PALETTE_103
+ palette_pointer Palette104, 7, 0 ; PALETTE_104
+ palette_pointer Palette105, 7, 0 ; PALETTE_105
+ palette_pointer Palette106, 7, 0 ; PALETTE_106
+ palette_pointer Palette107, 7, 0 ; PALETTE_107
+ palette_pointer Palette108, 0, 1 ; PALETTE_108
+ palette_pointer Palette109, 0, 1 ; PALETTE_109
+ palette_pointer Palette110, 0, 0 ; PALETTE_110
+ palette_pointer Palette111, 8, 1 ; PALETTE_111
+ palette_pointer Palette112, 8, 1 ; PALETTE_112
+ palette_pointer Palette113, 8, 1 ; PALETTE_113
+ palette_pointer Palette114, 4, 2 ; PALETTE_114
+ palette_pointer Palette115, 4, 2 ; PALETTE_115
+ palette_pointer Palette116, 4, 2 ; PALETTE_116
+ palette_pointer Palette117, 1, 0 ; PALETTE_117
+ palette_pointer Palette118, 6, 0 ; PALETTE_118
+ palette_pointer Palette119, 1, 0 ; PALETTE_119
+ palette_pointer Palette120, 1, 0 ; PALETTE_120
+ palette_pointer Palette121, 1, 0 ; PALETTE_121
+ palette_pointer Palette122, 1, 0 ; PALETTE_122
+ palette_pointer Palette123, 1, 0 ; PALETTE_123
+ palette_pointer Palette124, 1, 0 ; PALETTE_124
+ palette_pointer Palette125, 1, 0 ; PALETTE_125
+ palette_pointer Palette126, 1, 0 ; PALETTE_126
+ palette_pointer Palette127, 1, 0 ; PALETTE_127
+ palette_pointer Palette128, 1, 0 ; PALETTE_128
+ palette_pointer Palette129, 1, 0 ; PALETTE_129
+ palette_pointer Palette130, 1, 0 ; PALETTE_130
+ palette_pointer Palette131, 1, 0 ; PALETTE_131
+ palette_pointer Palette132, 1, 0 ; PALETTE_132
+ palette_pointer Palette133, 1, 0 ; PALETTE_133
+ palette_pointer Palette134, 1, 0 ; PALETTE_134
+ palette_pointer Palette135, 1, 0 ; PALETTE_135
+ palette_pointer Palette136, 1, 0 ; PALETTE_136
+ palette_pointer Palette137, 1, 0 ; PALETTE_137
+ palette_pointer Palette138, 1, 0 ; PALETTE_138
+ palette_pointer Palette139, 1, 0 ; PALETTE_139
+ palette_pointer Palette140, 1, 0 ; PALETTE_140
+ palette_pointer Palette141, 1, 0 ; PALETTE_141
+ palette_pointer Palette142, 1, 0 ; PALETTE_142
+ palette_pointer Palette143, 1, 0 ; PALETTE_143
+ palette_pointer Palette144, 1, 0 ; PALETTE_144
+ palette_pointer Palette145, 1, 0 ; PALETTE_145
+ palette_pointer Palette146, 1, 0 ; PALETTE_146
+ palette_pointer Palette147, 1, 0 ; PALETTE_147
+ palette_pointer Palette148, 1, 0 ; PALETTE_148
+ palette_pointer Palette149, 1, 0 ; PALETTE_149
+ palette_pointer Palette150, 1, 0 ; PALETTE_150
+ palette_pointer Palette151, 1, 0 ; PALETTE_151
+ palette_pointer Palette152, 1, 0 ; PALETTE_152
+ palette_pointer Palette153, 1, 0 ; PALETTE_153
+ palette_pointer Palette154, 1, 0 ; PALETTE_154
+ palette_pointer Palette155, 1, 0 ; PALETTE_155
+ palette_pointer Palette156, 1, 0 ; PALETTE_156
+ palette_pointer Palette157, 1, 0 ; PALETTE_157
+ palette_pointer Palette158, 1, 0 ; PALETTE_158
+ palette_pointer Palette159, 1, 0 ; PALETTE_159
+ palette_pointer Palette160, 1, 0 ; PALETTE_160
diff --git a/src/engine/gfx/sprite_animations.asm b/src/engine/gfx/sprite_animations.asm
new file mode 100644
index 0000000..7c432c6
--- /dev/null
+++ b/src/engine/gfx/sprite_animations.asm
@@ -0,0 +1,224 @@
+; \1 = anim data pointer
+anim_data_pointer: MACRO
+ dwb \1, BANK(\1) - BANK(SpriteAnimations)
+ db $00 ; unused (padding?)
+ENDM
+
+SpriteAnimations:
+ anim_data_pointer AnimData0 ; SPRITE_ANIM_LIGHT_NPC_UP
+ anim_data_pointer AnimData1 ; SPRITE_ANIM_LIGHT_NPC_RIGHT
+ anim_data_pointer AnimData2 ; SPRITE_ANIM_LIGHT_NPC_DOWN
+ anim_data_pointer AnimData3 ; SPRITE_ANIM_LIGHT_NPC_LEFT
+ anim_data_pointer AnimData4 ; SPRITE_ANIM_DARK_NPC_UP
+ anim_data_pointer AnimData5 ; SPRITE_ANIM_DARK_NPC_RIGHT
+ anim_data_pointer AnimData6 ; SPRITE_ANIM_DARK_NPC_DOWN
+ anim_data_pointer AnimData7 ; SPRITE_ANIM_DARK_NPC_LEFT
+ anim_data_pointer AnimData8 ; SPRITE_ANIM_SGB_AMY_LAYING
+ anim_data_pointer AnimData9 ; SPRITE_ANIM_SGB_AMY_STAND
+ anim_data_pointer AnimData10 ; SPRITE_ANIM_SGB_CLERK_NPC_UP
+ anim_data_pointer AnimData11 ; SPRITE_ANIM_SGB_CLERK_NPC_RIGHT
+ anim_data_pointer AnimData12 ; SPRITE_ANIM_SGB_CLERK_NPC_DOWN
+ anim_data_pointer AnimData13 ; SPRITE_ANIM_SGB_CLERK_NPC_LEFT
+ anim_data_pointer AnimData14 ; SPRITE_ANIM_BLUE_NPC_UP
+ anim_data_pointer AnimData15 ; SPRITE_ANIM_BLUE_NPC_RIGHT
+ anim_data_pointer AnimData16 ; SPRITE_ANIM_BLUE_NPC_DOWN
+ anim_data_pointer AnimData17 ; SPRITE_ANIM_BLUE_NPC_LEFT
+ anim_data_pointer AnimData18 ; SPRITE_ANIM_PINK_NPC_UP
+ anim_data_pointer AnimData19 ; SPRITE_ANIM_PINK_NPC_RIGHT
+ anim_data_pointer AnimData20 ; SPRITE_ANIM_PINK_NPC_DOWN
+ anim_data_pointer AnimData21 ; SPRITE_ANIM_PINK_NPC_LEFT
+ anim_data_pointer AnimData22 ; SPRITE_ANIM_YELLOW_NPC_UP
+ anim_data_pointer AnimData23 ; SPRITE_ANIM_YELLOW_NPC_RIGHT
+ anim_data_pointer AnimData24 ; SPRITE_ANIM_YELLOW_NPC_DOWN
+ anim_data_pointer AnimData25 ; SPRITE_ANIM_YELLOW_NPC_LEFT
+ anim_data_pointer AnimData26 ; SPRITE_ANIM_GREEN_NPC_UP
+ anim_data_pointer AnimData27 ; SPRITE_ANIM_GREEN_NPC_RIGHT
+ anim_data_pointer AnimData28 ; SPRITE_ANIM_GREEN_NPC_DOWN
+ anim_data_pointer AnimData29 ; SPRITE_ANIM_GREEN_NPC_LEFT
+ anim_data_pointer AnimData30 ; SPRITE_ANIM_RED_NPC_UP
+ anim_data_pointer AnimData31 ; SPRITE_ANIM_RED_NPC_RIGHT
+ anim_data_pointer AnimData32 ; SPRITE_ANIM_RED_NPC_DOWN
+ anim_data_pointer AnimData33 ; SPRITE_ANIM_RED_NPC_LEFT
+ anim_data_pointer AnimData34 ; SPRITE_ANIM_PURPLE_NPC_UP
+ anim_data_pointer AnimData35 ; SPRITE_ANIM_PURPLE_NPC_RIGHT
+ anim_data_pointer AnimData36 ; SPRITE_ANIM_PURPLE_NPC_DOWN
+ anim_data_pointer AnimData37 ; SPRITE_ANIM_PURPLE_NPC_LEFT
+ anim_data_pointer AnimData38 ; SPRITE_ANIM_WHITE_NPC_UP
+ anim_data_pointer AnimData39 ; SPRITE_ANIM_WHITE_NPC_RIGHT
+ anim_data_pointer AnimData40 ; SPRITE_ANIM_WHITE_NPC_DOWN
+ anim_data_pointer AnimData41 ; SPRITE_ANIM_WHITE_NPC_LEFT
+ anim_data_pointer AnimData42 ; SPRITE_ANIM_INDIGO_NPC_UP
+ anim_data_pointer AnimData43 ; SPRITE_ANIM_INDIGO_NPC_RIGHT
+ anim_data_pointer AnimData44 ; SPRITE_ANIM_INDIGO_NPC_DOWN
+ anim_data_pointer AnimData45 ; SPRITE_ANIM_INDIGO_NPC_LEFT
+ anim_data_pointer AnimData46 ; SPRITE_ANIM_CGB_AMY_LAYING
+ anim_data_pointer AnimData47 ; SPRITE_ANIM_CGB_AMY_STAND
+ anim_data_pointer AnimData48 ; SPRITE_ANIM_CGB_CLERK_NPC_UP
+ anim_data_pointer AnimData49 ; SPRITE_ANIM_CGB_CLERK_NPC_RIGHT
+ anim_data_pointer AnimData50 ; SPRITE_ANIM_CGB_CLERK_NPC_DOWN
+ anim_data_pointer AnimData51 ; SPRITE_ANIM_CGB_CLERK_NPC_LEFT
+ anim_data_pointer AnimData52 ; SPRITE_ANIM_SGB_VOLCANO_SMOKE
+ anim_data_pointer AnimData53 ; SPRITE_ANIM_SGB_OWMAP_CURSOR
+ anim_data_pointer AnimData54 ; SPRITE_ANIM_SGB_OWMAP_CURSOR_FAST
+ anim_data_pointer AnimData55 ; SPRITE_ANIM_CGB_VOLCANO_SMOKE
+ anim_data_pointer AnimData56 ; SPRITE_ANIM_CGB_OWMAP_CURSOR
+ anim_data_pointer AnimData57 ; SPRITE_ANIM_CGB_OWMAP_CURSOR_FAST
+ anim_data_pointer AnimData58 ; SPRITE_ANIM_TORCH
+ anim_data_pointer AnimData59 ; SPRITE_ANIM_SGB_CARD_TOP_LEFT
+ anim_data_pointer AnimData60 ; SPRITE_ANIM_SGB_CARD_TOP_RIGHT
+ anim_data_pointer AnimData61 ; SPRITE_ANIM_SGB_CARD_LEFT_SPARK
+ anim_data_pointer AnimData62 ; SPRITE_ANIM_SGB_CARD_BOTTOM_LEFT
+ anim_data_pointer AnimData63 ; SPRITE_ANIM_SGB_CARD_BOTTOM_RIGHT
+ anim_data_pointer AnimData64 ; SPRITE_ANIM_SGB_CARD_RIGHT_SPARK
+ anim_data_pointer AnimData65 ; SPRITE_ANIM_CGB_CARD_TOP_LEFT
+ anim_data_pointer AnimData66 ; SPRITE_ANIM_CGB_CARD_TOP_RIGHT
+ anim_data_pointer AnimData67 ; SPRITE_ANIM_CGB_CARD_LEFT_SPARK
+ anim_data_pointer AnimData68 ; SPRITE_ANIM_CGB_CARD_BOTTOM_LEFT
+ anim_data_pointer AnimData69 ; SPRITE_ANIM_CGB_CARD_BOTTOM_RIGHT
+ anim_data_pointer AnimData70 ; SPRITE_ANIM_CGB_CARD_RIGHT_SPARK
+ anim_data_pointer AnimData71 ; SPRITE_ANIM_71
+ anim_data_pointer AnimData72 ; SPRITE_ANIM_72
+ anim_data_pointer AnimData73 ; SPRITE_ANIM_73
+ anim_data_pointer AnimData74 ; SPRITE_ANIM_74
+ anim_data_pointer AnimData75 ; SPRITE_ANIM_75
+ anim_data_pointer AnimData76 ; SPRITE_ANIM_76
+ anim_data_pointer AnimData77 ; SPRITE_ANIM_77
+ anim_data_pointer AnimData78 ; SPRITE_ANIM_78
+ anim_data_pointer AnimData79 ; SPRITE_ANIM_79
+ anim_data_pointer AnimData80 ; SPRITE_ANIM_80
+ anim_data_pointer AnimData81 ; SPRITE_ANIM_81
+ anim_data_pointer AnimData82 ; SPRITE_ANIM_82
+ anim_data_pointer AnimData83 ; SPRITE_ANIM_83
+ anim_data_pointer AnimData84 ; SPRITE_ANIM_84
+ anim_data_pointer AnimData85 ; SPRITE_ANIM_85
+ anim_data_pointer AnimData86 ; SPRITE_ANIM_86
+ anim_data_pointer AnimData87 ; SPRITE_ANIM_87
+ anim_data_pointer AnimData88 ; SPRITE_ANIM_88
+ anim_data_pointer AnimData89 ; SPRITE_ANIM_89
+ anim_data_pointer AnimData90 ; SPRITE_ANIM_90
+ anim_data_pointer AnimData91 ; SPRITE_ANIM_91
+ anim_data_pointer AnimData92 ; SPRITE_ANIM_92
+ anim_data_pointer AnimData93 ; SPRITE_ANIM_93
+ anim_data_pointer AnimData94 ; SPRITE_ANIM_94
+ anim_data_pointer AnimData95 ; SPRITE_ANIM_95
+ anim_data_pointer AnimData96 ; SPRITE_ANIM_96
+ anim_data_pointer AnimData97 ; SPRITE_ANIM_97
+ anim_data_pointer AnimData98 ; SPRITE_ANIM_98
+ anim_data_pointer AnimData99 ; SPRITE_ANIM_99
+ anim_data_pointer AnimData100 ; SPRITE_ANIM_100
+ anim_data_pointer AnimData101 ; SPRITE_ANIM_101
+ anim_data_pointer AnimData102 ; SPRITE_ANIM_102
+ anim_data_pointer AnimData103 ; SPRITE_ANIM_103
+ anim_data_pointer AnimData104 ; SPRITE_ANIM_104
+ anim_data_pointer AnimData105 ; SPRITE_ANIM_105
+ anim_data_pointer AnimData106 ; SPRITE_ANIM_106
+ anim_data_pointer AnimData107 ; SPRITE_ANIM_107
+ anim_data_pointer AnimData108 ; SPRITE_ANIM_108
+ anim_data_pointer AnimData109 ; SPRITE_ANIM_109
+ anim_data_pointer AnimData110 ; SPRITE_ANIM_110
+ anim_data_pointer AnimData111 ; SPRITE_ANIM_111
+ anim_data_pointer AnimData112 ; SPRITE_ANIM_112
+ anim_data_pointer AnimData113 ; SPRITE_ANIM_113
+ anim_data_pointer AnimData114 ; SPRITE_ANIM_114
+ anim_data_pointer AnimData115 ; SPRITE_ANIM_115
+ anim_data_pointer AnimData116 ; SPRITE_ANIM_116
+ anim_data_pointer AnimData117 ; SPRITE_ANIM_117
+ anim_data_pointer AnimData118 ; SPRITE_ANIM_118
+ anim_data_pointer AnimData119 ; SPRITE_ANIM_119
+ anim_data_pointer AnimData120 ; SPRITE_ANIM_120
+ anim_data_pointer AnimData121 ; SPRITE_ANIM_121
+ anim_data_pointer AnimData122 ; SPRITE_ANIM_122
+ anim_data_pointer AnimData123 ; SPRITE_ANIM_123
+ anim_data_pointer AnimData124 ; SPRITE_ANIM_124
+ anim_data_pointer AnimData125 ; SPRITE_ANIM_125
+ anim_data_pointer AnimData126 ; SPRITE_ANIM_126
+ anim_data_pointer AnimData127 ; SPRITE_ANIM_127
+ anim_data_pointer AnimData128 ; SPRITE_ANIM_128
+ anim_data_pointer AnimData129 ; SPRITE_ANIM_129
+ anim_data_pointer AnimData130 ; SPRITE_ANIM_130
+ anim_data_pointer AnimData131 ; SPRITE_ANIM_131
+ anim_data_pointer AnimData132 ; SPRITE_ANIM_132
+ anim_data_pointer AnimData133 ; SPRITE_ANIM_133
+ anim_data_pointer AnimData134 ; SPRITE_ANIM_134
+ anim_data_pointer AnimData135 ; SPRITE_ANIM_135
+ anim_data_pointer AnimData136 ; SPRITE_ANIM_136
+ anim_data_pointer AnimData137 ; SPRITE_ANIM_137
+ anim_data_pointer AnimData138 ; SPRITE_ANIM_138
+ anim_data_pointer AnimData139 ; SPRITE_ANIM_139
+ anim_data_pointer AnimData140 ; SPRITE_ANIM_140
+ anim_data_pointer AnimData141 ; SPRITE_ANIM_141
+ anim_data_pointer AnimData142 ; SPRITE_ANIM_142
+ anim_data_pointer AnimData143 ; SPRITE_ANIM_143
+ anim_data_pointer AnimData144 ; SPRITE_ANIM_144
+ anim_data_pointer AnimData145 ; SPRITE_ANIM_145
+ anim_data_pointer AnimData146 ; SPRITE_ANIM_146
+ anim_data_pointer AnimData147 ; SPRITE_ANIM_147
+ anim_data_pointer AnimData148 ; SPRITE_ANIM_148
+ anim_data_pointer AnimData149 ; SPRITE_ANIM_149
+ anim_data_pointer AnimData150 ; SPRITE_ANIM_150
+ anim_data_pointer AnimData151 ; SPRITE_ANIM_151
+ anim_data_pointer AnimData152 ; SPRITE_ANIM_152
+ anim_data_pointer AnimData153 ; SPRITE_ANIM_153
+ anim_data_pointer AnimData154 ; SPRITE_ANIM_154
+ anim_data_pointer AnimData155 ; SPRITE_ANIM_155
+ anim_data_pointer AnimData156 ; SPRITE_ANIM_156
+ anim_data_pointer AnimData157 ; SPRITE_ANIM_157
+ anim_data_pointer AnimData158 ; SPRITE_ANIM_158
+ anim_data_pointer AnimData159 ; SPRITE_ANIM_159
+ anim_data_pointer AnimData160 ; SPRITE_ANIM_160
+ anim_data_pointer AnimData161 ; SPRITE_ANIM_161
+ anim_data_pointer AnimData162 ; SPRITE_ANIM_162
+ anim_data_pointer AnimData163 ; SPRITE_ANIM_163
+ anim_data_pointer AnimData164 ; SPRITE_ANIM_164
+ anim_data_pointer AnimData165 ; SPRITE_ANIM_165
+ anim_data_pointer AnimData166 ; SPRITE_ANIM_166
+ anim_data_pointer AnimData167 ; SPRITE_ANIM_167
+ anim_data_pointer AnimData168 ; SPRITE_ANIM_168
+ anim_data_pointer AnimData169 ; SPRITE_ANIM_169
+ anim_data_pointer AnimData170 ; SPRITE_ANIM_170
+ anim_data_pointer AnimData171 ; SPRITE_ANIM_171
+ anim_data_pointer AnimData172 ; SPRITE_ANIM_172
+ anim_data_pointer AnimData173 ; SPRITE_ANIM_173
+ anim_data_pointer AnimData174 ; SPRITE_ANIM_174
+ anim_data_pointer AnimData175 ; SPRITE_ANIM_175
+ anim_data_pointer AnimData176 ; SPRITE_ANIM_176
+ anim_data_pointer AnimData177 ; SPRITE_ANIM_177
+ anim_data_pointer AnimData178 ; SPRITE_ANIM_178
+ anim_data_pointer AnimData179 ; SPRITE_ANIM_179
+ anim_data_pointer AnimData180 ; SPRITE_ANIM_180
+ anim_data_pointer AnimData181 ; SPRITE_ANIM_181
+ anim_data_pointer AnimData182 ; SPRITE_ANIM_182
+ anim_data_pointer AnimData183 ; SPRITE_ANIM_183
+ anim_data_pointer AnimData184 ; SPRITE_ANIM_184
+ anim_data_pointer AnimData185 ; SPRITE_ANIM_185
+ anim_data_pointer AnimData186 ; SPRITE_ANIM_186
+ anim_data_pointer AnimData187 ; SPRITE_ANIM_187
+ anim_data_pointer AnimData188 ; SPRITE_ANIM_188
+ anim_data_pointer AnimData189 ; SPRITE_ANIM_189
+ anim_data_pointer AnimData190 ; SPRITE_ANIM_190
+ anim_data_pointer AnimData191 ; SPRITE_ANIM_191
+ anim_data_pointer AnimData192 ; SPRITE_ANIM_192
+ anim_data_pointer AnimData193 ; SPRITE_ANIM_193
+ anim_data_pointer AnimData194 ; SPRITE_ANIM_194
+ anim_data_pointer AnimData195 ; SPRITE_ANIM_195
+ anim_data_pointer AnimData196 ; SPRITE_ANIM_196
+ anim_data_pointer AnimData197 ; SPRITE_ANIM_197
+ anim_data_pointer AnimData198 ; SPRITE_ANIM_198
+ anim_data_pointer AnimData199 ; SPRITE_ANIM_199
+ anim_data_pointer AnimData200 ; SPRITE_ANIM_200
+ anim_data_pointer AnimData201 ; SPRITE_ANIM_201
+ anim_data_pointer AnimData202 ; SPRITE_ANIM_202
+ anim_data_pointer AnimData203 ; SPRITE_ANIM_203
+ anim_data_pointer AnimData204 ; SPRITE_ANIM_204
+ anim_data_pointer AnimData205 ; SPRITE_ANIM_205
+ anim_data_pointer AnimData206 ; SPRITE_ANIM_206
+ anim_data_pointer AnimData207 ; SPRITE_ANIM_207
+ anim_data_pointer AnimData208 ; SPRITE_ANIM_208
+ anim_data_pointer AnimData209 ; SPRITE_ANIM_209
+ anim_data_pointer AnimData210 ; SPRITE_ANIM_210
+ anim_data_pointer AnimData211 ; SPRITE_ANIM_211
+ anim_data_pointer AnimData212 ; SPRITE_ANIM_212
+ anim_data_pointer AnimData213 ; SPRITE_ANIM_213
+ anim_data_pointer AnimData214 ; SPRITE_ANIM_214
+ anim_data_pointer AnimData215 ; SPRITE_ANIM_215
+ anim_data_pointer AnimData216 ; SPRITE_ANIM_216
diff --git a/src/engine/gfx/sprite_vblank.asm b/src/engine/gfx/sprite_vblank.asm
new file mode 100644
index 0000000..5f099a1
--- /dev/null
+++ b/src/engine/gfx/sprite_vblank.asm
@@ -0,0 +1,39 @@
+; empties screen and replaces
+; wVBlankFunctionTrampoline with HandleAllSpriteAnimations
+SetSpriteAnimationsAsVBlankFunction:
+ call EmptyScreen
+ call Set_OBJ_8x8
+ call Func_3ca4
+ lb de, $38, $7f
+ call SetupText
+ ld hl, wVBlankFunctionTrampoline + 1
+ ld de, wVBlankFunctionTrampolineBackup
+ call BackupVBlankFunctionTrampoline
+ di
+ ld [hl], LOW(HandleAllSpriteAnimations)
+ inc hl
+ ld [hl], HIGH(HandleAllSpriteAnimations)
+ ei
+ ret
+
+; sets backup VBlank function as wVBlankFunctionTrampoline
+RestoreVBlankFunction:
+ ld hl, wVBlankFunctionTrampolineBackup
+ ld de, wVBlankFunctionTrampoline + 1
+ call BackupVBlankFunctionTrampoline
+ call Func_3ca4
+ bank1call ZeroObjectPositionsAndToggleOAMCopy
+ ret
+
+; copies 2 bytes from hl to de while interrupts are disabled
+; used to load or store wVBlankFunctionTrampoline
+; to wVBlankFunctionTrampolineBackup
+BackupVBlankFunctionTrampoline:
+ di
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hld]
+ ld [de], a
+ ei
+ ret
diff --git a/src/engine/gfx/sprites.asm b/src/engine/gfx/sprites.asm
new file mode 100644
index 0000000..c2aa277
--- /dev/null
+++ b/src/engine/gfx/sprites.asm
@@ -0,0 +1,122 @@
+; \1 = gfx pointer
+; \2 = number of tiles
+gfx_pointer: MACRO
+ dwb \1, BANK(\1) - BANK(Sprites)
+ db \2
+ENDM
+
+Sprites:
+ gfx_pointer OWPlayerGfx, $14 ; SPRITE_OW_PLAYER
+ gfx_pointer OWRonaldGfx, $14 ; SPRITE_OW_RONALD
+ gfx_pointer OWDrMasonGfx, $14 ; SPRITE_OW_DRMASON
+ gfx_pointer OWIshiharaGfx, $14 ; SPRITE_OW_ISHIHARA
+ gfx_pointer OWImakuniGfx, $14 ; SPRITE_OW_IMAKUNI
+ gfx_pointer OWNikkiGfx, $14 ; SPRITE_OW_NIKKI
+ gfx_pointer OWRickGfx, $14 ; SPRITE_OW_RICK
+ gfx_pointer OWKenGfx, $14 ; SPRITE_OW_KEN
+ gfx_pointer OWAmyGfx, $1b ; SPRITE_OW_AMY
+ gfx_pointer OWIsaacGfx, $14 ; SPRITE_OW_ISAAC
+ gfx_pointer OWMitchGfx, $14 ; SPRITE_OW_MITCH
+ gfx_pointer OWGeneGfx, $14 ; SPRITE_OW_GENE
+ gfx_pointer OWMurrayGfx, $14 ; SPRITE_OW_MURRAY
+ gfx_pointer OWCourtneyGfx, $14 ; SPRITE_OW_COURTNEY
+ gfx_pointer OWSteveGfx, $14 ; SPRITE_OW_STEVE
+ gfx_pointer OWJackGfx, $14 ; SPRITE_OW_JACK
+ gfx_pointer OWRodGfx, $14 ; SPRITE_OW_ROD
+ gfx_pointer OWBoyGfx, $14 ; SPRITE_OW_BOY
+ gfx_pointer OWLadGfx, $14 ; SPRITE_OW_LAD
+ gfx_pointer OWSpecsGfx, $14 ; SPRITE_OW_SPECS
+ gfx_pointer OWButchGfx, $14 ; SPRITE_OW_BUTCH
+ gfx_pointer OWManiaGfx, $14 ; SPRITE_OW_MANIA
+ gfx_pointer OWJoshuaGfx, $14 ; SPRITE_OW_JOSHUA
+ gfx_pointer OWHoodGfx, $14 ; SPRITE_OW_HOOD
+ gfx_pointer OWTechGfx, $14 ; SPRITE_OW_TECH
+ gfx_pointer OWChapGfx, $14 ; SPRITE_OW_CHAP
+ gfx_pointer OWManGfx, $14 ; SPRITE_OW_MAN
+ gfx_pointer OWPappyGfx, $14 ; SPRITE_OW_PAPPY
+ gfx_pointer OWGirlGfx, $14 ; SPRITE_OW_GIRL
+ gfx_pointer OWLass1Gfx, $14 ; SPRITE_OW_LASS1
+ gfx_pointer OWLass2Gfx, $14 ; SPRITE_OW_LASS2
+ gfx_pointer OWLass3Gfx, $14 ; SPRITE_OW_LASS3
+ gfx_pointer OWSwimmerGfx, $14 ; SPRITE_OW_SWIMMER
+ gfx_pointer OWClerkGfx, $08 ; SPRITE_OW_CLERK
+ gfx_pointer OWGalGfx, $14 ; SPRITE_OW_GAL
+ gfx_pointer OWWomanGfx, $14 ; SPRITE_OW_WOMAN
+ gfx_pointer OWGrannyGfx, $14 ; SPRITE_OW_GRANNY
+ gfx_pointer OverworldMapOAMGfx, $08 ; SPRITE_OW_MAP_OAM
+ gfx_pointer Duel0Gfx, $16 ; SPRITE_DUEL_0
+ gfx_pointer Duel63Gfx, $0a ; SPRITE_DUEL_63
+ gfx_pointer DuelGlowGfx, $0b ; SPRITE_DUEL_GLOW
+ gfx_pointer Duel1Gfx, $06 ; SPRITE_DUEL_1
+ gfx_pointer Duel2Gfx, $08 ; SPRITE_DUEL_2
+ gfx_pointer Duel55Gfx, $02 ; SPRITE_DUEL_55
+ gfx_pointer Duel58Gfx, $04 ; SPRITE_DUEL_58
+ gfx_pointer Duel3Gfx, $09 ; SPRITE_DUEL_3
+ gfx_pointer Duel4Gfx, $12 ; SPRITE_DUEL_4
+ gfx_pointer Duel5Gfx, $09 ; SPRITE_DUEL_5
+ gfx_pointer Duel6Gfx, $11 ; SPRITE_DUEL_6
+ gfx_pointer Duel59Gfx, $03 ; SPRITE_DUEL_59
+ gfx_pointer Duel7Gfx, $2d ; SPRITE_DUEL_7
+ gfx_pointer Duel8Gfx, $0d ; SPRITE_DUEL_8
+ gfx_pointer Duel9Gfx, $1c ; SPRITE_DUEL_9
+ gfx_pointer Duel10Gfx, $4c ; SPRITE_DUEL_10
+ gfx_pointer Duel61Gfx, $03 ; SPRITE_DUEL_61
+ gfx_pointer Duel11Gfx, $1b ; SPRITE_DUEL_11
+ gfx_pointer Duel12Gfx, $07 ; SPRITE_DUEL_12
+ gfx_pointer Duel13Gfx, $0c ; SPRITE_DUEL_13
+ gfx_pointer Duel62Gfx, $01 ; SPRITE_DUEL_62
+ gfx_pointer Duel14Gfx, $22 ; SPRITE_DUEL_14
+ gfx_pointer Duel15Gfx, $20 ; SPRITE_DUEL_15
+ gfx_pointer Duel16Gfx, $0a ; SPRITE_DUEL_16
+ gfx_pointer Duel17Gfx, $25 ; SPRITE_DUEL_17
+ gfx_pointer Duel18Gfx, $18 ; SPRITE_DUEL_18
+ gfx_pointer Duel19Gfx, $1b ; SPRITE_DUEL_19
+ gfx_pointer Duel20Gfx, $08 ; SPRITE_DUEL_20
+ gfx_pointer Duel21Gfx, $0d ; SPRITE_DUEL_21
+ gfx_pointer Duel22Gfx, $22 ; SPRITE_DUEL_22
+ gfx_pointer Duel23Gfx, $0c ; SPRITE_DUEL_23
+ gfx_pointer Duel24Gfx, $25 ; SPRITE_DUEL_24
+ gfx_pointer Duel25Gfx, $22 ; SPRITE_DUEL_25
+ gfx_pointer Duel26Gfx, $0c ; SPRITE_DUEL_26
+ gfx_pointer Duel27Gfx, $4c ; SPRITE_DUEL_27
+ gfx_pointer Duel28Gfx, $08 ; SPRITE_DUEL_28
+ gfx_pointer Duel29Gfx, $07 ; SPRITE_DUEL_29
+ gfx_pointer Duel56Gfx, $01 ; SPRITE_DUEL_56
+ gfx_pointer Duel30Gfx, $1a ; SPRITE_DUEL_30
+ gfx_pointer Duel31Gfx, $0a ; SPRITE_DUEL_31
+ gfx_pointer Duel32Gfx, $2e ; SPRITE_DUEL_32
+ gfx_pointer Duel33Gfx, $08 ; SPRITE_DUEL_33
+ gfx_pointer Duel34Gfx, $07 ; SPRITE_DUEL_34
+ gfx_pointer Duel35Gfx, $1c ; SPRITE_DUEL_35
+ gfx_pointer Duel66Gfx, $04 ; SPRITE_DUEL_66
+ gfx_pointer Duel36Gfx, $08 ; SPRITE_DUEL_36
+ gfx_pointer Duel37Gfx, $0b ; SPRITE_DUEL_37
+ gfx_pointer Duel57Gfx, $01 ; SPRITE_DUEL_57
+ gfx_pointer Duel38Gfx, $1c ; SPRITE_DUEL_38
+ gfx_pointer Duel39Gfx, $16 ; SPRITE_DUEL_39
+ gfx_pointer Duel40Gfx, $10 ; SPRITE_DUEL_40
+ gfx_pointer Duel41Gfx, $0f ; SPRITE_DUEL_41
+ gfx_pointer Duel42Gfx, $07 ; SPRITE_DUEL_42
+ gfx_pointer Duel43Gfx, $0a ; SPRITE_DUEL_43
+ gfx_pointer Duel44Gfx, $09 ; SPRITE_DUEL_44
+ gfx_pointer Duel60Gfx, $02 ; SPRITE_DUEL_60
+ gfx_pointer Duel64Gfx, $02 ; SPRITE_DUEL_64
+ gfx_pointer Duel45Gfx, $03 ; SPRITE_DUEL_45
+ gfx_pointer Duel46Gfx, $08 ; SPRITE_DUEL_46
+ gfx_pointer Duel47Gfx, $0f ; SPRITE_DUEL_47
+ gfx_pointer Duel48Gfx, $03 ; SPRITE_DUEL_48
+ gfx_pointer Duel49Gfx, $05 ; SPRITE_DUEL_49
+ gfx_pointer Duel50Gfx, $17 ; SPRITE_DUEL_50
+ gfx_pointer Duel51Gfx, $36 ; SPRITE_DUEL_WON_LOST_DRAW
+ gfx_pointer Duel52Gfx, $0b ; SPRITE_DUEL_52
+ gfx_pointer Duel53Gfx, $06 ; SPRITE_DUEL_53
+ gfx_pointer Duel54Gfx, $16 ; SPRITE_DUEL_54
+ gfx_pointer BoosterPackOAMGfx, $20 ; SPRITE_BOOSTER_PACK_OAM
+ gfx_pointer PressStartGfx, $14 ; SPRITE_PRESS_START
+ gfx_pointer GrassGfx, $04 ; SPRITE_GRASS
+ gfx_pointer FireGfx, $04 ; SPRITE_FIRE
+ gfx_pointer WaterGfx, $04 ; SPRITE_WATER
+ gfx_pointer ColorlessGfx, $04 ; SPRITE_COLORLESS
+ gfx_pointer LightningGfx, $04 ; SPRITE_LIGHTNING
+ gfx_pointer PsychicGfx, $04 ; SPRITE_PSYCHIC
+ gfx_pointer FightingGfx, $04 ; SPRITE_FIGHTING
diff --git a/src/engine/gfx/tilemaps.asm b/src/engine/gfx/tilemaps.asm
new file mode 100644
index 0000000..216cca1
--- /dev/null
+++ b/src/engine/gfx/tilemaps.asm
@@ -0,0 +1,114 @@
+; \1 = pointer
+; \2 = tileset
+tilemap: MACRO
+ dwb \1, BANK(\1) - BANK(Tilemaps)
+ db \2
+ENDM
+
+Tilemaps:
+ tilemap OverworldMapTilemap, TILESET_OVERWORLD_MAP ; TILEMAP_OVERWORLD_MAP
+ tilemap OverworldMapCGBTilemap, TILESET_OVERWORLD_MAP ; TILEMAP_OVERWORLD_MAP_CGB
+ tilemap MasonLaboratoryTilemap, TILESET_MASON_LABORATORY ; TILEMAP_MASON_LABORATORY
+ tilemap MasonLaboratoryCGBTilemap, TILESET_MASON_LABORATORY ; TILEMAP_MASON_LABORATORY_CGB
+ tilemap ChallengeMachineMapEventTilemap, TILESET_MASON_LABORATORY ; TILEMAP_CHALLENGE_MACHINE_MAP_EVENT
+ tilemap ChallengeMachineMapEventCGBTilemap,TILESET_MASON_LABORATORY ; TILEMAP_CHALLENGE_MACHINE_MAP_EVENT_CGB
+ tilemap DeckMachineRoomTilemap, TILESET_MASON_LABORATORY ; TILEMAP_DECK_MACHINE_ROOM
+ tilemap DeckMachineRoomCGBTilemap, TILESET_MASON_LABORATORY ; TILEMAP_DECK_MACHINE_ROOM_CGB
+ tilemap DeckMachineMapEventTilemap, TILESET_MASON_LABORATORY ; TILEMAP_DECK_MACHINE_MAP_EVENT
+ tilemap DeckMachineMapEventCGBTilemap, TILESET_MASON_LABORATORY ; TILEMAP_DECK_MACHINE_MAP_EVENT_CGB
+ tilemap IshiharaTilemap, TILESET_ISHIHARA ; TILEMAP_ISHIHARA
+ tilemap IshiharaCGBTilemap, TILESET_ISHIHARA ; TILEMAP_ISHIHARA_CGB
+ tilemap FightingClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_FIGHTING_CLUB_ENTRANCE
+ tilemap FightingClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_FIGHTING_CLUB_ENTRANCE_CGB
+ tilemap RockClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_ROCK_CLUB_ENTRANCE
+ tilemap RockClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_ROCK_CLUB_ENTRANCE_CGB
+ tilemap WaterClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_WATER_CLUB_ENTRANCE
+ tilemap WaterClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_WATER_CLUB_ENTRANCE_CGB
+ tilemap LightningClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_LIGHTNING_CLUB_ENTRANCE
+ tilemap LightningClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_LIGHTNING_CLUB_ENTRANCE_CGB
+ tilemap GrassClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_GRASS_CLUB_ENTRANCE
+ tilemap GrassClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_GRASS_CLUB_ENTRANCE_CGB
+ tilemap PsychicClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_PSYCHIC_CLUB_ENTRANCE
+ tilemap PsychicClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_PSYCHIC_CLUB_ENTRANCE_CGB
+ tilemap ScienceClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_SCIENCE_CLUB_ENTRANCE
+ tilemap ScienceClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_SCIENCE_CLUB_ENTRANCE_CGB
+ tilemap FireClubEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_FIRE_CLUB_ENTRANCE
+ tilemap FireClubEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_FIRE_CLUB_ENTRANCE_CGB
+ tilemap ChallengeHallEntranceTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_CHALLENGE_HALL_ENTRANCE
+ tilemap ChallengeHallEntranceCGBTilemap, TILESET_CLUB_ENTRANCE ; TILEMAP_CHALLENGE_HALL_ENTRANCE_CGB
+ tilemap ClubLobbyTilemap, TILESET_CLUB_LOBBY ; TILEMAP_CLUB_LOBBY
+ tilemap ClubLobbyCGBTilemap, TILESET_CLUB_LOBBY ; TILEMAP_CLUB_LOBBY_CGB
+ tilemap FightingClubTilemap, TILESET_FIGHTING_CLUB ; TILEMAP_FIGHTING_CLUB
+ tilemap FightingClubCGBTilemap, TILESET_FIGHTING_CLUB ; TILEMAP_FIGHTING_CLUB_CGB
+ tilemap RockClubTilemap, TILESET_ROCK_CLUB ; TILEMAP_ROCK_CLUB
+ tilemap RockClubCGBTilemap, TILESET_ROCK_CLUB ; TILEMAP_ROCK_CLUB_CGB
+ tilemap WaterClubTilemap, TILESET_WATER_CLUB ; TILEMAP_WATER_CLUB
+ tilemap WaterClubCGBTilemap, TILESET_WATER_CLUB ; TILEMAP_WATER_CLUB_CGB
+ tilemap LightningClubTilemap, TILESET_LIGHTNING_CLUB ; TILEMAP_LIGHTNING_CLUB
+ tilemap LightningClubCGBTilemap, TILESET_LIGHTNING_CLUB ; TILEMAP_LIGHTNING_CLUB_CGB
+ tilemap GrassClubTilemap, TILESET_GRASS_CLUB ; TILEMAP_GRASS_CLUB
+ tilemap GrassClubCGBTilemap, TILESET_GRASS_CLUB ; TILEMAP_GRASS_CLUB_CGB
+ tilemap PsychicClubTilemap, TILESET_PSYCHIC_CLUB ; TILEMAP_PSYCHIC_CLUB
+ tilemap PsychicClubCGBTilemap, TILESET_PSYCHIC_CLUB ; TILEMAP_PSYCHIC_CLUB_CGB
+ tilemap ScienceClubTilemap, TILESET_SCIENCE_CLUB ; TILEMAP_SCIENCE_CLUB
+ tilemap ScienceClubCGBTilemap, TILESET_SCIENCE_CLUB ; TILEMAP_SCIENCE_CLUB_CGB
+ tilemap FireClubTilemap, TILESET_FIRE_CLUB ; TILEMAP_FIRE_CLUB
+ tilemap FireClubCGBTilemap, TILESET_FIRE_CLUB ; TILEMAP_FIRE_CLUB_CGB
+ tilemap ChallengeHallTilemap, TILESET_CHALLENGE_HALL ; TILEMAP_CHALLENGE_HALL
+ tilemap ChallengeHallCGBTilemap, TILESET_CHALLENGE_HALL ; TILEMAP_CHALLENGE_HALL_CGB
+ tilemap PokemonDomeEntranceTilemap, TILESET_POKEMON_DOME_ENTRANCE ; TILEMAP_POKEMON_DOME_ENTRANCE
+ tilemap PokemonDomeEntranceCGBTilemap, TILESET_POKEMON_DOME_ENTRANCE ; TILEMAP_POKEMON_DOME_ENTRANCE_CGB
+ tilemap PokemonDomeDoorMapEventTilemap, TILESET_POKEMON_DOME_ENTRANCE ; TILEMAP_POKEMON_DOME_DOOR_MAP_EVENT
+ tilemap PokemonDomeDoorMapEventCGBTilemap, TILESET_POKEMON_DOME_ENTRANCE ; TILEMAP_POKEMON_DOME_DOOR_MAP_EVENT_CGB
+ tilemap PokemonDomeTilemap, TILESET_POKEMON_DOME ; TILEMAP_POKEMON_DOME
+ tilemap PokemonDomeCGBTilemap, TILESET_POKEMON_DOME ; TILEMAP_POKEMON_DOME_CGB
+ tilemap HallOfHonorDoorMapEventTilemap, TILESET_POKEMON_DOME ; TILEMAP_HALL_OF_HONOR_DOOR_MAP_EVENT
+ tilemap HallOfHonorDoorMapEventCGBTilemap, TILESET_POKEMON_DOME ; TILEMAP_HALL_OF_HONOR_DOOR_MAP_EVENT_CGB
+ tilemap HallOfHonorTilemap, TILESET_HALL_OF_HONOR ; TILEMAP_HALL_OF_HONOR
+ tilemap HallOfHonorCGBTilemap, TILESET_HALL_OF_HONOR ; TILEMAP_HALL_OF_HONOR_CGB
+ tilemap CardPopCGBTilemap, TILESET_CARD_POP ; TILEMAP_CARD_POP_CGB
+ tilemap CardPopTilemap, TILESET_CARD_POP ; TILEMAP_CARD_POP
+ tilemap GrassMedalTilemap, TILESET_MEDAL ; TILEMAP_GRASS_MEDAL
+ tilemap ScienceMedalTilemap, TILESET_MEDAL ; TILEMAP_SCIENCE_MEDAL
+ tilemap FireMedalTilemap, TILESET_MEDAL ; TILEMAP_FIRE_MEDAL
+ tilemap WaterMedalTilemap, TILESET_MEDAL ; TILEMAP_WATER_MEDAL
+ tilemap LightningMedalTilemap, TILESET_MEDAL ; TILEMAP_LIGHTNING_MEDAL
+ tilemap FightingMedalTilemap, TILESET_MEDAL ; TILEMAP_FIGHTING_MEDAL
+ tilemap RockMedalTilemap, TILESET_MEDAL ; TILEMAP_ROCK_MEDAL
+ tilemap PsychicMedalTilemap, TILESET_MEDAL ; TILEMAP_PSYCHIC_MEDAL
+ tilemap GameBoyLinkCGBTilemap, TILESET_GAMEBOY_LINK ; TILEMAP_GAMEBOY_LINK_CGB
+ tilemap GameBoyLinkTilemap, TILESET_GAMEBOY_LINK ; TILEMAP_GAMEBOY_LINK
+ tilemap GameBoyLinkConnectingCGBTilemap, TILESET_GAMEBOY_LINK ; TILEMAP_GAMEBOY_LINK_CONNECTING_CGB
+ tilemap GameBoyLinkConnectingTilemap, TILESET_GAMEBOY_LINK ; TILEMAP_GAMEBOY_LINK_CONNECTING
+ tilemap GameBoyPrinterCGBTilemap, TILESET_GAMEBOY_PRINTER ; TILEMAP_GAMEBOY_PRINTER_CGB
+ tilemap GameBoyPrinterTilemap, TILESET_GAMEBOY_PRINTER ; TILEMAP_GAMEBOY_PRINTER
+ tilemap ColosseumTilemap, TILESET_COLOSSEUM_1 ; TILEMAP_COLOSSEUM
+ tilemap ColosseumCGBTilemap, TILESET_COLOSSEUM_2 ; TILEMAP_COLOSSEUM_CGB
+ tilemap EvolutionTilemap, TILESET_EVOLUTION_1 ; TILEMAP_EVOLUTION
+ tilemap EvolutionCGBTilemap, TILESET_EVOLUTION_2 ; TILEMAP_EVOLUTION_CGB
+ tilemap MysteryTilemap, TILESET_MYSTERY_1 ; TILEMAP_MYSTERY
+ tilemap MysteryCGBTilemap, TILESET_MYSTERY_2 ; TILEMAP_MYSTERY_CGB
+ tilemap LaboratoryTilemap, TILESET_LABORATORY_1 ; TILEMAP_LABORATORY
+ tilemap LaboratoryCGBTilemap, TILESET_LABORATORY_2 ; TILEMAP_LABORATORY_CGB
+ tilemap CharizardIntroTilemap, TILESET_CHARIZARD_INTRO_1 ; TILEMAP_CHARIZARD_INTRO
+ tilemap CharizardIntroCGBTilemap, TILESET_CHARIZARD_INTRO_2 ; TILEMAP_CHARIZARD_INTRO_CGB
+ tilemap ScytherIntroTilemap, TILESET_SCYTHER_INTRO_1 ; TILEMAP_SCYTHER_INTRO
+ tilemap ScytherIntroCGBTilemap, TILESET_SCYTHER_INTRO_2 ; TILEMAP_SCYTHER_INTRO_CGB
+ tilemap AerodactylIntroTilemap, TILESET_AERODACTYL_INTRO_1 ; TILEMAP_AERODACTYL_INTRO
+ tilemap AerodactylIntroCGBTilemap, TILESET_AERODACTYL_INTRO_2 ; TILEMAP_AERODACTYL_INTRO_CGB
+ tilemap JapaneseTitleScreenTilemap, TILESET_JAPANESE_TITLE_SCREEN ; TILEMAP_JAPANESE_TITLE_SCREEN
+ tilemap JapaneseTitleScreenCGBTilemap, TILESET_JAPANESE_TITLE_SCREEN_CGB ; TILEMAP_JAPANESE_TITLE_SCREEN_CGB
+ tilemap SolidTiles1Tilemap, TILESET_SOLID_TILES_1 ; TILEMAP_SOLID_TILES_1
+ tilemap SolidTiles2Tilemap, TILESET_SOLID_TILES_1 ; TILEMAP_SOLID_TILES_2
+ tilemap SolidTiles3Tilemap, TILESET_SOLID_TILES_1 ; TILEMAP_SOLID_TILES_3
+ tilemap JapaneseTitleScreen2Tilemap, TILESET_JAPANESE_TITLE_SCREEN_2 ; TILEMAP_JAPANESE_TITLE_SCREEN_2
+ tilemap JapaneseTitleScreen2CGBTilemap, TILESET_JAPANESE_TITLE_SCREEN_2_CGB ; TILEMAP_JAPANESE_TITLE_SCREEN_2_CGB
+ tilemap SolidTiles4Tilemap, TILESET_SOLID_TILES_2 ; TILEMAP_SOLID_TILES_4
+ tilemap PlayerTilemap, TILESET_PLAYER ; TILEMAP_PLAYER
+ tilemap OpponentTilemap, TILESET_RONALD ; TILEMAP_OPPONENT
+ tilemap TitleScreenTilemap, TILESET_TITLE_SCREEN ; TILEMAP_TITLE_SCREEN
+ tilemap TitleScreenCGBTilemap, TILESET_TITLE_SCREEN_CGB ; TILEMAP_TITLE_SCREEN_CGB
+ tilemap CopyrightTilemap, TILESET_COPYRIGHT ; TILEMAP_COPYRIGHT
+ tilemap CopyrightCGBTilemap, TILESET_COPYRIGHT ; TILEMAP_COPYRIGHT_CGB
+ tilemap NintendoTilemap, TILESET_NINTENDO ; TILEMAP_NINTENDO
+ tilemap CompaniesTilemap, TILESET_COMPANIES ; TILEMAP_COMPANIES
diff --git a/src/engine/gfx/tilesets.asm b/src/engine/gfx/tilesets.asm
new file mode 100644
index 0000000..0b4f0af
--- /dev/null
+++ b/src/engine/gfx/tilesets.asm
@@ -0,0 +1,95 @@
+; \1 = pointer
+; \2 = number of tiles
+tileset: MACRO
+ dwb \1, BANK(\1) - BANK(Tilesets)
+ db \2
+ENDM
+
+Tilesets:
+ tileset OverworldMapTiles, 193 ; TILESET_OVERWORLD_MAP
+ tileset MasonLaboratoryTilesetGfx, 151 ; TILESET_MASON_LABORATORY
+ tileset IshiharaTilesetGfx, 77 ; TILESET_ISHIHARA
+ tileset ClubEntranceTilesetGfx, 129 ; TILESET_CLUB_ENTRANCE
+ tileset ClubLobbyTilesetGfx, 120 ; TILESET_CLUB_LOBBY
+ tileset FightingClubTilesetGfx, 99 ; TILESET_FIGHTING_CLUB
+ tileset RockClubTilesetGfx, 60 ; TILESET_ROCK_CLUB
+ tileset WaterClubTilesetGfx, 161 ; TILESET_WATER_CLUB
+ tileset LightningClubTilesetGfx, 131 ; TILESET_LIGHTNING_CLUB
+ tileset GrassClubTilesetGfx, 87 ; TILESET_GRASS_CLUB
+ tileset PsychicClubTilesetGfx, 58 ; TILESET_PSYCHIC_CLUB
+ tileset ScienceClubTilesetGfx, 82 ; TILESET_SCIENCE_CLUB
+ tileset FireClubTilesetGfx, 87 ; TILESET_FIRE_CLUB
+ tileset ChallengeHallTilesetGfx, 157 ; TILESET_CHALLENGE_HALL
+ tileset PokemonDomeEntranceTilesetGfx, 78 ; TILESET_POKEMON_DOME_ENTRANCE
+ tileset PokemonDomeTilesetGfx, 207 ; TILESET_POKEMON_DOME
+ tileset HallOfHonorTilesetGfx, 121 ; TILESET_HALL_OF_HONOR
+ tileset CardPopGfx, 189 ; TILESET_CARD_POP
+ tileset MedalGfx, 72 ; TILESET_MEDAL
+ tileset GameBoyLinkGfx, 109 ; TILESET_GAMEBOY_LINK
+ tileset GameBoyPrinterGfx, 93 ; TILESET_GAMEBOY_PRINTER
+ tileset Colosseum1Gfx, 96 ; TILESET_COLOSSEUM_1
+ tileset Colosseum2Gfx, 86 ; TILESET_COLOSSEUM_2
+ tileset Evolution1Gfx, 96 ; TILESET_EVOLUTION_1
+ tileset Evolution2Gfx, 86 ; TILESET_EVOLUTION_2
+ tileset Mystery1Gfx, 96 ; TILESET_MYSTERY_1
+ tileset Mystery2Gfx, 86 ; TILESET_MYSTERY_2
+ tileset Laboratory1Gfx, 96 ; TILESET_LABORATORY_1
+ tileset Laboratory2Gfx, 86 ; TILESET_LABORATORY_2
+ tileset CharizardIntro1Gfx, 96 ; TILESET_CHARIZARD_INTRO_1
+ tileset CharizardIntro2Gfx, 96 ; TILESET_CHARIZARD_INTRO_2
+ tileset ScytherIntro1Gfx, 96 ; TILESET_SCYTHER_INTRO_1
+ tileset ScytherIntro2Gfx, 96 ; TILESET_SCYTHER_INTRO_2
+ tileset AerodactylIntro1Gfx, 96 ; TILESET_AERODACTYL_INTRO_1
+ tileset AerodactylIntro2Gfx, 96 ; TILESET_AERODACTYL_INTRO_2
+ tileset JapaneseTitleScreenGfx, 97 ; TILESET_JAPANESE_TITLE_SCREEN
+ tileset JapaneseTitleScreenCGBGfx, 97 ; TILESET_JAPANESE_TITLE_SCREEN_CGB
+ tileset SolidTiles1, 4 ; TILESET_SOLID_TILES_1
+ tileset JapaneseTitleScreen2Gfx, 244 ; TILESET_JAPANESE_TITLE_SCREEN_2
+ tileset JapaneseTitleScreen2CGBGfx, 59 ; TILESET_JAPANESE_TITLE_SCREEN_2_CGB
+ tileset SolidTiles2, 4 ; TILESET_SOLID_TILES_2
+ tileset PlayerGfx, 36 ; TILESET_PLAYER
+ tileset RonaldGfx, 36 ; TILESET_RONALD
+ tileset TitleScreenGfx, 220 ; TILESET_TITLE_SCREEN
+ tileset TitleScreenCGBGfx, 212 ; TILESET_TITLE_SCREEN_CGB
+ tileset CopyrightGfx, 36 ; TILESET_COPYRIGHT
+ tileset NintendoGfx, 24 ; TILESET_NINTENDO
+ tileset CompaniesGfx, 49 ; TILESET_COMPANIES
+ tileset SamGfx, 36 ; TILESET_SAM
+ tileset ImakuniGfx, 36 ; TILESET_IMAKUNI
+ tileset NikkiGfx, 36 ; TILESET_NIKKI
+ tileset RickGfx, 36 ; TILESET_RICK
+ tileset KenGfx, 36 ; TILESET_KEN
+ tileset AmyGfx, 36 ; TILESET_AMY
+ tileset IsaacGfx, 36 ; TILESET_ISAAC
+ tileset MitchGfx, 36 ; TILESET_MITCH
+ tileset GeneGfx, 36 ; TILESET_GENE
+ tileset MurrayGfx, 36 ; TILESET_MURRAY
+ tileset CourtneyGfx, 36 ; TILESET_COURTNEY
+ tileset SteveGfx, 36 ; TILESET_STEVE
+ tileset JackGfx, 36 ; TILESET_JACK
+ tileset RodGfx, 36 ; TILESET_ROD
+ tileset JosephGfx, 36 ; TILESET_JOSEPH
+ tileset DavidGfx, 36 ; TILESET_DAVID
+ tileset ErikGfx, 36 ; TILESET_ERIK
+ tileset JohnGfx, 36 ; TILESET_JOHN
+ tileset AdamGfx, 36 ; TILESET_ADAM
+ tileset JonathanGfx, 36 ; TILESET_JONATHAN
+ tileset JoshuaGfx, 36 ; TILESET_JOSHUA
+ tileset NicholasGfx, 36 ; TILESET_NICHOLAS
+ tileset BrandonGfx, 36 ; TILESET_BRANDON
+ tileset MatthewGfx, 36 ; TILESET_MATTHEW
+ tileset RyanGfx, 36 ; TILESET_RYAN
+ tileset AndrewGfx, 36 ; TILESET_ANDREW
+ tileset ChrisGfx, 36 ; TILESET_CHRIS
+ tileset MichaelGfx, 36 ; TILESET_MICHAEL
+ tileset DanielGfx, 36 ; TILESET_DANIEL
+ tileset RobertGfx, 36 ; TILESET_ROBERT
+ tileset BrittanyGfx, 36 ; TILESET_BRITTANY
+ tileset KristinGfx, 36 ; TILESET_KRISTIN
+ tileset HeatherGfx, 36 ; TILESET_HEATHER
+ tileset SaraGfx, 36 ; TILESET_SARA
+ tileset AmandaGfx, 36 ; TILESET_AMANDA
+ tileset JenniferGfx, 36 ; TILESET_JENNIFER
+ tileset JessicaGfx, 36 ; TILESET_JESSICA
+ tileset StephanieGfx, 36 ; TILESET_STEPHANIE
+ tileset AaronGfx, 36 ; TILESET_AARON
diff --git a/src/engine/input_name.asm b/src/engine/input_name.asm
new file mode 100644
index 0000000..edcac4c
--- /dev/null
+++ b/src/engine/input_name.asm
@@ -0,0 +1,1417 @@
+WhatIsYourNameData:
+ textitem 1, 1, WhatIsYourNameText
+ db $ff
+; [Deck1Data ~ Deck4Data]
+; These are directed from InputCurDeckName,
+; without any bank description.
+; That is, the developers hard-coded it. -_-;;
+Deck1Data:
+ textitem 2, 1, Deck1Text
+ textitem 14, 1, DeckText
+ db $ff
+Deck2Data:
+ textitem 2, 1, Deck2Text
+ textitem 14, 1, DeckText
+ db $ff
+Deck3Data:
+ textitem 2, 1, Deck3Text
+ textitem 14, 1, DeckText
+ db $ff
+Deck4Data:
+ textitem 2, 1, Deck4Text
+ textitem 14, 1, DeckText
+ db $ff
+
+; set each byte zero from hl for b bytes.
+ClearMemory:
+ 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
+
+; play different sfx by a.
+; if a is 0xff play SFX_03 (usually following a B press),
+; else play SFX_02 (usually following an A press).
+PlayAcceptOrDeclineSFX:
+ push af
+ inc a
+ jr z, .sfx_decline
+ ld a, SFX_02
+ jr .sfx_accept
+.sfx_decline
+ ld a, SFX_03
+.sfx_accept
+ call PlaySFX
+ pop af
+ ret
+
+; get player name from the user
+; into hl
+InputPlayerName:
+ ld e, l
+ ld d, h
+ ld a, MAX_PLAYER_NAME_LENGTH
+ ld hl, WhatIsYourNameData
+ lb bc, 12, 1
+ call InitializeInputName
+ call Set_OBJ_8x8
+ xor a
+ ld [wTileMapFill], a
+ call EmptyScreen
+ call ZeroObjectPositions
+ ld a, $01
+ ld [wVBlankOAMCopyToggle], a
+ call LoadSymbolsFont
+ lb de, $38, $bf
+ call SetupText
+ call LoadTextCursorTile
+ ld a, $02
+ ld [wd009], a
+ call DrawNamingScreenBG
+ xor a
+ ld [wNamingScreenCursorX], a
+ ld [wNamingScreenCursorY], a
+ ld a, $09
+ ld [wNamingScreenNumColumns], a
+ ld a, $06
+ ld [wNamingScreenKeyboardHeight], a
+ ld a, $0f
+ ld [wVisibleCursorTile], a
+ ld a, $00
+ ld [wInvisibleCursorTile], a
+.loop
+ ld a, $01
+ ld [wVBlankOAMCopyToggle], a
+ call DoFrame
+ call UpdateRNGSources
+ ldh a, [hDPadHeld]
+ and START
+ jr z, .else
+ ; if pressed start button.
+ ld a, $01
+ call PlayAcceptOrDeclineSFX
+ call Func_1aa07
+ ld a, 6
+ ld [wNamingScreenCursorX], a
+ ld a, 5
+ ld [wNamingScreenCursorY], a
+ call Func_1aa23
+ jr .loop
+.else
+ call NamingScreen_CheckButtonState
+ jr nc, .loop ; if not pressed, go back to the loop.
+ cp $ff
+ jr z, .on_b_button
+ ; on A button.
+ call NamingScreen_ProcessInput
+ jr nc, .loop
+ ; if the player selected the end button,
+ ; end its naming.
+ call FinalizeInputName
+ ret
+.on_b_button
+ ld a, [wNamingScreenBufferLength]
+ or a
+ jr z, .loop ; empty string?
+ ; erase one character.
+ ld e, a
+ ld d, 0
+ ld hl, wNamingScreenBuffer
+ add hl, de
+ dec hl
+ dec hl
+ ld [hl], TX_END
+ ld hl, wNamingScreenBufferLength ; note that its unit is byte, not word.
+ dec [hl]
+ dec [hl]
+ call PrintPlayerNameFromInput
+ jr .loop
+
+; it's called when naming(either player's or deck's) starts.
+; a: maximum length of name(depending on whether player's or deck's).
+; bc: position of name.
+; de: dest. pointer.
+; hl: pointer to text item of the question.
+InitializeInputName:
+ ld [wNamingScreenBufferMaxLength], a
+ push hl
+ ld hl, wNamingScreenNamePosition
+ ld [hl], b
+ inc hl
+ ld [hl], c
+ pop hl
+ ld b, h
+ ld c, l
+ ; set the question string.
+ ld hl, wNamingScreenQuestionPointer
+ ld [hl], c
+ inc hl
+ ld [hl], b
+ ; set the destination buffer.
+ ld hl, wNamingScreenDestPointer
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ; clear the name buffer.
+ ld a, NAMING_SCREEN_BUFFER_LENGTH
+ ld hl, wNamingScreenBuffer
+ call ClearMemory
+ ld hl, wNamingScreenBuffer
+ ld a, [wNamingScreenBufferMaxLength]
+ ld b, a
+ inc b
+.loop
+ ; copy data from de to hl
+ ; for b bytes.
+ ld a, [de]
+ inc de
+ ld [hli], a
+ dec b
+ jr nz, .loop
+ ld hl, wNamingScreenBuffer
+ call GetTextLengthInTiles
+ ld a, c
+ ld [wNamingScreenBufferLength], a
+ ret
+
+FinalizeInputName:
+ ld hl, wNamingScreenDestPointer
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld l, e
+ ld h, d
+ ld de, wNamingScreenBuffer
+ ld a, [wNamingScreenBufferMaxLength]
+ ld b, a
+ inc b
+ jr InitializeInputName.loop
+
+; draws the keyboard frame
+; and the question if it exists.
+DrawNamingScreenBG:
+ call DrawTextboxForKeyboard
+ call PrintPlayerNameFromInput
+ ld hl, wNamingScreenQuestionPointer
+ ld c, [hl]
+ inc hl
+ ld a, [hl]
+ ld h, a
+ or c
+ jr z, .put_text_end
+ ; print the question string.
+ ; ex) "What is your name?"
+ ld l, c
+ call PlaceTextItems
+.put_text_end
+ ; print "End".
+ ld hl, .data
+ call PlaceTextItems
+ ldtx hl, PlayerNameKeyboardText
+ lb de, 2, 4
+ call InitTextPrinting
+ call ProcessTextFromID
+ call EnableLCD
+ ret
+.data
+ textitem $0f, $10, EndText ; "End"
+ db $ff
+
+DrawTextboxForKeyboard:
+ lb de, 0, 3 ; x, y
+ lb bc, 20, 15 ; w, h
+ call DrawRegularTextBox
+ ret
+
+PrintPlayerNameFromInput:
+ ld hl, wNamingScreenNamePosition
+ ld d, [hl]
+ inc hl
+ ld e, [hl]
+ push de
+ call InitTextPrinting
+ ld a, [wNamingScreenBufferMaxLength]
+ ld e, a
+ ld a, $14
+ sub e
+ inc a
+ ld e, a
+ ld d, 0
+ ; print the underbars
+ ; before print the input.
+ ld hl, .char_underbar
+ add hl, de
+ call ProcessText
+ pop de
+ call InitTextPrinting
+ ; print the input from the user.
+ ld hl, wNamingScreenBuffer
+ call ProcessText
+ ret
+.char_underbar
+ db $56
+rept 10
+ textfw3 "_"
+endr
+ done
+
+; check if button pressed.
+; if pressed, set the carry bit on.
+NamingScreen_CheckButtonState:
+ xor a
+ ld [wPlaysSfx], a
+ ldh a, [hDPadHeld]
+ or a
+ jp z, .no_press
+ ; detected any button press.
+ ld b, a
+ ld a, [wNamingScreenKeyboardHeight]
+ ld c, a
+ ld a, [wNamingScreenCursorX]
+ ld h, a
+ ld a, [wNamingScreenCursorY]
+ ld l, a
+ bit D_UP_F, b
+ jr z, .asm_692c
+ ; up
+ dec a
+ bit D_DOWN_F, a
+ jr z, .asm_69a7
+ ld a, c
+ dec a
+ jr .asm_69a7
+.asm_692c
+ bit D_DOWN_F, b
+ jr z, .asm_6937
+ ; down
+ inc a
+ cp c
+ jr c, .asm_69a7
+ xor a
+ jr .asm_69a7
+.asm_6937
+ ld a, [wNamingScreenNumColumns]
+ ld c, a
+ ld a, h
+ bit D_LEFT_F, b
+ jr z, .asm_6974
+ ; left
+ ld d, a
+ ld a, $06
+ cp l
+ ld a, d
+ jr nz, .asm_696b
+ push hl
+ push bc
+ push af
+ call GetCharInfoFromPos_Player
+ inc hl
+ inc hl
+ inc hl
+ inc hl
+ inc hl
+ ld a, [hl]
+ dec a
+ ld d, a
+ pop af
+ pop bc
+ pop hl
+ sub d
+ cp $ff
+ jr nz, .asm_6962
+ ld a, c
+ sub $02
+ jr .asm_69aa
+.asm_6962
+ cp $fe
+ jr nz, .asm_696b
+ ld a, c
+ sub $03
+ jr .asm_69aa
+.asm_696b
+ dec a
+ bit D_DOWN_F, a
+ jr z, .asm_69aa
+ ld a, c
+ dec a
+ jr .asm_69aa
+.asm_6974
+ bit D_RIGHT_F, b
+ jr z, .no_press
+ ld d, a
+ ld a, $06
+ cp l
+ ld a, d
+ jr nz, .asm_6990
+ push hl
+ push bc
+ push af
+ call GetCharInfoFromPos_Player
+ inc hl
+ inc hl
+ inc hl
+ inc hl
+ ld a, [hl]
+ dec a
+ ld d, a
+ pop af
+ pop bc
+ pop hl
+ add d
+.asm_6990
+ inc a
+ cp c
+ jr c, .asm_69aa
+ inc c
+ cp c
+ jr c, .asm_69a4
+ inc c
+ cp c
+ jr c, .asm_69a0
+ ld a, $02
+ jr .asm_69aa
+.asm_69a0
+ ld a, $01
+ jr .asm_69aa
+.asm_69a4
+ xor a
+ jr .asm_69aa
+.asm_69a7
+ ld l, a
+ jr .asm_69ab
+.asm_69aa
+ ld h, a
+.asm_69ab
+ push hl
+ call GetCharInfoFromPos_Player
+ inc hl
+ inc hl
+ inc hl
+ ld a, [wd009]
+ cp $02
+ jr nz, .asm_69bb
+ inc hl
+ inc hl
+.asm_69bb
+ ld d, [hl]
+ push de
+ call Func_1aa07
+ pop de
+ pop hl
+ ld a, l
+ ld [wNamingScreenCursorY], a
+ ld a, h
+ ld [wNamingScreenCursorX], a
+ xor a
+ ld [wCheckMenuCursorBlinkCounter], a
+ ld a, $06
+ cp d
+ jp z, NamingScreen_CheckButtonState
+ ld a, $01
+ ld [wPlaysSfx], a
+.no_press
+ ldh a, [hKeysPressed]
+ and A_BUTTON | B_BUTTON
+ jr z, .asm_69ef
+ and A_BUTTON
+ jr nz, .asm_69e5
+ ld a, $ff
+.asm_69e5
+ call PlayAcceptOrDeclineSFX
+ push af
+ call Func_1aa23
+ pop af
+ scf
+ ret
+.asm_69ef
+ ld a, [wPlaysSfx]
+ or a
+ jr z, .asm_69f8
+ call PlaySFX
+.asm_69f8
+ ld hl, wCheckMenuCursorBlinkCounter
+ ld a, [hl]
+ inc [hl]
+ and $0f
+ ret nz
+ ld a, [wVisibleCursorTile]
+ bit 4, [hl]
+ jr z, Func_1aa07.asm_6a0a
+
+Func_1aa07:
+ ld a, [wInvisibleCursorTile]
+.asm_6a0a
+ ld e, a
+ ld a, [wNamingScreenCursorX]
+ ld h, a
+ ld a, [wNamingScreenCursorY]
+ ld l, a
+ call GetCharInfoFromPos_Player
+ ld a, [hli]
+ ld c, a
+ ld b, [hl]
+ dec b
+ ld a, e
+ call Func_1aa28
+ call WriteByteToBGMap0
+ or a
+ ret
+
+Func_1aa23:
+ ld a, [wVisibleCursorTile]
+ jr Func_1aa07.asm_6a0a
+
+Func_1aa28:
+ push af
+ push bc
+ push de
+ push hl
+ push af
+ call ZeroObjectPositions
+ pop af
+ ld b, a
+ ld a, [wInvisibleCursorTile]
+ cp b
+ jr z, .asm_6a60
+ ld a, [wNamingScreenBufferLength]
+ srl a
+ ld d, a
+ ld a, [wNamingScreenBufferMaxLength]
+ srl a
+ ld e, a
+ ld a, d
+ cp e
+ jr nz, .asm_6a49
+ dec a
+.asm_6a49
+ ld hl, wNamingScreenNamePosition
+ add [hl]
+ ld d, a
+ ld h, $08
+ ld l, d
+ call HtimesL
+ ld a, l
+ add $08
+ ld d, a
+ ld e, $18
+ ld bc, $0000
+ call SetOneObjectAttributes
+.asm_6a60
+ pop hl
+ pop de
+ pop bc
+ pop af
+ ret
+
+; load, to the first tile of v0Tiles0, the graphics for the
+; blinking black square used in name input screens.
+; for inputting full width text.
+LoadTextCursorTile:
+ ld hl, v0Tiles0 + $00 tiles
+ ld de, .data
+ ld b, 0
+.loop
+ ld a, TILE_SIZE
+ cp b
+ ret z
+ inc b
+ ld a, [de]
+ inc de
+ ld [hli], a
+ jr .loop
+
+.data
+rept TILE_SIZE
+ db $ff
+endr
+
+; set the carry bit on,
+; if "End" was selected.
+NamingScreen_ProcessInput:
+ ld a, [wNamingScreenCursorX]
+ ld h, a
+ ld a, [wNamingScreenCursorY]
+ ld l, a
+ call GetCharInfoFromPos_Player
+ inc hl
+ inc hl
+ ; load types into de.
+ ld e, [hl]
+ inc hl
+ ld a, [hli]
+ ld d, a
+ cp $09
+ jp z, .on_end
+ cp $07
+ jr nz, .asm_6ab8
+ ld a, [wd009]
+ or a
+ jr nz, .asm_6aac
+ ld a, $01
+ jp .asm_6ace
+.asm_6aac
+ dec a
+ jr nz, .asm_6ab4
+ ld a, $02
+ jp .asm_6ace
+.asm_6ab4
+ xor a
+ jp .asm_6ace
+.asm_6ab8
+ cp $08
+ jr nz, .asm_6ad6
+ ld a, [wd009]
+ or a
+ jr nz, .asm_6ac6
+ ld a, $02
+ jr .asm_6ace
+.asm_6ac6
+ dec a
+ jr nz, .asm_6acc
+ xor a
+ jr .asm_6ace
+.asm_6acc
+ ld a, $01
+.asm_6ace
+ ld [wd009], a
+ call DrawNamingScreenBG
+ or a
+ ret
+.asm_6ad6
+ ld a, [wd009]
+ cp $02
+ jr z, .read_char
+ ldfw3 bc, "“"
+ ld a, d
+ cp b
+ jr nz, .asm_6af4
+ ld a, e
+ cp c
+ jr nz, .asm_6af4
+ push hl
+ ld hl, TransitionTable1 ; from 55th.
+ call TransformCharacter
+ pop hl
+ jr c, .nothing
+ jr .asm_6b09
+.asm_6af4
+ ldfw3 bc, "º(2)"
+ ld a, d
+ cp b
+ jr nz, .asm_6b1d
+ ld a, e
+ cp c
+ jr nz, .asm_6b1d
+ push hl
+ ld hl, TransitionTable2 ; from 72th.
+ call TransformCharacter
+ pop hl
+ jr c, .nothing
+.asm_6b09
+ ld a, [wNamingScreenBufferLength]
+ dec a
+ dec a
+ ld [wNamingScreenBufferLength], a
+ ld hl, wNamingScreenBuffer
+ push de
+ ld d, 0
+ ld e, a
+ add hl, de
+ pop de
+ ld a, [hl]
+ jr .asm_6b37
+.asm_6b1d
+ ld a, d
+ or a
+ jr nz, .asm_6b37
+ ld a, [wd009]
+ or a
+ jr nz, .asm_6b2b
+ ld a, TX_HIRAGANA
+ jr .asm_6b37
+.asm_6b2b
+ ld a, TX_KATAKANA
+ jr .asm_6b37
+; read character code from info. to register.
+; hl: pointer.
+.read_char
+ ld e, [hl]
+ inc hl
+ ld a, [hl] ; a: first byte of the code.
+ or a
+ ; if 2 bytes code, jump.
+ jr nz, .asm_6b37
+ ; if 1 byte code(ascii),
+ ; set first byte to $0e.
+ ld a, $0e
+; on 2 bytes code.
+.asm_6b37
+ ld d, a ; de: character code.
+ ld hl, wNamingScreenBufferLength
+ ld a, [hl]
+ ld c, a
+ push hl
+ ld hl, wNamingScreenBufferMaxLength
+ cp [hl]
+ pop hl
+ jr nz, .asm_6b4c
+ ; if the buffer is full
+ ; just change the last character of it.
+ ld hl, wNamingScreenBuffer
+ dec hl
+ dec hl
+ jr .asm_6b51
+; increase name length before add the character.
+.asm_6b4c
+ inc [hl]
+ inc [hl]
+ ld hl, wNamingScreenBuffer
+; write 2 bytes character codes to the name buffer.
+; de: 2 bytes character codes.
+; hl: dest.
+.asm_6b51
+ ld b, 0
+ add hl, bc
+ ld [hl], d
+ inc hl
+ ld [hl], e
+ inc hl
+ ld [hl], TX_END ; null terminator.
+ call PrintPlayerNameFromInput
+.nothing
+ or a
+ ret
+.on_end
+ scf
+ ret
+
+; this transforms the last japanese character
+; in the name buffer into its dakuon shape or something.
+; it seems to have been deprecated as the game was translated into english.
+; but it can still be applied to english, such as upper-lower case transition.
+; hl: info. pointer.
+TransformCharacter:
+ ld a, [wNamingScreenBufferLength]
+ or a
+ jr z, .return ; if the length is zero, just return.
+ dec a
+ dec a
+ push hl
+ ld hl, wNamingScreenBuffer
+ ld d, 0
+ ld e, a
+ add hl, de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ; de: last character in the buffer,
+ ; but byte-wise swapped.
+ ld a, TX_KATAKANA
+ cp e
+ jr nz, .hiragana
+ ; if it's katakana,
+ ; make it hiragana by decreasing its high byte.
+ dec e
+.hiragana
+ pop hl
+.loop
+ ld a, [hli]
+ or a
+ jr z, .return
+ cp d
+ jr nz, .next
+ ld a, [hl]
+ cp e
+ jr nz, .next
+ inc hl
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ or a
+ ret
+.next
+ inc hl
+ inc hl
+ inc hl
+ jr .loop
+.return
+ scf
+ ret
+
+; given the position of the current cursor,
+; it returns the pointer to the proper information.
+; h: position x.
+; l: position y.
+GetCharInfoFromPos_Player:
+ push de
+ ; (information index) = (x) * (height) + (y)
+ ; (height) = 0x05(Deck) or 0x06(Player)
+ ld e, l
+ ld d, h
+ ld a, [wNamingScreenKeyboardHeight]
+ ld l, a
+ call HtimesL
+ ld a, l
+ add e
+ ld hl, KeyboardData_Player
+ pop de
+ or a
+ ret z
+.loop
+ inc hl
+ inc hl
+ inc hl
+ inc hl
+ inc hl
+ inc hl
+ dec a
+ jr nz, .loop
+ ret
+
+; a set of keyboard datum.
+; unit: 6 bytes.
+; structure:
+; abs. y pos. (1) / abs. x pos. (1) / type 1 (1) / type 2 (1) / char. code (2)
+; unused data contains its character code as zero.
+kbitem: MACRO
+ db \1, \2, \3, \4
+if (_NARG == 5)
+ dw \5
+elif (\5 == TX_FULLWIDTH3)
+ dw (\5 << 8) | STRCAT("FW3_", \6)
+else
+ dw (\5 << 8) | \6
+endc
+ENDM
+
+KeyboardData_Player:
+ kbitem $04, $02, $11, $00, TX_FULLWIDTH3, "A"
+ kbitem $06, $02, $12, $00, TX_FULLWIDTH3, "J"
+ kbitem $08, $02, $13, $00, TX_FULLWIDTH3, "S"
+ kbitem $0a, $02, $14, $00, "o"
+ kbitem $0c, $02, $15, $00, "d"
+ kbitem $10, $0f, $01, $09, $0000
+
+ kbitem $04, $04, $16, $00, TX_FULLWIDTH3, "B"
+ kbitem $06, $04, $17, $00, TX_FULLWIDTH3, "K"
+ kbitem $08, $04, $18, $00, TX_FULLWIDTH3, "T"
+ kbitem $0a, $04, $19, $00, TX_FULLWIDTH3, "&"
+ kbitem $0c, $04, $1a, $00, "e"
+ kbitem $10, $0f, $01, $09, $0000
+
+ kbitem $04, $06, $1b, $00, TX_FULLWIDTH3, "C"
+ kbitem $06, $06, $1c, $00, TX_FULLWIDTH3, "L"
+ kbitem $08, $06, $1d, $00, TX_FULLWIDTH3, "U"
+ kbitem $0a, $06, $1e, $00, "j"
+ kbitem $0c, $06, $1f, $00, "f"
+ kbitem $10, $0f, $01, $09, $0000
+
+ kbitem $04, $08, $20, $00, TX_FULLWIDTH3, "D"
+ kbitem $06, $08, $21, $00, TX_FULLWIDTH3, "M"
+ kbitem $08, $08, $22, $00, TX_FULLWIDTH3, "V"
+ kbitem $0a, $08, $23, $00, "k"
+ kbitem $0c, $08, $24, $00, "g"
+ kbitem $10, $0f, $01, $09, $0000
+
+ kbitem $04, $0a, $25, $00, TX_FULLWIDTH3, "E"
+ kbitem $06, $0a, $26, $00, TX_FULLWIDTH3, "N"
+ kbitem $08, $0a, $27, $00, TX_FULLWIDTH3, "W"
+ kbitem $0a, $0a, $28, $00, "w"
+ kbitem $0c, $0a, $29, $00, "h"
+ kbitem $10, $0f, $01, $09, $0000
+
+ kbitem $04, $0c, $2a, $00, TX_FULLWIDTH3, "F"
+ kbitem $06, $0c, $2b, $00, TX_FULLWIDTH3, "O"
+ kbitem $08, $0c, $2c, $00, TX_FULLWIDTH3, "X"
+ kbitem $0a, $0c, $2d, $00, "`"
+ kbitem $0c, $0c, $2e, $00, "i"
+ kbitem $10, $0f, $01, $09, $0000
+
+ kbitem $04, $0e, $2f, $00, TX_FULLWIDTH3, "G"
+ kbitem $06, $0e, $30, $00, TX_FULLWIDTH3, "P"
+ kbitem $08, $0e, $31, $00, TX_FULLWIDTH3, "Y"
+ kbitem $0a, $0e, $32, $00, "a"
+ kbitem $0c, $0e, $33, $00, TX_SYMBOL, SYM_No
+ kbitem $10, $0f, $01, $09, $0000
+
+ kbitem $04, $10, $34, $00, TX_FULLWIDTH3, "H"
+ kbitem $06, $10, $35, $00, TX_FULLWIDTH3, "Q"
+ kbitem $08, $10, $36, $00, TX_FULLWIDTH3, "Z"
+ kbitem $0a, $10, $3c, $00, "b"
+ kbitem $0c, $10, $3d, $00, TX_SYMBOL, SYM_Lv
+ kbitem $10, $0f, $01, $09, $0000
+
+ kbitem $04, $12, $37, $00, TX_FULLWIDTH3, "I"
+ kbitem $06, $12, $38, $00, TX_FULLWIDTH3, "R"
+ kbitem $08, $12, $39, $00, "n"
+ kbitem $0a, $12, $3a, $00, "c"
+ kbitem $0c, $12, $3b, $00, "p"
+ kbitem $10, $0f, $01, $09, $0000
+ kbitem $00, $00, $00, $00, $0000
+
+; a set of transition datum.
+; unit: 4 bytes.
+; structure:
+; previous char. code (2) / translated char. code (2)
+; - the former char. code contains 0x0e in high byte.
+; - the latter char. code contains only low byte.
+TransitionTable1:
+ dw $0e16, $003e
+ dw $0e17, $003f
+ dw $0e18, $0040
+ dw $0e19, $0041
+ dw $0e1a, $0042
+ dw $0e1b, $0043
+ dw $0e1c, $0044
+ dw $0e1d, $0045
+ dw $0e1e, $0046
+ dw $0e1f, $0047
+ dw $0e20, $0048
+ dw $0e21, $0049
+ dw $0e22, $004a
+ dw $0e23, $004b
+ dw $0e24, $004c
+ dw $0e2a, $004d
+ dw $0e2b, $004e
+ dw $0e2c, $004f
+ dw $0e2d, $0050
+ dw $0e2e, $0051
+ dw $0e52, $004d
+ dw $0e53, $004e
+ dw $0e54, $004f
+ dw $0e55, $0050
+ dw $0e56, $0051
+ dw $0000
+
+TransitionTable2:
+ dw $0e2a, $0052
+ dw $0e2b, $0053
+ dw $0e2c, $0054
+ dw $0e2d, $0055
+ dw $0e2e, $0056
+ dw $0e4d, $0052
+ dw $0e4e, $0053
+ dw $0e4f, $0054
+ dw $0e50, $0055
+ dw $0e51, $0056
+ dw $0000
+
+; get deck name from the user into de.
+; function description is similar to the player's.
+; refer to 'InputPlayerName'.
+InputDeckName:
+ push af
+ ; check if the buffer is empty.
+ ld a, [de]
+ or a
+ jr nz, .not_empty
+ ; this buffer will contain half-width chars.
+ ld a, TX_HALFWIDTH
+ ld [de], a
+.not_empty
+ pop af
+ inc a
+ call InitializeInputName
+ call Set_OBJ_8x8
+
+ xor a
+ ld [wTileMapFill], a
+ call EmptyScreen
+ call ZeroObjectPositions
+
+ ld a, $01
+ ld [wVBlankOAMCopyToggle], a
+ call LoadSymbolsFont
+
+ lb de, $38, $bf
+ call SetupText
+ call LoadHalfWidthTextCursorTile
+
+ xor a
+ ld [wd009], a
+ call Func_1ae99
+
+ xor a
+ ld [wNamingScreenCursorX], a
+ ld [wNamingScreenCursorY], a
+
+ ld a, $09
+ ld [wNamingScreenNumColumns], a
+ ld a, $07
+ ld [wNamingScreenKeyboardHeight], a
+ ld a, $0f
+ ld [wVisibleCursorTile], a
+ ld a, $00
+ ld [wInvisibleCursorTile], a
+.loop
+ ld a, $01
+ ld [wVBlankOAMCopyToggle], a
+ call DoFrame
+
+ call UpdateRNGSources
+
+ ldh a, [hDPadHeld]
+ and START
+ jr z, .on_start
+
+ ld a, $01
+ call PlayAcceptOrDeclineSFX
+ call Func_1afa1
+
+ ld a, 6
+ ld [wNamingScreenCursorX], a
+ ld [wNamingScreenCursorY], a
+ call Func_1afbd
+
+ jr .loop
+.on_start
+ call Func_1aefb
+ jr nc, .loop
+
+ cp $ff
+ jr z, .asm_6e1c
+
+ call Func_1aec3
+ jr nc, .loop
+
+ call FinalizeInputName
+
+ ld hl, wNamingScreenDestPointer
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ inc hl
+
+ ld a, [hl]
+ or a
+ jr nz, .return
+
+ dec hl
+ ld [hl], TX_END
+.return
+ ret
+.asm_6e1c
+ ld a, [wNamingScreenBufferLength]
+ cp $02
+ jr c, .loop
+
+ ld e, a
+ ld d, 0
+ ld hl, wNamingScreenBuffer
+ add hl, de
+ dec hl
+ ld [hl], TX_END
+
+ ld hl, wNamingScreenBufferLength
+ dec [hl]
+ call ProcessTextWithUnderbar
+
+ jp .loop
+
+; load, to the first tile of v0Tiles0, the graphics for the
+; blinking black square used in name input screens.
+; for inputting half width text.
+LoadHalfWidthTextCursorTile:
+ ld hl, v0Tiles0 + $00 tiles
+ ld de, .data
+ ld b, 0
+.loop
+ ld a, TILE_SIZE
+ cp b
+ ret z
+ inc b
+ ld a, [de]
+ inc de
+ ld [hli], a
+ jr .loop
+
+.data
+rept TILE_SIZE
+ db $f0
+endr
+
+; it's only for naming the deck.
+ProcessTextWithUnderbar:
+ ld hl, wNamingScreenNamePosition
+ ld d, [hl]
+ inc hl
+ ld e, [hl]
+ call InitTextPrinting
+ ld hl, .underbar_data
+ ld de, wDefaultText
+.loop ; copy the underbar string.
+ ld a, [hli]
+ ld [de], a
+ inc de
+ or a
+ jr nz, .loop
+
+ ld hl, wNamingScreenBuffer
+ ld de, wDefaultText
+.loop2 ; copy the input from the user.
+ ld a, [hli]
+ or a
+ jr z, .print_name
+ ld [de], a
+ inc de
+ jr .loop2
+.print_name
+ ld hl, wDefaultText
+ call ProcessText
+ ret
+.underbar_data
+ db TX_HALFWIDTH
+rept MAX_DECK_NAME_LENGTH
+ db "_"
+endr
+ db TX_END
+
+Func_1ae99:
+ call DrawTextboxForKeyboard
+ call ProcessTextWithUnderbar
+ ld hl, wNamingScreenQuestionPointer
+ ld c, [hl]
+ inc hl
+ ld a, [hl]
+ ld h, a
+ or c
+ jr z, .print
+ ; print the question string.
+ ld l, c
+ call PlaceTextItems
+.print
+ ; print "End"
+ ld hl, DrawNamingScreenBG.data
+ call PlaceTextItems
+ ; print the keyboard characters.
+ ldtx hl, DeckNameKeyboardText ; "A B C D..."
+ lb de, 2, 4
+ call InitTextPrinting
+ call ProcessTextFromID
+ call EnableLCD
+ ret
+
+Func_1aec3:
+ ld a, [wNamingScreenCursorX]
+ ld h, a
+ ld a, [wNamingScreenCursorY]
+ ld l, a
+ call GetCharInfoFromPos_Deck
+ inc hl
+ inc hl
+ ld a, [hl]
+ cp $01
+ jr nz, .asm_6ed7
+ scf
+ ret
+.asm_6ed7
+ ld d, a
+ ld hl, wNamingScreenBufferLength
+ ld a, [hl]
+ ld c, a
+ push hl
+ ld hl, wNamingScreenBufferMaxLength
+ cp [hl]
+ pop hl
+ jr nz, .asm_6eeb
+ ld hl, wNamingScreenBuffer
+ dec hl
+ jr .asm_6eef
+.asm_6eeb
+ inc [hl]
+ ld hl, wNamingScreenBuffer
+.asm_6eef
+ ld b, 0
+ add hl, bc
+ ld [hl], d
+ inc hl
+ ld [hl], TX_END
+ call ProcessTextWithUnderbar
+ or a
+ ret
+
+Func_1aefb:
+ xor a
+ ld [wPlaysSfx], a
+ ldh a, [hDPadHeld]
+ or a
+ jp z, .asm_6f73
+ ld b, a
+ ld a, [wNamingScreenKeyboardHeight]
+ ld c, a
+ ld a, [wNamingScreenCursorX]
+ ld h, a
+ ld a, [wNamingScreenCursorY]
+ ld l, a
+ bit 6, b
+ jr z, .asm_6f1f
+ dec a
+ bit 7, a
+ jr z, .asm_6f4b
+ ld a, c
+ dec a
+ jr .asm_6f4b
+.asm_6f1f
+ bit 7, b
+ jr z, .asm_6f2a
+ inc a
+ cp c
+ jr c, .asm_6f4b
+ xor a
+ jr .asm_6f4b
+.asm_6f2a
+ cp $06
+ jr z, .asm_6f73
+ ld a, [wNamingScreenNumColumns]
+ ld c, a
+ ld a, h
+ bit 5, b
+ jr z, .asm_6f40
+ dec a
+ bit 7, a
+ jr z, .asm_6f4e
+ ld a, c
+ dec a
+ jr .asm_6f4e
+.asm_6f40
+ bit 4, b
+ jr z, .asm_6f73
+ inc a
+ cp c
+ jr c, .asm_6f4e
+ xor a
+ jr .asm_6f4e
+.asm_6f4b
+ ld l, a
+ jr .asm_6f4f
+.asm_6f4e
+ ld h, a
+.asm_6f4f
+ push hl
+ call GetCharInfoFromPos_Deck
+ inc hl
+ inc hl
+ ld d, [hl]
+ push de
+ call Func_1afa1
+ pop de
+ pop hl
+ ld a, l
+ ld [wNamingScreenCursorY], a
+ ld a, h
+ ld [wNamingScreenCursorX], a
+ xor a
+ ld [wCheckMenuCursorBlinkCounter], a
+ ld a, $02
+ cp d
+ jp z, Func_1aefb
+ ld a, $01
+ ld [wPlaysSfx], a
+.asm_6f73
+ ldh a, [hKeysPressed]
+ and $03
+ jr z, .asm_6f89
+ and $01
+ jr nz, .asm_6f7f
+ ld a, $ff
+.asm_6f7f
+ call PlayAcceptOrDeclineSFX
+ push af
+ call Func_1afbd
+ pop af
+ scf
+ ret
+.asm_6f89
+ ld a, [wPlaysSfx]
+ or a
+ jr z, .asm_6f92
+ call PlaySFX
+.asm_6f92
+ ld hl, wCheckMenuCursorBlinkCounter
+ ld a, [hl]
+ inc [hl]
+ and $0f
+ ret nz
+ ld a, [wVisibleCursorTile]
+ bit 4, [hl]
+ jr z, Func_1afa1.asm_6fa4
+
+Func_1afa1:
+ ld a, [wInvisibleCursorTile]
+.asm_6fa4
+ ld e, a
+ ld a, [wNamingScreenCursorX]
+ ld h, a
+ ld a, [wNamingScreenCursorY]
+ ld l, a
+ call GetCharInfoFromPos_Deck
+ ld a, [hli]
+ ld c, a
+ ld b, [hl]
+ dec b
+ ld a, e
+ call Func_1afc2
+ call WriteByteToBGMap0
+ or a
+ ret
+
+Func_1afbd:
+ ld a, [wVisibleCursorTile]
+ jr Func_1afa1.asm_6fa4
+
+Func_1afc2:
+ push af
+ push bc
+ push de
+ push hl
+ push af
+ call ZeroObjectPositions
+ pop af
+ ld b, a
+ ld a, [wInvisibleCursorTile]
+ cp b
+ jr z, .asm_6ffb
+ ld a, [wNamingScreenBufferLength]
+ ld d, a
+ ld a, [wNamingScreenBufferMaxLength]
+ ld e, a
+ ld a, d
+ cp e
+ jr nz, .asm_6fdf
+ dec a
+.asm_6fdf
+ dec a
+ ld d, a
+ ld hl, wNamingScreenNamePosition
+ ld a, [hl]
+ sla a
+ add d
+ ld d, a
+ ld h, $04
+ ld l, d
+ call HtimesL
+ ld a, l
+ add $08
+ ld d, a
+ ld e, $18
+ ld bc, $0000
+ call SetOneObjectAttributes
+.asm_6ffb
+ pop hl
+ pop de
+ pop bc
+ pop af
+ ret
+
+; given the cursor position,
+; returns the character information which the cursor directs.
+; it's similar to "GetCharInfoFromPos_Player",
+; but the data structure is different in its unit size.
+; its unit size is 3, and player's is 6.
+; h: x
+; l: y
+GetCharInfoFromPos_Deck:
+ push de
+ ld e, l
+ ld d, h
+ ld a, [wNamingScreenKeyboardHeight]
+ ld l, a
+ call HtimesL
+ ld a, l
+ add e
+ ; x * h + y
+ ld hl, KeyboardData_Deck
+ pop de
+ or a
+ ret z
+.loop
+ inc hl
+ inc hl
+ inc hl
+ dec a
+ jr nz, .loop
+ ret
+
+KeyboardData_Deck:
+ db $04, $02, "A"
+ db $06, $02, "J"
+ db $08, $02, "S"
+ db $0a, $02, "?"
+ db $0c, $02, "4"
+ db $0e, $02, $02
+ db $10, $0f, $01
+
+ db $04, $04, "B"
+ db $06, $04, "K"
+ db $08, $04, "T"
+ db $0a, $04, "&"
+ db $0c, $04, "5"
+ db $0e, $04, $02
+ db $10, $0f, $01
+
+ db $04, $06, "C"
+ db $06, $06, "L"
+ db $08, $06, "U"
+ db $0a, $06, "+"
+ db $0c, $06, "6"
+ db $0e, $06, $02
+ db $10, $0f, $01
+
+ db $04, $08, "D"
+ db $06, $08, "M"
+ db $08, $08, "V"
+ db $0a, $08, "-"
+ db $0c, $08, "7"
+ db $0e, $08, $02
+ db $10, $0f, $01
+
+ db $04, $0a, "E"
+ db $06, $0a, "N"
+ db $08, $0a, "W"
+ db $0a, $0a, "'"
+ db $0c, $0a, "8"
+ db $0e, $0a, $02
+ db $10, $0f, $01
+
+ db $04, $0c, "F"
+ db $06, $0c, "O"
+ db $08, $0c, "X"
+ db $0a, $0c, "0"
+ db $0c, $0c, "9"
+ db $0e, $0c, $02
+ db $10, $0f, $01
+
+ db $04, $0e, "G"
+ db $06, $0e, "P"
+ db $08, $0e, "Y"
+ db $0a, $0e, "1"
+ db $0c, $0e, " "
+ db $0e, $0e, $02
+ db $10, $0f, $01
+
+ db $04, $10, "H"
+ db $06, $10, "Q"
+ db $08, $10, "Z"
+ db $0a, $10, "2"
+ db $0c, $10, " "
+ db $0e, $10, $02
+ db $10, $0f, $01
+
+ db $04, $12, "I"
+ db $06, $12, "R"
+ db $08, $12, "!"
+ db $0a, $12, "3"
+ db $0c, $12, " "
+ db $0e, $12, $02
+ db $10, $0f, $01
+
+ ds 4 ; empty
diff --git a/src/engine/intro.asm b/src/engine/intro.asm
new file mode 100644
index 0000000..8a16b3a
--- /dev/null
+++ b/src/engine/intro.asm
@@ -0,0 +1,114 @@
+PlayIntroSequence:
+ call DisableLCD
+ farcall Func_10a9b
+ farcall Func_10000
+ call Func_3ca0
+ ld hl, HandleAllSpriteAnimations
+ call SetDoFrameFunction
+ call LoadTitleScreenSprites
+
+ ld a, LOW(IntroSequence)
+ ld [wSequenceCmdPtr + 0], a
+ ld a, HIGH(IntroSequence)
+ ld [wSequenceCmdPtr + 1], a
+
+ xor a
+ ld [wd317], a
+ ld [wIntroSequencePalsNeedUpdate], a
+ ld [wSequenceDelay], a
+ farcall FlashWhiteScreen
+
+.loop_cmds
+ call DoFrameIfLCDEnabled
+ call UpdateRNGSources
+ ldh a, [hKeysPressed]
+ and A_BUTTON | START
+ jr nz, .jump_to_title_screen
+ ld a, [wIntroSequencePalsNeedUpdate]
+ or a
+ jr z, .no_pal_update
+ farcall Func_10d74
+.no_pal_update
+ call ExecuteIntroSequenceCmd
+ ld a, [wSequenceDelay]
+ cp $ff
+ jr nz, .loop_cmds
+ jr .asm_1d39f
+
+.jump_to_title_screen
+ call AssertSongFinished
+ or a
+ jr nz, .asm_1d39f
+ call DisableLCD
+ ld a, MUSIC_TITLESCREEN
+ call PlaySong
+ lb bc, 0, 0
+ ld a, SCENE_TITLE_SCREEN
+ call LoadScene
+ call IntroSequenceEmptyFunc
+.asm_1d39f
+ call Func_3ca0
+ call .ShowPressStart
+ call EnableLCD
+ ret
+
+.ShowPressStart
+ ld a, SPRITE_PRESS_START
+ farcall CreateSpriteAndAnimBufferEntry
+ ld c, SPRITE_ANIM_COORD_X
+ call GetSpriteAnimBufferProperty
+ ld a, 48
+ ld [hli], a ; x
+ ld a, 112
+ ld [hl], a ; y
+ ld c, SPRITE_ANIM_190
+ ld a, [wConsole]
+ cp CONSOLE_CGB
+ jr nz, .asm_1d3c5
+ ld c, SPRITE_ANIM_191
+.asm_1d3c5
+ ld a, c
+ ld bc, 60
+ farcall Func_12ac9
+ ret
+
+LoadTitleScreenSprites:
+ xor a
+ ld [wd4ca], a
+ ld [wd4cb], a
+ ld a, PALETTE_30
+ farcall LoadPaletteData
+
+ ld bc, 0
+ ld de, wTitleScreenSprites
+.loop_load_sprites
+ push bc
+ push de
+ ld hl, .TitleScreenSpriteList
+ add hl, bc
+ ld a, [hl]
+ farcall CreateSpriteAndAnimBufferEntry
+ ld a, [wWhichSprite]
+ ld [de], a
+ call GetFirstSpriteAnimBufferProperty
+ inc hl
+ ld a, [hl] ; SPRITE_ANIM_ATTRIBUTES
+ or c
+ ld [hl], a
+ pop de
+ pop bc
+ inc de
+ inc c
+ ld a, c
+ cp $7
+ jr c, .loop_load_sprites
+ ret
+
+.TitleScreenSpriteList
+ db SPRITE_GRASS
+ db SPRITE_FIRE
+ db SPRITE_WATER
+ db SPRITE_COLORLESS
+ db SPRITE_LIGHTNING
+ db SPRITE_PSYCHIC
+ db SPRITE_FIGHTING
diff --git a/src/engine/link/card_pop.asm b/src/engine/link/card_pop.asm
new file mode 100644
index 0000000..5f809ef
--- /dev/null
+++ b/src/engine/link/card_pop.asm
@@ -0,0 +1,399 @@
+_DoCardPop:
+; loads scene for Card Pop! screen
+; then checks if console is SGB
+; and issues an error message in case it is
+ call SetSpriteAnimationsAsVBlankFunction
+ ld a,SCENE_CARD_POP
+ lb bc, 0, 0
+ call LoadScene
+ ldtx hl, AreYouBothReadyToCardPopText
+ call PrintScrollableText_NoTextBoxLabel
+ call RestoreVBlankFunction
+ ldtx hl, CardPopCannotBePlayedWithTheGameBoyText
+ ld a, [wConsole]
+ cp CONSOLE_SGB
+ jr z, .error
+
+; initiate the communications
+ call PauseSong
+ call SetSpriteAnimationsAsVBlankFunction
+ ld a, SCENE_GAMEBOY_LINK_CONNECTING
+ lb bc, 0, 0
+ call LoadScene
+ ldtx hl, PositionGameBoyColorsAndPressAButtonText
+ call DrawWideTextBox_PrintText
+ call EnableLCD
+ call HandleCardPopCommunications
+ push af
+ push hl
+ call ClearRP
+ call RestoreVBlankFunction
+ pop hl
+ pop af
+ jr c, .error
+
+; show the received card detail page
+; and play the corresponding song
+ ld a, [wLoadedCard1ID]
+ call AddCardToCollectionAndUpdateAlbumProgress
+ ld hl, wLoadedCard1Name
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call LoadTxRam2
+ ld a, PLAYER_TURN
+ ldh [hWhoseTurn], a
+ ld a, SFX_5D
+ call PlaySFX
+.wait_sfx
+ call AssertSFXFinished
+ or a
+ jr nz, .wait_sfx
+ ld a, [wCardPopCardObtainSong]
+ call PlaySong
+ ldtx hl, ReceivedThroughCardPopText
+ bank1call _DisplayCardDetailScreen
+ call ResumeSong
+ lb de, $38, $9f
+ call SetupText
+ bank1call OpenCardPage_FromHand
+ ret
+
+.error
+; show Card Pop! error scene
+; and print text in hl
+ push hl
+ call ResumeSong
+ call SetSpriteAnimationsAsVBlankFunction
+ ld a, SCENE_CARD_POP_ERROR
+ lb bc, 0, 0
+ call LoadScene
+ pop hl
+ call PrintScrollableText_NoTextBoxLabel
+ call RestoreVBlankFunction
+ ret
+
+; handles all communications to the other device to do Card Pop!
+; returns carry if Card Pop! is unsuccessful
+; and returns in hl the corresponding error text ID
+HandleCardPopCommunications:
+; copy CardPopNameList from SRAM to WRAM
+ call EnableSRAM
+ ld hl, sCardPopNameList
+ ld de, wCardPopNameList
+ ld bc, CARDPOP_NAME_LIST_SIZE
+ call CopyDataHLtoDE
+ call DisableSRAM
+
+ ld a, IRPARAM_CARD_POP
+ call InitIRCommunications
+.asm_19cc9
+ call TryReceiveIRRequest ; receive request
+ jr nc, .asm_19d05
+ bit 1, a
+ jr nz, .fail
+ call TrySendIRRequest ; send request
+ jr c, .asm_19cc9
+
+; do the player name search, then transmit the result
+ call ExchangeIRCommunicationParameters
+ jr c, .fail
+ ld hl, wCardPopNameList
+ ld de, wOtherPlayerCardPopNameList
+ ld c, 0 ; $100 bytes = CARDPOP_NAME_LIST_SIZE
+ call RequestDataTransmissionThroughIR
+ jr c, .fail
+ call LookUpNameInCardPopNameList
+ ld hl, wCardPopNameSearchResult
+ ld de, wCardPopNameSearchResult
+ ld c, 1
+ call RequestDataReceivalThroughIR
+ jr c, .fail
+ call SetIRCommunicationErrorCode_NoError
+ jr c, .fail
+ call ExecuteReceivedIRCommands
+ jr c, .fail
+ jr .check_search_result
+
+.asm_19d05
+ call ExecuteReceivedIRCommands
+ ld a, [wIRCommunicationErrorCode]
+ or a
+ jr nz, .fail
+ call RequestCloseIRCommunication
+ jr c, .fail
+
+.check_search_result
+ ld a, [wCardPopNameSearchResult]
+ or a
+ jr z, .success
+ ; not $00, means the name was found in the list
+ ldtx hl, CannotCardPopWithFriendPreviouslyPoppedWithText
+ scf
+ ret
+
+.success
+ call DecideCardToReceiveFromCardPop
+
+; increment number of times Card Pop! was done
+; and write the other player's name to sCardPopNameList
+; the spot where this is written in the list is derived
+; from the lower nybble of sTotalCardPopsDone
+; that means that after 16 Card Pop!, the older
+; names start to get overwritten
+ call EnableSRAM
+ ld hl, sTotalCardPopsDone
+ ld a, [hl]
+ inc [hl]
+ and $0f
+ swap a ; *NAME_BUFFER_LENGTH
+ ld l, a
+ ld h, $0
+ ld de, sCardPopNameList
+ add hl, de
+ ld de, wNameBuffer
+ ld c, NAME_BUFFER_LENGTH
+.loop_write_name
+ ld a, [de]
+ inc de
+ ld [hli], a
+ dec c
+ jr nz, .loop_write_name
+ call DisableSRAM
+ or a
+ ret
+
+.fail
+ ldtx hl, ThePopWasntSuccessfulText
+ scf
+ ret
+
+; looks up the name in wNameBuffer in wCardPopNameList
+; used to know whether this save file has done Card Pop!
+; with the other player already
+; returns carry and wCardPopNameSearchResult = $ff if the name was found;
+; returns no carry and wCardPopNameSearchResult = $00 otherwise
+LookUpNameInCardPopNameList:
+; searches for other player's name in this game's name list
+ ld hl, wCardPopNameList
+ ld c, CARDPOP_NAME_LIST_MAX_ELEMS
+.loop_own_card_pop_name_list
+ push hl
+ ld de, wNameBuffer
+ call .CompareNames
+ pop hl
+ jr nc, .found_name
+ ld de, NAME_BUFFER_LENGTH
+ add hl, de
+ dec c
+ jr nz, .loop_own_card_pop_name_list
+
+; name was not found in wCardPopNameList
+
+; searches for this player's name in the other game's name list
+; this is useless since it discards the result from the name comparisons
+; as a result this loop will always return no carry
+ call EnableSRAM
+ ld hl, wOtherPlayerCardPopNameList
+ ld c, CARDPOP_NAME_LIST_MAX_ELEMS
+.loop_other_card_pop_name_list
+ push hl
+ ld de, sPlayerName
+ call .CompareNames ; discards result from comparison
+ pop hl
+ ld de, NAME_BUFFER_LENGTH
+ add hl, de
+ dec c
+ jr nz, .loop_other_card_pop_name_list
+ xor a
+ jr .no_carry
+
+.found_name
+ ld a, $ff
+ scf
+.no_carry
+ call DisableSRAM
+ ld [wCardPopNameSearchResult], a ; $00 if name was not found, $ff otherwise
+ ret
+
+; compares names in hl and de
+; if they are different, return carry
+.CompareNames
+ ld b, NAME_BUFFER_LENGTH
+.loop_chars
+ ld a, [de]
+ inc de
+ cp [hl]
+ jr nz, .not_same
+ inc hl
+ dec b
+ jr nz, .loop_chars
+ or a
+ ret
+.not_same
+ scf
+ ret
+
+; loads in wLoadedCard1 a random card to be received
+; this selection is done based on the rarity that is
+; decided from the names of both participants
+; the card will always be a Pokemon card that is not
+; from a Promotional set, with the exception
+; of Venusaur1 and Mew2
+; output:
+; - e = card ID chosen
+DecideCardToReceiveFromCardPop:
+ ld a, PLAYER_TURN
+ ldh [hWhoseTurn], a
+ call EnableSRAM
+ ld hl, sPlayerName
+ call CalculateNameHash
+ call DisableSRAM
+ push de
+ ld hl, wNameBuffer
+ call CalculateNameHash
+ pop bc
+
+; de = other player's name hash
+; bc = this player's name hash
+
+; updates RNG values to subtraction of these two hashes
+ ld hl, wRNG1
+ ld a, b
+ sub d
+ ld d, a ; b - d
+ ld [hli], a ; wRNG1
+ ld a, c
+ sub e
+ ld e, a ; c - e
+ ld [hli], a ; wRNG2
+ ld [hl], $0 ; wRNGCounter
+
+; depending on the values obtained from the hashes,
+; determine which rarity card to give to the player
+; along with the song to play with each rarity
+; the probabilities of each possibility can be calculated
+; as follows (given 2 random player names):
+; 101/256 ~ 39% for Circle
+; 90/256 ~ 35% for Diamond
+; 63/256 ~ 25% for Star
+; 1/256 ~ .4% for Venusaur1 or Mew2
+ ld a, e
+ cp 5
+ jr z, .venusaur1_or_mew2
+ cp 64
+ jr c, .star_rarity ; < 64
+ cp 154
+ jr c, .diamond_rarity ; < 154
+ ; >= 154
+
+ ld a, MUSIC_BOOSTER_PACK
+ ld b, CIRCLE
+ jr .got_rarity
+.diamond_rarity
+ ld a, MUSIC_BOOSTER_PACK
+ ld b, DIAMOND
+ jr .got_rarity
+.star_rarity
+ ld a, MUSIC_MATCH_VICTORY
+ ld b, STAR
+.got_rarity
+ ld [wCardPopCardObtainSong], a
+ ld a, b
+ call CreateCardPopCandidateList
+ ; shuffle candidates and pick first from list
+ call ShuffleCards
+ ld a, [hl]
+ ld e, a
+.got_card_id
+ ld d, $0
+ call LoadCardDataToBuffer1_FromCardID
+ ld a, e
+ ret
+
+.venusaur1_or_mew2
+; choose either Venusaur1 or Mew2
+; depending on whether the lower
+; bit of d is unset or set, respectively
+ ld a, MUSIC_MEDAL
+ ld [wCardPopCardObtainSong], a
+ ld e, VENUSAUR1
+ ld a, d
+ and $1 ; get lower bit
+ jr z, .got_card_id
+ ld e, MEW2
+ jr .got_card_id
+
+; lists in wCardPopCardCandidates all cards that:
+; - are Pokemon cards;
+; - have the same rarity as input register a;
+; - are not from Promotional set.
+; input:
+; - a = card rarity
+; output:
+; - a = number of candidates
+CreateCardPopCandidateList:
+ ld hl, wPlayerDeck
+ push hl
+ push de
+ push bc
+ ld b, a
+
+ lb de, 0, GRASS_ENERGY
+.loop_card_ids
+ call LoadCardDataToBuffer1_FromCardID
+ jr c, .count ; no more card IDs
+ ld a, [wLoadedCard1Type]
+ and TYPE_ENERGY
+ jr nz, .next_card_id ; not Pokemon card
+ ld a, [wLoadedCard1Rarity]
+ cp b
+ jr nz, .next_card_id ; not equal rarity
+ ld a, [wLoadedCard1Set]
+ and $f0
+ cp PROMOTIONAL
+ jr z, .next_card_id ; no promos
+ ld [hl], e
+ inc hl
+.next_card_id
+ inc de
+ jr .loop_card_ids
+
+; count all the cards that were listed
+; and return it in a
+.count
+ ld [hl], $00 ; invalid card ID as end of list
+ ld hl, wPlayerDeck
+ ld c, -1
+.loop_count
+ inc c
+ ld a, [hli]
+ or a
+ jr nz, .loop_count
+ ld a, c
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; creates a unique two-byte hash from the name given in hl
+; the low byte is calculated by simply adding up all characters
+; the high byte is calculated by xoring all characters together
+; input:
+; - hl = points to the start of the name buffer
+; output:
+; - de = hash
+CalculateNameHash:
+ ld c, NAME_BUFFER_LENGTH
+ ld de, $0
+.loop
+ ld a, e
+ add [hl]
+ ld e, a
+ ld a, d
+ xor [hl]
+ ld d, a
+ inc hl
+ dec c
+ jr nz, .loop
+ ret
diff --git a/src/engine/link/ir_core.asm b/src/engine/link/ir_core.asm
new file mode 100644
index 0000000..ab9eaae
--- /dev/null
+++ b/src/engine/link/ir_core.asm
@@ -0,0 +1,531 @@
+; if carry flag is set, only delays
+; if carry not set:
+; - set rRP to $c1, wait;
+; - set rRP to $c0, wait;
+; - return
+Func_19674:
+ jr c, .delay_once
+ ld [hl], $c1
+ ld a, 5
+ jr .loop_delay_1 ; jump to possibly to add more cycles?
+.loop_delay_1
+ dec a
+ jr nz, .loop_delay_1
+ ld [hl], $c0
+ ld a, 14
+ jr .loop_delay_2 ; jump to possibly to add more cycles?
+.loop_delay_2
+ dec a
+ jr nz, .loop_delay_2
+ ret
+
+.delay_once
+ ld a, 21
+ jr .loop_delay_3 ; jump to possibly to add more cycles?
+.loop_delay_3
+ dec a
+ jr nz, .loop_delay_3
+ nop
+ ret
+
+; input a = byte to transmit through IR
+TransmitByteThroughIR:
+ push hl
+ ld hl, rRP
+ push de
+ push bc
+ ld b, a
+ scf ; carry set
+ call Func_19674
+ or a ; carry not set
+ call Func_19674
+ ld c, 8
+ ld c, 8 ; number of input bits
+.loop
+ ld a, $00
+ rr b
+ call Func_19674
+ dec c
+ jr nz, .loop
+ pop bc
+ pop de
+ pop hl
+ ldh a, [rJOYP]
+ bit 1, a ; P11
+ jr z, ReturnZFlagUnsetAndCarryFlagSet
+ xor a ; return z set
+ ret
+
+; same as ReceiveByteThroughIR but
+; returns $0 in a if there's an error in IR
+ReceiveByteThroughIR_ZeroIfUnsuccessful:
+ call ReceiveByteThroughIR
+ ret nc
+ xor a
+ ret
+
+; returns carry if there's some time out
+; and output in register a of $ff
+; otherwise returns in a some sequence of bits
+; related to how rRP sets/unsets bit 1
+ReceiveByteThroughIR:
+ push de
+ push bc
+ push hl
+
+; waits for bit 1 in rRP to be unset
+; up to $100 loops
+ ld b, 0
+ ld hl, rRP
+.wait_ir
+ bit 1, [hl]
+ jr z, .ok
+ dec b
+ jr nz, .wait_ir
+ ; looped around $100 times
+ ; return $ff and carry set
+ pop hl
+ pop bc
+ pop de
+ scf
+ ld a, $ff
+ ret
+
+.ok
+; delay for some cycles
+ ld a, 15
+.loop_delay
+ dec a
+ jr nz, .loop_delay
+
+; loop for each bit
+ ld e, 8
+.loop
+ ld a, $01
+ ; possibly delay cycles?
+ ld b, 9
+ ld b, 9
+ ld b, 9
+ ld b, 9
+
+; checks for bit 1 in rRP
+; if in any of the checks it is unset,
+; then a is set to 0
+; this is done a total of 9 times
+ bit 1, [hl]
+ jr nz, .asm_196ec
+ xor a
+.asm_196ec
+ bit 1, [hl]
+ jr nz, .asm_196f1
+ xor a
+.asm_196f1
+ dec b
+ jr nz, .asm_196ec
+ ; one bit received
+ rrca
+ rr d
+ dec e
+ jr nz, .loop
+ ld a, d ; has bits set for each "cycle" that bit 1 was not unset
+ pop hl
+ pop bc
+ pop de
+ or a
+ ret
+
+ReturnZFlagUnsetAndCarryFlagSet:
+ ld a, $ff
+ or a ; z not set
+ scf ; carry set
+ ret
+
+; called when expecting to transmit data
+Func_19705:
+ ld hl, rRP
+.asm_19708
+ ldh a, [rJOYP]
+ bit 1, a
+ jr z, ReturnZFlagUnsetAndCarryFlagSet
+ ld a, $aa ; request
+ call TransmitByteThroughIR
+ push hl
+ pop hl
+ call ReceiveByteThroughIR_ZeroIfUnsuccessful
+ cp $33 ; acknowledge
+ jr nz, .asm_19708
+ xor a
+ ret
+
+; called when expecting to receive data
+Func_1971e:
+ ld hl, rRP
+.asm_19721
+ ldh a, [rJOYP]
+ bit 1, a
+ jr z, ReturnZFlagUnsetAndCarryFlagSet
+ call ReceiveByteThroughIR_ZeroIfUnsuccessful
+ cp $aa ; request
+ jr nz, .asm_19721
+ ld a, $33 ; acknowledge
+ call TransmitByteThroughIR
+ xor a
+ ret
+
+ReturnZFlagUnsetAndCarryFlagSet2:
+ jp ReturnZFlagUnsetAndCarryFlagSet
+
+TransmitIRDataBuffer:
+ call Func_19705
+ jr c, ReturnZFlagUnsetAndCarryFlagSet2
+ ld a, $49
+ call TransmitByteThroughIR
+ ld a, $52
+ call TransmitByteThroughIR
+ ld hl, wIRDataBuffer
+ ld c, 8
+ jr TransmitNBytesFromHLThroughIR
+
+ReceiveIRDataBuffer:
+ call Func_1971e
+ jr c, ReturnZFlagUnsetAndCarryFlagSet2
+ call ReceiveByteThroughIR
+ cp $49
+ jr nz, ReceiveIRDataBuffer
+ call ReceiveByteThroughIR
+ cp $52
+ jr nz, ReceiveIRDataBuffer
+ ld hl, wIRDataBuffer
+ ld c, 8
+ jr ReceiveNBytesToHLThroughIR
+
+; hl = start of data to transmit
+; c = number of bytes to transmit
+TransmitNBytesFromHLThroughIR:
+ ld b, $0
+.loop_data_bytes
+ ld a, b
+ add [hl]
+ ld b, a
+ ld a, [hli]
+ call TransmitByteThroughIR
+ jr c, .asm_1977c
+ dec c
+ jr nz, .loop_data_bytes
+ ld a, b
+ cpl
+ inc a
+ call TransmitByteThroughIR
+.asm_1977c
+ ret
+
+; hl = address to write received data
+; c = number of bytes to be received
+ReceiveNBytesToHLThroughIR:
+ ld b, 0
+.loop_data_bytes
+ call ReceiveByteThroughIR
+ jr c, ReturnZFlagUnsetAndCarryFlagSet2
+ ld [hli], a
+ add b
+ ld b, a
+ dec c
+ jr nz, .loop_data_bytes
+ call ReceiveByteThroughIR
+ add b
+ or a
+ jr nz, ReturnZFlagUnsetAndCarryFlagSet2
+ ret
+
+; disables interrupts, and sets joypad and IR communication port
+; switches to CGB normal speed
+StartIRCommunications:
+ di
+ call SwitchToCGBNormalSpeed
+ ld a, P14
+ ldh [rJOYP], a
+ ld a, $c0
+ ldh [rRP], a
+ ret
+
+; reenables interrupts, and switches CGB back to double speed
+CloseIRCommunications:
+ ld a, P14 | P15
+ ldh [rJOYP], a
+.wait_vblank_on
+ ldh a, [rSTAT]
+ and STAT_LCDC_STATUS
+ cp STAT_ON_VBLANK
+ jr z, .wait_vblank_on
+.wait_vblank_off
+ ldh a, [rSTAT]
+ and STAT_LCDC_STATUS
+ cp STAT_ON_VBLANK
+ jr nz, .wait_vblank_off
+ call SwitchToCGBDoubleSpeed
+ ei
+ ret
+
+; set rRP to 0
+ClearRP:
+ ld a, $00
+ ldh [rRP], a
+ ret
+
+; expects to receive a command (IRCMD_* constant)
+; in wIRDataBuffer + 1, then calls the subroutine
+; corresponding to that command
+ExecuteReceivedIRCommands:
+ call StartIRCommunications
+.loop_commands
+ call ReceiveIRDataBuffer
+ jr c, .error
+ jr nz, .loop_commands
+ ld hl, wIRDataBuffer + 1
+ ld a, [hl]
+ ld hl, .CmdPointerTable
+ cp NUM_IR_COMMANDS
+ jr nc, .loop_commands ; invalid command
+ call .JumpToCmdPointer ; execute command
+ jr .loop_commands
+.error
+ call CloseIRCommunications
+ xor a
+ scf
+ ret
+
+.JumpToCmdPointer
+ add a ; *2
+ add l
+ ld l, a
+ ld a, 0
+ adc h
+ ld h, a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+.jp_hl
+ jp hl
+
+.CmdPointerTable
+ dw .Close ; IRCMD_CLOSE
+ dw .ReturnWithoutClosing ; IRCMD_RETURN_WO_CLOSING
+ dw .TransmitData ; IRCMD_TRANSMIT_DATA
+ dw .ReceiveData ; IRCMD_RECEIVE_DATA
+ dw .CallFunction ; IRCMD_CALL_FUNCTION
+
+; closes the IR communications
+; pops hl so that the sp points
+; to the return address of ExecuteReceivedIRCommands
+.Close
+ pop hl
+ call CloseIRCommunications
+ or a
+ ret
+
+; returns without closing the IR communications
+; will continue the command loop
+.ReturnWithoutClosing
+ or a
+ ret
+
+; receives an address and number of bytes
+; and transmits starting at that address
+.TransmitData
+ call Func_19705
+ ret c
+ call LoadRegistersFromIRDataBuffer
+ jp TransmitNBytesFromHLThroughIR
+
+; receives an address and number of bytes
+; and writes the data received to that address
+.ReceiveData
+ call LoadRegistersFromIRDataBuffer
+ ld l, e
+ ld h, d
+ call ReceiveNBytesToHLThroughIR
+ jr c, .asm_19812
+ sub b
+ call TransmitByteThroughIR
+.asm_19812
+ ret
+
+; receives an address to call, then stores
+; the registers in the IR data buffer
+.CallFunction
+ call LoadRegistersFromIRDataBuffer
+ call .jp_hl
+ call StoreRegistersInIRDataBuffer
+ ret
+
+; returns carry set if request sent was not acknowledged
+TrySendIRRequest:
+ call StartIRCommunications
+ ld hl, rRP
+ ld c, 4
+.send_request
+ ld a, $aa ; request
+ push bc
+ call TransmitByteThroughIR
+ push bc
+ pop bc
+ call ReceiveByteThroughIR_ZeroIfUnsuccessful
+ pop bc
+ cp $33 ; acknowledgement
+ jr z, .received_ack
+ dec c
+ jr nz, .send_request
+ scf
+ jr .close
+
+.received_ack
+ xor a
+.close
+ push af
+ call CloseIRCommunications
+ pop af
+ ret
+
+; returns carry set if request was not received
+TryReceiveIRRequest:
+ call StartIRCommunications
+ ld hl, rRP
+.wait_request
+ call ReceiveByteThroughIR_ZeroIfUnsuccessful
+ cp $aa ; request
+ jr z, .send_ack
+ ldh a, [rJOYP]
+ cpl
+ and P10 | P11
+ jr z, .wait_request
+ scf
+ jr .close
+
+.send_ack
+ ld a, $33 ; acknowledgement
+ call TransmitByteThroughIR
+ xor a
+.close
+ push af
+ call CloseIRCommunications
+ pop af
+ ret
+
+; sends request for other device to close current communication
+RequestCloseIRCommunication:
+ call StartIRCommunications
+ ld a, IRCMD_CLOSE
+ ld [wIRDataBuffer + 1], a
+ call TransmitIRDataBuffer
+; fallthrough
+
+; calls CloseIRCommunications while preserving af
+SafelyCloseIRCommunications:
+ push af
+ call CloseIRCommunications
+ pop af
+ ret
+
+; sends a request for data to be transmitted
+; from the other device
+; hl = start of data to request to transmit
+; de = address to write data received
+; c = length of data
+RequestDataTransmissionThroughIR:
+ ld a, IRCMD_TRANSMIT_DATA
+ call TransmitRegistersThroughIR
+ push de
+ push bc
+ call Func_1971e
+ pop bc
+ pop hl
+ jr c, SafelyCloseIRCommunications
+ call ReceiveNBytesToHLThroughIR
+ jr SafelyCloseIRCommunications
+
+; transmits data to be written in the other device
+; hl = start of data to transmit
+; de = address for other device to write data
+; c = length of data
+RequestDataReceivalThroughIR:
+ ld a, IRCMD_RECEIVE_DATA
+ call TransmitRegistersThroughIR
+ call TransmitNBytesFromHLThroughIR
+ jr c, SafelyCloseIRCommunications
+ call ReceiveByteThroughIR
+ jr c, SafelyCloseIRCommunications
+ add b
+ jr nz, .asm_1989e
+ xor a
+ jr SafelyCloseIRCommunications
+.asm_1989e
+ call ReturnZFlagUnsetAndCarryFlagSet
+ jr SafelyCloseIRCommunications
+
+; first stores all the current registers in wIRDataBuffer
+; then transmits it through IR
+TransmitRegistersThroughIR:
+ push hl
+ push de
+ push bc
+ call StoreRegistersInIRDataBuffer
+ call StartIRCommunications
+ call TransmitIRDataBuffer
+ pop bc
+ pop de
+ pop hl
+ ret nc
+ inc sp
+ inc sp
+ jr SafelyCloseIRCommunications
+
+; stores af, hl, de and bc in wIRDataBuffer
+StoreRegistersInIRDataBuffer:
+ push de
+ push hl
+ push af
+ ld hl, wIRDataBuffer
+ pop de
+ ld [hl], e ; <- f
+ inc hl
+ ld [hl], d ; <- a
+ inc hl
+ pop de
+ ld [hl], e ; <- l
+ inc hl
+ ld [hl], d ; <- h
+ inc hl
+ pop de
+ ld [hl], e ; <- e
+ inc hl
+ ld [hl], d ; <- d
+ inc hl
+ ld [hl], c ; <- c
+ inc hl
+ ld [hl], b ; <- b
+ ret
+
+; loads all the registers that were stored
+; from StoreRegistersInIRDataBuffer
+LoadRegistersFromIRDataBuffer:
+ ld hl, wIRDataBuffer
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+ push de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+ push de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+ ld c, [hl]
+ inc hl
+ ld b, [hl]
+ pop hl
+ pop af
+ ret
diff --git a/src/engine/link/ir_functions.asm b/src/engine/link/ir_functions.asm
new file mode 100644
index 0000000..140dccb
--- /dev/null
+++ b/src/engine/link/ir_functions.asm
@@ -0,0 +1,323 @@
+; hl = text ID
+LoadLinkConnectingScene:
+ push hl
+ call SetSpriteAnimationsAsVBlankFunction
+ ld a, SCENE_GAMEBOY_LINK_CONNECTING
+ lb bc, 0, 0
+ call LoadScene
+ pop hl
+ call DrawWideTextBox_PrintText
+ call EnableLCD
+ ret
+
+; shows Link Not Connected scene
+; then asks the player whether they want to try again
+; if the player selects "no", return carry
+; input:
+; - hl = text ID
+LoadLinkNotConnectedSceneAndAskWhetherToTryAgain:
+ push hl
+ call RestoreVBlankFunction
+ call SetSpriteAnimationsAsVBlankFunction
+ ld a, SCENE_GAMEBOY_LINK_NOT_CONNECTED
+ lb bc, 0, 0
+ call LoadScene
+ pop hl
+ call DrawWideTextBox_WaitForInput
+ ldtx hl, WouldYouLikeToTryAgainText
+ call YesOrNoMenuWithText_SetCursorToYes
+; fallthrough
+
+ClearRPAndRestoreVBlankFunction:
+ push af
+ call ClearRP
+ call RestoreVBlankFunction
+ pop af
+ ret
+
+; prepares IR communication parameter data
+; a = a IRPARAM_* constant for the function of this connection
+InitIRCommunications:
+ ld hl, wOwnIRCommunicationParams
+ ld [hl], a
+ inc hl
+ ld [hl], $50
+ inc hl
+ ld [hl], $4b
+ inc hl
+ ld [hl], $31
+ ld a, $ff
+ ld [wIRCommunicationErrorCode], a
+ ld a, PLAYER_TURN
+ ldh [hWhoseTurn], a
+; clear wNameBuffer and wOpponentName
+ xor a
+ ld [wNameBuffer], a
+ ld hl, wOpponentName
+ ld [hli], a
+ ld [hl], a
+; loads player's name from SRAM
+; to wDefaultText
+ call EnableSRAM
+ ld hl, sPlayerName
+ ld de, wDefaultText
+ ld c, NAME_BUFFER_LENGTH
+.loop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .loop
+ call DisableSRAM
+ ret
+
+; returns carry if communication was unsuccessful
+; if a = 0, then it was a communication error
+; if a = 1, then operation was cancelled by the player
+PrepareSendCardOrDeckConfigurationThroughIR:
+ call InitIRCommunications
+
+; pressing A button triggers request for IR communication
+.loop_frame
+ call DoFrame
+ ldh a, [hKeysPressed]
+ bit B_BUTTON_F, a
+ jr nz, .b_btn
+ ldh a, [hKeysHeld]
+ bit A_BUTTON_F, a
+ jr z, .loop_frame
+; a btn
+ call TrySendIRRequest
+ jr nc, .request_success
+ or a
+ jr z, .loop_frame
+ xor a
+ scf
+ ret
+
+.b_btn
+ ; cancelled by the player
+ ld a, $01
+ scf
+ ret
+
+.request_success
+ call ExchangeIRCommunicationParameters
+ ret c
+ ld a, [wOtherIRCommunicationParams + 3]
+ cp $31
+ jr nz, SetIRCommunicationErrorCode_Error
+ or a
+ ret
+
+; exchanges player names and IR communication parameters
+; checks whether parameters for communication match
+; and if they don't, an error is issued
+ExchangeIRCommunicationParameters:
+ ld hl, wOwnIRCommunicationParams
+ ld de, wOtherIRCommunicationParams
+ ld c, 4
+ call RequestDataTransmissionThroughIR
+ jr c, .error
+ ld hl, wOtherIRCommunicationParams + 1
+ ld a, [hli]
+ cp $50
+ jr nz, .error
+ ld a, [hli]
+ cp $4b
+ jr nz, .error
+ ld a, [wOwnIRCommunicationParams]
+ ld hl, wOtherIRCommunicationParams
+ cp [hl] ; do parameters match?
+ jr nz, SetIRCommunicationErrorCode_Error
+
+; receives wDefaultText from other device
+; and writes it to wNameBuffer
+ ld hl, wDefaultText
+ ld de, wNameBuffer
+ ld c, NAME_BUFFER_LENGTH
+ call RequestDataTransmissionThroughIR
+ jr c, .error
+; transmits wDefaultText to be
+; written in wNameBuffer in the other device
+ ld hl, wDefaultText
+ ld de, wNameBuffer
+ ld c, NAME_BUFFER_LENGTH
+ call RequestDataReceivalThroughIR
+ jr c, .error
+ or a
+ ret
+
+.error
+ xor a
+ scf
+ ret
+
+SetIRCommunicationErrorCode_Error:
+ ld hl, wIRCommunicationErrorCode
+ ld [hl], $01
+ ld de, wIRCommunicationErrorCode
+ ld c, 1
+ call RequestDataReceivalThroughIR
+ call RequestCloseIRCommunication
+ ld a, $01
+ scf
+ ret
+
+SetIRCommunicationErrorCode_NoError:
+ ld hl, wOwnIRCommunicationParams
+ ld [hl], $00
+ ld de, wIRCommunicationErrorCode
+ ld c, 1
+ call RequestDataReceivalThroughIR
+ ret c
+ call RequestCloseIRCommunication
+ or a
+ ret
+
+; makes device receptive to receive data from other device
+; to write in wDuelTempList (either list of cards or a deck configuration)
+; returns carry if some error occurred
+TryReceiveCardOrDeckConfigurationThroughIR:
+ call InitIRCommunications
+.loop_receive_request
+ xor a
+ ld [wDuelTempList], a
+ call TryReceiveIRRequest
+ jr nc, .receive_data
+ bit 1, a
+ jr nz, .cancelled
+ jr .loop_receive_request
+.receive_data
+ call ExecuteReceivedIRCommands
+ ld a, [wIRCommunicationErrorCode]
+ or a
+ ret z ; no error
+ xor a
+ scf
+ ret
+
+.cancelled
+ ld a, $01
+ scf
+ ret
+
+; returns carry if card(s) wasn't successfully sent
+_SendCard:
+ call StopMusic
+ ldtx hl, SendingACardText
+ call LoadLinkConnectingScene
+ ld a, IRPARAM_SEND_CARDS
+ call PrepareSendCardOrDeckConfigurationThroughIR
+ jr c, .fail
+
+ ; send cards
+ xor a
+ ld [wDuelTempList + DECK_SIZE], a
+ ld hl, wDuelTempList
+ ld e, l
+ ld d, h
+ ld c, DECK_SIZE + 1
+ call RequestDataReceivalThroughIR
+ jr c, .fail
+ call SetIRCommunicationErrorCode_NoError
+ jr c, .fail
+ call ExecuteReceivedIRCommands
+ jr c, .fail
+ ld a, [wOwnIRCommunicationParams + 1]
+ cp $4f
+ jr nz, .fail
+ call PlayCardPopSong
+ xor a
+ call ClearRPAndRestoreVBlankFunction
+ ret
+
+.fail
+ call PlayCardPopSong
+ ldtx hl, CardTransferWasntSuccessful1Text
+ call LoadLinkNotConnectedSceneAndAskWhetherToTryAgain
+ jr nc, _SendCard ; loop back and try again
+ ; failed
+ scf
+ ret
+
+PlayCardPopSong:
+ ld a, MUSIC_CARD_POP
+ jp PlaySong
+
+_ReceiveCard:
+ call StopMusic
+ ldtx hl, ReceivingACardText
+ call LoadLinkConnectingScene
+ ld a, IRPARAM_SEND_CARDS
+ call TryReceiveCardOrDeckConfigurationThroughIR
+ ld a, $4f
+ ld [wOwnIRCommunicationParams + 1], a
+ ld hl, wOwnIRCommunicationParams
+ ld e, l
+ ld d, h
+ ld c, 4
+ call RequestDataReceivalThroughIR
+ jr c, .fail
+ call RequestCloseIRCommunication
+ jr c, .fail
+ call PlayCardPopSong
+ or a
+ call ClearRPAndRestoreVBlankFunction
+ ret
+
+.fail
+ call PlayCardPopSong
+ ldtx hl, CardTransferWasntSuccessful2Text
+ call LoadLinkNotConnectedSceneAndAskWhetherToTryAgain
+ jr nc, _ReceiveCard
+ scf
+ ret
+
+_SendDeckConfiguration:
+ call StopMusic
+ ldtx hl, SendingADeckConfigurationText
+ call LoadLinkConnectingScene
+ ld a, IRPARAM_SEND_DECK
+ call PrepareSendCardOrDeckConfigurationThroughIR
+ jr c, .fail
+ ld hl, wDuelTempList
+ ld e, l
+ ld d, h
+ ld c, DECK_STRUCT_SIZE
+ call RequestDataReceivalThroughIR
+ jr c, .fail
+ call SetIRCommunicationErrorCode_NoError
+ jr c, .fail
+ call PlayCardPopSong
+ call ClearRPAndRestoreVBlankFunction
+ or a
+ ret
+
+.fail
+ call PlayCardPopSong
+ ldtx hl, DeckConfigurationTransferWasntSuccessful1Text
+ call LoadLinkNotConnectedSceneAndAskWhetherToTryAgain
+ jr nc, _SendDeckConfiguration
+ scf
+ ret
+
+_ReceiveDeckConfiguration:
+ call StopMusic
+ ldtx hl, ReceivingDeckConfigurationText
+ call LoadLinkConnectingScene
+ ld a, IRPARAM_SEND_DECK
+ call TryReceiveCardOrDeckConfigurationThroughIR
+ jr c, .fail
+ call PlayCardPopSong
+ call ClearRPAndRestoreVBlankFunction
+ or a
+ ret
+
+.fail
+ call PlayCardPopSong
+ ldtx hl, DeckConfigurationTransferWasntSuccessful2Text
+ call LoadLinkNotConnectedSceneAndAskWhetherToTryAgain
+ jr nc, _ReceiveDeckConfiguration ; loop back and try again
+ scf
+ ret
diff --git a/src/engine/link/link_duel.asm b/src/engine/link/link_duel.asm
new file mode 100644
index 0000000..fc484d0
--- /dev/null
+++ b/src/engine/link/link_duel.asm
@@ -0,0 +1,179 @@
+; sets up to start a link duel
+; decides which device will pick the number of prizes
+; then exchanges names and duels between the players
+; and starts the main duel routine
+_SetUpAndStartLinkDuel:
+ ld hl, sp+$00
+ ld a, l
+ ld [wDuelReturnAddress + 0], a
+ ld a, h
+ ld [wDuelReturnAddress + 1], a
+ call SetSpriteAnimationsAsVBlankFunction
+
+ ld a, SCENE_GAMEBOY_LINK_TRANSMITTING
+ lb bc, 0, 0
+ call LoadScene
+
+ bank1call LoadPlayerDeck
+ call SwitchToCGBNormalSpeed
+ bank1call DecideLinkDuelVariables
+ push af
+ call RestoreVBlankFunction
+ pop af
+ jp c, .error
+
+ ld a, DUELIST_TYPE_PLAYER
+ ld [wPlayerDuelistType], a
+ ld a, DUELIST_TYPE_LINK_OPP
+ ld [wOpponentDuelistType], a
+ ld a, DUELTYPE_LINK
+ ld [wDuelType], a
+
+ call EmptyScreen
+ ld a, [wSerialOp]
+ cp $29
+ jr nz, .asm_1a540
+
+ ld a, PLAYER_TURN
+ ldh [hWhoseTurn], a
+ call .ExchangeNamesAndDecks
+ jr c, .error
+ lb de, 6, 2
+ lb bc, 8, 6
+ call DrawRegularTextBox
+ lb de, 7, 4
+ call InitTextPrinting
+ ldtx hl, PrizesCardsText
+ call ProcessTextFromID
+ ldtx hl, ChooseTheNumberOfPrizesText
+ call DrawWideTextBox_PrintText
+ call EnableLCD
+ call .PickNumberOfPrizeCards
+ ld a, [wNPCDuelPrizes]
+ call SerialSend8Bytes
+ jr .prizes_decided
+
+.asm_1a540
+ ld a, OPPONENT_TURN
+ ldh [hWhoseTurn], a
+ call .ExchangeNamesAndDecks
+ jr c, .error
+ ldtx hl, PleaseWaitDecidingNumberOfPrizesText
+ call DrawWideTextBox_PrintText
+ call EnableLCD
+ call SerialRecv8Bytes
+ ld [wNPCDuelPrizes], a
+
+.prizes_decided
+ call ExchangeRNG
+ ld a, LINK_OPP_PIC
+ ld [wOpponentPortrait], a
+ ldh a, [hWhoseTurn]
+ push af
+ call EmptyScreen
+ bank1call SetDefaultPalettes
+ ld a, SHUFFLE_DECK
+ ld [wDuelDisplayedScreen], a
+ bank1call DrawDuelistPortraitsAndNames
+ ld a, OPPONENT_TURN
+ ldh [hWhoseTurn], a
+ ld a, [wNPCDuelPrizes]
+ ld l, a
+ ld h, $00
+ call LoadTxRam3
+ ldtx hl, BeginAPrizeDuelWithText
+ call DrawWideTextBox_WaitForInput
+ pop af
+ ldh [hWhoseTurn], a
+ call ExchangeRNG
+ bank1call StartDuel_VSLinkOpp
+ call SwitchToCGBDoubleSpeed
+ ret
+
+.error
+ ld a, -1
+ ld [wDuelResult], a
+ call SetSpriteAnimationsAsVBlankFunction
+
+ ld a, SCENE_GAMEBOY_LINK_NOT_CONNECTED
+ lb bc, 0, 0
+ call LoadScene
+
+ ldtx hl, TransmissionErrorText
+ call DrawWideTextBox_WaitForInput
+ call RestoreVBlankFunction
+ call ResetSerial
+ ret
+
+.ExchangeNamesAndDecks
+ ld de, wDefaultText
+ push de
+ call CopyPlayerName
+ pop hl
+ ld de, wNameBuffer
+ ld c, NAME_BUFFER_LENGTH
+ call SerialExchangeBytes
+ ret c
+ xor a
+ ld hl, wOpponentName
+ ld [hli], a
+ ld [hl], a
+ ld hl, wPlayerDeck
+ ld de, wOpponentDeck
+ ld c, DECK_SIZE
+ call SerialExchangeBytes
+ ret
+
+; handles player choice of number of prize cards
+; pressing left/right makes it decrease/increase respectively
+; selection is confirmed by pressing A button
+.PickNumberOfPrizeCards
+ ld a, PRIZES_4
+ ld [wNPCDuelPrizes], a
+ xor a
+ ld [wPrizeCardSelectionFrameCounter], a
+.loop_input
+ call DoFrame
+ ld a, [wNPCDuelPrizes]
+ add SYM_0
+ ld e, a
+ ; check frame counter so that it
+ ; either blinks or shows number
+ ld hl, wPrizeCardSelectionFrameCounter
+ ld a, [hl]
+ inc [hl]
+ and $10
+ jr z, .no_blink
+ ld e, SYM_SPACE
+.no_blink
+ ld a, e
+ lb bc, 9, 6
+ call WriteByteToBGMap0
+
+ ldh a, [hDPadHeld]
+ ld b, a
+ ld a, [wNPCDuelPrizes]
+ bit D_LEFT_F, b
+ jr z, .check_d_right
+ dec a
+ cp PRIZES_2
+ jr nc, .got_prize_count
+ ld a, PRIZES_6 ; wrap around to 6
+ jr .got_prize_count
+
+.check_d_right
+ bit D_RIGHT_F, b
+ jr z, .check_a_btn
+ inc a
+ cp PRIZES_6 + 1
+ jr c, .got_prize_count
+ ld a, PRIZES_2
+.got_prize_count
+ ld [wNPCDuelPrizes], a
+ xor a
+ ld [wPrizeCardSelectionFrameCounter], a
+
+.check_a_btn
+ bit A_BUTTON_F, b
+ jr z, .loop_input
+ ret
diff --git a/src/engine/link/printer.asm b/src/engine/link/printer.asm
new file mode 100644
index 0000000..110fde4
--- /dev/null
+++ b/src/engine/link/printer.asm
@@ -0,0 +1,1124 @@
+; sends serial data to printer
+; if there's an error in connection,
+; show Printer Not Connected scene with error message
+_PreparePrinterConnection:
+ ld bc, $0
+ lb de, PRINTERPKT_DATA, $0
+ call SendPrinterPacket
+ ret nc ; return if no error
+
+ ld hl, wPrinterStatus
+ ld a, [hl]
+ or a
+ jr nz, .asm_19e55
+ ld [hl], $ff
+.asm_19e55
+ ld a, [hl]
+ cp $ff
+ jr z, ShowPrinterIsNotConnected
+; fallthrough
+
+; shows message on screen depending on wPrinterStatus
+; also shows SCENE_GAMEBOY_PRINTER_NOT_CONNECTED.
+HandlePrinterError:
+ ld a, [wPrinterStatus]
+ cp $ff
+ jr z, .cable_or_printer_switch
+ or a
+ jr z, .interrupted
+ bit PRINTER_ERROR_BATTERIES_LOST_CHARGE, a
+ jr nz, .batteries_lost_charge
+ bit PRINTER_ERROR_CABLE_PRINTER_SWITCH, a
+ jr nz, .cable_or_printer_switch
+ bit PRINTER_ERROR_PAPER_JAMMED, a
+ jr nz, .jammed_printer
+
+ ldtx hl, PrinterPacketErrorText
+ ld a, $04
+ jr ShowPrinterConnectionErrorScene
+.cable_or_printer_switch
+ ldtx hl, CheckCableOrPrinterSwitchText
+ ld a, $02
+ jr ShowPrinterConnectionErrorScene
+.jammed_printer
+ ldtx hl, PrinterPaperIsJammedText
+ ld a, $03
+ jr ShowPrinterConnectionErrorScene
+.batteries_lost_charge
+ ldtx hl, BatteriesHaveLostTheirChargeText
+ ld a, $01
+ jr ShowPrinterConnectionErrorScene
+.interrupted
+ ldtx hl, PrintingWasInterruptedText
+ call DrawWideTextBox_WaitForInput
+ scf
+ ret
+
+ShowPrinterIsNotConnected:
+ ldtx hl, PrinterIsNotConnectedText
+ ld a, $02
+; fallthrough
+
+; a = error code
+; hl = text ID to print in text box
+ShowPrinterConnectionErrorScene:
+ push hl
+ ; unnecessary loading TxRam, since the text data
+ ; already incorporate the error number
+ ld l, a
+ ld h, $00
+ call LoadTxRam3
+
+ call SetSpriteAnimationsAsVBlankFunction
+ ld a, SCENE_GAMEBOY_PRINTER_NOT_CONNECTED
+ lb bc, 0, 0
+ call LoadScene
+ pop hl
+ call DrawWideTextBox_WaitForInput
+ call RestoreVBlankFunction
+ scf
+ ret
+
+; main card printer function
+Func_19eb4:
+ ld e, a
+ ld d, $0
+ call LoadCardDataToBuffer1_FromCardID
+ call SetSpriteAnimationsAsVBlankFunction
+ ld a, SCENE_GAMEBOY_PRINTER_TRANSMITTING
+ lb bc, 0, 0
+ call LoadScene
+ ld a, 20
+ call CopyCardNameAndLevel
+ ld [hl], TX_END
+ ld hl, $0
+ call LoadTxRam2
+ ldtx hl, NowPrintingText
+ call DrawWideTextBox_PrintText
+ call EnableLCD
+ call PrepareForPrinterCommunications
+ call DrawTopCardInfoInSRAMGfxBuffer0
+ call Func_19f87
+ call DrawCardPicInSRAMGfxBuffer2
+ call Func_19f99
+ jr c, .error
+ call DrawBottomCardInfoInSRAMGfxBuffer0
+ call Func_1a011
+ jr c, .error
+ call RestoreVBlankFunction
+ call ResetPrinterCommunicationSettings
+ or a
+ ret
+.error
+ call RestoreVBlankFunction
+ call ResetPrinterCommunicationSettings
+ jp HandlePrinterError
+
+DrawCardPicInSRAMGfxBuffer2:
+ ld hl, wLoadedCard1Gfx
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, sGfxBuffer2
+ call Func_37a5
+ ; draw card's picture in sGfxBuffer2
+ ld a, $40
+ lb hl, 12, 1
+ lb de, 2, 68
+ lb bc, 16, 12
+ call FillRectangle
+ ret
+
+; writes the tiles necessary to draw
+; the card's information in sGfxBuffer0
+; this includes card's type, lv, HP and attacks if Pokemon card
+; or otherwise just the card's name and type symbol
+DrawTopCardInfoInSRAMGfxBuffer0:
+ call Func_1a025
+ call Func_212f
+
+ ; draw empty text box frame
+ ld hl, sGfxBuffer0
+ ld a, $34
+ lb de, $30, $31
+ ld b, 20
+ call CopyLine
+ ld c, 15
+.loop_lines
+ xor a ; SYM_SPACE
+ lb de, $36, $37
+ ld b, 20
+ call CopyLine
+ dec c
+ jr nz, .loop_lines
+
+ ; draw card type symbol
+ ld a, $38
+ lb hl, 1, 2
+ lb de, 1, 65
+ lb bc, 2, 2
+ call FillRectangle
+ ; print card's name
+ lb de, 4, 65
+ ld hl, wLoadedCard1Name
+ call InitTextPrinting_ProcessTextFromPointerToID
+
+; prints card's type, lv, HP and attacks if it's a Pokemon card
+ ld a, [wLoadedCard1Type]
+ cp TYPE_ENERGY
+ jr nc, .skip_pokemon_data
+ inc a ; symbol corresponding to card's type (color)
+ lb bc, 18, 65
+ call WriteByteToBGMap0
+ ld a, SYM_Lv
+ lb bc, 11, 66
+ call WriteByteToBGMap0
+ ld a, [wLoadedCard1Level]
+ lb bc, 12, 66
+ bank1call WriteTwoDigitNumberInTxSymbolFormat
+ ld a, SYM_HP
+ lb bc, 15, 66
+ call WriteByteToBGMap0
+ ld a, [wLoadedCard1EffectCommands]
+ inc b
+ bank1call WriteTwoByteNumberInTxSymbolFormat
+.skip_pokemon_data
+ ret
+
+Func_19f87:
+ call TryInitPrinterCommunications
+ ret c
+ ld hl, sGfxBuffer0
+ call Func_1a0cc
+ ret c
+ call Func_1a0cc
+ call Func_1a111
+ ret
+
+Func_19f99:
+ call TryInitPrinterCommunications
+ ret c
+ ld hl, sGfxBuffer0 + $8 tiles
+ ld c, $06
+.asm_19fa2
+ call Func_1a0cc
+ ret c
+ dec c
+ jr nz, .asm_19fa2
+ call Func_1a111
+ ret
+
+; writes the tiles necessary to draw
+; the card's information in sGfxBuffer0
+; this includes card's Retreat cost, Weakness, Resistance,
+; and attack if it's Pokemon card
+; or otherwise just the card's description.
+DrawBottomCardInfoInSRAMGfxBuffer0:
+ call Func_1a025
+ xor a
+ ld [wCardPageType], a
+ ld hl, sGfxBuffer0
+ ld b, 20
+ ld c, 9
+.loop_lines
+ xor a ; SYM_SPACE
+ lb de, $36, $37
+ call CopyLine
+ dec c
+ jr nz, .loop_lines
+ ld a, $35
+ lb de, $32, $33
+ call CopyLine
+
+ ld a, [wLoadedCard1Type]
+ cp TYPE_ENERGY
+ jr nc, .not_pkmn_card
+ ld hl, RetreatWeakResistData
+ call PlaceTextItems
+ ld c, 66
+ bank1call DisplayCardPage_PokemonOverview.attacks
+ ld a, SYM_No
+ lb bc, 15, 72
+ call WriteByteToBGMap0
+ inc b
+ ld a, [wLoadedCard1PokedexNumber]
+ bank1call WriteTwoByteNumberInTxSymbolFormat
+ ret
+
+.not_pkmn_card
+ bank1call SetNoLineSeparation
+ lb de, 1, 66
+ ld a, SYM_No
+ call InitTextPrintingInTextbox
+ ld hl, wLoadedCard1NonPokemonDescription
+ call ProcessTextFromPointerToID
+ bank1call SetOneLineSeparation
+ ret
+
+RetreatWeakResistData:
+ textitem 1, 70, RetreatText
+ textitem 1, 71, WeaknessText
+ textitem 1, 72, ResistanceText
+ db $ff
+
+Func_1a011:
+ call TryInitPrinterCommunications
+ ret c
+ ld hl, sGfxBuffer0
+ ld c, $05
+.asm_1a01a
+ call Func_1a0cc
+ ret c
+ dec c
+ jr nz, .asm_1a01a
+ call Func_1a108
+ ret
+
+; calls setup text and sets wTilePatternSelector
+Func_1a025:
+ lb de, $40, $bf
+ call SetupText
+ ld a, $a4
+ ld [wTilePatternSelector], a
+ xor a
+ ld [wTilePatternSelectorCorrection], a
+ ret
+
+; switches to CGB normal speed, resets serial
+; enables SRAM and switches to SRAM1
+; and clears sGfxBuffer0
+PrepareForPrinterCommunications:
+ call SwitchToCGBNormalSpeed
+ call ResetSerial
+ ld a, $10
+ ld [wce9b], a
+ call EnableSRAM
+ ld a, [sPrinterContrastLevel]
+ ld [wPrinterContrastLevel], a
+ call DisableSRAM
+ ldh a, [hBankSRAM]
+ ld [wce8f], a
+ ld a, BANK("SRAM1")
+ call BankswitchSRAM
+ call EnableSRAM
+; fallthrough
+
+ClearPrinterGfxBuffer:
+ ld hl, sGfxBuffer0
+ ld bc, $400
+.loop
+ xor a
+ ld [hli], a
+ dec bc
+ ld a, c
+ or b
+ jr nz, .loop
+ xor a
+ ld [wce9f], a
+ ret
+
+; reverts settings changed by PrepareForPrinterCommunications
+ResetPrinterCommunicationSettings:
+ push af
+ call SwitchToCGBDoubleSpeed
+ ld a, [wce8f]
+ call BankswitchSRAM
+ call DisableSRAM
+ lb de, $30, $bf
+ call SetupText
+ pop af
+ ret
+
+; send some bytes through serial
+Func_1a080: ; unreferenced
+ ld bc, $0
+ lb de, PRINTERPKT_NUL, $0
+ jp SendPrinterPacket
+
+; tries initiating the communications for
+; sending data to printer
+; returns carry if operation was cancelled
+; by pressing B button or serial transfer took long
+TryInitPrinterCommunications:
+ xor a
+ ld [wPrinterInitAttempts], a
+.wait_input
+ call DoFrame
+ ldh a, [hKeysHeld]
+ and B_BUTTON
+ jr nz, .b_button
+ ld bc, $0
+ lb de, PRINTERPKT_NUL, $0
+ call SendPrinterPacket
+ jr c, .delay
+ and (1 << PRINTER_STATUS_BUSY) | (1 << PRINTER_STATUS_PRINTING)
+ jr nz, .wait_input
+
+.init
+ ld bc, $0
+ lb de, PRINTERPKT_INIT, $0
+ call SendPrinterPacket
+ jr nc, .no_carry
+ ld hl, wPrinterInitAttempts
+ inc [hl]
+ ld a, [hl]
+ cp 3
+ jr c, .wait_input
+ ; time out
+ scf
+ ret
+.no_carry
+ ret
+
+.b_button
+ xor a
+ ld [wPrinterStatus], a
+ scf
+ ret
+
+.delay
+ ld c, 10
+.delay_loop
+ call DoFrame
+ dec c
+ jr nz, .delay_loop
+ jr .init
+
+; loads tiles given by map in hl to sGfxBuffer5
+; copies first 20 tiles, then offsets by 2 tiles
+; and copies another 20
+Func_1a0cc:
+ push bc
+ ld de, sGfxBuffer5
+ call .Copy20Tiles
+ call .Copy20Tiles
+ push hl
+ call CompressDataForPrinterSerialTransfer
+ call SendPrinterPacket
+ pop hl
+ pop bc
+ ret
+
+; copies 20 tiles given by hl to de
+; then adds 2 tiles to hl
+.Copy20Tiles ; 1a0e0 (6:60e0)
+ push hl
+ ld c, 20
+.loop_tiles
+ ld a, [hli]
+ call .CopyTile
+ dec c
+ jr nz, .loop_tiles
+ pop hl
+ ld bc, 2 tiles
+ add hl, bc
+ ret
+
+; copies a tile to de
+; a = tile to get from sGfxBuffer1
+.CopyTile ; 1a0f0 (6:60f0)
+ push hl
+ push bc
+ ld l, a
+ ld h, $00
+ add hl, hl
+ add hl, hl
+ add hl, hl
+ add hl, hl ; *TILE_SIZE
+ ld bc, sGfxBuffer1
+ add hl, bc
+ ld c, TILE_SIZE
+.loop_copy
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .loop_copy
+ pop bc
+ pop hl
+ ret
+
+Func_1a108:
+ call GetPrinterContrastSerialData
+ push hl
+ lb hl, $3, $1
+ jr SendPrinterInstructionPacket
+
+Func_1a111:
+ call GetPrinterContrastSerialData
+ push hl
+ ld hl, wce9b
+ ld a, [hl]
+ ld [hl], $00
+ ld h, a
+ ld l, $01
+; fallthrough
+
+SendPrinterInstructionPacket:
+ push hl
+ ld bc, $0
+ lb de, PRINTERPKT_DATA, $0
+ call SendPrinterPacket
+ jr c, .asm_1a135
+ ld hl, sp+$00 ; contrast level bytes
+ ld bc, $4 ; instruction packets are 4 bytes in size
+ lb de, PRINTERPKT_PRINT_INSTRUCTION, $0
+ call SendPrinterPacket
+.asm_1a135
+ pop hl
+ pop hl
+ ret
+
+; returns in h and l the bytes
+; to be sent through serial to the printer
+; for the set contrast level
+GetPrinterContrastSerialData:
+ ld a, [wPrinterContrastLevel]
+ ld e, a
+ ld d, $00
+ ld hl, .contrast_level_data
+ add hl, de
+ ld h, [hl]
+ ld l, $e4
+ ret
+
+.contrast_level_data
+ db $00, $20, $40, $60, $7f
+
+Func_1a14b: ; unreferenced
+ ld a, $01
+ jr .asm_1a15d
+ ld a, $02
+ jr .asm_1a15d
+ ld a, $03
+ jr .asm_1a15d
+ ld a, $04
+ jr .asm_1a15d
+ ld a, $05
+.asm_1a15d
+ ld [wce9d], a
+ scf
+ ret
+
+; a = saved deck index to print
+_PrintDeckConfiguration:
+; copies selected deck from SRAM to wDuelTempList
+ call EnableSRAM
+ ld l, a
+ ld h, DECK_STRUCT_SIZE
+ call HtimesL
+ ld de, sSavedDeck1
+ add hl, de
+ ld de, wDuelTempList
+ ld bc, DECK_STRUCT_SIZE
+ call CopyDataHLtoDE
+ call DisableSRAM
+
+ call ShowPrinterTransmitting
+ call PrepareForPrinterCommunications
+ call Func_1a025
+ call Func_212f
+ lb de, 0, 64
+ lb bc, 20, 4
+ call DrawRegularTextBoxDMG
+ lb de, 4, 66
+ call InitTextPrinting
+ ld hl, wDuelTempList ; print deck name
+ call ProcessText
+ ldtx hl, DeckPrinterText
+ call ProcessTextFromID
+
+ ld a, 5
+ ld [wPrinterHorizontalOffset], a
+ ld hl, wPrinterTotalCardCount
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld [wPrintOnlyStarRarity], a
+
+ ld hl, wCurDeckCards
+.loop_cards
+ ld a, [hl]
+ or a
+ jr z, .asm_1a1d6
+ ld e, a
+ ld d, $00
+ call LoadCardDataToBuffer1_FromCardID
+
+ ; find out this card's count
+ ld a, [hli]
+ ld b, a
+ ld c, 1
+.loop_card_count
+ cp [hl]
+ jr nz, .got_card_count
+ inc hl
+ inc c
+ jr .loop_card_count
+
+.got_card_count
+ ld a, c
+ ld [wPrinterCardCount], a
+ call LoadCardInfoForPrinter
+ call AddToPrinterGfxBuffer
+ jr c, .printer_error
+ jr .loop_cards
+
+.asm_1a1d6
+ call SendCardListToPrinter
+ jr c, .printer_error
+ call ResetPrinterCommunicationSettings
+ call RestoreVBlankFunction
+ or a
+ ret
+
+.printer_error
+ call ResetPrinterCommunicationSettings
+ call RestoreVBlankFunction
+ jp HandlePrinterError
+
+SendCardListToPrinter:
+ ld a, [wPrinterHorizontalOffset]
+ cp 1
+ jr z, .skip_load_gfx
+ call LoadGfxBufferForPrinter
+ ret c
+.skip_load_gfx
+ call TryInitPrinterCommunications
+ ret c
+ call Func_1a108
+ ret
+; 0z1a1ff
+
+; increases printer horizontal offset by 2
+AddToPrinterGfxBuffer:
+ push hl
+ ld hl, wPrinterHorizontalOffset
+ inc [hl]
+ inc [hl]
+ ld a, [hl]
+ pop hl
+ ; return no carry if below 18
+ cp 18
+ ccf
+ ret nc
+ ; >= 18
+; fallthrough
+
+; copies Gfx to Gfx buffer and sends some serial data
+; returns carry set if unsuccessful
+LoadGfxBufferForPrinter:
+ push hl
+ call TryInitPrinterCommunications
+ jr c, .set_carry
+ ld a, [wPrinterHorizontalOffset]
+ srl a
+ ld c, a
+ ld hl, sGfxBuffer0
+.loop_gfx_buffer
+ call Func_1a0cc
+ jr c, .set_carry
+ dec c
+ jr nz, .loop_gfx_buffer
+ call Func_1a111
+ jr c, .set_carry
+
+ call ClearPrinterGfxBuffer
+ ld a, 1
+ ld [wPrinterHorizontalOffset], a
+ pop hl
+ or a
+ ret
+
+.set_carry
+ pop hl
+ scf
+ ret
+
+; load symbol, name, level and card count to buffer
+LoadCardInfoForPrinter:
+ push hl
+ ld a, [wPrinterHorizontalOffset]
+ or %1000000
+ ld e, a
+ ld d, 3
+ ld a, [wPrintOnlyStarRarity]
+ or a
+ jr nz, .skip_card_symbol
+ ld hl, wPrinterTotalCardCount
+ ld a, [hli]
+ or [hl]
+ call z, DrawCardSymbol
+.skip_card_symbol
+ ld a, 14
+ call CopyCardNameAndLevel
+ call InitTextPrinting
+ ld hl, wDefaultText
+ call ProcessText
+ ld a, [wPrinterHorizontalOffset]
+ or %1000000
+ ld c, a
+ ld b, 16
+ ld a, SYM_CROSS
+ call WriteByteToBGMap0
+ inc b
+ ld a, [wPrinterCardCount]
+ bank1call WriteTwoDigitNumberInTxSymbolFormat
+ pop hl
+ ret
+
+_PrintCardList:
+; if Select button is held when printing card list
+; only print cards with Star rarity (excluding Promotional cards)
+; even if it's not marked as seen in the collection
+ ld e, FALSE
+ ldh a, [hKeysHeld]
+ and SELECT
+ jr z, .no_select
+ inc e ; TRUE
+.no_select
+ ld a, e
+ ld [wPrintOnlyStarRarity], a
+
+ call ShowPrinterTransmitting
+ call CreateTempCardCollection
+ ld de, wDefaultText
+ call CopyPlayerName
+ call PrepareForPrinterCommunications
+ call Func_1a025
+ call Func_212f
+
+ lb de, 0, 64
+ lb bc, 20, 4
+ call DrawRegularTextBoxDMG
+ ld a, PLAYER_TURN
+ ldh [hWhoseTurn], a
+ lb de, 2, 66
+ call InitTextPrinting
+ ld hl, wDefaultText
+ call ProcessText
+ ldtx hl, AllCardsOwnedText
+ call ProcessTextFromID
+ ld a, [wPrintOnlyStarRarity]
+ or a
+ jr z, .asm_1a2c2
+ ld a, TX_HALF2FULL
+ call ProcessSpecialTextCharacter
+ lb de, 3, 84
+ call Func_22ca
+.asm_1a2c2
+ ld a, $ff
+ ld [wCurPrinterCardType], a
+ xor a
+ ld hl, wPrinterTotalCardCount
+ ld [hli], a
+ ld [hl], a
+ ld [wPrinterNumCardTypes], a
+ ld a, 5
+ ld [wPrinterHorizontalOffset], a
+
+ ld e, GRASS_ENERGY
+.loop_cards
+ push de
+ ld d, $00
+ call LoadCardDataToBuffer1_FromCardID
+ jr c, .done_card_loop
+ ld d, HIGH(wTempCardCollection)
+ ld a, [de] ; card ID count in collection
+ ld [wPrinterCardCount], a
+ call .LoadCardTypeEntry
+ jr c, .printer_error_pop_de
+
+ ld a, [wPrintOnlyStarRarity]
+ or a
+ jr z, .all_owned_cards_mode
+ ld a, [wLoadedCard1Set]
+ and %11110000
+ cp PROMOTIONAL
+ jr z, .next_card
+ ld a, [wLoadedCard1Rarity]
+ cp STAR
+ jr nz, .next_card
+ ; not Promotional, and Star rarity
+ ld hl, wPrinterCardCount
+ res CARD_NOT_OWNED_F, [hl]
+ jr .got_card_count
+
+.all_owned_cards_mode
+ ld a, [wPrinterCardCount]
+ or a
+ jr z, .next_card
+ cp CARD_NOT_OWNED
+ jr z, .next_card ; ignore not owned cards
+
+.got_card_count
+ ld a, [wPrinterCardCount]
+ and CARD_COUNT_MASK
+ ld c, a
+
+ ; add to total card count
+ ld hl, wPrinterTotalCardCount
+ add [hl]
+ ld [hli], a
+ ld a, 0
+ adc [hl]
+ ld [hl], a
+
+ ; add to current card type count
+ ld hl, wPrinterCurCardTypeCount
+ ld a, c
+ add [hl]
+ ld [hli], a
+ ld a, 0
+ adc [hl]
+ ld [hl], a
+
+ ld hl, wPrinterNumCardTypes
+ inc [hl]
+ ld hl, wce98
+ inc [hl]
+ call LoadCardInfoForPrinter
+ call AddToPrinterGfxBuffer
+ jr c, .printer_error_pop_de
+.next_card
+ pop de
+ inc e
+ jr .loop_cards
+
+.printer_error_pop_de
+ pop de
+.printer_error
+ call ResetPrinterCommunicationSettings
+ call RestoreVBlankFunction
+ jp HandlePrinterError
+
+.done_card_loop
+ pop de
+ ; add separator line
+ ld a, [wPrinterHorizontalOffset]
+ dec a
+ or $40
+ ld c, a
+ ld b, 0
+ call BCCoordToBGMap0Address
+ ld a, $35
+ lb de, $35, $35
+ ld b, 20
+ call CopyLine
+ call AddToPrinterGfxBuffer
+ jr c, .printer_error
+
+ ld hl, wPrinterTotalCardCount
+ ld c, [hl]
+ inc hl
+ ld b, [hl]
+ ldtx hl, TotalNumberOfCardsText
+ call .PrintTextWithNumber
+ jr c, .printer_error
+ ld a, [wPrintOnlyStarRarity]
+ or a
+ jr nz, .done
+ ld a, [wPrinterNumCardTypes]
+ ld c, a
+ ld b, 0
+ ldtx hl, TypesOfCardsText
+ call .PrintTextWithNumber
+ jr c, .printer_error
+
+.done
+ call SendCardListToPrinter
+ jr c, .printer_error
+ call ResetPrinterCommunicationSettings
+ call RestoreVBlankFunction
+ or a
+ ret
+
+; prints text ID given in hl
+; with decimal representation of
+; the number given in bc
+; hl = text ID
+; bc = number
+.PrintTextWithNumber
+ push bc
+ ld a, [wPrinterHorizontalOffset]
+ dec a
+ or $40
+ ld e, a
+ ld d, 2
+ call InitTextPrinting
+ call ProcessTextFromID
+ ld d, 14
+ call InitTextPrinting
+ pop hl
+ call TwoByteNumberToTxSymbol_TrimLeadingZeros
+ ld hl, wStringBuffer
+ call ProcessText
+ call AddToPrinterGfxBuffer
+ ret
+
+; loads this card's type icon and text
+; if it's a new card type that hasn't been printed yet
+.LoadCardTypeEntry
+ ld a, [wLoadedCard1Type]
+ ld c, a
+ cp TYPE_ENERGY
+ jr c, .got_type ; jump if Pokemon card
+ ld c, $08
+ cp TYPE_TRAINER
+ jr nc, .got_type ; jump if Trainer card
+ ld c, $07
+.got_type
+ ld hl, wCurPrinterCardType
+ ld a, [hl]
+ cp c
+ ret z ; already handled this card type
+
+ ; show corresponding icon and text
+ ; for this new card type
+ ld a, c
+ ld [hl], a ; set it as current card type
+ add a
+ add c ; *3
+ ld c, a
+ ld b, $00
+ ld hl, .IconTextList
+ add hl, bc
+ ld a, [wPrinterHorizontalOffset]
+ dec a
+ or %1000000
+ ld e, a
+ ld d, 1
+ ld a, [hli]
+ push hl
+ lb bc, 2, 2
+ lb hl, 1, 2
+ call FillRectangle
+ pop hl
+ ld d, 3
+ inc e
+ call InitTextPrinting
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call ProcessTextFromID
+
+ call AddToPrinterGfxBuffer
+ ld hl, wPrinterCurCardTypeCount
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld [wce98], a
+ ret
+
+.IconTextList
+ ; Fire
+ db $e0 ; icon tile
+ tx FirePokemonText
+
+ ; Grass
+ db $e4 ; icon tile
+ tx GrassPokemonText
+
+ ; Lightning
+ db $e8 ; icon tile
+ tx LightningPokemonText
+
+ ; Water
+ db $ec ; icon tile
+ tx WaterPokemonText
+
+ ; Fighting
+ db $f0 ; icon tile
+ tx FightingPokemonText
+
+ ; Psychic
+ db $f4 ; icon tile
+ tx PsychicPokemonText
+
+ ; Colorless
+ db $f8 ; icon tile
+ tx ColorlessPokemonText
+
+ ; Energy
+ db $fc ; icon tile
+ tx EnergyCardText
+
+ ; Trainer
+ db $dc ; icon tile
+ tx TrainerCardText
+
+ShowPrinterTransmitting:
+ call SetSpriteAnimationsAsVBlankFunction
+ ld a, SCENE_GAMEBOY_PRINTER_TRANSMITTING
+ lb bc, 0, 0
+ call LoadScene
+ ldtx hl, NowPrintingPleaseWaitText
+ call DrawWideTextBox_PrintText
+ call EnableLCD
+ ret
+
+; compresses $28 tiles in sGfxBuffer5
+; and writes it in sGfxBuffer5 + $28 tiles.
+; compressed data has 2 commands to instruct on how to decompress it.
+; - a command byte with bit 7 not set, means to copy that many + 1
+; bytes that are following it literally.
+; - a command byte with bit 7 set, means to copy the following byte
+; that many times + 2 (after masking the top bit of command byte).
+; returns in bc the size of the compressed data and
+; in de the packet type data.
+CompressDataForPrinterSerialTransfer:
+ ld hl, sGfxBuffer5
+ ld de, sGfxBuffer5 + $28 tiles
+ ld bc, $28 tiles
+.loop_remaining_data
+ ld a, $ff
+ inc b
+ dec b
+ jr nz, .check_compression
+ ld a, c
+.check_compression
+ push bc
+ push de
+ ld c, a
+ call CheckDataCompression
+ ld a, e
+ ld c, e
+ pop de
+ jr c, .copy_byte
+ ld a, c
+ ld b, c
+ dec a
+ ld [de], a ; number of bytes to copy literally - 1
+ inc de
+.copy_literal_sequence
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .copy_literal_sequence
+ ld c, b
+ jr .sub_added_bytes
+
+.copy_byte
+ ld a, c
+ dec a
+ dec a
+ or %10000000 ; set high bit
+ ld [de], a ; = (n times to copy - 2) | %10000000
+ inc de
+ ld a, [hl] ; byte to copy n times
+ ld [de], a
+ inc de
+ ld b, $0
+ add hl, bc
+
+.sub_added_bytes
+ ld a, c
+ cpl
+ inc a
+ pop bc
+ add c
+ ld c, a
+ ld a, $ff
+ adc b
+ ld b, a
+ or c
+ jr nz, .loop_remaining_data
+
+ ld hl, $10000 - (sGfxBuffer5 + $28 tiles)
+ add hl, de ; gets the size of the compressed data
+ ld c, l
+ ld b, h
+ ld hl, sGfxBuffer5 + $28 tiles
+ lb de, PRINTERPKT_DATA, $1
+ ret
+
+; checks whether the next byte sequence in hl, up to c bytes, can be compressed
+; returns carry if the next sequence of bytes can be compressed,
+; i.e. has at least 3 consecutive bytes with the same value.
+; in that case, returns in e the number of consecutive
+; same value bytes that were found.
+; if there are no bytes with same value, then count as many bytes left
+; as possible until either there are no more remaining data bytes,
+; or until a sequence of 3 bytes with the same value are found.
+; in that case, the number of bytes in this sequence is returned in e.
+CheckDataCompression:
+ push hl
+ ld e, c
+ ld a, c
+; if number of remaining bytes is less than 4
+; then no point in compressing
+ cp 4
+ jr c, .no_carry
+
+; check first if there are at least
+; 3 consecutive bytes with the same value
+ ld b, c
+ ld a, [hli]
+ cp [hl]
+ inc hl
+ jr nz, .literal_copy ; not same
+ cp [hl]
+ inc hl
+ jr nz, .literal_copy ; not same
+
+; 3 consecutive bytes were found with same value
+; keep track of how many consecutive bytes
+; with the same value there are in e
+ dec c
+ dec c
+ dec c
+ ld e, 3
+.loop_same_value
+ cp [hl]
+ jr nz, .set_carry ; exit when a different byte is found
+ inc hl
+ inc e
+ dec c
+ jr z, .set_carry ; exit when there is no more remaining data
+ bit 5, e
+ ; exit if number of consecutive bytes >= $20
+ jr z, .loop_same_value
+.set_carry
+ pop hl
+ scf
+ ret
+
+.literal_copy
+; consecutive bytes are not the same value
+; count the number of bytes there are left
+; until a sequence of 3 bytes with the same value is found
+ pop hl
+ push hl
+ ld c, b ; number of remaining bytes
+ ld e, 1
+ ld a, [hli]
+ dec c
+ jr z, .no_carry ; exit if no more data
+.reset_same_value_count
+ ld d, 2 ; number of consecutive same value bytes to exit
+.next_byte
+ inc e
+ dec c
+ jr z, .no_carry
+ bit 7, e
+ jr nz, .no_carry ; exit if >= $80
+ cp [hl]
+ jr z, .same_consecutive_value
+ ld a, [hli]
+ jr .reset_same_value_count
+.no_carry
+ pop hl
+ or a
+ ret
+
+.same_consecutive_value
+ inc hl
+ dec d
+ jr nz, .next_byte
+ ; 3 consecutive bytes with same value found
+ ; discard the last 3 bytes in the sequence
+ dec e
+ dec e
+ dec e
+ jr .no_carry
diff --git a/src/engine/menus/booster_pack.asm b/src/engine/menus/booster_pack.asm
new file mode 100644
index 0000000..934b730
--- /dev/null
+++ b/src/engine/menus/booster_pack.asm
@@ -0,0 +1,42 @@
+_OpenBoosterPack:
+ ld a, PLAYER_TURN
+ ldh [hWhoseTurn], a
+; clears DECK_SIZE bytes starting from wPlayerDuelVariables
+ ld h, a
+ ld l, $00
+.loop_clear
+ xor a
+ ld [hli], a
+ ld a, l
+ cp DECK_SIZE
+ jr c, .loop_clear
+
+; fills wDuelTempList with 0, 1, 2, 3, ...
+; up to the number of cards received in Boster Pack
+ xor a
+ ld hl, wBoosterCardsDrawn
+ ld de, wDuelTempList
+ ld c, $00
+.loop_index_sequence
+ ld a, [hli]
+ or a
+ jr z, .done_index_sequence
+ ld a, c
+ ld [de], a
+ inc de
+ inc c
+ jr .loop_index_sequence
+.done_index_sequence
+ ld a, $ff ; terminator byte
+ ld [de], a
+
+ lb de, $38, $9f
+ call SetupText
+ bank1call InitAndDrawCardListScreenLayout
+ ldtx hl, ChooseTheCardYouWishToExamineText
+ ldtx de, BoosterPackText
+ bank1call SetCardListHeaderText
+ ld a, A_BUTTON | START
+ ld [wNoItemSelectionMenuKeys], a
+ bank1call DisplayCardList
+ ret
diff --git a/src/engine/menus/common.asm b/src/engine/menus/common.asm
index 069d168..60ad0a9 100644
--- a/src/engine/menus/common.asm
+++ b/src/engine/menus/common.asm
@@ -19,8 +19,8 @@ DoCardPop:
farcall _DoCardPop
ret
-Func_7576:
- farcall Func_1991f
+AddStarterDeck:
+ farcall _AddStarterDeck
ret
PreparePrinterConnection:
@@ -43,8 +43,8 @@ SetUpAndStartLinkDuel:
farcall _SetUpAndStartLinkDuel
ret
-Func_7594:
- farcall Func_1a61f
+ShowPromotionalCardScreen:
+ farcall _ShowPromotionalCardScreen
ret
OpenBoosterPack:
diff --git a/src/engine/menus/glossary.asm b/src/engine/menus/glossary.asm
new file mode 100644
index 0000000..78f44dd
--- /dev/null
+++ b/src/engine/menus/glossary.asm
@@ -0,0 +1,221 @@
+OpenGlossaryScreen:
+ xor a
+ ld [wGlossaryPageNo], a
+ call .display_menu
+
+ xor a
+ ld [wInPlayAreaCurPosition], a
+ ld de, OpenGlossaryScreen_TransitionTable ; this data is stored in bank 2.
+ ld hl, wMenuInputTablePointer
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ld a, $ff
+ ld [wDuelInitialPrizesUpperBitsSet], a
+ xor a
+ ld [wCheckMenuCursorBlinkCounter], a
+.next
+ ld a, $01
+ ld [wVBlankOAMCopyToggle], a
+ call DoFrame
+ ldh a, [hKeysPressed]
+ and SELECT
+ jr nz, .on_select
+
+ farcall YourOrOppPlayAreaScreen_HandleInput
+ jr nc, .next
+
+ cp -1 ; b button
+ jr nz, .check_button
+
+ farcall ZeroObjectPositionsWithCopyToggleOn
+ ret
+
+.check_button
+ push af
+ farcall ZeroObjectPositionsWithCopyToggleOn
+ pop af
+
+ cp $09 ; $09: next page or prev page
+ jr z, .change_page
+
+ call .print_description
+ call .display_menu
+ xor a
+ ld [wCheckMenuCursorBlinkCounter], a
+ jr .next
+
+.on_select
+ ld a, $01
+ farcall PlaySFXConfirmOrCancel
+.change_page
+ ld a, [wGlossaryPageNo]
+ xor $01 ; swap page
+ ld [wGlossaryPageNo], a
+ call .print_menu
+ jr .next
+
+; display glossary menu.
+.display_menu ; 1852b (6:452b)
+ xor a
+ ld [wTileMapFill], a
+ call ZeroObjectPositions
+ ld a, $01
+ ld [wVBlankOAMCopyToggle], a
+ call DoFrame
+ call EmptyScreen
+ call Set_OBJ_8x8
+ farcall LoadCursorTile
+
+ lb de, 5, 0
+ call InitTextPrinting
+ ldtx hl, PokemonCardGlossaryText
+ call ProcessTextFromID
+ call .print_menu
+ ldtx hl, ChooseWordAndPressAButtonText
+ call DrawWideTextBox_PrintText
+ ret
+
+; print texts in glossary menu.
+.print_menu ; 1855a (6:455a)
+ ld hl, wDefaultText
+
+ ld a, TX_SYMBOL
+ ld [hli], a
+
+ ld a, [wGlossaryPageNo]
+ add SYM_1
+ ld [hli], a
+
+ ld a, TX_SYMBOL
+ ld [hli], a
+
+ ld a, SYM_SLASH
+ ld [hli], a
+
+ ld a, TX_SYMBOL
+ ld [hli], a
+
+ ld a, SYM_2
+ ld [hli], a
+
+ ld [hl], TX_END
+
+ lb de, 16, 1
+ call InitTextPrinting
+ ld hl, wDefaultText
+ call ProcessText
+
+ lb de, 1, 3
+ call InitTextPrinting
+ ld a, [wGlossaryPageNo]
+ or a
+ jr nz, .page_two
+
+ ldtx hl, GlossaryMenuPage1Text
+ jr .page_one
+
+.page_two
+ ldtx hl, GlossaryMenuPage2Text
+.page_one
+ call ProcessTextFromID
+ ret
+
+; display glossary description.
+.print_description ; 18598 (6:4598)
+ push af
+ xor a
+ ld [wTileMapFill], a
+ call EmptyScreen
+ lb de, 5, 0
+ call InitTextPrinting
+ ldtx hl, PokemonCardGlossaryText
+ call ProcessTextFromID
+ lb de, 0, 4
+ lb bc, 20, 14
+ call DrawRegularTextBox
+
+ ld a, [wGlossaryPageNo]
+ or a
+ jr nz, .back_page
+
+ ld hl, GlossaryData1
+ jr .front_page
+
+.back_page
+ ld hl, GlossaryData2
+.front_page
+ pop af
+ ; hl += (a + (a << 2)).
+ ; that is,
+ ; hl += (5 * a).
+ ld c, a
+ ld b, 0
+ add hl, bc
+ sla a
+ sla a
+ ld c, a
+ add hl, bc
+ ld a, [hli]
+ push hl
+ ld d, a
+ ld e, $02
+ call InitTextPrinting
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call ProcessTextFromID
+ pop hl
+ lb de, 1, 5
+ call InitTextPrinting
+ inc hl
+ inc hl
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, $01
+ ld [wLineSeparation], a
+ call ProcessTextFromID
+ xor a
+ ld [wLineSeparation], a
+ call EnableLCD
+.loop
+ call DoFrame
+ ldh a, [hKeysPressed]
+ and B_BUTTON
+ jr z, .loop
+
+ ld a, -1
+ farcall PlaySFXConfirmOrCancel
+ ret
+
+; unit: 5 bytes.
+; [structure]
+; horizontal align (1) / title text id (2) / desc. text id (2)
+glossary_entry: MACRO
+ db \1
+ tx \2
+ tx \3
+ENDM
+
+GlossaryData1:
+ glossary_entry 7, AboutTheDeckText, DeckDescriptionText
+ glossary_entry 5, AboutTheDiscardPileText, DiscardPileDescriptionText
+ glossary_entry 7, AboutTheHandText, HandDescriptionText
+ glossary_entry 6, AboutTheArenaText, ArenaDescriptionText
+ glossary_entry 6, AboutTheBenchText, BenchDescriptionText
+ glossary_entry 4, AboutTheActivePokemonText, ActivePokemonDescriptionText
+ glossary_entry 5, AboutBenchPokemonText, BenchPokemonDescriptionText
+ glossary_entry 7, AboutPrizesText, PrizesDescriptionText
+ glossary_entry 5, AboutDamageCountersText, DamageCountersDescriptionText
+
+GlossaryData2:
+ glossary_entry 5, AboutEnergyCardsText, EnergyCardsDescriptionText
+ glossary_entry 5, AboutTrainerCardsText, TrainerCardsDescriptionText
+ glossary_entry 5, AboutBasicPokemonText, BasicPokemonDescriptionText
+ glossary_entry 5, AboutEvolutionCardsText, EvolutionCardsDescriptionText
+ glossary_entry 6, AboutAttackingText, AttackingDescriptionText
+ glossary_entry 5, AboutPokemonPowerText, PokemonPowerDescriptionText
+ glossary_entry 6, AboutWeaknessText, WeaknessDescriptionText
+ glossary_entry 6, AboutResistanceText, ResistanceDescriptionText
+ glossary_entry 6, AboutRetreatingText, RetreatingDescriptionText
diff --git a/src/engine/menus/play_area.asm b/src/engine/menus/play_area.asm
new file mode 100644
index 0000000..047d24f
--- /dev/null
+++ b/src/engine/menus/play_area.asm
@@ -0,0 +1,570 @@
+; this function is called when the player is shown the "In Play Area" screen.
+; it can be called with either the select button (DuelMenuShortcut_BothActivePokemon),
+; or via the "In Play Area" item of the Check menu (DuelCheckMenu_InPlayArea)
+OpenInPlayAreaScreen:
+ ld a, INPLAYAREA_PLAYER_ACTIVE
+ ld [wInPlayAreaCurPosition], a
+.start
+ xor a
+ ld [wCheckMenuCursorBlinkCounter], a
+ farcall DrawInPlayAreaScreen
+ call EnableLCD
+ call IsClairvoyanceActive
+ jr c, .clairvoyance_on
+
+ ld de, OpenInPlayAreaScreen_TransitionTable1
+ jr .clairvoyance_off
+
+.clairvoyance_on
+ ld de, OpenInPlayAreaScreen_TransitionTable2
+.clairvoyance_off
+ ld hl, wMenuInputTablePointer
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ld a, [wInPlayAreaCurPosition]
+ call .print_associated_text
+.on_frame
+ ld a, $01
+ ld [wVBlankOAMCopyToggle], a
+ call DoFrame
+
+ ldh a, [hDPadHeld]
+ and START
+ jr nz, .selection
+
+ ; if this function's been called from 'select' button,
+ ; wInPlayAreaFromSelectButton is on.
+ ld a, [wInPlayAreaFromSelectButton]
+ or a
+ jr z, .handle_input ; if it's from the Check menu, jump.
+
+ ldh a, [hDPadHeld]
+ and SELECT
+ jr nz, .skip_input
+
+.handle_input
+ ld a, [wInPlayAreaCurPosition]
+ ld [wInPlayAreaTemporaryPosition], a
+ call OpenInPlayAreaScreen_HandleInput
+ jr c, .pressed
+
+ ld a, [wInPlayAreaCurPosition]
+ cp INPLAYAREA_PLAYER_PLAY_AREA
+ jp z, .show_turn_holder_play_area
+ cp INPLAYAREA_OPP_PLAY_AREA
+ jp z, .show_non_turn_holder_play_area
+
+ ; check if the cursor moved.
+ ld hl, wInPlayAreaTemporaryPosition
+ cp [hl]
+ call nz, .print_associated_text
+
+ jr .on_frame
+
+.pressed
+ cp -1
+ jr nz, .selection
+
+ ; pressed b button.
+ call ZeroObjectPositionsAndToggleOAMCopy_Bank6
+ lb de, $38, $9f
+ call SetupText
+ scf
+ ret
+
+.skip_input
+ call ZeroObjectPositionsAndToggleOAMCopy_Bank6
+ lb de, $38, $9f
+ call SetupText
+ or a
+ ret
+
+.selection ; pressed a button or start button.
+ call ZeroObjectPositionsAndToggleOAMCopy_Bank6
+ lb de, $38, $9f
+ call SetupText
+ ld a, [wInPlayAreaCurPosition]
+ ld [wInPlayAreaPreservedPosition], a
+ ld hl, .jump_table
+ call JumpToFunctionInTable
+ ld a, [wInPlayAreaPreservedPosition]
+ ld [wInPlayAreaCurPosition], a
+
+ jp .start
+
+.print_associated_text ; 18171 (6:4171)
+; each position has a text associated to it,
+; which is printed at the bottom of the screen
+ push af
+ lb de, 1, 17
+ call InitTextPrinting
+ ldtx hl, EmptyLineText
+ call ProcessTextFromID
+
+ ld hl, hffb0
+ ld [hl], $01
+ ldtx hl, HandText_2
+ call ProcessTextFromID
+
+ ld hl, hffb0
+ ld [hl], $00
+ lb de, 1, 17
+ call InitTextPrinting
+ pop af
+ ld hl, OpenInPlayAreaScreen_TextTable
+ ld b, 0
+ sla a
+ ld c, a
+ add hl, bc
+
+ ; hl = OpenInPlayAreaScreen_TextTable + 2 * (wInPlayAreaCurPosition)
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, h
+
+ ; jump ahead if entry does not contain null text (it's not active pokemon)
+ or a
+ jr nz, .print_hand_or_discard_pile
+
+ ld a, l
+ ; bench slots have dummy text IDs assigned to them, which are never used.
+ ; these are secretly not text id's, but rather, 2-byte PLAY_AREA_BENCH_* constants
+ ; check if the value at register l is one of those, and jump ahead if not
+ cp PLAY_AREA_BENCH_5 + $01
+ jr nc, .print_hand_or_discard_pile
+
+; if we make it here, we need to print a Pokemon card name.
+; wInPlayAreaCurPosition determines which duelist
+; and l contains the PLAY_AREA_* location of the card.
+ ld a, [wInPlayAreaCurPosition]
+ cp INPLAYAREA_PLAYER_HAND
+ jr nc, .opponent_side
+
+ ld a, l
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ cp -1
+ ret z
+
+ call GetCardIDFromDeckIndex
+ call LoadCardDataToBuffer1_FromCardID
+ jr .display_card_name
+
+.opponent_side
+ ld a, l
+ add DUELVARS_ARENA_CARD
+ call GetNonTurnDuelistVariable
+ cp -1
+ ret z
+
+ call SwapTurn
+ call GetCardIDFromDeckIndex
+ call LoadCardDataToBuffer1_FromCardID
+ call SwapTurn
+
+.display_card_name
+ ld a, 18
+ call CopyCardNameAndLevel
+ ld hl, wDefaultText
+ call ProcessText
+ ret
+
+.print_hand_or_discard_pile
+; if we make it here, cursor position is to Hand or Discard Pile
+; so DuelistHandText_2 or DuelistDiscardPileText will be printed
+
+ ld a, [wInPlayAreaCurPosition]
+ cp INPLAYAREA_OPP_ACTIVE
+ jr nc, .opp_side_print_hand_or_discard_pile
+ call PrintTextNoDelay
+ ret
+
+.opp_side_print_hand_or_discard_pile
+ call SwapTurn
+ call PrintTextNoDelay
+ call SwapTurn
+ ret
+
+.show_turn_holder_play_area
+ lb de, $38, $9f
+ call SetupText
+ ldh a, [hWhoseTurn]
+ push af
+ bank1call OpenTurnHolderPlayAreaScreen
+ pop af
+ ldh [hWhoseTurn], a
+ ld a, [wInPlayAreaPreservedPosition]
+ ld [wInPlayAreaCurPosition], a
+ jp .start
+
+.show_non_turn_holder_play_area
+ lb de, $38, $9f
+ call SetupText
+ ldh a, [hWhoseTurn]
+ push af
+ bank1call OpenNonTurnHolderPlayAreaScreen
+ pop af
+ ldh [hWhoseTurn], a
+ ld a, [wInPlayAreaPreservedPosition]
+ ld [wInPlayAreaCurPosition], a
+ jp .start
+
+.jump_table ; (6:4228)
+ dw OpenInPlayAreaScreen_TurnHolderPlayArea ; 0x00: INPLAYAREA_PLAYER_BENCH_1
+ dw OpenInPlayAreaScreen_TurnHolderPlayArea ; 0x01: INPLAYAREA_PLAYER_BENCH_2
+ dw OpenInPlayAreaScreen_TurnHolderPlayArea ; 0x02: INPLAYAREA_PLAYER_BENCH_3
+ dw OpenInPlayAreaScreen_TurnHolderPlayArea ; 0x03: INPLAYAREA_PLAYER_BENCH_4
+ dw OpenInPlayAreaScreen_TurnHolderPlayArea ; 0x04: INPLAYAREA_PLAYER_BENCH_5
+ dw OpenInPlayAreaScreen_TurnHolderPlayArea ; 0x05: INPLAYAREA_PLAYER_ACTIVE
+ dw OpenInPlayAreaScreen_TurnHolderHand ; 0x06: INPLAYAREA_PLAYER_HAND
+ dw OpenInPlayAreaScreen_TurnHolderDiscardPile ; 0x07: INPLAYAREA_PLAYER_DISCARD_PILE
+ dw OpenInPlayAreaScreen_NonTurnHolderPlayArea ; 0x08: INPLAYAREA_OPP_ACTIVE
+ dw OpenInPlayAreaScreen_NonTurnHolderHand ; 0x09: INPLAYAREA_OPP_HAND
+ dw OpenInPlayAreaScreen_NonTurnHolderDiscardPile ; 0x0a: INPLAYAREA_OPP_DISCARD_PILE
+ dw OpenInPlayAreaScreen_NonTurnHolderPlayArea ; 0x0b: INPLAYAREA_OPP_BENCH_1
+ dw OpenInPlayAreaScreen_NonTurnHolderPlayArea ; 0x0c: INPLAYAREA_OPP_BENCH_2
+ dw OpenInPlayAreaScreen_NonTurnHolderPlayArea ; 0x0d: INPLAYAREA_OPP_BENCH_3
+ dw OpenInPlayAreaScreen_NonTurnHolderPlayArea ; 0x0e: INPLAYAREA_OPP_BENCH_4
+ dw OpenInPlayAreaScreen_NonTurnHolderPlayArea ; 0x0f: INPLAYAREA_OPP_BENCH_5
+
+OpenInPlayAreaScreen_TurnHolderPlayArea:
+ ; wInPlayAreaCurPosition constants conveniently map to (PLAY_AREA_* constants - 1)
+ ; for bench locations. this mapping is taken for granted in the following code.
+ ld a, [wInPlayAreaCurPosition]
+ inc a
+ cp INPLAYAREA_PLAYER_ACTIVE + $01
+ jr nz, .on_bench
+ xor a ; PLAY_AREA_ARENA
+.on_bench
+ ld [wCurPlayAreaSlot], a
+ add DUELVARS_ARENA_CARD
+ call GetTurnDuelistVariable
+ cp -1
+ ret z
+ call GetCardIDFromDeckIndex
+ call LoadCardDataToBuffer1_FromCardID
+ xor a
+ ld [wCurPlayAreaY], a
+ bank1call OpenCardPage_FromCheckPlayArea
+ ret
+
+OpenInPlayAreaScreen_NonTurnHolderPlayArea:
+ ld a, [wInPlayAreaCurPosition]
+ sub INPLAYAREA_OPP_ACTIVE
+ or a
+ jr z, .active
+ ; convert INPLAYAREA_OPP_BENCH_* constant to PLAY_AREA_BENCH_* constant
+ sub INPLAYAREA_OPP_BENCH_1 - INPLAYAREA_OPP_ACTIVE - PLAY_AREA_BENCH_1
+.active
+ ld [wCurPlayAreaSlot], a
+ add DUELVARS_ARENA_CARD
+ call GetNonTurnDuelistVariable
+ cp -1
+ ret z
+ call SwapTurn
+ call GetCardIDFromDeckIndex
+ call LoadCardDataToBuffer1_FromCardID
+ xor a
+ ld [wCurPlayAreaY], a
+ bank1call OpenCardPage_FromCheckPlayArea
+ call SwapTurn
+ ret
+
+OpenInPlayAreaScreen_TurnHolderHand:
+ ldh a, [hWhoseTurn]
+ push af
+ bank1call OpenTurnHolderHandScreen_Simple
+ pop af
+ ldh [hWhoseTurn], a
+ ret
+
+OpenInPlayAreaScreen_NonTurnHolderHand:
+ ldh a, [hWhoseTurn]
+ push af
+ bank1call OpenNonTurnHolderHandScreen_Simple
+ pop af
+ ldh [hWhoseTurn], a
+ ret
+
+OpenInPlayAreaScreen_TurnHolderDiscardPile:
+ ldh a, [hWhoseTurn]
+ push af
+ bank1call OpenTurnHolderDiscardPileScreen
+ pop af
+ ldh [hWhoseTurn], a
+ ret
+
+OpenInPlayAreaScreen_NonTurnHolderDiscardPile:
+ ldh a, [hWhoseTurn]
+ push af
+ bank1call OpenNonTurnHolderDiscardPileScreen
+ pop af
+ ldh [hWhoseTurn], a
+ ret
+
+OpenInPlayAreaScreen_TextTable:
+; note that for bench slots, the entries are
+; PLAY_AREA_BENCH_* constants in practice
+ tx HandText ; INPLAYAREA_PLAYER_BENCH_1
+ tx CheckText ; INPLAYAREA_PLAYER_BENCH_2
+ tx AttackText ; INPLAYAREA_PLAYER_BENCH_3
+ tx PKMNPowerText ; INPLAYAREA_PLAYER_BENCH_4
+ tx DoneText ; INPLAYAREA_PLAYER_BENCH_5
+ dw NULL ; INPLAYAREA_PLAYER_ACTIVE
+ tx DuelistHandText_2 ; INPLAYAREA_PLAYER_HAND
+ tx DuelistDiscardPileText ; INPLAYAREA_PLAYER_DISCARD_PILE
+ dw NULL ; INPLAYAREA_OPP_ACTIVE
+ tx DuelistHandText_2 ; INPLAYAREA_OPP_HAND
+ tx DuelistDiscardPileText ; INPLAYAREA_OPP_DISCARD_PILE
+ tx HandText ; INPLAYAREA_OPP_BENCH_1
+ tx CheckText ; INPLAYAREA_OPP_BENCH_2
+ tx AttackText ; INPLAYAREA_OPP_BENCH_3
+ tx PKMNPowerText ; INPLAYAREA_OPP_BENCH_4
+ tx DoneText ; INPLAYAREA_OPP_BENCH_5
+
+in_play_area_cursor_transition: MACRO
+ cursor_transition \1, \2, \3, INPLAYAREA_\4, INPLAYAREA_\5, INPLAYAREA_\6, INPLAYAREA_\7
+ENDM
+
+; it's related to wMenuInputTablePointer.
+; with this table, the cursor moves into the proper location by the input.
+; note that the unit of the position is not a 8x8 tile.
+OpenInPlayAreaScreen_TransitionTable1:
+ in_play_area_cursor_transition $18, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_2, PLAYER_BENCH_5
+ in_play_area_cursor_transition $30, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_3, PLAYER_BENCH_1
+ in_play_area_cursor_transition $48, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_4, PLAYER_BENCH_2
+ in_play_area_cursor_transition $60, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_5, PLAYER_BENCH_3
+ in_play_area_cursor_transition $78, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_1, PLAYER_BENCH_4
+ in_play_area_cursor_transition $30, $6c, $00, OPP_ACTIVE, PLAYER_BENCH_1, PLAYER_DISCARD_PILE, PLAYER_DISCARD_PILE
+ in_play_area_cursor_transition $78, $80, $00, PLAYER_DISCARD_PILE, PLAYER_BENCH_1, PLAYER_ACTIVE, PLAYER_ACTIVE
+ in_play_area_cursor_transition $78, $70, $00, OPP_ACTIVE, PLAYER_HAND, PLAYER_ACTIVE, PLAYER_ACTIVE
+ in_play_area_cursor_transition $78, $34, 1 << OAM_X_FLIP, OPP_BENCH_1, PLAYER_ACTIVE, OPP_DISCARD_PILE, OPP_DISCARD_PILE
+ in_play_area_cursor_transition $30, $20, 1 << OAM_X_FLIP, OPP_BENCH_1, OPP_DISCARD_PILE, OPP_ACTIVE, OPP_ACTIVE
+ in_play_area_cursor_transition $30, $38, 1 << OAM_X_FLIP, OPP_BENCH_1, PLAYER_ACTIVE, OPP_ACTIVE, OPP_ACTIVE
+ in_play_area_cursor_transition $90, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_5, OPP_BENCH_2
+ in_play_area_cursor_transition $78, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_1, OPP_BENCH_3
+ in_play_area_cursor_transition $60, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_2, OPP_BENCH_4
+ in_play_area_cursor_transition $48, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_3, OPP_BENCH_5
+ in_play_area_cursor_transition $30, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_4, OPP_BENCH_1
+
+OpenInPlayAreaScreen_TransitionTable2:
+ in_play_area_cursor_transition $18, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_2, PLAYER_BENCH_5
+ in_play_area_cursor_transition $30, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_3, PLAYER_BENCH_1
+ in_play_area_cursor_transition $48, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_4, PLAYER_BENCH_2
+ in_play_area_cursor_transition $60, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_5, PLAYER_BENCH_3
+ in_play_area_cursor_transition $78, $8c, $00, PLAYER_ACTIVE, PLAYER_PLAY_AREA, PLAYER_BENCH_1, PLAYER_BENCH_4
+ in_play_area_cursor_transition $30, $6c, $00, OPP_ACTIVE, PLAYER_BENCH_1, PLAYER_DISCARD_PILE, PLAYER_DISCARD_PILE
+ in_play_area_cursor_transition $78, $80, $00, PLAYER_DISCARD_PILE, PLAYER_BENCH_1, PLAYER_ACTIVE, PLAYER_ACTIVE
+ in_play_area_cursor_transition $78, $70, $00, OPP_ACTIVE, PLAYER_HAND, PLAYER_ACTIVE, PLAYER_ACTIVE
+ in_play_area_cursor_transition $78, $34, 1 << OAM_X_FLIP, OPP_BENCH_1, PLAYER_ACTIVE, OPP_DISCARD_PILE, OPP_DISCARD_PILE
+ in_play_area_cursor_transition $30, $20, 1 << OAM_X_FLIP, OPP_BENCH_1, OPP_DISCARD_PILE, OPP_ACTIVE, OPP_ACTIVE
+ in_play_area_cursor_transition $30, $38, 1 << OAM_X_FLIP, OPP_HAND, PLAYER_ACTIVE, OPP_ACTIVE, OPP_ACTIVE
+ in_play_area_cursor_transition $90, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_5, OPP_BENCH_2
+ in_play_area_cursor_transition $78, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_1, OPP_BENCH_3
+ in_play_area_cursor_transition $60, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_2, OPP_BENCH_4
+ in_play_area_cursor_transition $48, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_3, OPP_BENCH_5
+ in_play_area_cursor_transition $30, $14, 1 << OAM_X_FLIP, OPP_PLAY_AREA, OPP_ACTIVE, OPP_BENCH_4, OPP_BENCH_1
+
+OpenInPlayAreaScreen_HandleInput:
+ xor a
+ ld [wPlaysSfx], a
+ ld hl, wMenuInputTablePointer
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld a, [wInPlayAreaCurPosition]
+ ld l, a
+ ld h, $07
+ call HtimesL
+ add hl, de
+
+ ldh a, [hDPadHeld]
+ or a
+ jp z, .check_button
+
+ inc hl
+ inc hl
+ inc hl
+
+ ; check d-pad
+ 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
+ push af
+ ld a, [wInPlayAreaCurPosition]
+ ld [wInPlayAreaPreservedPosition], a
+ pop af
+
+ ld [wInPlayAreaCurPosition], a
+ cp INPLAYAREA_PLAYER_ACTIVE
+ jr c, .player_area
+ cp INPLAYAREA_OPP_BENCH_1
+ jr c, .next
+ cp INPLAYAREA_PLAYER_PLAY_AREA
+ jr c, .opponent_area
+
+ jr .next
+
+.player_area
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetTurnDuelistVariable
+ dec a
+ jr nz, .bench_pokemon_exists
+
+ ; no pokemon in player's bench.
+ ; then move to player's play area.
+ ld a, INPLAYAREA_PLAYER_PLAY_AREA
+ ld [wInPlayAreaCurPosition], a
+ jr .next
+
+.bench_pokemon_exists
+ ld b, a
+ ld a, [wInPlayAreaCurPosition]
+ cp b
+ jr c, .next
+
+ ; handle index overflow
+ ldh a, [hDPadHeld]
+ bit D_RIGHT_F, a
+ jr z, .on_left
+
+ xor a
+ ld [wInPlayAreaCurPosition], a
+ jr .next
+
+.on_left
+ ld a, b
+ dec a
+ ld [wInPlayAreaCurPosition], a
+ jr .next
+
+.opponent_area
+ ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA
+ call GetNonTurnDuelistVariable
+ dec a
+ jr nz, .bench_pokemon_exists_2
+
+ ld a, INPLAYAREA_OPP_PLAY_AREA
+ ld [wInPlayAreaCurPosition], a
+ jr .next
+
+.bench_pokemon_exists_2
+ ld b, a
+ ld a, [wInPlayAreaCurPosition]
+ sub INPLAYAREA_OPP_BENCH_1
+ cp b
+ jr c, .next
+
+ ldh a, [hDPadHeld]
+ bit D_LEFT_F, a
+ jr z, .on_right
+
+ ld a, INPLAYAREA_OPP_BENCH_1
+ ld [wInPlayAreaCurPosition], a
+ jr .next
+
+.on_right
+ ld a, b
+ add INPLAYAREA_OPP_DISCARD_PILE
+ ld [wInPlayAreaCurPosition], a
+.next
+ ld a, $01
+ ld [wPlaysSfx], a
+ 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
+
+ ; pressed b button
+ ld a, -1
+ farcall PlaySFXConfirmOrCancel
+ scf
+ ret
+
+.a_button
+ call .draw_cursor
+ ld a, $01
+ farcall PlaySFXConfirmOrCancel
+ ld a, [wInPlayAreaCurPosition]
+ 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 $10 - 1
+ ret nz
+
+ bit 4, [hl] ; = and $10
+ jr nz, ZeroObjectPositionsAndToggleOAMCopy_Bank6
+
+.draw_cursor ; 184a0 (6:44a0)
+ call ZeroObjectPositions
+ ld hl, wMenuInputTablePointer
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld a, [wInPlayAreaCurPosition]
+ ld l, a
+ ld h, $07
+ call HtimesL
+ add hl, de
+
+ ld d, [hl] ; x position.
+ inc hl
+ ld e, [hl] ; y position.
+ inc hl
+ ld b, [hl] ; attribute.
+ ld c, $00
+ call SetOneObjectAttributes
+ or a
+ ret
+
+ZeroObjectPositionsAndToggleOAMCopy_Bank6:
+ call ZeroObjectPositions
+ ld a, $01
+ ld [wVBlankOAMCopyToggle], a
+ ret
diff --git a/src/engine/menus/start.asm b/src/engine/menus/start.asm
new file mode 100644
index 0000000..4d46d4a
--- /dev/null
+++ b/src/engine/menus/start.asm
@@ -0,0 +1,418 @@
+; plays the Opening sequence, and handles player selection
+; in the Title Screen and Start Menu
+HandleTitleScreen:
+; if last selected item in Start Menu is 0 (Card Pop!)
+; then skip straight to the Start Menu
+; this makes it so that returning from Card Pop!
+; doesn't play the Opening sequence
+ ld a, [wLastSelectedStartMenuItem]
+ or a
+ jr z, .start_menu
+
+.play_opening
+ ld a, MUSIC_STOP
+ call PlaySong
+ call Func_3ca0
+ call PlayIntroSequence
+ call LoadTitleScreenSprites
+
+ xor a
+ ld [wd635], a
+ ld a, $3c
+ ld [wTitleScreenIgnoreInputCounter], a
+.loop
+ call DoFrameIfLCDEnabled
+ call UpdateRNGSources
+ call AnimateRandomTitleScreenOrb
+ ld hl, wd635
+ inc [hl]
+ call AssertSongFinished
+ or a
+ jr nz, .song_playing
+ ; reset back to the opening sequence
+ farcall Func_10ab4
+ jr .play_opening
+
+.song_playing
+ ; should we ignore user input?
+ ld hl, wTitleScreenIgnoreInputCounter
+ ld a, [hl]
+ or a
+ jr z, .check_keys
+ ; ignore input, decrement the counter
+ dec [hl]
+ jr .loop
+
+.check_keys
+ ldh a, [hKeysPressed]
+ and A_BUTTON | START
+ jr z, .loop
+ ld a, SFX_02
+ call PlaySFX
+ farcall Func_10ab4
+
+.start_menu
+ call CheckIfHasSaveData
+ call HandleStartMenu
+
+; new game
+ ld a, [wStartMenuChoice]
+ cp START_MENU_NEW_GAME
+ jr nz, .continue_from_diary
+ call DeleteSaveDataForNewGame
+ jr c, HandleTitleScreen
+ jr .card_pop
+.continue_from_diary
+ ld a, [wStartMenuChoice]
+ cp START_MENU_CONTINUE_FROM_DIARY
+ jr nz, .card_pop
+ call AskToContinueFromDiaryWithDuelData
+ jr c, HandleTitleScreen
+.card_pop
+ ld a, [wStartMenuChoice]
+ cp START_MENU_CARD_POP
+ jr nz, .continue_duel
+ call ShowCardPopCGBDisclaimer
+ jr c, HandleTitleScreen
+.continue_duel
+ call ResetDoFrameFunction
+ call Func_3ca0
+ ret
+
+; updates wHasSaveData and wHasDuelSaveData
+; depending on whether the save data is valid or not
+CheckIfHasSaveData:
+ farcall ValidateBackupGeneralSaveData
+ ld a, TRUE
+ jr c, .no_error
+ ld a, FALSE
+.no_error
+ ld [wHasSaveData], a
+ cp $00 ; or a
+ jr z, .write_has_duel_data
+ bank1call ValidateSavedNonLinkDuelData
+ ld a, TRUE
+ jr nc, .write_has_duel_data
+ ld a, FALSE
+.write_has_duel_data
+ ld [wHasDuelSaveData], a
+ farcall ValidateBackupGeneralSaveData
+ ret
+
+; handles printing the Start Menu
+; and getting player input and choice
+HandleStartMenu:
+ ld a, MUSIC_PC_MAIN_MENU
+ call PlaySong
+ call DisableLCD
+ farcall Func_10000
+ lb de, $30, $8f
+ call SetupText
+ call Func_3ca0
+ xor a
+ ld [wLineSeparation], a
+ call .DrawPlayerPortrait
+ call .SetStartMenuParams
+
+ ld a, $ff
+ ld [wTitleScreenIgnoreInputCounter], a
+ ld a, [wLastSelectedStartMenuItem]
+ cp $4
+ jr c, .init_menu
+ ld a, [wHasSaveData]
+ or a
+ jr z, .init_menu
+ ld a, 1 ; start at second menu option
+.init_menu
+ ld hl, wStartMenuParams
+ farcall InitAndPrintPauseMenu
+ farcall FlashWhiteScreen
+
+.wait_input
+ call DoFrameIfLCDEnabled
+ call UpdateRNGSources
+ call HandleMenuInput
+ push af
+ call PrintStartMenuDescriptionText
+ pop af
+ jr nc, .wait_input
+ ldh a, [hCurMenuItem]
+ cp e
+ jr nz, .wait_input
+
+ ld [wLastSelectedStartMenuItem], a
+ ld a, [wHasSaveData]
+ or a
+ jr nz, .no_adjustment
+ ; New Game is 3rd option
+ ; but when there's no save data,
+ ; it's the 1st in menu list, so adjust it
+ inc e
+ inc e
+.no_adjustment
+ ld a, e
+ ld [wStartMenuChoice], a
+ ret
+
+.SetStartMenuParams
+ ld hl, .StartMenuParams
+ ld de, wStartMenuParams
+ ld bc, .StartMenuParamsEnd - .StartMenuParams
+ call CopyDataHLtoDE
+
+ ld e, 0
+ ld a, [wHasSaveData]
+ or a
+ jr z, .get_text_id ; New Game
+ inc e
+ ld a, 2
+ call .AddItems
+ ld a, [wHasDuelSaveData]
+ or a
+ jr z, .get_text_id ; Continue From Diary
+ inc e
+ ld a, 1
+ call .AddItems
+ ; Continue Duel
+
+.get_text_id
+ sla e
+ ld d, $00
+ ld hl, .StartMenuTextIDs
+ add hl, de
+ ; set text ID as Start Menu param
+ ld a, [hli]
+ ld [wStartMenuParams + 6], a
+ ld a, [hl]
+ ld [wStartMenuParams + 7], a
+ ret
+
+; adds c items to start menu list
+; this means adding 2 units per item to the text box height
+; and adding to the number of items
+.AddItems
+ push bc
+ ld c, a
+ ; number of items in menu
+ ld a, [wStartMenuParams + 12]
+ add c
+ ld [wStartMenuParams + 12], a
+ ; height of text box
+ sla c
+ ld a, [wStartMenuParams + 3]
+ add c
+ ld [wStartMenuParams + 3], a
+ pop bc
+ ret
+
+.StartMenuParams
+ db 0, 0 ; start menu coords
+ db 14, 4 ; start menu text box dimensions
+
+ db 2, 2 ; text alignment for InitTextPrinting
+ tx NewGameText
+ db $ff
+
+ db 1, 2 ; cursor x, cursor y
+ db 2 ; y displacement between items
+ db 1 ; number of items
+ db SYM_CURSOR_R ; cursor tile number
+ db SYM_SPACE ; tile behind cursor
+ dw NULL ; function pointer if non-0
+.StartMenuParamsEnd
+
+.StartMenuTextIDs
+ tx NewGameText
+ tx CardPopContinueDiaryNewGameText
+ tx CardPopContinueDiaryNewGameContinueDuelText
+
+.DrawPlayerPortrait
+ lb bc, 14, 1
+ farcall $4, DrawPlayerPortrait
+ ret
+
+; prints the description for the current selected item
+; in the Start Menu in the text box
+PrintStartMenuDescriptionText:
+ push hl
+ push bc
+ push de
+ ; don't print if it's already showing
+ ld a, [wCurMenuItem]
+ ld e, a
+ ld a, [wCurHighlightedStartMenuItem]
+ cp e
+ jr z, .skip
+ ld a, [wHasSaveData]
+ or a
+ jr nz, .has_data
+ ; New Game option is 3rd element
+ ; in function table, so add 2
+ inc e
+ inc e
+.has_data
+
+ ld a, e
+ push af
+ lb de, 0, 10
+ lb bc, 20, 8
+ call DrawRegularTextBox
+ pop af
+ ld hl, .StartMenuDescriptionFunctionTable
+ call JumpToFunctionInTable
+.skip
+ ld a, [wCurMenuItem]
+ ld [wCurHighlightedStartMenuItem], a
+ pop de
+ pop bc
+ pop hl
+ ret
+
+.StartMenuDescriptionFunctionTable
+ dw .CardPop
+ dw .ContinueFromDiary
+ dw .NewGame
+ dw .ContinueDuel
+
+.CardPop
+ lb de, 1, 12
+ call InitTextPrinting
+ ldtx hl, WhenYouCardPopWithFriendText
+ call PrintTextNoDelay
+ ret
+
+.ContinueDuel
+ lb de, 1, 12
+ call InitTextPrinting
+ ldtx hl, TheGameWillContinueFromThePointInTheDuelText
+ call PrintTextNoDelay
+ ret
+
+.NewGame
+ lb de, 1, 12
+ call InitTextPrinting
+ ldtx hl, StartANewGameText
+ call PrintTextNoDelay
+ ret
+
+.ContinueFromDiary
+ ; get OW map name
+ ld a, [wCurOverworldMap]
+ add a
+ ld c, a
+ ld b, $00
+ ld hl, OverworldMapNames
+ add hl, bc
+ ld a, [hli]
+ ld [wTxRam2 + 0], a
+ ld a, [hl]
+ ld [wTxRam2 + 1], a
+
+ ; get medal count
+ ld a, [wMedalCount]
+ ld [wTxRam3 + 0], a
+ xor a
+ ld [wTxRam3 + 1], a
+
+ ; print text
+ lb de, 1, 10
+ call InitTextPrinting
+ ldtx hl, ContinueFromDiarySummaryText
+ call PrintTextNoDelay
+
+ ld a, [wTotalNumCardsCollected]
+ ld d, a
+ ld a, [wTotalNumCardsToCollect]
+ ld e, a
+ ld bc, $90e
+ farcall Func_1024f
+ ld bc, $a10
+ farcall Func_101df
+ ret
+
+; asks the player whether it's okay to delete
+; the save data in order to create a new one
+; if player answers "yes", delete it
+DeleteSaveDataForNewGame:
+; exit if there no save data
+ ld a, [wHasSaveData]
+ or a
+ ret z
+
+ call DisableLCD
+ farcall Func_10000
+ call Func_3ca0
+ farcall FlashWhiteScreen
+ call DoFrameIfLCDEnabled
+ ldtx hl, SavedDataAlreadyExistsText
+ call PrintScrollableText_NoTextBoxLabel
+ ldtx hl, OKToDeleteTheDataText
+ call YesOrNoMenuWithText
+ ret c ; quit if chose "no"
+ farcall InvalidateSaveData
+ ldtx hl, AllDataWasDeletedText
+ call PrintScrollableText_NoTextBoxLabel
+ or a
+ ret
+
+; asks the player if the game should resume
+; from diary even though there is Duel save data
+; returns carry if "no" was selected
+AskToContinueFromDiaryWithDuelData:
+; return if there's no duel save data
+ ld a, [wHasDuelSaveData]
+ or a
+ ret z
+
+ call DisableLCD
+ farcall Func_10000
+ call Func_3ca0
+ farcall FlashWhiteScreen
+ call DoFrameIfLCDEnabled
+ ldtx hl, DataExistsWhenPowerWasTurnedOFFDuringDuelText
+ call PrintScrollableText_NoTextBoxLabel
+ ldtx hl, ContinueFromDiaryText
+ call YesOrNoMenuWithText
+ ret c
+ or a
+ ret
+
+; shows disclaimer for Card Pop!
+; in case player is not playing in CGB
+; return carry if disclaimer was shown
+ShowCardPopCGBDisclaimer:
+; return if playing in CGB
+ ld a, [wConsole]
+ cp CONSOLE_CGB
+ ret z
+
+ lb de, 0, 10
+ lb bc, 20, 8
+ call DrawRegularTextBox
+ lb de, 1,12
+ call InitTextPrinting
+ ldtx hl, YouCanAccessCardPopOnlyWithGameBoyColorsText
+ call PrintTextNoDelay
+ lb bc, SYM_CURSOR_D, SYM_BOX_BOTTOM
+ lb de, 18, 17
+ call SetCursorParametersForTextBox
+ call WaitForButtonAorB
+ scf
+ ret
+
+DrawPlayerPortraitAndPrintNewGameText:
+ call DisableLCD
+ farcall Func_10a9b
+ farcall Func_10000
+ call Func_3ca0
+ ld hl, HandleAllSpriteAnimations
+ call SetDoFrameFunction
+ lb bc, 7, 3
+ farcall $4, DrawPlayerPortrait
+ farcall Func_10af9
+ call DoFrameIfLCDEnabled
+ ldtx hl, IsCrazyAboutPokemonAndPokemonCardCollectingText
+ call PrintScrollableText_NoTextBoxLabel
+ call ResetDoFrameFunction
+ call Func_3ca0
+ ret
diff --git a/src/engine/menus/unknown.asm b/src/engine/menus/unknown.asm
new file mode 100644
index 0000000..c6f04fa
--- /dev/null
+++ b/src/engine/menus/unknown.asm
@@ -0,0 +1,103 @@
+Func_18661: ; unreferenced
+ xor a
+ ld [wPlaysSfx], a
+ ld a, [wCheckMenuCursorXPosition]
+ ld d, a
+ ld a, [wCheckMenuCursorYPosition]
+ ld e, a
+ ldh a, [hDPadHeld]
+ or a
+ jr z, .check_button
+; check input from dpad
+ bit D_LEFT_F, a
+ jr nz, .left_or_right
+ bit D_RIGHT_F, a
+ jr z, .check_up_and_down
+.left_or_right
+; swap the lsb of x position value.
+ ld a, d
+ xor $1
+ ld d, a
+ jr .cursor_moved
+
+.check_up_and_down
+ bit D_UP_F, a
+ jr nz, .up_or_down
+ bit D_DOWN_F, a
+ jr z, .check_button
+.up_or_down
+ ld a, e
+ xor $1
+ ld e, a
+.cursor_moved
+ ld a, $1
+ ld [wPlaysSfx], a
+ push de
+ call .draw_blank_cursor
+ pop de
+ ld a, d
+ ld [wCheckMenuCursorXPosition], a
+ ld a, e
+ ld [wCheckMenuCursorYPosition], a
+ xor a
+ ld [wCheckMenuCursorBlinkCounter], a
+.check_button
+ ldh a, [hKeysPressed]
+ and A_BUTTON | B_BUTTON
+ jr z, .check_cursor_moved
+ and A_BUTTON
+ jr nz, .a_button
+
+; b button
+ ld a, -1
+ call Func_190fb
+ scf
+ ret
+
+; a button
+.a_button
+ call .draw_cursor
+ ld a, 1
+ call Func_190fb
+ scf
+ ret
+
+.check_cursor_moved
+ ld a, [wPlaysSfx]
+ or a
+ jr z, .check_cursor_blink
+ call PlaySFX
+.check_cursor_blink
+ ld hl, wCheckMenuCursorBlinkCounter
+ ld a, [hl]
+ inc [hl]
+ and %00001111
+ ret nz
+ ld a, SYM_CURSOR_R
+ bit D_RIGHT_F, [hl]
+ jr z, .draw_tile
+.draw_blank_cursor ; 186d4 (6:46d4)
+ ld a, SYM_SPACE
+.draw_tile
+ 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
+ ; b = 11, c = y_pos * 2 + 14
+ ; h = x_pos * 10, l = 10
+ call WriteByteToBGMap0
+ or a
+ ret
+.draw_cursor ; 186f3 (6:46f3)
+ ld a, SYM_CURSOR_R
+ jr .draw_tile
diff --git a/src/engine/overworld/scripting.asm b/src/engine/overworld/scripting.asm
index 0010a77..79cfaa3 100644
--- a/src/engine/overworld/scripting.asm
+++ b/src/engine/overworld/scripting.asm
@@ -1819,7 +1819,7 @@ ScriptCommand_nop:
ScriptCommand_GiveStarterDeck:
ld a, [wStarterDeckChoice]
- bank1call Func_7576
+ bank1call AddStarterDeck
jp IncreaseScriptPointerBy1
Unknown_d3dd:
diff --git a/src/engine/promotional_card.asm b/src/engine/promotional_card.asm
new file mode 100644
index 0000000..bb3250a
--- /dev/null
+++ b/src/engine/promotional_card.asm
@@ -0,0 +1,61 @@
+; shows screen with the promotional card and received text
+; depending on input a
+; if $0 = Legendary Molters, Articuno, Zapdos and Dragonite cards
+; otherwise, a card ID
+_ShowPromotionalCardScreen:
+ push af
+ lb de, $38, $9f
+ call SetupText
+ pop af
+ or a
+ jr nz, .else
+ ld a, MOLTRES2
+ call .legendary_card_text
+ ld a, ARTICUNO2
+ call .legendary_card_text
+ ld a, ZAPDOS3
+ call .legendary_card_text
+ ld a, DRAGONITE1
+.legendary_card_text
+ ldtx hl, ReceivedLegendaryCardText
+ jr .print_text
+.else
+ ldtx hl, ReceivedCardText
+ cp VILEPLUME
+ jr z, .print_text
+ cp BLASTOISE
+ jr z, .print_text
+ ldtx hl, ReceivedPromotionalFlyingPikachuText
+ cp FLYING_PIKACHU
+ jr z, .print_text
+ ldtx hl, ReceivedPromotionalSurfingPikachuText
+ cp SURFING_PIKACHU1
+ jr z, .print_text
+ cp SURFING_PIKACHU2
+ jr z, .print_text
+ ldtx hl, ReceivedPromotionalCardText
+.print_text
+ push hl
+ ld e, a
+ ld d, $0
+ call LoadCardDataToBuffer1_FromCardID
+ call PauseSong
+ ld a, MUSIC_MEDAL
+ call PlaySong
+ ld hl, wLoadedCard1Name
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ bank1call LoadTxRam2 ; switch to bank 1, but call a home func
+ ld a, PLAYER_TURN
+ ldh [hWhoseTurn], a
+ pop hl
+ bank1call _DisplayCardDetailScreen
+.loop
+ call AssertSongFinished
+ or a
+ jr nz, .loop
+
+ call ResumeSong
+ bank1call OpenCardPage_FromHand
+ ret
diff --git a/src/engine/sequences/credits_sequence_commands.asm b/src/engine/sequences/credits_sequence_commands.asm
index 0fde871..d80df8b 100644
--- a/src/engine/sequences/credits_sequence_commands.asm
+++ b/src/engine/sequences/credits_sequence_commands.asm
@@ -300,7 +300,7 @@ CreditsSequenceCmd_DisableLCD: ; 1d9db (7:59db)
CreditsSequenceCmd_FadeIn: ; 1d9e1 (7:59e1)
call DisableLCD
- call Set_WD_on
+ call SetWindowOn
farcall Func_10af9
jp AdvanceCreditsSequenceCmdPtrBy2
@@ -310,7 +310,7 @@ CreditsSequenceCmd_FadeOut: ; 1d9ee (7:59ee)
call EnableLCD
call DoFrameIfLCDEnabled
call DisableLCD
- call Set_WD_off
+ call SetWindowOff
jp AdvanceCreditsSequenceCmdPtrBy2
CreditsSequenceCmd_DrawRectangle: ; 1da04 (7:5a04)
diff --git a/src/engine/sequences/opening_sequence_commands.asm b/src/engine/sequences/intro_sequence_commands.asm
index 446daa2..028027b 100644
--- a/src/engine/sequences/opening_sequence_commands.asm
+++ b/src/engine/sequences/intro_sequence_commands.asm
@@ -1,4 +1,4 @@
-ExecuteOpeningSequenceCmd: ; 1d408 (7:5408)
+ExecuteIntroSequenceCmd: ; 1d408 (7:5408)
ld a, [wSequenceDelay]
or a
jr z, .call_function
@@ -25,22 +25,22 @@ ExecuteOpeningSequenceCmd: ; 1d408 (7:5408)
ld l, e
ld h, d
call CallHL2
- jr c, ExecuteOpeningSequenceCmd
+ jr c, ExecuteIntroSequenceCmd
ret
-AdvanceOpeningSequenceCmdPtrBy2: ; 1d42e (7:542e)
+AdvanceIntroSequenceCmdPtrBy2: ; 1d42e (7:542e)
ld a, 2
- jr AdvanceOpeningSequenceCmdPtr
+ jr AdvanceIntroSequenceCmdPtr
-AdvanceOpeningSequenceCmdPtrBy3: ; 1d432 (7:5432)
+AdvanceIntroSequenceCmdPtrBy3: ; 1d432 (7:5432)
ld a, 3
- jr AdvanceOpeningSequenceCmdPtr
+ jr AdvanceIntroSequenceCmdPtr
-AdvanceOpeningSequenceCmdPtrBy4: ; 1d436 (7:5436)
+AdvanceIntroSequenceCmdPtrBy4: ; 1d436 (7:5436)
ld a, 4
; fallthrough
-AdvanceOpeningSequenceCmdPtr: ; 1d438 (7:5438)
+AdvanceIntroSequenceCmdPtr: ; 1d438 (7:5438)
push hl
ld hl, wSequenceCmdPtr
add [hl]
@@ -51,7 +51,7 @@ AdvanceOpeningSequenceCmdPtr: ; 1d438 (7:5438)
pop hl
ret
-OpeningSequenceCmd_WaitOrbsAnimation: ; 1d444 (7:5444)
+IntroSequenceCmd_WaitOrbsAnimation: ; 1d444 (7:5444)
ld c, $7
ld de, wTitleScreenSprites
.loop
@@ -63,7 +63,7 @@ OpeningSequenceCmd_WaitOrbsAnimation: ; 1d444 (7:5444)
inc de
dec c
jr nz, .loop
- call AdvanceOpeningSequenceCmdPtrBy2
+ call AdvanceIntroSequenceCmdPtrBy2
scf
ret
@@ -71,14 +71,14 @@ OpeningSequenceCmd_WaitOrbsAnimation: ; 1d444 (7:5444)
or a
ret
-OpeningSequenceCmd_Wait: ; 1d460 (7:5460)
+IntroSequenceCmd_Wait: ; 1d460 (7:5460)
ld a, c
ld [wSequenceDelay], a
- call AdvanceOpeningSequenceCmdPtrBy3
+ call AdvanceIntroSequenceCmdPtrBy3
scf
ret
-OpeningSequenceCmd_SetOrbsAnimations: ; 1d469 (7:5469)
+IntroSequenceCmd_SetOrbsAnimations: ; 1d469 (7:5469)
ld l, c
ld h, b
@@ -97,11 +97,11 @@ OpeningSequenceCmd_SetOrbsAnimations: ; 1d469 (7:5469)
dec c
jr nz, .loop
- call AdvanceOpeningSequenceCmdPtrBy4
+ call AdvanceIntroSequenceCmdPtrBy4
scf
ret
-OpeningSequenceCmd_SetOrbsCoordinates: ; 1d486 (7:5486)
+IntroSequenceCmd_SetOrbsCoordinates: ; 1d486 (7:5486)
ld l, c
ld h, b
@@ -131,11 +131,11 @@ OpeningSequenceCmd_SetOrbsCoordinates: ; 1d486 (7:5486)
dec c
jr nz, .loop
- call AdvanceOpeningSequenceCmdPtrBy4
+ call AdvanceIntroSequenceCmdPtrBy4
scf
ret
-OpeningOrbAnimations_CharizardScene: ; 1d4b0 (7:54b0)
+IntroOrbAnimations_CharizardScene: ; 1d4b0 (7:54b0)
db SPRITE_ANIM_192 ; GRASS
db SPRITE_ANIM_193 ; FIRE
db SPRITE_ANIM_193 ; WATER
@@ -144,7 +144,7 @@ OpeningOrbAnimations_CharizardScene: ; 1d4b0 (7:54b0)
db SPRITE_ANIM_192 ; PSYCHIC
db SPRITE_ANIM_193 ; FIGHTING
-OpeningOrbCoordinates_CharizardScene: ; 1d4b7 (7:54b7)
+IntroOrbCoordinates_CharizardScene: ; 1d4b7 (7:54b7)
; x coord, y coord
db 240, 28 ; GRASS
db 160, 120 ; FIRE
@@ -154,7 +154,7 @@ OpeningOrbCoordinates_CharizardScene: ; 1d4b7 (7:54b7)
db 240, 100 ; PSYCHIC
db 160, 44 ; FIGHTING
-OpeningOrbAnimations_ScytherScene: ; 1d4c5 (7:54c5)
+IntroOrbAnimations_ScytherScene: ; 1d4c5 (7:54c5)
db SPRITE_ANIM_193 ; GRASS
db SPRITE_ANIM_192 ; FIRE
db SPRITE_ANIM_192 ; WATER
@@ -163,7 +163,7 @@ OpeningOrbAnimations_ScytherScene: ; 1d4c5 (7:54c5)
db SPRITE_ANIM_193 ; PSYCHIC
db SPRITE_ANIM_192 ; FIGHTING
-OpeningOrbCoordinates_ScytherScene: ; 1d4cc (7:54cc)
+IntroOrbCoordinates_ScytherScene: ; 1d4cc (7:54cc)
; x coord, y coord
db 160, 28 ; GRASS
db 240, 120 ; FIRE
@@ -173,7 +173,7 @@ OpeningOrbCoordinates_ScytherScene: ; 1d4cc (7:54cc)
db 160, 100 ; PSYCHIC
db 240, 44 ; FIGHTING
-OpeningOrbAnimations_AerodactylScene: ; 1d4da (7:54da)
+IntroOrbAnimations_AerodactylScene: ; 1d4da (7:54da)
db SPRITE_ANIM_194 ; GRASS
db SPRITE_ANIM_197 ; FIRE
db SPRITE_ANIM_200 ; WATER
@@ -182,7 +182,7 @@ OpeningOrbAnimations_AerodactylScene: ; 1d4da (7:54da)
db SPRITE_ANIM_209 ; PSYCHIC
db SPRITE_ANIM_212 ; FIGHTING
-OpeningOrbCoordinates_AerodactylScene: ; 1d4e1 (7:54e1)
+IntroOrbCoordinates_AerodactylScene: ; 1d4e1 (7:54e1)
; x coord, y coord
db 240, 32 ; GRASS
db 160, 112 ; FIRE
@@ -192,7 +192,7 @@ OpeningOrbCoordinates_AerodactylScene: ; 1d4e1 (7:54e1)
db 240, 96 ; PSYCHIC
db 160, 48 ; FIGHTING
-OpeningOrbAnimations_InitialTitleScreen: ; 1d4ef (7:54ef)
+IntroOrbAnimations_InitialTitleScreen: ; 1d4ef (7:54ef)
db SPRITE_ANIM_195 ; GRASS
db SPRITE_ANIM_198 ; FIRE
db SPRITE_ANIM_201 ; WATER
@@ -201,7 +201,7 @@ OpeningOrbAnimations_InitialTitleScreen: ; 1d4ef (7:54ef)
db SPRITE_ANIM_210 ; PSYCHIC
db SPRITE_ANIM_213 ; FIGHTING
-OpeningOrbCoordinates_InitialTitleScreen: ; 1d4f6 (7:54f6)
+IntroOrbCoordinates_InitialTitleScreen: ; 1d4f6 (7:54f6)
; x coord, y coord
db 112, 144 ; GRASS
db 12, 144 ; FIRE
@@ -211,7 +211,7 @@ OpeningOrbCoordinates_InitialTitleScreen: ; 1d4f6 (7:54f6)
db 132, 144 ; PSYCHIC
db 72, 144 ; FIGHTING
-OpeningOrbAnimations_InTitleScreen: ; 1d504 (7:5504)
+IntroOrbAnimations_InTitleScreen: ; 1d504 (7:5504)
db SPRITE_ANIM_196 ; GRASS
db SPRITE_ANIM_199 ; FIRE
db SPRITE_ANIM_202 ; WATER
@@ -220,7 +220,7 @@ OpeningOrbAnimations_InTitleScreen: ; 1d504 (7:5504)
db SPRITE_ANIM_211 ; PSYCHIC
db SPRITE_ANIM_214 ; FIGHTING
-OpeningOrbCoordinates_InTitleScreen: ; 1d50b (7:550b)
+IntroOrbCoordinates_InTitleScreen: ; 1d50b (7:550b)
; x coord, y coord
db 112, 76 ; GRASS
db 0, 28 ; FIRE
@@ -230,18 +230,18 @@ OpeningOrbCoordinates_InTitleScreen: ; 1d50b (7:550b)
db 144, 28 ; PSYCHIC
db 72, 76 ; FIGHTING
-OpeningSequenceCmd_PlayTitleScreenMusic: ; 1d519 (7:5519)
+IntroSequenceCmd_PlayTitleScreenMusic: ; 1d519 (7:5519)
ld a, MUSIC_TITLESCREEN
call PlaySong
- call AdvanceOpeningSequenceCmdPtrBy2
+ call AdvanceIntroSequenceCmdPtrBy2
scf
ret
-OpeningSequenceCmd_WaitSFX: ; 1d523 (7:5523)
+IntroSequenceCmd_WaitSFX: ; 1d523 (7:5523)
call AssertSFXFinished
or a
jr nz, .no_carry
- call AdvanceOpeningSequenceCmdPtrBy2
+ call AdvanceIntroSequenceCmdPtrBy2
scf
ret
@@ -249,39 +249,39 @@ OpeningSequenceCmd_WaitSFX: ; 1d523 (7:5523)
or a
ret
-OpeningSequenceCmd_PlaySFX: ; 1d530 (7:5530)
+IntroSequenceCmd_PlaySFX: ; 1d530 (7:5530)
ld a, c
call PlaySFX
- call AdvanceOpeningSequenceCmdPtrBy3
+ call AdvanceIntroSequenceCmdPtrBy3
scf
ret
-OpeningSequenceCmd_FadeIn: ; 1d539 (7:5539)
+IntroSequenceCmd_FadeIn: ; 1d539 (7:5539)
ld a, TRUE
- ld [wOpeningSequencePalsNeedUpdate], a
- call AdvanceOpeningSequenceCmdPtrBy2
+ ld [wIntroSequencePalsNeedUpdate], a
+ call AdvanceIntroSequenceCmdPtrBy2
scf
ret
-OpeningSequenceCmd_FadeOut: ; 1d543 (7:5543)
+IntroSequenceCmd_FadeOut: ; 1d543 (7:5543)
farcall Func_10d50
ld a, TRUE
- ld [wOpeningSequencePalsNeedUpdate], a
- call AdvanceOpeningSequenceCmdPtrBy2
+ ld [wIntroSequencePalsNeedUpdate], a
+ call AdvanceIntroSequenceCmdPtrBy2
scf
ret
-OpeningSequenceCmd_LoadCharizardScene: ; 1d551 (7:5551)
+IntroSequenceCmd_LoadCharizardScene: ; 1d551 (7:5551)
lb bc, 6, 3
ld a, SCENE_CHARIZARD_INTRO
jr LoadOpeningSceneAndUpdateSGBBorder
-OpeningSequenceCmd_LoadScytherScene: ; 1d558 (7:5558)
+IntroSequenceCmd_LoadScytherScene: ; 1d558 (7:5558)
lb bc, 6, 3
ld a, SCENE_SCYTHER_INTRO
jr LoadOpeningSceneAndUpdateSGBBorder
-OpeningSequenceCmd_LoadAerodactylScene: ; 1d55f (7:555f)
+IntroSequenceCmd_LoadAerodactylScene: ; 1d55f (7:555f)
lb bc, 6, 3
ld a, SCENE_AERODACTYL_INTRO
; fallthrough
@@ -295,11 +295,11 @@ LoadOpeningSceneAndUpdateSGBBorder: ; 1d564 (7:5564)
scf
ret
-OpeningSequenceCmd_LoadTitleScreenScene: ; 1d575 (7:5575)
+IntroSequenceCmd_LoadTitleScreenScene: ; 1d575 (7:5575)
lb bc, 0, 0
ld a, SCENE_TITLE_SCREEN
call LoadOpeningScene
- call OpeningSequenceEmptyFunc
+ call IntroSequenceEmptyFunc
scf
ret
@@ -316,10 +316,77 @@ LoadOpeningScene: ; 1d582 (7:5582)
farcall Func_10d17
xor a
- ld [wOpeningSequencePalsNeedUpdate], a
- call AdvanceOpeningSequenceCmdPtrBy2
+ ld [wIntroSequencePalsNeedUpdate], a
+ call AdvanceIntroSequenceCmdPtrBy2
call EnableLCD
ret
-OpeningSequenceEmptyFunc: ; 1d59c (7:559c)
+IntroSequenceEmptyFunc: ; 1d59c (7:559c)
+ ret
+
+INCLUDE "data/sequences/intro.asm"
+
+; once every 63 frames randomly choose an orb sprite
+; to animate, i.e. circle around the screen
+AnimateRandomTitleScreenOrb:
+ ld a, [wConsole]
+ cp CONSOLE_CGB
+ call z, .UpdateSpriteAttributes
+ ld a, [wd635]
+ and 63
+ ret nz ; don't pick an orb now
+
+.pick_orb
+ ld a, $7
+ call Random
+ ld c, a
+ ld b, $00
+ ld hl, wTitleScreenSprites
+ add hl, bc
+ ld a, [hl]
+ ld [wWhichSprite], a
+ farcall GetSpriteAnimCounter
+ cp $ff
+ jr nz, .pick_orb
+
+ ld c, SPRITE_ANIM_ATTRIBUTES
+ call GetSpriteAnimBufferProperty
+ ld a, [wConsole]
+ cp CONSOLE_CGB
+ jr nz, .set_coords
+ set SPRITE_ANIM_FLAG_UNSKIPPABLE, [hl]
+
+.set_coords
+ inc hl
+ ld a, 248
+ ld [hli], a ; SPRITE_ANIM_COORD_X
+ ld a, 14
+ ld [hl], a ; SPRITE_ANIM_COORD_Y
+ ld a, [wConsole]
+ cp CONSOLE_CGB
+ ld a, SPRITE_ANIM_215
+ jr nz, .start_anim
+ ld a, SPRITE_ANIM_216
+.start_anim
+ farcall StartSpriteAnimation
+ ret
+
+.UpdateSpriteAttributes
+ ld c, $7
+ ld de, wTitleScreenSprites
+.loop_orbs
+ push bc
+ ld a, [de]
+ ld [wWhichSprite], a
+ ld c, SPRITE_ANIM_COORD_X
+ call GetSpriteAnimBufferProperty
+ ld a, [hld]
+ cp 152
+ jr nz, .skip
+ res SPRITE_ANIM_FLAG_UNSKIPPABLE, [hl]
+.skip
+ pop bc
+ inc de
+ dec c
+ jr nz, .loop_orbs
ret
diff --git a/src/engine/bank1c.asm b/src/engine/sgb.asm
index d32928a..288dc45 100644
--- a/src/engine/bank1c.asm
+++ b/src/engine/sgb.asm
@@ -1,4 +1,4 @@
-SetMainSGBBorder: ; 70000 (1c:4000)
+SetMainSGBBorder:
ld a, [wConsole]
cp CONSOLE_SGB
ret nz ; exit if not SGB
@@ -13,7 +13,7 @@ SetMainSGBBorder: ; 70000 (1c:4000)
call SetSGBBorder
ret
-SetIntroSGBBorder: ; 70018 (1c:4018)
+SetIntroSGBBorder:
ld a, [wConsole]
cp CONSOLE_SGB
ret nz ; exit if not SGB
@@ -21,13 +21,13 @@ SetIntroSGBBorder: ; 70018 (1c:4018)
call SetSGBBorder
ret
-AtrcEnPacket_Disable: ; 70024 (1c:4024)
+AtrcEnPacket_Disable:
sgb ATRC_EN, 1 ; sgb_command, length
db 1
ds $0e
; disable Controller Set-up Screen
-IconEnPacket: ; 70034 (1c:4034)
+IconEnPacket:
sgb ICON_EN, 3 ; sgb_command, length
db $01
ds $0e
@@ -37,7 +37,7 @@ IconEnPacket: ; 70034 (1c:4034)
; $1 = medals (gold)
; $2 = medals (blue)
; $3 = debug
-SetSGBBorder: ; 70044 (1c:4044)
+SetSGBBorder:
push hl
push bc
add a ; *2
@@ -62,7 +62,7 @@ SetSGBBorder: ; 70044 (1c:4044)
; forces SGB border intro
; unreferenced?
-Func_7006f: ; 7006f (1c:406f)
+Func_7006f:
ld a, [wConsole]
cp CONSOLE_SGB
ret nz ; exit if not SGB
@@ -72,7 +72,7 @@ Func_7006f: ; 7006f (1c:406f)
call Func_701c0
ret
-DecompressAndSendSGBBorder: ; 70082 (1c:4082)
+DecompressAndSendSGBBorder:
ld a, [wConsole]
cp CONSOLE_SGB
ret nz ; exit if not SGB
@@ -99,7 +99,7 @@ DecompressAndSendSGBBorder: ; 70082 (1c:4082)
pop hl
ret
-Func_700a3: ; 700a3 (1c:40a3)
+Func_700a3:
push hl
push bc
push de
@@ -139,20 +139,20 @@ Func_700a3: ; 700a3 (1c:40a3)
ret
; CHR_TRN: tiles $00-$7F, BG (border) tiles (from SNES $000-$FFF)
-ChrTrnPacket_BGTiles1: ; 700de (1c:40de)
+ChrTrnPacket_BGTiles1:
sgb CHR_TRN, 1 ; sgb_command, length
db 0
ds $0e
; CHR_TRN: tiles $80-$FF, BG (border) tiles (from SNES $000-$FFF)
-ChrTrnPacket_BGTiles2: ; 700ee (1c:40ee)
+ChrTrnPacket_BGTiles2:
sgb CHR_TRN, 1 ; sgb_command, length
db 1
ds $0e
; de = pals
; hl = map
-SetMainSGBBorderPalsAndMap: ; 700fe (1c:40fe)
+SetMainSGBBorderPalsAndMap:
push hl
push bc
push de
@@ -179,11 +179,11 @@ SetMainSGBBorderPalsAndMap: ; 700fe (1c:40fe)
ret
; PCT_TRN: read tile map & palette data into VRAM (from SNES $000-$87F)
-PctTrnPacket: ; 70126 (1c:4126)
+PctTrnPacket:
sgb PCT_TRN, 1 ; sgb_command, length
ds $0f
-Func_70136: ; 70136 (1c:4136)
+Func_70136:
push hl
push bc
push de
@@ -218,7 +218,7 @@ Func_70136: ; 70136 (1c:4136)
pop hl
ret
-SendSGBBorder: ; 70177 (1c:4177)
+SendSGBBorder:
push hl
push bc
push de
@@ -242,18 +242,18 @@ SendSGBBorder: ; 70177 (1c:4177)
ret
; MASK_EN on
-MaskEnPacket_Freeze_Bank1c: ; 701a0 (1c:41a0)
+MaskEnPacket_Freeze_Bank1c:
sgb MASK_EN, 1 ; sgb_command, length
db MASK_EN_FREEZE_SCREEN
ds $0e
; MASK_EN off
-MaskEnPacket_Cancel_Bank1c: ; 701b0 (1c:41b0)
+MaskEnPacket_Cancel_Bank1c:
sgb MASK_EN, 1 ; sgb_command, length
db MASK_EN_CANCEL_MASK
ds $0e
-Func_701c0: ; 701c0 (1c:41c0)
+Func_701c0:
push hl
push bc
call DisableLCD
@@ -280,7 +280,7 @@ Func_701c0: ; 701c0 (1c:41c0)
ret
; decompresses data pointed by hl to de
-DecompressSGBData: ; 701e9 (1c:41e9)
+DecompressSGBData:
ld a, [hli]
ld c, a
ld a, [hli]
@@ -300,7 +300,7 @@ DecompressSGBData: ; 701e9 (1c:41e9)
; fills a 20x13 rectangle in v0BGMap0
; with values ascending bytes starting at $80
-PrepareBGMapForSendingSGBBorder: ; 701fe (1c:41fe)
+PrepareBGMapForSendingSGBBorder:
ld hl, v0BGMap0
ld de, $000c
ld a, $80
@@ -319,7 +319,7 @@ PrepareBGMapForSendingSGBBorder: ; 701fe (1c:41fe)
; iterates all the medals obtained by the player
; and fills the corresponding medal slot in the SGB border
-FillSGBBorderMedalSlots: ; 70214 (1c:4214)
+FillSGBBorderMedalSlots:
; exit if not SGBData_BorderMedals5
ld a, l
cp LOW(SGBData_BorderMedals5)
@@ -463,7 +463,7 @@ ENDM
; decompresses palette data depending on wCurMapSGBPals
; then sends it as SGB packet
-SetSGB2AndSGB3MapPalette: ; 7036a (1c:436a)
+SetSGB2AndSGB3MapPalette:
ld a, [wConsole]
cp CONSOLE_SGB
ret nz ; return if not SGB
@@ -520,7 +520,7 @@ SetSGB2AndSGB3MapPalette: ; 7036a (1c:436a)
dw SGBData_MapPals9 ; MAP_SGB_PALS_9
dw SGBData_MapPals10 ; MAP_SGB_PALS_10
-Func_703cb: ; 703cb (1c:43cb)
+Func_703cb:
ld a, [wConsole]
cp CONSOLE_SGB
ret nz
@@ -548,7 +548,7 @@ Func_703cb: ; 703cb (1c:43cb)
pop hl
ret
-DecompressSGBPalette: ; 70403 (1c:4403)
+DecompressSGBPalette:
push hl
push bc
push de
@@ -570,7 +570,7 @@ DecompressSGBPalette: ; 70403 (1c:4403)
ret
; sends an SGB packet related with palettes
-Func_7041d: ; 7041d (1c:441d)
+Func_7041d:
ld a, [wConsole]
cp CONSOLE_SGB
ret nz ; exit if not SGB
@@ -653,7 +653,7 @@ Func_7041d: ; 7041d (1c:441d)
; d = block width
; e = block height
; l = %00xxyyzz, palette number for: outside block, block border, inside block
-Func_70498: ; 70498 (1c:4498)
+Func_70498:
ld a, [wConsole]
cp CONSOLE_SGB
ret nz
@@ -693,7 +693,7 @@ Func_70498: ; 70498 (1c:4498)
; set color 0 to default white rgb(28, 28, 24)
; input:
; hl = pointer to start of SGB packet
-Func_704c7: ; 704c7 (1c:44c7)
+Func_704c7:
push af
push hl
inc hl
@@ -705,318 +705,318 @@ Func_704c7: ; 704c7 (1c:44c7)
pop af
ret
-SGBData_BorderDebug4: ; 704d3 (1c:44d3)
+SGBData_BorderDebug4:
dw $800 ; length
INCBIN "data/sgb_data/border_debug_4.bin"
-SGBData_BorderIntro4: ; 706dd (1c:46dd)
+SGBData_BorderIntro4:
dw $800 ; length
INCBIN "data/sgb_data/border_intro_4.bin"
-SGBData_BorderMedals5: ; 709dc (1c:49dc)
+SGBData_BorderMedals5:
dw $800 ; length
INCBIN "data/sgb_data/border_medals_5.bin"
-SGBBorderDebugGfxPointers: ; 70b96 (1c:4b96)
+SGBBorderDebugGfxPointers:
dw SGBData_BorderDebug1
dw SGBData_BorderDebug2
-SGBData_BorderDebug1: ; 70b9a (1c:45b9a)
+SGBData_BorderDebug1:
dw $1000 ; length
INCBIN "data/sgb_data/border_debug_1.bin"
-SGBData_BorderDebug2: ; 71359 (1c:5359)
+SGBData_BorderDebug2:
dw $a0 ; length
INCBIN "data/sgb_data/border_debug_2.bin"
-SGBBorderIntroGfxPointers: ; 713a9 (1c:53a9)
+SGBBorderIntroGfxPointers:
dw SGBData_BorderIntro1
dw SGBData_BorderIntro2
-SGBData_BorderIntro1: ; 713ad (1c:53ad)
+SGBData_BorderIntro1:
dw $1000 ; length
INCBIN "data/sgb_data/border_intro_1.bin"
-SGBData_BorderIntro2: ; 71ec0 (1c:5ec0)
+SGBData_BorderIntro2:
dw $4e0 ; length
INCBIN "data/sgb_data/border_intro_2.bin"
-SGBBorderMedalsGfxPointers: ; 72273 (1c:6273)
+SGBBorderMedalsGfxPointers:
dw SGBData_BorderMedals1
dw SGBData_BorderMedals2
-SGBData_BorderMedals1: ; 72277 (1c:5277)
+SGBData_BorderMedals1:
dw $1000 ; length
INCBIN "data/sgb_data/border_medals_1.bin"
-SGBData_BorderMedals2: ; 72fe4 (1c:5fe4)
+SGBData_BorderMedals2:
dw $100 ; length
INCBIN "data/sgb_data/border_medals_2.bin"
-SGBData_BorderDebug3: ; 730de (1c:70de)
+SGBData_BorderDebug3:
dw $60 ; length
INCBIN "data/sgb_data/border_debug_3.bin"
-SGBData_BorderIntro3: ; 73146 (1c:7146)
+SGBData_BorderIntro3:
dw $60 ; length
INCBIN "data/sgb_data/border_intro_3.bin"
-SGBData_BorderMedals3: ; 7319a (1c:719a)
+SGBData_BorderMedals3:
dw $60 ; length
INCBIN "data/sgb_data/border_medals_3.bin"
-SGBData_BorderMedals4: ; 731e5 (1c:71e5)
+SGBData_BorderMedals4:
dw $60 ; length
INCBIN "data/sgb_data/border_medals_4.bin"
-SGBData_MapPals1: ; 7322f (1c:722f)
+SGBData_MapPals1:
dw $20 ; length
INCBIN "data/sgb_data/map_pals_1.bin"
-SGBData_MapPals2: ; 73253 (1c:7253)
+SGBData_MapPals2:
dw $20 ; length
INCBIN "data/sgb_data/map_pals_2.bin"
-SGBData_MapPals3: ; 73277 (1c:7277)
+SGBData_MapPals3:
dw $20 ; length
INCBIN "data/sgb_data/map_pals_3.bin"
-SGBData_MapPals4: ; 7329a (1c:729a)
+SGBData_MapPals4:
dw $20 ; length
INCBIN "data/sgb_data/map_pals_4.bin"
-SGBData_MapPals5: ; 732bd (1c:72bd)
+SGBData_MapPals5:
dw $20 ; length
INCBIN "data/sgb_data/map_pals_5.bin"
-SGBData_MapPals6: ; 732e0 (1c:72e0)
+SGBData_MapPals6:
dw $20 ; length
INCBIN "data/sgb_data/map_pals_6.bin"
-SGBData_MapPals7: ; 73304 (1c:7304)
+SGBData_MapPals7:
dw $20 ; length
INCBIN "data/sgb_data/map_pals_7.bin"
-SGBData_MapPals8: ; 73328 (1c:7328)
+SGBData_MapPals8:
dw $20 ; length
INCBIN "data/sgb_data/map_pals_8.bin"
-SGBData_MapPals9: ; 7334b (1c:734b)
+SGBData_MapPals9:
dw $20 ; length
INCBIN "data/sgb_data/map_pals_9.bin"
-SGBData_MapPals10: ; 7336f (1c:736f)
+SGBData_MapPals10:
dw $20 ; length
INCBIN "data/sgb_data/map_pals_10.bin"
-SGBData_CharizardIntro: ; 73393 (1c:7393)
+SGBData_CharizardIntro:
dw $20 ; length
INCBIN "data/sgb_data/charizard_intro_pals.bin"
-SGBData_ScytherIntro: ; 733b8 (1c:73b8)
+SGBData_ScytherIntro:
dw $20 ; length
INCBIN "data/sgb_data/scyther_intro_pals.bin"
-SGBData_AerodactylIntro: ; 733dd (1c:73dd)
+SGBData_AerodactylIntro:
dw $20 ; length
INCBIN "data/sgb_data/aerodactyl_intro_pals.bin"
-SGBData_ColosseumBooster: ; 73402 (1c:7402)
+SGBData_ColosseumBooster:
dw $20 ; length
INCBIN "data/sgb_data/colosseum_booster_pals.bin"
-SGBData_EvolutionBooster: ; 73427 (1c:7427)
+SGBData_EvolutionBooster:
dw $20 ; length
INCBIN "data/sgb_data/evolution_booster_pals.bin"
-SGBData_MysteryBooster: ; 7344c (1c:744c)
+SGBData_MysteryBooster:
dw $20 ; length
INCBIN "data/sgb_data/mystery_booster_pals.bin"
-SGBData_LaboratoryBooster: ; 73471 (1c:7471)
+SGBData_LaboratoryBooster:
dw $20 ; length
INCBIN "data/sgb_data/laboratory_booster_pals.bin"
-SGBData_PlayerPortraitPals: ; 73496 (1c:7496)
+SGBData_PlayerPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/player_pals.bin"
-SGBData_LinkOpponentPortraitPals: ; 734bb (1c:74bb)
+SGBData_LinkOpponentPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/link_opponent_pals.bin"
-SGBData_RonaldPortraitPals: ; 734e0 (1c:74e0)
+SGBData_RonaldPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/ronald_pals.bin"
-SGBData_SamPortraitPals: ; 73505 (1c:7505)
+SGBData_SamPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/sam_pals.bin"
-SGBData_ImakuniPortraitPals: ; 7352a (1c:752a)
+SGBData_ImakuniPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/imakuni_pals.bin"
-SGBData_NikkiPortraitPals: ; 7354f (1c:754f)
+SGBData_NikkiPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/nikki_pals.bin"
-SGBData_RickPortraitPals: ; 73574 (1c:7574)
+SGBData_RickPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/rick_pals.bin"
-SGBData_KenPortraitPals: ; 73599 (1c:7599)
+SGBData_KenPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/ken_pals.bin"
-SGBData_AmyPortraitPals: ; 735be (1c:75be)
+SGBData_AmyPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/amy_pals.bin"
-SGBData_IsaacPortraitPals: ; 735e3 (1c:75e3)
+SGBData_IsaacPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/isaac_pals.bin"
-SGBData_MitchPortraitPals: ; 73608 (1c:7608)
+SGBData_MitchPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/mitch_pals.bin"
-SGBData_GenePortraitPals: ; 7362d (1c:762d)
+SGBData_GenePortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/gene_pals.bin"
-SGBData_MurrayPortraitPals: ; 73652 (1c:7652)
+SGBData_MurrayPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/murray_pals.bin"
-SGBData_CourtneyPortraitPals: ; 73677 (1c:7677)
+SGBData_CourtneyPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/courtney_pals.bin"
-SGBData_StevePortraitPals: ; 7369c (1c:769c)
+SGBData_StevePortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/steve_pals.bin"
-SGBData_JackPortraitPals: ; 736c1 (1c:76c1)
+SGBData_JackPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/jack_pals.bin"
-SGBData_RodPortraitPals: ; 736e6 (1c:76e6)
+SGBData_RodPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/rod_pals.bin"
-SGBData_JosephPortraitPals: ; 7370b (1c:770b)
+SGBData_JosephPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/joseph_pals.bin"
-SGBData_DavidPortraitPals: ; 73730 (1c:7730)
+SGBData_DavidPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/david_pals.bin"
-SGBData_ErikPortraitPals: ; 73755 (1c:7755)
+SGBData_ErikPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/erik_pals.bin"
-SGBData_JohnPortraitPals: ; 7377a (1c:777a)
+SGBData_JohnPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/john_pals.bin"
-SGBData_AdamPortraitPals: ; 7379f (1c:779f)
+SGBData_AdamPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/adam_pals.bin"
-SGBData_JonathanPortraitPals: ; 737c4 (1c:77c4)
+SGBData_JonathanPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/jonathan_pals.bin"
-SGBData_JoshuaPortraitPals: ; 737e9 (1c:77e9)
+SGBData_JoshuaPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/joshua_pals.bin"
-SGBData_NicholasPortraitPals: ; 7380e (1c:780e)
+SGBData_NicholasPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/nicholas_pals.bin"
-SGBData_BrandonPortraitPals: ; 73833 (1c:7833)
+SGBData_BrandonPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/brandon_pals.bin"
-SGBData_MatthewPortraitPals: ; 73858 (1c:7858)
+SGBData_MatthewPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/matthew_pals.bin"
-SGBData_RyanPortraitPals: ; 7387d (1c:787d)
+SGBData_RyanPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/ryan_pals.bin"
-SGBData_AndrewPortraitPals: ; 738a2 (1c:78a2)
+SGBData_AndrewPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/andrew_pals.bin"
-SGBData_ChrisPortraitPals: ; 738c7 (1c:78c7)
+SGBData_ChrisPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/chris_pals.bin"
-SGBData_MichaelPortraitPals: ; 738ec (1c:78ec)
+SGBData_MichaelPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/michael_pals.bin"
-SGBData_DanielPortraitPals: ; 73911 (1c:7911)
+SGBData_DanielPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/daniel_pals.bin"
-SGBData_RobertPortraitPals: ; 73936 (1c:7936)
+SGBData_RobertPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/robert_pals.bin"
-SGBData_BrittanyPortraitPals: ; 7395b (1c:795b)
+SGBData_BrittanyPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/brittany_pals.bin"
-SGBData_KristinPortraitPals: ; 73980 (1c:7980)
+SGBData_KristinPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/kristin_pals.bin"
-SGBData_HeatherPortraitPals: ; 739a5 (1c:79a5)
+SGBData_HeatherPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/heather_pals.bin"
-SGBData_SaraPortraitPals: ; 739ca (1c:79ca)
+SGBData_SaraPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/sara_pals.bin"
-SGBData_AmandaPortraitPals: ; 739ef (1c:79ef)
+SGBData_AmandaPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/amanda_pals.bin"
-SGBData_JenniferPortraitPals: ; 73a14 (1c:7a14)
+SGBData_JenniferPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/jennifer_pals.bin"
-SGBData_JessicaPortraitPals: ; 73a39 (1c:7a39)
+SGBData_JessicaPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/jessica_pals.bin"
-SGBData_StephaniePortraitPals: ; 73a5e (1c:7a5e)
+SGBData_StephaniePortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/stephanie_pals.bin"
-SGBData_AaronPortraitPals: ; 73a83 (1c:7a83)
+SGBData_AaronPortraitPals:
dw $20 ; length
INCBIN "data/sgb_data/aaron_pals.bin"
-SGBData_GameBoyLink: ; 73aa8 (1c:7aa8)
+SGBData_GameBoyLink:
dw $40 ; length
INCBIN "data/sgb_data/gameboy_link_pals.bin"
-SGBData_CardPop: ; 73ad8 (1c:7ad8)
+SGBData_CardPop:
dw $40 ; length
INCBIN "data/sgb_data/card_pop_pals.bin"
-SGBData_GameBoyPrinter: ; 73b05 (1c:7b05)
+SGBData_GameBoyPrinter:
dw $40 ; length
INCBIN "data/sgb_data/gameboy_printer_pals.bin"
-SGBData_TitleScreen: ; 73b33 (1c:7b33)
+SGBData_TitleScreen:
dw $40 ; length
INCBIN "data/sgb_data/title_screen_pals.bin"
diff --git a/src/engine/starter_deck.asm b/src/engine/starter_deck.asm
new file mode 100644
index 0000000..0500b4a
--- /dev/null
+++ b/src/engine/starter_deck.asm
@@ -0,0 +1,182 @@
+; adds the chosen starter deck to the player's first deck configuration
+; and also adds to the collection its corresponding extra cards
+; input:
+; - a = starter deck chosen
+; $0 = Charmander
+; $1 = Squirtle
+; $2 = Bulbasaur
+_AddStarterDeck:
+ add a
+ ld e, a
+ ld d, 0
+ ld hl, .StarterCardIDs
+ add hl, de
+ ld a, PLAYER_TURN
+ ldh [hWhoseTurn], a
+ ld a, [hli] ; main deck
+ add 2
+ push hl
+ ld hl, sDeck1
+ call CopyDeckNameAndCards
+ pop hl
+ call SwapTurn
+ ld a, [hli] ; extra deck
+ add 2
+ call LoadDeck
+ call SwapTurn
+
+; wPlayerDeck = main starter deck
+; wOpponentDeck = extra cards
+ call EnableSRAM
+ ld h, HIGH(sCardCollection)
+ ld de, wPlayerDeck
+ ld c, DECK_SIZE
+.loop_main_cards
+ ld a, [de]
+ inc de
+ ld l, a
+ res CARD_NOT_OWNED_F, [hl]
+ dec c
+ jr nz, .loop_main_cards
+
+ ld h, HIGH(sCardCollection)
+ ld de, wOpponentDeck
+ ld c, 30 ; number of extra cards
+.loop_extra_cards
+ ld a, [de]
+ inc de
+ ld l, a
+ res CARD_NOT_OWNED_F, [hl]
+ inc [hl]
+ dec c
+ jr nz, .loop_extra_cards
+ call DisableSRAM
+ ret
+
+.StarterCardIDs
+ ; main deck, extra cards
+ db CHARMANDER_AND_FRIENDS_DECK_ID, CHARMANDER_EXTRA_DECK_ID
+ db SQUIRTLE_AND_FRIENDS_DECK_ID, SQUIRTLE_EXTRA_DECK_ID
+ db BULBASAUR_AND_FRIENDS_DECK_ID, BULBASAUR_EXTRA_DECK_ID
+
+; 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:
+; clear card and deck save data
+ call EnableSRAM
+ ld a, PLAYER_TURN
+ ldh [hWhoseTurn], a
+ ld hl, sCardAndDeckSaveData
+ ld bc, sCardAndDeckSaveDataEnd - sCardAndDeckSaveData
+.loop_clear
+ xor a
+ ld [hli], a
+ dec bc
+ ld a, c
+ or b
+ jr nz, .loop_clear
+
+; add the starter decks
+ ld a, CHARMANDER_AND_FRIENDS_DECK
+ ld hl, sSavedDeck1
+ call CopyDeckNameAndCards
+ ld a, SQUIRTLE_AND_FRIENDS_DECK
+ ld hl, sSavedDeck2
+ call CopyDeckNameAndCards
+ ld a, BULBASAUR_AND_FRIENDS_DECK
+ ld hl, sSavedDeck3
+ call CopyDeckNameAndCards
+
+; marks all cards in Collection to not owned
+ call EnableSRAM
+ ld hl, sCardCollection
+ ld a, CARD_NOT_OWNED
+.loop_collection
+ ld [hl], a
+ inc l
+ jr nz, .loop_collection
+
+ ld hl, sCurrentDuel
+ xor 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
+ ld [hl], $0
+ ld de, NAME_BUFFER_LENGTH
+ add hl, de
+ 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 InitPromotionalCardAndDeckCounterSaveData
+ call DisableSRAM
+ ret
+
+; input:
+; a = Deck ID
+; hl = destination to copy
+CopyDeckNameAndCards:
+ push de
+ push bc
+ push hl
+ call LoadDeck
+ jr c, .done
+ call .CopyDeckName
+ pop hl
+ call EnableSRAM
+ push hl
+ ld de, wDefaultText
+.loop_write_name
+ ld a, [de]
+ inc de
+ ld [hli], a
+ or a
+ jr nz, .loop_write_name
+ pop hl
+
+ push hl
+ ld de, DECK_NAME_SIZE
+ add hl, de
+ ld de, wPlayerDeck
+ ld c, DECK_SIZE
+.loop_write_cards
+ ld a, [de]
+ inc de
+ ld [hli], a
+ dec c
+ jr nz, .loop_write_cards
+ call DisableSRAM
+ or a
+.done
+ pop hl
+ pop bc
+ pop de
+ ret
+
+.CopyDeckName
+ ld hl, wDeckName
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wDefaultText
+ call CopyText
+ ret
diff --git a/src/engine/unused_copyright.asm b/src/engine/unused_copyright.asm
new file mode 100644
index 0000000..31a489b
--- /dev/null
+++ b/src/engine/unused_copyright.asm
@@ -0,0 +1,26 @@
+; shows Copyright information for 300 frames
+; or until Start button is pressed
+UnusedCopyrightScreen: ; unreferenced
+ call DisableLCD
+ farcall Func_10a9b
+ farcall Func_10000
+ ld bc, $0
+ ld a, SCENE_COPYRIGHT
+ call LoadScene
+ farcall Func_10af9
+ ld bc, 300
+.loop_frame
+ push bc
+ call DoFrameIfLCDEnabled
+ call UpdateRNGSources
+ pop bc
+ ldh a, [hKeysPressed]
+ and START
+ jr nz, .exit
+ dec bc
+ ld a, b
+ or c
+ jr nz, .loop_frame
+.exit
+ farcall Func_10ab4
+ ret
diff --git a/src/engine/unused_save_validation.asm b/src/engine/unused_save_validation.asm
new file mode 100644
index 0000000..f26bbcb
--- /dev/null
+++ b/src/engine/unused_save_validation.asm
@@ -0,0 +1,96 @@
+; this is a commented out routine for save data validation
+; sUnusedSaveDataValidationByte would be used to store some validation byte
+; and xor'd with $250 bytes in SRAM starting from sCardCollection
+; if the result wasn't 0, then it would mean there was
+; some save corruption and an error message would pop up
+StubbedUnusedSaveDataValidation:
+ ret
+
+UnusedSaveDataValidation: ; unreferenced
+ ldh a, [hBankSRAM]
+ or a
+ ret nz
+
+ push hl
+ push de
+ push bc
+ ld hl, sCardCollection
+ ld bc, $250
+ ld a, [sUnusedSaveDataValidationByte]
+ ld e, a
+.loop_xor
+ ld a, [hli]
+ xor e
+ ld e, a
+ dec bc
+ ld a, c
+ or b
+ jr nz, .loop_xor
+ ld a, e
+ pop bc
+ pop de
+ pop hl
+ or a
+ ret z
+
+ xor a
+ ld [wTileMapFill], a
+ ld hl, wDoFrameFunction
+ ld [hli], a
+ ld [hl], a
+ ldh [hSCX], a
+ ldh [hSCY], a
+ bank1call ZeroObjectPositionsAndToggleOAMCopy
+ call EmptyScreen
+ call LoadSymbolsFont
+ bank1call SetDefaultPalettes
+ ld a, [wConsole]
+ cp CONSOLE_SGB
+ jr nz, .not_sgb
+ ld a, $e4
+ ld [wOBP0], a
+ ld [wBGP], a
+ ld a, $01
+ ld [wFlushPaletteFlags], a
+.not_sgb
+ lb de, $38, $9f
+ call SetupText
+ ldtx hl, YourDataWasDestroyedSomehowText
+ bank1call DrawWholeScreenTextBox
+ ld a, SRAM_ENABLE
+ ld [MBC3SRamEnable], a
+ xor a
+ ldh [hBankSRAM], a
+ ld [MBC3SRamBank], a
+ ld [MBC3RTC], a
+ ld [MBC3SRamEnable], a
+ jp Reset
+
+ ret
+
+UnusedCalculateSaveDataValidationByte: ; unreferenced
+ ldh a, [hBankSRAM]
+ or a
+ ret nz
+ push hl
+ push de
+ push bc
+ ld hl, sCardCollection
+ ld bc, $250
+ ld e, $00
+.loop_xor
+ ld a, [hli]
+ xor e
+ ld e, a
+ dec bc
+ ld a, c
+ or b
+ jr nz, .loop_xor
+ ld a, SRAM_ENABLE
+ ld [MBC3SRamEnable], a
+ ld a, e
+ ld [sUnusedSaveDataValidationByte], a
+ pop bc
+ pop de
+ pop hl
+ ret