diff options
Diffstat (limited to 'src/engine')
-rw-r--r-- | src/engine/bank1.asm | 2473 | ||||
-rw-r--r-- | src/engine/bank1c.asm | 2 | ||||
-rw-r--r-- | src/engine/bank2.asm | 16 | ||||
-rw-r--r-- | src/engine/bank20.asm | 2 | ||||
-rw-r--r-- | src/engine/bank3.asm | 20 | ||||
-rw-r--r-- | src/engine/bank4.asm | 10 | ||||
-rw-r--r-- | src/engine/bank5.asm | 2 | ||||
-rw-r--r-- | src/engine/bank6.asm | 157 | ||||
-rw-r--r-- | src/engine/bank7.asm | 4 | ||||
-rw-r--r-- | src/engine/booster_packs.asm | 2 | ||||
-rw-r--r-- | src/engine/home.asm | 947 |
11 files changed, 3109 insertions, 526 deletions
diff --git a/src/engine/bank1.asm b/src/engine/bank1.asm index 8852914..7933fc4 100644 --- a/src/engine/bank1.asm +++ b/src/engine/bank1.asm @@ -15,7 +15,7 @@ GameLoop: ; 4000 (1:4000) ld a, $1 ld [wUppercaseFlag], a ei - farcall Func_1a6cc + farcall CommentedOut_1a6cc ldh a, [hButtonsHeld] cp A_BUTTON | B_BUTTON jr z, .ask_erase_backup_ram @@ -45,8 +45,8 @@ Func_405a: ; 405a (1:405a) xor a ld [wTileMapFill], a call DisableLCD - call Func_2119 - call Func_5aeb + call LoadDuelHUDTiles + call SetDefaultPalettes ld de, $387f call Func_2275 ret @@ -67,16 +67,16 @@ TryContinueDuel: ; 406f (1:406f) ContinueDuel: ; 407a (1:407a) ld hl, sp+$00 ld a, l - ld [wcbe5], a + ld [wDuelReturnAddress], a ld a, h - ld [wcbe5 + 1], a + ld [wDuelReturnAddress + 1], a call ClearJoypad ld a, [wDuelTheme] call PlaySong xor a ld [wDuelFinished], a - call DuelMainScene - jp StartDuel.asm_40fb + call DuelMainInterface + jp StartDuel.begin_turn ; 0x4097 FailedToContinueDuel: ; 4097 (1:4097) @@ -99,7 +99,7 @@ StartDuel: ; 409f (1:409f) call SwapTurn call LoadOpponentDeck call SwapTurn - jr .asm_40ca + jr .continue ld a, MUSIC_DUEL_THEME_1 ld [wDuelTheme], a @@ -109,17 +109,17 @@ StartDuel: ; 409f (1:409f) ld [hl], a ld [wIsPracticeDuel], a -.asm_40ca +.continue ld hl, sp+$0 ld a, l - ld [wcbe5], a + ld [wDuelReturnAddress], a ld a, h - ld [wcbe5 + 1], a + ld [wDuelReturnAddress + 1], a xor a ld [wCurrentDuelMenuItem], a call Func_420b ld a, [wcc18] - ld [wcc08], a + ld [wDuelInitialPrizes], a call $70aa ld a, [wDuelTheme] call PlaySong @@ -134,7 +134,7 @@ StartDuel: ; 409f (1:409f) call $54c8 call HandleTurn -.asm_40fb +.begin_turn call Func_0f58 ld a, [wDuelFinished] or a @@ -148,27 +148,27 @@ StartDuel: ; 409f (1:409f) jr nz, .duel_finished ld hl, wDuelTurns inc [hl] - ld a, [wcc09] - cp $80 - jr z, .asm_4126 + ld a, [wDuelType] + cp DUELTYPE_PRACTICE + jr z, .practice_duel .next_turn call SwapTurn jr .main_duel_loop -.asm_4126 +.practice_duel ld a, [wIsPracticeDuel] or a jr z, .next_turn ld a, [hl] - cp $f + cp 15 ; the practice duel lasts 15 turns jr c, .next_turn - xor a - ld [wd0c3], a + xor a ; DUEL_WIN + ld [wDuelResult], a ret .duel_finished - call $5990 + call ZeroObjectPositionsAndToggleOAMCopy call EmptyScreen ld a, BOXMSG_DECISION call DrawDuelBoxMessage @@ -179,19 +179,19 @@ StartDuel: ; 409f (1:409f) push af ld a, PLAYER_TURN ldh [hWhoseTurn], a - call $4a97 - call $4ad6 + call Func_4a97 + call Func_4ad6 pop af ldh [hWhoseTurn], a call Func_3b21 ld a, [wDuelFinished] - cp DUEL_WON + cp TURN_PLAYER_WON jr z, .active_duelist_won_battle - cp DUEL_LOST + cp TURN_PLAYER_LOST jr z, .active_duelist_lost_batte ld a, $5f ld c, MUSIC_DARK_DIDDLY - ldtx hl, DuelWasDrawText + ldtx hl, DuelWasADrawText jr .handle_duel_finished .active_duelist_won_battle @@ -199,8 +199,8 @@ StartDuel: ; 409f (1:409f) cp PLAYER_TURN jr nz, .opponent_won_battle .player_won_battle - xor a - ld [wd0c3], a + xor a ; DUEL_WIN + ld [wDuelResult], a ld a, $5d ld c, MUSIC_MATCH_VICTORY ldtx hl, WonDuelText @@ -211,8 +211,8 @@ StartDuel: ; 409f (1:409f) cp PLAYER_TURN jr nz, .player_won_battle .opponent_won_battle - ld a, $1 - ld [wd0c3], a + ld a, DUEL_LOSS + ld [wDuelResult], a ld a, $5e ld c, MUSIC_MATCH_LOSS ldtx hl, LostDuelText @@ -225,13 +225,13 @@ StartDuel: ; 409f (1:409f) ldh [hWhoseTurn], a call DrawWideTextBox_PrintText call EnableLCD -.asm_41a7 +.wait_song call DoFrame - call Func_378a + call AssertSongFinished or a - jr nz, .asm_41a7 + jr nz, .wait_song ld a, [wDuelFinished] - cp DUEL_DRAW + cp TURN_PLAYER_TIED jr z, .tied_battle call Func_39fc call WaitForWideTextBoxInput @@ -248,26 +248,26 @@ StartDuel: ; 409f (1:409f) call PlaySong ldtx hl, StartSuddenDeathMatchText call DrawWideTextBox_WaitForInput - ld a, $1 - ld [wcc08], a + ld a, 1 + ld [wDuelInitialPrizes], a call $70aa - ld a, [wcc09] - cp $1 - jr z, .asm_41f3 + ld a, [wDuelType] + cp DUELTYPE_LINK + jr z, .link_duel ld a, PLAYER_TURN ldh [hWhoseTurn], a call Func_4b60 jp .main_duel_loop -.asm_41f3 +.link_duel call Func_0f58 ld h, PLAYER_TURN ld a, [wSerialOp] cp $29 - jr z, .asm_4201 + jr z, .got_turn ld h, OPPONENT_TURN -.asm_4201 +.got_turn ld a, h ldh [hWhoseTurn], a call Func_4b60 @@ -278,31 +278,32 @@ StartDuel: ; 409f (1:409f) Func_420b: ; 420b (1:420b) xor a ld [wTileMapFill], a - call $5990 + call ZeroObjectPositionsAndToggleOAMCopy call EmptyScreen - call Func_2119 - call Func_5aeb + call LoadDuelHUDTiles + call SetDefaultPalettes ld de, $389f call Func_2275 call EnableLCD ret ; 0x4225 +; handle the turn of the duelist identified by hWhoseTurn HandleTurn: ; 4225 (1:4225) ld a, DUELVARS_DUELIST_TYPE call GetTurnDuelistVariable ld [wDuelistType], a ld a, [wDuelTurns] cp 2 - jr c, .asm_4237 ; jump if it's the turn holder's first turn - call $70f6 + jr c, .skip_let_evolve ; jump if it's the turn holder's first turn + call SetAllPlayAreaPokemonCanEvolve -.asm_4237 - call $70e6 - call $4933 +.skip_let_evolve + call Func_70e6 + call Func_4933 call DrawCardFromDeck jr nc, .deck_not_empty - ld a, DUEL_LOST + ld a, TURN_PLAYER_LOST ld [wDuelFinished], a ret @@ -311,23 +312,31 @@ HandleTurn: ; 4225 (1:4225) call AddCardToHand ld a, [wDuelistType] cp DUELIST_TYPE_PLAYER - jr z, Func_4262 + jr z, HandleTurn_PlayerDrewCard call SwapTurn call IsClairvoyanceActive call SwapTurn - call c, $4b2c - jr DuelMainScene - -Func_4262: - call $4b2c - call Func_100b + call c, DisplayPlayerDrawCardScreen + jr DuelMainInterface + +; display the animation of the player drawing the card at hTempCardIndex_ff98 +; save duel state to SRAM, and fall through to DuelMainInterface to effectively +; begin the turn +HandleTurn_PlayerDrewCard: + call DisplayPlayerDrawCardScreen + call SaveDuelStateToSRAM +; fallthrough Func_4268: ld a, $06 - call $51e7 + call DoPracticeDuelAction +; fallthrough -DuelMainScene: - call $4f9d +; print the main interface during a duel, including background, Pokemon, HUDs and a text box. +; the bottom text box changes depending on whether the turn belongs to the player (show the duel menu), +; an AI opponent (print "Waiting..." and a reduced menu) or a link opponent (print "<Duelist> is thinking"). +DuelMainInterface: ; 426d (1:426d) + call DrawDuelMainScene ld a, [wDuelistType] cp DUELIST_TYPE_PLAYER jr z, PrintDuelMenu @@ -345,7 +354,7 @@ DuelMainScene: ld [wcc10], a ret -PrintDuelMenu: +PrintDuelMenu: ; 4295 (1:4295) call DrawWideTextBox ld hl, $54e9 call Func_2c08 @@ -356,38 +365,39 @@ PrintDuelMenu: ret nz ld a, [wCurrentDuelMenuItem] call SetMenuItem +; fallthrough -HandleDuelMenuInput: +HandleDuelMenuInputAndShortcuts: call DoFrame ldh a, [hButtonsHeld] and B_BUTTON jr z, .b_not_held ldh a, [hButtonsPressed] bit D_UP_F, a - jr nz, OpponentPlayAreaScreen + jr nz, DuelMenuShortcut_OpponentPlayArea bit D_DOWN_F, a - jr nz, PlayerPlayAreaScreen + jr nz, DuelMenuShortcut_PlayerPlayArea bit D_LEFT_F, a - jr nz, PlayerDiscardPileScreen + jr nz, DuelMenuShortcut_PlayerDiscardPile bit D_RIGHT_F, a - jr nz, OpponentDiscardPileScreen + jr nz, DuelMenuShortcut_OpponentDiscardPile bit START_F, a - jp nz, OpponentActivePokemonScreen + jp nz, DuelMenuShortcut_OpponentActivePokemon .b_not_held ldh a, [hButtonsPressed] and START - jp nz, PlayerActivePokemonScreen + jp nz, DuelMenuShortcut_PlayerActivePokemon ldh a, [hButtonsPressed] bit SELECT_F, a - jp nz, $458e + jp nz, DuelMenuShortcut_BothActivePokemon ld a, [wcbe7] or a - jr nz, HandleDuelMenuInput - call Func_271a + jr nz, HandleDuelMenuInputAndShortcuts + call HandleDuelMenuInput ld a, e ld [wCurrentDuelMenuItem], a - jr nc, HandleDuelMenuInput + jr nc, HandleDuelMenuInputAndShortcuts ldh a, [hCurrentMenuItem] ld hl, DuelMenuFunctionTable jp JumpToFunctionInTable @@ -408,41 +418,49 @@ Func_42fd: ; 42fd (1:42fd) jp PrintDuelMenu.asm_429e ; 0x430b -OpponentPlayAreaScreen: ; 430b (1:430b) - call DrawOpponentPlayAreaScreen - jp DuelMainScene +; triggered by pressing B + UP in the duel menu +DuelMenuShortcut_OpponentPlayArea: ; 430b (1:430b) + call OpenOpponentPlayAreaScreen + jp DuelMainInterface -PlayerPlayAreaScreen: ; 4311 (1:4311) - call DrawPlayerPlayAreaScreen - jp DuelMainScene +; triggered by pressing B + DOWN in the duel menu +DuelMenuShortcut_PlayerPlayArea: ; 4311 (1:4311) + call OpenPlayAreaScreen + jp DuelMainInterface -OpponentDiscardPileScreen: ; 4317 (1:4317) - call DrawOpponentDiscardPileScreen +; triggered by pressing B + LEFT in the duel menu +DuelMenuShortcut_OpponentDiscardPile: ; 4317 (1:4317) + call OpenOpponentDiscardPileScreen jp c, PrintDuelMenu - jp DuelMainScene + jp DuelMainInterface -PlayerDiscardPileScreen: ; 4320 (1:4320) - call DrawPlayerDiscardPileScreen +; triggered by pressing B + RIGHT in the duel menu +DuelMenuShortcut_PlayerDiscardPile: ; 4320 (1:4320) + call OpenPlayerDiscardPileScreen jp c, PrintDuelMenu - jp DuelMainScene + jp DuelMainInterface -DrawOpponentPlayAreaScreen: ; 4329 (1:4329) +; draw the opponent's play area screen +OpenOpponentPlayAreaScreen: ; 4329 (1:4329) call SwapTurn - call DrawPlayerPlayAreaScreen + call OpenPlayAreaScreen call SwapTurn ret -DrawPlayerPlayAreaScreen: ; 4333 (1:4333) - call $5fdd - jp $6008 +; draw the turn holder's play area screen +OpenPlayAreaScreen: ; 4333 (1:4333) + call HasAlivePokemonInPlayArea + jp OpenPlayAreaScreenForViewing -DrawOpponentDiscardPileScreen: ; 4339 (1:4339) +; draw the opponent's discard pile screen +OpenOpponentDiscardPileScreen: ; 4339 (1:4339) call SwapTurn - call $5550 + call OpenDiscardPileScreen jp SwapTurn -DrawPlayerDiscardPileScreen: ; 4342 (1:4342) - jp $5550 +; draw the player's discard pile screen +OpenPlayerDiscardPileScreen: ; 4342 (1:4342) + jp OpenDiscardPileScreen Func_4345: ; 4345 (1:4345) call SwapTurn @@ -453,28 +471,31 @@ Func_4345: ; 4345 (1:4345) Func_434e: ; 434e (1:434e) call CreateHandCardList jr c, .no_cards_in_hand - call $559a - ld a, $09 + call DrawCardListScreenLayout + ld a, START + A_BUTTON ld [wcbd6], a - jp $55f0 + jp Func_55f0 .no_cards_in_hand ldtx hl, NoCardsInHandText jp DrawWideTextBox_WaitForInput ; 0x4364 -OpponentActivePokemonScreen: ; 4364 (1:4364) +; triggered by pressing B + START in the duel menu +DuelMenuShortcut_OpponentActivePokemon: ; 4364 (1:4364) call SwapTurn - call Func_4376 + call OpenActivePokemonScreen call SwapTurn - jp DuelMainScene + jp DuelMainInterface ; 0x4370 -PlayerActivePokemonScreen: ; 4370 (1:4370) - call Func_4376 - jp DuelMainScene +; triggered by pressing START in the duel menu +DuelMenuShortcut_PlayerActivePokemon: ; 4370 (1:4370) + call OpenActivePokemonScreen + jp DuelMainInterface ; 0x4376 -Func_4376: ; 4376 (1:4376) +; draw the turn holder's active Pokemon screen if it exists +OpenActivePokemonScreen: ; 4376 (1:4376) ld a, DUELVARS_ARENA_CARD call GetTurnDuelistVariable cp -1 @@ -485,31 +506,34 @@ Func_4376: ; 4376 (1:4376) xor a ld [hli], a ld [hl], a - call $576a + call Func_576a ret ; 0x438e +; triggered by selecting the "Pkmn Power" item in the duel menu DuelMenu_PkmnPower: ; 438e (1:438e) call $6431 - jp c, DuelMainScene + jp c, DuelMainInterface call Func_1730 - jp DuelMainScene + jp DuelMainInterface +; triggered by selecting the "Done" item in the duel menu DuelMenu_Done: ; 439a (1:439a) ld a, $08 - call $51e7 + call DoPracticeDuelAction jp c, Func_4268 ld a, $05 call SetDuelAIAction call $717a ret +; triggered by selecting the "Retreat" item in the duel menu DuelMenu_Retreat: ; 43ab (1:43ab) ld a, DUELVARS_ARENA_CARD_STATUS call GetTurnDuelistVariable and CNF_SLP_PRZ cp CONFUSED - ldh [hffa0], a + ldh [hTemp_ffa0], a jr nz, Func_43f1 ld a, [wcc0c] or a @@ -520,7 +544,7 @@ DuelMenu_Retreat: ; 43ab (1:43ab) jr c, Func_441c ldtx hl, SelectPkmnOnBenchToSwitchWithActiveText call DrawWideTextBox_WaitForInput - call $600c + call OpenPlayAreaScreenForSelection jr c, Func_441c ld [wBenchSelectedPokemon], a ld a, [wBenchSelectedPokemon] @@ -529,7 +553,7 @@ DuelMenu_Retreat: ; 43ab (1:43ab) call SetDuelAIAction call $657a jr nc, Func_441c - call $4f9d + call DrawDuelMainScene Func_43e8: ; 43e8 ldtx hl, UnableToRetreatText @@ -544,38 +568,70 @@ Func_43f1: ; 43f1 (1:43f1) call $6558 ldtx hl, SelectPkmnOnBenchToSwitchWithActiveText call DrawWideTextBox_WaitForInput - call $600c + call OpenPlayAreaScreenForSelection ld [wBenchSelectedPokemon], a ldh [hTempPlayAreaLocationOffset_ffa1], a push af call $6564 pop af - jp c, DuelMainScene + jp c, DuelMainInterface ld a, $04 call SetDuelAIAction call $657a Func_441c: ; 441c (1:441c) - jp DuelMainScene + jp DuelMainInterface Func_441f: ; 441f (1:441f) call DrawWideTextBox_WaitForInput jp PrintDuelMenu +; triggered by selecting the "Hand" item in the duel menu DuelMenu_Hand: ; 4425 (1:4425) ld a, DUELVARS_NUMBER_OF_CARDS_IN_HAND call GetTurnDuelistVariable or a - jr nz, Func_4436 + jr nz, OpenPlayerHandScreen ldtx hl, NoCardsInHandText call DrawWideTextBox_WaitForInput jp PrintDuelMenu -Func_4436: ; 4436 (1:4436) - INCROM $4436, $4477 - +; draw the screen for the player's hand and handle user input to for example check +; a card or attempt to use a card, playing the card if possible in that case. +OpenPlayerHandScreen: ; 4436 (1:4436) + call CreateHandCardList + call DrawCardListScreenLayout + ldtx hl, PleaseSelectHandText + call SetCardListInfoBoxText + ld a, $1 + ld [wcbde], a +.handle_input + call Func_55f0 + push af + ld a, [wcbdf] + or a + call nz, SortHandCardsByID + pop af + jp c, DuelMainInterface + ldh a, [hTempCardIndex_ff98] + call LoadCardDataToBuffer1_FromDeckIndex + ld a, [wLoadedCard1Type] + ld c, a + bit TYPE_TRAINER_F, c + jr nz, .trainer_card + bit TYPE_ENERGY_F, c + jr nz, UseEnergyCard + call UsePokemonCard + jr c, ReloadCardListScreen ; jump if card not played + jp DuelMainInterface +.trainer_card + call UseTrainerCard + jr c, ReloadCardListScreen ; jump if card not played + jp DuelMainInterface + +; use the energy card with deck index at hTempCardIndex_ff98 ; c contains the type of energy card being played -PlayerUseEnergyCard: ; 4477 (1:4477) +UseEnergyCard: ; 4477 (1:4477) ld a, c cp TYPE_ENERGY_WATER jr nz, .not_water_energy @@ -586,9 +642,9 @@ PlayerUseEnergyCard: ; 4477 (1:4477) ld a, [wAlreadyPlayedEnergy] or a jr nz, .already_played_energy - call $5fdd - call $600c ; choose card to play energy card on - jp c, DuelMainScene ; exit if no card was chosen + call HasAlivePokemonInPlayArea + call OpenPlayAreaScreenForSelection ; choose card to play energy card on + jp c, DuelMainInterface ; exit if no card was chosen .play_energy_set_played ld a, $1 ld [wAlreadyPlayedEnergy], a @@ -597,58 +653,192 @@ PlayerUseEnergyCard: ; 4477 (1:4477) ldh [hTempPlayAreaLocationOffset_ffa1], a ld e, a ldh a, [hTempCardIndex_ff98] - ldh [hffa0], a + ldh [hTemp_ffa0], a call PutHandCardInPlayArea call $61b8 ld a, $3 call SetDuelAIAction call $68e4 - jp DuelMainScene + jp DuelMainInterface .rain_dance_active - call $5fdd - call $600c ; choose card to play energy card on - jp c, DuelMainScene ; exit if no card was chosen + call HasAlivePokemonInPlayArea + call OpenPlayAreaScreenForSelection ; choose card to play energy card on + jp c, DuelMainInterface ; exit if no card was chosen call CheckRainDanceScenario jr c, .play_energy ld a, [wAlreadyPlayedEnergy] or a jr z, .play_energy_set_played - ldtx hl, OnlyOneEnergyCardText + ldtx hl, MayOnlyAttachOneEnergyCardText call DrawWideTextBox_WaitForInput - jp Func_4436 + jp OpenPlayerHandScreen .already_played_energy - ldtx hl, OnlyOneEnergyCardText + ldtx hl, MayOnlyAttachOneEnergyCardText call DrawWideTextBox_WaitForInput +; fallthrough + +; reload the card list screen after the card trying to play couldn't be played +ReloadCardListScreen: ; 44d2 (1:44d2) call CreateHandCardList - call $55be - jp $4447 + ; skip doing the things that have already been done when initially opened + call DrawCardListScreenLayout.draw + jp OpenPlayerHandScreen.handle_input ; 0x44db - INCROM $44db, $4585 +; use a basic Pokemon card on the arena or bench, or place an stage 1 or 2 +; Pokemon card over a Pokemon card already in play to evolve it. +; the card to use is loaded in wLoadedCard1 and its deck index is at hTempCardIndex_ff98. +; return nc if the card was played, carry if it wasn't. +UsePokemonCard: ; 44db (1:44db) + ld a, [wLoadedCard1Stage] + or a ; BASIC + jr nz, .try_evolve ; jump if the card being played is a Stage 1 or 2 Pokemon + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + cp MAX_PLAY_AREA_POKEMON + jr nc, .no_space + ldh a, [hTempCardIndex_ff98] + ldh [hTemp_ffa0], a + call PutHandPokemonCardInPlayArea + ldh [hTempPlayAreaLocationOffset_ff9d], a + add DUELVARS_ARENA_CARD_STAGE + call GetTurnDuelistVariable + ld [hl], BASIC + ld a, $01 + call SetDuelAIAction + ldh a, [hTempCardIndex_ff98] + call LoadCardDataToBuffer1_FromDeckIndex + ld a, 20 + call CopyCardNameAndLevel + ld [hl], $00 + ld hl, $0000 + call LoadTxRam2 + ldtx hl, PlacedOnTheBenchText + call DrawWideTextBox_WaitForInput + call Func_161e + or a + ret +.no_space + ldtx hl, NoSpaceOnTheBenchText + call DrawWideTextBox_WaitForInput + scf + ret +.try_evolve + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + ld c, a + ldh a, [hTempCardIndex_ff98] + ld d, a + ld e, PLAY_AREA_ARENA + push de + push bc +.next_play_area_pkmn + push de + call CheckIfCanEvolveInto + pop de + jr nc, .can_evolve + inc e + dec c + jr nz, .next_play_area_pkmn + pop bc + pop de +.find_cant_evolve_reason_loop + push de + call CheckIfCanEvolveInto + pop de + ldtx hl, CantEvolvePokemonInSameTurnItsPlacedText + jr nz, .cant_same_turn + inc e + dec c + jr nz, .find_cant_evolve_reason_loop + ldtx hl, NoPokemonCapableOfEvolvingText +.cant_same_turn + ; don't bother opening the selection screen if there are no pokemon capable of evolving + call DrawWideTextBox_WaitForInput + scf + ret +.can_evolve + pop bc + pop de + call IsPrehistoricPowerActive + jr c, .prehistoric_power + call HasAlivePokemonInPlayArea +.try_evolve_loop + call OpenPlayAreaScreenForSelection + jr c, .done + ldh a, [hTempCardIndex_ff98] + ldh [hTemp_ffa0], a + ldh a, [hTempPlayAreaLocationOffset_ff9d] + ldh [hTempPlayAreaLocationOffset_ffa1], a + call EvolvePokemonCard + jr c, .try_evolve_loop ; jump if evolution wasn't successsful somehow + ld a, $02 + call SetDuelAIAction + call $61b8 + call $68fa + call Func_161e +.done + or a + ret +.prehistoric_power + call DrawWideTextBox_WaitForInput + scf + ret +; 0x4585 +; triggered by selecting the "Check" item in the duel menu DuelMenu_Check: ; 4585 (1:4585) call Func_3b31 call Func_3096 - jp DuelMainScene + jp DuelMainInterface - INCROM $458e, $46fc +; triggered by pressing SELECT in the duel menu +DuelMenuShortcut_BothActivePokemon:: ; 458e (1:458e) + call Func_3b31 + call Func_4597 + jp DuelMainInterface +; 0x4597 +Func_4597: ; 4597 (1:4597) + call Func_30a6 + ret c + call Func_45a9 + ret c + call SwapTurn + call Func_45a9 + call SwapTurn + ret +; 0x45a9 + +Func_45a9: ; 45a9 (1:45a9) + call HasAlivePokemonInPlayArea + ld a, $02 + ld [wcbd4], a + call OpenPlayAreaScreenForViewing + ldh a, [hButtonsPressed] + and B_BUTTON + ret z + scf + ret +; 0x45bb + + INCROM $45bb, $46fc + +; triggered by selecting the "Attack" item in the duel menu DuelMenu_Attack: ; 46fc (1:46fc) call HandleCantAttackSubstatus jr c, .alert_cant_attack_and_cancel_menu call CheckIfActiveCardParalyzedOrAsleep - jr nc, .clear_sub_menu_selection - + jr nc, .can_attack .alert_cant_attack_and_cancel_menu call DrawWideTextBox_WaitForInput jp PrintDuelMenu -.clear_sub_menu_selection +.can_attack xor a ld [wSelectedDuelSubMenuItem], a - .try_open_attack_menu call LoadPokemonMovesToDuelTempList or a @@ -660,8 +850,8 @@ DuelMenu_Attack: ; 46fc (1:46fc) .open_attack_menu push af ld a, [wSelectedDuelSubMenuItem] - ld hl, AttackMenuCursorData - call InitializeCursorParameters + ld hl, AttackMenuParameters + call InitializeMenuParameters pop af ld [wNumMenuItems], a ldh a, [hWhoseTurn] @@ -677,7 +867,7 @@ DuelMenu_Attack: ; 46fc (1:46fc) jr nz, .display_selected_move_info call HandleMenuInput jr nc, .wait_for_input - cp $ff ; was B pressed? + cp -1 ; was B pressed? jp z, PrintDuelMenu ld [wSelectedDuelSubMenuItem], a call CheckIfEnoughEnergies @@ -693,44 +883,44 @@ DuelMenu_Attack: ; 46fc (1:46fc) ld d, $00 ld hl, wDuelTempList add hl, de - ld d, [hl] ; card number within the deck (0 to 59) + ld d, [hl] ; card index within the deck (0 to 59) inc hl ld e, [hl] ; attack index (0 or 1) call CopyMoveDataAndDamage_FromDeckIndex call HandleAmnesiaSubstatus jr c, .cannot_use_due_to_amnesia ld a, $07 - call $51e7 + call DoPracticeDuelAction jp c, Func_4268 call Func_1730 - jp c, DuelMainScene + jp c, DuelMainInterface ret -.cannot_use_due_to_amnesia ; 477d (1:477d) +.cannot_use_due_to_amnesia call DrawWideTextBox_WaitForInput jr .try_open_attack_menu -.display_selected_move_info ; 4782 (1:4782) +.display_selected_move_info call Func_478b - call $4f9d + call DrawDuelMainScene jp .try_open_attack_menu Func_478b: ; 478b (1:478b) - ld a, $01 + ld a, CARDPAGE_POKEMON_OVERVIEW ld [wCardPageNumber], a xor a ld [wcbc9], a call EmptyScreen call Func_3b31 - ld de, $8a00 - call $59ca - call $5a0e - call $59f5 - call $5a34 - ld de, $3830 - call $5999 - ld de, $0604 - call $5a56 + ld de, v0Tiles1 + $20 tiles + call LoadLoaded1CardGfx + call SetOBP1OrSGB3ToCardPalette + call SetBGP6OrSGB3ToCardPalette + call FlushAllPalettesOrSendPal23Packet + lb de, $38, $30 ; X Position and Y Position of top-left corner + call PlaceCardImageOAM + lb de, 6, 4 + call ApplyBGP6OrSGB3ToCardImage ldh a, [hCurrentMenuItem] ld [wSelectedDuelSubMenuItem], a add a @@ -764,13 +954,13 @@ Func_478b: ; 478b (1:478b) jr z, .asm_47d4 ret -AttackMenuCursorData: - db 1, 13 ; x, y +AttackMenuParameters: + db 1, 13 ; cursor x, cursor y db 2 ; y displacement between items db 2 ; number of items db $0f ; cursor tile number db $00 ; tile behind cursor - dw $0000 ; unknown function pointer if non-0 + dw $0000 ; function pointer if non-0 Func_47ec: ; $47ec (1:47ec) ld a, [wcc04] @@ -866,6 +1056,8 @@ LoadPokemonMovesToDuelTempList: ; 4823 (1:4823) ld a, c ret +; given de = wLoadedCard*Move*Name, return carry if the move is a +; Pkmn Power or the moveslot is empty. CheckIfMoveExists: ; 4872 (1:4872) push hl push de @@ -883,13 +1075,11 @@ CheckIfMoveExists: ; 4872 (1:4872) cp POKEMON_POWER jr z, .return_no_move_found or a - .return pop bc pop de pop hl ret - .return_no_move_found scf jr .return @@ -909,7 +1099,7 @@ CheckIfEnoughEnergies: ; 488f (1:488f) ld d, $0 ld hl, wDuelTempList add hl, de - ld d, [hl] ; card number within the deck (0 to 59) + ld d, [hl] ; card index within the deck (0 to 59) inc hl ld e, [hl] ; attack index (0 or 1) call _CheckIfEnoughEnergies @@ -920,7 +1110,7 @@ CheckIfEnoughEnergies: ; 488f (1:488f) ; check if a pokemon card has enough energy attached to it in order to use a move ; input: -; d = card number within the deck (0 to 59) +; d = card index within the deck (0 to 59) ; e = attack index (0 or 1) ; wAttachedEnergies and wTotalAttachedEnergies ; returns: carry if not enough energy, nc if enough energy. @@ -941,12 +1131,12 @@ _CheckIfEnoughEnergies: ; 48ac (1:48ac) add hl, de ld a, [hli] or [hl] - jr z, .not_usable + jr z, .not_usable_or_not_enough_energies ld hl, CARD_DATA_MOVE1_CATEGORY - CARD_DATA_MOVE1_ENERGY add hl, de ld a, [hl] cp POKEMON_POWER - jr z, .not_usable + jr z, .not_usable_or_not_enough_energies xor a ld [wAttachedEnergiesAccum], a ld hl, wAttachedEnergies @@ -955,11 +1145,11 @@ _CheckIfEnoughEnergies: ; 48ac (1:48ac) .next_energy_type_pair ld a, [de] swap a - call _CheckIfEnoughEnergiesOfType - jr c, .not_enough_energies + call CheckIfEnoughEnergiesOfType + jr c, .not_usable_or_not_enough_energies ld a, [de] - call _CheckIfEnoughEnergiesOfType - jr c, .not_enough_energies + call CheckIfEnoughEnergiesOfType + jr c, .not_usable_or_not_enough_energies inc de dec c jr nz, .next_energy_type_pair @@ -972,14 +1162,13 @@ _CheckIfEnoughEnergies: ; 48ac (1:48ac) ld a, [wTotalAttachedEnergies] sub c cp b - jr c, .not_enough_energies + jr c, .not_usable_or_not_enough_energies or a .done pop de ret -.not_usable -.not_enough_energies +.not_usable_or_not_enough_energies scf jr .done ; 0x4900 @@ -987,7 +1176,7 @@ _CheckIfEnoughEnergies: ; 48ac (1:48ac) ; given the amount of energies of a specific type required for an attack in the ; lower nybble of register a, test if the pokemon card has enough energies of that type ; to use the move. Return carry if not enough energy, nc if enough energy. -_CheckIfEnoughEnergiesOfType: ; 4900 (1:4900) +CheckIfEnoughEnergiesOfType: ; 4900 (1:4900) and $f push af push hl @@ -1011,6 +1200,8 @@ _CheckIfEnoughEnergiesOfType: ; 4900 (1:4900) ret ; 0x4918 +; return carry and the corresponding text in hl if the turn holder's +; arena Pokemon card is paralyzed or asleep. CheckIfActiveCardParalyzedOrAsleep: ; 4918 (1:4918) ld a, DUELVARS_ARENA_CARD_STATUS call GetTurnDuelistVariable @@ -1021,19 +1212,265 @@ CheckIfActiveCardParalyzedOrAsleep: ; 4918 (1:4918) jr z, .asleep or a ret - .paralyzed ldtx hl, UnableDueToParalysisText jr .return_with_status_condition - .asleep ldtx hl, UnableDueToSleepText - .return_with_status_condition scf ret - INCROM $4933, $4b60 +; this handles drawing a card at the beginning of the turn among other things +Func_4933: ; 4933 (1:4933) + ld a, $01 + push hl + push de + push bc + ld [wcbe8], a + xor a + ld [wcbe9], a + ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK + call GetTurnDuelistVariable + ld a, DECK_SIZE + sub [hl] + ld hl, wcbe8 + cp [hl] + jr nc, .has_cards_left + ld [hl], a +.has_cards_left + ld a, [wcac2] + cp $07 + jr z, .asm_495f + cp $09 + jr z, .asm_495f + call EmptyScreen + call Func_4a97 +.asm_495f + ld a, $07 + ld [wcac2], a + call Func_49ca + ld a, [wcbe8] + or a + jr nz, .can_draw + ldtx hl, NoCardsInDeckCannotDraw + call DrawWideTextBox_WaitForInput + jr .done +.can_draw + ld l, a + ld h, 0 + call LoadTxRam3 + ldtx hl, DrawCardsFromTheDeck + call DrawWideTextBox_PrintText + call EnableLCD +.asm_4984 + call Func_49a8 + ld hl, wcbe9 + inc [hl] + call Func_49ed + ld a, [wcbe9] + ld hl, wcbe8 + cp [hl] + jr c, .asm_4984 + ld c, 30 +.asm_4999 + call DoFrame + call Func_67b2 + jr c, .done + dec c + jr nz, .asm_4999 +.done + pop bc + pop de + pop hl + ret +; 0x49a8 + +Func_49a8: ; 49a8 (1:49a8) + call Func_3b21 + ld e, $56 + ldh a, [hWhoseTurn] + cp PLAYER_TURN + jr z, .asm_49b5 + ld e, $57 +.asm_49b5 + ld a, e + call Func_3b6a +.asm_49b9 + call DoFrame + call Func_67b2 + jr c, .asm_49c6 + call Func_3b52 + jr c, .asm_49b9 +.asm_49c6 + call Func_3b31 + ret +; 0x49ca + +Func_49ca: ; 49ca (1:49ca) + call LoadDuelDrawCardsScreenTiles + ld hl, $4a35 + call WriteDataBlocksToBGMap0 + ld a, [wConsole] + cp CONSOLE_CGB + jr nz, .not_cgb + call BankswitchVRAM1 + ld hl, $4a6e + call WriteDataBlocksToBGMap0 + call BankswitchVRAM0 +.not_cgb + call Func_49ed.player_turn + call Func_49ed.opponent_turn + ret +; 0x49ed + +Func_49ed: ; 49ed (1:49ed) + ldh a, [hWhoseTurn] + cp PLAYER_TURN + jr nz, .opponent_turn +.player_turn + ld a, [wPlayerNumberOfCardsInHand] + ld hl, wcbe9 + add [hl] + ld d, a + ld a, DECK_SIZE + ld hl, wPlayerNumberOfCardsNotInDeck + sub [hl] + ld hl, wcbe9 + sub [hl] + ld e, a + ld a, d + lb bc, 16, 10 + call $65b7 + ld a, e + lb bc, 10, 10 + jp $65b7 +.opponent_turn + ld a, [wOpponentNumberOfCardsInHand] + ld hl, wcbe9 + add [hl] + ld d, a + ld a, DECK_SIZE + ld hl, wOpponentNumberOfCardsNotInDeck + sub [hl] + ld hl, wcbe9 + sub [hl] + ld e, a + ld a, d + lb bc, 5, 3 + call $65b7 + ld a, e + lb bc, 11, 3 + jp $65b7 +; 0x4a35 + + INCROM $4a35, $4a97 + +Func_4a97: ; 4a97 (1:4a97) + call LoadDuelHUDTiles + ld de, wDefaultText + push de + call CopyPlayerName + lb de, 0, 11 + call Func_22ae + pop hl + call Func_21c5 + ld bc, $5 + call Func_3e10 + ld de, wDefaultText + push de + call CopyOpponentName + pop hl + call Func_23c1 + push hl + add SCREEN_WIDTH + ld d, a + ld e, 0 + call Func_22ae + pop hl + call Func_21c5 + ld a, [wOpponentPortrait] + ld bc, $d01 + call Func_3e2a + call DrawDuelHorizontalSeparator + ret +; 0x4ad6 + +Func_4ad6: ; 4ad6 (1:4ad6) + lb de, 8, 8 + call Func_4ae9 + call SwapTurn + lb de, 1, 1 + call Func_4ae9 + call SwapTurn + ret +; 0x4ae9 + +Func_4ae9: ; 4ae9 (1:4ae9) + call $5f4a + ld hl, $7b + call Func_2c1b + call $5f50 + ld c, e + ld a, d + add $07 + ld b, a + inc a + inc a + ld d, a + call CountPrizes + call .asm_4b22 + inc e + inc c + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + ld hl, $7d + or a + jr nz, .pkmn_in_play_area + ld hl, $7c +.pkmn_in_play_area + dec d + call Func_2c1b + inc e + inc d + inc c + ld a, DUELVARS_NUMBER_OF_CARDS_NOT_IN_DECK + call GetTurnDuelistVariable + ld a, DECK_SIZE + sub [hl] +.asm_4b22 + call $65b7 + ld hl, $7e + call Func_2c1b + ret +; 0x4b2c + +; display the animation of the player drawing the card at hTempCardIndex_ff98 +DisplayPlayerDrawCardScreen: ; 4b2c (1:4b2c) + ldtx hl, YouDrewText + ldh a, [hTempCardIndex_ff98] + call LoadCardDataToBuffer1_FromDeckIndex + call _DisplayPlayerDrawCardScreen + ret +; 0x4b38 + +Func_4b38: ; 4b38 (1:4b38) + ld a, [wDuelTempList] + cp $ff + ret z + call DrawCardListScreenLayout + call CountCardsInDuelTempList ; list length + ld hl, CardListParameters ; other list params + lb de, 0, 0 ; initial page scroll offset, initial item (in the visible page) + call PrintCardListItems + ldtx hl, TheCardYouReceivedText + lb de, 1, 1 + call Func_22ae + call PrintTextNoDelay + ldtx hl, YouReceivedTheseCardsText + call DrawWideTextBox_WaitForInput + ret +; 0x4b60 Func_4b60: ; 4b60 (1:4b60) call $7107 @@ -1042,12 +1479,12 @@ Func_4b60: ; 4b60 (1:4b60) call SwapTurn call $4e84 call $4d97 - ldh [hffa0], a + ldh [hTemp_ffa0], a call SwapTurn call $4d97 call SwapTurn ld c, a - ldh a, [hffa0] + ldh a, [hTemp_ffa0] ld b, a and c jr nz, .asm_4bd0 @@ -1102,7 +1539,7 @@ Func_4b60: ; 4b60 (1:4b60) ldtx hl, PlacingThePrizesText call DrawWideTextBox_WaitForInput call Func_0f58 - ld a, [wcc08] + ld a, [wDuelInitialPrizes] ld l, a ld h, 0 call LoadTxRam3 @@ -1161,7 +1598,6 @@ Func_4b60: ; 4b60 (1:4b60) ret ; 0x4c77 - INCROM $4c77, $4cd5 ; Select Basic Pokemon From Hand @@ -1209,7 +1645,7 @@ Func_4cd5: ; 4cd5 (1:4cd5) ldtx hl, ChooseBasicPkmnToPlaceInArenaText call DrawWideTextBox_WaitForInput ld a, $1 - call $51e7 + call DoPracticeDuelAction .asm_4d28 xor a ld hl, $006e @@ -1218,7 +1654,7 @@ Func_4cd5: ; 4cd5 (1:4cd5) ldh a, [hTempCardIndex_ff98] call LoadCardDataToBuffer1_FromDeckIndex ld a, $2 - call $51e7 + call DoPracticeDuelAction jr c, .asm_4d28 ldh a, [hTempCardIndex_ff98] call PutHandPokemonCardInPlayArea @@ -1234,13 +1670,13 @@ Func_4cd5: ; 4cd5 (1:4cd5) ldtx hl, ChooseUpTo5BasicPkmnToPlaceOnBenchText call Func_2c73 ld a, $3 - call $51e7 + call DoPracticeDuelAction .asm_4d5f ld a, $1 ld hl, $006f call $5502 jr c, .asm_4d8e - ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable cp MAX_PLAY_AREA_POKEMON jr nc, .asm_4d86 @@ -1250,7 +1686,7 @@ Func_4cd5: ; 4cd5 (1:4cd5) ld hl, $0061 call $4b31 ld a, $5 - call $51e7 + call DoPracticeDuelAction jr .asm_4d5f .asm_4d86 @@ -1260,17 +1696,1615 @@ Func_4cd5: ; 4cd5 (1:4cd5) .asm_4d8e ld a, $4 - call $51e7 + call DoPracticeDuelAction jr c, .asm_4d5f or a ret ; 0x4d97 + INCROM $4d97, $4e40 - INCROM $4d97, $5aeb +Func_4e40: ; 4e40 (1:4e40) + call CreateHandCardList + call EmptyScreen + call LoadDuelCardSymbolTiles + lb de, 0, 0 + lb bc, 20, 13 + call DrawRegularTextBox + call CountCardsInDuelTempList ; list length + ld hl, CardListParameters ; other list params + lb de, 0, 0 ; initial page scroll offset, initial item (in the visible page) + call PrintCardListItems + ldtx hl, DuelistHandText + lb de, 1, 1 + call Func_22ae + call PrintTextNoDelay + call EnableLCD + ret +; 0x4e6e + + INCROM $4e6e, $4f9d -Func_5aeb: ; 5aeb (1:5aeb) - INCROM $5aeb, $6785 +; draw the main scene during a duel, except the contents of the bottom text box, +; which depend on the type of duelist holding the turn. +; includes the background, both arena Pokemon, and both HUDs. +DrawDuelMainScene: ; 4f9d (1:4f9d) + ld a, DUELVARS_DUELIST_TYPE + call GetTurnDuelistVariable + cp DUELIST_TYPE_PLAYER + jr z, .draw + ldh a, [hWhoseTurn] + push af + ld a, PLAYER_TURN + ldh [hWhoseTurn], a + call .draw + pop af + ldh [hWhoseTurn], a + ret +.draw +; first, load the graphics and draw the background scene + ld a, [wcac2] + cp $01 + ret z + call ZeroObjectPositionsAndToggleOAMCopy + call EmptyScreen + call LoadDuelHUDTiles + ld a, $01 + ld [wcac2], a + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + ld de, v0Tiles1 + $50 tiles + call LoadPlayAreaCardGfx + call SetBGP7OrSGB2ToCardPalette + call SwapTurn + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + ld de, v0Tiles1 + $20 tiles + call LoadPlayAreaCardGfx + call SetBGP6OrSGB3ToCardPalette + call FlushAllPalettesOrSendPal23Packet + call SwapTurn +; next, draw the Pokemon in the arena +;.place_player_arena_pkmn + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + cp -1 + jr z, .place_opponent_arena_pkmn + ld a, $d0 ; v0Tiles1 + $50 tiles + lb hl, 6, 1 + lb de, 0, 5 + lb bc, 8, 6 + call FillRectangle + call ApplyBGP7OrSGB2ToCardImage +.place_opponent_arena_pkmn + call SwapTurn + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + cp -1 + jr z, .place_other_elements + ld a, $a0 ; v0Tiles1 + $20 tiles + lb hl, 6, 1 + lb de, 12, 1 + lb bc, 8, 6 + call FillRectangle + call ApplyBGP6OrSGB3ToCardImage +.place_other_elements + call SwapTurn + ld hl, DuelEAndHPTileData + call WriteDataBlocksToBGMap0 + call DrawDuelHorizontalSeparator + call DrawDuelHUDs + call DrawWideTextBox + call EnableLCD + ret +; 0x503a + +; draws the main elements of the main duel interface, including HUDs, HPs, card names +; and color symbols, attached cards, and other information, of both duelists. +DrawDuelHUDs: ; 503a (1:503a) + ld a, DUELVARS_DUELIST_TYPE + call GetTurnDuelistVariable + cp DUELIST_TYPE_PLAYER + jr z, .draw_hud + ldh a, [hWhoseTurn] + push af + ld a, PLAYER_TURN + ldh [hWhoseTurn], a + call .draw_hud + pop af + ldh [hWhoseTurn], a + ret +.draw_hud + lb de, 1, 11 ; coordinates for player's arena card name and info icons + lb bc, 11, 8 ; coordinates for player's attached energies and HP bar + call DrawDuelHUD + lb bc, 8, 5 + ld a, DUELVARS_ARENA_CARD_STATUS + call GetTurnDuelistVariable + call CheckPrintCnfSlpPrz + inc c + call CheckPrintPoisoned + inc c + call CheckPrintDoublePoisoned + call SwapTurn + lb de, 7, 0 ; coordinates for opponent's arena card name and info icons + lb bc, 3, 1 ; coordinates for opponent's attached energies and HP bar + call GetNonTurnDuelistVariable + call DrawDuelHUD + lb bc, 11, 6 + ld a, DUELVARS_ARENA_CARD_STATUS + call GetTurnDuelistVariable + call CheckPrintCnfSlpPrz + dec c + call CheckPrintPoisoned + dec c + call CheckPrintDoublePoisoned + call SwapTurn + ret +; 0x5093 + +DrawDuelHUD: ; 5093 (1:5093) + ld hl, wcbc9 + ld [hl], b + inc hl + ld [hl], c ; save coordinates for the HP bar + push de ; save coordinates for the arena card name + ld d, 1 ; opponent's info icons start in the second tile to the right + ld a, e + or a + jr z, .go + ld d, 15 ; player's info icons start in the 15th tile to the right +.go + push de + pop bc + + ; print the Pkmn icon along with the no. of play area Pokemon + ld a, LOW("<PKMN_ICON>") + call WriteByteToBGMap0 + inc b + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + add LOW("<0>") - 1 + call WriteByteToBGMap0 + inc b + + ; print the Prize icon along with the no. of prizes yet to draw + ld a, LOW("<PRIZE_ICON>") + call WriteByteToBGMap0 + inc b + call CountPrizes + add LOW("<0>") + call WriteByteToBGMap0 + + ; print the arena Pokemon card name and level text + pop de + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + cp -1 + ret z + call LoadCardDataToBuffer1_FromDeckIndex + push de + ld a, 32 + call CopyCardNameAndLevel + ld [hl], TX_END + + ; print the arena Pokemon card color symbol just before the name + pop de + ld a, e + or a + jr nz, .print_color_icon + ld hl, wDefaultText + call Func_23c1 + add SCREEN_WIDTH + ld d, a +.print_color_icon + call Func_22ae + ld hl, wDefaultText + call Func_21c5 + push de + pop bc + call GetArenaCardColor + inc a ; TX_SYMBOL color tiles start at 1 + dec b ; place the color symbol one tile to the left of the start of the card's name + call JPWriteByteToBGMap0 + + ; print attached energies + ld hl, wcbc9 + ld b, [hl] + inc hl + ld c, [hl] + lb de, 9, PLAY_AREA_ARENA + call PrintPlayAreaCardAttachedEnergies + + ; print HP bar + ld a, DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + call LoadCardDataToBuffer1_FromDeckIndex + ld a, [wLoadedCard1HP] + ld d, a ; max HP + ld a, DUELVARS_ARENA_CARD_HP + call GetTurnDuelistVariable + ld e, a ; cur HP + call DrawHPBar + ld hl, wcbc9 + ld b, [hl] + inc hl + ld c, [hl] + inc c + call BCCoordToBGMap0Address + push de + ld hl, wDefaultText + ld b, HP_BAR_LENGTH / 2 ; first row of the HP bar + call SafeCopyDataHLtoDE + pop de + ld hl, BG_MAP_WIDTH + add hl, de + ld e, l + ld d, h + ld hl, wDefaultText + HP_BAR_LENGTH / 2 + ld b, HP_BAR_LENGTH / 2 ; second row of the HP bar + call SafeCopyDataHLtoDE + + ; print number of attached Pluspower and Defender with respective icon, if any + ld hl, wcbc9 + ld a, [hli] + add 6 + ld b, a + ld c, [hl] + inc c + ld a, DUELVARS_ARENA_CARD_ATTACHED_PLUSPOWER + call GetTurnDuelistVariable + or a + jr z, .check_defender + ld a, LOW("<PLUSPOWER>") + call WriteByteToBGMap0 + inc b + ld a, [hl] ; number of attached Pluspower + add LOW("<0>") + call WriteByteToBGMap0 + dec b +.check_defender + ld a, DUELVARS_ARENA_CARD_ATTACHED_DEFENDER + call GetTurnDuelistVariable + or a + jr z, .done + inc c + ld a, LOW("<DEFENDER>") + call WriteByteToBGMap0 + inc b + ld a, [hl] ; number of attached Defender + add LOW("<0>") + call WriteByteToBGMap0 +.done + ret +; 0x516f + +; draws an horizonal line that separates the arena side of each duelist +; also colorizes the line on CGB +DrawDuelHorizontalSeparator: ; 516f (1:516f) + ld hl, DuelHorizontalSeparatorTileData + call WriteDataBlocksToBGMap0 + ld a, [wConsole] + cp CONSOLE_CGB + ret nz + call BankswitchVRAM1 + ld hl, DuelHorizontalSeparatorCGBPalData + call WriteDataBlocksToBGMap0 + call BankswitchVRAM0 + ret +; 0x5188 + +DuelEAndHPTileData: ; 5188 (1:5188) +; x, y, tiles[], 0 + db 1, 1, LOW("<E>"), 0 + db 1, 2, LOW("<HP>"), 0 + db 9, 8, LOW("<E>"), 0 + db 9, 9, LOW("<HP>"), 0 + db $ff +; 0x5199 + +DuelHorizontalSeparatorTileData: ; 5199 (1:5199) +; x, y, tiles[], 0 + db 0, 4, $37, $37, $37, $37, $37, $37, $37, $37, $37, $31, $32, 0 + db 9, 5, $33, $34, 0 + db 9, 6, $33, $34, 0 + db 9, 7, $35, $36, $37, $37, $37, $37, $37, $37, $37, $37, $37, 0 + db $ff +; 0x51c0 + +DuelHorizontalSeparatorCGBPalData: ; 51c0 (1:51c0) +; x, y, tiles[], 0 + db 0, 4, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, 0 + db 9, 5, $02, $02, 0 + db 9, 6, $02, $02, 0 + db 9, 7, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, 0 + db $ff +; 0x51e7 + +; if this is a practice duel, execute the practice duel action at wPracticeDuelAction +DoPracticeDuelAction: ; 51e7 (1:51e7) + ld [wPracticeDuelAction], a + ld a, [wIsPracticeDuel] + or a + ret z + ld a, [wPracticeDuelAction] + ld hl, PracticeDuelActionTable + jp JumpToFunctionInTable +; 0x51f8 + +PracticeDuelActionTable:: ; 51f8 (1:51f8) + dw $0000 + dw Func_520e + dw Func_521a + dw Func_522a + dw Func_5236 + dw Func_5245 + dw Func_5256 + dw Func_5278 + dw Func_5284 + dw Func_529b + dw Func_52b0 +; 0x520e + +Func_520e: ; 520e (1:520e) + call Func_4e40 + call EnableLCD + ldtx hl, Text01a4 + jp Func_52bc +; 0x521a + +Func_521a: ; 521a (1:521a) + ld a, [wLoadedCard1ID] + cp GOLDEEN + ret z + ldtx hl, Text01a5 + ldtx de, DrMasonText + scf + jp Func_52bc +; 0x522a + +Func_522a: ; 522a (1:522a) + call Func_4e40 + call EnableLCD + ldtx hl, Text01a6 + jp Func_52bc +; 0x5236 + +Func_5236: ; 5236 (1:5236) + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + cp 2 + ret z + ldtx hl, Text01a7 + scf + jp Func_52bc +; 0x5245 + +Func_5245: ; 5245 (1:5245) + call Func_4e40 + call EnableLCD + ld a, $ff + ld [wcc00], a + ldtx hl, Text01a8 + jp Func_52bc +; 0x5256 + +Func_5256: ; 5256 (1:5256) + call $5351 + call EnableLCD + ld a, [wDuelTurns] + ld hl, wcc00 + cp [hl] + ld [hl], a + ld a, $00 + jp nz, $5382 + ldtx de, DrMasonText + ldtx hl, Text01d9 + call Func_2c62.asm_2c67 + call YesOrNoMenu + jp $5382 +; 0x5278 + +Func_5278: ; 5278 (1:5278) + ld a, [wDuelTurns] + srl a + ld hl, $541f + call JumpToFunctionInTable + ret nc +; fallthrough + +Func_5284: ; 5284 (1:5284) + ldtx hl, Text01da + call Func_52bc + ld a, $02 + call BankswitchSRAM + ld de, $bc00 + call $66ff + xor a + call BankswitchSRAM + scf + ret +; 0x529b + +Func_529b: ; 529b (1:529b) + ld a, [wDuelTurns] + cp 7 + jr z, .asm_52a4 + or a + ret +.asm_52a4 + call $5351 + call EnableLCD + ld hl, $5346 + jp $5396 +; 0x52b0 + +Func_52b0: ; 52b0 (1:52b0) + ldh a, [hTempPlayAreaLocationOffset_ff9d] + cp PLAY_AREA_BENCH_1 + ret z + call $5fd9 + ldtx hl, Text01d7 + scf +; fallthrough + +Func_52bc: ; 52bc (1:52bc) + push af + ldtx de, DrMasonText + call Func_2c62 + pop af + ret +; 0x52c5 + + INCROM $52c5, $5550 + +; draw the turn holder's discard pile screen +OpenDiscardPileScreen: ; 5550 (1:5550) + call CreateDiscardPileCardList + jr c, .discard_pile_empty + call DrawCardListScreenLayout + call SetDiscardPileScreenTexts + ld a, START + A_BUTTON + ld [wcbd6], a + call Func_55f0 + or a + ret +.discard_pile_empty + ldtx hl, TheDiscardPileHasNoCardsText + call DrawWideTextBox_WaitForInput + scf + ret +; 0x556d + +; set wCardListHeaderText and SetCardListInfoBoxText to the text +; that correspond to the Discard Pile screen +SetDiscardPileScreenTexts: ; 556d (1:556d) + ldtx de, YourDiscardPileText + ldh a, [hWhoseTurn] + cp PLAYER_TURN + jr z, .got_header_text + ldtx de, OpponentsDiscardPileText +.got_header_text + ldtx hl, ChooseTheCardYouWishToExamineText + call SetCardListHeaderText + ret +; 0x5580 + +SetCardListHeaderText: ; 5580 (1:5580) + ld a, e + ld [wCardListHeaderText], a + ld a, d + ld [wCardListHeaderText + 1], a +; fallthrough + +SetCardListInfoBoxText: ; 5588 (1:5588) + ld a, l + ld [wCardListInfoBoxText], a + ld a, h + ld [wCardListInfoBoxText + 1], a + ret +; 0x5591 + +Func_5591: ; 5591 (1:5591) + call DrawCardListScreenLayout + ld a, $02 + ld [wcbde], a + ret +; 0x559a + +; draw the layout of the screen that displays the player's Hand card list or a +; Discard Pile card list, including a bottom-right image of the current card. +; since this loads the text for the Hand card list screen, SetDiscardPileScreenTexts +; is called after this if the screen corresponds to a Discard Pile list. +DrawCardListScreenLayout: ; 559a (1:559a) + xor a + ld hl, wSelectedDuelSubMenuItem + ld [hli], a + ld [hl], a + ld [wcbdf], a + ld hl, wcbd8 + ld [hli], a + ld [hl], a + ld [wcbde], a + ld a, START + ld [wcbd6], a + ld hl, wCardListInfoBoxText + ld [hl], LOW(PleaseSelectHandText_) + inc hl + ld [hl], HIGH(PleaseSelectHandText_) + inc hl ; wCardListHeaderText + ld [hl], LOW(DuelistHandText_) + inc hl + ld [hl], HIGH(DuelistHandText_) +.draw + call ZeroObjectPositionsAndToggleOAMCopy + call EmptyScreen + call LoadDuelHUDTiles + call LoadDuelCardSymbolTiles + ; draw the surrounding box + lb de, 0, 0 + lb bc, 20, 13 + call DrawRegularTextBox + ; draw the image of the selected card + ld a, $a0 + lb hl, 6, 1 + lb de, 12, 12 + lb bc, 8, 6 + call FillRectangle + call ApplyBGP6OrSGB3ToCardImage + call Func_5744 + ld a, [wDuelTempList] + cp $ff + scf + ret z + or a + ret +; 0x55f0 + +Func_55f0: ; 55f0 (1:55f0) + call DrawNarrowTextBox + call Func_56a0 +.asm_55f6 + call CountCardsInDuelTempList ; list length + ld hl, wSelectedDuelSubMenuItem + ld e, [hl] ; initial item (in the visible page) + inc hl + ld d, [hl] ; initial page scroll offset + ld hl, CardListParameters ; other list params + call PrintCardListItems + call DrawSelectedCard + call EnableLCD +.asm_560b + call DoFrame + call Func_5690 + call HandleCardListInput + jr nc, .asm_560b + ld hl, wSelectedDuelSubMenuItem + ld [hl], e + inc hl + ld [hl], d + ldh a, [hButtonsPressed] + ld b, a + bit SELECT_F, b + jr nz, .asm_563b + bit B_BUTTON_F, b + jr nz, .asm_568c + ld a, [wcbd6] + and b + jr nz, .asm_5654 + ldh a, [hCurrentMenuItem] + call GetCardInDuelTempList_OnlyDeckIndex + call $56c2 + jr c, Func_55f0 + ldh a, [hTempCardIndex_ff98] + or a + ret +.asm_563b + ld a, [wcbdf] + or a + jr nz, .asm_560b + call SortCardsInDuelTempListByID + xor a + ld hl, wSelectedDuelSubMenuItem + ld [hli], a + ld [hl], a + ld a, $01 + ld [wcbdf], a + call EraseCursor + jr .asm_55f6 +.asm_5654 + ldh a, [hCurrentMenuItem] + call GetCardInDuelTempList + call LoadCardDataToBuffer1_FromDeckIndex + call $5762 + ldh a, [hButtonsPressed2] + bit D_UP_F, a + jr nz, .asm_566f + bit D_DOWN_F, a + jr nz, .asm_5677 + call DrawCardListScreenLayout.draw + jp Func_55f0 +.asm_566f + ldh a, [hCurrentMenuItem] + or a + jr z, .asm_5654 + dec a + jr .asm_5681 +.asm_5677 + call CountCardsInDuelTempList + ld b, a + ldh a, [hCurrentMenuItem] + inc a + cp b + jr nc, .asm_5654 +.asm_5681 + ldh [hCurrentMenuItem], a + ld hl, wSelectedDuelSubMenuItem + ld [hl], $00 + inc hl + ld [hl], a + jr .asm_5654 +.asm_568c + ldh a, [hCurrentMenuItem] + scf + ret +; 0x5690 + +Func_5690: ; 5690 (1:5690) + ldh a, [hButtonsPressed2] + and D_PAD + ret z + ld a, $01 + ldh [hffb0], a + call Func_56a0 + xor a + ldh [hffb0], a + ret +; 0x56a0 + +Func_56a0: ; 56a0 (1:56a0) + lb de, 1, 14 + call AdjustCoordinatesForWindow + call Func_22ae + ld hl, wCardListInfoBoxText + ld a, [hli] + ld h, [hl] + ld l, a + call PrintTextNoDelay + ld hl, wCardListHeaderText + ld a, [hli] + ld h, [hl] + ld l, a + lb de, 1, 1 + call Func_22ae + call PrintTextNoDelay + ret +; 0x56c2 + + INCROM $56c2, $5710 + +CardListParameters: ; 5710 (1;5710) + db 1, 3 ; cursor x, cursor y + db 4 ; item x + db $0e + db 5 ; number of items selectable without scrolling + db $0f ; cursor tile number + db $00 ; tile behind cursor + dw $5719 ; function pointer if non-0 +; 0x5719 + + INCROM $5719, $5744 + +Func_5744: ; 5744 (1:5744) + ld hl, wcbd8 + jp CallIndirect +; 0x574a + + INCROM $574a, $576a + +Func_576a: ; 576a (1:576a) + ld a, B_BUTTON + ld [wcbd7], a + ld a, $01 + jr Func_5779 + +Func_5773: ; 5773 (1:5773) + ld a, B_BUTTON + ld [wcbd7], a + xor a +; fallthrough + +Func_5779: ; 5779 (1:5779) + ld [wcbd1], a + call ZeroObjectPositionsAndToggleOAMCopy + call EmptyScreen + call Func_3b31 + call LoadDuelCardSymbolTiles + ld de, v0Tiles1 + $20 tiles + call LoadLoaded1CardGfx + call SetOBP1OrSGB3ToCardPalette + call SetBGP6OrSGB3ToCardPalette + call FlushAllPalettesOrSendPal23Packet + lb de, $38, $30 ; X Position and Y Position of top-left corner + call PlaceCardImageOAM + lb de, 6, 4 + call ApplyBGP6OrSGB3ToCardImage + xor a + ld [wCardPageNumber], a +.asm_57a7 + call Func_5898 + jr c, .asm_57cc + call EnableLCD +.asm_57af + call DoFrame + ldh a, [hButtonsPressed2] + ld b, a + ld a, [wcbd7] + and b + jr nz, .asm_57cc + ldh a, [hButtonsPressed] + and START + A_BUTTON + jr nz, .asm_57a7 + ldh a, [hButtonsPressed] + and D_RIGHT + D_LEFT + jr z, .asm_57af + call Func_57cd + jr .asm_57af +.asm_57cc + ret +; 0x57cd + +Func_57cd: ; 57cd (1:57cd) + bit D_LEFT_F, a + jr nz, .left +;.right + call Func_5898 + call c, Func_589c + ret +.left + call Func_5892 + call c, Func_589c + ret +; 0x57df + + INCROM $57df, $5892 + +Func_5892: ; 5892 (1:5892) + call Func_5911 + jr nc, Func_589c + ret + +Func_5898: ; 5898 (1:5898) + call Func_58e2 + ret c +; fallthrough + +Func_589c: ; 589c (1:589c) + ld a, [wCardPageNumber] + ld hl, CardPagePointerTable + call JumpToFunctionInTable + call EnableLCD + or a + ret +; 0x58aa + +; load the tiles and palette of the card selected in card list screen +DrawSelectedCard: ; 58aa (1:58aa) + ldh a, [hCurrentMenuItem] + call GetCardInDuelTempList + call LoadCardDataToBuffer1_FromCardID + ld de, v0Tiles1 + $20 tiles + call LoadLoaded1CardGfx + ld de, $c0c ; useless + call SetBGP6OrSGB3ToCardPalette + call FlushAllPalettesOrSendPal23Packet + ret +; 0x58c2 + +CardPagePointerTable: ; 58c2 (1:58c2) + dw DrawDuelMainScene + dw $5b7d ; CARDPAGE_POKEMON_OVERVIEW + dw $5d1f ; CARDPAGE_POKEMON_MOVE1_1 + dw $5d27 ; CARDPAGE_POKEMON_MOVE1_2 + dw $5d2f ; CARDPAGE_POKEMON_MOVE2_1 + dw $5d37 ; CARDPAGE_POKEMON_MOVE2_2 + dw $5d54 ; CARDPAGE_POKEMON_DESCRIPTION + dw DrawDuelMainScene + dw DrawDuelMainScene + dw $5e28 ; CARDPAGE_ENERGY + dw $5e28 ; CARDPAGE_ENERGY + 1 + dw DrawDuelMainScene + dw DrawDuelMainScene + dw $5e1c ; CARDPAGE_TRAINER_1 + dw $5e22 ; CARDPAGE_TRAINER_2 + dw DrawDuelMainScene +; 0x58e2 + +Func_58e2: ; 58e2 (1:58e2) + ld a, [wCardPageNumber] + or a + jr nz, .asm_58ff + ld a, [wLoadedCard1Type] + ld b, a + ld a, CARDPAGE_ENERGY + bit TYPE_ENERGY_F, b + jr nz, .set_card_page_nc + ld a, CARDPAGE_TRAINER_1 + bit TYPE_TRAINER_F, b + jr nz, .set_card_page_nc + ld a, CARDPAGE_POKEMON_OVERVIEW +.set_card_page_nc + ld [wCardPageNumber], a + or a + ret +.asm_58ff + ld hl, wCardPageNumber + inc [hl] + ld a, [hl] + call Func_5930 + jr c, .set_card_page_c + or a + ret nz + jr .asm_58ff +.set_card_page_c + ld [wCardPageNumber], a + ret +; 0x5911 + +Func_5911: ; 5911 (1:5911) + ld hl, wCardPageNumber + dec [hl] + ld a, [hl] + call Func_5930 + jr c, .asm_591f + or a + ret nz + jr Func_5911 +.asm_591f + ld [wCardPageNumber], a +.asm_5922 + call Func_5930 + or a + jr nz, .asm_592e + ld hl, wCardPageNumber + dec [hl] + jr .asm_5922 +.asm_592e + scf + ret +; 0x5930 + +Func_5930: ; 5930 (1:5930) + ld hl, CardPagePointerTable2 + jp JumpToFunctionInTable +; 0x5936 + +CardPagePointerTable2: ; 5936 (1:5936) + dw $5956 + dw $595a ; CARDPAGE_POKEMON_OVERVIEW + dw $595e ; CARDPAGE_POKEMON_MOVE1_1 + dw $5963 ; CARDPAGE_POKEMON_MOVE1_2 + dw $5968 ; CARDPAGE_POKEMON_MOVE2_1 + dw $596d ; CARDPAGE_POKEMON_MOVE2_2 + dw $595a ; CARDPAGE_POKEMON_DESCRIPTION + dw $5973 + dw $5977 + dw $597b ; CARDPAGE_ENERGY + dw $597f ; CARDPAGE_ENERGY + 1 + dw $5984 + dw $5988 + dw $597b ; CARDPAGE_TRAINER_1 + dw $597f ; CARDPAGE_TRAINER_2 + dw $598c +; 0x5956 + + INCROM $5956, $5990 + +ZeroObjectPositionsAndToggleOAMCopy: ; 5990 (1:5990) + call ZeroObjectPositions + ld a, $01 + ld [wVBlankOAMCopyToggle], a + ret +; 0x5999 + +; place OAM for a 8x6 image, using object size 8x16 and obj palette 1. +; d, e: X Position and Y Position of the top-left corner. +; starting tile number is $a0 (v0Tiles1 + $20 tiles). +; used to draw the image of a card in the check card screens. +PlaceCardImageOAM: ; 5999 (1:5999) + call Set_OBJ_8x16 + ld l, $a0 + ld c, 8 ; number of rows +.next_column + ld b, 3 ; number of columns + push de +.next_row + push bc + ld c, l ; tile number + ld b, 1 ; attributes (palette) + call SetOneObjectAttributes + pop bc + inc l + inc l ; next 8x16 tile + ld a, 16 + add e ; Y Position += 16 (next 8x16 row) + ld e, a + dec b + jr nz, .next_row + pop de + ld a, 8 + add d ; X Position += 8 (next 8x16 column) + ld d, a + dec c + jr nz, .next_column + ld a, $01 + ld [wVBlankOAMCopyToggle], a + ret +; 0x59c2 + +; given the deck index of a card in the play area (i.e. -1 indicates empty) +; load the graphics (tiles and palette) of the card to de +LoadPlayAreaCardGfx: ; 59c2 (1:59c2) + cp -1 + ret z + push de + call LoadCardDataToBuffer1_FromDeckIndex + pop de +; fallthrough + +; load the graphics (tiles and palette) of the card loaded in wLoadedCard1 to de +LoadLoaded1CardGfx: ; 59ca (1:59ca) + ld hl, wLoadedCard1Gfx + ld a, [hli] + ld h, [hl] + ld l, a + lb bc, $30, TILE_SIZE + call LoadCardGfx + ret +; 0x59d7 + +SetBGP7OrSGB2ToCardPalette: ; 59d7 (1:59d7) + ld a, [wConsole] + or a ; CONSOLE_DMG + ret z + cp CONSOLE_SGB + jr z, .sgb + ld a, $07 ; CGB BG Palette 7 + call CopyCGBCardPalette + ret +.sgb + ld hl, wCardPalette + ld de, wTempSGBPacket + 1 ; PAL Packet color #0 (PAL23's SGB2) + ld b, CGB_PAL_SIZE +.copy_pal_loop + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .copy_pal_loop + ret +; 0x59f5 + +SetBGP6OrSGB3ToCardPalette: ; 59f5 (1:59f5) + ld a, [wConsole] + or a ; CONSOLE_DMG + ret z + cp CONSOLE_SGB + jr z, SetSGB3ToCardPalette + ld a, $06 ; CGB BG Palette 6 + call CopyCGBCardPalette + ret + +SetSGB3ToCardPalette: ; 5a04 (1:5a04) + ld hl, wCardPalette + 2 + ld de, wTempSGBPacket + 9 ; Pal Packet color #4 (PAL23's SGB3) + ld b, 6 + jr SetBGP7OrSGB2ToCardPalette.copy_pal_loop +; 0x5a0e + +SetOBP1OrSGB3ToCardPalette: ; 5a0e (1:5a0e) + ld a, $e4 + ld [wOBP0], a + ld a, [wConsole] + or a ; CONSOLE_DMG + ret z + cp CONSOLE_SGB + jr z, SetSGB3ToCardPalette + ld a, $09 ; CGB Object Palette 1 +; fallthrough + +CopyCGBCardPalette: ; 5a1e (1:5a1e) + add a + add a + add a ; a *= CGB_PAL_SIZE + ld e, a + ld d, $00 + ld hl, wBackgroundPalettesCGB ; wObjectPalettesCGB - 8 palettes + add hl, de + ld de, wCardPalette + ld b, CGB_PAL_SIZE +.copy_pal_loop + ld a, [de] + inc de + ld [hli], a + dec b + jr nz, .copy_pal_loop + ret +; 0x5a34 + +FlushAllPalettesOrSendPal23Packet: ; 5a34 (1:5a34) + ld a, [wConsole] + or a ; CONSOLE_DMG + ret z + cp CONSOLE_SGB + jr z, .sgb + call SetFlushAllPalettes + ret +.sgb +; sgb PAL23, 1 ; sgb_command, length +; rgb 28, 28, 24 +; colors 1-7 carried over + ld a, PAL23 << 3 + 1 + ld hl, wTempSGBPacket + ld [hli], a + ld a, $9c + ld [hli], a + ld a, $63 + ld [hld], a + dec hl + xor a + ld [wTempSGBPacket + $f], a + call SendSGB + ret +; 0x5a56 + +ApplyBGP6OrSGB3ToCardImage: ; 5a56 (1:5a56) + ld a, [wConsole] + or a ; CONSOLE_DMG + ret z + cp CONSOLE_SGB + jr z, .sgb + ld a, $06 ; CGB BG Palette 6 + call ApplyCardCGBAttributes + ret +.sgb + ld a, 3 << 0 + 3 << 2 ; Color Palette Designation +; fallthrough + +SendCardAttrBlkPacket: ; 5a67 (1:5a67) + call CreateCardAttrBlkPacket + call SendSGB + ret +; 0x5a6e + +ApplyBGP7OrSGB2ToCardImage: ; 5a6e (1:5a6e) + ld a, [wConsole] + or a ; CONSOLE_DMG + ret z + cp CONSOLE_SGB + jr z, .sgb + ld a, $07 ; CGB BG Palette 7 + call ApplyCardCGBAttributes + ret +.sgb + ld a, 2 << 0 + 2 << 2 ; Color Palette Designation + jr SendCardAttrBlkPacket +; 0x5a81 + +Func_5a81: ; 5a81 (1:5a81) + ld a, [wConsole] + or a ; CONSOLE_DMG + ret z + cp CONSOLE_SGB + jr z, .sgb + lb de, 0, 5 + call ApplyBGP7OrSGB2ToCardImage + lb de, 12, 1 + call ApplyBGP6OrSGB3ToCardImage + ret +.sgb + ld a, 2 << 0 + 2 << 2 ; Data Set #1: Color Palette Designation + lb de, 0, 5 ; Data Set #1: X, Y + call CreateCardAttrBlkPacket + push hl + ld a, 2 + ld [wTempSGBPacket + 1], a ; set number of data sets to 2 + ld hl, wTempSGBPacket + 8 + ld a, 3 << 0 + 3 << 2 ; Data Set #2: Color Palette Designation + lb de, 12, 1 ; Data Set #2: X, Y + call CreateCardAttrBlkPacket_DataSet + pop hl + call SendSGB + ret +; 0x5ab5 + +CreateCardAttrBlkPacket: ; 5ab5 (1:5ab5) +; sgb ATTR_BLK, 1 ; sgb_command, length +; db 1 ; number of data sets + ld hl, wTempSGBPacket + push hl + ld [hl], ATTR_BLK << 3 + 1 + inc hl + ld [hl], 1 + inc hl + call CreateCardAttrBlkPacket_DataSet + xor a + ld [hli], a + ld [hli], a + ld [hli], a + ld [hli], a + pop hl + ret +; 0x5ac9 + +CreateCardAttrBlkPacket_DataSet: ; 5ac9 (1:5ac9) +; Control Code, Color Palette Designation, X1, Y1, X2, Y2 +; db ATTR_BLK_CTRL_INSIDE + ATTR_BLK_CTRL_LINE, a, d, e, d+7, e+5 ; data set 1 + ld [hl], ATTR_BLK_CTRL_INSIDE + ATTR_BLK_CTRL_LINE + inc hl + ld [hl], a + inc hl + ld [hl], d + inc hl + ld [hl], e + inc hl + ld a, 7 + add d + ld [hli], a + ld a, 5 + add e + ld [hli], a + ret +; 0x5adb + +; given the 8x6 card image with coordinates at de, fill its BGMap attributes with a +ApplyCardCGBAttributes: ; 5adb (1:5adb) + call BankswitchVRAM1 + lb hl, 0, 0 + lb bc, 8, 6 + call FillRectangle + call BankswitchVRAM0 + ret +; 0x5aeb + +; set the default game palettes for all three systems +; BGP and OBP0 on DMG +; SGB0 and SGB1 on SGB +; BGP0 to BGP5 and OBP1 on CGB +SetDefaultPalettes: ; 5aeb (1:5aeb) + ld a, [wConsole] + cp CONSOLE_SGB + jr z, .sgb + cp CONSOLE_CGB + jr z, .cgb + ld a, $e4 + ld [wOBP0], a + ld [wBGP], a + ld a, $01 ; equivalent to FLUSH_ONE + ld [wFlushPaletteFlags], a + ret +.cgb + ld a, $04 + ld [wTextBoxFrameType], a + ld de, CGBDefaultPalettes + ld hl, wBackgroundPalettesCGB + ld c, 5 palettes + call .copy_de_to_hl + ld de, CGBDefaultPalettes + ld hl, wObjectPalettesCGB + ld c, CGB_PAL_SIZE + call .copy_de_to_hl + call SetFlushAllPalettes + ret +.sgb + ld a, $04 + ld [wTextBoxFrameType], a + ld a, PAL01 << 3 + 1 + ld hl, wTempSGBPacket + push hl + ld [hli], a + ld de, Pal01Packet_Default + ld c, $0e + call .copy_de_to_hl + ld [hl], c + pop hl + call SendSGB + ret + +.copy_de_to_hl + ld a, [de] + inc de + ld [hli], a + dec c + jr nz, .copy_de_to_hl + ret +; 0x5b44 + +CGBDefaultPalettes: +; BGP0 and OBP0 + rgb 28, 28, 24 + rgb 21, 21, 16 + rgb 10, 10, 8 + rgb 0, 0, 0 +; BGP1 + rgb 28, 28, 24 + rgb 30, 29, 0 + rgb 30, 3, 0 + rgb 0, 0, 0 +; BGP2 + rgb 28, 28, 24 + rgb 0, 18, 0 + rgb 12, 11, 20 + rgb 0, 0, 0 +; BGP3 + rgb 28, 28, 24 + rgb 22, 0 ,22 + rgb 27, 7, 3 + rgb 0, 0, 0 +; BGP4 + rgb 28, 28, 24 + rgb 26, 10, 0 + rgb 28, 0, 0 + rgb 0, 0, 0 + +; first and last byte of the packet not contained here (see SetDefaultPalettes.sgb) +Pal01Packet_Default: +; SGB0 + rgb 28, 28, 24 + rgb 21, 21, 16 + rgb 10, 10, 8 + rgb 0, 0, 0 +; SGB1 + rgb 26, 10, 0 + rgb 28, 0, 0 + rgb 0, 0, 0 + +JPWriteByteToBGMap0: ; 5b7a (1:5b7a) + jp WriteByteToBGMap0 +; 0x5b7d + + INCROM $5b7d, $5e5f + +; display the animation of the player drawing the card loaded in wLoadedCard1 +; print the text at hl (which is YouDrewText) +_DisplayPlayerDrawCardScreen: ; 5e5f (1:5e5f) + push hl + call DrawLargePictureOfCard + ld a, 18 + call CopyCardNameAndLevel + ld [hl], TX_END + ld hl, 0 + call LoadTxRam2 + pop hl + call DrawWideTextBox_WaitForInput + ret +; 0x5e75 + +; draw a large picture of the card loaded in wLoadedCard1, including its image +; and a header indicating the type of card (TRAINER, ENERGY, PoKéMoN) +DrawLargePictureOfCard: ; 5e75 (1:5e75) + call ZeroObjectPositionsAndToggleOAMCopy + call EmptyScreen + call LoadDuelHUDTiles + call SetDefaultPalettes + ld a, $08 + ld [wcac2], a + call LoadCardOrDuelMenuBorderTiles + ld e, HEADER_TRAINER + ld a, [wLoadedCard1Type] + cp TYPE_TRAINER + jr z, .draw + ld e, HEADER_ENERGY + and TYPE_ENERGY + jr nz, .draw + ld e, HEADER_POKEMON +.draw + ld a, e + call LoadCardTypeHeaderTiles + ld de, v0Tiles1 + $20 tiles + call LoadLoaded1CardGfx + call SetBGP6OrSGB3ToCardPalette + call FlushAllPalettesOrSendPal23Packet + ld hl, LargeCardTileData + call WriteDataBlocksToBGMap0 + lb de, 6, 3 + call ApplyBGP6OrSGB3ToCardImage + ret +; 0x5eb7 + +LargeCardTileData: ; 5eb7 (1:5eb7) + db 5, 0, $d0, $d4, $d4, $d4, $d4, $d4, $d4, $d4, $d4, $d1, 0 ; top border + db 5, 1, $d6, $e0, $e1, $e2, $e3, $e4, $e5, $e6, $e7, $d7, 0 ; header top + db 5, 2, $d6, $e8, $e9, $ea, $eb, $ec, $ed, $ee, $ef, $d7, 0 ; header bottom + db 5, 3, $d6, $a0, $a6, $ac, $b2, $b8, $be, $c4, $ca, $d7, 0 ; image + db 5, 4, $d6, $a1, $a7, $ad, $b3, $b9, $bf, $c5, $cb, $d7, 0 ; image + db 5, 5, $d6, $a2, $a8, $ae, $b4, $ba, $c0, $c6, $cc, $d7, 0 ; image + db 5, 6, $d6, $a3, $a9, $af, $b5, $bb, $c1, $c7, $cd, $d7, 0 ; image + db 5, 7, $d6, $a4, $aa, $b0, $b6, $bc, $c2, $c8, $ce, $d7, 0 ; image + db 5, 8, $d6, $a5, $ab, $b1, $b7, $bd, $c3, $c9, $cf, $d7, 0 ; image + db 5, 9, $d6, 0 ; empty line 1 (left) + db 14, 9, $d7, 0 ; empty line 1 (right) + db 5, 10, $d6, 0 ; empty line 2 (left) + db 14, 10, $d7, 0 ; empty line 2 (right) + db 5, 11, $d2, $d5, $d5, $d5, $d5, $d5, $d5, $d5, $d5, $d3, 0 ; bottom border + db $ff +; 0x5f4a + + INCROM $5f4a, $5fdd + +; return carry if the turn holder has any Pokemon with non-zero HP in the play area. +; return how many Pokemon with non-zero HP in b. +HasAlivePokemonInPlayArea: ; 5fdd (1:5fdd) + xor a + ld [wcbd2], a + ld b, a + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + sub b + ld c, a + ld a, DUELVARS_ARENA_CARD_HP + add b + call GetTurnDuelistVariable + ld b, 0 + inc c + xor a + ld [wcbd3], a + ld [wcbd4], a + jr .next_pkmn +.loop + ld a, [hli] + or a + jr z, .next_pkmn ; jump if this play area Pokemon has 0 HP + inc b +.next_pkmn + dec c + jr nz, .loop + ld a, b + or a + ret nz + scf + ret +; 0x6008 + +OpenPlayAreaScreenForViewing: ; 6008 (1:6008) + ld a, START + A_BUTTON + jr _OpenPlayAreaScreen + +OpenPlayAreaScreenForSelection: ; 600c (1:600c) + ld a, START +; fallthrough + +_OpenPlayAreaScreen: ; 600e (1:600e) + ld [wcbd6], a + ldh a, [hTempCardIndex_ff98] + push af + ld a, [wcbd3] + or a + jr nz, .asm_6034 + xor a + ld [wSelectedDuelSubMenuItem], a + inc a + ld [wcbd3], a +.asm_6022 + call ZeroObjectPositionsAndToggleOAMCopy + call EmptyScreen + call LoadDuelCardSymbolTiles + call LoadDuelCheckPokemonScreenTiles + call $61c7 + call EnableLCD +.asm_6034 + ld hl, MenuParameters_60be + ld a, [wcbd2] + or a + jr z, .asm_6040 + ld hl, MenuParameters_60c6 +.asm_6040 + ld a, [wSelectedDuelSubMenuItem] + call InitializeMenuParameters + ld a, [wcbc8] + ld [wNumMenuItems], a +.asm_604c + call DoFrame + call $60dd + jr nc, .asm_6061 + cp $02 + jp z, $60ac + pop af + ldh [hTempCardIndex_ff98], a + ld a, [wcbd4] + jr OpenPlayAreaScreenForSelection +.asm_6061 + call HandleMenuInput + jr nc, .asm_604c + ld a, e + ld [wSelectedDuelSubMenuItem], a + ld a, [wcbd2] + add e + ld [wcbc9], a + ld a, [wcbd6] + ld b, a + ldh a, [hButtonsPressed] + and b + jr z, .asm_6091 + ld a, [wcbc9] + add DUELVARS_ARENA_CARD + call GetTurnDuelistVariable + cp -1 + jr z, .asm_6022 + call GetCardIDFromDeckIndex + call LoadCardDataToBuffer1_FromCardID + call Func_576a + jr .asm_6022 +.asm_6091 + ld a, [wcbd2] + ld c, a + ldh a, [hCurrentMenuItem] + add c + ldh [hTempPlayAreaLocationOffset_ff9d], a + ldh a, [hCurrentMenuItem] + cp $ff + jr z, .asm_60b5 + ldh a, [hTempPlayAreaLocationOffset_ff9d] + add DUELVARS_ARENA_CARD_HP + call GetTurnDuelistVariable + or a + jr nz, .asm_60ac + jr .asm_6034 +.asm_60ac + pop af + ldh [hTempCardIndex_ff98], a + ldh a, [hTempPlayAreaLocationOffset_ff9d] + ldh [hCurrentMenuItem], a + or a + ret +.asm_60b5 + pop af + ldh [hTempCardIndex_ff98], a + ldh a, [hTempPlayAreaLocationOffset_ff9d] + ldh [hCurrentMenuItem], a + scf + ret +; 0x60be + +MenuParameters_60be: ; 60be (1:60be) + db 0, 0 ; cursor x, cursor y + db 3 ; y displacement between items + db 6 ; number of items + db $0f ; cursor tile number + db $00 ; tile behind cursor + dw $60ce ; function pointer if non-0 + +MenuParameters_60c6: ; 60c6 (1:60c6) + db 0, 3 ; cursor x, cursor y + db 3 ; y displacement between items + db 6 ; number of items + db $0f ; cursor tile number + db $00 ; tile behind cursor + dw $60ce ; function pointer if non-0 + + INCROM $60ce, $63bb + +; given a card's status in a, print the Poison symbol at bc if it's poisoned +CheckPrintPoisoned: ; 63bb (1:63bb) + push af + and POISONED + jr z, .print +.poison + ld a, LOW("<POISONED>") +.print + call WriteByteToBGMap0 + pop af + ret +; 0x63c7 + +; given a card's status in a, print the Poison symbol at bc if it's double poisoned +CheckPrintDoublePoisoned: ; 63c7 (1:63c7) + push af + and DOUBLE_POISONED - POISONED + jr nz, CheckPrintPoisoned.poison ; double poison (print a second symbol) + jr CheckPrintPoisoned.print ; not double poisoned +; 0x63ce + +; given a card's status in a, print the Confusion, Sleep, or Paralysis symbol at bc +; for each of those status that is active +CheckPrintCnfSlpPrz: ; 63ce (1:63ce) + push af + push hl + push de + and CNF_SLP_PRZ + ld e, a + ld d, $00 + ld hl, .status_symbols + add hl, de + ld a, [hl] + call WriteByteToBGMap0 + pop de + pop hl + pop af + ret + +.status_symbols + ; NO_STATUS, CONFUSED, ASLEEP, PARALYZED + db LOW("< >"), LOW("<CONFUSED>"), LOW("<ASLEEP>"), LOW("<PARALYZED>") +; 0x63e6 + +; print the symbols of the attached energies of a turn holder's play area card +; input: +; - e: PLAY_AREA_* +; - b, c: where to print (x, y) +; - wAttachedEnergies and wTotalAttachedEnergies +PrintPlayAreaCardAttachedEnergies: ; 63e6 (1:63e6) + push bc + call GetPlayAreaCardAttachedEnergies + ld hl, wDefaultText + push hl + ld c, NUM_TYPES + xor a +.empty_loop + ld [hli], a + dec c + jr nz, .empty_loop + pop hl + ld de, wAttachedEnergies + lb bc, LOW("<FIRE>"), NUM_TYPES - 1 +.next_color + ld a, [de] ; energy count of current color + inc de + inc a + jr .check_amount +.has_energy + ld [hl], b + inc hl +.check_amount + dec a + jr nz, .has_energy + inc b + dec c + jr nz, .next_color + ld a, [wTotalAttachedEnergies] + cp 9 + jr c, .place_tiles + ld a, LOW("<+>") + ld [wDefaultText + 7], a +.place_tiles + pop bc + call BCCoordToBGMap0Address + ld hl, wDefaultText + ld b, NUM_TYPES + call SafeCopyDataHLtoDE + ret +; 0x6423 + + INCROM $6423, $6614 + +; input d, e: max. HP, current HP +DrawHPBar: ; 6614 (1:6614) + ld a, MAX_HP + ld c, LOW("< >") + call .fill_hp_bar ; empty bar + ld a, d + ld c, LOW("<🌕>") + call .fill_hp_bar ; fill (max. HP) with HP counters + ld a, d + sub e + ld c, LOW("<🌑>") + ; fill (max. HP - current HP) with damaged HP counters +.fill_hp_bar + or a + ret z + ld hl, wDefaultText + ld b, HP_BAR_LENGTH +.tile_loop + ld [hl], c + inc hl + dec b + ret z + sub MAX_HP / HP_BAR_LENGTH + jr nz, .tile_loop + ret +; 0x6635 + + INCROM $6635, $6785 Func_6785: ; 6785 (1:6785) call EnableSRAM @@ -1304,7 +3338,16 @@ LoadPlayerDeck: ; 6793 (1:6793) ret ; 0x67b2 - INCROM $67b2, $67be +Func_67b2: ; 67b2 (1:67b2) + ld a, [wccf2] + or a + ret z + ldh a, [hButtonsHeld] + and B_BUTTON + ret z + scf + ret +; 0x67be ; related to ai taking their turn in a duel ; called multiple times during one ai turn @@ -1378,23 +3421,23 @@ AIUseEnergyCard: ; 69a5 (1:69a5) ldh a, [hTempPlayAreaLocationOffset_ffa1] ldh [hTempPlayAreaLocationOffset_ff9d], a ld e, a - ldh a, [hffa0] + ldh a, [hTemp_ffa0] ldh [hTempCardIndex_ff98], a call PutHandCardInPlayArea - ldh a, [hffa0] + ldh a, [hTemp_ffa0] call LoadCardDataToBuffer1_FromDeckIndex - call $5e75 + call DrawLargePictureOfCard call $68e4 ld a, $1 ld [wAlreadyPlayedEnergy], a - call $4f9d + call DrawDuelMainScene ret ; 0x69c5 INCROM $69c5, $6d84 -; converts clefairy doll/mysterious fossil at specified wLoadedCard to pokemon card -ConvertTrainerCardToPokemon: +; converts clefairy doll/mysterious fossil to pokemon card +ConvertTrainerCardToPokemon: ; 6d84 (1:6d84) ld c, a ld a, [hl] cp TYPE_TRAINER @@ -1448,7 +3491,31 @@ ConvertTrainerCardToPokemon: db UNABLE_RETREAT ; CARD_DATA_RETREAT_COST ds $0d ; PKMN_CARD_DATA_LENGTH - (CARD_DATA_RETREAT_COST + 1) - INCROM $6df1, $7107 + INCROM $6df1, $70e6 + +Func_70e6: ; 70e6 (1:70e6) + xor a + ld [wAlreadyPlayedEnergy], a + ld [wcc0c], a + ld [wGotHeadsFromSandAttackOrSmokescreenCheck], a + ldh a, [hWhoseTurn] + ld [wcc05], a + ret +; 0x70f6 + +SetAllPlayAreaPokemonCanEvolve: ; 70f6 (1:70f6) + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + call GetTurnDuelistVariable + ld c, a + ld l, DUELVARS_ARENA_CARD_FLAGS_C2 +.next_pkmn_loop + res 5, [hl] + set CAN_EVOLVE_THIS_TURN_F, [hl] + inc l + dec c + jr nz, .next_pkmn_loop + ret +; 0x7107 ; initializes duel variables such as cards in deck and in hand, or Pokemon in play area ; player turn: [c200, c2ff] @@ -1503,7 +3570,7 @@ _TossCoin: ; 71ad (1:71ad) xor a ld [wcd9f], a call EmptyScreen - call Func_210f + call LoadDuelCoinTossResultTiles .asm_71c1 ld a, [wcd9f] @@ -1546,9 +3613,9 @@ _TossCoin: ; 71ad (1:71ad) ld a, [wcd9f] inc a call $65b7 - ld b, $11 + ld b, 17 ld a, $2e - call Func_06c3 + call WriteByteToBGMap0 inc b ld a, [wcd9c] call $65b7 diff --git a/src/engine/bank1c.asm b/src/engine/bank1c.asm index 005eb3f..333ef53 100644 --- a/src/engine/bank1c.asm +++ b/src/engine/bank1c.asm @@ -269,7 +269,7 @@ Func_701e9: ; 701e9 (1c:41e9) ret Func_701fe: ; 701fe (1c:41fe) - ld hl, v0BGMapTiles1 + ld hl, v0BGMap0 ld de, $000c ld a, $80 ld c, $d diff --git a/src/engine/bank2.asm b/src/engine/bank2.asm index 22435ee..e9f2868 100644 --- a/src/engine/bank2.asm +++ b/src/engine/bank2.asm @@ -43,13 +43,13 @@ Func_8d56: ; 8d56 (2:4d56) xor a ld [wTileMapFill], a call EmptyScreen - call InitSpritePositions + call ZeroObjectPositions ld a, $1 ld [wVBlankOAMCopyToggle], a - call Func_2119 - call Func_20b0 + call LoadDuelHUDTiles + call LoadDuelCardSymbolTiles call Func_8d0b - bank1call Func_5aeb + bank1call SetDefaultPalettes ld de, $3cbf call Func_2275 ret @@ -80,7 +80,7 @@ Func_8db0: ; 8db0 (2:4db0) Func_8dbc: ; 8dbc (2:4dbc) ld hl, Unknown_8de2 - call InitializeCursorParameters + call InitializeMenuParameters ldtx hl, PleaseSelectDeckText call DrawWideTextBox_PrintText .asm_8dc8 @@ -268,7 +268,7 @@ Func_8f38: ; 8f38 (2:4f38) call DisableSRAM ld l, a ld de, wDefaultText - call Func_0663 + call TwoByteNumberToText ld hl, wcfb9 ld [hl], $6 inc hl @@ -500,7 +500,7 @@ asm_90da add $e ld c, a ld a, e - call Func_06c3 + call WriteByteToBGMap0 or a ret @@ -912,7 +912,7 @@ Func_ba04: ; ba04 (2:7a04) ld [wd0a5], a xor a ld hl, $7b6e - call InitializeCursorParameters + call InitializeMenuParameters ldtx hl, PleaseSelectDeckText call DrawWideTextBox_PrintText ld a, $5 diff --git a/src/engine/bank20.asm b/src/engine/bank20.asm index 5a0367c..d2acf6a 100644 --- a/src/engine/bank20.asm +++ b/src/engine/bank20.asm @@ -66,7 +66,7 @@ Func_801a1: ; 801a1 (20:41a1) ld a, $1 call BankswitchSRAM ld hl, v0End - ld de, v0BGMapTiles1 + ld de, v0BGMap0 ld c, $20 .asm_801b4 push bc diff --git a/src/engine/bank3.asm b/src/engine/bank3.asm index 1fc8f11..1df0b19 100644 --- a/src/engine/bank3.asm +++ b/src/engine/bank3.asm @@ -11,10 +11,10 @@ LoadMap: ; c000 (3:4000) ld [wMatchStartTheme], a farcall Func_10a9b call Func_c1a4 - call InitSpritePositions + call ZeroObjectPositions xor a ld [wTileMapFill], a - call Func_2119 + call LoadDuelHUDTiles call Set_OBJ_8x8 xor a ld [wcd08], a @@ -341,7 +341,7 @@ Unknown_c27c: ; c27c (3:427c) Func_c280: ; c280 (3:4280) call Func_c228 call Func_3ca0 - call InitSpritePositions + call ZeroObjectPositions ld hl, wVBlankOAMCopyToggle inc [hl] call EnableLCD @@ -370,7 +370,7 @@ Func_c2a3: ; c2a3 (3:42a3) call Func_2275 farcall Func_12ba7 call Func_3ca0 - call InitSpritePositions + call ZeroObjectPositions ld a, $1 ld [wVBlankOAMCopyToggle], a call EnableLCD @@ -439,7 +439,7 @@ Func_c335: ; c335 (3:4335) ld [wd10d], a ld hl, wObjectPalettesCGB ld de, wd0cc - ld bc, 8 * CGB_PAL_SIZE + ld bc, 8 palettes call CopyDataHLtoDE_SaveRegisters ret @@ -450,7 +450,7 @@ Func_c34e: ; c34e (3:434e) ld [wOBP1], a ld hl, wd0cc ld de, wObjectPalettesCGB - ld bc, 8 * CGB_PAL_SIZE + ld bc, 8 palettes call CopyDataHLtoDE_SaveRegisters call SetFlushAllPalettes ret @@ -3118,8 +3118,8 @@ OWSequence_Joshua: FindEndOfBattleScript: ; e52c (3:652c) ld c, $0 - ld a, [wd0c3] - or a + ld a, [wDuelResult] + or a ; cp DUEL_WIN jr z, .player_won ld c, $2 @@ -3186,8 +3186,8 @@ Func_f580: ; f580 (3:7580) INCROM $f5b3, $fc2b Func_fc2b: ; fc2b (3:7c2b) - ld a, [wd0c3] - cp $2 + ld a, [wDuelResult] + cp 2 jr c, .asm_fc34 ld a, $2 .asm_fc34 diff --git a/src/engine/bank4.asm b/src/engine/bank4.asm index 883065a..5140705 100644 --- a/src/engine/bank4.asm +++ b/src/engine/bank4.asm @@ -2,7 +2,7 @@ Func_10000: ; 10000 (4:4000) ld a, $0 ld [wTileMapFill], a call EmptyScreen - call Func_2119 + call LoadDuelHUDTiles ld de, $307f call Func_2275 call Set_OBJ_8x8 @@ -18,7 +18,7 @@ Func_10000: ; 10000 (4:4000) .asm_10025 call Func_1288c - call InitSpritePositions + call ZeroObjectPositions ld a, $1 ld [wVBlankOAMCopyToggle], a ret @@ -155,7 +155,7 @@ BoosterPack_1031b: ; 1031b (4:431b) call Func_2c73 call DisableLCD call Func_1288c - call InitSpritePositions + call ZeroObjectPositions ld a, $1 ld [wVBlankOAMCopyToggle], a ld a, $4 @@ -434,7 +434,7 @@ Unknown_10f14: ; 10f14 (4:4f14) Func_10f2e: ; 10f2e (4:4f2e) push hl push de - ld de, $0101 + lb de, 1, 1 call Func_22ae call Func_10f4a rlca @@ -1081,7 +1081,7 @@ Unknown_1229f: ; 1229f (4:629f) ; is selected, there is no need to come back to the menu. ; the only exception is after returning from Card Pop! _GameLoop: ; 126d1 (4:66d1) - call InitSpritePositions + call ZeroObjectPositions ld hl, wVBlankOAMCopyToggle inc [hl] farcall Func_70018 diff --git a/src/engine/bank5.asm b/src/engine/bank5.asm index 5820a24..0fd6f82 100644 --- a/src/engine/bank5.asm +++ b/src/engine/bank5.asm @@ -66,7 +66,7 @@ Func_14226: ; 14226 (5:4226) ret z call LoadCardDataToBuffer1_FromDeckIndex ld a, [wLoadedCard1Type] - cp TYPE_ENERGY_FIRE + cp TYPE_ENERGY jr nc, .check_for_next_pokemon ld a, [wLoadedCard1Stage] or a diff --git a/src/engine/bank6.asm b/src/engine/bank6.asm index 18e8b98..1a85a24 100644 --- a/src/engine/bank6.asm +++ b/src/engine/bank6.asm @@ -1,4 +1,153 @@ - INCROM $18000, $186f7 +_CopyCardNameAndLevel: ; 18000 (6:4000) + push bc + push de + ld [wcd9b], 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_START + jp z, Func_18086 + ld a, [wcd9b] + 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 Func_23c1 + 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], LOW("<Lv>") + inc hl + ld a, [wLoadedCard1Level] + cp 10 + jr c, .one_digit + ld [hl], TX_SYMBOL + inc hl + ld b, LOW("<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 LOW("<0>") + ld [hl], a ; last (or only) digit + inc hl +.done + pop de + pop bc + ret +; 0x18086 + +Func_18086: ; 18086 (6:4086) + ld a, [wcd9b] + 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 +; 0x180d5 + + INCROM $180d5, $186f7 INCLUDE "data/effect_commands.asm" @@ -104,7 +253,7 @@ Func_19a12: ; 19a12 (6:5a12) ld h, [hl] ld l, a ld de, wDefaultText - call PrintTextBoxBorderLabel + call CopyText ret ; 0x19a1f @@ -159,7 +308,7 @@ Func_1a61f: ; 1a61f (6:661f) pop hl bank1call $5e5f .asm_1a680 - call Func_378a + call AssertSongFinished or a jr nz, .asm_1a680 call ResumeSong @@ -169,7 +318,7 @@ Func_1a61f: ; 1a61f (6:661f) INCROM $1a68d, $1a6cc -Func_1a6cc: ; 1a6cc (6:66cc) +CommentedOut_1a6cc: ; 1a6cc (6:66cc) ret ; 0x1a6cd diff --git a/src/engine/bank7.asm b/src/engine/bank7.asm index 156d421..725b51b 100644 --- a/src/engine/bank7.asm +++ b/src/engine/bank7.asm @@ -389,7 +389,7 @@ Func_1d078: ; 1d078 (7:5078) call $5614 ld hl, wd635 inc [hl] - call Func_378a + call AssertSongFinished or a jr nz, .asm_1d0ae farcall Func_10ab4 @@ -492,7 +492,7 @@ Func_1d306: ; 1d306 (7:5306) INCROM $1d306, $1d386 Titlescreen_1d386: ; 1d386 (7:5386) - call Func_378a + call AssertSongFinished or a jr nz, .asm_1d39f call DisableLCD diff --git a/src/engine/booster_packs.asm b/src/engine/booster_packs.asm index 98692d8..fc24355 100644 --- a/src/engine/booster_packs.asm +++ b/src/engine/booster_packs.asm @@ -590,4 +590,4 @@ LoadRarityAmountsToWram: ; 1e4ba (7:64ba) INCLUDE "data/booster_packs.asm" - INCROM $1e640, $20000
\ No newline at end of file + INCROM $1e640, $20000 diff --git a/src/engine/home.asm b/src/engine/home.asm index 4c5ecfa..c416abe 100644 --- a/src/engine/home.asm +++ b/src/engine/home.asm @@ -51,7 +51,7 @@ Start: ; 0150 (0:0150) pop af ld [wInitialA], a call DetectConsole - ld a, $20 + ld a, " " ld [wTileMapFill], a call SetupVRAM call SetupLCD @@ -420,7 +420,7 @@ SetupVRAM: ; 03a1 (0:03a1) call BankswitchVRAM0 .vram0 ld hl, v0Tiles0 - ld bc, v0BGMapTiles1 - v0Tiles0 + ld bc, v0BGMap0 - v0Tiles0 .loop xor a ld [hli], a @@ -433,8 +433,8 @@ SetupVRAM: ; 03a1 (0:03a1) ; fill VRAM0 BG maps with [wTileMapFill] and VRAM1 BG Maps with 0 FillTileMap: ; 03c0 (0:03c0) call BankswitchVRAM0 - ld hl, v0BGMapTiles1 - ld bc, v0BGMapTiles2 - v0BGMapTiles1 + ld hl, v0BGMap0 + ld bc, v0BGMap1 - v0BGMap0 .vram0_loop ld a, [wTileMapFill] ld [hli], a @@ -446,8 +446,8 @@ FillTileMap: ; 03c0 (0:03c0) cp CONSOLE_CGB ret nz call BankswitchVRAM1 - ld hl, v1BGMapTiles1 - ld bc, v1BGMapTiles2 - v1BGMapTiles1 + ld hl, v1BGMap0 + ld bc, v1BGMap1 - v1BGMap0 .vram1_loop xor a ld [hli], a @@ -558,16 +558,16 @@ FlushPalettes: ; 042d (0:042d) FlushAllCGBPalettes: ; 0458 (0:0458) ; flush 8 BGP palettes xor a - ld b, 8 * CGB_PAL_SIZE + ld b, 8 palettes call CopyCGBPalettes ; flush 8 OBP palettes ld a, CGB_PAL_SIZE - ld b, 8 * CGB_PAL_SIZE + ld b, 8 palettes call CopyCGBPalettes jr FlushPalettes.done ; copy b bytes of CGB palette data starting at -; wBackgroundPalettesCGB + a * CGB_PAL_SIZE into rBGPD or rOGPD. +; wBackgroundPalettesCGB + a palettes into rBGPD or rOGPD. CopyCGBPalettes: ; 0467 (0:0467) add a add a @@ -641,7 +641,7 @@ AttrBlkPacket_04bf: ; 04bf (0:04bf) ds 6 ; data set 2 ds 2 ; data set 3 -; returns v*BGMapTiles1 + BG_MAP_WIDTH * c + b in de. +; returns v*BGMap0 + BG_MAP_WIDTH * c + b in de. ; used to map coordinates at bc to a BGMap0 address. BCCoordToBGMap0Address: ; 04cf (0:04cf) ld l, c @@ -652,7 +652,7 @@ BCCoordToBGMap0Address: ; 04cf (0:04cf) add hl, hl add hl, hl ld c, b - ld b, HIGH(v0BGMapTiles1) + ld b, HIGH(v0BGMap0) add hl, bc ld e, l ld d, h @@ -848,12 +848,12 @@ Func_05c2: ; 5c2 (0:5c2) ld hl, wcaa0 push hl push bc - call Func_0614 + call WriteNumbersInTextFormat pop bc call BCCoordToBGMap0Address pop hl ld b, $02 - call JumpToHblankCopyDataHLtoDE + call JPHblankCopyDataHLtoDE pop de pop bc pop hl @@ -867,12 +867,12 @@ Func_05db: ; 5db (0:5db) ld hl, wcaa0 push hl push bc - call Func_061b + call WriteNumberInTextFormat pop bc call BCCoordToBGMap0Address pop hl ld b, $01 - call JumpToHblankCopyDataHLtoDE + call JPHblankCopyDataHLtoDE pop de pop bc pop hl @@ -889,61 +889,66 @@ Func_05f4: ; 5f4 (0:5f4) push hl push bc ld a, d - call Func_0614 + call WriteNumbersInTextFormat ld a, e - call Func_0614 + call WriteNumbersInTextFormat pop bc call BCCoordToBGMap0Address pop hl ld b, $04 - call JumpToHblankCopyDataHLtoDE + call JPHblankCopyDataHLtoDE pop de pop bc pop hl ret ; 0x614 -Func_0614: ; 614 (0:614) +; given two numbers in the two nybbles of register a, write them +; in text format to hl (most significant nybble first) +WriteNumbersInTextFormat: ; 614 (0:614) push af swap a - call Func_061b + call WriteNumberInTextFormat pop af -Func_061b: +; fallthrough + +; given a number in the (bottom nybble) of register a, write it in text format to hl +WriteNumberInTextFormat: and $0f - add $30 - cp $3a - jr c, .asm_625 + add "0" + cp "9" + 1 + jr c, .write_num add $07 -.asm_625 +.write_num ld [hli], a ret ; 0x627 INCROM $0627, $0663 -Func_0663: ; 0663 (0:0663) +; convert the number at hl to text (ascii) format and write it to de +TwoByteNumberToText: ; 0663 (0:0663) push bc - ld bc, $d8f0 - call Func_0686 - ld bc, $fc18 - call Func_0686 - ld bc, $ff9c - call Func_0686 - ld bc, $fff6 - call Func_0686 - ld bc, $ffff - call Func_0686 - xor a + ld bc, -10000 + call .get_digit + ld bc, -1000 + call .get_digit + ld bc, -100 + call .get_digit + ld bc, -10 + call .get_digit + ld bc, -1 + call .get_digit + xor a ; TX_END ld [de], a pop bc ret - -Func_0686: ; 0686 (0:0686) - ld a, $2f -.asm_688 +.get_digit + ld a, "0" - 1 +.substract_loop inc a add hl, bc - jr c, .asm_688 + jr c, .substract_loop ld [de], a inc de ld a, l @@ -955,50 +960,60 @@ Func_0686: ; 0686 (0:0686) ret ; 0x695 -Func_0695: ; 0695 (0:0695) - call Func_069d - bit 7, [hl] - jr z, Func_0695 +; reads structs: +; x (1 byte), y (1 byte), data (n bytes), $00 +; x (1 byte), y (1 byte), data (n bytes), $00 +; ... +; $ff +; for each struct, writes data to BGMap0-translated x,y +WriteDataBlocksToBGMap0: ; 0695 (0:0695) + call WriteDataBlockToBGMap0 + bit 7, [hl] ; check for $ff + jr z, WriteDataBlocksToBGMap0 ret ; 0x69d -Func_069d: ; 069d (0:069d) +; reads struct: +; x (1 byte), y (1 byte), data (n bytes), $00 +; writes data to BGMap0-translated x,y +WriteDataBlockToBGMap0: ; 069d (0:069d) ld b, [hl] inc hl ld c, [hl] inc hl - push hl - push bc - ld b, $ff -.asm_6a5 + push hl ; hl = addr of data + push bc ; b,c = x,y + ld b, -1 +.find_zero_loop inc b ld a, [hli] or a - jr nz, .asm_6a5 - ld a, b - pop bc + jr nz, .find_zero_loop + ld a, b ; length of data + pop bc ; x,y push af call BCCoordToBGMap0Address pop af - ld b, a - pop hl + ld b, a ; length of data + pop hl ; addr of data or a - jr z, .asm_6bd + jr z, .move_to_next push bc push hl - call SafeCopyDataHLtoDE + call SafeCopyDataHLtoDE ; copy data to de (BGMap0 translated x,y) pop hl pop bc -.asm_6bd - inc b +.move_to_next + inc b ; length of data += 1 (to account for the last $0) ld c, b - ld b, $0 - add hl, bc + ld b, 0 + add hl, bc ; point to next structure ret ; 0x6c3 -Func_06c3: ; 06c3 (0:06c3) +; writes a to [v*BGMap0 + BG_MAP_WIDTH * c + b] +WriteByteToBGMap0: ; 06c3 (0:06c3) push af ld a, [wLCDC] rla @@ -1034,7 +1049,7 @@ Func_06c3: ; 06c3 (0:06c3) ; 0x6ee ; copy a bytes of data from hl to vBGMap0 address pointed to by coord at bc -Func_06ee: ; 06ee (0:06ee) +CopyDataToBGMap0: ; 06ee (0:06ee) push bc push hl push af @@ -1052,7 +1067,7 @@ Func_06ee: ; 06ee (0:06ee) SafeCopyDataHLtoDE: ; 6fc (0:6fc) ld a, [wLCDC] rla - jr c, JumpToHblankCopyDataHLtoDE + jr c, JPHblankCopyDataHLtoDE .lcd_off_loop ld a, [hli] ld [de], a @@ -1060,12 +1075,12 @@ SafeCopyDataHLtoDE: ; 6fc (0:6fc) dec b jr nz, .lcd_off_loop ret -JumpToHblankCopyDataHLtoDE: ; 0709 (0:0709) +JPHblankCopyDataHLtoDE: ; 0709 (0:0709) jp HblankCopyDataHLtoDE ; 0x70c ; copy c bytes of data from hl to de, b times. -; used to copy gfx data. +; used to copy gfx data with c = TILE_SIZE CopyGfxData: ; 070c (0:070c) ld a, [wLCDC] rla @@ -1075,7 +1090,7 @@ CopyGfxData: ; 070c (0:070c) push hl push de ld b, c - call JumpToHblankCopyDataHLtoDE + call JPHblankCopyDataHLtoDE ld b, $0 pop hl add hl, bc @@ -1563,12 +1578,82 @@ Func_08ef: ; 08ef (0:08ef) jr .asm_93c ; 0x950 - INCROM $0950, $099c +; set attributes for [hl] sprites starting from wOAM + [wOAMOffset] / 4 +; return carry if reached end of wOAM before finishing +SetManyObjectsAttributes: ; 950 (0:950) + push hl + ld a, [wOAMOffset] + ld c, a + ld b, HIGH(wOAM) + cp 40 * 4 + jr nc, .beyond_oam + pop hl + ld a, [hli] ; [hl] = how many obj? +.copy_obj_loop + push af + ld a, [hli] + add e + ld [bc], a ; Y Position <- [hl + 1 + 4*i] + e + inc bc + ld a, [hli] + add d + ld [bc], a ; X Position <- [hl + 2 + 4*i] + d + inc bc + ld a, [hli] + ld [bc], a ; Tile/Pattern Number <- [hl + 3 + 4*i] + inc bc + ld a, [hli] + ld [bc], a ; Attributes/Flags <- [hl + 4 + 4*i] + inc bc + ld a, c + cp 40 * 4 + jr nc, .beyond_oam + pop af + dec a + jr nz, .copy_obj_loop + or a +.done + ld hl, wOAMOffset + ld [hl], c + ret +.beyond_oam + pop hl + scf + jr .done +; 0x97f + +; for the sprite at wOAM + [wOAMOffset] / 4, set its attributes from registers e, d, c, b +; return carry if [wOAMOffset] > 40 * 4 (beyond the end of wOAM) +SetOneObjectAttributes: ; 97f (0:97f) + push hl + ld a, [wOAMOffset] + ld l, a + ld h, HIGH(wOAM) + cp 40 * 4 + jr nc, .beyond_oam + ld [hl], e ; Y Position + inc hl + ld [hl], d ; X Position + inc hl + ld [hl], c ; Tile/Pattern Number + inc hl + ld [hl], b ; Attributes/Flags + inc hl + ld a, l + ld [wOAMOffset], a + pop hl + or a + ret +.beyond_oam + pop hl + scf + ret +; 0x99c ; set the Y Position and X Position of all sprites in wOAM to $00 -InitSpritePositions: ; 099c (0:099c) +ZeroObjectPositions: ; 099c (0:099c) xor a - ld [wcab5], a + ld [wOAMOffset], a ld hl, wOAM ld c, 40 xor a @@ -1878,7 +1963,7 @@ Func_0bcb: ; 0bcb (0:0bcb) ld a, %11100100 ld [rBGP], a ld de, v0Tiles1 - ld bc, v0BGMapTiles1 - v0Tiles1 + ld bc, v0BGMap0 - v0Tiles1 .loop ld a, [hli] ld [de], a @@ -1887,7 +1972,7 @@ Func_0bcb: ; 0bcb (0:0bcb) ld a, b or c jr nz, .loop - ld hl, v0BGMapTiles1 + ld hl, v0BGMap0 ld de, $000c ld a, $80 ld c, $d @@ -2460,9 +2545,9 @@ DuelTransmissionError: ; 0f35 (0:0f35) call LoadTxRam3 ldtx hl, TransmissionErrorText call DrawWideTextBox_WaitForInput - ld a, $ff - ld [wd0c3], a - ld hl, wcbe5 + ld a, -1 + ld [wDuelResult], a + ld hl, wDuelReturnAddress ld a, [hli] ld h, [hl] ld l, a @@ -2473,8 +2558,8 @@ DuelTransmissionError: ; 0f35 (0:0f35) ret Func_0f58: ; 0f58 (0:0f58) - ld a, [wcc09] - cp $1 + ld a, [wDuelType] + cp DUELTYPE_LINK jr z, .asm_f60 ret .asm_f60 @@ -2606,7 +2691,9 @@ Func_0fe9: ; 0fe9 (0:0fe9) ret ; 0x100b -Func_100b: ; 100b (0:100b) +; save duel state to SRAM +; called between each two-player turn, just after player draws card +SaveDuelStateToSRAM: ; 100b (0:100b) ld a, $2 call BankswitchSRAM call $669d @@ -3437,26 +3524,34 @@ LoadCardDataToBuffer2_FromDeckIndex: ; 138c (0:138c) ret ; 0x13a2 -Func_13a2: ; 13a2 (0:13a2) +; evolve a turn holder's Pokemon card in the play area slot determined by hTempPlayAreaLocationOffset_ff9d +; into another turn holder's Pokemon card identifier by it's deck index (0-59) in hTempCardIndex_ff98. +; return nc if evolution was succesful. +EvolvePokemonCard: ; 13a2 (0:13a2) + ; first make sure the attempted evolution is viable ldh a, [hTempCardIndex_ff98] ld d, a ldh a, [hTempPlayAreaLocationOffset_ff9d] ld e, a - call Func_13f7 - ret c + call CheckIfCanEvolveInto + ret c ; return if it's not capable of evolving into the selected Pokemon + + ; place the evolved Pokemon card in the play area location of the pre-evolved Pokemon card ldh a, [hTempPlayAreaLocationOffset_ff9d] ld e, a add DUELVARS_ARENA_CARD call GetTurnDuelistVariable - ld [wccee], a + ld [wccee], a ; save pre-evolved Pokemon card into wccee call LoadCardDataToBuffer2_FromDeckIndex ldh a, [hTempCardIndex_ff98] ld [hl], a call LoadCardDataToBuffer1_FromDeckIndex ldh a, [hTempCardIndex_ff98] call PutHandCardInPlayArea + + ; update the Pokemon's HP with the difference ldh a, [hTempPlayAreaLocationOffset_ff9d] - ld a, e + ld a, e ; derp add DUELVARS_ARENA_CARD_HP call GetTurnDuelistVariable ld a, [wLoadedCard2HP] @@ -3465,8 +3560,9 @@ Func_13a2: ; 13a2 (0:13a2) sub c add [hl] ld [hl], a + ; reset status (if in arena) and set the flag that prevents it from evolving again this turn ld a, e - add $c2 + add DUELVARS_ARENA_CARD_FLAGS_C2 ld l, a ld [hl], $00 ld a, e @@ -3476,18 +3572,25 @@ Func_13a2: ; 13a2 (0:13a2) ld a, e or a call z, ResetStatusConditions + + ; set the new evolution stage of the card ldh a, [hTempPlayAreaLocationOffset_ff9d] add DUELVARS_ARENA_CARD_STAGE call GetTurnDuelistVariable ld a, [wLoadedCard1Stage] ld [hl], a or a - ret ; ! + ret + scf ret ; 0x13f7 -Func_13f7: ; 13f7 (0:13f7) +; check if the turn holder's Pokemon card e can evolve into the turn holder's Pokemon card d. +; e is the play area location offset (PLAY_AREA_*) of the Pokemon trying to evolve. +; d is the deck index (0-59) of the Pokemon card that was selected to be the evolution target. +; return carry if can't evolve, plus nz if the reason for it is the card was played this turn. +CheckIfCanEvolveInto: ; 13f7 (0:13f7) push de ld a, e add DUELVARS_ARENA_CARD @@ -3496,43 +3599,45 @@ Func_13f7: ; 13f7 (0:13f7) ld a, d call LoadCardDataToBuffer1_FromDeckIndex ld hl, wLoadedCard2Name - ld de, wLoadedCard1NonPokemonDescription + ld de, wLoadedCard1PreEvoName ld a, [de] cp [hl] - jr nz, .asm_1427 + jr nz, .cant_evolve ; jump if they are incompatible to evolve inc de inc hl ld a, [de] cp [hl] - jr nz, .asm_1427 + jr nz, .cant_evolve ; jump if they are incompatible to evolve pop de ld a, e - add $c2 + add DUELVARS_ARENA_CARD_FLAGS_C2 call GetTurnDuelistVariable - and $80 - jr nz, .asm_1425 + and CAN_EVOLVE_THIS_TURN + jr nz, .can_evolve + ; if the card trying to evolve was played this turn, it can't evolve ld a, $01 or a scf ret -.asm_1425 +.can_evolve or a ret -.asm_1427 +.cant_evolve pop de xor a scf ret ; 0x142b +; similar to CheckIfCanEvolveInto, but with the twist of calling Func_2ecd Func_142b: ; 142b (0:142b) ld a, e - add $c2 + add DUELVARS_ARENA_CARD_FLAGS_C2 call GetTurnDuelistVariable - and $80 - jr nz, .asm_1437 - jr .asm_145e -.asm_1437 + and CAN_EVOLVE_THIS_TURN + jr nz, .can_evolve + jr .cant_evolve +.can_evolve ld a, e add DUELVARS_ARENA_CARD ld l, a @@ -3540,24 +3645,24 @@ Func_142b: ; 142b (0:142b) call LoadCardDataToBuffer2_FromDeckIndex ld a, d call LoadCardDataToBuffer1_FromDeckIndex - ld hl, wLoadedCard1NonPokemonDescription + ld hl, wLoadedCard1PreEvoName ld e, [hl] inc hl ld d, [hl] call $2ecd ld hl, wLoadedCard2Name - ld de, wLoadedCard1NonPokemonDescription + ld de, wLoadedCard1PreEvoName ld a, [de] cp [hl] - jr nz, .asm_145e + jr nz, .cant_evolve inc de inc hl ld a, [de] cp [hl] - jr nz, .asm_145e + jr nz, .cant_evolve or a ret -.asm_145e +.cant_evolve xor a scf ret @@ -3572,7 +3677,7 @@ ResetStatusConditions: ; 1461 (0:1461) ld h, a xor a ld l, DUELVARS_ARENA_CARD_STATUS - ld [hl], a + ld [hl], a ; NO_STATUS ld l, DUELVARS_ARENA_CARD_SUBSTATUS1 ld [hl], a ld l, DUELVARS_ARENA_CARD_SUBSTATUS2 @@ -3603,7 +3708,7 @@ ResetStatusConditions: ; 1461 (0:1461) ; return carry if there is no room for more Pokemon PutHandPokemonCardInPlayArea: ; 1485 (0:1485) push af - ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA call GetTurnDuelistVariable cp MAX_PLAY_AREA_POKEMON jr nc, .already_max_pkmn_in_play @@ -3623,7 +3728,7 @@ PutHandPokemonCardInPlayArea: ; 1485 (0:1485) ld l, a ld a, [wLoadedCard2HP] ld [hl], a ; set card's HP - ld a, $c2 + ld a, DUELVARS_ARENA_CARD_FLAGS_C2 add e ld l, a ld [hl], $0 @@ -3631,11 +3736,11 @@ PutHandPokemonCardInPlayArea: ; 1485 (0:1485) add e ld l, a ld [hl], $0 - ld a, $e0 + ld a, DUELVARS_ARENA_CARD_ATTACHED_PLUSPOWER add e ld l, a ld [hl], $0 - ld a, $da + ld a, DUELVARS_ARENA_CARD_ATTACHED_DEFENDER add e ld l, a ld [hl], $0 @@ -3677,7 +3782,7 @@ PutHandCardInPlayArea: ; 14d2 (0:14d2) ; to the discard pile MovePlayAreaCardToDiscardPile: ; 14dd (0:14dd) call EmptyPlayAreaSlot - ld l, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY + ld l, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA dec [hl] ld l, DUELVARS_CARD_LOCATIONS .next_card @@ -3712,9 +3817,9 @@ EmptyPlayAreaSlot: ; 14f8 (0:14f8) call .init_duelvar ld a, DUELVARS_ARENA_CARD_CHANGED_TYPE call .init_duelvar - ld a, $da + ld a, DUELVARS_ARENA_CARD_ATTACHED_DEFENDER call .init_duelvar - ld a, $e0 + ld a, DUELVARS_ARENA_CARD_ATTACHED_PLUSPOWER .init_duelvar add e ld l, a @@ -3776,15 +3881,15 @@ SwapPlayAreaPokemon: ; 1548 (0:1548) call .swap_duelvar ld a, DUELVARS_ARENA_CARD_HP call .swap_duelvar - ld a, $c2 + ld a, DUELVARS_ARENA_CARD_FLAGS_C2 call .swap_duelvar ld a, DUELVARS_ARENA_CARD_STAGE call .swap_duelvar ld a, DUELVARS_ARENA_CARD_CHANGED_TYPE call .swap_duelvar - ld a, $e0 + ld a, DUELVARS_ARENA_CARD_ATTACHED_PLUSPOWER call .swap_duelvar - ld a, $da + ld a, DUELVARS_ARENA_CARD_ATTACHED_DEFENDER call .swap_duelvar set CARD_LOCATION_PLAY_AREA_F, d set CARD_LOCATION_PLAY_AREA_F, e @@ -3997,7 +4102,7 @@ Func_161e: ; 161e (0:161e) ld a, $07 call CheckMatchingCommand ret c ; return if command not found - bank1call $4f9d + bank1call DrawDuelMainScene ldh a, [hTempCardIndex_ff9f] call LoadCardDataToBuffer1_FromDeckIndex ld de, wLoadedCard1Name @@ -4178,11 +4283,11 @@ Func_1730: ; 1730 (0:1730) call SubstractHP ld a, [wcac2] cp $1 - jr nz, .asm_17e8 + jr nz, .skip_draw_huds push hl - bank1call $503a + bank1call DrawDuelHUDs pop hl -.asm_17e8 +.skip_draw_huds call PrintKnockedOutIfHLZero jr Func_17fb @@ -4227,7 +4332,7 @@ Func_1823: ; 1823 (0:1823) ret DealConfusionDamageToSelf: ; 1828 (0:1828) - bank1call $4f9d + bank1call DrawDuelMainScene ld a, $1 ld [wDamageToSelfMode], a ldtx hl, DamageToSelfDueToConfusionText @@ -4265,7 +4370,7 @@ Func_1874: ; 1874 (0:1874) ld a, [wccec] or a ret nz - ldh a, [hffa0] + ldh a, [hTemp_ffa0] push af ldh a, [hTempCardIndex_ff9f] push af @@ -4274,14 +4379,14 @@ Func_1874: ; 1874 (0:1874) ld a, [wcc11] ldh [hTempCardIndex_ff9f], a ld a, [wcc10] - ldh [hffa0], a + ldh [hTemp_ffa0], a ld a, $8 call SetDuelAIAction call Func_0f58 pop af ldh [hTempCardIndex_ff9f], a pop af - ldh [hffa0], a + ldh [hTemp_ffa0], a ret Func_189d: ; 189d (0:189d) @@ -4310,17 +4415,17 @@ Func_189d: ; 189d (0:189d) call SwapTurn pop de ret nc - bank1call $4f9d + bank1call DrawDuelMainScene ld a, DUELVARS_ARENA_CARD_SUBSTATUS2 call GetNonTurnDuelistVariable ld [hl], $0 ld de, 0 ret -; return carry and 1 into wccc9 if damage is dealt to oneself due to confusion +; return carry and 1 into wGotHeadsFromConfusionCheck if damage will be dealt to oneself due to confusion CheckSelfConfusionDamage: ; 18d7 (0:18d7) xor a - ld [wccc9], a + ld [wGotHeadsFromConfusionCheck], a ld a, DUELVARS_ARENA_CARD_STATUS call GetTurnDuelistVariable and CNF_SLP_PRZ @@ -4333,7 +4438,7 @@ CheckSelfConfusionDamage: ; 18d7 (0:18d7) call TossCoin jr c, .no_confusion_damage ld a, $1 - ld [wccc9], a + ld [wGotHeadsFromConfusionCheck], a scf ret .no_confusion_damage @@ -4341,8 +4446,9 @@ CheckSelfConfusionDamage: ; 18d7 (0:18d7) ret ; 0x18f9 -; use the trainer card with deck index at hTempCardIndex_ff98 -; a trainer card is like a move effect, with its own effect commands +; use the trainer card with deck index at hTempCardIndex_ff98. +; a trainer card is like a move effect, with its own effect commands. +; return nc if the card was played, carry if it wasn't. UseTrainerCard: ; 18f9 (0:18f9) call CheckCantUseTrainerDueToHeadache jr c, .cant_use @@ -4762,12 +4868,12 @@ Func_1af3: ; 1af3 (0:1af3) ; 0x1b8d Func_1b8d: ; 1b8d (0:1b8d) - bank1call $4f9d + bank1call DrawDuelMainScene ld a, DUELVARS_ARENA_CARD call GetTurnDuelistVariable call LoadCardDataToBuffer1_FromDeckIndex - ld a, $12 - call Func_29f5 + ld a, 18 + call CopyCardNameAndLevel ld [hl], $0 ld hl, wTxRam2 xor a @@ -4783,7 +4889,7 @@ Func_1b8d: ; 1b8d (0:1b8d) Func_1bb4: ; 1bb4 (0:1bb4) call Func_3b31 - bank1call $4f9d + bank1call DrawDuelMainScene call $503a xor a ldh [hTempPlayAreaLocationOffset_ff9d], a @@ -4802,8 +4908,8 @@ Func_1bca: ; 1bca (0:1bca) add DUELVARS_ARENA_CARD call GetTurnDuelistVariable call LoadCardDataToBuffer1_FromDeckIndex - ld a, $12 - call Func_29f5 + ld a, 18 + call CopyCardNameAndLevel ld [hl], $0 ld hl, $0000 call LoadTxRam2 @@ -4949,7 +5055,7 @@ CopyPlayerName: ; 1c7d (0:1c7d) call DisableSRAM ret -; copy the opponent's name to de (usually via PrintTextBoxBorderLabel) +; copy the opponent's name to de (usually via CopyText) CopyOpponentName: ; 1c8e (0:1c8e) ld hl, wOpponentName ld a, [hli] @@ -4958,7 +5064,7 @@ CopyOpponentName: ; 1c8e (0:1c8e) ld a, [hld] ld l, [hl] ld h, a - jp PrintTextBoxBorderLabel + jp CopyText .special_name ld hl, wc500 ld a, [hl] @@ -4967,7 +5073,7 @@ CopyOpponentName: ; 1c8e (0:1c8e) jr CopyPlayerName.loop .print_player2 ldtx hl, Player2Text - jp PrintTextBoxBorderLabel + jp CopyText ; return, in hl, the total amount of cards owned anywhere, including duplicates GetRawAmountOfCardsOwned: ; 1caa (0:1caa) @@ -5215,7 +5321,7 @@ SafeCopyDataDEtoHL: ; 1dca (0:1dca) .lcd_on jp HblankCopyDataDEtoHL -; returns v*BGMapTiles1 + BG_MAP_WIDTH * e + d in hl. +; returns v*BGMap0 + BG_MAP_WIDTH * e + d in hl. ; used to map coordinates at de to a BGMap0 address. DECoordToBGMap0Address: ; 1ddb (0:1ddb) ld l, e @@ -5229,7 +5335,7 @@ DECoordToBGMap0Address: ; 1ddb (0:1ddb) add d ld l, a ld a, h - adc HIGH(v0BGMapTiles1) + adc HIGH(v0BGMap0) ld h, a ret @@ -5264,7 +5370,7 @@ DrawLabeledTextBox: ; 1e00 (0:1e00) or a jr z, .draw_top_border ; Console is SGB and frame type is != 0. -; The text box will be colorized so a SGB command needs to be transferred +; The text box will be colorized so a SGB command needs to be sent push de push bc call .draw_top_border ; this falls through to drawing the whole box @@ -5277,7 +5383,7 @@ DrawLabeledTextBox: ; 1e00 (0:1e00) push bc push hl ; top left tile of the box - ld hl, wTempCardCollection + ld hl, wc000 ld a, $5 ld [hli], a ld a, $18 @@ -5285,10 +5391,11 @@ DrawLabeledTextBox: ; 1e00 (0:1e00) ; white tile before the text ld a, $70 ld [hli], a + ; text label ld e, l ld d, h pop hl - call PrintTextBoxBorderLabel + call CopyText ld hl, $c003 call Func_23c1 ld l, e @@ -5324,7 +5431,7 @@ DrawLabeledTextBox: ; 1e00 (0:1e00) push de push bc call Func_22ae - ld hl, wTempCardCollection + ld hl, wc000 call Func_21c5 pop bc pop de @@ -5433,7 +5540,7 @@ ContinueDrawingTextBoxCGB: call CopyLine pop hl call BankswitchVRAM1 - ld a, [wTextBoxFrameType] + ld a, [wTextBoxFrameType] ; on CGB, wTextBoxFrameType determines the palette and the other attributes ld e, a ld d, a xor a @@ -5568,78 +5675,115 @@ FillRectangle: ; 1f5f (0:1f5f) ret ; 0x1f96 - INCROM $1f96, $20b0 + INCROM $1f96, $208d -Func_20b0: ; 20b0 (0:20b0) - ld hl, DuelGraphics + $680 - $4000 +; loads the Deck and Hand icons for the "Draw X card(s) from the deck." screen +LoadDuelDrawCardsScreenTiles: ; 208d (0:208d) + ld hl, DuelOtherGraphics + $29 tiles + ld de, v0Tiles1 + $74 tiles + ld b, $08 + jp CopyFontsOrDuelGraphicsTiles +; 0x2098 + +; loads the 8 tiles that make up the border of the main duel menu as well as the border +; of a large card picture (displayed after drawing the card or placing it in the arena). +LoadCardOrDuelMenuBorderTiles: ; 2098 (0:2098) + ld hl, DuelOtherGraphics + $15 tiles + ld de, v0Tiles1 + $50 tiles + ld b, $08 + jr CopyFontsOrDuelGraphicsTiles +; 0x20a2 + +; loads the graphics of a card type header, used to display a picture of a card after drawing it +; or placing it in the arena. register e determines which header (TRAINER, ENERGY, PoKéMoN) +LoadCardTypeHeaderTiles: ; 20a2 (0:20a2) + ld d, a + ld e, 0 + ld hl, DuelCardHeaderGraphics - $4000 + add hl, de + ld de, v0Tiles1 + $60 tiles + ld b, $10 + jr CopyFontsOrDuelGraphicsTiles +; 0x20b0 + +; loads the symbols that are displayed near the names of a list of cards in the hand or discard pile +LoadDuelCardSymbolTiles: ; 20b0 (0:20b0) + ld hl, DuelDmgSgbSymbolGraphics - $4000 ld a, [wConsole] cp CONSOLE_CGB - jr nz, .asm_20bd - ld hl, DuelGraphics + $e90 - $4000 -.asm_20bd - ld de, v0Tiles1 + $500 + jr nz, .copy + ld hl, DuelCgbSymbolGraphics - $4000 +.copy + ld de, v0Tiles1 + $50 tiles ld b, $30 jr CopyFontsOrDuelGraphicsTiles -Func_20c4: ; 20c4 (0:20c4) - ld hl, DuelGraphics + $6c0 - $4000 +; loads the symbols for Stage 1 Pkmn card, Stage 2 Pkmn card, and Trainer card +LoadDuelCardSymbolTiles2: ; 20c4 (0:20c4) + ld hl, DuelDmgSgbSymbolGraphics + $4 tiles - $4000 ld a, [wConsole] cp CONSOLE_CGB jr nz, .copy - ld hl, DuelGraphics + $ed0 - $4000 + ld hl, DuelCgbSymbolGraphics + $4 tiles - $4000 .copy - ld de, v0Tiles1 + $540 + ld de, v0Tiles1 + $54 tiles ld b, $c jr CopyFontsOrDuelGraphicsTiles -Func_20d8: ; 20d8 (0:20d8) +; load the face down stage0 / stage1 / stage2 card images shown in the ckeck Pokemon screens +LoadDuelFaceDownCardTiles: ; 20d8 (0:20d8) ld b, $10 - jr Func_20dc.asm_20de + jr LoadDuelCheckPokemonScreenTiles.got_num_tiles -Func_20dc: ; 20dc (0:20dc) +; same as LoadDuelFaceDownCardTiles, plus also load the ACT / BP text tiles +LoadDuelCheckPokemonScreenTiles: ; 20dc (0:20dc) ld b, $24 -.asm_20de - ld hl, DuelGraphics + $980 - $4000 +.got_num_tiles + ld hl, DuelDmgSgbSymbolGraphics + $30 tiles - $4000 ld a, [wConsole] cp CONSOLE_CGB jr nz, .copy - ld hl, DuelGraphics + $1190 - $4000 + ld hl, DuelCgbSymbolGraphics + $30 tiles - $4000 .copy - ld de, v0Tiles1 + $500 + ld de, v0Tiles1 + $50 tiles jr CopyFontsOrDuelGraphicsTiles -Func_20f0: ; 20f0 (0:20f0) - ld hl, Fonts + $8 - ld de, v0Tiles1 + $200 +; load the tiles for the "Placing the prizes..." screen +LoadPlacingThePrizesScreenTiles: ; 20f0 (0:20f0) + ; load the Pokeball field tiles + ld hl, DuelOtherGraphics + ld de, v0Tiles1 + $20 tiles ld b, $d call CopyFontsOrDuelGraphicsTiles - ld hl, DuelGraphics + $bc0 - $4000 + ; load the Deck and the Discard Pile icons + ld hl, DuelDmgSgbSymbolGraphics + $54 tiles - $4000 ld a, [wConsole] cp CONSOLE_CGB jr nz, .copy - ld hl, DuelGraphics + $13d0 - $4000 + ld hl, DuelCgbSymbolGraphics + $54 tiles - $4000 .copy - ld de, v0Tiles1 + $500 + ld de, v0Tiles1 + $50 tiles ld b, $30 jr CopyFontsOrDuelGraphicsTiles -Func_210f: ; 210f (0:210f) - ld hl, DuelGraphics + $1770 - $4000 - ld de, v0Tiles2 + $300 +; load the tiles for the [O] and [X] symbols used to display the results of a coin toss +LoadDuelCoinTossResultTiles: ; 210f (0:210f) + ld hl, DuelOtherGraphics + $d tiles + ld de, v0Tiles2 + $30 tiles ld b, $8 jr CopyFontsOrDuelGraphicsTiles -Func_2119: ; 2119 (0:2119) - ld hl, DuelGraphics - $4000 +LoadDuelHUDTiles: ; 2119 (0:2119) + ld hl, DuelHUDGraphics - $4000 ld de, v0Tiles2 ; destination - ld b, $38 ; number of tiles + ld b, (DuelCardHeaderGraphics - DuelHUDGraphics) / TILE_SIZE ; number of tiles ; fallthrough ; if hl ≤ $3fff ; copy b tiles from Gfx1:(hl+$4000) to de ; if $4000 ≤ hl ≤ $7fff ; copy b tiles from Gfx2:hl to de -CopyFontsOrDuelGraphicsTiles: +CopyFontsOrDuelGraphicsTiles: ; 2121 (0:2121) ld a, BANK(Fonts); BANK(DuelGraphics); BANK(VWF) call BankpushHome ld c, TILE_SIZE @@ -5650,11 +5794,11 @@ CopyFontsOrDuelGraphicsTiles: ; this function appears to copy duel gfx data into sram Func_212f: ; 212f (0:212f) - ld hl, DuelGraphics - $4000 + ld hl, DuelHUDGraphics - $4000 ld de, $a400 ld b, $30 call CopyFontsOrDuelGraphicsTiles - ld hl, DuelGraphics + $17f0 - $4000 + ld hl, DuelOtherGraphics + $150 ld de, $a700 ld b, $08 call CopyFontsOrDuelGraphicsTiles @@ -5666,12 +5810,12 @@ Func_212f: ; 212f (0:212f) add hl, hl add hl, hl add hl, hl - ld de, DuelGraphics + $680 - $4000 + ld de, DuelDmgSgbSymbolGraphics - $4000 add hl, de ld de, $a780 ld b, $04 call CopyFontsOrDuelGraphicsTiles - ld hl, DuelGraphics + $680 - $4000 + ld hl, DuelDmgSgbSymbolGraphics - $4000 ld de, $b100 ld b, $30 jr CopyFontsOrDuelGraphicsTiles @@ -5679,7 +5823,7 @@ Func_212f: ; 212f (0:212f) DrawDuelBoxMessage: ; 2167 (0:2167) ld l, a - ld h, (40 * TILE_SIZE) / 4 ; boxes are 10x4 tiles + ld h, (40 tiles) / 4 ; boxes are 10x4 tiles call HtimesL add hl, hl add hl, hl @@ -5738,9 +5882,9 @@ Func_21f2: ; 21f2 (0:21f2) jr z, .asm_2221 cp $a jr z, .asm_224d - cp $5 + cp TX_SYMBOL jr z, .asm_2225 - cp $6 + cp TX_START jr z, .asm_220f cp $7 jr z, .asm_2215 @@ -5834,6 +5978,10 @@ Func_2275: ; 2275 (0:2275) jr nz, .asm_2292 ret +; wcd0a <- 0 +; hffac <- 0 +; wcd0b <- 0 +; hffaf <- $f Func_2298: ; 2298 (0:2298) xor a ld [wcd0a], a @@ -5843,6 +5991,8 @@ Func_2298: ; 2298 (0:2298) ldh [hffaf], a ret +; Func_22ae +; hffae <- a Func_22a6: ; 22a6 (0:22a6) push af call Func_22ae @@ -5850,6 +6000,13 @@ Func_22a6: ; 22a6 (0:22a6) ldh [hffae], a ret +; hffad <- d +; hffae <- 0 +; wcd09 <- 0 +; hffaa <- BGMap0(e) +; hffab <- BGMap0(d) +; Func_2298 +;; writes BGMap0-translated DE to (hffab,hffaa) Func_22ae: ; 22ae (0:22ae) push hl ld a, d @@ -5895,6 +6052,11 @@ Func_22ca: ; 22ca (0:22ca) call Func_235e jr .asm_22e9 +; wcd05 <- a +; &(hffab,hffaa) <- a +; (hffab,hffaa) ++ +; hffac ++ +;; writes a to addr pointed to by (hffab,hffaa), then increments (hffab,hffaa) and hffac Func_22f2: ; 22f2 (0:22f2) ld [wcd05], a ld hl, hffaa @@ -6051,13 +6213,13 @@ Uppercase: ; 23b1 (0:23b1) ret c cp $7b ret nc - sub $20 + sub "a" - "A" ld e, a ret Func_23c1: ; 23c1 (0:23c1) ld a, [hl] - cp $6 + cp TX_START jr nz, .asm_23cf call Func_23d3 inc b @@ -6081,7 +6243,7 @@ Func_23d3: ; 23d3 (0:23d3) jr c, .asm_23ec cp $10 jr nc, .asm_23ec - cp $5 + cp TX_SYMBOL jr nz, .asm_23d8 inc b jr .asm_23f4 @@ -6105,51 +6267,53 @@ Func_23d3: ; 23d3 (0:23d3) INCROM $23fd, $245d -Func_245d: ; 245d (0:245d) +; convert the number at hl to TX_SYMBOL text format and write it to wcaa0 +; replace leading zeros with $00 +TwoByteNumberToLargeText_TrimLeadingZeros: ; 245d (0:245d) push de push bc ld de, wcaa0 push de - ld bc, $d8f0 - call Func_2499 - ld bc, $fc18 - call Func_2499 - ld bc, $ff9c - call Func_2499 - ld bc, $fff6 - call Func_2499 - ld bc, $ffff - call Func_2499 + ld bc, -10000 + call .get_digit + ld bc, -1000 + call .get_digit + ld bc, -100 + call .get_digit + ld bc, -10 + call .get_digit + ld bc, -1 + call .get_digit xor a ld [de], a pop hl - ld e, $5 -.asm_2486 + ld e, 5 +.digit_loop inc hl ld a, [hl] - cp $20 - jr nz, .asm_2495 - ld [hl], $0 + cp LOW("<0>") + jr nz, .done ; jump if not zero + ld [hl], LOW("< >") ; trim leading zero inc hl dec e - jr nz, .asm_2486 + jr nz, .digit_loop dec hl - ld [hl], $20 -.asm_2495 + ld [hl], LOW("<0>") +.done dec hl pop bc pop de ret -Func_2499: ; 2499 (0:2499) - ld a, $5 +.get_digit + ld a, TX_SYMBOL ld [de], a inc de - ld a, $1f -.asm_249f + ld a, LOW("<0>") - 1 +.substract_loop inc a add hl, bc - jr c, .asm_249f + jr c, .substract_loop ld [de], a inc de ld a, l @@ -6323,14 +6487,66 @@ Func_256d: ; 256d (0:256d) ret ; 0x2589 - INCROM $2589, $2636 + INCROM $2589, $25ea -; initializes cursor parameters given the 8 bytes starting at hl, +; initializes parameters for a card list (e.g. list of hand cards in a duel or booster pack cards) +; input: a = list length, de = initial page scroll offset, initial item (in the visible page) +; hl: 9 bytes with the rest of the parameters +InitializeCardListParameters: ; 25ea (0:25ea) + ld [wNumListItems], a + ld a, d + ld [wListScrollOffset], a + ld a, e + ld [wCurMenuItem], a + add d + ldh [hCurrentMenuItem], a + ld a, [hli] + ld [wCursorXPosition], a + ld a, [hli] + ld [wCursorYPosition], a + ld a, [hli] + ld [wListItemXPosition], a + ld a, [hli] + ld [wcd1c], a + ld a, [hli] + ld [wNumMenuItems], a + ld a, [hli] + ld [wCursorTileNumber], a + ld a, [hli] + ld [wTileBehindCursor], a + ld a, [hli] + ld [wListFunctionPointer], a + ld a, [hli] + ld [wListFunctionPointer + 1], a + xor a + ld [wCursorBlinkCounter], a + ld a, 1 + ld [wYDisplacementBetweenMenuItems], a + ret +; 0x2626 + +; similar to HandleMenuInput, but conveniently returns parameters related +; to the state of the list in a, d, and e if A or B were pressed. +; also returns carry if A or B were pressed, nc otherwise. +; used in the Hand card list and Discard Pile card list screens. +HandleCardListInput: ; 2626 (0:2626) + call HandleMenuInput + ret nc + ld a, [wListScrollOffset] + ld d, a + ld a, [wCurMenuItem] + ld e, a + ldh a, [hCurrentMenuItem] + scf + ret +; 0x2636 + +; initializes parameters for a menu, given the 8 bytes starting at hl, ; which represent the following: -; x coord, y coord, y displacement between items, number of items, -; cursor tile number, tile behind cursor, ???? (unknown function pointer if non-0) +; cursor x coord, cursor y coord, y displacement between items, number of items, +; cursor tile number, tile behind cursor, function pointer if non-0. ; also sets the current menu item to the one specified in register a -InitializeCursorParameters: ; 2636 (0:2636) +InitializeMenuParameters: ; 2636 (0:2636) ld [wCurMenuItem], a ldh [hCurrentMenuItem], a ld de, wCursorXPosition @@ -6384,7 +6600,7 @@ HandleMenuInput: ; 264b (0:264b) .up_down_done ld a, [wCurMenuItem] ldh [hCurrentMenuItem], a - ld hl, wcd17 + ld hl, wMenuFunctionPointer ; call the function if non-0 (periodically) ld a, [hli] or [hl] jr z, .check_A_or_B @@ -6419,7 +6635,7 @@ HandleMenuInput: ; 264b (0:264b) ret ; plays an "open screen" sound if [hCurrentMenuItem] != 0xff -; plays a "exit screen" sound if [hCurrentMenuItem] == 0xff +; plays an "exit screen" sound if [hCurrentMenuItem] == 0xff PlayOpenOrExitScreenSFX: ; 26c0 (0:26c0) push af ldh a, [hCurrentMenuItem] @@ -6469,7 +6685,7 @@ DrawCursor: ld a, c ld c, e ld b, d - call Func_06c3 + call WriteByteToBGMap0 or a ret @@ -6485,35 +6701,41 @@ SetMenuItem: ; 2710 (0:2710) ld [wCursorBlinkCounter], a ret -Func_271a: ; 271a (0:271a) +; handle input for the 2-row 3-column duel menu. +; only handles input not involving the B, START, or SELECT buttons, that is, +; navigating through the menu or selecting an item with the A button. +; other input in handled by HandleDuelMenuInputAndShortcuts. +HandleDuelMenuInput: ; 271a (0:271a) ldh a, [hButtonsPressed2] or a - jr z, .asm_2764 + jr z, .blink_cursor ld b, a ld hl, wCurMenuItem - and $c0 - jr z, .asm_272c + and D_UP | D_DOWN + jr z, .check_left ld a, [hl] - xor $1 - jr .asm_2748 -.asm_272c + xor 1 ; move to the other menu item in the same column + jr .dpad_pressed +.check_left bit D_LEFT_F, b - jr z, .asm_273b + jr z, .check_right ld a, [hl] - sub $2 - jr nc, .asm_2748 - and $1 - add $4 - jr .asm_2748 -.asm_273b + sub 2 + jr nc, .dpad_pressed + ; wrap to the rightmost item in the same row + and 1 + add 4 + jr .dpad_pressed +.check_right bit D_RIGHT_F, b - jr z, .asm_275d + jr z, .dpad_not_pressed ld a, [hl] - add $2 - cp $6 - jr c, .asm_2748 - and $1 -.asm_2748 + add 2 + cp 6 + jr c, .dpad_pressed + ; wrap to the leftmost item in the same row + and 1 +.dpad_pressed push af ld a, $1 call PlaySFX @@ -6523,12 +6745,13 @@ Func_271a: ; 271a (0:271a) ldh [hCurrentMenuItem], a xor a ld [wCursorBlinkCounter], a - jr .asm_2764 -.asm_275d + jr .blink_cursor +.dpad_not_pressed ldh a, [hButtonsPressed2] and A_BUTTON jp nz, HandleMenuInput.A_pressed -.asm_2764 +.blink_cursor + ; blink cursor every 16 frames ld hl, wCursorBlinkCounter ld a, [hl] inc [hl] @@ -6545,26 +6768,118 @@ Func_271a: ; 271a (0:271a) add a ld c, a ld b, $0 - ld hl, $278d + ld hl, DuelMenuCursorCoords add hl, bc ld b, [hl] inc hl ld c, [hl] ld a, e - call Func_06c3 + call WriteByteToBGMap0 ld a, [wCurMenuItem] ld e, a or a ret ; 0x278d - INCROM $278d, $2988 +DuelMenuCursorCoords: ; 278d (0:278d) + db 2, 14 ; Hand + db 2, 16 ; Attack + db 8, 14 ; Check + db 8, 16 ; Pkmn Power + db 14, 14 ; Retreat + db 14, 16 ; Done + +; print the items of a list of cards (hand cards in a duel, cards from a booster pack...) +; and initialize the parameters of the list +PrintCardListItems: ; 2799 (0:2799) + call InitializeCardListParameters + ld hl, wMenuFunctionPointer + ld a, LOW($283f) + ld [hli], a + ld a, HIGH($283f) + ld [hli], a + ld a, 2 + ld [wYDisplacementBetweenMenuItems], a + ld a, $01 + ld [wcd97], a + ld e, $00 + ld a, [wListScrollOffset] + or a + jr z, .asm_27b9 + ld e, $0c +.asm_27b9 + ld a, [wCursorYPosition] + dec a + ld c, a + ld b, 18 + ld a, e + call WriteByteToBGMap0 + ld e, $00 + ld a, [wListScrollOffset] + ld hl, wNumMenuItems + add [hl] + ld hl, wNumListItems + cp [hl] + jr nc, .asm_27d5 + ld e, $2f +.asm_27d5 + ld a, [wNumMenuItems] + add a + add c + dec a + ld c, a + ld a, e + call WriteByteToBGMap0 + ld a, [wListScrollOffset] + ld e, a + ld d, $00 + ld hl, wDuelTempList + add hl, de + ld a, [wNumMenuItems] + ld b, a + ld a, [wListItemXPosition] + ld d, a + ld a, [wCursorYPosition] + ld e, a + ld c, $00 +.asm_27f8 + ld a, [hl] + cp $ff + jr z, .asm_2826 + push hl + push bc + push de + call LoadCardDataToBuffer1_FromDeckIndex + call DrawCardSymbol + call Func_22ae + ld a, [wcd1c] + call CopyCardNameAndLevel + ld hl, wDefaultText + call Func_21c5 + pop de + pop bc + pop hl + inc hl + ld a, [wNumListItems] + dec a + inc c + cp c + jr c, .asm_2826 + inc e + inc e + dec b + jr nz, .asm_27f8 +.asm_2826 + ret +; 0x2827 + + INCROM $2827, $2988 CardTypeToSymbolID: ; 2988 (0:2988) ld a, [wLoadedCard1Type] cp TYPE_TRAINER jr nc, .trainer_card - cp TYPE_ENERGY_FIRE + cp TYPE_ENERGY jr c, .pokemon_card ; energy card and 7 ; convert energy constant to type constant @@ -6636,8 +6951,10 @@ CardSymbolTable: db $d8, $01 ; TYPE_PKMN_*, Stage 2 db $dc, $02 ; TYPE_TRAINER -Func_29f5: ; 29f5 (0:29f5) - farcall $6, $4000 +; copy the name and level of the card at wLoadedCard1 to wDefaultText +; a = string length in number of tiles (padded with spaces to fit) +CopyCardNameAndLevel: ; 29f5 (0:29f5) + farcall _CopyCardNameAndLevel ret ; 0x29fa @@ -6729,8 +7046,8 @@ DrawNarrowTextBox: ; 2a6f (0:2a6f) DrawNarrowTextBox_WaitForInput: ; 2a7c (0:2a7c) call DrawNarrowTextBox_PrintTextNoDelay xor a - ld hl, NarrowTextBoxPromptCursorData - call InitializeCursorParameters + ld hl, NarrowTextBoxMenuParameters + call InitializeMenuParameters call EnableLCD .wait_A_or_B_loop call DoFrame @@ -6740,13 +7057,13 @@ DrawNarrowTextBox_WaitForInput: ; 2a7c (0:2a7c) jr z, .wait_A_or_B_loop ret -NarrowTextBoxPromptCursorData: ; 2a96 (0:2a96) - db 10, 17 ; x, y +NarrowTextBoxMenuParameters: ; 2a96 (0:2a96) + db 10, 17 ; corsor x, cursor y db 1 ; y displacement between items db 1 ; number of items db $2f ; cursor tile number db $1d ; tile behind cursor - dw $0000 ; unknown function pointer if non-0 + dw $0000 ; function pointer if non-0 ; draws a 20x6 text box aligned to the bottom of the screen DrawWideTextBox: ; 2a9e (0:2a9e) @@ -6761,8 +7078,8 @@ DrawWideTextBox_WaitForInput: ; 2aab (0:2aab) ; fallthrough WaitForWideTextBoxInput: ; 2aae (0:2aae) xor a - ld hl, WideTextBoxPromptCursorData - call InitializeCursorParameters + ld hl, WideTextBoxMenuParameters + call InitializeMenuParameters call EnableLCD .wait_A_or_B_loop call DoFrame @@ -6773,13 +7090,13 @@ WaitForWideTextBoxInput: ; 2aae (0:2aae) call EraseCursor ret -WideTextBoxPromptCursorData: ; 2ac8 (0:2ac8) - db 18, 17 ; x, y +WideTextBoxMenuParameters: ; 2ac8 (0:2ac8) + db 18, 17 ; cursor x, cursor y db 1 ; y displacement between items db 1 ; number of items db $2f ; cursor tile number db $1d ; tile behind cursor - dw $0000 ; unknown function pointer if non-0 + dw $0000 ; function pointer if non-0 TwoItemHorizontalMenu: ; 2ad0 (0:2ad0) call DrawWideTextBox_PrintText @@ -6865,7 +7182,7 @@ HandleYesOrNoMenu: .no xor a ld [wcd9a], a ; 0 - ld a, $1 + ld a, 1 ldh [hCurrentMenuItem], a scf ret @@ -6950,7 +7267,7 @@ Func_2bc7: ; 2bc7 (0:2bc7) Func_2bcf: ; 2bcf (0:2bcf) ld a, $4 call Func_2bdb - ldh [hffa0], a + ldh [hTemp_ffa0], a ret Func_2bd7: ; 2bd7 (0:2bd7) @@ -7027,7 +7344,52 @@ Func_2c29: ; 2c29 (0:2c29) ret ; 0x2c37 - INCROM $2c37, $2c73 +Func_2c37: ; 2c37 (0:2c37) + push hl + push de + push bc + ldh a, [hBankROM] + push af + call ReadTextOffset + ld c, $00 +.char_loop + ld a, [hli] + or a ; TX_END + jr z, .end + cp $10 + jr nc, .char_loop + cp TX_START + jr c, .skip + cp "\n" + jr nz, .char_loop + inc c + jr .char_loop +.skip + inc hl + jr .char_loop +.end + pop af + call BankswitchHome + ld a, c + inc a + pop bc + pop de + pop hl + ret +; 0x2c62 + +Func_2c62: ; 2c62 (0:2c62) + call .asm_2c67 + jr Func_2c77 +.asm_2c67 + push hl + ld hl, wce4c + ld [hl], e + inc hl + ld [hl], d + pop hl + ld a, $01 + jr Func_2c84 Func_2c73: ; 2c73 (0:2c73) xor a @@ -7161,9 +7523,9 @@ Func_2d15: ; 2d15 (0:2d15) Func_2d43: ; 2d43 (0:2d43) call Func_2cf3 ld a, [hli] - or a + or a ; TX_END jr z, .asm_2d79 - cp $5 + cp TX_SYMBOL jr c, .asm_2d65 cp $10 jr nc, .asm_2d65 @@ -7225,7 +7587,7 @@ Func_2d43: ; 2d43 (0:2d43) ld de, wTxRam3 ld hl, wce4a call Func_2de0 - call Func_2e12 + call TwoByteNumberToText_CountLeadingZeros call Func_2cd7 jp Func_2d43 .tx_ram1 @@ -7286,22 +7648,24 @@ ReadTextOffset: ; 2ded (0:2ded) pop de ret -Func_2e12: ; 2e12 (0:2e12) +; convert the number at hl to text (ascii) format and write it to wcaa0 +; return c = 4 - leading_zeros +TwoByteNumberToText_CountLeadingZeros: ; 2e12 (0:2e12) ld a, [wcd0a] or a - jp z, Func_245d + jp z, TwoByteNumberToLargeText_TrimLeadingZeros ld de, wcaa0 push de - call Func_0663 + call TwoByteNumberToText pop hl - ld c, $4 -.asm_2e23 + ld c, 4 +.digit_loop ld a, [hl] - cp $30 + cp "0" ret nz inc hl dec c - jr nz, .asm_2e23 + jr nz, .digit_loop ret ; copy the name of the duelist whose turn it is to de @@ -7370,11 +7734,9 @@ PrintTextNoDelay: ; 2e76 (0:2e76) call BankswitchHome ret -; Prints a name in the left side of the top border of a text box, usually to identify the talked-to NPC. -; input: - ; hl: text id - ; de: where to print the name -PrintTextBoxBorderLabel: ; 2e89 (0:2e89) +; copies a text given its id at hl, to de +; if hl is 0, the name of the turn duelist is copied instead +CopyText: ; 2e89 (0:2e89) ld a, l or h jr z, .special @@ -7552,8 +7914,10 @@ GetCardPointer: ; 2f7c (0:2f7c) pop de ret -; input: hl = card_gfx_index +; input: hl = card_gfx_index, de = where to load the card gfx to +; bc are supposed to be $30 and TILE_SIZE ; card_gfx_index = (<Name>CardGfx - CardGraphics) / 8 ; using absolute ROM addresses +; also copies the card's palette to wCardPalette LoadCardGfx: ; 2fa0 (0:2fa0) ldh a, [hBankROM] push af @@ -7574,7 +7938,7 @@ LoadCardGfx: ; 2fa0 (0:2fa0) set 6, h ; $4000 ≤ de ≤ $7fff call CopyGfxData ld b, CGB_PAL_SIZE - ld de, wce23 + ld de, wCardPalette .copy_card_palette ld a, [hli] ld [de], a @@ -8363,7 +8727,7 @@ HandleSandAttackOrSmokescreenSubstatus: ; 3400 (0:3400) call CheckSandAttackOrSmokescreenSubstatus ret nc call TossCoin - ld [wcc0a], a + ld [wGotHeadsFromSandAttackOrSmokescreenCheck], a ccf ret nc ldtx hl, AttackUnsuccessfulText @@ -8386,7 +8750,7 @@ CheckSandAttackOrSmokescreenSubstatus: ; 3414 (0:3414) or a ret .card_is_affected - ld a, [wcc0a] + ld a, [wGotHeadsFromSandAttackOrSmokescreenCheck] or a ret nz scf @@ -8678,7 +9042,7 @@ CheckCantUseTrainerDueToHeadache: ; 35a9 (0:35a9) ret ; 0x35b7 -; return carry if turn holder has Aerodactyl and its Prehistoric Power Pkmn Power is active +; return carry if any duelist has Aerodactyl and its Prehistoric Power Pkmn Power is active IsPrehistoricPowerActive: ; 35b7 (0:35b7) ld a, AERODACTYL call CountPokemonIDInBothPlayAreas @@ -9020,12 +9384,14 @@ PlaySong: ; 3785 (0:3785) farcall _PlaySong ret -Func_378a: ; 378a (0:378a) - farcall Func_f400f +; return a = 0: song finished, a = 1: song not finished +AssertSongFinished: ; 378a (0:378a) + farcall _AssertSongFinished ret -Func_378f: ; 378f (0:378f) - farcall Func_f4012 +; return a = 0: SFX finished, a = 1: SFX not finished +AssertSFXFinished: ; 378f (0:378f) + farcall _AssertSFXFinished ret Func_3794: ; 3794 (0:3794) @@ -9134,8 +9500,8 @@ GameEvent_BattleCenter: ; 38a3 (0:38a3) ld [wd0c2], a xor a ld [wd112], a - ld a, $ff - ld [wd0c3], a + ld a, -1 + ld [wDuelResult], a ld a, $2 ld [wDuelTheme], a ld a, MUSIC_CARD_POP @@ -9300,6 +9666,7 @@ Func_39a7: ; 39a7 (0:39a7) call Func_39ad ret +; return hl = wd34a + a * $c + l, a < $8 Func_39ad: ; 39ad (0:39ad) push bc cp $8 @@ -9369,7 +9736,7 @@ Func_39ea: ; 39ea (0:39ea) Func_39fc: ; 39fc (0:39fc) push hl push bc - call Func_378a + call AssertSongFinished or a push af call Func_3a1f @@ -9599,7 +9966,7 @@ Func_3b31: ; 3b31 (0:3b31) ld [wDoFrameFunction], a ld [wcad4], a .asm_3b45 - call InitSpritePositions + call ZeroObjectPositions ld a, $1 ld [wVBlankOAMCopyToggle], a pop af @@ -9780,7 +10147,7 @@ Func_3c87: ; 3c87 (0:3c87) Func_3c96: ; 3c96 (0:3c96) call DoFrameIfLCDEnabled - call Func_378a + call AssertSongFinished or a jr nz, Func_3c96 ret |