diff options
| author | ElectroDeoxys <ElectroDeoxys@gmail.com> | 2021-09-27 11:56:10 +0100 | 
|---|---|---|
| committer | ElectroDeoxys <ElectroDeoxys@gmail.com> | 2021-09-27 11:56:10 +0100 | 
| commit | 7825b5ef0f09a877142ea1eb221e895bb60a0253 (patch) | |
| tree | 9d46dfebd219919f5144786caf3ebfdf7cdab3a7 /src/engine | |
| parent | 48f83527c769441b6c123f3382d90e2e962ef9a0 (diff) | |
Split bank 6
Diffstat (limited to 'src/engine')
| -rw-r--r-- | src/engine/auto_deck_machines.asm | 191 | ||||
| -rw-r--r-- | src/engine/bank03.asm | 4 | ||||
| -rw-r--r-- | src/engine/bank06.asm | 5974 | ||||
| -rw-r--r-- | src/engine/copy_card_name.asm | 152 | ||||
| -rw-r--r-- | src/engine/duel/animations.asm | 354 | ||||
| -rw-r--r-- | src/engine/duel/core.asm | 2 | ||||
| -rw-r--r-- | src/engine/duel/effect_commands.asm | 1619 | ||||
| -rw-r--r-- | src/engine/game_loop.asm | 2 | ||||
| -rw-r--r-- | src/engine/input_name.asm | 1417 | ||||
| -rw-r--r-- | src/engine/link/card_pop.asm | 399 | ||||
| -rw-r--r-- | src/engine/link/ir_core.asm | 531 | ||||
| -rw-r--r-- | src/engine/link/ir_functions.asm | 323 | ||||
| -rw-r--r-- | src/engine/link/link_duel.asm | 179 | ||||
| -rw-r--r-- | src/engine/link/printer.asm | 1124 | ||||
| -rw-r--r-- | src/engine/menus/booster_pack.asm | 42 | ||||
| -rw-r--r-- | src/engine/menus/common.asm | 8 | ||||
| -rw-r--r-- | src/engine/menus/glossary.asm | 221 | ||||
| -rw-r--r-- | src/engine/menus/play_area.asm | 570 | ||||
| -rw-r--r-- | src/engine/menus/unknown.asm | 103 | ||||
| -rw-r--r-- | src/engine/promotional_card.asm | 61 | ||||
| -rw-r--r-- | src/engine/sprite_vblank.asm | 39 | ||||
| -rw-r--r-- | src/engine/starter_deck.asm | 182 | ||||
| -rw-r--r-- | src/engine/unused_save_validation.asm | 96 | 
23 files changed, 7611 insertions, 5982 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/bank03.asm b/src/engine/bank03.asm index 3c83056..7bd4b75 100644 --- a/src/engine/bank03.asm +++ b/src/engine/bank03.asm @@ -2379,7 +2379,7 @@ ScriptCommand_ShowCardReceivedScreen: ; cee2 (3:4ee2)  	farcall Func_10000  	farcall FlashWhiteScreen  	pop af -	bank1call Func_7594 +	bank1call ShowPromotionalCardScreen  	call WhiteOutDMGPals  	call DoFrameIfLCDEnabled  	call ReturnToOverworldNoCallback @@ -3199,7 +3199,7 @@ ScriptCommand_nop: ; d3d1 (3:53d1)  ScriptCommand_GiveStarterDeck: ; d3d4 (3:53d4)  	ld a, [wStarterDeckChoice] -	bank1call Func_7576 +	bank1call AddStarterDeck  	jp IncreaseScriptPointerBy1  Unknown_d3dd: ; d3dd (3:53dd) 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/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/duel/animations.asm b/src/engine/duel/animations.asm new file mode 100644 index 0000000..46b1ea1 --- /dev/null +++ b/src/engine/duel/animations.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/core.asm b/src/engine/duel/core.asm index 3b4b95c..f2f08c7 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/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/input_name.asm b/src/engine/input_name.asm new file mode 100644 index 0000000..c9d222e --- /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 around (2:4f05), +; 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/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/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/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/sprite_vblank.asm b/src/engine/sprite_vblank.asm new file mode 100644 index 0000000..5f099a1 --- /dev/null +++ b/src/engine/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/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_save_validation.asm b/src/engine/unused_save_validation.asm new file mode 100644 index 0000000..9a30d38 --- /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 corrpution 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 | 
