From 0e8f6e6a69a76622a9e7504ad2af7d863e99f383 Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Fri, 2 Feb 2024 17:11:01 +0000 Subject: [PATCH 1/2] Disassemble menu and printer functions --- src/constants.asm | 2 + src/constants/card_data_constants.asm | 43 +- src/constants/duel_constants.asm | 33 +- src/constants/duel_interface_constants.asm | 20 + src/constants/gfx_constants.asm | 15 + src/constants/menu_constants.asm | 62 + src/constants/printer_constants.asm | 17 + src/constants/scene_constants.asm | 74 +- src/engine/bank01.asm | 2113 +++++++++- src/engine/bank02.asm | 4328 +++++++++++++++++++- src/engine/bank03.asm | 2 +- src/engine/bank04.asm | 531 ++- src/engine/bank06.asm | 1288 +++++- src/engine/bank07.asm | 68 +- src/engine/bank09.asm | 269 +- src/engine/bank0e.asm | 1094 +++++ src/engine/glossary.asm | 368 ++ src/engine/scenes.asm | 78 +- src/gfx/menu_cursor.png | Bin 0 -> 89 bytes src/home/card_collection.asm | 2 +- src/home/card_data.asm | 41 +- src/home/double_speed.asm | 4 +- src/home/duel.asm | 31 +- src/home/menus.asm | 70 +- src/home/print_text.asm | 2 +- src/home/printer.asm | 179 +- src/home/process_text.asm | 16 +- src/home/serial.asm | 12 +- src/home/text_box.asm | 4 +- src/home/tiles.asm | 10 +- src/home/unsorted.asm | 34 +- src/home/vram.asm | 4 +- src/hram.asm | 15 +- src/layout.link | 22 +- src/macros/code.asm | 9 + src/macros/data.asm | 11 + src/macros/wram.asm | 7 +- src/main.asm | 3 + src/sram.asm | 16 +- src/wram.asm | 495 ++- 40 files changed, 10828 insertions(+), 564 deletions(-) create mode 100644 src/constants/duel_interface_constants.asm create mode 100644 src/constants/printer_constants.asm create mode 100644 src/engine/bank0e.asm create mode 100644 src/engine/glossary.asm create mode 100644 src/gfx/menu_cursor.png diff --git a/src/constants.asm b/src/constants.asm index fdff1b4..49ccbe7 100644 --- a/src/constants.asm +++ b/src/constants.asm @@ -6,6 +6,7 @@ INCLUDE "constants/credits_constants.asm" INCLUDE "constants/deck_ai_constants.asm" INCLUDE "constants/deck_constants.asm" INCLUDE "constants/duel_constants.asm" +INCLUDE "constants/duel_interface_constants.asm" INCLUDE "constants/gfx_constants.asm" INCLUDE "constants/hardware_constants.asm" INCLUDE "constants/intro_constants.asm" @@ -18,6 +19,7 @@ INCLUDE "constants/ow_anim_constants.asm" INCLUDE "constants/ow_object_constants.asm" INCLUDE "constants/palette_constants.asm" INCLUDE "constants/portrait_constants.asm" +INCLUDE "constants/printer_constants.asm" INCLUDE "constants/scene_constants.asm" INCLUDE "constants/script_constants.asm" INCLUDE "constants/sfx_constants.asm" diff --git a/src/constants/card_data_constants.asm b/src/constants/card_data_constants.asm index 8472eae..e3c6f12 100644 --- a/src/constants/card_data_constants.asm +++ b/src/constants/card_data_constants.asm @@ -10,7 +10,7 @@ DEF CARD_COUNT_MASK EQU $7f ; sDeck* and generic deck constants DEF NUM_DECKS EQU 4 DEF DECK_NAME_SIZE EQU 24 -DEF DECK_NAME_SIZE_WO_SUFFIX EQU 21 ; name part before "deck" +DEF DECK_NAME_SIZE_WO_SUFFIX EQU 20 ; name part before "deck" DEF DECK_SIZE EQU 60 DEF DECK_SIZE_BYTES EQU DECK_SIZE * 2 DEF DECK_STRUCT_SIZE EQU DECK_NAME_SIZE + DECK_SIZE_BYTES @@ -75,9 +75,9 @@ DEF CARD_DATA_POKEDEX_NUMBER EQU $37 DEF CARD_DATA_UNKNOWN1 EQU $38 DEF CARD_DATA_LEVEL EQU $39 DEF CARD_DATA_LENGTH EQU $3a -DEF CARD_DATA_WEIGHT EQU $3c -DEF CARD_DATA_PKMN_DESCRIPTION EQU $3e -DEF CARD_DATA_UNKNOWN2 EQU $40 +DEF CARD_DATA_WEIGHT EQU $3b +DEF CARD_DATA_PKMN_DESCRIPTION EQU $3d +DEF CARD_DATA_UNKNOWN2 EQU $3f DEF PKMN_CARD_DATA_LENGTH EQU $42 @@ -91,7 +91,7 @@ DEF PKMN_CARD_DATA_LENGTH EQU $42 const PSYCHIC ; $05 DEF NUM_COLORED_TYPES EQU const_value const COLORLESS ; $06 - const UNUSED_TYPE ; $07 + const RAINBOW ; $07 DEF NUM_TYPES EQU const_value ; generic type (color) flag constants @@ -111,7 +111,7 @@ DEF TYPE_PKMN_WATER EQU WATER DEF TYPE_PKMN_FIGHTING EQU FIGHTING DEF TYPE_PKMN_PSYCHIC EQU PSYCHIC DEF TYPE_PKMN_COLORLESS EQU COLORLESS -DEF TYPE_PKMN_UNUSED EQU UNUSED_TYPE +DEF TYPE_PKMN_UNUSED EQU RAINBOW const_def TYPE_PKMN_UNUSED + 1 - TYPE_PKMN_FIRE DEF TYPE_ENERGY EQU const_value const TYPE_ENERGY_FIRE ; $08 @@ -134,31 +134,20 @@ DEF TYPE_TRAINER_F EQU 4 DEF CIRCLE EQU $0 DEF DIAMOND EQU $1 DEF STAR EQU $2 +DEF RARITY_3 EQU $3 DEF PROMOSTAR EQU $ff ; card set constants (set 1) const_def - const CARD_SET_COLOSSEUM ; $0 - const CARD_SET_EVOLUTION ; $1 - const CARD_SET_MYSTERY ; $2 - const CARD_SET_LABORATORY ; $3 - const CARD_SET_PROMOTIONAL ; $4 - const CARD_SET_ENERGY ; $5 -DEF NUM_CARD_SETS EQU const_value - 1 - -; CARD_DATA_SET constants (set 1) -DEF COLOSSEUM EQU CARD_SET_COLOSSEUM << 4 -DEF EVOLUTION EQU CARD_SET_EVOLUTION << 4 -DEF MYSTERY EQU CARD_SET_MYSTERY << 4 -DEF LABORATORY EQU CARD_SET_LABORATORY << 4 -DEF PROMOTIONAL EQU CARD_SET_PROMOTIONAL << 4 -DEF ENERGY EQU CARD_SET_ENERGY << 4 - -; CARD_DATA_SET constants (set 2) -DEF JUNGLE EQU $1 -DEF FOSSIL EQU $2 -DEF GB EQU $7 -DEF PRO EQU $8 + const BEGINNING_POKEMON ; $0 + const LEGENDARY_POWER ; $1 + const ISLAND_OF_FOSSIL ; $2 + const PSYCHIC_BATTLE ; $3 + const SKY_FLYING_POKEMON ; $4 + const WE_ARE_TEAM_ROCKET ; $5 + const TEAM_ROCKETS_AMBITION ; $6 + const PROMOTIONAL ; $7 +DEF NUM_CARD_SETS EQU const_value ; CARD_DATA_STAGE constants DEF BASIC EQU $00 diff --git a/src/constants/duel_constants.asm b/src/constants/duel_constants.asm index 1f5a28e..2846c7f 100644 --- a/src/constants/duel_constants.asm +++ b/src/constants/duel_constants.asm @@ -63,6 +63,13 @@ DEF DUELVARS_BENCH2_CARD_ATTACHED_PLUSPOWER EQUS "LOW(wPlayerBench2CardAttache DEF DUELVARS_BENCH3_CARD_ATTACHED_PLUSPOWER EQUS "LOW(wPlayerBench3CardAttachedPluspower)" ; e3 DEF DUELVARS_BENCH4_CARD_ATTACHED_PLUSPOWER EQUS "LOW(wPlayerBench4CardAttachedPluspower)" ; e4 DEF DUELVARS_BENCH5_CARD_ATTACHED_PLUSPOWER EQUS "LOW(wPlayerBench5CardAttachedPluspower)" ; e5 +DEF DUELVARS_ARENA_CARD_FOOD_COUNTERS EQU $e6 ; EQUS "LOW(wPlayerArenaCardFoodCounters)" ; e6 +DEF DUELVARS_BENCH1_CARD_FOOD_COUNTERS EQU $e7 ; EQUS "LOW(wPlayerBench1FoodCounters)" ; e7 +DEF DUELVARS_BENCH2_CARD_FOOD_COUNTERS EQU $e8 ; EQUS "LOW(wPlayerBench2FoodCounters)" ; e8 +DEF DUELVARS_BENCH3_CARD_FOOD_COUNTERS EQU $e9 ; EQUS "LOW(wPlayerBench3FoodCounters)" ; e9 +DEF DUELVARS_BENCH4_CARD_FOOD_COUNTERS EQU $ea ; EQUS "LOW(wPlayerBench4FoodCounters)" ; ea +DEF DUELVARS_BENCH5_CARD_FOOD_COUNTERS EQU $eb ; EQUS "LOW(wPlayerBench5FoodCounters)" ; eb +DEF DUELVARS_ARENA_CARD_STATUS EQU $ec ; EQUS "LOW(wPlayerArenaCardStatus)" ; f0 DEF DUELVARS_ARENA_CARD_SUBSTATUS1 EQU $ed ; EQUS "LOW(wPlayerArenaCardSubstatus1)" ; e7 DEF DUELVARS_ARENA_CARD_SUBSTATUS2 EQU $ee ; EQUS "LOW(wPlayerArenaCardSubstatus2)" ; e8 DEF DUELVARS_ARENA_CARD_CHANGED_WEAKNESS EQU $ef ; EQUS "LOW(wPlayerArenaCardChangedWeakness)" ; e9 @@ -72,7 +79,6 @@ DEF DUELVARS_PRIZES EQU $f2 ; EQUS "LOW(wPlayerPrizes) DEF DUELVARS_NUMBER_OF_CARDS_IN_DISCARD_PILE EQU $f3 ; EQUS "LOW(wPlayerNumberOfCardsInDiscardPile)" ; ed DEF DUELVARS_NUMBER_OF_CARDS_IN_HAND EQU $f4 ; EQUS "LOW(wPlayerNumberOfCardsInHand)" ; ee DEF DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA EQU $f5 ; EQUS "LOW(wPlayerNumberOfPokemonInPlayArea)" ; ef -DEF DUELVARS_ARENA_CARD_STATUS EQU $ec ; EQUS "LOW(wPlayerArenaCardStatus)" ; f0 DEF DUELVARS_DUELIST_TYPE EQU $f6 ; EQUS "LOW(wPlayerDuelistType)" ; f1 DEF DUELVARS_ARENA_CARD_DISABLED_ATTACK_INDEX EQU $f7 ; EQUS "LOW(wPlayerArenaCardDisabledAttackIndex)" ; f2 DEF DUELVARS_ARENA_CARD_LAST_TURN_DAMAGE EQUS "LOW(wPlayerArenaCardLastTurnDamage)" ; f3 @@ -266,8 +272,23 @@ DEF PRIZES_5 EQU $05 DEF PRIZES_6 EQU $06 ; constants to use as input to LookForCardInDeck -DEF SEARCHEFFECT_CARD_ID EQU $0 -DEF SEARCHEFFECT_NIDORAN EQU $1 -DEF SEARCHEFFECT_BASIC_FIGHTING EQU $2 -DEF SEARCHEFFECT_BASIC_ENERGY EQU $3 -DEF SEARCHEFFECT_POKEMON EQU $4 + const_def + const SEARCHEFFECT_CARD_ID ; $0 + const SEARCHEFFECT_NIDORAN ; $1 + const SEARCHEFFECT_BASIC_FIGHTING ; $2 + const SEARCHEFFECT_BASIC_ENERGY ; $3 + const SEARCHEFFECT_POKEMON ; $4 + +; special rule constants, stored in wSpecialRule + const_def + const NO_RULES ; $0 + const CHLOROPHYLL ; $1 + const THUNDER_CHARGE ; $2 + const FLAME_ARMOR ; $3 + const SMALL_BENCH ; $4 + const RUNNING_WATER ; $5 + const EARTH_POWER ; $6 + const LOW_RESISTANCE ; $7 + const ENERGY_RETURN ; $8 + const TOUGH_ESCAPE ; $9 + const BLACK_HOLE ; $a diff --git a/src/constants/duel_interface_constants.asm b/src/constants/duel_interface_constants.asm new file mode 100644 index 0000000..5951ea0 --- /dev/null +++ b/src/constants/duel_interface_constants.asm @@ -0,0 +1,20 @@ +; wCardPageNumber constants +DEF CARDPAGE_POKEMON_OVERVIEW EQU $01 +DEF CARDPAGE_POKEMON_ATTACK1_1 EQU $02 +DEF CARDPAGE_POKEMON_ATTACK1_2 EQU $03 +DEF CARDPAGE_POKEMON_ATTACK2_1 EQU $04 +DEF CARDPAGE_POKEMON_ATTACK2_2 EQU $05 +DEF CARDPAGE_POKEMON_DESCRIPTION EQU $06 +DEF CARDPAGE_ENERGY_1 EQU $09 +DEF CARDPAGE_ENERGY_2 EQU $0a +DEF CARDPAGE_TRAINER_1 EQU $0d +DEF CARDPAGE_TRAINER_2 EQU $0e + +; wCardPageType constants +DEF CARDPAGETYPE_NOT_PLAY_AREA EQU $00 +DEF CARDPAGETYPE_PLAY_AREA EQU $01 + +; card type header constants ($10-tile headers in DuelCardHeaderGraphics) +DEF HEADER_TRAINER EQU $00 +DEF HEADER_ENERGY EQU $01 +DEF HEADER_POKEMON EQU $02 diff --git a/src/constants/gfx_constants.asm b/src/constants/gfx_constants.asm index 9cf4d5f..21ba3fb 100644 --- a/src/constants/gfx_constants.asm +++ b/src/constants/gfx_constants.asm @@ -21,3 +21,18 @@ DEF tiles EQUS "* TILE_SIZE" DEF TILE_SIZE_1BPP EQU 8 ; bytes DEF tiles_1bpp EQUS "* TILE_SIZE_1BPP" + +; icon tile offsets +DEF ICON_TILE_BASIC_POKEMON EQU $d0 +DEF ICON_TILE_STAGE_1_POKEMON EQU $d4 +DEF ICON_TILE_STAGE_2_POKEMON EQU $d8 +DEF ICON_TILE_TRAINER EQU $dc + +DEF ICON_TILE_FIRE EQU $e0 +DEF ICON_TILE_GRASS EQU $e4 +DEF ICON_TILE_LIGHTNING EQU $e8 +DEF ICON_TILE_WATER EQU $ec +DEF ICON_TILE_FIGHTING EQU $f0 +DEF ICON_TILE_PSYCHIC EQU $f4 +DEF ICON_TILE_COLORLESS EQU $f8 +DEF ICON_TILE_ENERGY EQU $fc diff --git a/src/constants/menu_constants.asm b/src/constants/menu_constants.asm index 845da84..6f5e91c 100644 --- a/src/constants/menu_constants.asm +++ b/src/constants/menu_constants.asm @@ -31,4 +31,66 @@ const STARTMENU_NEW_GAME ; 2 const STARTMENU_CONTINUE_DUEL ; 3 +; constants for wGlossaryMenu + const_def + const GLOSSARY_GAME_BASICS ; $0 + const GLOSSARY_CARD_TYPE_EXPLANATIONS ; $1 + const GLOSSARY_STATUS_WINNING_LOSING ; $2 + const GLOSSARY_SPECIAL_DUEL_RULES ; $3 + const GLOSSARY_EXIT ; $4 + +; filter types for CardTypeFilters +; used to categorise the different cards +; i.e. in the deck building screen +DEF FILTER_FIRE EQUS "TYPE_PKMN_FIRE" +DEF FILTER_GRASS EQUS "TYPE_PKMN_GRASS" +DEF FILTER_LIGHTNING EQUS "TYPE_PKMN_LIGHTNING" +DEF FILTER_WATER EQUS "TYPE_PKMN_WATER" +DEF FILTER_FIGHTING EQUS "TYPE_PKMN_FIGHTING" +DEF FILTER_PSYCHIC EQUS "TYPE_PKMN_PSYCHIC" +DEF FILTER_COLORLESS EQUS "TYPE_PKMN_COLORLESS" +DEF FILTER_TRAINER EQUS "TYPE_TRAINER" +DEF FILTER_ENERGY EQU $20 + +DEF NUM_FILTERS EQU 9 + +DEF NUM_DECK_CONFIRMATION_VISIBLE_CARDS EQU 7 + DEF NUM_DECK_SAVE_MACHINE_SLOTS EQU 50 +DEF NUM_DECK_MACHINE_VISIBLE_DECKS EQU 5 + +; deck flags + const_def + const DECK_1_F ; $0 + const DECK_2_F ; $1 + const DECK_3_F ; $2 + const DECK_4_F ; $3 + +DEF DECK_1 EQU 1 << DECK_1_F ; $1 +DEF DECK_2 EQU 1 << DECK_2_F ; $2 +DEF DECK_3 EQU 1 << DECK_3_F ; $4 +DEF DECK_4 EQU 1 << DECK_4_F ; $8 + +DEF ALL_DECKS EQU $ff + +; flags in wOwnedPhantomCards + const_def + const PROMO_VENUSAUR_LV64_F ; $0 + const PROMO_MEW_LV15_F ; $1 + const PROMO_LUGIA_F ; $2 + const PROMO_HERE_COMES_TEAM_ROCKET_F ; $3 + +DEF PROMO_VENUSAUR_LV64 EQU (1 << PROMO_VENUSAUR_LV64_F) +DEF PROMO_MEW_LV15 EQU (1 << PROMO_MEW_LV15_F) +DEF PROMO_LUGIA EQU (1 << PROMO_LUGIA_F) +DEF PROMO_HERE_COMES_TEAM_ROCKET EQU (1 << PROMO_HERE_COMES_TEAM_ROCKET_F) + +; TODO find a way to not have these hardcoded? +DEF NUM_CARDS_BEGINNING_POKEMON EQU 66 +DEF NUM_CARDS_LEGENDARY_POWER EQU 61 +DEF NUM_CARDS_ISLAND_OF_FOSSIL EQU 59 +DEF NUM_CARDS_PSYCHIC_BATTLE EQU 54 +DEF NUM_CARDS_SKY_FLYING_POKEMON EQU 56 +DEF NUM_CARDS_WE_ARE_TEAM_ROCKET EQU 50 +DEF NUM_CARDS_TEAM_ROCKETS_AMBITION EQU 50 +DEF NUM_CARDS_PROMOTIONAL EQU 45 ; doesn't include Phantom cards diff --git a/src/constants/printer_constants.asm b/src/constants/printer_constants.asm new file mode 100644 index 0000000..715c982 --- /dev/null +++ b/src/constants/printer_constants.asm @@ -0,0 +1,17 @@ +; wPrinterStatus + const_def + const PRINTER_ERROR_CHECKSUM ; $0 + const PRINTER_STATUS_BUSY ; $1 + const PRINTER_STATUS_IMAGE_FULL ; $2 + const PRINTER_STATUS_PRINTING ; $3 + const PRINTER_ERROR_INVALID_PACKET ; $4 + const PRINTER_ERROR_PAPER_JAMMED ; $5 + const PRINTER_ERROR_CABLE_PRINTER_SWITCH ; $6 + const PRINTER_ERROR_BATTERIES_LOST_CHARGE ; $7 + +; printer packet types +DEF PRINTERPKT_INIT EQU $01 +DEF PRINTERPKT_PRINT_INSTRUCTION EQU $02 +DEF PRINTERPKT_DATA EQU $04 +DEF PRINTERPKT_BREAK EQU $08 +DEF PRINTERPKT_NUL EQU $0f diff --git a/src/constants/scene_constants.asm b/src/constants/scene_constants.asm index 1247c9d..f674f95 100644 --- a/src/constants/scene_constants.asm +++ b/src/constants/scene_constants.asm @@ -1,38 +1,38 @@ const_def - const SCENE_SPECIAL_RULES ; $00 - const SCENE_SLOT_MACHINE ; $01 - const SCENE_BEGINNING_PACK ; $02 - const SCENE_LEGENDARY_PACK ; $03 - const SCENE_FOSSIL_PACK ; $04 - const SCENE_PSYCHIC_PACK ; $05 - const SCENE_FLYING_PACK ; $06 - const SCENE_ROCKET_PACK ; $07 - const SCENE_AMBITION_PACK ; $08 - const SCENE_PRESENT_PACK ; $09 - const SCENE_INTRO_BASE_SET ; $0a - const SCENE_INTRO_JUNGLE ; $0b - const SCENE_INTRO_FOSSIL ; $0c - const SCENE_INTRO_TEAM_ROCKET ; $0d - const SCENE_TOURNAMENT_TABLE ; $0e - const SCENE_CARD_POP_MENU ; $0f - const SCENE_CARD_POP ; $10 - const SCENE_CARD_POP_ERROR ; $11 - const SCENE_LINK ; $12 - const SCENE_RARE_CARD_POP ; $13 - const SCENE_RARE_CARD_POP_ERROR ; $14 - const SCENE_BLACK_BOX ; $15 - const SCENE_TITLE_SCREEN_1 ; $16 - const SCENE_TITLE_SCREEN_2 ; $17 - const SCENE_TITLE_SCREEN_3 ; $18 - const SCENE_TITLE_SCREEN_4 ; $19 - const SCENE_PRINTER_1 ; $1a - const SCENE_PRINTER_2 ; $1b - const SCENE_FULL_MAILBOX ; $1c - const SCENE_GOT_MAIL ; $1d - const SCENE_MAILBOX ; $1e - const SCENE_DECK_DIAGNOSIS ; $1f - const SCENE_LINK_INTRO_1 ; $20 - const SCENE_LINK_INTRO_2 ; $21 - const SCENE_COIN_TOSS_RESULT_1 ; $22 - const SCENE_COIN_TOSS_RESULT_2 ; $23 - const SCENE_GBC_ONLY_DISCLAIMER ; $24 + const SCENE_SPECIAL_RULES ; $00 + const SCENE_SLOT_MACHINE ; $01 + const SCENE_BEGINNING_PACK ; $02 + const SCENE_LEGENDARY_PACK ; $03 + const SCENE_FOSSIL_PACK ; $04 + const SCENE_PSYCHIC_PACK ; $05 + const SCENE_FLYING_PACK ; $06 + const SCENE_ROCKET_PACK ; $07 + const SCENE_AMBITION_PACK ; $08 + const SCENE_PRESENT_PACK ; $09 + const SCENE_INTRO_BASE_SET ; $0a + const SCENE_INTRO_JUNGLE ; $0b + const SCENE_INTRO_FOSSIL ; $0c + const SCENE_INTRO_TEAM_ROCKET ; $0d + const SCENE_TOURNAMENT_TABLE ; $0e + const SCENE_CARD_POP_MENU ; $0f + const SCENE_CARD_POP ; $10 + const SCENE_CARD_POP_ERROR ; $11 + const SCENE_LINK ; $12 + const SCENE_RARE_CARD_POP ; $13 + const SCENE_RARE_CARD_POP_ERROR ; $14 + const SCENE_BLACK_BOX ; $15 + const SCENE_TITLE_SCREEN_1 ; $16 + const SCENE_TITLE_SCREEN_2 ; $17 + const SCENE_TITLE_SCREEN_3 ; $18 + const SCENE_TITLE_SCREEN_4 ; $19 + const SCENE_GAMEBOY_PRINTER_TRANSMITTING ; $1a + const SCENE_GAMEBOY_PRINTER_NOT_CONNECTED ; $1b + const SCENE_FULL_MAILBOX ; $1c + const SCENE_GOT_MAIL ; $1d + const SCENE_MAILBOX ; $1e + const SCENE_DECK_DIAGNOSIS ; $1f + const SCENE_LINK_INTRO_1 ; $20 + const SCENE_LINK_INTRO_2 ; $21 + const SCENE_COIN_TOSS_RESULT_1 ; $22 + const SCENE_COIN_TOSS_RESULT_2 ; $23 + const SCENE_GBC_ONLY_DISCLAIMER ; $24 diff --git a/src/engine/bank01.asm b/src/engine/bank01.asm index 838df0b..d73c7fa 100644 --- a/src/engine/bank01.asm +++ b/src/engine/bank01.asm @@ -1,4 +1,601 @@ -SECTION "Bank 1@563e", ROMX[$563e], BANK[$1] +SECTION "Bank 1@4cd7", ROMX[$4cd7], BANK[$1] + +DrawDuelMainScene: + ld a, [wDuelType] + cp $00 + jr nz, .asm_4ced + ldh a, [hWhoseTurn] + push af + ld a, [wcbfd] + ldh [hWhoseTurn], a + call .Draw + pop af + ldh [hWhoseTurn], a + ret + +.asm_4ced + ldh a, [hWhoseTurn] + push af + ld a, PLAYER_TURN + ldh [hWhoseTurn], a + call .Draw + pop af + ldh [hWhoseTurn], a + ret + +.Draw: + ld a, [wDuelDisplayedScreen] + cp $01 + ret z + call ZeroObjectPositionsAndToggleOAMCopy + call EmptyScreen + call LoadSymbolsFont + ld a, $01 + ld [wDuelDisplayedScreen], a + + ld a, DUELVARS_ARENA_CARD + get_turn_duelist_var + cp $ff + jr z, .turn_duelist_no_arena + ld de, v0Tiles1 + $50 tiles + call LoadCardGfxFromDeckIndex + lb de, 0, 5 + call DrawCardGfxToDE_BGPalIndex2 +.turn_duelist_no_arena + call SwapTurn + ld a, DUELVARS_ARENA_CARD + get_turn_duelist_var + cp $ff + jr z, .non_turn_duelist_no_arena + ld de, v0Tiles1 + $20 tiles + call LoadCardGfxFromDeckIndex + lb de, 12, 1 + call DrawCardGfxToDE_BGPalIndex5 + call FlushAllPalettesIfNotDMG +.non_turn_duelist_no_arena + call SwapTurn +; next, draw the Pokemon in the arena +;.place_player_arena_pkmn + ld a, DUELVARS_ARENA_CARD + get_turn_duelist_var + cp $ff + 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 +.place_opponent_arena_pkmn + call SwapTurn + ld a, DUELVARS_ARENA_CARD + get_turn_duelist_var + cp $ff + 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 +.place_other_elements + call SwapTurn + ld hl, DuelEAndHPTileData + call WriteDataBlocksToBGMap0 + farcall DrawDuelHorizontalSeparator + call DrawDuelHUDs + call DrawWideTextBox + call EnableLCD + ret + +DrawDuelHUDs: + ld a, [wDuelDisplayedScreen] + cp $01 + ret nz + ld e, PLAYER_TURN + ld a, [wDuelType] + cp $00 + jr nz, .asm_4d95 + ld a, [wcbfd] + ld e, a +.asm_4d95 + ldh a, [hWhoseTurn] + push af + ld a, e + ldh [hWhoseTurn], a + 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 + get_turn_duelist_var + call CheckPrintCnfSlpPrz + inc c + call CheckPrintPoisoned + inc c + call CheckPrintDoublePoisoned ; if double poisoned, print a second poison icon + inc c + ld a, 1 + call CheckPrintFoodCounters + + 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 + get_turn_duelist_var + call CheckPrintCnfSlpPrz + dec c + call CheckPrintPoisoned + dec c + call CheckPrintDoublePoisoned ; if double poisoned, print a second poison icon + dec c + ld a, -1 + call CheckPrintFoodCounters + pop af + ldh [hWhoseTurn], a + ret + +DuelEAndHPTileData: +; x, y, tiles[], 0 + db 1, 1, SYM_E, 0 + db 1, 2, SYM_HP, 0 + db 9, 8, SYM_E, 0 + db 9, 9, SYM_HP, 0 + db $ff ; end + +DrawDuelHUD: + ld hl, wHUDEnergyAndHPBarsX + ld [hl], b + inc hl + ld [hl], c ; wHUDEnergyAndHPBarsY + push de + ld d, 1 ; x + ld a, e + or a + jr z, .asm_4e05 + ld d, 15 ; x +.asm_4e05 + push de + pop bc + + ; number of Bench Pokemon + ld a, SYM_POKEMON + call WriteByteToBGMap0 + inc b + ld a, DUELVARS_NUMBER_OF_POKEMON_IN_PLAY_AREA + get_turn_duelist_var + add SYM_0 - 1 + call WriteByteToBGMap0 + inc b + + ; number of prize cards + ld a, SYM_PRIZE + call WriteByteToBGMap0 + inc b + call CountPrizes + add SYM_0 + call WriteByteToBGMap0 + pop de + + ; Arena card names + ld a, DUELVARS_ARENA_CARD + get_turn_duelist_var + cp $ff + ret z ; no arena card + 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 GetTextLengthInTiles + add SCREEN_WIDTH + ld d, a +.print_color_icon + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + 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, wHUDEnergyAndHPBarsX + ld b, [hl] + inc hl + ld c, [hl] ; wHUDEnergyAndHPBarsY + lb de, 9, PLAY_AREA_ARENA + call PrintPlayAreaCardAttachedEnergies + + ; print HP bar + ld a, DUELVARS_ARENA_CARD + get_turn_duelist_var + call LoadCardDataToBuffer1_FromDeckIndex + ld a, [wLoadedCard1HP] + ld d, a ; max HP + ld a, DUELVARS_ARENA_CARD_HP + get_turn_duelist_var + ld e, a ; cur HP + call DrawHPBar + ld hl, wHUDEnergyAndHPBarsX + ld b, [hl] + inc hl + ld c, [hl] ; wHUDEnergyAndHPBarsY + inc c ; [wHUDEnergyAndHPBarsY] + 1 + 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, wHUDEnergyAndHPBarsX + ld a, [hli] + add 6 + ld b, a + ld c, [hl] ; wHUDEnergyAndHPBarsY + inc c + ld a, DUELVARS_ARENA_CARD_ATTACHED_PLUSPOWER + get_turn_duelist_var + or a + jr z, .check_defender + ld a, SYM_PLUSPOWER + call WriteByteToBGMap0 + inc b + ld a, [hl] ; number of attached Pluspower + add SYM_0 + call WriteByteToBGMap0 + dec b +.check_defender + ld a, DUELVARS_ARENA_CARD_ATTACHED_DEFENDER + get_turn_duelist_var + or a + jr z, .done + inc c + ld a, SYM_DEFENDER + call WriteByteToBGMap0 + inc b + ld a, [hl] ; number of attached Defender + add SYM_0 + call WriteByteToBGMap0 +.done + ret +; 0x4ec6 + +SECTION "Bank 1@53e9", ROMX[$53e9], BANK[$1] + +; draw the card page of the card at wLoadedCard1 and listen for input +; in order to switch the page or to exit. +; triggered by checking a hand card or a discard pile card in the Check menu. +; D_UP and D_DOWN exit the card page allowing the caller to load the card page +; of the card above or below in the list. +OpenCardPage_FromCheckHandOrDiscardPile: + ld a, B_BUTTON | D_UP | D_DOWN + ld [wCardPageExitKeys], a + xor a ; CARDPAGETYPE_NOT_PLAY_AREA + jr OpenCardPage + +; draw the card page of the card at wLoadedCard1 and listen for input +; in order to switch the page or to exit. +; triggered by checking an arena card or a bench card in the Check menu. +OpenCardPage_FromCheckPlayArea: + ld a, B_BUTTON + ld [wCardPageExitKeys], a + ld a, CARDPAGETYPE_PLAY_AREA + jr OpenCardPage + +; draw the card page of the card at wLoadedCard1 and listen for input +; in order to switch the page or to exit. +; triggered by checking a card in the Hand menu. +OpenCardPage_FromHand: + ld a, B_BUTTON + ld [wCardPageExitKeys], a + xor a ; CARDPAGETYPE_NOT_PLAY_AREA +; fallthrough + +; draw the card page of the card at wLoadedCard1 and listen for input +; in order to switch the page or to exit. +OpenCardPage: + ld [wCardPageType], a + call ZeroObjectPositionsAndToggleOAMCopy + call EmptyScreen + call FinishQueuedAnimations + ; load the graphics and display the card image of wLoadedCard1 + call LoadDuelCardSymbolTiles + ld de, v0Tiles1 + $200 + call LoadLoadedCard1Gfx + lb de, 6, 4 + call DrawCardGfxToDE_BGPalIndex5 + call Func_6c12 + call FlushAllPalettesIfNotDMG + ; display the initial card page for the card at wLoadedCard1 + xor a + ld [wCardPageNumber], a + +.load_next + call DisplayFirstOrNextCardPage + jr c, .done ; done if trying to advance past the last page with START or A_BUTTON + +.loop_input + call DoFrame + ldh a, [hDPadHeld] + ld b, a + ld a, [wCardPageExitKeys] + and b + jr nz, .done + ; START and A_BUTTON advance to the next valid card page, but close it + ; after trying to advance from the last page + ldh a, [hKeysPressed] + and A_BUTTON | START + jr nz, .load_next + ; D_RIGHT and D_LEFT advance to the next and previous valid card page respectively. + ; however, unlike START and A_BUTTON, D_RIGHT past the last page goes back to the start. + ldh a, [hKeysPressed] + and D_RIGHT | D_LEFT + jr z, .loop_input + call .LeftOrRightPressed + jr .loop_input +.done + ret + +.LeftOrRightPressed: + bit D_LEFT_F, a + jr nz, .d_left +; d_right + call DisplayFirstOrNextCardPage + call c, DisplayCardPage + ret +.d_left + call DisplayPreviousCardPage + call c, DisplayCardPage + ret + +DrawCardPageCardGfx: + ld de, v0Tiles1 + $20 tiles + call LoadLoadedCard1Gfx + ld a, $a0 + lb hl, 6, 1 + lb de, 6, 4 + lb bc, 8, 6 + call FillRectangle + lb de, 6, 4 + call DrawCardGfxToDE_BGPalIndex5 + ret +; 0x5475 + +SECTION "Bank 1@553d", ROMX[$553d], BANK[$1] + +; display the previous valid card page +DisplayPreviousCardPage: + call GoToPreviousCardPage + jr nc, DisplayCardPage + ret + +; display the next valid card page or load the first valid card page if [wCardPageNumber] == 0 +DisplayFirstOrNextCardPage: + call GoToFirstOrNextCardPage + ret c +; fallthrough + +; display the card page with id at wCardPageNumber of wLoadedCard1 +DisplayCardPage: + ld a, [wCardPageNumber] + ld hl, CardPageDisplayPointerTable + call JumpToFunctionInTable + call EnableLCD + or a + ret +; 0x5555 + +SECTION "Bank 1@5570", ROMX[$5570], BANK[$1] + +CardPageDisplayPointerTable: + dw DrawDuelMainScene ; $0 + dw DisplayCardPage_PokemonOverview ; CARDPAGE_POKEMON_OVERVIEW + dw DisplayCardPage_PokemonAttack1Page1 ; CARDPAGE_POKEMON_ATTACK1_1 + dw DisplayCardPage_PokemonAttack1Page2 ; CARDPAGE_POKEMON_ATTACK1_2 + dw DisplayCardPage_PokemonAttack2Page1 ; CARDPAGE_POKEMON_ATTACK2_1 + dw DisplayCardPage_PokemonAttack2Page2 ; CARDPAGE_POKEMON_ATTACK2_2 + dw DisplayCardPage_PokemonDescription ; CARDPAGE_POKEMON_DESCRIPTION + dw DrawDuelMainScene ; $7 + dw DrawDuelMainScene ; $8 + dw DisplayCardPage_Energy1 ; CARDPAGE_ENERGY_1 + dw DisplayCardPage_Energy2 ; CARDPAGE_ENERGY_2 + dw DrawDuelMainScene ; $b + dw DrawDuelMainScene ; $c + dw DisplayCardPage_TrainerPage1 ; CARDPAGE_TRAINER_1 + dw DisplayCardPage_TrainerPage2 ; CARDPAGE_TRAINER_2 + dw DrawDuelMainScene ; $f + +; given the current card page at [wCardPageNumber], go to the next valid card page or load +; the first valid card page of the current card at wLoadedCard1 if [wCardPageNumber] == 0 +GoToFirstOrNextCardPage: + ld a, [wCardPageNumber] + or a + jr nz, .advance_page + ; load the first page for this type of card + ld a, [wLoadedCard1Type] + ld b, a + ld a, CARDPAGE_ENERGY_1 + bit TYPE_ENERGY_F, b + jr nz, .set_initial_page + ld a, CARDPAGE_TRAINER_1 + bit TYPE_TRAINER_F, b + jr nz, .set_initial_page + ld a, CARDPAGE_POKEMON_OVERVIEW +.set_initial_page + ld [wCardPageNumber], a + or a + ret + +.advance_page + ld hl, wCardPageNumber + inc [hl] + ld a, [hl] + call SwitchCardPage + jr c, .set_card_page + ; stay in this page if it exists, or skip to previous page if it doesn't + or a + ret nz + ; non-existent page: skip to next + jr .advance_page +.set_card_page + ld [wCardPageNumber], a + ret + +; given the current card page at [wCardPageNumber], go to the previous +; valid card page for the current card at wLoadedCard1 +GoToPreviousCardPage: + ld hl, wCardPageNumber + dec [hl] + ld a, [hl] + call SwitchCardPage + jr c, .set_card_page + ; stay in this page if it exists, or skip to previous page if it doesn't + or a + ret nz + ; non-existent page: skip to previous + jr GoToPreviousCardPage +.set_card_page + ld [wCardPageNumber], a +.previous_page_loop + call SwitchCardPage + or a + jr nz, .stay + ld hl, wCardPageNumber + dec [hl] + jr .previous_page_loop +.stay + scf + ret + +; check if the card page trying to switch to is valid for the card at wLoadedCard1 +; return with the equivalent to one of these three actions: + ; stay in card page trying to switch to (nc, nz) + ; change to card page returned in a if D_LEFT/D_RIGHT pressed, or exit if A_BUTTON/START pressed (c) + ; non-existent page, so skip to next/previous (nc, z) +SwitchCardPage: + ld hl, .CardPageSwitchPointerTable + jp JumpToFunctionInTable + +.CardPageSwitchPointerTable: + dw CardPageSwitch_00 + dw CardPageSwitch_PokemonOverviewOrDescription ; CARDPAGE_POKEMON_OVERVIEW + dw CardPageSwitch_PokemonAttack1Page1 ; CARDPAGE_POKEMON_ATTACK1_1 + dw CardPageSwitch_PokemonAttack1Page2 ; CARDPAGE_POKEMON_ATTACK1_2 + dw CardPageSwitch_PokemonAttack2Page1 ; CARDPAGE_POKEMON_ATTACK2_1 + dw CardPageSwitch_PokemonAttack2Page2 ; CARDPAGE_POKEMON_ATTACK2_2 + dw CardPageSwitch_PokemonOverviewOrDescription ; CARDPAGE_POKEMON_DESCRIPTION + dw CardPageSwitch_PokemonEnd + dw CardPageSwitch_08 + dw CardPageSwitch_EnergyOrTrainerPage1 ; CARDPAGE_ENERGY_1 + dw CardPageSwitch_TrainerPage2 ; CARDPAGE_ENERGY_1 + 1 + dw CardPageSwitch_EnergyEnd + dw CardPageSwitch_0c + dw CardPageSwitch_EnergyOrTrainerPage1 ; CARDPAGE_TRAINER_1 + dw CardPageSwitch_TrainerPage2 ; CARDPAGE_TRAINER_2 + dw CardPageSwitch_TrainerEnd + +; return with CARDPAGE_POKEMON_DESCRIPTION +CardPageSwitch_00: + ld a, CARDPAGE_POKEMON_DESCRIPTION + scf + ret + +; return with current page +CardPageSwitch_PokemonOverviewOrDescription: + ld a, $1 + or a + ret ; nz + +; return with current page if [wLoadedCard1Atk1Name] non-0 +; (if card has at least one attack) +CardPageSwitch_PokemonAttack1Page1: + ld hl, wLoadedCard1Atk1Name + jr CheckCardPageExists + +; return with current page if [wLoadedCard1Atk1Description + 2] non-0 +; (if card's first attack has a two-page description) +CardPageSwitch_PokemonAttack1Page2: + ld hl, wLoadedCard1Atk1Description + 2 + jr CheckCardPageExists + +; return with current page if [wLoadedCard1Atk2Name] non-0 +; (if card has two attacks) +CardPageSwitch_PokemonAttack2Page1: + ld hl, wLoadedCard1Atk2Name + jr CheckCardPageExists + +; return with current page if [wLoadedCard1Atk1Description + 2] non-0 +; (if card's second attack has a two-page description) +CardPageSwitch_PokemonAttack2Page2: + ld hl, wLoadedCard1Atk2Description + 2 +; fallthrough + +CheckCardPageExists: + ld a, [hli] + or [hl] + ret + +; return with CARDPAGE_POKEMON_OVERVIEW +CardPageSwitch_PokemonEnd: + ld a, CARDPAGE_POKEMON_OVERVIEW + scf + ret + +; return with CARDPAGE_ENERGY_1 + 1 +CardPageSwitch_08: + ld a, CARDPAGE_ENERGY_1 + 1 + scf + ret + +; return with current page +CardPageSwitch_EnergyOrTrainerPage1: + ld a, $1 + or a + ret ; nz + +; return with current page if [wLoadedCard1NonPokemonDescription + 2] non-0 +; (if this trainer card has a two-page description) +CardPageSwitch_TrainerPage2: + ld hl, wLoadedCard1NonPokemonDescription + 2 + jr CheckCardPageExists + +; return with CARDPAGE_ENERGY_1 +CardPageSwitch_EnergyEnd: + ld a, CARDPAGE_ENERGY_1 + scf + ret + +; return with CARDPAGE_TRAINER_2 +CardPageSwitch_0c: + ld a, CARDPAGE_TRAINER_2 + scf + ret + +; return with CARDPAGE_TRAINER_1 +CardPageSwitch_TrainerEnd: + ld a, CARDPAGE_TRAINER_1 + scf + ret ZeroObjectPositionsAndToggleOAMCopy: call ZeroObjectPositions @@ -6,18 +603,1224 @@ ZeroObjectPositionsAndToggleOAMCopy: ld [wVBlankOAMCopyToggle], a ret -SECTION "Bank 1@59f4", ROMX[$59f4], BANK[$1] +SECTION "Bank 1@5670", ROMX[$5670], BANK[$1] + +LoadCardGfxFromDeckIndex: + push de + call LoadCardDataToBuffer1_FromDeckIndex + pop de +; fallthrough + +LoadLoadedCard1Gfx: + ld hl, wLoadedCard1Gfx + ld a, [hli] + ld h, [hl] + ld l, a + lb bc, $30, TILE_SIZE + call LoadCardGfx + ret + +; applies the tilemap of the loaded card gfx +; to coordinates in de, and loads its palette +; starting from BG pal 2 +DrawCardGfxToDE_BGPalIndex2: + ld a, [wConsole] + or a + ret z + ld a, $02 + call LoadCardPalettesAndAttributes + ret + +; applies the tilemap of the loaded card gfx +; to coordinates in de, and loads its palette +; starting from BG pal 5 +DrawCardGfxToDE_BGPalIndex5: + ld a, [wConsole] + or a + ret z + ld a, $5 + call LoadCardPalettesAndAttributes + ret +; 0x5698 + +SECTION "Bank 1@56a6", ROMX[$56a6], BANK[$1] + +; de = coordinates +LoadCardPalettesAndAttributes: + push de + call .CopyCardPals + pop bc + + ; copy attributes + push hl + call BCCoordToBGMap0Address + pop hl + call BankswitchVRAM1 + ld c, $06 +.loop_copy_attr + ld b, $08 + push de + call SafeCopyDataHLtoDE + pop de + ld a, e + add BG_MAP_WIDTH + ld e, a + ld a, $00 + adc d + ld d, a + dec c + jr nz, .loop_copy_attr + call BankswitchVRAM0 + ret + +; a = starting BG palette index to copy to +.CopyCardPals: + ld c, a + add a + add a + add a ; *8 + ld e, a + ld d, $00 + ld hl, wBackgroundPalettesCGB + add hl, de + ld de, wCardPalettes + ld b, 3 palettes +.loop_copy_pal + ld a, [de] + inc de + ld [hli], a + dec b + jr nz, .loop_copy_pal + + ; de = wCardAttrMap + push de + ld b, $30 +.asm_56e4 + ld a, [de] + rlca + rlca + and $03 + add c + ld [de], a + inc de + dec b + jr nz, .asm_56e4 + pop hl + ret + +FlushAllPalettesIfNotDMG: + ld a, [wConsole] + or a + ret z + call FlushAllPalettes + ret +; 0x56fa + + ret ; stray ret + +JPWriteByteToBGMap0: + jp WriteByteToBGMap0 + +DisplayCardPage_PokemonOverview: + ld a, [wCardPageType] + or a + jr nz, .play_area_card_page + + ; print surrounding box, card name at 5,1, type, set 2, and rarity + call PrintPokemonCardPageGenericInformation + ; print fixed text and draw the card symbol associated to its TYPE_* + ld hl, CardPageRetreatWRTextData + call PlaceTextItems + ld hl, CardPageLvHPNoTextTileData + call WriteDataBlocksToBGMap0 + lb de, 3, 2 + call DrawCardSymbol + ; print pre-evolution's name (if any) + ld a, [wLoadedCard1Stage] + or a + jr z, .basic + ld hl, wLoadedCard1NonPokemonDescription + lb de, 1, 3 + call InitTextPrinting_ProcessTextFromPointerToID +.basic + ; print card level and maximum HP + lb bc, 12, 2 + ld a, [wLoadedCard1Level] + call WriteTwoDigitNumberInTxSymbolFormat + lb bc, 16, 2 + ld a, [wLoadedCard1HP] + call WriteTwoByteNumberInTxSymbolFormat + jr .print_numbers_and_energies + +.play_area_card_page + ; draw the surrounding box, and print fixed text + call DrawCardPageBoxAndCardGfx + call LoadDuelCheckPokemonScreenTiles + ld hl, CardPageRetreatWRTextData + call PlaceTextItems + ld hl, CardPageNoTextTileData + call WriteDataBlocksToBGMap0 + ld a, 1 + ld [wCurPlayAreaY], a + ; print set 2 icon and rarity symbol at fixed positions + call DrawCardPageSet2AndRarityIcons + ; print (Y coord at [wCurPlayAreaY]) card name, level, type, energies, HP, location... + call PrintPlayAreaCardInformationAndLocation + +; common for both card page types +.print_numbers_and_energies + ; print Pokedex number in the bottom right corner (16,16) + lb bc, 16, 16 + ld a, [wLoadedCard1PokedexNumber] + call WriteTwoByteNumberInTxSymbolFormat + ; print the name, damage, and energy cost of each attack and/or Pokemon power that exists + ; first attack at 5,10 and second at 5,12 + lb bc, 5, 10 + +.attacks + ld e, c + ld hl, wLoadedCard1Atk1Name + call PrintAttackOrPkmnPowerInformation + inc c + inc c ; 12 + ld e, c + ld hl, wLoadedCard1Atk2Name + call PrintAttackOrPkmnPowerInformation + ; print the retreat cost (some amount of colorless energies) at 8,14 + inc c + inc c ; 14 + ld b, 5 + ld a, [wLoadedCard1RetreatCost] + ld e, a + inc e +.retreat_cost_loop + dec e + jr z, .retreat_cost_done + ld a, SYM_COLORLESS + call JPWriteByteToBGMap0 + inc b + jr .retreat_cost_loop +.retreat_cost_done + ; print the colors (energies) of the weakness(es) and resistance(s) + inc c ; 15 + ld a, [wCardPageType] + or a + jr z, .wr_from_loaded_card + ld a, [wCurPlayAreaSlot] + or a + jr nz, .wr_from_loaded_card + call GetArenaCardWeakness + ld d, a + call GetArenaCardResistance + ld e, a + jr .got_wr +.wr_from_loaded_card + ld a, [wLoadedCard1Weakness] + ld d, a + ld a, [wLoadedCard1Resistance] + ld e, a +.got_wr + ld a, d + ld b, 5 + call PrintCardPageWeaknessesOrResistances + inc c + ld a, e + call PrintCardPageWeaknessesOrResistances + ret + +; displays the name, damage, and energy cost of an attack or Pokemon power. +; used in the Attack menu and in the card page of a Pokemon. +; input: + ; hl: pointer to attack 1 name in a atk_data_struct (which can be inside at card_data_struct) + ; e: Y coordinate to start printing the data at +PrintAttackOrPkmnPowerInformation: + ld a, [hli] + or [hl] + ret z + push bc + push hl + dec hl + ; print text ID pointed to by hl at 7,e + ld d, 7 + call InitTextPrinting_ProcessTextFromPointerToID + pop hl + inc hl + inc hl + ld a, [wCardPageNumber] + or a + jr nz, .print_damage + dec hl + ld a, [hli] + or [hl] + jr z, .print_damage + ; if in Attack menu and attack 1 description exists, print at 7,e: + ld b, 7 + ld c, e + inc c + ld a, SYM_ATK_DESCR + call WriteByteToBGMap0 +.print_damage + inc hl + inc hl + inc hl + push hl + ld a, [hl] + or a + jr z, .print_category + ; print attack damage at 15,(e+1) if non-0 + ld b, 15 ; unless damage has three digits, this is effectively 16 + ld c, e + inc c + call WriteTwoByteNumberInTxSymbolFormat +.print_category + pop hl + inc hl + ld a, [hl] + and $ff ^ RESIDUAL + jr z, .print_energy_cost + cp POKEMON_POWER + jr z, .print_pokemon_power + ; register a is DAMAGE_PLUS, DAMAGE_MINUS, or DAMAGE_X + ; print the damage modifier (+, -, x) at 18,(e+1) (after the damage value) + add SYM_PLUS - DAMAGE_PLUS + ld b, 18 + ld c, e + inc c + call WriteByteToBGMap0 + jr .print_energy_cost +.print_energy_cost + ld bc, CARD_DATA_ATTACK1_ENERGY_COST - CARD_DATA_ATTACK1_CATEGORY + add hl, bc + ld c, e + ld b, 2 ; bc = 2, e + lb de, NUM_TYPES / 2, 0 +.energy_loop + ld a, [hl] + swap a + call .PrintEnergiesOfColor + ld a, [hli] + call .PrintEnergiesOfColor + dec d + jr nz, .energy_loop + pop bc + ret +.print_pokemon_power + ; print "PKMN PWR" at 2,e + ld d, 2 + ldtx hl, Text000a + call InitTextPrinting_ProcessTextFromID + pop bc + ret + +; print the number of energies required of color (type) e, and return e ++ (next color). +; the requirement of the current color is provided as input in the lower nybble of a. +.PrintEnergiesOfColor: + inc e + and $0f + ret z + push de + ld d, a +.print_energies_loop + ld a, e + call JPWriteByteToBGMap0 + inc b + dec d + jr nz, .print_energies_loop + pop de + ret + +; print the weaknesses or resistances of a Pokemon card, given in a, at b,c +PrintCardPageWeaknessesOrResistances: + push bc + push de + ld d, a + xor a ; FIRE +.loop + ; each WR_* constant is a different bit. rotate the value to find out + ; which bits are set and therefore which WR_* values are active. + ; a is kept updated with the equivalent TYPE_* constant. + inc a + cp 8 + jr nc, .done + rl d + jr nc, .loop + push af + call JPWriteByteToBGMap0 + inc b + pop af + jr .loop +.done + pop de + pop bc + ret + +; prints surrounding box, card name at 5,1, type, set 2, and rarity. +; used in all CARDPAGE_POKEMON_* and ATTACKPAGE_*, except in +; CARDPAGE_POKEMON_OVERVIEW when wCardPageType is CARDPAGETYPE_PLAY_AREA. +PrintPokemonCardPageGenericInformation: + call DrawCardPageBoxAndCardGfx + lb de, 5, 1 + ld hl, wLoadedCard1Name + call InitTextPrinting_ProcessTextFromPointerToID + ld a, [wCardPageType] + or a + jr z, .from_loaded_card + ld a, [wCurPlayAreaSlot] + call GetPlayAreaCardColor + jr .got_color +.from_loaded_card + ld a, [wLoadedCard1Type] +.got_color + lb bc, 18, 1 + inc a + call JPWriteByteToBGMap0 + call DrawCardPageSet2AndRarityIcons + ret + +DrawCardPageBoxAndCardGfx: + lb de, 0, 0 + lb bc, 20, 18 + call DrawRegularTextBox + call DrawCardPageCardGfx + ret + +CardPageRetreatWRTextData: + textitem 1, 14, Text0007 + textitem 1, 15, Text0008 + textitem 1, 16, Text0009 + db $ff + +CardPageLvHPNoTextTileData: + db 11, 2, SYM_Lv, 0 + db 15, 2, SYM_HP, 0 +; continues to CardPageNoTextTileData + +CardPageNoTextTileData: + db 15, 16, SYM_No, 0 + db $ff + +DisplayCardPage_PokemonAttack1Page1: + ld hl, wLoadedCard1Atk1Name + ld de, wLoadedCard1Atk1Description + jr DisplayPokemonAttackCardPage + +DisplayCardPage_PokemonAttack1Page2: + ld hl, wLoadedCard1Atk1Name + ld de, wLoadedCard1Atk1Description + 2 + jr DisplayPokemonAttackCardPage + +DisplayCardPage_PokemonAttack2Page1: + ld hl, wLoadedCard1Atk2Name + ld de, wLoadedCard1Atk2Description + jr DisplayPokemonAttackCardPage + +DisplayCardPage_PokemonAttack2Page2: + ld hl, wLoadedCard1Atk2Name + ld de, wLoadedCard1Atk2Description + 2 +; fallthrough + +; input: + ; hl = address of the attack's name (text id) + ; de = address of the attack's description (either first or second text id) +DisplayPokemonAttackCardPage: + push de + push hl + ; print surrounding box, card name at 5,1, type, set 2, and rarity + call PrintPokemonCardPageGenericInformation + ; print name, damage, and energy cost of attack or Pokemon power starting at line 2 + ld e, 2 + pop hl + call PrintAttackOrPkmnPowerInformation + pop hl +; fallthrough + +; print, if non-null, the description of the trainer card, energy card, attack, +; or Pokemon power, given as a pointer to text id in hl, starting from 1,11 +PrintAttackOrNonPokemonCardDescription: + ld a, [hli] + or [hl] + ret z + dec hl + lb de, 1, 11 + call PrintAttackOrCardDescription + ret + +DisplayCardPage_PokemonDescription: + ; print surrounding box, card name at 5,1, type, set 2, and rarity + call PrintPokemonCardPageGenericInformation + call LoadDuelCardSymbolTiles2 + ; print "LENGTH", "WEIGHT", "Lv", and "HP" where it corresponds in the page + ld hl, CardPageLengthWeightTextData + call PlaceTextItems + ld hl, CardPageLvHPTextTileData + call WriteDataBlocksToBGMap0 + ; draw the card symbol associated to its TYPE_* at 3,2 + lb de, 3, 2 + call DrawCardSymbol + ; print the Level and HP numbers at 12,2 and 16,2 respectively + lb bc, 12, 2 + ld a, [wLoadedCard1Level] + call WriteTwoDigitNumberInTxSymbolFormat + lb bc, 16, 2 + ld a, [wLoadedCard1HP] + call WriteTwoByteNumberInTxSymbolFormat + ; print the Pokemon's category at 1,10 (just above the length and weight texts) + lb de, 1, 10 + ld hl, wLoadedCard1Category + call InitTextPrinting_ProcessTextFromPointerToID + ld a, TX_KATAKANA + call ProcessSpecialTextCharacter + ldtx hl, Text000e + call ProcessTextFromID + ; print the length at 3, 11 + lb bc, 3, 11 + ld a, [wLoadedCard1Length] + ld l, a + ld h, $00 + call PrintNumberAsMeasurement + call InitTextPrinting + ldtx hl, Text000f ; "m" + call ProcessTextFromID + ; print the weight at 3, 12 + lb bc, 3, 12 + ld hl, wLoadedCard1Weight + ld a, [hli] + ld h, [hl] + ld l, a + call PrintNumberAsMeasurement + ldtx hl, Text0010 ; "kg" + call InitTextPrinting_ProcessTextFromID + call SetNoLineSeparation + ld a, 19 + lb de, 1, 14 + call InitTextPrintingInTextbox + ld hl, wLoadedCard1Description + call ProcessTextFromPointerToID + call SetOneLineSeparation + ret + +; given a card rarity constant in a, and CardRarityTextIDs in hl, +; print the text character associated to it at d,e +PrintCardPageRarityIcon: + inc a + add a + ld c, a + ld b, $00 + add hl, bc + call InitTextPrinting_ProcessTextFromPointerToID + ret + +; prints the card's set 2 icon and the full width text character of the card's rarity +DrawCardPageSet2AndRarityIcons: + ld a, [wLoadedCard1Set] + call LoadCardSet2Tiles + jr c, .icon_done + ; draw the 2x2 set 2 icon of this card + ld a, $fc + lb hl, 1, 2 + lb bc, 2, 2 + lb de, 15, 8 + call FillRectangle +.icon_done + lb de, 18, 9 + ld hl, CardRarityTextIDs + ld a, [wLoadedCard1Rarity] + cp PROMOSTAR + call nz, PrintCardPageRarityIcon + ret + +CardPageLengthWeightTextData: + textitem 1, 11, Text000c + textitem 1, 12, Text000d + db $ff + +CardPageLvHPTextTileData: + db 11, 2, SYM_Lv, 0 + db 15, 2, SYM_HP, 0 + db $ff + +CardRarityTextIDs: + tx Text0011 ; PROMOSTAR (unused) + tx Text0012 ; CIRCLE + tx Text0013 ; DIAMOND + tx Text0014 ; STAR + tx Text0015 ; RARITY_3 + +DisplayCardPage_TrainerPage1: + xor a ; HEADER_TRAINER + ld hl, wLoadedCard1NonPokemonDescription + jr DisplayEnergyOrTrainerCardPage + +DisplayCardPage_TrainerPage2: + xor a ; HEADER_TRAINER + ld hl, wLoadedCard1NonPokemonDescription + 2 + jr DisplayEnergyOrTrainerCardPage + +DisplayCardPage_Energy2: + ld a, HEADER_ENERGY + ld hl, wLoadedCard1NonPokemonDescription + 2 + jr DisplayEnergyOrTrainerCardPage + +DisplayCardPage_Energy1: + ld a, HEADER_ENERGY + ld hl, wLoadedCard1NonPokemonDescription +; fallthrough + +; input: + ; a = HEADER_ENERGY or HEADER_TRAINER + ; hl = address of the card's description (text id) +DisplayEnergyOrTrainerCardPage: + push hl + push af + call LoadCardTypeHeaderTiles + ; draw surrounding box + lb de, 0, 0 + lb bc, 20, 18 + call DrawRegularTextBox + pop af + ld e, a + ld d, $00 + ld hl, .HeaderPaletteIndices + add hl, de + ld a, [hl] + lb hl, 0, 0 + call BankswitchVRAM1 + call .FillHeaderRectangle + call BankswitchVRAM0 + call DrawCardPageCardGfx + ; print the card's name at 4,3 + lb de, 4, 3 + ld hl, wLoadedCard1Name + call InitTextPrinting_ProcessTextFromPointerToID + ld a, $e0 + lb hl, 1, 8 + call .FillHeaderRectangle + call DrawCardPageSet2AndRarityIcons + pop hl + call PrintAttackOrNonPokemonCardDescription + ret + +.FillHeaderRectangle: + lb de, 6, 1 + lb bc, 8, 2 + jp FillRectangle + +.HeaderPaletteIndices: + db $4 ; HEADER_TRAINER + db $3 ; HEADER_ENERGY + db $2 ; HEADER_POKEMON (unused) + +; print lines of text with no separation between them +SetNoLineSeparation: + ld a, $01 +; fallthrough SetLineSeparation: ld [wLineSeparation], a ret -SetZeroLineSeparation: +; separate lines of text by an empty line +SetOneLineSeparation: xor a jr SetLineSeparation -; 0x59fb -SECTION "Bank 1@610c", ROMX[$610c], BANK[$1] +; prints number in register hl, first +; by dividing by 10, then by adding ".0" +; to the end if result has less than +; 4 digits (ie xxxx.0) +PrintNumberAsMeasurement: + push bc + ld de, -1 + ld bc, -10 +.loop_subtract + inc de + add hl, bc + jr c, .loop_subtract + ld bc, 10 + add hl, bc + pop bc + push hl + push bc + ld l, e + ld h, d + call TwoByteNumberToTxSymbol_TrimLeadingZeros_Bank1 + pop bc + pop hl + ld a, l + ld hl, wStringBuffer + $5 + or a + jr z, .skip_decimal + ; appends ".0" to string + ld [hl], SYM_DOT + inc hl + add SYM_0 + ld [hli], a +.skip_decimal + ld [hl], TX_END + push bc + call BCCoordToBGMap0Address + + ; loop through the string to find the first + ; non-0 byte (first number character) + ld hl, wStringBuffer +.loop_find_first_number + ld a, [hli] + or a + jr z, .loop_find_first_number + dec hl + + ; now loop string until end of text is found + ; and output size in b for SafeCopyDataHLtoDE + push hl + ld b, -1 +.loop_get_size + inc b + ld a, [hli] + or a + jr nz, .loop_get_size + pop hl + push bc + call SafeCopyDataHLtoDE + pop bc + pop de + ld a, b + add d + ld d, a + ret +; 0x5a42 + +SECTION "Bank 1@5cb7", ROMX[$5cb7], BANK[$1] + +; print a turn holder's play area Pokemon card's name, level, face down stage card, +; color symbol, status symbol (if any), pluspower/defender symbols (if any), +; attached energies (if any), HP bar, and the play area location (ACT/BPx indicator) +; input: + ; wCurPlayAreaSlot: PLAY_AREA_* of the card to display the information of + ; wCurPlayAreaY: Y coordinate of where to print the card's information +; total space occupied is a rectangle of 20x3 tiles +PrintPlayAreaCardInformationAndLocation: + ld a, [wCurPlayAreaSlot] + add DUELVARS_ARENA_CARD + get_turn_duelist_var + cp -1 + ret z + call PrintPlayAreaCardInformation + ld de, PlayerPlayAreaLocationTileNumbers + ldh a, [hWhoseTurn] + cp PLAYER_TURN + jr z, .opps_turn + ld de, OpponentPlayAreaLocationTileNumbers +.opps_turn + ld a, [wCurPlayAreaSlot] + add a + add a + ld l, a + ld h, $00 + add hl, de + ld a, [wCurPlayAreaY] + ld c, a + ld b, 1 + ld a, [hli] + ld e, a + ; call .WritePalAndTile 3 times + ; because each position is 3 tiles high + call .WritePalAndTile + call .WritePalAndTile +; fallthrough + +.WritePalAndTile: + call BankswitchVRAM1 + ld a, e ; pal index + call WriteByteToBGMap0 + call BankswitchVRAM0 + ld a, [hli] ; vtile + call WriteByteToBGMap0 + inc c + ret + +PlayerPlayAreaLocationTileNumbers: + db $2, $e0, $e1, $e2 ; ACT + db $2, $e3, $e4, $e5 ; BP1 + db $2, $e3, $e4, $e6 ; BP2 + db $2, $e3, $e4, $e7 ; BP3 + db $2, $e3, $e4, $e8 ; BP4 + db $2, $e3, $e4, $e9 ; BP5 + +OpponentPlayAreaLocationTileNumbers: + db $4, $ea, $eb, $ec ; ACT + db $3, $ed, $ee, $ef ; BP1 + db $3, $ed, $ee, $f0 ; BP2 + db $3, $ed, $ee, $f1 ; BP3 + db $3, $ed, $ee, $f2 ; BP4 + db $3, $ed, $ee, $f3 ; BP5 + +; print a turn holder's play area Pokemon card's name, level, face down stage card, +; color symbol, status symbol (if any), pluspower/defender symbols (if any), +; attached energies (if any), and HP bar. +; input: + ; wCurPlayAreaSlot: PLAY_AREA_* of the card to display the information of + ; wCurPlayAreaY: Y coordinate of where to print the card's information +; total space occupied is a rectangle of 20x3 tiles +PrintPlayAreaCardInformation: + ; print name, level, color, stage, status, pluspower/defender + call PrintPlayAreaCardHeader + ; print the symbols of the attached energies + ld a, [wCurPlayAreaSlot] + ld e, a + ld a, [wCurPlayAreaY] + inc a + ld c, a + ld b, 7 + call PrintPlayAreaCardAttachedEnergies + ld a, [wCurPlayAreaY] + inc a + ld c, a + ld b, 5 + ld a, SYM_E + call WriteByteToBGMap0 + ; print the HP bar + inc c + ld a, SYM_HP + call WriteByteToBGMap0 + ld a, [wCurPlayAreaSlot] + add DUELVARS_ARENA_CARD_HP + get_turn_duelist_var + or a + jr z, .zero_hp + ld e, a + ld a, [wLoadedCard1HP] + ld d, a + call DrawHPBar + ld a, [wCurPlayAreaY] + inc a + inc a + ld c, a + ld b, 7 + call BCCoordToBGMap0Address + ld hl, wDefaultText + ld b, 12 + call SafeCopyDataHLtoDE + ret +.zero_hp + ; if fainted, print "Knock Out" in place of the HP bar + ld a, [wCurPlayAreaY] + inc a + inc a + ld e, a + ld d, 7 + ldtx hl, Text004f + call InitTextPrinting_ProcessTextFromID + ret + +; print a turn holder's play area Pokemon card's name, level, face down stage card, +; color symbol, status symbol (if any), and pluspower/defender symbols (if any). +; input: + ; wCurPlayAreaSlot: PLAY_AREA_* of the card to display the information of + ; wCurPlayAreaY: Y coordinate of where to print the card's information +PrintPlayAreaCardHeader: + ld a, [wCurPlayAreaSlot] + add DUELVARS_ARENA_CARD + get_turn_duelist_var + call LoadCardDataToBuffer1_FromDeckIndex + ld a, [wCurPlayAreaY] + ld e, a + ld d, 4 + call InitTextPrinting + ; copy the name to wDefaultText (max. 10 characters) + ; then call ProcessText with hl = wDefaultText + ld hl, wLoadedCard1Name + ld a, [hli] + ld h, [hl] + ld l, a + ld de, wDefaultText + push de + ld a, 10 ; card name maximum length + call CopyTextData_FromTextID + pop hl + call ProcessText + + ; print the Pokemon's color and the level + ld a, [wCurPlayAreaY] + ld c, a + ld b, 18 + ld a, [wCurPlayAreaSlot] + call GetPlayAreaCardColor + inc a + call JPWriteByteToBGMap0 + ld b, 14 + ld a, SYM_Lv + call WriteByteToBGMap0 + ld a, [wCurPlayAreaY] + ld c, a + ld b, 15 + ld a, [wLoadedCard1Level] + call WriteTwoDigitNumberInTxSymbolFormat + + ; print the 2x2 face down card image depending on the Pokemon's evolution stage + ld a, [wCurPlayAreaSlot] + add DUELVARS_ARENA_CARD_STAGE + get_turn_duelist_var + add a + ld e, a + ld d, $00 + ld hl, FaceDownCardTileNumbers + add hl, de + ld a, [hli] ; starting tile to fill the 2x2 rectangle with + push hl + push af + lb hl, 1, 2 + lb bc, 2, 2 + ld a, [wCurPlayAreaY] + ld e, a + ld d, 2 + pop af + call FillRectangle + pop hl + ld a, [wConsole] + cp CONSOLE_CGB + jr nz, .not_cgb + ; in cgb, we have to take care of coloring it too + ld a, [hl] + lb hl, 0, 0 + lb bc, 2, 2 + call BankswitchVRAM1 + call FillRectangle + call BankswitchVRAM0 + +.not_cgb + ; print the status condition symbol if any (only for the arena Pokemon card) + ld hl, wCurPlayAreaSlot + ld a, [hli] + or a + jr nz, .skip_status + ld c, [hl] + inc c + inc c + ld b, 2 + ld a, DUELVARS_ARENA_CARD_STATUS + get_turn_duelist_var + call CheckPrintCnfSlpPrz + inc b + call CheckPrintPoisoned + inc b + call CheckPrintDoublePoisoned + +.skip_status + ; finally check whether to print the Pluspower and/or Defender symbols + ld a, [wCurPlayAreaSlot] + add DUELVARS_ARENA_CARD_ATTACHED_PLUSPOWER + get_turn_duelist_var + or a + jr z, .not_pluspower + ld a, [wCurPlayAreaY] + inc a + ld c, a + ld b, 15 + ld a, SYM_PLUSPOWER + call WriteByteToBGMap0 + inc b + ld a, [hl] + add SYM_0 + call WriteByteToBGMap0 +.not_pluspower + ld a, [wCurPlayAreaSlot] + add DUELVARS_ARENA_CARD_ATTACHED_DEFENDER + get_turn_duelist_var + or a + jr z, .not_defender + ld a, [wCurPlayAreaY] + inc a + ld c, a + ld b, 17 + ld a, SYM_DEFENDER + call WriteByteToBGMap0 + inc b + ld a, [hl] + add SYM_0 + call WriteByteToBGMap0 + +.not_defender + ld a, [wCurPlayAreaSlot] + add DUELVARS_ARENA_CARD_FOOD_COUNTERS + get_turn_duelist_var + or a + jr z, .no_food_counters + ld e, a + ld a, [wCurPlayAreaY] + inc a + ld c, a + ld b, 6 +.loop_food_counters + ld a, SYM_CHERRY + call WriteByteToBGMap0 + inc c + dec e + jr nz, .loop_food_counters +.no_food_counters + ret + +FaceDownCardTileNumbers: +; starting tile number, cgb palette (grey, yellow/red, green/blue, pink/orange) + db $d0, $03 ; basic + db $d4, $03 ; stage 1 + db $d8, $02 ; stage 2 + db $dc, $02 ; stage 2 special + +CheckPrintPoisoned: + push af + and POISONED + jr z, .print +.poison + ld a, SYM_POISONED +.print + call WriteByteToBGMap0 + pop af + ret + +CheckPrintDoublePoisoned: + push af + and DOUBLE_POISONED & (POISONED ^ $ff) + jr nz, CheckPrintPoisoned.poison ; double poisoned (print SYM_POISONED) + jr CheckPrintPoisoned.print ; not double poisoned (print SYM_SPACE) + +; 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: + 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 SYM_SPACE, SYM_CONFUSED, SYM_ASLEEP, SYM_PARALYZED + +; prints cherry symbols on the arena card +; if it has any Food Counters +; if a = 1, prints them left to right +; if a = -1, print them right to left +CheckPrintFoodCounters: + push af + ld a, DUELVARS_ARENA_CARD_FOOD_COUNTERS + get_turn_duelist_var + or a + jr z, .done + ld e, a +.loop_counters + ld a, SYM_CHERRY + call WriteByteToBGMap0 + pop af + push af + add c + ld c, a + dec e + jr nz, .loop_counters +.done + pop af + ret + +; 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: + push bc + call GetPlayAreaCardAttachedEnergies + ld hl, wDefaultText + push hl + ld c, 8 + xor a +.empty_loop + ld [hli], a + dec c + jr nz, .empty_loop + pop hl + ld a, [wAttachedEnergies + RAINBOW] + inc a + ld c, a + jr .next_rainbow_energy +.loop_rainbow_energies + ld [hl], SYM_RAINBOW + inc hl +.next_rainbow_energy + dec c + jr nz, .loop_rainbow_energies + + ld de, wAttachedEnergies + lb bc, SYM_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, SYM_PLUS + ld [wDefaultText + 7], a +.place_tiles + pop bc + call BCCoordToBGMap0Address + ld hl, wDefaultText + ld b, NUM_TYPES + call SafeCopyDataHLtoDE + ret +; 0x5efe + +SECTION "Bank 1@5fea", ROMX[$5fea], BANK[$1] + +; print the description of an attack, a Pokemon power, or a trainer or energy card +; x,y coordinates of where to start printing the text are given at de +; don't separate lines of text +PrintAttackOrCardDescription: + call SetNoLineSeparation + ld a, [hli] + ld h, [hl] + ld l, a + call CountLinesOfTextFromID + cp 7 + jr c, .print + dec e ; move one line up to fit (assumes it will be enough) +.print + ld a, 19 + call InitTextPrintingInTextbox + call ProcessTextFromID + call SetOneLineSeparation + ret +; 0x6004 + +SECTION "Bank 1@6061", ROMX[$6061], BANK[$1] + +WriteTwoByteNumberInTxSymbolFormat: + push de + push bc + ld l, a + ld h, $00 + call TwoByteNumberToTxSymbol_TrimLeadingZeros_Bank1 + pop bc + push bc + call BCCoordToBGMap0Address + ld hl, wStringBuffer + 2 + ld b, 3 + call SafeCopyDataHLtoDE + pop bc + pop de + ret +; 0x6079 + +SECTION "Bank 1@608e", ROMX[$608e], BANK[$1] + +; given a number between 0-99 in a, converts it to TX_SYMBOL format, +; and writes it to wStringBuffer + 3 and to the BGMap0 address at bc. +; if the number is between 0-9, the first digit is replaced with SYM_SPACE. +WriteTwoDigitNumberInTxSymbolFormat: + push hl + push de + push bc + ld l, a + ld h, $00 + call TwoByteNumberToTxSymbol_TrimLeadingZeros_Bank1 + pop bc + push bc + call BCCoordToBGMap0Address + ld hl, wStringBuffer + 3 + ld b, 2 + call SafeCopyDataHLtoDE + pop bc + pop de + pop hl + ret + +; convert the number at hl to TX_SYMBOL text format and write it to wStringBuffer +; replace leading zeros with SYM_SPACE +TwoByteNumberToTxSymbol_TrimLeadingZeros_Bank1: + ld de, wStringBuffer + 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 + ld hl, wStringBuffer + ld b, 4 +.digit_loop + ld a, [hl] + cp SYM_0 + jr nz, .done ; jump if not zero + ld [hl], SYM_SPACE ; trim leading zero + inc hl + dec b + jr nz, .digit_loop +.done + ret + +.get_digit + ld a, SYM_0 - 1 +.subtract_loop + inc a + add hl, bc + jr c, .subtract_loop + ld [de], a + inc de + ld a, l + sub c + ld l, a + ld a, h + sbc b + ld h, a + ret + +; input d, e: max. HP, current HP +DrawHPBar: + ld a, MAX_HP + ld c, SYM_SPACE + call .fill_hp_bar ; empty bar + ld a, d + ld c, SYM_HP_OK + call .fill_hp_bar ; fill (max. HP) with HP counters + ld a, d + sub e + ld c, SYM_HP_NOK +; 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 ; loads a player deck (sDeck*Cards) from SRAM to wPlayerDeck ; sCurrentlySelectedDeck determines which sDeck*Cards source (0-3) @@ -32,7 +1835,7 @@ LoadPlayerDeck: ld e, l ld d, h ld hl, wPlayerDeck - call LoadDeckFromSRAM + call DecompressSRAMDeck call DisableSRAM ret ; 0x6128 @@ -76,7 +1879,7 @@ SaveDeckCards: ret ; loads deck saved in SRAM to hl -LoadDeckFromSRAM: +DecompressSRAMDeck: push hl push de push bc @@ -106,6 +1909,51 @@ LoadDeckFromSRAM: ret ; 0x68da +SECTION "Bank 1@6a0c", ROMX[$6a0c], BANK[$1] + +; creates a list at wTempCardCollection of every card the player owns and how many +CreateTempCardCollection:: + call EnableSRAM + ld hl, sCardCollection + ld de, wTempCardCollection + ld bc, CARD_COLLECTION_SIZE + call CopyDataHLtoDE + ld de, sDeck1Cards + call .AddCards + call .AddCards + call .AddCards + call .AddCards + call DisableSRAM + ret + +.AddCards: + push de + ld hl, wDuelTempList + push hl + call DecompressSRAMDeck + pop hl +.loop_cards + ld e, [hl] + inc hl + ld d, [hl] + inc hl + ld a, e + or d + jr z, .next_deck + push hl + ld hl, wTempCardCollection + add hl, de + inc [hl] + pop hl + jr .loop_cards +.next_deck + pop de + ld hl, DECK_COMPRESSED_STRUCT_SIZE + add hl, de + ld e, l + ld d, h + ret + SECTION "Bank 1@6bc8", ROMX[$6bc8], BANK[$1] SetDefaultPalettes: @@ -145,3 +1993,254 @@ SetFontAndTextBoxFrameColor: ld c, CGB_PAL_SIZE call CopyFontsOrDuelGraphicsBytes ret + +SECTION "Bank 1@6c12", ROMX[$6c12], BANK[$1] + +Func_6c12: + ld hl, $30d8 + ld de, wBackgroundPalettesCGB + 2 * CGB_PAL_SIZE + ld c, 3 palettes + jp CopyFontsOrDuelGraphicsBytes +; 0x6c1d + +SECTION "Bank 1@70b4", ROMX[$70b4], BANK[$1] + +; returns carry if Pokemon in turn holder's +; Play Area location in register a cannot +; use its Pkmn Power +CheckIsIncapableOfUsingPkmnPower: + ld [wce0c], a + or a + jr nz, .skip_arena_card_condition + ld a, DUELVARS_ARENA_CARD_STATUS + get_turn_duelist_var + and CNF_SLP_PRZ + ldtx hl, Text00d6 + scf + ret nz +.skip_arena_card_condition + call CheckGoopGasAttackAndToxicGasActive + ret c + ld a, [wce0c] + add DUELVARS_ARENA_CARD_FLAGS + get_turn_duelist_var + and $10 + jr z, .can_use + ; used this turn + ldtx hl, Text00e0 ; can't use due to "Shock Eye"? + ld a, $02 + scf + ret +.can_use + or a + ret + +; return in a the amount of cards that correspond to the +; card ID in input register de, which have their Pkmn Power active +; also return carry if at least 1 is found +; de = card ID +CountPokemonWithActivePkmnPowerInBothPlayAreas: + push bc + push de + call CountTurnDuelistPokemonWithActivePkmnPower + ld c, a + call SwapTurn + pop de + call CountTurnDuelistPokemonWithActivePkmnPower + call SwapTurn + add c + jr z, .none_found + scf +.none_found + pop bc + ret +; 0x70f1 + +SECTION "Bank 1@7100", ROMX[$7100], BANK[$1] + +; counts how many Pokemon with card ID in de +; is in Turn Duelist's Play Area with its Pkmn Power active +; de = card ID +CountTurnDuelistPokemonWithActivePkmnPower: + push hl + push de + push bc + ld c, 0 + call .CheckArenaCard + jr nc, .check_bench + inc c + +; if a Bench card is the same as wTempCardID_ce08, +; and its flag 4 is not set, then add to count +.check_bench + ld b, PLAY_AREA_BENCH_1 + ldh a, [hWhoseTurn] + ld h, a +.loop_bench + ld a, b + add DUELVARS_ARENA_CARD + ld l, a + ld a, [hl] + cp $ff + jr z, .tally + call GetCardIDFromDeckIndex + ld a, [wTempCardID_ce08 + 0] + cp e + jr nz, .next_bench_card + ld a, [wTempCardID_ce08 + 1] + cp d + jr nz, .next_bench_card + ; is input card ID + ld a, b + add DUELVARS_ARENA_CARD_FLAGS + ld l, a + bit 4, [hl] + jr nz, .next_bench_card + inc c +.next_bench_card + inc b + jr .loop_bench + +.tally + ld a, c + or a + scf + jr nz, .at_least_1 + or a +.at_least_1 + pop bc + pop de + pop hl + ret + +; returns carry if turn duelist's Arena card +; is the card in input registers de, +; is not affected by a status condition and +; flag 4 is not set +.CheckArenaCard: + ld hl, wTempCardID_ce08 + ld [hl], e + inc hl + ld [hl], d + ld a, DUELVARS_ARENA_CARD + get_turn_duelist_var + cp $ff + jr z, .false + call GetCardIDFromDeckIndex + ld hl, wTempCardID_ce08 + ld a, [hli] + cp e + jr nz, .false + ld a, [hl] + cp d + jr nz, .false + ld a, DUELVARS_ARENA_CARD_STATUS + get_turn_duelist_var + and CNF_SLP_PRZ + jr nz, .false + ld l, DUELVARS_ARENA_CARD_FLAGS + bit 4, [hl] + jr nz, .false +; true + scf + ret +.false + or a + ret +; 0x716a + +SECTION "Bank 1@71ea", ROMX[$71ea], BANK[$1] + +; checks if Goop Gas Attack is active and if so, +; returns carry and a = $1 +; otherwise, checks for Muk in Play Area with Pkmn Power active +; and if there is at least 1, return carry and a = $0 +CheckGoopGasAttackAndToxicGasActive: + ld a, [wGoopGasAttackActive] + or a + jr nz, .goop_gas_attack_active + push de + ld de, MUK + call CountPokemonWithActivePkmnPowerInBothPlayAreas + pop de + ld a, $00 + ldtx hl, Text00df + ret +.goop_gas_attack_active + ld a, $01 + ldtx hl, Text024a + scf + ret +; 0x7205 + +SECTION "Bank 1@755d", ROMX[$755d], BANK[$1] + +; return the turn holder's arena card's color in a, accounting for Venomoth's Shift Pokemon Power if active +GetArenaCardColor: + xor a + +; input: a = play area location offset (PLAY_AREA_*) of the desired card +; return the turn holder's card's color in a, accounting for Venomoth's Shift Pokemon Power if active +GetPlayAreaCardColor:: + push hl + push de + ld e, a + add DUELVARS_ARENA_CARD_CHANGED_TYPE + get_turn_duelist_var + bit HAS_CHANGED_COLOR_F, a + jr nz, .has_changed_color +.regular_color + ld a, e + add DUELVARS_ARENA_CARD + get_turn_duelist_var + call GetCardIDFromDeckIndex + call GetCardType + cp TYPE_TRAINER + jr nz, .got_type + ld a, COLORLESS +.got_type + pop de + pop hl + ret +.has_changed_color + ld a, e + call CheckIsIncapableOfUsingPkmnPower + jr c, .regular_color ; jump if can't use Shift + ld a, e + add DUELVARS_ARENA_CARD_CHANGED_TYPE + get_turn_duelist_var + pop de + pop hl + and $f + ret +; 0x758a + +SECTION "Bank 1@7591", ROMX[$7591], BANK[$1] + +; return in a the weakness of the turn holder's arena Pokemon +; if [DUELVARS_ARENA_CARD_CHANGED_WEAKNESS] != 0, return it instead +GetArenaCardWeakness: + ld a, DUELVARS_ARENA_CARD_CHANGED_WEAKNESS + get_turn_duelist_var + or a + ret nz + ld a, DUELVARS_ARENA_CARD + get_turn_duelist_var + call LoadCardDataToBuffer2_FromDeckIndex + ld a, [wLoadedCard2Weakness] + ret +; 0x75a0 + +SECTION "Bank 1@75a7", ROMX[$75a7], BANK[$1] + +GetArenaCardResistance: + ld a, DUELVARS_ARENA_CARD_CHANGED_RESISTANCE + get_turn_duelist_var + or a + ret nz + ld a, DUELVARS_ARENA_CARD + get_turn_duelist_var + call LoadCardDataToBuffer2_FromDeckIndex + ld a, [wLoadedCard2Resistance] + ret +; 0x75b6 diff --git a/src/engine/bank02.asm b/src/engine/bank02.asm index 539f5dd..18d9f63 100644 --- a/src/engine/bank02.asm +++ b/src/engine/bank02.asm @@ -1,17 +1,279 @@ -SECTION "Bank 2@4f10", ROMX[$4f10], BANK[$2] +SECTION "Bank 2@4acb", ROMX[$4acb], BANK[$2] + +LoadMenuCursorTile: + call Set_OBJ_8x8 + ld de, v0Tiles0 + ld hl, MenuCursorGfx + ld b, 1 tiles + call SafeCopyDataHLtoDE + ret + +MenuCursorGfx: + INCBIN "gfx/menu_cursor.2bpp" + +; handles menus which support cursor moving in +; all 4 directions using a transition table, +; instead of a simple up/down menu list +HandleMultiDirectionalMenu: + xor a + ld [wMenuInputSFX], a + + ; get the transition data + ld hl, wTransitionTablePtr + ld e, [hl] + inc hl + ld d, [hl] + ld a, [wd0c1] + ld [wd0d0], a + ld l, a + ld h, 7 ; length of each transition table item + call HtimesL + add hl, de + +; get the transition index related to the directional input + ldh a, [hDPadHeld] + or a + jp z, .check_button + inc hl + inc hl + inc hl + + bit D_UP_F, a + jr z, .else_if_down + ; up + ld a, [hl] + jr .process_dpad + +.else_if_down + inc hl + bit D_DOWN_F, a + jr z, .else_if_right + ; down + ld a, [hl] + jr .process_dpad + +.else_if_right + inc hl + bit D_RIGHT_F, a + jr z, .else_if_left + ; right + ld a, [hl] + jr .process_dpad + +.else_if_left + inc hl + bit D_LEFT_F, a + jr z, .check_button + ; left + ld a, [hl] + +.process_dpad + ld [wd0c1], a + cp $8 ; if a >= 0x8 + jr nc, .sfx + ld b, $1 + +; this loop equals to +; b = (1 << a) +.make_bitmask_loop + or a + jr z, .make_bitmask_done + sla b + dec a + jr .make_bitmask_loop + +.make_bitmask_done +; check if the moved cursor refers to an existing item. + ld a, [wd0c4] + and b + jr nz, .sfx + ld a, [wd0d0] + cp $06 + jr nz, HandleMultiDirectionalMenu + +; check if one of the dpad, left or right, is pressed. +; if not, just go back to the start. + ldh a, [hDPadHeld] + bit D_RIGHT_F, a + jr nz, .left_or_right + bit D_LEFT_F, a + jr z, HandleMultiDirectionalMenu + +.left_or_right + ; if started with 5 or 6 prize cards + ; can switch sides normally, + ld a, [wDuelInitialPrizes] + cp PRIZES_5 + jr nc, .sfx + ; else if it's last card, + ld a, [wd0c1] + cp 5 + jr nz, .not_last_card + ; place it at pos 3 + ld a, 3 + ld [wd0c1], a + jr .ok +.not_last_card + ; otherwise place at pos 2 + ld a, 2 + ld [wd0c1], a + +.ok + ld a, [wDuelInitialPrizes] + cp PRIZES_3 + jr nc, .handled_cursor_pos + ; in this case can just sub 2 from pos + ld a, [wd0c1] + sub 2 + ld [wd0c1], a + +.handled_cursor_pos + ld a, [wd0c1] + ld [wd0d0], a + ld b, $1 + jr .make_bitmask_loop + +.sfx + ld a, SFX_01 + ld [wMenuInputSFX], a + + ; reset cursor blink + xor a + ld [wScrollMenuCursorBlinkCounter], a +.check_button + ldh a, [hKeysPressed] + and A_BUTTON | B_BUTTON + jr z, .no_btns + and A_BUTTON + jr nz, .a_btn +; b btn + ld a, $ff ; cancel + call PlayAcceptOrDeclineSFX + scf + ret +.a_btn + call .DrawCursor + ld a, $01 + call PlayAcceptOrDeclineSFX + ld a, [wd0c1] + scf + ret + +.no_btns + ld a, [wMenuInputSFX] + or a + jr z, .skip_sfx + call PlaySFX +.skip_sfx + ld hl, wScrollMenuCursorBlinkCounter + ld a, [hl] + inc [hl] + and $0f + ret nz + bit 4, [hl] + jr nz, ZeroObjectPositionsWithCopyToggleOn + +.DrawCursor: + call ZeroObjectPositions + ld hl, wTransitionTablePtr + ld e, [hl] + inc hl + ld d, [hl] + ld a, [wd0c1] + ld l, a + ld h, 7 + call HtimesL + add hl, de +; hl = [wTransitionTablePtr] + 7 * wd0c1 + + ld d, [hl] + inc hl + ld e, [hl] + inc hl + ld b, [hl] + ld c, $00 ; cursor tile + call SetOneObjectAttributes + or a + ret + +ZeroObjectPositionsWithCopyToggleOn: + call ZeroObjectPositions + ld a, $01 + ld [wVBlankOAMCopyToggle], a + ret +; 0x8be6 + +SECTION "Bank 2@4e6b", ROMX[$4e6b], BANK[$2] + +GlossaryTransitionTable_10Topics: + cursor_transition $08, $28, $00, 4, 1, 5, 5 ; 0 + cursor_transition $08, $38, $00, 0, 2, 6, 6 ; 1 + cursor_transition $08, $48, $00, 1, 3, 7, 7 ; 2 + cursor_transition $08, $58, $00, 2, 4, 8, 8 ; 3 + cursor_transition $08, $68, $00, 3, 0, 9, 9 ; 4 + cursor_transition $58, $28, $00, 9, 6, 0, 0 ; 5 + cursor_transition $58, $38, $00, 5, 7, 1, 1 ; 6 + cursor_transition $58, $48, $00, 6, 8, 2, 2 ; 7 + cursor_transition $58, $58, $00, 7, 9, 3, 3 ; 8 + cursor_transition $58, $68, $00, 8, 5, 4, 4 ; 9 + +GlossaryTransitionTable_8Topics: + cursor_transition $08, $28, $00, 3, 1, 4, 4 ; 0 + cursor_transition $08, $38, $00, 0, 2, 5, 5 ; 1 + cursor_transition $08, $48, $00, 1, 3, 6, 6 ; 2 + cursor_transition $08, $58, $00, 2, 0, 7, 7 ; 3 + cursor_transition $58, $28, $00, 7, 5, 0, 0 ; 4 + cursor_transition $58, $38, $00, 4, 6, 1, 1 ; 5 + cursor_transition $58, $48, $00, 5, 7, 2, 2 ; 6 + cursor_transition $58, $58, $00, 6, 4, 3, 3 ; 7 +; 0x8ee9 + +SECTION "Bank 2@4ee9", ROMX[$4ee9], BANK[$2] + +; copies DECK_SIZE number of cards from de to hl in SRAM +CopyDeckFromSRAM: + push hl + call EnableSRAM + bank1call DecompressSRAMDeck + call DisableSRAM + pop hl + push bc + ld bc, DECK_SIZE_BYTES + add hl, bc + pop bc + xor a ; terminating byte + ld [hli], a + ld [hl], a + ret + +; clears some WRAM addresses to act as +; terminator bytes to wTempCardList and wCurDeckCards +WriteCardListsTerminatorBytes: + xor a + ld hl, wTempCardList + ld bc, $80 + add hl, bc + ld [hl], a ; terminator byte + ld hl, wCurDeckCards + ld bc, $80 + add hl, bc + ld [hl], a ; terminator byte + ret Func_8f10: call EnableSRAM xor a - ld hl, $b7a3 + ld hl, sBoosterPacksObtained ld [hli], a inc a ld [hli], a ld [hli], a ld [hl], a - ld [$b7a1], a + ld [s0b7a1], a call DisableSRAM +; fallthrough +EmptyScreenAndLoadFontDuelAndHandCardsIcons: xor a ld [wTileMapFill], a call EmptyScreen @@ -22,15 +284,505 @@ Func_8f10: call LoadDuelCardSymbolTiles farcall LoadHandCardsIcon bank1call SetDefaultPalettes - ld de, $3cbf + lb de, $3c, $bf call SetupText ret -; 0x8f45 -SECTION "Bank 2@5c26", ROMX[$5c26], BANK[$2] +; empties screen, zeroes object positions, +; loads cursor tile, symbol fonts, duel card symbols +; hand card icon and sets default palettes +PrepareMenuGraphics: + xor a + ld [wTileMapFill], a + call EmptyScreen + call ZeroObjectPositions + ld a, $1 + ld [wVBlankOAMCopyToggle], a + call LoadMenuCursorTile + call LoadSymbolsFont + call LoadDuelCardSymbolTiles + farcall LoadHandCardsIcon + bank1call SetDefaultPalettes + lb de, $3c, $bf + call SetupText + ret +; 0x8f6b -; clears a bytes in hl -ClearBytesInHL: +SECTION "Bank 2@4fee", ROMX[$4fee], BANK[$2] + +OpenDeckConfirmationMenu: +; copy deck name + push de + ld de, wCurDeckName + call CopyListFromHLToDEInSRAM + pop de + +; copy deck cards + ld hl, wCurDeckCards + call CopyDeckFromSRAM + + ld a, NUM_FILTERS + ld hl, wCardFilterCounts + call ClearNBytesFromHL + ld a, DECK_SIZE + ld [wTotalCardCount], a + ld [wd381], a + ld hl, wCardFilterCounts + ld [hl], a + call HandleDeckConfirmationMenu + ret + +SECTION "Bank 2@5328", ROMX[$5328], BANK[$2] + +; play different sfx by a. +; if a is 0xff play SFX_03 (usually following a B press), +; else play SFX_02 (usually following an A press). +PlayAcceptOrDeclineSFX: + push af + inc a + jr z, .cancel + ld a, SFX_02 + jr .play_sfx +.cancel + ld a, SFX_03 +.play_sfx + call PlaySFX + pop af + ret +; 0x9337 + +SECTION "Bank 2@54fc", ROMX[$54fc], BANK[$2] + +DeckNameSuffix: + katakana "デ" + katakana "ッ" + katakana "キ" + done + +SECTION "Bank 2@5503", ROMX[$5503], BANK[$2] + +CopyListFromHLToDE: +.loop + ld a, [hli] + ld [de], a + or a + ret z ; TX_END + inc de + jr .loop + +; same as CopyListFromHLToDE, but for SRAM copying +CopyListFromHLToDEInSRAM: + call EnableSRAM + call CopyListFromHLToDE + call DisableSRAM + ret + +; appends text in hl to wDefaultText +; then adds "deck" to the end +; returns carry if deck has no cards +; hl = text to append +; de = input to InitTextPrinting +AppendDeckName: + push hl + call CheckIfDeckHasCards + pop hl + ret c ; no cards + + push de + ; append the text from hl + ld de, wDefaultText + call CopyListFromHLToDEInSRAM + + ; get string length (up to DECK_NAME_SIZE_WO_SUFFIX) + ld hl, wDefaultText + ld a, [hl] + cp TX_HALFWIDTH + jr z, .halfwidth + call GetTextLengthInTiles + ld a, c + cp DECK_NAME_SIZE_WO_SUFFIX + jr c, .got_len + ld c, DECK_NAME_SIZE_WO_SUFFIX +.got_len + ld b, $0 + ld hl, wDefaultText + add hl, bc + ld d, h + ld e, l + ; append "deck" starting from the given length + ld hl, .text_start + ld b, .text_end - .text_start + call CopyBBytesFromHLToDE_Bank02 + xor a ; TX_END + ld [wDefaultText + DECK_NAME_SIZE + 2], a + pop de + ld hl, wDefaultText + call InitTextPrinting + call ProcessText + or a + ret + +.halfwidth + call GetTextLengthInTiles + ld a, c + cp DECK_NAME_SIZE_WO_SUFFIX + 1 + jr c, .asm_955d + ld c, DECK_NAME_SIZE_WO_SUFFIX + 1 +.asm_955d + ld b, $00 + ld hl, wDefaultText + add hl, bc + ld d, h + ld e, l + ld hl, .text_start + ld b, .text_end - .text_start + 1 + call CopyBBytesFromHLToDE_Bank02 + ld hl, wDefaultText + (.text_end - .text_start + 1) + ld a, [hl] + or a + jr nz, .asm_9575 + dec hl +.asm_9575 + xor a + ld [hl], a + pop de + ld hl, wDefaultText + call InitTextPrinting + call ProcessText + or a + ret + +.text_start + katakana "デ" + katakana "ッ" + katakana "キ" + db "" +.text_end + +; returns carry if the deck in hl +; is not valid, that is, has no cards +; alternatively, the direct address of the cards +; can be used, since DECK_SIZE > DECK_NAME_SIZE +; hl = deck name (sDeck1Name ~ sDeck4Name) +; or deck cards (sDeck1Cards ~ sDeck4Cards) +CheckIfDeckHasCards: + ld bc, DECK_NAME_SIZE + add hl, bc + push de + ld d, h + ld e, l + ld hl, wTempSavedDeckCards + call CopyDeckFromSRAM + ; first card being invalid means empty deck + ld hl, wTempSavedDeckCards + ld e, [hl] + inc hl + ld d, [hl] + call CheckIfCardIDIsZero + pop de + ret c + or a + ret +; 0x95b7 + +SECTION "Bank 2@55ca", ROMX[$55ca], BANK[$2] + +; de = coordinates to draw rectangle +DrawHandCardsTileAtDE: + ld a, $38 ; hand cards tile + lb hl, 1, 2 + lb bc, 2, 2 + call FillRectangle + ret + +SECTION "Bank 2@5a31", ROMX[$5a31], BANK[$2] + +FiltersCardSelectionParams: + db 1 ; x pos + db 1 ; y pos + db 0 ; y spacing + db 2 ; x spacing + db NUM_FILTERS ; num entries + db SYM_CURSOR_D ; visible cursor tile + db SYM_SPACE ; invisible cursor tile + dw NULL ; wCardListHandlerFunction + +SECTION "Bank 2@5a8e", ROMX[$5a8e], BANK[$2] + +; fills one line at coordinate bc in BG Map +; with the byte in register a +; fills the same line with $01 in VRAM1 if in CGB +; bc = coordinates +FillBGMapLineWithA: + call BCCoordToBGMap0Address + ld b, SCREEN_WIDTH + call WriteBBytesToDE + ld a, [wConsole] + cp CONSOLE_CGB + ret nz ; not cgb + ld a, $01 ; attributes + ld b, SCREEN_WIDTH + call BankswitchVRAM1 + call WriteBBytesToDE + call BankswitchVRAM0 + ret +; 0x9aaa + +SECTION "Bank 2@5abb", ROMX[$5abb], BANK[$2] + +; a = byte to write +; b = number of bytes +; de = target address +WriteBBytesToDE: + push hl + ld l, e + ld h, d +.loop + ld [hli], a + dec b + jr nz, .loop + pop hl + ret + +; draws all the card type icons +; in a line specified by .CardTypeIcons +DrawCardTypeIcons: + ld hl, .CardTypeIcons +.loop + ld a, [hli] + or a + ret z ; done + ld d, [hl] ; x coord + inc hl + ld e, [hl] ; y coord + inc hl + call .DrawIcon + jr .loop + +; input: +; de = coordinates +.DrawIcon: + push hl + push af + lb hl, 1, 2 + lb bc, 2, 2 + call FillRectangle + pop af + call GetCardTypeIconPalette + ld b, a + ld a, [wConsole] + cp CONSOLE_CGB + jr nz, .not_cgb + ld a, b + lb bc, 2, 2 + lb hl, 0, 0 + call BankswitchVRAM1 + call FillRectangle + call BankswitchVRAM0 +.not_cgb + pop hl + ret + +.CardTypeIcons: +; icon tile, x coord, y coord + db ICON_TILE_GRASS, 1, 2 + db ICON_TILE_FIRE, 3, 2 + db ICON_TILE_WATER, 5, 2 + db ICON_TILE_LIGHTNING, 7, 2 + db ICON_TILE_FIGHTING, 9, 2 + db ICON_TILE_PSYCHIC, 11, 2 + db ICON_TILE_COLORLESS, 13, 2 + db ICON_TILE_TRAINER, 15, 2 + db ICON_TILE_ENERGY, 17, 2 + db $00 +; 0x9b18 + +SECTION "Bank 2@5b31", ROMX[$5b31], BANK[$2] + +; prints "/60" to the coordinates given in de +PrintSlashSixty: + ld hl, wDefaultText + ld a, TX_SYMBOL + ld [hli], a + ld a, SYM_SLASH + ld [hli], a + ld a, [wd381] + call ConvertToNumericalDigits + ld [hl], TX_END + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + ret + +; creates two separate lists given the card type in register a +; if a card matches the card type given, then it's added to wTempCardList +; if a card has been owned by the player, and its card count is at least 1, +; (or in case it's 0 if it's in any deck configurations saved) +; then its collection count is also added to wTempCardList +; if input a is $ff, then all card types are included +CreateFilteredCardList: + push af + push bc + push de + push hl + +; clear wOwnedCardsCountList and wTempCardList + push af + ld a, $51 + ld hl, wOwnedCardsCountList + call ClearNBytesFromHL + ld a, $a0 + ld hl, wTempCardList + call ClearNBytesFromHL + pop af + +; loops all cards in collection + ld hl, $0 + ld de, 0 + ld b, a ; input card type +.loop_card_ids + inc de + call GetCardType + jr c, .store_count + ld c, a + ld a, b + cp $ff + jr z, .add_card + and FILTER_ENERGY + cp FILTER_ENERGY + jr z, .check_energy + ld a, c + cp b + jr nz, .loop_card_ids + jr .add_card +.check_energy + ld a, c + and TYPE_ENERGY + cp TYPE_ENERGY + jr nz, .loop_card_ids + +.add_card + push bc + push hl + add hl, hl + ld bc, wTempCardList + add hl, bc + ld [hl], e + inc hl + ld [hl], d + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + pop hl + cp CARD_NOT_OWNED + jr z, .next_card ; jump if never seen card + or a + jr nz, .ok ; has at least 1 + call .IsCardInAnyDeck + jr c, .next_card ; jump if not in any deck +.ok + push af + cp16 BILLS_COMPUTER + jr nz, .asm_9bb8 + ld a, [wd121] + or a + jr nz, .asm_9bb8 + pop af + jr .next_card +.asm_9bb8 + pop af + + push hl + ld bc, wOwnedCardsCountList + add hl, bc + ld [hl], a + pop hl + inc l +.next_card + pop bc + jr .loop_card_ids + +.store_count + ld a, l + ld [wNumEntriesInCurFilter], a +; add terminator bytes in both lists + ld c, l + ld b, h + ld a, $ff + ld hl, wOwnedCardsCountList + add hl, bc + ld [hl], a ; $ff + ld hl, wTempCardList + add hl, bc + add hl, bc + xor a + ld [hli], a ; $00 + ld [hl], a + pop hl + pop de + pop bc + pop af + ret + +; returns carry if card ID in register e is not +; found in any of the decks saved in SRAM +.IsCardInAnyDeck: + push af + push hl + ld hl, sDeck1Cards + call .FindCardInDeck + jr nc, .found_card + ld hl, sDeck2Cards + call .FindCardInDeck + jr nc, .found_card + ld hl, sDeck3Cards + call .FindCardInDeck + jr nc, .found_card + ld hl, sDeck4Cards + call .FindCardInDeck + jr nc, .found_card + pop hl + pop af + scf + ret +.found_card + pop hl + pop af + or a + ret + +; returns carry if input card ID in de +; is not found in deck given by hl +.FindCardInDeck: + push de + ld d, h + ld e, l + ld hl, wTempSavedDeckCards + call CopyDeckFromSRAM + + ld hl, wTempSavedDeckCards + pop de + ld b, DECK_SIZE +.loop + ld a, [hli] + cp e + ld a, [hli] + jr nz, .not_equal + cp d + jr z, .not_found_in_deck +.not_equal + dec b + jr nz, .loop + scf + ret +.not_found_in_deck + or a + ret + +; preserves all registers +; hl = start of bytes to set to $0 +; a = number of bytes to set to $0 +ClearNBytesFromHL: push af push bc push hl @@ -44,4 +796,3562 @@ ClearBytesInHL: pop bc pop af ret -; 0x9c33 + +; returns the number of times that card de +; appears in wCurDeckCards +GetCountOfCardInCurDeck: + push hl + push bc + ld hl, wCurDeckCards + ld b, 0 +.loop + push de + ld e, [hl] + inc hl + ld d, [hl] + inc hl + call CheckIfCardIDIsZero + ld c, e + ld a, d + pop de + jr c, .zero ; not found + ; is valid ID, compare card ID + cp d + jr nz, .loop + ld a, c + cp e + jr nz, .loop + inc b + jr .loop + +.zero + ld a, b + pop bc + pop hl + ret + +Func_9c55: + push hl + push bc + ld hl, wBoosterPackCardList + ld b, -1 +.loop + inc b + push de + ld e, [hl] + inc hl + ld d, [hl] + inc hl + call CheckIfCardIDIsZero + ld c, e + ld a, d + pop de + jr c, .zero ; not found + ; is valid ID, compare card ID + cp d + jr nz, .loop + ld a, c + cp e + jr nz, .loop + ; has same card ID, get its count + ld hl, wBoosterPackCardCounts + ld c, b + ld b, $00 + add hl, bc + ld a, [hl] + pop bc + pop hl + ret + +.zero + xor a + pop bc + pop hl + ret +; 0x9c80 + +SECTION "Bank 2@5ca6", ROMX[$5ca6], BANK[$2] + +; determines the ones and tens digits in a for printing +; the ones place is added $20 (SYM_0) so that it maps to a numerical character +; if the tens is 0, it maps to an empty character +; a = value to calculate digits +CalculateOnesAndTensDigits: + push af + push bc + push de + push hl + ld c, -1 +.loop_sub + inc c + sub 10 + jr nc, .loop_sub + jr z, .got_result + add 10 +.got_result + add SYM_0 + ld hl, wDecimalDigitsSymbols + ld [hli], a ; ones place + ld a, c + or a + jr z, .below_10 + add SYM_0 +.below_10 + ld [hl], a ; tens place + pop hl + pop de + pop bc + pop af + ret + +; converts value in register a to +; numerical symbols for ProcessText +; places the symbols in hl +ConvertToNumericalDigits: + call CalculateOnesAndTensDigits + push hl + ld hl, wDecimalDigitsSymbols + ld a, [hli] + ld b, a + ld a, [hl] + pop hl + ld [hl], TX_SYMBOL + inc hl + ld [hli], a + ld [hl], TX_SYMBOL + inc hl + ld a, b + ld [hli], a + ret +; 0x9cdc + +SECTION "Bank 2@5d1a", ROMX[$5d1a], BANK[$2] + +; prints the card count of each individual card type +; assumes CountNumberOfCardsForEachCardType was already called +; this is done by processing text in a single line +; and concatenating all digits +PrintCardTypeCounts: + ld bc, $0 + ld hl, wDefaultText +.loop + push hl + ld hl, wCardFilterCounts + add hl, bc + ld a, [hl] + pop hl + push bc + call ConvertToNumericalDigits + pop bc + inc c + ld a, NUM_FILTERS + cp c + jr nz, .loop + ld [hl], TX_END + lb de, 1, 4 + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + ret +; 0x9d41 + +SECTION "Bank 2@5d8c", ROMX[$5d8c], BANK[$2] + +; used to filter the cards in the deck building/card selection screen +CardTypeFilters: + db FILTER_GRASS + db FILTER_FIRE + db FILTER_WATER + db FILTER_LIGHTNING + db FILTER_FIGHTING + db FILTER_PSYCHIC + db FILTER_COLORLESS + db FILTER_TRAINER + db FILTER_ENERGY + db -1 ; end of list + +; counts all the cards from each card type +; (stored in wCardFilterCounts) and store it in wTotalCardCount +; also prints it in coordinates de +PrintTotalCardCount: + push de + ld bc, $0 + ld hl, wCardFilterCounts +.loop + ld a, [hli] + add b + ld b, a + inc c + ld a, NUM_FILTERS + cp c + jr nz, .loop + ld hl, wDefaultText + ld a, b + ld [wTotalCardCount], a + push bc + call ConvertToNumericalDigits + pop bc + ld [hl], TX_END + pop de + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + ret +; 0x9dbf + +SECTION "Bank 2@5e48", ROMX[$5e48], BANK[$2] + +Text_9e48: + db "" + db "" + db "" + db "" + db "" + db "" + db "" + db "" + db "" + db "" + db "" + db "" + db "" + db "" + db "" + db "" + db "" + db "" + db "" + db "" + done + +; returns carry if card ID in de is $0000 +; de = card ID +CheckIfCardIDIsZero: + push af + xor a + cp d + jr nz, .false + cp e + jr nz, .false + pop af + scf + ret +.false + pop af + or a + ret + +; writes the card ID in register de to wVisibleListCardIDs +; given its position in the list in register b +; input: +; b = list position (starts from bottom) +; de = card ID +AddCardIDToVisibleList: + push af + push bc + push hl + ld hl, wVisibleListCardIDs + ld c, b + ld a, [wNumVisibleCardListEntries] + sub c + ; a = wNumVisibleCardListEntries - b + add a ; *2 + ld c, a + ld b, $00 + add hl, bc + ld [hl], e + inc hl + ld [hl], d + pop hl + pop bc + pop af + ret + +; initializes parameters for a menu, given the 8 bytes starting at hl, +; which are loaded to the following addresses: +; wMenuCursorXOffset, wMenuCursorYOffset, wMenuYSeparation, wNumMenuItems, +; wMenuVisibleCursorTile, wMenuInvisibleCursorTile, wMenuUpdateFunc. +; also sets the current menu item (wCurScrollMenuItem) to the one specified in register a. +InitializeScrollMenuParameters: + ld [wCurScrollMenuItem], a + ld [hCurMenuItem], a + ld de, wMenuParams + ld b, wMenuParamsEnd - wMenuParams +.loop + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .loop + xor a + ld [wScrollMenuCursorBlinkCounter], a + ret + +DeckMachineSelectionParams: + db 1 ; x pos + db 2 ; y pos + db 2 ; y spacing + db 0 ; x spacing + db 5 ; num entries + db SYM_CURSOR_R ; visible cursor tile + db SYM_SPACE ; invisible cursor tile + dw NULL ; wCardListHandlerFunction +; 0x9eb5 + +SECTION "Bank 2@5ebe", ROMX[$5ebe], BANK[$2] + +HandleCardSelectionInput: + xor a ; FALSE + ld [wMenuInputSFX], a + ldh a, [hDPadHeld] + or a + jr z, .handle_ab_btns + +; handle d-pad + ld b, a + ld a, [wNumMenuItems] + ld c, a + ld a, [wCurScrollMenuItem] + bit D_LEFT_F, b + jr z, .check_d_right + dec a + bit 7, a + jr z, .got_cursor_pos + ; if underflow, set to max cursor pos + ld a, [wNumMenuItems] + dec a + jr .got_cursor_pos +.check_d_right + bit D_RIGHT_F, b + jr z, .handle_ab_btns + inc a + cp c + jr c, .got_cursor_pos + ; if over max pos, set to pos 0 + xor a +.got_cursor_pos + push af + ld a, TRUE + ld [wMenuInputSFX], a + call DrawHorizontalListCursor_Invisible + pop af + ld [wCurScrollMenuItem], a + xor a + ld [wScrollMenuCursorBlinkCounter], a + +.handle_ab_btns + ld a, [wCurScrollMenuItem] + ld [hCurMenuItem], a + ldh a, [hKeysPressed] + and A_BUTTON | B_BUTTON + jr z, HandleCardSelectionCursorBlink + and A_BUTTON + jr nz, ConfirmSelectionAndReturnCarry + ; b button + ld a, $ff + ld [hCurMenuItem], a + call PlayAcceptOrDeclineSFX + scf + ret + +; outputs cursor position in e and selection in a +ConfirmSelectionAndReturnCarry: + call DrawHorizontalListCursor_Visible + ld a, $01 + call PlayAcceptOrDeclineSFX + ld a, [wCurScrollMenuItem] + ld e, a + ld a, [hCurMenuItem] + scf + ret + +HandleCardSelectionCursorBlink: + ld a, [wMenuInputSFX] + or a + jr z, .skip_sfx + call PlaySFX +.skip_sfx + ld hl, wScrollMenuCursorBlinkCounter + ld a, [hl] + inc [hl] + and $0f + ret nz + ld a, [wMenuVisibleCursorTile] + bit 4, [hl] + jr z, DrawHorizontalListCursor + +DrawHorizontalListCursor_Invisible: + ld a, [wMenuInvisibleCursorTile] +; fallthrough + +; like DrawListCursor but only +; for lists with one line, and each entry +; being laid horizontally +; a = tile to write +DrawHorizontalListCursor: + ld e, a + ld a, [wMenuXSeparation] + ld l, a + ld a, [wCurScrollMenuItem] + ld h, a + call HtimesL + ld a, l + ld hl, wMenuCursorXOffset + add [hl] + ld b, a ; x coord + ld hl, wMenuCursorYOffset + ld a, [hl] + ld c, a ; y coord + ld a, e + call WriteByteToBGMap0 + or a + ret + +DrawHorizontalListCursor_Visible: + ld a, [wMenuVisibleCursorTile] + jr DrawHorizontalListCursor + +; handles user input when selecting cards to add +; to deck configuration +; returns carry if a selection was made +; (either selected card or cancelled) +; outputs in a the list index if selection was made +; or $ff if operation was cancelled +HandleScrollListInput: + xor a ; FALSE + ld [wMenuInputSFX], a + ldh a, [hDPadHeld] + or a + jp z, .asm_9ff4 + ld b, a + ld a, [wNumMenuItems] + ld c, a + ld a, [wCurScrollMenuItem] + bit D_UP_F, b + jr z, .check_d_down +; d_up + push af + ld a, SFX_01 + ld [wMenuInputSFX], a + pop af + dec a + bit 7, a + jr z, .done_scroll + ld a, [wScrollMenuScrollOffset] + or a + jr z, .already_at_top + dec a + ld [wScrollMenuScrollOffset], a + ld hl, wScrollMenuScrollFunc + call CallIndirect + xor a + jr .done_scroll +.already_at_top + xor a + ld [wMenuInputSFX], a + jr .done_scroll + +.check_d_down + bit D_DOWN_F, b + jr z, .asm_9fd8 +; d_down + push af + ld a, SFX_01 + ld [wMenuInputSFX], a + pop af + inc a + cp c + jr c, .done_scroll + push af + ld a, [wUnableToScrollDown] + or a + jr nz, .already_at_bottom + ld a, [wScrollMenuScrollOffset] + inc a + ld [wScrollMenuScrollOffset], a + ld hl, wScrollMenuScrollFunc + call CallIndirect + pop af + dec a + jr .done_scroll +.already_at_bottom + pop af + dec a + push af + xor a + ld [wMenuInputSFX], a + pop af + +.done_scroll + push af + call DrawListCursor_Invisible + pop af + ld [wCurScrollMenuItem], a + xor a + ld [wScrollMenuCursorBlinkCounter], a + jr .asm_9ff4 + +.asm_9fd8 + ld a, [wd119] + or a + jr z, .asm_9ff4 + bit D_LEFT_F, b + jr z, .asm_9fea + call GetSelectedVisibleCardID + call RemoveCardFromDeckAndUpdateCount + jr .asm_9ff4 +.asm_9fea + bit D_RIGHT_F, b + jr z, .asm_9ff4 + call GetSelectedVisibleCardID + call AddCardToDeckAndUpdateCount + +.asm_9ff4 + ld a, [wCurScrollMenuItem] + ld [hCurMenuItem], a + ld hl, wMenuUpdateFunc + ld a, [hli] + or [hl] + jr z, .null + ld a, [hld] + ld l, [hl] + ld h, a + ld a, [hCurMenuItem] + call CallHL + jr nc, .blink_cursor +.selected + call DrawListCursor_Visible + ld a, $01 + call PlayAcceptOrDeclineSFX + ld a, [wCurScrollMenuItem] + ld e, a + ld a, [hCurMenuItem] + scf + ret + +.null + ldh a, [hKeysPressed] + and A_BUTTON | B_BUTTON + jr z, .check_sfx + and A_BUTTON + jr nz, .selected + ld a, $ff + ld [hCurMenuItem], a + call PlayAcceptOrDeclineSFX + scf + ret + +.check_sfx + ld a, [wMenuInputSFX] + or a + jr z, .blink_cursor + call PlaySFX + +.blink_cursor + ld hl, wScrollMenuCursorBlinkCounter + ld a, [hl] + inc [hl] + and %1111 + ret nz + ld a, [wMenuVisibleCursorTile] + bit 4, [hl] + jr z, DrawListCursor + +DrawListCursor_Invisible: + ld a, [wMenuInvisibleCursorTile] +; fallthrough + +; draws cursor considering wCurScrollMenuItem +; spaces each entry horizontally by wCardListXSpacing +; and vertically by wCardListYSpacing +; a = tile to write +DrawListCursor: + ld e, a + ld a, [wMenuXSeparation] + ld l, a + ld a, [wCurScrollMenuItem] + ld h, a + call HtimesL + ld a, l + ld hl, wMenuCursorXOffset + add [hl] + ld b, a ; x coord + ld a, [wMenuYSeparation] + ld l, a + ld a, [wCurScrollMenuItem] + ld h, a + call HtimesL + ld a, l + ld hl, wMenuCursorYOffset + add [hl] + ld c, a ; y coord + ld a, e + call WriteByteToBGMap0 + or a + ret + +DrawListCursor_Visible: + ld a, [wMenuVisibleCursorTile] + jr DrawListCursor + +OpenCardPageFromCardList: +; get the card index that is selected +; and open its card page + ld hl, wCurCardListPtr + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wCurScrollMenuItem] + add a ; *2 + ld c, a + ld b, $0 + add hl, bc + ld a, [wScrollMenuScrollOffset] + add a ; *2 + ld c, a + ld b, $0 + add hl, bc + ld e, [hl] + inc hl + ld d, [hl] + push de + call LoadCardDataToBuffer1_FromCardID + lb de, $38, $9f + call SetupText + bank1call OpenCardPage_FromCheckHandOrDiscardPile + pop de + +.handle_input + ldh a, [hDPadHeld] + ld b, a + and A_BUTTON | B_BUTTON | SELECT | START + jp nz, .exit + +; check d-pad +; if UP or DOWN is pressed, change the +; card that is being shown, given the +; order in the current card list + xor a ; FALSE + ld [wMenuInputSFX], a + ld a, [wNumMenuItems] + ld c, a + ld a, [wCurScrollMenuItem] + bit D_UP_F, b + jr z, .check_d_down + push af + ld a, TRUE + ld [wMenuInputSFX], a + pop af + dec a + bit 7, a + jr z, .reopen_card_page + ld a, [wScrollMenuScrollOffset] + or a + jr z, .handle_regular_card_page_input + dec a + ld [wScrollMenuScrollOffset], a + xor a + jr .reopen_card_page + +.check_d_down + bit D_DOWN_F, b + jr z, .handle_regular_card_page_input + push af + ld a, TRUE + ld [wMenuInputSFX], a + pop af + inc a + cp c + jr c, .reopen_card_page + push af + ld hl, wCurCardListPtr + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wCurScrollMenuItem] + add a ; *2 + ld c, a + ld b, $0 + add hl, bc + ld a, [wScrollMenuScrollOffset] + inc a + add a ; *2 + ld c, a + ld b, $0 + add hl, bc + push de + ld e, [hl] + inc hl + ld d, [hl] + call CheckIfCardIDIsZero + pop de + jr c, .skip_change_card + ld a, [wScrollMenuScrollOffset] + inc a + ld [wScrollMenuScrollOffset], a + pop af + dec a +.reopen_card_page + ld [wCurScrollMenuItem], a + ld a, [wMenuInputSFX] + or a + jp z, OpenCardPageFromCardList + call PlaySFX + jp OpenCardPageFromCardList + +.skip_change_card + pop af + jr .handle_regular_card_page_input ; unnecessary jr +.handle_regular_card_page_input + push de + bank1call OpenCardPage.loop_input + pop de + jp .handle_input + +.exit + ld a, $1 + ld [wVBlankOAMCopyToggle], a + ld a, [wCurScrollMenuItem] + ld [wTempCurMenuItem], a + ret +; 0xa132 + +SECTION "Bank 2@6152", ROMX[$6152], BANK[$2] + +; adds card in register de to deck configuration +; and updates the values shown for its count +; in the card selection list +; input: +; de = card ID +AddCardToDeckAndUpdateCount: + call .TryAddCardToDeck + ret c ; failed to add card + push de + call PrintCardTypeCounts + lb de, 15, 0 + call PrintTotalCardCount + pop de + call GetCountOfCardInCurDeck + call PrintNumberValueInCursorYPos + ret + +; tries to add card ID in register e to wCurDeckCards +; fails to add card if one of the following conditions are met: +; - total cards are equal to wMaxNumCardsAllowed +; - cards with the same name as it reached the allowed limit +; - player doesn't own more copies in the collection +; returns carry if fails +; otherwise, writes card ID to first empty slot in wCurDeckCards +; input: +; de = card ID +.TryAddCardToDeck: + push de + ld a, [wMaxNumCardsAllowed] + ld d, a + ld a, [wTotalCardCount] + cp d + pop de + jr nz, .not_equal + ; wMaxNumCardsAllowed == wTotalCardCount + scf + ret + +.not_equal + push de + call .CheckIfCanAddCardWithSameName + pop de + ret c ; cannot add more cards with this name + + push de + call GetCountOfCardInCurDeck + ld b, a + ld hl, wBoosterPackCardCounts + ld d, $00 + ld a, [wScrollMenuScrollOffset] + ld e, a + add hl, de + ld a, [wCurScrollMenuItem] + ld e, a + add hl, de + ld d, [hl] + ld a, b + cp d + pop de + scf + ret z ; cannot add because player doesn't own more copies + + ld a, SFX_01 + call PlaySFX + push de + call .AddCardToCurDeck + ld a, [wCurCardTypeFilter] + ld c, a + ld b, $00 + ld hl, wCardFilterCounts + add hl, bc + inc [hl] + pop de + or a + ret + +; finds first empty slot in wCurDeckCards +; then writes the card ID in de to it +.AddCardToCurDeck: + ld hl, wCurDeckCards +.loop_find_empty + ld a, [hli] + or a + jr z, .empty + inc hl + jr .loop_find_empty +.empty + ld a, [hli] + or a + jr nz, .loop_find_empty + xor a + ld [hli], a + ld [hl], a + dec hl + dec hl + ld [hl], d + dec hl + ld [hl], e + ret + +; returns carry if card ID in de cannot be +; added to the current deck configuration +; due to having reached the maximum number +; of cards allowed with that same name +; de = card id +.CheckIfCanAddCardWithSameName: + call LoadCardDataToBuffer1_FromCardID + ld a, [wLoadedCard1Type] + cp TYPE_ENERGY_DOUBLE_COLORLESS + jr nc, .has_limit + ; basic energy cards have no limit + and TYPE_ENERGY + cp TYPE_ENERGY + jr z, .no_carry + +.has_limit +; compare this card's name to +; the names of cards in list wCurDeckCards + ld a, [wLoadedCard1Name + 0] + ld c, a + ld a, [wLoadedCard1Name + 1] + ld b, a + ld hl, wCurDeckCards + ld d, 0 + push de +.loop_cards + ld e, [hl] + inc hl + ld d, [hl] + inc hl + call CheckIfCardIDIsZero + jr c, .no_carry_pop_de + call GetCardName + ld a, e + cp c + jr nz, .loop_cards + ld a, d + cp b + jr nz, .loop_cards + ; has same name + pop de + inc d ; increment counter of cards with this name + ld a, [wSameNameCardsLimit] + cp d + push de + jr nz, .loop_cards + ; reached the maximum number + ; of cards with same name allowed + pop de + scf + ret + +.no_carry_pop_de + pop de +.no_carry + or a + ret + +; gets the element in wVisibleListCardIDs +; corresponding to index wCurScrollMenuItem +GetSelectedVisibleCardID: + ld hl, wVisibleListCardIDs + ld a, [wCurScrollMenuItem] + add a ; *2 + ld e, a + ld d, $00 + add hl, de + ld e, [hl] + inc hl + ld d, [hl] + ret + +; appends the digits of value in register a to wDefaultText +; then prints it in cursor Y position +; a = value to convert to numerical digits +PrintNumberValueInCursorYPos: + ld hl, wDefaultText + call ConvertToNumericalDigits + ld [hl], TX_END + ld a, [wMenuYSeparation] + ld l, a + ld a, [wCurScrollMenuItem] + ld h, a + call HtimesL + ld a, l + ld hl, wMenuCursorYOffset + add [hl] + ld e, a + ld d, 14 + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + ret + +; removes card in register de from deck configuration +; and updates the values shown for its count +; in the card selection list +; input: +; de = card ID +RemoveCardFromDeckAndUpdateCount: + call RemoveCardFromDeck + ret nc + push de + call PrintCardTypeCounts + ld de, $f00 + call PrintTotalCardCount + pop de + call GetCountOfCardInCurDeck + call PrintNumberValueInCursorYPos + ret + +; removes card ID in de from wCurDeckCards +RemoveCardFromDeck: + push de + call GetCountOfCardInCurDeck + pop de + or a + ret z ; card is not in deck + ld a, SFX_01 + call PlaySFX + push de + call .RemoveCard + ld a, [wCurCardTypeFilter] + ld c, a + ld b, $00 + ld hl, wCardFilterCounts + add hl, bc + dec [hl] + pop de + scf + ret + +; remove first card instance of card ID in de +; and shift all elements up by one +.RemoveCard: + ld hl, wCurDeckCards +.loop_find + ld a, [hli] + cp e + jr z, .compare_high_byte + inc hl + jr .loop_find +.compare_high_byte + ld a, [hli] + cp d + jr nz, .loop_find + ld c, l + ld b, h + dec bc + dec bc +.loop_overwrite + ld e, [hl] + inc hl + ld d, [hl] + inc hl + call CheckIfCardIDIsZero + jr c, .done + ld a, e + ld [bc], a + inc bc + ld a, d + ld [bc], a + inc bc + jr .loop_overwrite + +.done + xor a + ld [bc], a + inc bc + ld [bc], a + ret +; 0xa295 + +SECTION "Bank 2@6295", ROMX[$6295], BANK[$2] + +UpdateConfirmationCardScreen: + ld hl, hffbb + ld [hl], $01 + call PrintCurDeckNumberAndName + ld hl, hffbb + ld [hl], $00 + jp PrintConfirmationCardList + +HandleDeckConfirmationMenu: +; if deck is empty, just show deck info header with empty card list + ld a, [wTotalCardCount] + or a + jp z, ShowDeckInfoHeaderAndWaitForBButton + +; create list of all unique cards + call SortCurDeckCardsByID + call CreateCurDeckUniqueCardList + + xor a + ld [wScrollMenuScrollOffset], a +.init_params + ld hl, .CardSelectionParams + call InitializeScrollMenuParameters + ld a, [wNumUniqueCards] + ld [wNumCardListEntries], a + cp NUM_DECK_CONFIRMATION_VISIBLE_CARDS + jr c, .no_cap + ld a, NUM_DECK_CONFIRMATION_VISIBLE_CARDS +.no_cap + ld [wNumMenuItems], a + ld [wNumVisibleCardListEntries], a + call ShowConfirmationCardScreen + + ld hl, UpdateConfirmationCardScreen + ld d, h + ld a, l + ld hl, wScrollMenuScrollFunc + ld [hli], a + ld [hl], d + + xor a + ld [wd119], a +.loop_input + call DoFrame + call HandleScrollListInput + jr c, .selection_made + call HandleJumpListInput + jr c, .loop_input + ldh a, [hDPadHeld] + and START + jr z, .loop_input + +.selected_card + ld a, $01 + call PlayAcceptOrDeclineSFX + ld a, [wCurScrollMenuItem] + ld [wced7], a + + ; set wOwnedCardsCountList as current card list + ; and show card page screen + ld de, wOwnedCardsCountList + ld hl, wCurCardListPtr + ld [hl], e + inc hl + ld [hl], d + call OpenCardPageFromCardList + jr .init_params + +.selection_made + ld a, [hCurMenuItem] + cp $ff + ret z ; operation cancelled + jr .selected_card + +.CardSelectionParams + db 0 ; x pos + db 5 ; y pos + db 2 ; y spacing + db 0 ; x spacing + db 7 ; num entries + db SYM_CURSOR_R ; visible cursor tile + db SYM_SPACE ; invisible cursor tile + dw NULL ; wCardListHandlerFunction + +; handles the cases where player presses +; left or right to jump in a scrolling list +HandleJumpListInput: + ld a, [wNumMenuItems] + ld d, a + ld a, [wScrollMenuScrollOffset] + ld c, a + ldh a, [hDPadHeld] + cp D_RIGHT + jr z, .d_right + cp D_LEFT + jr z, .d_left + or a + ret + +.d_right + ld a, [wScrollMenuScrollOffset] + add d + ld b, a + add d + ld hl, wNumCardListEntries + cp [hl] + jr c, .got_new_index + ld a, [wNumCardListEntries] + sub d + ld b, a + jr .got_new_index + +.d_left + ld a, [wScrollMenuScrollOffset] + sub d + ld b, a + jr nc, .got_new_index + ld b, $00 +.got_new_index + ld a, b + ld [wScrollMenuScrollOffset], a + cp c + jr z, .no_scroll + ld a, SFX_01 + call PlaySFX + ld hl, wScrollMenuScrollFunc + call CallIndirect +.no_scroll + scf + ret + +; handles scrolling up and down with Select button +; in this case, the cursor position goes up/down +; by wNumMenuItems entries respectively +; return carry if scrolling happened, otherwise no carry +HandleSelectUpAndDownInList: + ld a, [wNumMenuItems] + ld d, a + ld a, [wScrollMenuScrollOffset] + ld c, a + ldh a, [hDPadHeld] + cp SELECT | D_DOWN + jr z, .sel_down + cp SELECT | D_UP + jr z, .sel_up + or a + ret + +.sel_down + ld a, [wScrollMenuScrollOffset] + add d + ld b, a ; wScrollMenuScrollOffset + wNumMenuItems + add d + ld hl, wNumCardListEntries + cp [hl] + jr c, .got_new_pos + ld a, [wNumCardListEntries] + sub d + ld b, a ; wNumCardListEntries - wNumMenuItems + jr .got_new_pos +.sel_up + ld a, [wScrollMenuScrollOffset] + sub d + ld b, a ; wScrollMenuScrollOffset - wNumMenuItems + jr nc, .got_new_pos + ld b, 0 ; go to first position + +.got_new_pos + ld a, b + ld [wScrollMenuScrollOffset], a + cp c + jr z, .set_carry + ld a, SFX_01 + call PlaySFX + ld hl, wScrollMenuScrollFunc + call CallIndirect +.set_carry + scf + ret + +; simply draws the deck info header +; then awaits a b button press to exit +ShowDeckInfoHeaderAndWaitForBButton: + call ShowDeckInfoHeader +.wait_input + call DoFrame + ldh a, [hKeysPressed] + and B_BUTTON + jr z, .wait_input + ld a, $ff + call PlayAcceptOrDeclineSFX + ret + +ShowConfirmationCardScreen: + call ShowDeckInfoHeader + lb de, 3, 5 + ld hl, wCardListCoords + ld [hl], e + inc hl + ld [hl], d + call PrintConfirmationCardList + ret + +; draws a box on the top of the screen +; with wCurDeck's number, name and card count +; and draws the Hand Cards icon if it's +; the current dueling deck +ShowDeckInfoHeader: + call EmptyScreenAndLoadFontDuelAndHandCardsIcons + lb de, 0, 0 + lb bc, 20, 4 + call DrawRegularTextBox + ld a, [wCurDeckName] + or a + jp z, .print_card_count ; can be jr + +; draw hand cards icon if it's the current dueling deck + call PrintCurDeckNumberAndName + ld a, [wCurDeck] + ld b, a + call EnableSRAM + ld a, [sCurrentlySelectedDeck] + call DisableSRAM + cp b + jr nz, .print_card_count + lb de, 2, 1 + call DrawHandCardsTileAtDE + +.print_card_count + lb de, 14, 1 + call PrintTotalCardCount + lb de, 16, 1 + call PrintSlashSixty + call EnableLCD + ret + +; prints the name of wCurDeck in the form +; "X・ deck", where X is the number +; of the deck in the given menu +; if no current deck, print blank line +PrintCurDeckNumberAndName: + ld a, [wCurDeck] + cp $ff + jr z, .skip_deck_numeral + +; print the deck number in the menu +; in the form "X・" + lb de, 3, 2 + call InitTextPrinting + ld a, [wCurDeck] + bit 7, a + jr z, .incr_by_one + and $7f + jr .got_deck_numeral +.incr_by_one + inc a +.got_deck_numeral + ld hl, wDefaultText + call ConvertToNumericalDigits + ld [hl], "FW0_・" + inc hl + ld [hl], TX_END + ld hl, wDefaultText + call ProcessText + +.skip_deck_numeral + ld hl, wCurDeckName + ld de, wDefaultText + call CopyListFromHLToDE + ld a, [wCurDeck] + cp $ff + jr z, .blank_deck_name + +; print " deck" + ld hl, wDefaultText + call GetTextLengthInTiles + ld b, $0 + ld hl, wDefaultText + add hl, bc + ld d, h + ld e, l + ld hl, DeckNameSuffix + call CopyListFromHLToDE + lb de, 6, 2 + ld hl, wDefaultText + call InitTextPrinting + call ProcessText + ret + +.blank_deck_name + lb de, 2, 2 + ld hl, wDefaultText + call InitTextPrinting + call ProcessText + ret + +; sorts wCurDeckCards by ID in place +SortCurDeckCardsByID: + ld hl, wCurDeckCards +.loop + ld b, h + ld c, l + inc bc + inc bc + call .CheckEndOfDeck + ret z ; done +.compare + call .CompareCardIDs + jr nc, .ordered + call .SwapCardIDs +.ordered + call .CheckEndOfDeck + jr nz, .compare + inc hl + inc hl + jr .loop + +; returns c if card ID in [bc] < card ID in [hl] +.CompareCardIDs: + ld e, [hl] + inc hl + ld d, [hl] + dec hl + inc bc + ld a, [bc] + cp d + jr nz, .different_high + ; high byte matches, check low byte + dec bc + ld a, [bc] + cp e + inc bc +.different_high + inc bc + ret + +; swap card ID in [bc - $2] with [hl] +.SwapCardIDs: + dec bc + dec bc + ld a, [bc] + ld d, [hl] + ld [hli], a + ld a, d + ld [bc], a + inc bc + ld a, [bc] + ld d, [hl] + ld [hl], a + dec hl + ld a, d + ld [bc], a + inc bc + ret + +; returns z if bc points to end of deck +.CheckEndOfDeck: + ld a, [bc] + or a + ret nz + inc bc + ld a, [bc] + or a + dec bc + ret + +; goes through list in wCurDeckCards, and for each card in it +; creates list in wUniqueDeckCardList of all unique cards +; it finds (assuming wCurDeckCards is sorted by ID) +; also counts the total number of the different cards +CreateCurDeckUniqueCardList: + xor a + ld [wNumUniqueCards], a + ld b, a + ld c, a + ld hl, wCurDeckCards + ld de, wUniqueDeckCardList +.loop + ld a, [hli] + cp c + jr nz, .different_card_1 + ld a, [hl] + cp b + jr nz, .different_card_2 + inc hl + jr .loop +.different_card_2 + dec hl + ld a, [hli] +.different_card_1 + ld c, a + ld [de], a + inc de + push af + ld a, [hl] + ld b, a + ld [de], a + inc de + pop af + or [hl] + ret z + inc hl + ld a, [wNumUniqueCards] + inc a + ld [wNumUniqueCards], a + jr .loop + +; prints the list of cards visible in the window +; of the confirmation screen +; card info is presented with name, level and +; its count preceded by "x" +PrintConfirmationCardList: + push bc + ld hl, wCardListCoords + ld e, [hl] + inc hl + ld d, [hl] + ld b, 19 ; x coord + ld c, e + dec c + ld a, [wScrollMenuScrollOffset] + or a + jr z, .no_cursor + ld a, SYM_CURSOR_U + jr .got_cursor_tile_1 +.no_cursor + ld a, SYM_SPACE +.got_cursor_tile_1 + call WriteByteToBGMap0 + +; iterates by decreasing value in wNumVisibleCardListEntries +; by 1 until it reaches 0 + ld a, [wScrollMenuScrollOffset] + add a + ld c, a + ld b, $0 + ld hl, wOwnedCardsCountList + add hl, bc + ld a, [wNumVisibleCardListEntries] +.loop_cards + push de + or a + jr z, .exit_loop + ld b, a + ld e, [hl] + inc hl + ld d, [hl] + inc hl + call CheckIfCardIDIsZero + jr c, .no_more_cards + call AddCardIDToVisibleList + call LoadCardDataToBuffer1_FromCardID + ; places in wDefaultText the card's name and level + ; then appends at the end "x" with the count of that card + ; draws the card's type icon as well + ld a, 13 + push bc + push hl + push de + call CopyCardNameAndLevel + pop de + call .PrintCardCount + pop hl + pop bc + pop de + call .DrawCardTypeIcon + push hl + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + pop hl + ld a, b + dec a + inc e + inc e + jr .loop_cards + +.exit_loop + ld e, [hl] + inc hl + ld d, [hl] + call CheckIfCardIDIsZero + jr c, .no_more_cards + pop de + xor a ; FALSE + ld [wUnableToScrollDown], a + ld a, SYM_CURSOR_D + jr .got_cursor_tile_2 + +.no_more_cards + pop de + ld a, TRUE + ld [wUnableToScrollDown], a + ld a, SYM_SPACE +.got_cursor_tile_2 + ld b, 19 ; x coord + ld c, e + dec c + dec c + call WriteByteToBGMap0 + pop bc + ret + +; prints the card count preceded by a cross +; for example "x42" +.PrintCardCount: + push af + push bc + push de + push hl +.loop_search + ld a, [hl] + or a + jr z, .found_card_id + inc hl + jr .loop_search +.found_card_id + call GetCountOfCardInCurDeck + ld [hl], TX_SYMBOL + inc hl + ld [hl], SYM_CROSS + inc hl + call ConvertToNumericalDigits + ld [hl], TX_END + pop hl + pop de + pop bc + pop af + ret + +; draws the icon corresponding to the loaded card's type +; can be any of Pokemon stages (basic, 1st and 2nd stage) +; Energy or Trainer +; draws it 2 tiles to the left and 1 up to +; the current coordinate in de +.DrawCardTypeIcon + push hl + push de + push bc + ld a, [wLoadedCard1Type] + cp TYPE_ENERGY + jr nc, .not_pkmn_card + +; pokemon card + ld a, [wLoadedCard1Stage] + ld b, a + add b + add b + add b ; *4 + add ICON_TILE_BASIC_POKEMON + jr .got_tile + +.not_pkmn_card + cp TYPE_TRAINER + jr nc, .trainer_card + +; energy card + sub TYPE_ENERGY + ld b, a + add b + add b + add b ; *4 + add ICON_TILE_FIRE + jr .got_tile + +.trainer_card + ld a, ICON_TILE_TRAINER +.got_tile + dec d + dec d + dec e + push af + lb hl, 1, 2 + lb bc, 2, 2 + call FillRectangle + pop af + + call GetCardTypeIconPalette + ld b, a + ld a, [wConsole] + cp CONSOLE_CGB + jr nz, .skip_pal + ld a, b + lb bc, 2, 2 + lb hl, 0, 0 + call BankswitchVRAM1 + call FillRectangle + call BankswitchVRAM0 +.skip_pal + pop bc + pop de + pop hl + ret + +; returns in a the BG Pal corresponding to the +; card type icon in input register a +; if not found, returns $00 +GetCardTypeIconPalette: + push bc + push hl + push de + push af + bank1call Func_6c12 + pop af + pop de + ld b, a + ld hl, .CardTypeIconPalettes +.loop + ld a, [hli] + or a + jr z, .done + cp b + jr z, .done + inc hl + jp .loop ; can be jr +.done + ld a, [hl] + pop hl + pop bc + ret + +.CardTypeIconPalettes: +; icon tile, BG pal + db ICON_TILE_FIRE, 2 + db ICON_TILE_GRASS, 3 + db ICON_TILE_LIGHTNING, 2 + db ICON_TILE_WATER, 3 + db ICON_TILE_FIGHTING, 4 + db ICON_TILE_PSYCHIC, 4 + db ICON_TILE_COLORLESS, 0 + db ICON_TILE_ENERGY, 3 + db ICON_TILE_BASIC_POKEMON, 3 + db ICON_TILE_STAGE_1_POKEMON, 3 + db ICON_TILE_STAGE_2_POKEMON, 2 + db ICON_TILE_TRAINER, 3 + db $00, $ff +; 0xa603 + +SECTION "Bank 2@677f", ROMX[$677f], BANK[$2] + +CopyBBytesFromHLToDE_Bank02: +.loop + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .loop + ret +; 0xa786 + +SECTION "Bank 2@68b4", ROMX[$68b4], BANK[$2] + +; a = which card type filter +PrintFilteredCardSelectionList: + push af + ld hl, CardTypeFilters + ld b, $00 + ld c, a + add hl, bc + ld a, [hl] + push af + ld a, ALL_DECKS + call CreateCardCollectionListWithDeckCards + ld a, TRUE + ld [wd121], a + pop af + call CreateFilteredCardList + + ld a, NUM_DECK_CONFIRMATION_VISIBLE_CARDS + ld [wNumVisibleCardListEntries], a + lb de, 2, 5 + ld hl, wCardListCoords + ld [hl], e + inc hl + ld [hl], d + ld a, SYM_SPACE + ld [wCursorAlternateTile], a + call PrintCardSelectionList + pop af + ret + +; creates a card collection list in wTempCardCollection +; if a is $80, only include cards that are in the +; built decks, otherwise include all owned cards +CreateCardCollectionListWithDeckCards: + cp $80 + jr nz, .copy_card_collection + ld hl, wTempCardCollection + xor a + call ClearNBytesFromHL + ld hl, wTempCardCollection + $100 + xor a + call ClearNBytesFromHL + ld a, ALL_DECKS + ld [hffbf], a + jr .deck_1 + +.copy_card_collection + ld [hffbf], a + +; copies sCardCollection to wTempCardCollection + call EnableSRAM + ld hl, sCardCollection + ld de, wTempCardCollection + ld b, $00 ; aka $100 bytes + call CopyBBytesFromHLToDE_Bank02 + ld hl, sCardCollection + $100 + ld de, wTempCardCollection + $100 + ld b, $00 ; aka $100 bytes + call CopyBBytesFromHLToDE_Bank02 + call DisableSRAM +.deck_1 + ld a, [hffbf] + bit DECK_1_F, a + jr z, .deck_2 + ld de, sDeck1Cards + call IncrementDeckCardsInTempCollection +.deck_2 + ld a, [hffbf] + bit DECK_2_F, a + jr z, .deck_3 + ld de, sDeck2Cards + call IncrementDeckCardsInTempCollection +.deck_3 + ld a, [hffbf] + bit DECK_3_F, a + jr z, .deck_4 + ld de, sDeck3Cards + call IncrementDeckCardsInTempCollection +.deck_4 + ld a, [hffbf] + bit DECK_4_F, a + ret z + ld de, sDeck4Cards + call IncrementDeckCardsInTempCollection + ret + +; goes through cards in deck in de +; and for each card ID, increments its corresponding +; entry in wTempCardCollection +IncrementDeckCardsInTempCollection: + call EnableSRAM + ld a, 8 +.loop_outer + push af + ld a, [de] + inc de + ld b, a + ld c, 8 +.loop_inner + ld a, [de] + inc de + push de + ld e, a + xor a + rl b + rla + ld d, a + ld hl, wTempCardCollection + add hl, de + inc [hl] + pop de + dec c + jr nz, .loop_inner + pop af + dec a + jr nz, .loop_outer + call DisableSRAM + ret + +; prints the name, level and storage count of the cards +; that are visible in the list window +; in the form: +; CARD NAME/LEVEL X +; where X is the current count of that card +PrintCardSelectionList: + push bc + ld hl, wCardListCoords + ld e, [hl] + inc hl + ld d, [hl] + ld b, 19 ; x coord + ld c, e + ld a, [wScrollMenuScrollOffset] + or a + jr z, .alternate_cursor_tile + ld a, SYM_CURSOR_U + jr .got_cursor_tile_1 +.alternate_cursor_tile + ld a, [wCursorAlternateTile] +.got_cursor_tile_1 + call WriteByteToBGMap0 + +; iterates by decreasing value in wNumVisibleCardListEntries +; by 1 until it reaches 0 + ld a, [wScrollMenuScrollOffset] + add a + ld c, a + ld b, $0 + ld hl, wTempCardList + add hl, bc + ld a, [wNumVisibleCardListEntries] +.loop_filtered_cards + push de + or a + jr z, .exit_loop + ld b, a + ld e, [hl] + inc hl + ld d, [hl] + inc hl + call CheckIfCardIDIsZero + jr c, .invalid_card + call AddCardIDToVisibleList + call LoadCardDataToBuffer1_FromCardID + ; places in wDefaultText the card's name and level + ; then appends at the end the count of that card + ; in the card storage + ld a, 14 + push bc + push hl + push de + call CopyCardNameAndLevel + pop de + call AppendOwnedCardCountNumber + pop hl + pop bc + pop de + push hl + call InitTextPrinting + ld hl, wDefaultText + jr .process_text +.invalid_card + pop de + push hl + call InitTextPrinting + ld hl, Text_9e48 + $6 +.process_text + call ProcessText + pop hl + + ld a, b + dec a + inc e + inc e + jr .loop_filtered_cards + +.exit_loop + ld a, [hli] + or a + jr nz, .asm_a9e3 + ld a, [hli] + or a + jr z, .cannot_scroll +.asm_a9e3 + pop de +; draw down cursor because +; there are still more cards +; to be scrolled down + xor a ; FALSE + ld [wUnableToScrollDown], a + ld a, SYM_CURSOR_D + jr .got_cursor_tile_2 +.cannot_scroll + pop de + ld a, TRUE + ld [wUnableToScrollDown], a + ld a, [wCursorAlternateTile] +.got_cursor_tile_2 + ld b, 19 ; x coord + ld c, e + dec c + dec c + call WriteByteToBGMap0 + pop bc + ret + +; appends the card count given in register e +; to the list in hl, in numerical form +; (i.e. its numeric symbol representation) +AppendOwnedCardCountNumber: + push af + push bc + push de + push hl +; increment hl until end is reached ($00 byte) +.loop + ld a, [hl] + or a + jr z, .end + inc hl + jr .loop +.end + call Func_9c55 + call ConvertToNumericalDigits + ld bc, $84 + ld [hl], c + inc hl + ld [hl], b + inc hl + ld [hl], $00 ; insert byte terminator + pop hl + pop de + pop bc + pop af + ret + +; print header info (card count and player name) +PrintPlayersCardsHeaderInfo: + call PrepareMenuGraphics +; fallthrough +PrintPlayersCardsHeaderInfo_SkipEmptyScreen: + lb bc, 0, 4 + ld a, SYM_BOX_TOP + call FillBGMapLineWithA + call PrintTotalNumberOfCardsInCollection + call PrintPlayersCardsText + call DrawCardTypeIcons + ret + +; prints "'s cards" +PrintPlayersCardsText: + lb de, 1, 0 + call InitTextPrinting + ld de, wDefaultText + call CopyPlayerName + ld hl, wDefaultText + call ProcessText + ld hl, wDefaultText + call GetTextLengthInTiles + inc b + ld d, b + ld e, 0 + call InitTextPrinting + ldtx hl, Text02d1 + call ProcessTextFromID + ret + +PrintTotalNumberOfCardsInCollection: + ld a, ALL_DECKS + call CreateCardCollectionListWithDeckCards + +; count all the cards in collection + ld bc, wTempCardCollection + 1 + ld de, 0 + ld hl, 0 +.loop_all_cards + ld a, [bc] + inc bc + and $7f + push de + ld d, $00 + ld e, a + add hl, de + pop de + cp16 NUM_CARDS + inc de + jr nz, .loop_all_cards + +; hl = total number of cards in collection + call .GetTotalCountDigits + ld hl, wTempCardCollection + ld de, wDecimalDigitsSymbols + ld b, $00 + call .PlaceNumericalChar + call .PlaceNumericalChar + call .PlaceNumericalChar + call .PlaceNumericalChar + call .PlaceNumericalChar + lb bc, TX_END, "FW0_枚" + ld [hl], c ; 枚 + inc hl + ld [hl], b + inc hl + ld [hl], TX_END + lb de, 13, 0 + call InitTextPrinting + ld hl, wTempCardCollection + call ProcessText + ret + +; places a numerical character in hl from de +; doesn't place a 0 if no non-0 +; numerical character has been placed before +; this makes it so that there are no +; 0s in more significant digits +.PlaceNumericalChar: + ld [hl], TX_SYMBOL + inc hl + ld a, b + or a + jr z, .leading_num + ld a, [de] + inc de + ld [hli], a + ret +.leading_num +; don't place a 0 as a leading number + ld a, [de] + inc de + cp SYM_0 + jr z, .space_char + ld [hli], a + ld b, $01 ; at least one non-0 char was placed + ret +.space_char + xor a ; SYM_SPACE + ld [hli], a + ret + +.GetTotalCountDigits: + ld de, wDecimalDigitsSymbols + ld bc, -10000 + call .GetDigit + ld bc, -1000 + call .GetDigit + ld bc, -100 + call .GetDigit + ld bc, -10 + call .GetDigit + ld bc, -1 + call .GetDigit + ret + +.GetDigit + ld a, SYM_0 - 1 +.loop + inc a + add hl, bc + jr c, .loop + ld [de], a + inc de + ld a, l + sub c + ld l, a + ld a, h + sbc b + ld h, a + ret + +; a = Booster Pack +CreateBoosterPackCardList: + push af + ld a, 2 * 80 + ld hl, wBoosterPackCardList + call ClearNBytesFromHL + ld a, 80 + 1 + ld hl, wBoosterPackCardCounts + call ClearNBytesFromHL + xor a + ld [wOwnedPhantomCards], a + pop af + + ld hl, 0 + ld de, 0 + ld b, a +.loop_create_booster_pack_list + inc de + call LoadCardDataToBuffer1_FromCardID + jp c, .handle_energy_cards + ld a, [wLoadedCard1Unk07] + cp b + jr nz, .loop_create_booster_pack_list + + ; handle promo cards differently + cp16 VENUSAUR_LV64 + jp z, .venusaur_lv64 + cp16 MEW_LV15 + jp z, .mew_lv15 + cp16 LUGIA + jp z, .lugia + cp16 HERE_COMES_TEAM_ROCKET + jp z, .here_comes_team_rocket + + ; ignore special energy cards + cp16 DOUBLE_COLORLESS_ENERGY + jp z, .loop_create_booster_pack_list + cp16 POTION_ENERGY + jp z, .loop_create_booster_pack_list + cp16 FULLHEAL_ENERGY + jp z, .loop_create_booster_pack_list + cp16 RAINBOW_ENERGY + jp z, .loop_create_booster_pack_list + cp16 RECYCLE_ENERGY + jp z, .loop_create_booster_pack_list + + push bc + push hl + ld bc, wBoosterPackCardList + add hl, hl + add hl, bc + ld [hl], e + inc hl + ld [hl], d + + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + pop hl + push hl + ld bc, wBoosterPackCardCounts + add hl, bc + ld [hl], a + pop hl + inc l + pop bc + jp .loop_create_booster_pack_list + +.handle_energy_cards + ld a, b + cp LEGENDARY_POWER + jr z, .legendary_power + cp WE_ARE_TEAM_ROCKET + jr z, .we_are_team_rocket + cp TEAM_ROCKETS_AMBITION + jp z, .team_rockets_ambition + or a + jp nz, .handle_phantom_cards + +; beginning pokemon + ld de, 0 +.loop_add_basic_energy_cards + inc de + cp16 DOUBLE_COLORLESS_ENERGY + jp z, .handle_phantom_cards + push bc + push hl + ld bc, wBoosterPackCardList + add hl, hl + add hl, bc + ld [hl], e + inc hl + ld [hl], d + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + pop hl + push hl + ld bc, wBoosterPackCardCounts + add hl, bc + ld [hl], a + pop hl + inc l + pop bc + jr .loop_add_basic_energy_cards + +.legendary_power + ld de, 0 +.loop_add_double_colorless_energy + inc de + cp16 BULBASAUR_LV12 + jp z, .handle_phantom_cards + cp16 DOUBLE_COLORLESS_ENERGY + jr nz, .loop_add_double_colorless_energy + push bc + push hl + ld bc, wBoosterPackCardList + add hl, hl + add hl, bc + ld [hl], e + inc hl + ld [hl], d + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + pop hl + push hl + ld bc, wBoosterPackCardCounts + add hl, bc + ld [hl], a + pop hl + inc l + pop bc + jr .loop_add_double_colorless_energy + +.we_are_team_rocket + ld de, 0 +.loop_add_potion_and_fullheal_energy + inc de + cp16 BULBASAUR_LV12 + jr z, .handle_phantom_cards + cp16 POTION_ENERGY + jr z, .potion_or_fullheal_energy + cp16 FULLHEAL_ENERGY + jr z, .potion_or_fullheal_energy + cp16 RAINBOW_ENERGY + jr nz, .loop_add_potion_and_fullheal_energy +.potion_or_fullheal_energy + push bc + push hl + ld bc, wBoosterPackCardList + add hl, hl + add hl, bc + ld [hl], e + inc hl + ld [hl], d + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + pop hl + push hl + ld bc, wBoosterPackCardCounts + add hl, bc + ld [hl], a + pop hl + inc l + pop bc + jr .loop_add_potion_and_fullheal_energy + +.team_rockets_ambition + ld de, 0 +.loop_add_recycle_energy + inc de + cp16 BULBASAUR_LV12 + jr z, .handle_phantom_cards + cp16 RECYCLE_ENERGY + jr nz, .loop_add_recycle_energy + push bc + push hl + ld bc, wBoosterPackCardList + add hl, hl + add hl, bc + ld [hl], e + inc hl + ld [hl], d + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + pop hl + push hl + ld bc, wBoosterPackCardCounts + add hl, bc + ld [hl], a + pop hl + inc l + pop bc + jr .loop_add_recycle_energy + +.handle_phantom_cards + ld a, [wOwnedPhantomCards] + bit PROMO_VENUSAUR_LV64_F, a + jr z, .asm_ac92 + call .AddVenusaurLv64 +.asm_ac92 + bit PROMO_MEW_LV15_F, a + jr z, .asm_ac99 + call .AddMewLv15 +.asm_ac99 + bit PROMO_LUGIA_F, a + jr z, .asm_aca0 + call .AddLugia +.asm_aca0 + bit PROMO_HERE_COMES_TEAM_ROCKET_F, a + jr z, .find_last_owned_card + call .AddHereComesTeamRocket + +.find_last_owned_card + dec l + ld c, l + ld b, h +.loop_find_last_owned_card + ld hl, wBoosterPackCardCounts + add hl, bc + ld a, [hl] + cp CARD_NOT_OWNED + jr nz, .owns_card + dec c + jr .loop_find_last_owned_card +.owns_card + inc c + ld a, c + ld [wBoosterPackCardListSize], a + + ; terminate lists + xor a + ld hl, wBoosterPackCardList + add hl, bc + add hl, bc + ld [hli], a + ld [hl], a + ld a, $ff + ld hl, wBoosterPackCardCounts + add hl, bc + ld [hl], a + ret + +.mew_lv15 + ld a, PROMO_MEW_LV15 + +.store_owned_phantom_card + push hl + push bc + ld b, a + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + cp CARD_NOT_OWNED + jr z, .promo_card_not_owned + ld a, [wOwnedPhantomCards] + or b + ld [wOwnedPhantomCards], a +.promo_card_not_owned + pop bc + pop hl + jp .loop_create_booster_pack_list + +.venusaur_lv64 + ld a, PROMO_VENUSAUR_LV64 + jr .store_owned_phantom_card + +.lugia + ld a, PROMO_LUGIA + jr .store_owned_phantom_card + +.here_comes_team_rocket + ld a, PROMO_HERE_COMES_TEAM_ROCKET + jr .store_owned_phantom_card + +.AddVenusaurLv64: + push af + push hl + ld de, VENUSAUR_LV64 +.asm_acf6 + ld bc, wBoosterPackCardList + add hl, hl + add hl, bc + ld [hl], e + inc hl + ld [hl], d + pop hl + push hl + ld bc, wBoosterPackCardCounts + add hl, bc + ld [hl], $01 + pop hl + inc l + pop af + ret + +.AddMewLv15: + push af + push hl + ld de, MEW_LV15 + jr .asm_acf6 + +.AddLugia: + push af + push hl + ld de, LUGIA + jr .asm_acf6 + +.AddHereComesTeamRocket: + push af + push hl + ld de, HERE_COMES_TEAM_ROCKET + jr .asm_acf6 + +; a = Booster Pack +PrepareBoosterPackCardList: + push af + call EnableSRAM + ld hl, sCardCollection + ld de, wTempCardCollection + ld b, 0 ; aka $100 bytes + call CopyBBytesFromHLToDE_Bank02 + ld hl, sCardCollection + $100 + ld de, wTempCardCollection + $100 + ld b, 0 ; aka $100 bytes + call CopyBBytesFromHLToDE_Bank02 + call DisableSRAM + pop af + + push af + call .GetEntryPrefix + call CreateBoosterPackCardList + ld a, 7 + ld [wNumVisibleCardListEntries], a + lb de, 2, 4 + ld hl, wCardListCoords + ld [hl], e + inc hl + ld [hl], d + pop af + ret + +; places in entry name the prefix associated with the selected Card Set +; a = CARD_SET_* constant +.GetEntryPrefix: + push af + cp PROMOTIONAL + jr nz, .check_team_rockets_ambition + lb de, $4, "FW4_P" + jr .got_letter +.check_team_rockets_ambition + cp TEAM_ROCKETS_AMBITION + jr nz, .check_we_are_team_rocket + lb de, $4, "FW4_H" + jr .got_letter +.check_we_are_team_rocket + cp WE_ARE_TEAM_ROCKET + jr nz, .check_sky_flying_pokemon + lb de, $4, "FW4_G" + jr .got_letter +.check_sky_flying_pokemon + cp SKY_FLYING_POKEMON + jr nz, .check_psychic_battle + lb de, $4, "FW4_F" + jr .got_letter +.check_psychic_battle + cp PSYCHIC_BATTLE + jr nz, .check_island_of_fossil + lb de, $4, "FW4_D" + jr .got_letter +.check_island_of_fossil + cp ISLAND_OF_FOSSIL + jr nz, .check_legendary_power + lb de, $4, "FW4_C" + jr .got_letter +.check_legendary_power + cp LEGENDARY_POWER + jr nz, .beginning_pokemon + lb de, $4, "FW4_B" + jr .got_letter +.beginning_pokemon + lb de, $4, "FW4_A" +.got_letter + ld hl, wBoosterPackCardListPrefixBuffer + ld [hl], d + inc hl + ld [hl], e + pop af + ret + +; prints the cards being shown in the Card Album screen +; for the corresponding Card Set +FillBoosterPackCardList: + push bc + ld hl, wCardListCoords + ld e, [hl] + inc hl + ld d, [hl] + ld b, 19 ; x + ld c, e + dec c + dec c + +; draw up cursor on top right + ld a, [wScrollMenuScrollOffset] + or a + jr z, .box_top_tile + ld a, SYM_CURSOR_U + jr .write_byte +.box_top_tile + ld a, SYM_BOX_TOP_R +.write_byte + call WriteByteToBGMap0 + + ; iterate through the visible cards + ; in reverse order to fill their names + ld a, [wScrollMenuScrollOffset] + ld l, a + ld h, $00 + ld a, [wNumVisibleCardListEntries] +.loop_visible_cards + push de + or a + jr z, .done_card_names + ld b, a + ld de, wBoosterPackCardList + push hl + add hl, hl + add hl, de + ld e, [hl] + inc hl + ld d, [hl] + pop hl + inc l + call CheckIfCardIDIsZero + jr c, .at_the_bottom + call AddCardIDToVisibleList + call LoadCardDataToBuffer1_FromCardID + push bc + push hl + ld de, wBoosterPackCardCounts + add hl, de + dec hl + ld a, [hl] + cp CARD_NOT_OWNED + jr nz, .copy_card_name + ld hl, .empty_slot_text + ld de, wDefaultText + call CopyListFromHLToDE + jr .got_card_text +.copy_card_name + ld a, 13 + call CopyCardNameAndLevel +.got_card_text + pop hl + pop bc + pop de + push hl + call InitTextPrinting + pop hl + push hl + call .AppendCardListIndex + call ProcessText + ld hl, wDefaultText + jr .process_text + ; unreachable + pop de + push hl + call InitTextPrinting + ld hl, Text_9e48 + $6 +.process_text + call ProcessText + pop hl + ld a, b + dec a + inc e + inc e + jr .loop_visible_cards + +.done_card_names + ld de, wBoosterPackCardList + add hl, hl + add hl, de + ld e, [hl] + inc hl + ld d, [hl] + call CheckIfCardIDIsZero + jr c, .at_the_bottom + pop de + xor a ; FALSE + ld [wUnableToScrollDown], a + ld a, SYM_CURSOR_D + jr .draw_down_arrow +.at_the_bottom + pop de + ld a, TRUE + ld [wUnableToScrollDown], a + ld a, SYM_BOX_BTM_R +.draw_down_arrow + ld b, 19 + ld c, 17 + call WriteByteToBGMap0 + pop bc + ret + +.empty_slot_text + textfw0 "-------------" + done + +.AppendCardListIndex: + push bc + push de + ld de, wBoosterPackCardList + add hl, hl + add hl, de + dec hl + ld d, [hl] + dec hl + ld e, [hl] + cp16 BULBASAUR_LV12 + jr c, .energy + + cp16 VENUSAUR_LV64 + jr z, .promo_card + cp16 MEW_LV15 + jr z, .promo_card + cp16 LUGIA + jr z, .promo_card + cp16 HERE_COMES_TEAM_ROCKET + jr z, .promo_card + + ld a, [wNumVisibleCardListEntries] + sub b + ld hl, wScrollMenuScrollOffset + add [hl] + inc a + call CalculateOnesAndTensDigits + ld hl, wDecimalDigitsSymbols + ld a, [hli] + ld b, a + ld a, [hl] + or a + jr nz, .over_10 + ld a, SYM_0 +.over_10 + ld hl, wBoosterPackCardListPrefixBuffer + $2 + ld [hl], TX_SYMBOL + inc hl + ld [hli], a + ld [hl], TX_SYMBOL + inc hl + ld a, b + ld [hli], a + ld [hl], TX_SYMBOL + inc hl + xor a + ld [hli], a ; SYM_SPACE + ld [hl], a ; TX_END + ld hl, wBoosterPackCardListPrefixBuffer + pop de + pop bc + ret + +.energy + ld a, e + call CalculateOnesAndTensDigits + ld hl, wDecimalDigitsSymbols + ld a, [hli] + ld b, a + ld a, [hl] + ld hl, wBoosterPackCardListPrefixBuffer + $2 + lb de, $4, "FW4_E" + ld [hl], d + inc hl + ld [hl], e + inc hl + ld [hl], TX_SYMBOL + inc hl + or a + jr nz, .over_10_energy + ld a, SYM_0 +.over_10_energy + ld [hli], a + ld [hl], TX_SYMBOL + inc hl + ld a, b + ld [hli], a + ld [hl], TX_SYMBOL + inc hl + xor a + ld [hli], a ; SYM_SPACE + ld [hl], a ; TX_END + ld hl, wBoosterPackCardListPrefixBuffer + $2 + pop de + pop bc + ret + +.promo_card + ; promo cards are numbered as xx + ld hl, wBoosterPackCardListPrefixBuffer + $2 + ld [hl], "FW0_×" + inc hl + ld [hl], "FW0_×" + inc hl + ld [hl], TX_SYMBOL + inc hl + xor a + ld [hli], a ; SYM_SPACE + ld [hl], a ; TX_END + ld hl, wBoosterPackCardListPrefixBuffer + pop de + pop bc + ret + +; handles opening card page, and inputs when inside Card Album +HandleCardAlbumCardPage: + ld a, [wCurScrollMenuItem] + ld b, a + ld a, [wScrollMenuScrollOffset] + add b + ld c, a + ld b, $00 + ld hl, wBoosterPackCardCounts + add hl, bc + ld a, [hl] + cp CARD_NOT_OWNED + jr z, .handle_input + + ld hl, wCurCardListPtr + ld a, [hli] + ld h, [hl] + ld l, a + add hl, bc + add hl, bc + ld e, [hl] + inc hl + ld d, [hl] + push de + call LoadCardDataToBuffer1_FromCardID + lb de, $38, $9f + call SetupText + bank1call OpenCardPage_FromCheckHandOrDiscardPile + pop de + +.handle_input + ldh a, [hDPadHeld] + ld b, a + and BUTTONS + jp nz, .exit + xor a ; FALSE + ld [wMenuInputSFX], a + ld a, [wNumMenuItems] + ld c, a + ld a, [wCurScrollMenuItem] + bit D_UP_F, b + jr z, .check_d_down + + push af + ld a, SFX_01 + ld [wMenuInputSFX], a + ld a, [wCurScrollMenuItem] + ld hl, wScrollMenuScrollOffset + add [hl] + ld hl, wFirstOwnedCardIndex + cp [hl] + jr z, .open_card_page_pop_af_2 + pop af + + dec a + bit 7, a + jr z, .got_new_pos + ld a, [wScrollMenuScrollOffset] + or a + jr z, .open_card_page + dec a + ld [wScrollMenuScrollOffset], a + xor a + jr .got_new_pos + +.check_d_down + bit D_DOWN_F, b + jr z, .open_card_page + push af + ld a, SFX_01 + ld [wMenuInputSFX], a + pop af + inc a + cp c + jr c, .got_new_pos + push af + ld hl, wCurCardListPtr + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wCurScrollMenuItem] + ld b, a + ld a, [wScrollMenuScrollOffset] + inc a + add b + ld c, a + ld b, $00 + add hl, bc + add hl, bc + ld e, [hl] + inc hl + ld d, [hl] + call CheckIfCardIDIsZero + jr c, .open_card_page_pop_af_1 + ld a, [wScrollMenuScrollOffset] + inc a + ld [wScrollMenuScrollOffset], a + pop af + dec a +.got_new_pos + ld [wCurScrollMenuItem], a + ld a, [wMenuInputSFX] + or a + jp z, HandleCardAlbumCardPage + call PlaySFX + jp HandleCardAlbumCardPage +.open_card_page_pop_af_1 + pop af + jr .open_card_page +.open_card_page_pop_af_2 + pop af + +.open_card_page + push de + bank1call OpenCardPage.loop_input + pop de + jp .handle_input + +.exit + ld a, $01 + ld [wVBlankOAMCopyToggle], a + ld a, [wCurScrollMenuItem] + ld [wTempCurMenuItem], a + ret + +GetFirstOwnedCardIndex: + ld hl, wBoosterPackCardCounts + ld b, 0 +.loop + ld a, [hli] + cp CARD_NOT_OWNED + jr nz, .owned + inc b + jr .loop +.owned + ld a, b + ld [wFirstOwnedCardIndex], a + ret + +CardAlbum: + ld a, $01 + ld [hffbe], a ; should be ldh + + xor a + ld [wScrollMenuScrollOffset], a +.booster_pack_menu + ld hl, .BoosterPackMenuParams + call InitializeScrollMenuParameters + call .ShowBoosterPackMenu + ld a, 5 + ld [wNumMenuItems], a + ld hl, FillBoosterPackMenuItems + ld d, h + ld a, l + ld hl, wScrollMenuScrollFunc + ld [hli], a + ld [hl], d + xor a + ld [wd119], a +.loop_input + call DoFrame + farcall HandleScrollMenu + jp nc, .loop_input ; can be jr + ld a, [hCurMenuItem] + cp $ff + ret z ; exit + + ; selected a Booster Pack + ld a, [wScrollMenuScrollOffset] + ld [wTempScrollMenuScrollOffset], a + ld b, a + ld a, [wCurScrollMenuItem] + ld [wTempScrollMenuItem], a + add b + ld c, a + ld b, $00 + ld hl, wBoosterPackItems + add hl, bc + ld a, [hl] + or a + jr nz, .loop_input ; haven't obtained + + ld a, c + ld [wCardAlbumBoosterPack], a + call PrepareBoosterPackCardList + call .InitList + xor a + ld [wScrollMenuScrollOffset], a + call FillBoosterPackCardList + call EnableLCD + ld a, [wBoosterPackCardListSize] + or a + jr nz, .card_list + ; is empty list +.loop_input_empty_list + call DoFrame + ldh a, [hKeysPressed] + and B_BUTTON + jr z, .loop_input_empty_list + ld a, $ff + call PlayAcceptOrDeclineSFX + ld a, [wTempScrollMenuScrollOffset] + ld [wScrollMenuScrollOffset], a + ld a, [wTempScrollMenuItem] + ld [wCurScrollMenuItem], a + jp .booster_pack_menu + +.card_list + call .CountCardIDs + xor a + ld hl, .BoosterPackCardsMenuParams + call InitializeScrollMenuParameters + ld a, [wBoosterPackCardListSize] + ld hl, wNumVisibleCardListEntries + cp [hl] + jr nc, .got_num_visible_cards + ld [wNumMenuItems], a +.got_num_visible_cards + ld hl, FillBoosterPackCardList + ld d, h + ld a, l + ld hl, wScrollMenuScrollFunc + ld [hli], a + ld [hl], d + xor a + ld [wd119], a +.loop + call DoFrame + call HandleScrollListInput + jr c, .card_selection_made + call HandleJumpListInput + jr c, .loop + ldh a, [hDPadHeld] + and START + jr z, .loop +.open_card_page + ld a, $01 + call PlayAcceptOrDeclineSFX + ld a, [wNumMenuItems] + ld [wTempScrollMenuNumVisibleItems], a + ld a, [wCurScrollMenuItem] + ld [wTempCurMenuItem], a + ld c, a + ld a, [wScrollMenuScrollOffset] + add c + ld hl, wBoosterPackCardCounts + ld c, a + ld b, $00 + add hl, bc + ld a, [hl] + cp CARD_NOT_OWNED + jr z, .loop + + ld de, wBoosterPackCardList + ld hl, wCurCardListPtr + ld [hl], e + inc hl + ld [hl], d + call GetFirstOwnedCardIndex + call HandleCardAlbumCardPage + + call .InitList + call FillBoosterPackCardList + call EnableLCD + ld hl, .BoosterPackCardsMenuParams + call InitializeScrollMenuParameters + ld a, [wTempScrollMenuNumVisibleItems] + ld [wNumMenuItems], a + ld a, [wTempCurMenuItem] + ld [wCurScrollMenuItem], a + jr .loop + +.card_selection_made + call DrawListCursor_Invisible + ld a, [wCurScrollMenuItem] + ld [wTempCurMenuItem], a + ld a, [hCurMenuItem] + cp $ff + jr nz, .open_card_page + ld a, [wTempScrollMenuScrollOffset] + ld [wScrollMenuScrollOffset], a + ld a, [wTempScrollMenuItem] + ld [wCurScrollMenuItem], a + jp .booster_pack_menu + +.BoosterPackMenuParams: + db 3, 2 ; x,y offset + db 2 ; y separation + db 0 ; x separation + db 5 ; number of items + db SYM_CURSOR_R ; visible cursor + db SYM_SPACE ; invisible cursor + dw NULL ; update func + +.BoosterPackCardsMenuParams + db 1, 4 ; x,y offset + db 2 ; y separation + db 0 ; x separation + db 7 ; number of items + db SYM_CURSOR_R ; visible cursor + db SYM_SPACE ; invisible cursor + dw NULL ; update func + +.CountCardIDs: + ld hl, wBoosterPackCardList + ld b, $00 +.loop_count_card_ids + ld e, [hl] + inc hl + ld d, [hl] + inc hl + call CheckIfCardIDIsZero + jr c, .zero + inc b + jr .loop_count_card_ids +.zero + ld a, b + ld [wNumCardListEntries], a + ret + +.InitList: + xor a + ld [wTileMapFill], a + call ZeroObjectPositions + call EmptyScreen + ld a, $01 + ld [wVBlankOAMCopyToggle], a + call LoadMenuCursorTile + call LoadSymbolsFont + call LoadDuelCardSymbolTiles + bank1call SetDefaultPalettes + ld de, $3cff + call SetupText + lb de, 1, 1 + call InitTextPrinting + + ld a, [wCardAlbumBoosterPack] + cp PROMOTIONAL + jr nz, .check_team_rockets_ambition + ldtx hl, Text02cd + ld e, NUM_CARDS_PROMOTIONAL + + ; check which Phantom cards were obtained + ; and adjust card count in e + ld a, [wOwnedPhantomCards] + bit PROMO_VENUSAUR_LV64_F, a + jr z, .check_mew + inc e +.check_mew + bit PROMO_MEW_LV15_F, a + jr z, .check_lugia + inc e +.check_lugia + bit PROMO_LUGIA_F, a + jr z, .check_here_comes_team_rocket + inc e +.check_here_comes_team_rocket + bit PROMO_HERE_COMES_TEAM_ROCKET_F, a + jr z, .got_booster_pack + inc e + jr .got_booster_pack + +.check_team_rockets_ambition + cp TEAM_ROCKETS_AMBITION + jr nz, .check_we_are_team_rocket + ldtx hl, Text02cb + ld e, NUM_CARDS_TEAM_ROCKETS_AMBITION + jr .got_booster_pack + +.check_we_are_team_rocket + cp WE_ARE_TEAM_ROCKET + jr nz, .check_sky_flying_pokemon + ld hl, SetWindowOn + ld e, NUM_CARDS_WE_ARE_TEAM_ROCKET + jr .got_booster_pack + +.check_sky_flying_pokemon + cp SKY_FLYING_POKEMON + jr nz, .check_psychic_battle + ldtx hl, Text02c7 + ld e, NUM_CARDS_SKY_FLYING_POKEMON + jr .got_booster_pack + +.check_psychic_battle + cp PSYCHIC_BATTLE + jr nz, .check_island_of_fossil + ldtx hl, Text02c5 + ld e, NUM_CARDS_PSYCHIC_BATTLE + jr .got_booster_pack + +.check_island_of_fossil + cp ISLAND_OF_FOSSIL + jr nz, .check_legendary_power + ldtx hl, Text02c3 + ld e, NUM_CARDS_ISLAND_OF_FOSSIL + jr .got_booster_pack + +.check_legendary_power + cp LEGENDARY_POWER + jr nz, .beginning_pokemon + ld hl, Set_OBJ_8x16 + ld e, NUM_CARDS_LEGENDARY_POWER + jr .got_booster_pack + +.beginning_pokemon + ldtx hl, Text02c1 + ld e, NUM_CARDS_BEGINNING_POKEMON +.got_booster_pack + ; prints "X/Y" where X is number of cards owned in the set + ; and Y is the total card count of the Card Set + push de + call ProcessTextFromID + call .GetNumberOfOwnedCards + lb de, 14, 1 + call InitTextPrinting + ld a, [wBoosterPackCardListNumItems] + ld hl, wDefaultText + call ConvertToNumericalDigits + ld [hl], TX_SYMBOL + inc hl + ld [hl], SYM_SLASH + inc hl + pop de + ld a, e ; number of cards + call ConvertToNumericalDigits + ld [hl], TX_END + ld hl, wDefaultText + call ProcessText + lb de, 0, 2 + lb bc, 20, 16 + call DrawRegularTextBox + call EnableLCD + ret + +.GetNumberOfOwnedCards: + ld hl, wBoosterPackCardCounts + ld b, 0 +.loop_counts + ld a, [hli] + cp $ff + jr z, .got_num_items + cp CARD_NOT_OWNED + jr z, .loop_counts + inc b + jr .loop_counts +.got_num_items + ld a, b + ld [wBoosterPackCardListNumItems], a + ret + +.ShowBoosterPackMenu: + xor a + ld [wTileMapFill], a + call EmptyScreen + ld a, [hffbe] + dec a + jp nz, .draw_box + ld [hffbe], a + call ZeroObjectPositions + ld a, $01 + ld [wVBlankOAMCopyToggle], a + + call LoadMenuCursorTile + call LoadSymbolsFont + call LoadDuelCardSymbolTiles + bank1call SetDefaultPalettes + lb de, $3c, $ff + call SetupText + + ; set all Card Sets as available + ld a, NUM_CARD_SETS + ld hl, wBoosterPackItems + call ClearNBytesFromHL + + ; check whether player has had promotional cards + call EnableSRAM + ld a, [sBoosterPacksObtained] + call DisableSRAM + cp $ff + jr z, .draw_box ; has all sets + + ; copies whole card collection from SRAM to WRAM, + ; in two batches of $100 cards each + call EnableSRAM + ld hl, sCardCollection + ld de, wTempCardCollection + ld b, $00 + call CopyBBytesFromHLToDE_Bank02 + ld hl, sCardCollection + $100 + ld de, wTempCardCollection + $100 + ld b, $00 + call CopyBBytesFromHLToDE_Bank02 + call DisableSRAM + + ld b, %1 + ld c, CIRCLE +.loop_sets + call EnableSRAM + ld a, [sBoosterPacksObtained] + call DisableSRAM + and b + jr nz, .next_set + push bc + ld a, c + call .CheckHasCardFromSet + pop bc + jr c, .has_set_card + ld hl, wBoosterPackItems + ld e, c + ld d, $00 + add hl, de + ld [hl], TRUE + jr .next_set +.has_set_card + call EnableSRAM + ld a, [sBoosterPacksObtained] + or b + ld [sBoosterPacksObtained], a + call DisableSRAM +.next_set + sla b + inc c + ld a, NUM_CARD_SETS + cp c + jr nz, .loop_sets + +.draw_box + lb de, 0, 0 + lb bc, 20, 13 + call DrawRegularTextBox + lb de, 1, 0 + ldtx hl, Text02c0 ; title + call Func_2c4b + farcall FillBoosterPackMenuItems + ldtx hl, Text02cf + call DrawWideTextBox_PrintText + farcall UpdateBoosterPackMenuArrows + ret + +; returns carry if any card +; with given set is owned +; b = set +.CheckHasCardFromSet: + ld de, 0 + ld hl, wTempCardCollection + $1 + ld b, a +.loop_card_ids + inc de + ld a, [hli] + cp CARD_NOT_OWNED + jr c, .owns +; not owned + cp16 NUM_CARDS + ret nc + jr .loop_card_ids +.owns + push bc + call GetCardTypeRarityAndSet + ld a, c ; set + pop bc + ccf + ret nc + cp NUM_CARD_SETS + jr nz, .ok + xor a ; BEGINNING_POKEMON +.ok + cp b + jr nz, .loop_card_ids + ; found + scf + ret + +PrinterMenu_PokemonCards: + call WriteCardListsTerminatorBytes + call PrintPlayersCardsHeaderInfo + xor a + ld [wScrollMenuScrollOffset], a + ld [wCurCardTypeFilter], a + call PrintFilteredCardSelectionList + call EnableLCD + xor a + ld hl, FiltersCardSelectionParams + call InitializeScrollMenuParameters + +.loop_frame_1 + call DoFrame + ld a, [wCurCardTypeFilter] + ld b, a + ld a, [wTempCardTypeFilter] + cp b + jr z, .handle_input + ld [wCurCardTypeFilter], a + ld hl, wScrollMenuScrollOffset + ld [hl], $00 + call PrintFilteredCardSelectionList + ld hl, hffbb + ld [hl], $01 + call PrintPlayersCardsText + ld hl, hffbb + ld [hl], $00 + ld a, NUM_FILTERS + ld [wNumMenuItems], a +.handle_input + ldh a, [hDPadHeld] + and D_DOWN + jr z, .asm_b33b +; d_down + call ConfirmSelectionAndReturnCarry + jr .asm_b348 +.asm_b33b + call HandleCardSelectionInput + jr nc, .loop_frame_1 + ld a, [hCurMenuItem] + cp $ff + jr nz, .asm_b348 + ret + +.asm_b348 + ld a, [wBoosterPackCardListSize] + or a + jr z, .loop_frame_1 + + xor a + ld hl, $689d + call InitializeScrollMenuParameters + ld a, [wBoosterPackCardListSize] + ld [wNumCardListEntries], a + ld hl, wNumVisibleCardListEntries + cp [hl] + jr nc, .asm_b367 + ld [wNumMenuItems], a + ld [wTempScrollMenuNumVisibleItems], a +.asm_b367 + ld hl, $68a6 + ld d, h + ld a, l + ld hl, wScrollMenuScrollFunc + ld [hli], a + ld [hl], d + xor a + ld [wd119], a + +.loop_frame_2 + call DoFrame + ldh a, [hDPadHeld] + and D_UP + jr z, .asm_b38e + ld a, [wTempCardTypeFilter] + ld hl, wScrollMenuScrollOffset + add [hl] + jr nz, .asm_b38e + ld a, $ff + ld [hCurMenuItem], a + jr .asm_b3e7 +.asm_b38e + call HandleSelectUpAndDownInList + jr c, .loop_frame_2 + call HandleScrollListInput + jr c, .asm_b3e7 + ldh a, [hDPadHeld] + and START + jr z, .loop_frame_2 +; start btn + ld a, $01 + call PlayAcceptOrDeclineSFX + ld a, [wNumMenuItems] + ld [wTempScrollMenuNumVisibleItems], a + ld a, [wTempCardTypeFilter] + ld [wTempCurMenuItem], a + + ; set wTempCardList as current card list + ; and show card page screen + ld de, wTempCardList + ld hl, wCurCardListPtr + ld [hl], e + inc hl + ld [hl], d + call OpenCardPageFromCardList + call PrintPlayersCardsHeaderInfo + +.asm_b3be + ld hl, FiltersCardSelectionParams + call InitializeScrollMenuParameters + ld a, [wCurCardTypeFilter] + ld [wTempCardTypeFilter], a + call DrawHorizontalListCursor_Visible + call PrintCardSelectionList + call EnableLCD + ld hl, $689d + call InitializeScrollMenuParameters + ld a, [wTempScrollMenuNumVisibleItems] + ld [wNumMenuItems], a + ld a, [wTempCurMenuItem] + ld [wTempCardTypeFilter], a + jr .loop_frame_2 + +.asm_b3e7 + call DrawListCursor_Invisible + ld a, [wNumMenuItems] + ld [wTempScrollMenuNumVisibleItems], a + ld a, [wTempCardTypeFilter] + ld [wTempCurMenuItem], a + ld a, [hCurMenuItem] + cp $ff + jr nz, .asm_b40c + + ld hl, FiltersCardSelectionParams + call InitializeScrollMenuParameters + ld a, [wCurCardTypeFilter] + ld [wTempCardTypeFilter], a + jp .loop_frame_1 + +.asm_b40c + call DrawListCursor_Visible + call .Func_b45d + lb de, 1, 1 + call InitTextPrinting + ld hl, $2f6 + call ProcessTextFromID + ld a, $01 + ld hl, Data_ad05 + call InitializeScrollMenuParameters +.loop_frame_3 + call DoFrame + call HandleCardSelectionInput + jr nc, .loop_frame_3 + ld a, [hCurMenuItem] + or a + jr nz, .asm_b454 + ld hl, wTempCardList + ld a, [wTempCurMenuItem] + add a + ld c, a + ld b, $00 + add hl, bc + ld a, [wScrollMenuScrollOffset] + add a + ld c, a + ld b, $00 + add hl, bc + ld e, [hl] + inc hl + ld d, [hl] + farcall RequestToPrintCard + call PrintPlayersCardsHeaderInfo + jp .asm_b3be + +.asm_b454 + call .Func_b45d + call PrintPlayersCardsHeaderInfo_SkipEmptyScreen + jp .asm_b3be + +.Func_b45d: + xor a + lb hl, 0, 0 + lb de, 0, 0 + lb bc, 20, 4 + call FillRectangle + ld a, [wConsole] + cp CONSOLE_CGB + ret nz ; exit if not CGB + + xor a + lb hl, 0, 0 + lb de, 0, 0 + lb bc, 20, 4 + call BankswitchVRAM1 + call FillRectangle + call BankswitchVRAM0 + ret + +Data_ad05: + db 3 ; x pos + db 3 ; y pos + db 0 ; y spacing + db 4 ; x spacing + db 2 ; num entries + db SYM_CURSOR_R ; visible cursor tile + db SYM_SPACE ; invisible cursor tile + dw NULL ; wCardListHandlerFunction + +PrinterMenu_CardList: + call WriteCardListsTerminatorBytes + call PrepareMenuGraphics + lb bc, 0, 4 + ld a, SYM_BOX_TOP + call FillBGMapLineWithA + + xor a + ld [wScrollMenuScrollOffset], a + ld [wCurCardTypeFilter], a + call PrintFilteredCardSelectionList + call EnableLCD + lb de, 1, 1 + call InitTextPrinting + ldtx hl, Text02f9 ; PrintTheCardListText + call ProcessTextFromID + ld a, $01 + ld hl, Data_ad05 + call InitializeScrollMenuParameters +.loop_frame + call DoFrame + call HandleCardSelectionInput + jr nc, .loop_frame + ld a, [hCurMenuItem] + or a + ret nz + farcall PrintCardList + ret + +PrinterMenu: + farcall ConnectPrinter + ret c ; error occured + xor a +.loop + ld hl, .MenuParameters + call InitializeMenuParameters + call EmptyScreenAndLoadFontDuelAndHandCardsIcons + lb de, 4, 0 + lb bc, 12, 12 + call DrawRegularTextBox + lb de, 6, 2 + call InitTextPrinting + ldtx hl, Text02fa + call ProcessTextFromID + ldtx hl, Text02fb + call DrawWideTextBox_PrintText + call EnableLCD +.loop_input + call DoFrame + call HandleMenuInput + jr nc, .loop_input + ldh a, [hCurScrollMenuItem] + cp $ff + call z, .QuitPrint + ld [wSelectedPrinterMenuItem], a + ld hl, .MenuFunctionTable + call JumpToFunctionInTable + ld a, [wSelectedPrinterMenuItem] + jr .loop + +.QuitPrint: + add sp, $2 ; exit menu + ldtx hl, Text02fd + call DrawWideTextBox_WaitForInput + ret + +.MenuFunctionTable: + dw PrinterMenu_PokemonCards + dw PrinterMenu_DeckConfiguration + dw PrinterMenu_CardList + dw .PrintQuality + dw .QuitPrint + +.MenuParameters: + db 5, 2 ; cursor x, cursor y + db 2 ; y displacement between items + db 5 ; number of items + db SYM_CURSOR_R ; cursor tile number + db SYM_SPACE ; tile behind cursor + dw NULL ; function pointer if non-0 + +.PrintQuality: + ldtx hl, Text02fc + call DrawWideTextBox_PrintText + call EnableSRAM + ld a, [sPrinterContrastLevel] + call DisableSRAM + ld hl, .PrinterQualityMenuParams + call InitializeScrollMenuParameters +.loop_input_quality + call DoFrame + call HandleCardSelectionInput + jr nc, .loop_input_quality + ld a, [hCurMenuItem] + cp $ff ; cancel + jr z, .re_draw_menu + call EnableSRAM + ld [sPrinterContrastLevel], a + call DisableSRAM +.re_draw_menu + add sp, $2 ; exit menu + ld a, [wSelectedPrinterMenuItem] + ld hl, .MenuParameters + call InitializeMenuParameters + ldtx hl, Text02fb + call DrawWideTextBox_PrintText + jr .loop_input + +.PrinterQualityMenuParams + db 5, 16 ; x,y offset + db 0 ; y separation + db 2 ; x separation + db 5 ; number of items + db SYM_CURSOR_R ; visible cursor + db SYM_SPACE ; invisible cursor + dw NULL ; update func +; 0xb57c + +SECTION "Bank 2@7af6", ROMX[$7af6], BANK[$2] + +PrinterMenu_DeckConfiguration: + farcall _PrinterMenu_DeckConfiguration + ret +; 0xbafb diff --git a/src/engine/bank03.asm b/src/engine/bank03.asm index f165512..a16b927 100644 --- a/src/engine/bank03.asm +++ b/src/engine/bank03.asm @@ -972,7 +972,7 @@ Func_d411: call PauseSong ld a, MUSIC_PCMAINMENU call PlaySong - farcall $4, $50c6 + farcall Func_110c6 call ResumeSong ret diff --git a/src/engine/bank04.asm b/src/engine/bank04.asm index d87362b..086e694 100644 --- a/src/engine/bank04.asm +++ b/src/engine/bank04.asm @@ -114,7 +114,7 @@ Func_102ef: .Func_10327: ld a, [wWRAMBank] push af - ld a, $03 + ld a, BANK("WRAM3") call SwitchWRAMBank xor a ld [w3d400], a @@ -126,9 +126,164 @@ Func_102ef: pop af call SwitchWRAMBank ret -; 0x10342 -SECTION "Bank 4@4413", ROMX[$4413], BANK[$4] +Func_10342: + push af + push bc + push de + push hl + ld a, [wWRAMBank] + push af + ld a, BANK("WRAM3") + call SwitchWRAMBank + push bc + ld a, [w3d400] + ld c, a + ld b, $00 + ld hl, w3d401 + add hl, bc + add hl, bc + pop bc + push hl + ld a, [hli] + ld h, [hl] + ld l, a + ld [hl], d ; x + inc hl + ld [hl], e ; y + inc hl + ld [hl], b ; width + inc hl + ld [hl], c ; height + inc hl + push hl + push bc + ld b, d ; x + ld c, e ; y + call BCCoordToBGMap0Address + pop bc + pop de +.loop + xor a ; VRAM0 + call BankswitchVRAM + push bc + push hl +.loop_copy_vram0 + di + call WaitForLCDOff + ld a, [hli] + ld [de], a + ei + inc de + dec b + jr nz, .loop_copy_vram0 + pop hl + pop bc + ld a, BANK("VRAM1") + call BankswitchVRAM + push bc + push hl +.loop_copy_vram1 + di + call WaitForLCDOff + ld a, [hli] + ld [de], a + ei + inc de + dec b + jr nz, .loop_copy_vram1 + pop hl + ld bc, BG_MAP_WIDTH + add hl, bc + pop bc + dec c + jr nz, .loop + + ld hl, w3d400 + inc [hl] + pop hl + inc hl + inc hl + ld [hl], e + inc hl + ld [hl], d + xor a + call BankswitchVRAM + pop af + call SwitchWRAMBank + pop hl + pop de + pop bc + pop af + ret + +Func_103b6: + push af + push hl + ld a, [wWRAMBank] + push af + ld a, $03 + call SwitchWRAMBank + ld hl, w3d400 + dec [hl] + ld a, [hl] + ld c, a + ld b, $00 + ld hl, w3d401 + add hl, bc + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [hli] + ld d, a + ld a, [hli] + ld e, a + ld a, [hli] + ld b, a + ld a, [hli] + ld c, a + push bc + push de + push hl + push bc + ld b, d + ld c, e + call BCCoordToBGMap0Address + pop bc + pop hl +.loop_rows + push bc + xor a + call BankswitchVRAM + push de + call SafeCopyDataHLtoDE + pop de + ld a, BANK("VRAM1") + call BankswitchVRAM + push de + call SafeCopyDataHLtoDE + pop de + push hl + ld h, d + ld l, e + ld bc, BG_MAP_WIDTH + add hl, bc + ld d, h + ld e, l + pop hl + pop bc + dec c + jr nz, .loop_rows + xor a + call BankswitchVRAM + pop de + pop bc + pop af + call SwitchWRAMBank + pop hl + pop af + ret Func_10413: ld [wd895], a @@ -337,7 +492,7 @@ Func_1059f: ld b, [hl] ld a, [wWRAMBank] push af - ld a, $03 + ld a, BANK("WRAM3") call SwitchWRAMBank ld a, b ld [de], a @@ -349,10 +504,10 @@ Func_1059f: jr nz, .loop_copy ld a, [wWRAMBank] push af - ld a, $03 + ld a, BANK("WRAM3") call SwitchWRAMBank ld bc, $415 - ld de, $d4c6 + ld de, w3d4c6 ld hl, w3d000 call CopyBCBytesFromHLToDE pop af @@ -374,7 +529,7 @@ Func_105de: .loop_copy ld a, [wWRAMBank] push af - ld a, $03 + ld a, BANK("WRAM3") call SwitchWRAMBank ld a, [de] ld b, a @@ -387,11 +542,11 @@ Func_105de: jr nz, .loop_copy ld a, [wWRAMBank] push af - ld a, $03 + ld a, BANK("WRAM3") call SwitchWRAMBank ld bc, $415 ld de, w3d000 - ld hl, $d4c6 + ld hl, w3d4c6 call CopyBCBytesFromHLToDE pop af call SwitchWRAMBank @@ -411,7 +566,7 @@ SetInitialGraphicsConfiguration: push hl xor a ld [wTileMapFill], a - bank1call SetZeroLineSeparation + bank1call SetOneLineSeparation call LoadSymbolsFont call Func_35a0 call SetZeroScroll @@ -492,7 +647,7 @@ SafeClearBGMap: xor a ld [hl], a ei - ld a, $01 + ld a, BANK("VRAM1") call BankswitchVRAM ei .wait_lcd_2 @@ -548,7 +703,7 @@ FillBoxInBGMap: ld a, [wd89d] ld [hl], a ei - ld a, $01 + ld a, BANK("VRAM1") call BankswitchVRAM di call WaitForLCDOff @@ -598,7 +753,7 @@ Func_10742: ld c, e call BCCoordToBGMap0Address pop bc - ld a, $01 + ld a, BANK("VRAM1") call BankswitchVRAM .loop push bc @@ -1054,15 +1209,150 @@ Func_10aa8: SECTION "Bank 4@4ab9", ROMX[$4ab9], BANK[$4] Func_10ab9: - res 6, [hl] ; SPRITEANIMSTRUCT_FLAGS + res SPRITEANIMSTRUCT_FLAG6_F, [hl] ; SPRITEANIMSTRUCT_FLAGS ret Func_10abc: - set 6, [hl] ; SPRITEANIMSTRUCT_FLAGS + set SPRITEANIMSTRUCT_FLAG6_F, [hl] ; SPRITEANIMSTRUCT_FLAGS ret -; 0x10abf -SECTION "Bank 4@4b71", ROMX[$4b71], BANK[$4] +Func_10abf: + push af + push bc + push de + push hl + inc d + inc e + inc e + ld a, d + add b + ld b, a ; (d + 1 + b) + ld a, e + add c + ld c, a ; (e + 2 + c) + + ld hl, wSpriteAnimationStructs + ld a, NUM_SPRITE_ANIM_STRUCTS +.loop_anims + push af + push hl + ld a, [hl] ; SPRITEANIMSTRUCT_FLAGS + and SPRITEANIMSTRUCT_ACTIVE + jr z, .next_anim + inc hl + inc hl + inc hl + ld a, [hli] ; SPRITEANIMSTRUCT_X_POS + srl a + srl a + srl a ; /8 + cp d + jr c, .next_anim + ld a, [hld] ; SPRITEANIMSTRUCT_Y_POS + srl a + srl a + srl a ; /8 + cp e + jr c, .next_anim + ld a, [hli] ; SPRITEANIMSTRUCT_X_POS + srl a + srl a + srl a ; /8 + cp b + jr nc, .next_anim + ld a, [hld] ; SPRITEANIMSTRUCT_Y_POS + srl a + srl a + srl a ; /8 + cp c + jr nc, .next_anim + dec hl + dec hl + dec hl + res SPRITEANIMSTRUCT_FLAG6_F, [hl] ; SPRITEANIMSTRUCT_FLAGS +.next_anim + pop hl + push bc + ld bc, SPRITEANIMSTRUCT_LENGTH + add hl, bc + pop bc + pop af + dec a + jr nz, .loop_anims + pop hl + pop de + pop bc + pop af + ret + +Func_10b18: + push af + push bc + push de + push hl + inc d + inc e + inc e + ld a, d + add b + ld b, a ; (d + 1 + b) + ld a, e + add c + ld c, a ; (e + 2 + c) + + ld hl, wSpriteAnimationStructs + ld a, NUM_SPRITE_ANIM_STRUCTS +.loop_sprite_anims + push af + push hl + ld a, [hl] ; SPRITEANIMSTRUCT_FLAGS + and SPRITEANIMSTRUCT_ACTIVE + jr z, .next_sprite_anim + inc hl + inc hl + inc hl + ld a, [hli] ; SPRITEANIMSTRUCT_X_POS + srl a + srl a + srl a ; /8 + cp d + jr c, .next_sprite_anim + ld a, [hld] ; SPRITEANIMSTRUCT_Y_POS + srl a + srl a + srl a ; /8 + cp e + jr c, .next_sprite_anim + ld a, [hli] ; SPRITEANIMSTRUCT_X_POS + srl a + srl a + srl a ; /8 + cp b + jr nc, .next_sprite_anim + ld a, [hld] ; SPRITEANIMSTRUCT_Y_POS + srl a + srl a + srl a ; /8 + cp c + jr nc, .next_sprite_anim + dec hl + dec hl + dec hl + set SPRITEANIMSTRUCT_FLAG6_F, [hl] ; SPRITEANIMSTRUCT_FLAGS +.next_sprite_anim + pop hl + push bc + ld bc, SPRITEANIMSTRUCT_LENGTH + add hl, bc + pop bc + pop af + dec a + jr nz, .loop_sprite_anims + pop hl + pop de + pop bc + pop af + ret Func_10b71: push af @@ -1160,7 +1450,7 @@ Func_10be7: ld b, [hl] ld a, [wWRAMBank] push af - ld a, $03 + ld a, BANK("WRAM3") call SwitchWRAMBank ld a, b ld [de], a @@ -1185,12 +1475,12 @@ Func_10c10: push de push hl ld de, wSpriteAnim4TileOffset - ld hl, wSpriteAnim1 + ld hl, wSpriteAnimationStructs ld c, $ca .asm_10c1e ld a, [wWRAMBank] push af - ld a, $03 + ld a, BANK("WRAM3") call SwitchWRAMBank ld a, [de] ld b, a @@ -1626,7 +1916,7 @@ Func_10ea7: ld b, [hl] ld a, [wWRAMBank] push af - ld a, $03 + ld a, BANK("WRAM3") call SwitchWRAMBank ld a, b ld [de], a @@ -1657,7 +1947,7 @@ Func_10ed3: .asm_10ee1 ld a, [wWRAMBank] push af - ld a, $03 + ld a, BANK("WRAM3") call SwitchWRAMBank ld a, [de] ld b, a @@ -1887,9 +2177,36 @@ IsStillOWObject: db OW_PURPLE_CASTLE_COIN db OW_STRONGHOLD_PLATFORM db $ff ; end -; 0x11002 -SECTION "Bank 4@502c", ROMX[$502c], BANK[$4] +Func_11002: + push af + push bc + push de + push hl + lb de, 0, 12 + lb bc, 20, 6 + call Func_10673 + call Func_10abf + call DoFrame + call Func_10342 + pop hl + pop de + pop bc + pop af + ret + +Func_1101d: + push af + push bc + push de + push hl + call Func_103b6 + call Func_10b18 + pop hl + pop de + pop bc + pop af + ret PrintScrollableText_NoTextBoxLabelVRAM0:: push af @@ -1995,11 +2312,159 @@ Func_110c2:: call PopFrameFunction ret +Func_110c6: + push af + push bc + push de + push hl + call Func_11002 + ldtx hl, Text05bb + call PrintScrollableText_NoTextBoxLabelVRAM0 + ld e, $01 +.asm_110d5 + call .ShowMenu + call .HandleInput + jr c, .asm_110f2 + push de + call .ExecuteSelectedOption + pop de + jr c, .asm_110f2 + call .Func_11181 + ld a, e + and a + jr z, .asm_110f0 + call Func_1101d + ld e, $00 +.asm_110f0 + jr .asm_110d5 +.asm_110f2 + call .Func_11181 + ld a, e + and a + jr nz, .asm_110fc + call Func_11002 +.asm_110fc + ldtx hl, Text05bc + call PrintScrollableText_NoTextBoxLabelVRAM0 + call Func_1101d + pop hl + pop de + pop bc + pop af + ret + +.ShowMenu: + push af + push bc + push de + push hl + lb de, 10, 0 + ld b, BANK(.menu_params) + ld hl, .menu_params + call LoadMenuBoxParams + farcall Func_1cacf + ld a, [wPCMenuCursorPosition] + farcall DrawMenuBox + pop hl + pop de + pop bc + pop af + ret + +.menu_params + db TRUE ; skip clear + db 10, 12 ; width, height + db SYM_CURSOR_R ; blink cursor symbol + db SYM_SPACE ; space symbol + db SYM_CURSOR_R ; default cursor symbol + db SYM_CURSOR_R ; selection cursor symbol + db A_BUTTON ; press keys + db B_BUTTON ; held keys + db FALSE ; has horizontal scroll + db 1 ; vertical step + dw NULL ; update function + dw NULL ; label text ID + + textitem 2, 2, Text05b7 + textitem 2, 4, Text05cc + textitem 2, 6, Text05b9 + textitem 2, 8, Text05ba + textitem 2, 10, Text05bd + db $ff + +.HandleInput: + ld a, [wPCMenuCursorPosition] + farcall HandleMenuBox + ld [wPCMenuCursorPosition], a + jr c, .asm_11161 + push af + ld a, SFX_02 + call CallPlaySFX + pop af + ret +.asm_11161 + push af + ld a, SFX_03 + call CallPlaySFX + pop af + ret + +; a = option that was selected +.ExecuteSelectedOption: + ld hl, .function_map + call CallMappedFunction + ret + +.function_map + key_func $0, .CardAlbum + db $1, BANK(@) + dw $51d7 + key_func $2, .Glossary + key_func $3, .Func_111be + db $ff ; end + +.Func_11181: + farcall Func_1caf1 + ret + +.CardAlbum: + call Func_1022a + call SetFadePalsFrameFunc + farcall CardAlbum + farcall StartFadeToWhite + farcall WaitPalFading_Bank07 + call UnsetFadePalsFrameFunc + call Func_10252 + ret + +.Glossary: + call Func_1022a + call SetFadePalsFrameFunc + call ClearSpriteAnimsAndSetInitialGraphicsConfiguration + call FlushAllPalettes + farcall Glossary + farcall StartFadeToWhite + farcall WaitPalFading_Bank07 + call UnsetFadePalsFrameFunc + call Func_10252 + ret + +.Func_111be: + call Func_1022a + call SetFadePalsFrameFunc + farcall PrinterMenu + farcall StartFadeToWhite + farcall WaitPalFading_Bank07 + call UnsetFadePalsFrameFunc + call Func_10252 + ret +; 0x111d7 + SECTION "Bank 4@51f0", ROMX[$51f0], BANK[$4] Func_111f0: ld a, $04 - ld [wd9dc], a + ld [wPCMenuCursorPosition], a ret ; 0x111f6 @@ -2302,7 +2767,7 @@ Func_11384:: .loop push bc push hl - bit 6, [hl] + bit 6, [hl] ; OWOBJSTRUCT_FLAGS jr z, .next push hl call GetOWObjectSpriteAnim @@ -2400,7 +2865,7 @@ Func_113f8: ld b, [hl] ld a, [wWRAMBank] push af - ld a, $03 + ld a, BANK("WRAM3") call SwitchWRAMBank ld a, b ld [de], a @@ -2431,7 +2896,7 @@ Func_11424: .asm_11432 ld a, [wWRAMBank] push af - ld a, $03 + ld a, BANK("WRAM3") call SwitchWRAMBank ld a, [de] ld b, a @@ -2771,7 +3236,7 @@ DoIntro: call ResetIntroOrbStates push af ld a, SFX_9A - call Func_3cfe + call CallPlaySFX pop af .loop_intro_update @@ -2981,7 +3446,7 @@ AnimateTitle: jr c, .finish push af ld a, SFX_9B - call Func_3cfe + call CallPlaySFX pop af call .Expand jr c, .finish @@ -3099,7 +3564,7 @@ AnimateSubtitleEnter: call LoadTitleScreenGraphics push af ld a, SFX_9C - call Func_3cfe + call CallPlaySFX pop af call .Distort farcall SetAllBGPaletteFadeConfigsToEnabled @@ -3630,7 +4095,7 @@ ClearBoxInBGMap: call WaitForLCDOff xor a ld [hl], a - ld a, $01 + ld a, BANK("VRAM1") call BankswitchVRAM call WaitForLCDOff xor a @@ -3993,7 +4458,7 @@ DrawLoadedCard: xor a call BankswitchVRAM call .ApplyTilemap - ld a, $01 + ld a, BANK("VRAM1") call BankswitchVRAM call .ApplyAttrmap pop hl diff --git a/src/engine/bank06.asm b/src/engine/bank06.asm index be49fc8..a72ab8a 100644 --- a/src/engine/bank06.asm +++ b/src/engine/bank06.asm @@ -1,3 +1,45 @@ +SECTION "Bank 6@46a6", ROMX[$46a6], BANK[$6] + +INCLUDE "engine/glossary.asm" + + +SECTION "Bank 6@58ca", ROMX[$58ca], BANK[$6] + +; empties screen and enables sprite animations +SetSpriteAnimationsAsVBlankFunction: + call EmptyScreen + lb de, $38, $7f + call SetupText + ld hl, wVBlankFunctionTrampoline + 1 + ld de, wVBlankFunctionTrampolineBackup + call BackupVBlankFunctionTrampoline + di + call Func_3e4f + ei + ret + +; sets backup VBlank function as wVBlankFunctionTrampoline +RestoreVBlankFunction: + call Func_3e54 + ld hl, wVBlankFunctionTrampolineBackup + ld de, wVBlankFunctionTrampoline + 1 + call BackupVBlankFunctionTrampoline + ret + +; copies 2 bytes from hl to de while interrupts are disabled +; used to load or store wVBlankFunctionTrampoline +; to wVBlankFunctionTrampolineBackup +BackupVBlankFunctionTrampoline: + di + ld a, [hli] + ld [de], a + inc de + ld a, [hld] + ld [de], a + ei + ret +; 0x198f7 + SECTION "Bank 6@58f8", ROMX[$58f8], BANK[$6] ; clears saved data (card Collection/saved decks/Card Pop! data/etc) @@ -198,7 +240,1215 @@ ClearCardPopNameList: ret ; 0x1a03b -SECTION "Bank 6@6e14", ROMX[$6e14], BANK[$6] + +SECTION "Bank 6@64b1", ROMX[$64b1], BANK[$6] + +; sends serial data to printer +; if there's an error in connection, +; show Printer Not Connected scene with error message +ConnectPrinter: + ld bc, 0 + lb de, PRINTERPKT_DATA, FALSE + call SendPrinterPacket + ret nc ; return if no error + + ld hl, wPrinterStatus + ld a, [hl] + or a + jr nz, .asm_1a4c4 + ld [hl], $ff +.asm_1a4c4 + ld a, [hl] + cp $ff + jr z, ShowPrinterIsNotConnected +; fallthrough + +; shows message on screen depending on wPrinterStatus +; also shows SCENE_GAMEBOY_PRINTER_NOT_CONNECTED. +HandlePrinterError: + ld a, [wPrinterStatus] + cp $ff + jr z, .cable_or_printer_switch + or a + jr z, .interrupted + bit PRINTER_ERROR_BATTERIES_LOST_CHARGE, a + jr nz, .batteries_lost_charge + bit PRINTER_ERROR_CABLE_PRINTER_SWITCH, a + jr nz, .cable_or_printer_switch + bit PRINTER_ERROR_PAPER_JAMMED, a + jr nz, .jammed_printer + + ldtx hl, Text00f6 ; PrinterPacketErrorText + ld a, $04 + jr ShowPrinterConnectionErrorScene +.cable_or_printer_switch + ldtx hl, Text00f5 ; CheckCableOrPrinterSwitchText + ld a, $04 + jr ShowPrinterConnectionErrorScene +.jammed_printer + ldtx hl, Text00f4 ; PrinterPaperIsJammedText + ld a, $04 + jr ShowPrinterConnectionErrorScene +.batteries_lost_charge + ldtx hl, Text00f3 ; BatteriesHaveLostTheirChargeText + ld a, $01 + jr ShowPrinterConnectionErrorScene +.interrupted + ldtx hl, Text00f7 ; PrintingWasInterruptedText + call DrawWideTextBox_WaitForInput + scf + ret + +ShowPrinterIsNotConnected: + ldtx hl, Text00f2 ; PrinterIsNotConnectedText + ld a, $02 +; fallthrough + +; a = error code +; hl = text ID to print in text box +ShowPrinterConnectionErrorScene: + push hl + ; unnecessary loading TxRam, since the text data + ; already incorporate the error number + ld l, a + ld h, $00 + call LoadTxRam3 + + call SetSpriteAnimationsAsVBlankFunction + ld a, SCENE_GAMEBOY_PRINTER_NOT_CONNECTED + lb bc, 0, 0 + call EmptyScreenAndLoadScene + pop hl + call DrawWideTextBox_WaitForInput + call RestoreVBlankFunction + scf + ret + +; main card printer function +RequestToPrintCard: + call LoadCardDataToBuffer1_FromCardID + call SetSpriteAnimationsAsVBlankFunction + ld a, SCENE_GAMEBOY_PRINTER_TRANSMITTING + lb bc, 0, 0 + call EmptyScreenAndLoadScene + ld a, 20 + call CopyCardNameAndLevel + ld [hl], TX_END + ld hl, $0 + call LoadTxRam2 + ldtx hl, Text0248 + call DrawWideTextBox_PrintText + call EnableLCD + call PrepareForPrinterCommunications + call .DrawTopCardInfoInSRAMGfxBuffer0 + call Func_19f87 + call .DrawCardPicInSRAMGfxBuffer2 + call Func_19f99 + jr c, .error + call DrawBottomCardInfoInSRAMGfxBuffer0 + call Func_1a011 + jr c, .error + call RestoreVBlankFunction + call ResetPrinterCommunicationSettings + or a + ret +.error + call RestoreVBlankFunction + call ResetPrinterCommunicationSettings + jp HandlePrinterError + +; draw card's picture in sGfxBuffer2 +.DrawCardPicInSRAMGfxBuffer2: + ld hl, wLoadedCard1Gfx + ld a, [hli] + ld h, [hl] + ld l, a + ld de, sGfxBuffer2 + call Func_1adbd + ld a, $40 + lb hl, 12, 1 + lb de, 2, 68 + lb bc, 16, 12 + call FillRectangle + ret + +; writes the tiles necessary to draw +; the card's information in sGfxBuffer0 +; this includes card's type, lv, HP and attacks if Pokemon card +; or otherwise just the card's name and type symbol +.DrawTopCardInfoInSRAMGfxBuffer0: + call Func_1a025 + call Func_212f + + ; draw empty text box frame + ld hl, sGfxBuffer0 + ld a, $34 + lb de, $30, $31 + ld b, 20 + call CopyLine + ld c, 15 +.loop_lines + xor a ; SYM_SPACE + lb de, $36, $37 + ld b, 20 + call CopyLine + dec c + jr nz, .loop_lines + + ; draw card type symbol + ld a, $38 + lb hl, 1, 2 + lb de, 1, 65 + lb bc, 2, 2 + call FillRectangle + ; print card's name + lb de, 4, 65 + ld hl, wLoadedCard1Name + call InitTextPrinting_ProcessTextFromPointerToID + +; prints card's type, lv, HP and attacks if it's a Pokemon card + ld a, [wLoadedCard1Type] + cp TYPE_ENERGY + jr nc, .skip_pokemon_data + inc a ; symbol corresponding to card's type (color) + lb bc, 18, 65 + call WriteByteToBGMap0 + ld a, SYM_Lv + lb bc, 11, 66 + call WriteByteToBGMap0 + ld a, [wLoadedCard1Level] + lb bc, 12, 66 + bank1call WriteTwoDigitNumberInTxSymbolFormat + ld a, SYM_HP + lb bc, 15, 66 + call WriteByteToBGMap0 + ld a, [wLoadedCard1HP] + inc b + bank1call WriteTwoByteNumberInTxSymbolFormat +.skip_pokemon_data + ret + +Func_19f87: + call TryInitPrinterCommunications + ret c ; aborted + ld hl, sGfxBuffer0 + call SendTilesToPrinter + ret c + call SendTilesToPrinter + call SendPrinterInstructionPacket_1Sheet + ret + +Func_19f99: + call TryInitPrinterCommunications + ret c + ld hl, sGfxBuffer0 + $8 tiles + ld c, $06 +.asm_19fa2 + call SendTilesToPrinter + ret c + dec c + jr nz, .asm_19fa2 + call SendPrinterInstructionPacket_1Sheet + ret + +; writes the tiles necessary to draw +; the card's information in sGfxBuffer0 +; this includes card's Retreat cost, Weakness, Resistance, +; and attack if it's Pokemon card +; or otherwise just the card's description. +DrawBottomCardInfoInSRAMGfxBuffer0: + call Func_1a025 + xor a + ld [wCardPageType], a + ld hl, sGfxBuffer0 + ld b, 20 + ld c, 9 +.loop_lines + xor a ; SYM_SPACE + lb de, $36, $37 + call CopyLine + dec c + jr nz, .loop_lines + ld a, $35 + lb de, $32, $33 + call CopyLine + + ld a, [wLoadedCard1Type] + cp TYPE_ENERGY + jr nc, .not_pkmn_card + ld hl, RetreatWeakResistData + call PlaceTextItems + ld c, 66 + bank1call DisplayCardPage_PokemonOverview.attacks + + ld a, SYM_No + lb bc, 15, 72 + call WriteByteToBGMap0 + inc b + ld a, [wLoadedCard1PokedexNumber] + bank1call WriteTwoByteNumberInTxSymbolFormat + ret + +.not_pkmn_card + bank1call SetNoLineSeparation + lb de, 1, 66 + ld a, SYM_No + call InitTextPrintingInTextbox + ld hl, wLoadedCard1NonPokemonDescription + call ProcessTextFromPointerToID + bank1call SetOneLineSeparation + ret + +RetreatWeakResistData: + textitem 1, 70, Text0007 + textitem 1, 71, Text0008 + textitem 1, 72, Text0009 + db $ff + +Func_1a011: + call TryInitPrinterCommunications + ret c + ld hl, sGfxBuffer0 + ld c, $05 +.asm_1a01a + call SendTilesToPrinter + ret c + dec c + jr nz, .asm_1a01a + call SendPrinterInstructionPacket_1Sheet_3LineFeeds + ret + +; calls setup text and sets wTilePatternSelector +Func_1a025: + lb de, $40, $bf + call SetupText + ld a, $a4 + ld [wTilePatternSelector], a + xor a + ld [wTilePatternSelectorCorrection], a + ret + +; switches to CGB normal speed, resets serial +; enables SRAM and switches to SRAM1 +; and clears sGfxBuffer0 +PrepareForPrinterCommunications: + call SwitchToCGBNormalSpeed + call ResetSerial + ld a, $10 + ld [wPrinterNumberLineFeeds], a + call EnableSRAM + ld a, [sPrinterContrastLevel] + ld [wPrinterContrastLevel], a + ldh a, [hBankSRAM] + ld [wTempPrinterSRAM], a + ld a, BANK("SRAM3") + call BankswitchSRAM + call EnableSRAM +; fallthrough + +ClearPrinterGfxBuffer: + ld hl, sGfxBuffer0 + ld bc, $400 +.loop + xor a + ld [hli], a + dec bc + ld a, c + or b + jr nz, .loop + xor a + ld [wce9f], a + ret + +; reverts settings changed by PrepareForPrinterCommunications +ResetPrinterCommunicationSettings: + push af + call SwitchToCGBDoubleSpeed + ld a, [wTempPrinterSRAM] + call BankswitchSRAM + call DisableSRAM + lb de, $30, $bf + call SetupText + pop af + ret + + ; send some bytes through serial +Func_1a080: ; unreferenced + ld bc, 0 + lb de, PRINTERPKT_NUL, FALSE + jp SendPrinterPacket + +; tries initiating the communications for +; sending data to printer +; returns carry if operation was cancelled +; by pressing B button or serial transfer took long +TryInitPrinterCommunications: + xor a + ld [wPrinterInitAttempts], a +.wait_input + call DoFrame + ldh a, [hKeysHeld] + and B_BUTTON + jr nz, .b_button + ld bc, 0 + lb de, PRINTERPKT_NUL, FALSE + call SendPrinterPacket + jr c, .delay + and (1 << PRINTER_STATUS_BUSY) | (1 << PRINTER_STATUS_PRINTING) + jr nz, .wait_input + +.init + ld bc, 0 + lb de, PRINTERPKT_INIT, FALSE + call SendPrinterPacket + jr nc, .no_carry + ld hl, wPrinterInitAttempts + inc [hl] + ld a, [hl] + cp 3 + jr c, .wait_input + ; time out + scf + ret +.no_carry + ret + +.b_button + xor a + ld [wPrinterStatus], a + scf + ret + +.delay + ld c, 10 +.delay_loop + call DoFrame + dec c + jr nz, .delay_loop + jr .init + +; loads tiles given by map in hl to sGfxBuffer5 +; copies first 20 tiles, then offsets by 2 tiles +; and copies another 20 +; compresses this data and sends it to printer +SendTilesToPrinter: + push bc + ld de, sGfxBuffer5 + call .Copy20Tiles + call .Copy20Tiles + push hl + call CompressDataForPrinterSerialTransfer + call SendPrinterPacket + pop hl + pop bc + ret + +; copies 20 tiles given by hl to de +; then adds 2 tiles to hl +.Copy20Tiles + push hl + ld c, 20 +.loop_tiles + ld a, [hli] + call .CopyTile + dec c + jr nz, .loop_tiles + pop hl + ld bc, 2 tiles + add hl, bc + ret + +; copies a tile to de +; a = tile to get from sGfxBuffer1 +.CopyTile + push hl + push bc + ld l, a + ld h, $00 + add hl, hl + add hl, hl + add hl, hl + add hl, hl ; *TILE_SIZE + ld bc, sGfxBuffer1 + add hl, bc + ld c, TILE_SIZE +.loop_copy + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .loop_copy + pop bc + pop hl + ret + +SendPrinterInstructionPacket_1Sheet_3LineFeeds: + call GetPrinterContrastSerialData + push hl + lb hl, 3, 1 + jr SendPrinterInstructionPacket + +; uses wPrinterNumberLineFeeds to get number +; of line feeds to insert before print +SendPrinterInstructionPacket_1Sheet: + call GetPrinterContrastSerialData + push hl + ld hl, wPrinterNumberLineFeeds + ld a, [hl] + ld [hl], $00 + ld h, a + ld l, 1 +; fallthrough + +; h = number of line feeds where: +; high nybble is number of line feeds before printing +; low nybble is number of line feeds after printing +; l = number of sheets +; expects printer contrast information to be on stack +SendPrinterInstructionPacket: + push hl + ld bc, 0 + lb de, PRINTERPKT_DATA, FALSE + call SendPrinterPacket + jr c, .aborted + ld hl, sp+$00 ; contrast level bytes + ld bc, 4 ; instruction packets are 4 bytes in size + lb de, PRINTERPKT_PRINT_INSTRUCTION, FALSE + call SendPrinterPacket +.aborted + pop hl + pop hl + ret + + ; returns in h and l the bytes +; to be sent through serial to the printer +; for the set contrast level +GetPrinterContrastSerialData: + ld a, [wPrinterContrastLevel] + ld e, a + ld d, $00 + ld hl, .contrast_level_data + add hl, de + ld h, [hl] + ld l, %11100100 ; palette format + ret + +.contrast_level_data + db $00, $20, $40, $60, $7f + +Func_1a14b: ; unreferenced + ld a, $01 + jr .asm_1a15d + ld a, $02 + jr .asm_1a15d + ld a, $03 + jr .asm_1a15d + ld a, $04 + jr .asm_1a15d + ld a, $05 +.asm_1a15d + ld [wce9d], a + scf + ret + +; a = saved deck index to print +PrintDeckConfiguration: +; copies selected deck from SRAM to wDuelTempList + call EnableSRAM + ld l, a + ld h, DECK_COMPRESSED_STRUCT_SIZE + call HtimesL + ld de, sSavedDeck1 + add hl, de + ld de, wDuelTempList + ld bc, DECK_COMPRESSED_STRUCT_SIZE + call CopyDataHLtoDE + call DisableSRAM + + call ShowPrinterTransmitting + call PrepareForPrinterCommunications + call Func_1a025 + call Func_212f + lb de, 0, 64 + lb bc, 20, 4 + call DrawRegularTextBoxDMG + lb de, 4, 66 + call InitTextPrinting + ld hl, wDuelTempList ; print deck name + call ProcessText + ldtx hl, Text0022 ; DeckPrinterText + call ProcessTextFromID + + ld a, 5 + ld [wPrinterHorizontalOffset], a + ld hl, wPrinterTotalCardCount + xor a + ld [hli], a + ld [hl], a + ld [wPrintOnlyStarRarity], a + + ld hl, wCurDeckCards +.loop_cards + ld a, [hli] + ld e, a + ld d, [hl] + inc hl + or d + jr z, .asm_1a1d6 + call LoadCardDataToBuffer1_FromCardID + + ; find out this card's count + ld c, 1 +.loop_card_count + ld a, e + cp [hl] + jr nz, .got_card_count + inc hl + ld a, d + cp [hl] + jr nz, .got_card_count + inc hl + inc c + jr .loop_card_count + +.got_card_count + ld a, c + ld [wPrinterCardCount], a + call LoadCardInfoForPrinter + call AddToPrinterGfxBuffer + jr c, .printer_error + jr .loop_cards + +.asm_1a1d6 + call SendCardListToPrinter + jr c, .printer_error + call ResetPrinterCommunicationSettings + call RestoreVBlankFunction + or a + ret + +.printer_error + call ResetPrinterCommunicationSettings + call RestoreVBlankFunction + jp HandlePrinterError + +SendCardListToPrinter: + ld a, [wPrinterHorizontalOffset] + cp 1 + jr z, .skip_load_gfx + call LoadGfxBufferForPrinter + ret c +.skip_load_gfx + call TryInitPrinterCommunications + ret c + call SendPrinterInstructionPacket_1Sheet_3LineFeeds + ret + +; increases printer horizontal offset by 2 +AddToPrinterGfxBuffer: + push hl + ld hl, wPrinterHorizontalOffset + inc [hl] + inc [hl] + ld a, [hl] + pop hl + ; return no carry if below 18 + cp 18 + ccf + ret nc + ; >= 18 +; fallthrough + +; copies Gfx to Gfx buffer and sends some serial data +; returns carry set if unsuccessful +LoadGfxBufferForPrinter: + push hl + call TryInitPrinterCommunications + jr c, .set_carry + ld a, [wPrinterHorizontalOffset] + srl a + ld c, a + ld hl, sGfxBuffer0 +.loop_gfx_buffer + call SendTilesToPrinter + jr c, .set_carry + dec c + jr nz, .loop_gfx_buffer + call SendPrinterInstructionPacket_1Sheet + jr c, .set_carry + + call ClearPrinterGfxBuffer + ld a, 1 + ld [wPrinterHorizontalOffset], a + pop hl + or a + ret + +.set_carry + pop hl + scf + ret + +; load symbol, name, level and card count to buffer +LoadCardInfoForPrinter: + push hl + ld a, [wPrinterHorizontalOffset] + or %1000000 + ld e, a + ld d, 3 + ld a, [wPrintOnlyStarRarity] + or a + jr nz, .skip_card_symbol + ld hl, wPrinterTotalCardCount + ld a, [hli] + or [hl] + call z, DrawCardSymbol +.skip_card_symbol + ld a, 14 + call CopyCardNameAndLevel + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + ld a, [wPrinterHorizontalOffset] + or %1000000 + ld c, a + ld b, 16 + ld a, SYM_CROSS + call WriteByteToBGMap0 + inc b + ld a, [wPrinterCardCount] + bank1call WriteTwoDigitNumberInTxSymbolFormat + pop hl + ret + +PrintCardList: +; if Select button is held when printing card list +; only print cards with Star rarity (excluding Promotional cards) +; even if it's not marked as seen in the collection + ld e, FALSE + ldh a, [hKeysHeld] + and SELECT + jr z, .no_select + inc e ; TRUE +.no_select + ld a, e + ld [wPrintOnlyStarRarity], a + + call ShowPrinterTransmitting + bank1call CreateTempCardCollection + ld de, wDefaultText + call CopyPlayerName + call PrepareForPrinterCommunications + call Func_1a025 + call Func_212f + + lb de, 0, 64 + lb bc, 20, 4 + call DrawRegularTextBoxDMG + ld a, PLAYER_TURN + ldh [hWhoseTurn], a + lb de, 2, 66 + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + ldtx hl, Text0016 ; AllCardsOwnedText + call ProcessTextFromID + ld a, [wPrintOnlyStarRarity] + or a + jr z, .asm_1a2c2 + lb de, 4, 85 + call Func_22ca +.asm_1a2c2 + ld a, $ff + ld [wCurPrinterCardType], a + xor a + ld hl, wPrinterTotalCardCount + ld [hli], a + ld [hl], a + ld hl, wPrinterNumCardTypes + ld [hli], a + ld [hl], a + ld a, 5 + ld [wPrinterHorizontalOffset], a + + ld de, GRASS_ENERGY +.loop_cards + push de + call LoadCardDataToBuffer1_FromCardID + jr c, .done_card_loop + ld hl, wTempCardCollection + add hl, de + ld a, [hl] ; card ID count in collection + ld [wPrinterCardCount], a + call .LoadCardTypeEntry + jr c, .printer_error_pop_de + + ld a, [wPrintOnlyStarRarity] + or a + jr z, .all_owned_cards_mode + ld a, [wLoadedCard1Set] + and %11110000 + cp $40 ; PROMOTIONAL + jr z, .next_card + ld a, [wLoadedCard1Rarity] + cp STAR + jr nz, .next_card + ; not Promotional, and Star rarity + ld hl, wPrinterCardCount + res CARD_NOT_OWNED_F, [hl] + jr .got_card_count + +.all_owned_cards_mode + ld a, [wPrinterCardCount] + or a + jr z, .next_card + cp CARD_NOT_OWNED + jr z, .next_card ; ignore not owned cards + +.got_card_count + ld a, [wPrinterCardCount] + and CARD_COUNT_MASK + ld c, a + + ; add to total card count + ld hl, wPrinterTotalCardCount + add [hl] + ld [hli], a + ld a, 0 + adc [hl] + ld [hl], a + + ; add to current card type count + ld hl, wPrinterCurCardTypeCount + ld a, c + add [hl] + ld [hli], a + ld a, 0 + adc [hl] + ld [hl], a + + ld hl, wPrinterNumCardTypes + inc [hl] + jr nz, .asm_1a99d + inc hl + inc [hl] +.asm_1a99d + ld hl, wce98 + inc [hl] + call LoadCardInfoForPrinter + call AddToPrinterGfxBuffer + jr c, .printer_error_pop_de +.next_card + pop de + inc de + jr .loop_cards + +.printer_error_pop_de + pop de +.printer_error + call ResetPrinterCommunicationSettings + call RestoreVBlankFunction + jp HandlePrinterError + +.done_card_loop + pop de + ; add separator line + ld a, [wPrinterHorizontalOffset] + dec a + or $40 + ld c, a + ld b, 0 + call BCCoordToBGMap0Address + ld a, $35 + lb de, $35, $35 + ld b, 20 + call CopyLine + call AddToPrinterGfxBuffer + jr c, .printer_error + + ld hl, wPrinterTotalCardCount + ld c, [hl] + inc hl + ld b, [hl] + ldtx hl, Text0017 ; TotalNumberOfCardsText + call .PrintTextWithNumber + jr c, .printer_error + ld a, [wPrintOnlyStarRarity] + or a + jr nz, .done + ld hl, wPrinterNumCardTypes + ld c, [hl] + inc hl + ld b, [hl] + ldtx hl, Text0018 ; TypesOfCardsText + call .PrintTextWithNumber + jr c, .printer_error + +.done + call SendCardListToPrinter + jr c, .printer_error + call ResetPrinterCommunicationSettings + call RestoreVBlankFunction + or a + ret + +; prints text ID given in hl +; with decimal representation of +; the number given in bc +; hl = text ID +; bc = number +.PrintTextWithNumber + push bc + ld a, [wPrinterHorizontalOffset] + dec a + or $40 + ld e, a + ld d, 2 + call InitTextPrinting + call ProcessTextFromID + ld d, 14 + call InitTextPrinting + pop hl + call TwoByteNumberToTxSymbol_TrimLeadingZeros + ld hl, wStringBuffer + call ProcessText + call AddToPrinterGfxBuffer + ret + +; loads this card's type icon and text +; if it's a new card type that hasn't been printed yet +.LoadCardTypeEntry + ld a, [wLoadedCard1Type] + ld c, a + cp TYPE_ENERGY + jr c, .got_type ; jump if Pokemon card + ld c, $08 + cp TYPE_TRAINER + jr nc, .got_type ; jump if Trainer card + ld c, $07 +.got_type + ld hl, wCurPrinterCardType + ld a, [hl] + cp c + ret z ; already handled this card type + + ; show corresponding icon and text + ; for this new card type + ld a, c + ld [hl], a ; set it as current card type + add a + add c ; *3 + ld c, a + ld b, $00 + ld hl, .IconTextList + add hl, bc + ld a, [wPrinterHorizontalOffset] + dec a + or %1000000 + ld e, a + ld d, 1 + ld a, [hli] + push hl + lb bc, 2, 2 + lb hl, 1, 2 + call FillRectangle + pop hl + ld d, 3 + inc e + call InitTextPrinting + ld a, [hli] + ld h, [hl] + ld l, a + call ProcessTextFromID + + call AddToPrinterGfxBuffer + ld hl, wPrinterCurCardTypeCount + xor a + ld [hli], a + ld [hl], a + ld [wce98], a + ret + +.IconTextList + ; Fire + db $e0 ; icon tile + tx Text001a ; FirePokemonText + + ; Grass + db $e4 ; icon tile + tx Text0019 ; GrassPokemonText + + ; Lightning + db $e8 ; icon tile + tx Text001c ; LightningPokemonText + + ; Water + db $ec ; icon tile + tx Text001b ; WaterPokemonText + + ; Fighting + db $f0 ; icon tile + tx Text001d ;FightingPokemonText + + ; Psychic + db $f4 ; icon tile + tx Text001e ; PsychicPokemonText + + ; Colorless + db $f8 ; icon tile + tx Text001f ; ColorlessPokemonText + + ; Energy + db $fc ; icon tile + tx Text0021 ; EnergyCardText + + ; Trainer + db $dc ; icon tile + tx Text0020 ; TrainerCardText + +ShowPrinterTransmitting: + call SetSpriteAnimationsAsVBlankFunction + ld a, SCENE_GAMEBOY_PRINTER_TRANSMITTING + lb bc, 0, 0 + call EmptyScreenAndLoadScene + ldtx hl, Text023b ; NowPrintingPleaseWaitText + call DrawWideTextBox_PrintText + call EnableLCD + ret + +; compresses $28 tiles in sGfxBuffer5 +; and writes it in sGfxBuffer5 + $28 tiles. +; compressed data has 2 commands to instruct on how to decompress it. +; - a command byte with bit 7 not set, means to copy that many + 1 +; bytes that are following it literally. +; - a command byte with bit 7 set, means to copy the following byte +; that many times + 2 (after masking the top bit of command byte). +; returns in bc the size of the compressed data and +; in de the packet type data. +CompressDataForPrinterSerialTransfer: + ld hl, sGfxBuffer5 + ld de, sGfxBuffer5 + $28 tiles + ld bc, $28 tiles +.loop_remaining_data + ld a, $ff + inc b + dec b + jr nz, .check_compression + ld a, c +.check_compression + push bc + push de + ld c, a + call CheckDataCompression + ld a, e + ld c, e + pop de + jr c, .copy_byte + ld a, c + ld b, c + dec a + ld [de], a ; number of bytes to copy literally - 1 + inc de +.copy_literal_sequence + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .copy_literal_sequence + ld c, b + jr .sub_added_bytes + +.copy_byte + ld a, c + dec a + dec a + or %10000000 ; set high bit + ld [de], a ; = (n times to copy - 2) | %10000000 + inc de + ld a, [hl] ; byte to copy n times + ld [de], a + inc de + ld b, $0 + add hl, bc + +.sub_added_bytes + ld a, c + cpl + inc a + pop bc + add c + ld c, a + ld a, $ff + adc b + ld b, a + or c + jr nz, .loop_remaining_data + + ld hl, $10000 - (sGfxBuffer5 + $28 tiles) + add hl, de ; gets the size of the compressed data + ld c, l + ld b, h + ld hl, sGfxBuffer5 + $28 tiles + lb de, PRINTERPKT_DATA, TRUE + ret + +; checks whether the next byte sequence in hl, up to c bytes, can be compressed +; returns carry if the next sequence of bytes can be compressed, +; i.e. has at least 3 consecutive bytes with the same value. +; in that case, returns in e the number of consecutive +; same value bytes that were found. +; if there are no bytes with same value, then count as many bytes left +; as possible until either there are no more remaining data bytes, +; or until a sequence of 3 bytes with the same value are found. +; in that case, the number of bytes in this sequence is returned in e. +CheckDataCompression: + push hl + ld e, c + ld a, c +; if number of remaining bytes is less than 4 +; then no point in compressing + cp 4 + jr c, .no_carry + +; check first if there are at least +; 3 consecutive bytes with the same value + ld b, c + ld a, [hli] + cp [hl] + inc hl + jr nz, .literal_copy ; not same + cp [hl] + inc hl + jr nz, .literal_copy ; not same + +; 3 consecutive bytes were found with same value +; keep track of how many consecutive bytes +; with the same value there are in e + dec c + dec c + dec c + ld e, 3 +.loop_same_value + cp [hl] + jr nz, .set_carry ; exit when a different byte is found + inc hl + inc e + dec c + jr z, .set_carry ; exit when there is no more remaining data + bit 5, e + ; exit if number of consecutive bytes >= $20 + jr z, .loop_same_value +.set_carry + pop hl + scf + ret + +.literal_copy +; consecutive bytes are not the same value +; count the number of bytes there are left +; until a sequence of 3 bytes with the same value is found + pop hl + push hl + ld c, b ; number of remaining bytes + ld e, 1 + ld a, [hli] + dec c + jr z, .no_carry ; exit if no more data +.reset_same_value_count + ld d, 2 ; number of consecutive same value bytes to exit +.next_byte + inc e + dec c + jr z, .no_carry + bit 7, e + jr nz, .no_carry ; exit if >= $80 + cp [hl] + jr z, .same_consecutive_value + ld a, [hli] + jr .reset_same_value_count +.no_carry + pop hl + or a + ret + +.same_consecutive_value + inc hl + dec d + jr nz, .next_byte + ; 3 consecutive bytes with same value found + ; discard the last 3 bytes in the sequence + dec e + dec e + dec e + jr .no_carry +; 0x1ab3e + +SECTION "Bank 6@6dbd", ROMX[$6dbd], BANK[$6] + +Func_1adbd: + push de + ld de, wc000 + lb bc, $30, TILE_SIZE + call Func_2dc4 + pop de + ld hl, wc000 + ld c, $08 +.asm_1adcd + ld b, $06 +.asm_1adcf + push bc + ld c, $08 +.asm_1add2 + ld b, $02 +.asm_1add4 + push bc + push hl + ld c, [hl] + ld b, $04 +.asm_1add9 + rr c + rra + sra a + dec b + jr nz, .asm_1add9 + ld hl, $c0 + add hl, de + ld [hli], a + inc hl + ld [hl], a + ld b, $04 +.asm_1adea + rr c + rra + sra a + dec b + jr nz, .asm_1adea + ld [de], a + ld hl, $2 + add hl, de + ld [hl], a + pop hl + pop bc + inc de + inc hl + dec b + jr nz, .asm_1add4 + inc de + inc de + dec c + jr nz, .asm_1add2 + pop bc + dec b + jr nz, .asm_1adcf + ld a, $c0 + add e + ld e, a + ld a, $00 + adc d + ld d, a + dec c + jr nz, .asm_1adcd + ret LoadHandCardsIcon: ld hl, HandCardsGfx @@ -220,15 +1470,15 @@ SECTION "Bank 6@6e92", ROMX[$6e92], BANK[$6] ; play different sfx by a. ; if a is 0xff play SFX_03 (usually following a B press), ; else play SFX_02 (usually following an A press). -PlayAcceptOrDeclineSFX: +PlayAcceptOrDeclineSFX_Bank06: push af inc a - jr z, .asm_1ae9a + jr z, .sfx_decline ld a, SFX_02 - jr .asm_1ae9c -.asm_1ae9a + jr .sfx_accept +.sfx_decline ld a, SFX_03 -.asm_1ae9c +.sfx_accept call PlaySFX pop af ret @@ -268,9 +1518,9 @@ InputPlayerName: ld a, 7 ld [wNamingScreenNumRows], a ld a, SYM_CURSOR_R - ld [wVisibleCursorTile], a + ld [wMenuVisibleCursorTile], a ld a, SYM_SPACE - ld [wInvisibleCursorTile], a + ld [wMenuInvisibleCursorTile], a .loop ld a, $01 ld [wVBlankOAMCopyToggle], a @@ -282,7 +1532,7 @@ InputPlayerName: and START jr z, .check_select ld a, $01 - call PlayAcceptOrDeclineSFX + call PlayAcceptOrDeclineSFX_Bank06 call HideCursorAtCharPosition ld a, 6 ld [wNamingScreenCursorY], a @@ -296,7 +1546,7 @@ InputPlayerName: and SELECT jr z, .asm_1af3b ld a, $01 - call PlayAcceptOrDeclineSFX + call PlayAcceptOrDeclineSFX_Bank06 ld a, [wNamingScreenMode] inc a cp NUM_NAME_MODES @@ -370,7 +1620,7 @@ InitializeInputName: ; clear the name buffer ld a, NAMING_SCREEN_BUFFER_LENGTH ld hl, wNamingScreenBuffer - farcall ClearBytesInHL + farcall ClearNBytesFromHL ld a, [de] cp $06 @@ -528,7 +1778,7 @@ ENDR HandleNamingScreenInput: .start xor a - ld [wNamingScreenInputSFX], a + ld [wMenuInputSFX], a ldh a, [hDPadHeld] or a jp z, .check_btns @@ -686,7 +1936,7 @@ HandleNamingScreenInput: cp d jp z, .start ld a, SFX_01 - ld [wNamingScreenInputSFX], a + ld [wMenuInputSFX], a .check_btns ldh a, [hKeysPressed] @@ -696,7 +1946,7 @@ HandleNamingScreenInput: jr nz, .asm_1b174 ld a, $ff .asm_1b174 - call PlayAcceptOrDeclineSFX + call PlayAcceptOrDeclineSFX_Bank06 push af call ShowCursorAtCharPosition pop af @@ -704,7 +1954,7 @@ HandleNamingScreenInput: ret .no_pressed_btns - ld a, [wNamingScreenInputSFX] + ld a, [wMenuInputSFX] or a jr z, .skip_sfx call PlaySFX @@ -714,13 +1964,13 @@ HandleNamingScreenInput: inc [hl] and $0f ret nz - ld a, [wVisibleCursorTile] + ld a, [wMenuVisibleCursorTile] bit 4, [hl] jr z, DrawSymbolAtCharPosition ; fallthrough HideCursorAtCharPosition: - ld a, [wInvisibleCursorTile] + ld a, [wMenuInvisibleCursorTile] ; fallthrough DrawSymbolAtCharPosition: @@ -746,7 +1996,7 @@ DrawSymbolAtCharPosition: ret ShowCursorAtCharPosition: - ld a, [wVisibleCursorTile] + ld a, [wMenuVisibleCursorTile] jr DrawSymbolAtCharPosition ; a = tile of cursor @@ -759,7 +2009,7 @@ UpdateNameTextCursor: call ZeroObjectPositions pop af ld b, a - ld a, [wInvisibleCursorTile] + ld a, [wMenuInvisibleCursorTile] cp b jr z, .done ; cursor is invisible, done ld a, [wd3ef] diff --git a/src/engine/bank07.asm b/src/engine/bank07.asm index 22ebdc6..e928689 100644 --- a/src/engine/bank07.asm +++ b/src/engine/bank07.asm @@ -1195,7 +1195,38 @@ SetAllOBPaletteFadeConfigsToEnabled: ret ; 0x1cac3 -SECTION "Bank 7@4b00", ROMX[$4b00], BANK[$7] +SECTION "Bank 7@4acf", ROMX[$4acf], BANK[$7] + +Func_1cacf: + push af + push bc + push de + ld a, [wMenuBoxX] + ld d, a + ld a, [wMenuBoxY] + ld e, a + ld a, [wMenuBoxWidth] + ld b, a + ld a, [wMenuBoxHeight] + ld c, a + farcall Func_10abf + call DoFrame + farcall Func_10342 + pop de + pop bc + pop af + ret + +Func_1caf1: + push af + push bc + push de + farcall Func_103b6 + farcall Func_10b18 + pop de + pop bc + pop af + ret ; a = default cursor position DrawMenuBox: @@ -1283,6 +1314,11 @@ DrawMenuBox: pop af ret +; handles player input inside a menu box +; that was initialized with LoadMenuBoxParams +; returns carry if a selection was made +; input: +; a = default cursor position HandleMenuBox: push bc push de @@ -1350,12 +1386,12 @@ HandleMenuBox: ld b, a ld a, c sub b - jr nc, .asm_1cbf6 + jr nc, .no_overflow_1 add h ; warp around -.asm_1cbf6 +.no_overflow_1 push af ld a, SFX_01 - call Func_3cfe + call CallPlaySFX pop af call .UnfocusItem ld c, a @@ -1374,12 +1410,12 @@ HandleMenuBox: ld a, c add b cp h - jr c, .asm_1cc17 + jr c, .no_overflow_2 sub h ; warp around -.asm_1cc17 +.no_overflow_2 push af ld a, SFX_01 - call Func_3cfe + call CallPlaySFX pop af call .UnfocusItem ld c, a @@ -1395,12 +1431,12 @@ HandleMenuBox: ld b, a ld a, c sub b - jr nc, .asm_1cc33 + jr nc, .no_overflow_3 add h -.asm_1cc33 +.no_overflow_3 push af ld a, SFX_01 - call Func_3cfe + call CallPlaySFX pop af call .UnfocusItem ld c, a @@ -1417,12 +1453,12 @@ HandleMenuBox: ld a, c add b cp h - jr c, .asm_1cc50 + jr c, .no_overflow_4 sub h -.asm_1cc50 +.no_overflow_4 push af ld a, SFX_01 - call Func_3cfe + call CallPlaySFX pop af call .UnfocusItem ld c, a @@ -1901,13 +1937,13 @@ HandleStartMenuBox: jr c, .selected push af ld a, SFX_02 - call Func_3cfe + call CallPlaySFX pop af ret .selected push af ld a, SFX_03 - call Func_3cfe + call CallPlaySFX pop af ret @@ -2242,7 +2278,7 @@ Func_1dcb7: SECTION "Bank 7@5fb9", ROMX[$5fb9], BANK[$7] -Func_1dfb9: +Func_1dfb9:: push af push bc push de diff --git a/src/engine/bank09.asm b/src/engine/bank09.asm index dd7a64a..8823dad 100644 --- a/src/engine/bank09.asm +++ b/src/engine/bank09.asm @@ -62,6 +62,35 @@ ClearSavedDuel: ret ; 0x240e6 +SECTION "Bank 9@425e", ROMX[$425e], BANK[$9] + +DrawDuelHorizontalSeparator: + ld hl, .LineSeparatorTileData + call WriteDataBlocksToBGMap0 + ld a, [wConsole] + cp CONSOLE_CGB + ret nz + call BankswitchVRAM1 + ld hl, .LineSeparatorAttributeData + call WriteDataBlocksToBGMap0 + call BankswitchVRAM0 + ret + +.LineSeparatorTileData: + db 0, 4, $34, $34, $34, $34, $34, $34, $34, $34, $34, $31, $32, 0 + db 9, 5, $33, $33, 0 + db 9, 6, $33, $33, 0 + db 9, 7, $32, $31, $34, $34, $34, $34, $34, $34, $34, $34, $34, 0 + db $ff ; end + +.LineSeparatorAttributeData: + db 0, 4, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, 0 + db 9, 5, $01, $21, 0 + db 9, 6, $01, $21, 0 + db 9, 7, $61, $61, $01, $01, $01, $01, $01, $01, $01, $01, $01, 0 + db $ff ; end +; 0x242c5 + SECTION "Bank 9@5934", ROMX[$5934], BANK[$9] ; a = deck ID @@ -97,7 +126,7 @@ LoadDeckIDData: ld a, [hli] ld [wcc15], a ld a, [hli] - ld [wcc10], a + ld [wSpecialRule], a ld a, [hli] ld [wcd0e], a ld a, [hli] @@ -115,7 +144,7 @@ DeckIDData: tx Text04d5 ; opponent name db $05 ; ? db $02 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $12 ; ? @@ -126,7 +155,7 @@ DeckIDData: tx Text04f6 ; opponent name db $00 ; ? db $00 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $00 ; ? db $00 ; ? @@ -137,7 +166,7 @@ DeckIDData: tx Text04f6 ; opponent name db $00 ; ? db $00 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $00 ; ? db $00 ; ? @@ -148,7 +177,7 @@ DeckIDData: tx Text04f6 ; opponent name db $00 ; ? db $00 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $00 ; ? db $00 ; ? @@ -159,7 +188,7 @@ DeckIDData: tx Text04f6 ; opponent name db $00 ; ? db $00 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $00 ; ? db $00 ; ? @@ -170,7 +199,7 @@ DeckIDData: tx Text04f6 ; opponent name db $00 ; ? db $00 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $00 ; ? db $00 ; ? @@ -181,7 +210,7 @@ DeckIDData: tx Text04f6 ; opponent name db $00 ; ? db $00 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $00 ; ? db $00 ; ? @@ -192,7 +221,7 @@ DeckIDData: tx Text04d5 ; opponent name db $05 ; ? db $02 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $12 ; ? @@ -203,7 +232,7 @@ DeckIDData: tx Text04f6 ; opponent name db $00 ; ? db $00 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $00 ; ? db $00 ; ? @@ -214,7 +243,7 @@ DeckIDData: tx Text0432 ; opponent name db $06 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $12 ; ? @@ -225,7 +254,7 @@ DeckIDData: tx Text04f6 ; opponent name db $00 ; ? db $00 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $00 ; ? db $00 ; ? @@ -236,7 +265,7 @@ DeckIDData: tx Text0432 ; opponent name db $06 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $12 ; ? @@ -247,7 +276,7 @@ DeckIDData: tx Text04f6 ; opponent name db $00 ; ? db $00 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $00 ; ? db $00 ; ? @@ -258,7 +287,7 @@ DeckIDData: tx Text0432 ; opponent name db $06 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $12 ; ? @@ -269,7 +298,7 @@ DeckIDData: tx Text0432 ; opponent name db $06 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $12 ; ? @@ -280,7 +309,7 @@ DeckIDData: tx Text0432 ; opponent name db $06 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $12 ; ? @@ -291,7 +320,7 @@ DeckIDData: tx Text04a3 ; opponent name db $0a ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $03 ; ? db $09 ; ? @@ -302,7 +331,7 @@ DeckIDData: tx Text04a3 ; opponent name db $0a ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $03 ; ? db $09 ; ? @@ -313,7 +342,7 @@ DeckIDData: tx Text04a0 ; opponent name db $0c ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $01 ; ? @@ -324,7 +353,7 @@ DeckIDData: tx Text04a0 ; opponent name db $0c ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $01 ; ? @@ -335,7 +364,7 @@ DeckIDData: tx Text04e4 ; opponent name db $0b ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $01 ; ? @@ -346,7 +375,7 @@ DeckIDData: tx Text04aa ; opponent name db $0d ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $01 ; ? @@ -357,7 +386,7 @@ DeckIDData: tx Text04d4 ; opponent name db $0e ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $03 ; ? db $0a ; ? @@ -368,7 +397,7 @@ DeckIDData: tx Text04d4 ; opponent name db $0e ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $03 ; ? db $0a ; ? @@ -379,7 +408,7 @@ DeckIDData: tx Text04ec ; opponent name db $0f ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $02 ; ? @@ -390,7 +419,7 @@ DeckIDData: tx Text04bd ; opponent name db $11 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $02 ; ? @@ -401,7 +430,7 @@ DeckIDData: tx Text0491 ; opponent name db $10 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $02 ; ? @@ -412,7 +441,7 @@ DeckIDData: tx Text0493 ; opponent name db $12 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $03 ; ? db $0b ; ? @@ -423,7 +452,7 @@ DeckIDData: tx Text04de ; opponent name db $13 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $03 ; ? @@ -434,7 +463,7 @@ DeckIDData: tx Text04b8 ; opponent name db $14 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $03 ; ? @@ -445,7 +474,7 @@ DeckIDData: tx Text049c ; opponent name db $15 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $03 ; ? @@ -456,7 +485,7 @@ DeckIDData: tx Text04e0 ; opponent name db $16 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $03 ; ? db $0c ; ? @@ -467,7 +496,7 @@ DeckIDData: tx Text04ce ; opponent name db $17 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $04 ; ? @@ -478,7 +507,7 @@ DeckIDData: tx Text04ce ; opponent name db $17 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $04 ; ? @@ -489,7 +518,7 @@ DeckIDData: tx Text04a5 ; opponent name db $18 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $04 ; ? @@ -500,7 +529,7 @@ DeckIDData: tx Text04b5 ; opponent name db $19 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $04 ; ? @@ -511,7 +540,7 @@ DeckIDData: tx Text0489 ; opponent name db $1a ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $03 ; ? db $0d ; ? @@ -522,7 +551,7 @@ DeckIDData: tx Text0475 ; opponent name db $1b ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $05 ; ? @@ -533,7 +562,7 @@ DeckIDData: tx Text0475 ; opponent name db $1b ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $05 ; ? @@ -544,7 +573,7 @@ DeckIDData: tx Text04b9 ; opponent name db $1c ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $05 ; ? @@ -555,7 +584,7 @@ DeckIDData: tx Text04d7 ; opponent name db $1d ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $05 ; ? @@ -566,7 +595,7 @@ DeckIDData: tx Text048a ; opponent name db $1e ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $03 ; ? db $0e ; ? @@ -577,7 +606,7 @@ DeckIDData: tx Text04df ; opponent name db $20 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $06 ; ? @@ -588,7 +617,7 @@ DeckIDData: tx Text04a1 ; opponent name db $1f ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $06 ; ? @@ -599,7 +628,7 @@ DeckIDData: tx Text04cc ; opponent name db $21 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $06 ; ? @@ -610,7 +639,7 @@ DeckIDData: tx Text047d ; opponent name db $22 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $03 ; ? db $0f ; ? @@ -621,7 +650,7 @@ DeckIDData: tx Text049a ; opponent name db $23 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $07 ; ? @@ -632,7 +661,7 @@ DeckIDData: tx Text049a ; opponent name db $23 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $07 ; ? @@ -643,7 +672,7 @@ DeckIDData: tx Text04d3 ; opponent name db $24 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $07 ; ? @@ -654,7 +683,7 @@ DeckIDData: tx Text04dc ; opponent name db $25 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $07 ; ? @@ -665,7 +694,7 @@ DeckIDData: tx Text0474 ; opponent name db $26 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $03 ; ? db $10 ; ? @@ -676,7 +705,7 @@ DeckIDData: tx Text04a2 ; opponent name db $27 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $08 ; ? @@ -687,7 +716,7 @@ DeckIDData: tx Text04cd ; opponent name db $29 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $08 ; ? @@ -698,7 +727,7 @@ DeckIDData: tx Text04f5 ; opponent name db $28 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $08 ; ? @@ -709,7 +738,7 @@ DeckIDData: tx Text042a ; opponent name db $3e ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $1f ; ? db $16 ; ? @@ -720,7 +749,7 @@ DeckIDData: tx Text0427 ; opponent name db $3b ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $1f ; ? db $16 ; ? @@ -731,7 +760,7 @@ DeckIDData: tx Text0428 ; opponent name db $3c ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $1f ; ? db $16 ; ? @@ -742,7 +771,7 @@ DeckIDData: tx Text0429 ; opponent name db $3d ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $1f ; ? db $16 ; ? @@ -753,7 +782,7 @@ DeckIDData: tx Text04be ; opponent name db $2a ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $04 ; ? db $11 ; ? @@ -764,7 +793,7 @@ DeckIDData: tx Text049e ; opponent name db $2b ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $04 ; ? db $11 ; ? @@ -775,7 +804,7 @@ DeckIDData: tx Text0482 ; opponent name db $2c ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $04 ; ? db $11 ; ? @@ -786,7 +815,7 @@ DeckIDData: tx Text04ed ; opponent name db $2d ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $04 ; ? db $11 ; ? @@ -797,7 +826,7 @@ DeckIDData: tx Text04d8 ; opponent name db $3f ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $1f ; ? db $17 ; ? @@ -808,7 +837,7 @@ DeckIDData: tx Text04e3 ; opponent name db $40 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $1f ; ? db $17 ; ? @@ -819,7 +848,7 @@ DeckIDData: tx Text04da ; opponent name db $41 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $01 ; ? db $1f ; ? db $17 ; ? @@ -830,7 +859,7 @@ DeckIDData: tx Text04dd ; opponent name db $42 ; ? db $06 ; ? - db $01 ; ? + db $01 ; special duel rules db $00 ; ? db $20 ; ? db $1d ; ? @@ -841,7 +870,7 @@ DeckIDData: tx Text04a4 ; opponent name db $46 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $26 ; ? @@ -852,7 +881,7 @@ DeckIDData: tx Text04f2 ; opponent name db $43 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $07 ; ? db $1f ; ? db $18 ; ? @@ -863,7 +892,7 @@ DeckIDData: tx Text0479 ; opponent name db $44 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $02 ; ? db $1f ; ? db $18 ; ? @@ -874,7 +903,7 @@ DeckIDData: tx Text0487 ; opponent name db $45 ; ? db $06 ; ? - db $02 ; ? + db $02 ; special duel rules db $00 ; ? db $20 ; ? db $1e ; ? @@ -885,7 +914,7 @@ DeckIDData: tx Text049b ; opponent name db $47 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $1f ; ? db $19 ; ? @@ -896,7 +925,7 @@ DeckIDData: tx Text04e2 ; opponent name db $48 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $03 ; ? db $1f ; ? db $19 ; ? @@ -907,7 +936,7 @@ DeckIDData: tx Text0499 ; opponent name db $49 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $08 ; ? db $1f ; ? db $19 ; ? @@ -918,7 +947,7 @@ DeckIDData: tx Text04bc ; opponent name db $4a ; ? db $06 ; ? - db $03 ; ? + db $03 ; special duel rules db $00 ; ? db $20 ; ? db $1f ; ? @@ -929,7 +958,7 @@ DeckIDData: tx Text04d9 ; opponent name db $4b ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $04 ; ? db $1f ; ? db $1a ; ? @@ -940,7 +969,7 @@ DeckIDData: tx Text049f ; opponent name db $4c ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $09 ; ? db $1f ; ? db $1a ; ? @@ -951,7 +980,7 @@ DeckIDData: tx Text0473 ; opponent name db $4d ; ? db $04 ; ? - db $04 ; ? + db $04 ; special duel rules db $00 ; ? db $1f ; ? db $1a ; ? @@ -962,7 +991,7 @@ DeckIDData: tx Text0483 ; opponent name db $4e ; ? db $06 ; ? - db $05 ; ? + db $05 ; special duel rules db $00 ; ? db $20 ; ? db $20 ; ? @@ -973,7 +1002,7 @@ DeckIDData: tx Text0494 ; opponent name db $4f ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $0c ; ? db $1f ; ? db $1b ; ? @@ -984,7 +1013,7 @@ DeckIDData: tx Text048c ; opponent name db $50 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $05 ; ? db $1f ; ? db $1b ; ? @@ -995,7 +1024,7 @@ DeckIDData: tx Text0485 ; opponent name db $51 ; ? db $06 ; ? - db $06 ; ? + db $06 ; special duel rules db $00 ; ? db $20 ; ? db $21 ; ? @@ -1006,7 +1035,7 @@ DeckIDData: tx Text04db ; opponent name db $52 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $06 ; ? db $1f ; ? db $1c ; ? @@ -1017,7 +1046,7 @@ DeckIDData: tx Text0492 ; opponent name db $53 ; ? db $04 ; ? - db $07 ; ? + db $07 ; special duel rules db $00 ; ? db $1f ; ? db $1c ; ? @@ -1028,7 +1057,7 @@ DeckIDData: tx Text04e5 ; opponent name db $54 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $0a ; ? db $1f ; ? db $1c ; ? @@ -1039,7 +1068,7 @@ DeckIDData: tx Text04ee ; opponent name db $55 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $0d ; ? db $1f ; ? db $1c ; ? @@ -1050,7 +1079,7 @@ DeckIDData: tx Text04d2 ; opponent name db $56 ; ? db $06 ; ? - db $08 ; ? + db $08 ; special duel rules db $00 ; ? db $20 ; ? db $22 ; ? @@ -1061,7 +1090,7 @@ DeckIDData: tx Text04b6 ; opponent name db $57 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $0e ; ? db $20 ; ? db $23 ; ? @@ -1072,7 +1101,7 @@ DeckIDData: tx Text0478 ; opponent name db $58 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $0f ; ? db $20 ; ? db $23 ; ? @@ -1083,7 +1112,7 @@ DeckIDData: tx Text0497 ; opponent name db $59 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $10 ; ? db $20 ; ? db $23 ; ? @@ -1094,7 +1123,7 @@ DeckIDData: tx Text042d ; opponent name db $07 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $23 ; ? db $14 ; ? @@ -1105,7 +1134,7 @@ DeckIDData: tx Text0486 ; opponent name db $5a ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $0b ; ? db $20 ; ? db $24 ; ? @@ -1116,7 +1145,7 @@ DeckIDData: tx Text04f0 ; opponent name db $5b ; ? db $06 ; ? - db $09 ; ? + db $09 ; special duel rules db $00 ; ? db $20 ; ? db $24 ; ? @@ -1127,7 +1156,7 @@ DeckIDData: tx Text04f0 ; opponent name db $5b ; ? db $06 ; ? - db $0a ; ? + db $0a ; special duel rules db $00 ; ? db $20 ; ? db $24 ; ? @@ -1138,7 +1167,7 @@ DeckIDData: tx Text04f0 ; opponent name db $5b ; ? db $06 ; ? - db $07 ; ? + db $07 ; special duel rules db $00 ; ? db $20 ; ? db $24 ; ? @@ -1149,7 +1178,7 @@ DeckIDData: tx Text04c2 ; opponent name db $5c ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $21 ; ? db $25 ; ? @@ -1160,7 +1189,7 @@ DeckIDData: tx Text04c2 ; opponent name db $5c ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $21 ; ? db $25 ; ? @@ -1171,7 +1200,7 @@ DeckIDData: tx Text04c2 ; opponent name db $5c ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $21 ; ? db $25 ; ? @@ -1182,7 +1211,7 @@ DeckIDData: tx Text04c2 ; opponent name db $5c ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $21 ; ? db $25 ; ? @@ -1193,7 +1222,7 @@ DeckIDData: tx Text04c8 ; opponent name db $36 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $02 ; ? db $27 ; ? @@ -1204,7 +1233,7 @@ DeckIDData: tx Text04b4 ; opponent name db $37 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $03 ; ? db $27 ; ? @@ -1215,7 +1244,7 @@ DeckIDData: tx Text04bf ; opponent name db $38 ; ? db $04 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $1f ; ? db $27 ; ? @@ -1226,7 +1255,7 @@ DeckIDData: tx Text04ef ; opponent name db $39 ; ? db $05 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $1f ; ? db $27 ; ? @@ -1237,7 +1266,7 @@ DeckIDData: tx Text0488 ; opponent name db $3a ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $20 ; ? db $27 ; ? @@ -1248,7 +1277,7 @@ DeckIDData: tx Text047a ; opponent name db $08 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $10 ; ? db $13 ; ? @@ -1259,7 +1288,7 @@ DeckIDData: tx Text047a ; opponent name db $09 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $24 ; ? db $13 ; ? @@ -1270,7 +1299,7 @@ DeckIDData: tx Text04e6 ; opponent name db $04 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $0f ; ? db $15 ; ? @@ -1281,7 +1310,7 @@ DeckIDData: tx Text042b ; opponent name db $5d ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $0f ; ? db $16 ; ? @@ -1292,7 +1321,7 @@ DeckIDData: tx Text04e6 ; opponent name db $04 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $0f ; ? db $15 ; ? @@ -1303,7 +1332,7 @@ DeckIDData: tx Text04e6 ; opponent name db $04 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $0f ; ? db $15 ; ? @@ -1314,7 +1343,7 @@ DeckIDData: tx Text04e6 ; opponent name db $04 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $0f ; ? db $15 ; ? @@ -1325,7 +1354,7 @@ DeckIDData: tx Text047f ; opponent name db $2e ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $20 ; ? db $28 ; ? @@ -1336,7 +1365,7 @@ DeckIDData: tx Text04cf ; opponent name db $2f ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $20 ; ? db $28 ; ? @@ -1347,7 +1376,7 @@ DeckIDData: tx Text04e1 ; opponent name db $30 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $20 ; ? db $28 ; ? @@ -1358,7 +1387,7 @@ DeckIDData: tx Text04ab ; opponent name db $31 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $20 ; ? db $28 ; ? @@ -1369,7 +1398,7 @@ DeckIDData: tx Text04c3 ; opponent name db $32 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $20 ; ? db $28 ; ? @@ -1380,7 +1409,7 @@ DeckIDData: tx Text0476 ; opponent name db $33 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $20 ; ? db $28 ; ? @@ -1391,7 +1420,7 @@ DeckIDData: tx Text04a9 ; opponent name db $34 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $20 ; ? db $28 ; ? @@ -1402,7 +1431,7 @@ DeckIDData: tx Text04d0 ; opponent name db $35 ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $20 ; ? db $28 ; ? @@ -1413,7 +1442,7 @@ DeckIDData: tx Text04ac ; opponent name db $5e ; ? db $06 ; ? - db $00 ; ? + db NO_RULES ; special duel rules db $00 ; ? db $20 ; ? db $28 ; ? diff --git a/src/engine/bank0e.asm b/src/engine/bank0e.asm new file mode 100644 index 0000000..cac9ad5 --- /dev/null +++ b/src/engine/bank0e.asm @@ -0,0 +1,1094 @@ +SECTION "Bank e@6b82", ROMX[$6b82], BANK[$e] + +HandleScrollMenu: + xor a + ld [wMenuInputSFX], a + ldh a, [hDPadHeld] + or a + jp z, .call_update_func ; no keys + ld b, a + ld a, [wNumMenuItems] + ld c, a + ld a, [wCurScrollMenuItem] + bit D_UP_F, b + jr z, .check_d_down +; d-up + push af + ld a, SFX_01 + ld [wMenuInputSFX], a + pop af + dec a + bit 7, a + jr z, .scroll_done +; wrap around + ld a, [wScrollMenuScrollOffset] + or a + jr z, .no_scroll_up + dec a + ld [wScrollMenuScrollOffset], a + ld hl, wScrollMenuScrollFunc + call CallIndirect + xor a + jr .scroll_done +.no_scroll_up + xor a + ld [wMenuInputSFX], a + jr .scroll_done + +.check_d_down + bit D_DOWN_F, b + jr z, .call_update_func +; d-down + push af + ld a, SFX_01 + ld [wMenuInputSFX], a + pop af + inc a + cp c + jr c, .scroll_done + push af + ld a, [wUnableToScrollDown] + or a + jr nz, .already_at_bottom + ld a, [wScrollMenuScrollOffset] + inc a + ld [wScrollMenuScrollOffset], a + ld hl, wScrollMenuScrollFunc + call CallIndirect + pop af + dec a + jr .scroll_done +.already_at_bottom + pop af + dec a + push af + xor a + ld [wMenuInputSFX], a + pop af + +.scroll_done + push af + call .draw_invisible_cursor + pop af + ld [wCurScrollMenuItem], a + xor a + ld [wScrollMenuCursorBlinkCounter], a + jr .call_update_func ; unnecessary jump + +.call_update_func + ld a, [wCurScrollMenuItem] + ld [hCurMenuItem], a + ld hl, wMenuUpdateFunc + ld a, [hli] + or [hl] + jr z, .null + ld a, [hld] + ld l, [hl] + ld h, a + ld a, [hCurMenuItem] + call CallHL + jr nc, .blink_cursor + +.asm_3ac12 + call .draw_visible_cursor + ld a, $01 + farcall PlayAcceptOrDeclineSFX + ld a, [wCurScrollMenuItem] + ld e, a + ld a, [hCurMenuItem] + scf + ret + +.null + ldh a, [hKeysPressed] + and A_BUTTON | B_BUTTON + jr z, .play_menu_input_sfx + and A_BUTTON + jr nz, .asm_3ac12 +; b button + ld a, $ff + ld [hCurMenuItem], a + farcall PlayAcceptOrDeclineSFX + scf + ret + +.play_menu_input_sfx + ld a, [wMenuInputSFX] + or a + jr z, .blink_cursor + call PlaySFX + +.blink_cursor + ld hl, wScrollMenuCursorBlinkCounter + ld a, [hl] + inc [hl] + and %1111 + ret nz + ld a, [wMenuVisibleCursorTile] + bit 4, [hl] + jr z, .draw_cursor +.draw_invisible_cursor + ld a, [wMenuInvisibleCursorTile] +.draw_cursor + ld e, a + ld a, [wMenuXSeparation] + ld l, a + ld a, [wCurScrollMenuItem] + ld h, a + call HtimesL + ld a, l + ld hl, wMenuCursorXOffset + add [hl] + ld b, a + ld a, [wMenuYSeparation] + ld l, a + ld a, [wCurScrollMenuItem] + ld h, a + call HtimesL + ld a, l + ld hl, wMenuCursorYOffset + add [hl] + ld c, a + ld a, e + call WriteByteToBGMap0 + or a + ret + +.draw_visible_cursor: + ld a, [wMenuVisibleCursorTile] + jr .draw_cursor +; 0x3ac82 + +SECTION "Bank e@6d06", ROMX[$6d06], BANK[$e] + +FillBoosterPackMenuItems: + call UpdateBoosterPackMenuArrows + ld a, [wScrollMenuScrollOffset] + lb de, 5, 2 + ld b, $05 +.loop + push af + push bc + push de + call .PrintBoosterPackName + pop de + pop bc + pop af + ret c + dec b + ret z + inc a + inc e + inc e + jr .loop + +; prints Booster Pack name in case +; player has obtained that booster pack +.PrintBoosterPackName: + push af + call InitTextPrinting + pop af + ld b, $00 + ld c, %1 +.loop_find + cp b + jr z, .found + sla c + inc b + jr .loop_find +.found + call EnableSRAM + ld a, [sBoosterPacksObtained] + call DisableSRAM + and c + ld hl, .ObtainedTextIDs + jr nz, .has_booster + ld hl, .NotObtainedTextIDs +.has_booster + ld a, b + add a ; *2 + ld c, a + ld b, $00 + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + call ProcessTextFromID + ret + +.ObtainedTextIDs: + tx Text02c1 + tx Text02c2 + tx Text02c3 + tx Text02c5 + tx Text02c7 + tx Text02c9 + tx Text02cb + tx Text02cd + +.NotObtainedTextIDs: + tx Text02c1 + tx Text02c2 + tx Text02c4 + tx Text02c6 + tx Text02c8 + tx Text02ca + tx Text02cc + tx Text02ce + +UpdateBoosterPackMenuArrows: + ld a, [wScrollMenuScrollOffset] + or a + jr z, .no_up_arrow + ld a, SYM_CURSOR_U + jr .draw_up_arrow +.no_up_arrow + ld a, SYM_BOX_TOP +.draw_up_arrow + lb bc, 18, 0 + call WriteByteToBGMap0 + ld a, [wScrollMenuScrollOffset] + cp $03 + jr nc, .no_down_arrow + xor a + ld [wUnableToScrollDown], a + ld a, SYM_CURSOR_D + jr .draw_down_arrow +.no_down_arrow + ld a, $01 + ld [wUnableToScrollDown], a + ld a, SYM_BOX_TOP +.draw_down_arrow + lb bc, 18, 12 + call WriteByteToBGMap0 + ret +; 0x3ada1 + +SECTION "Bank e@6e8c", ROMX[$6e8c], BANK[$e] + +; sets the number of cursor positions for deck machine menu, +; sets the text ID to show given by de +; and sets DrawDeckMachineScreen as the update function +; de = text ID +InitDeckMachineDrawingParams: + ld a, NUM_DECK_MACHINE_VISIBLE_DECKS + ld [wNumMenuItems], a + ld hl, wDeckMachineText + ld [hl], e + inc hl + ld [hl], d + ld hl, DrawDeckMachineScreen + ld d, h + ld a, l + ld hl, wScrollMenuScrollFunc + ld [hli], a + ld [hl], d + xor a + ld [wd119], a + ret + + ; handles player input inside the Deck Machine screen +; the Start button opens up the deck confirmation menu +; and returns carry +; otherwise, returns no carry and selection made in a +HandleDeckMachineSelection: +.start + call DoFrame + call HandleScrollMenu + jr c, .selection_made + + call .HandleListJumps + jr c, .start + ldh a, [hDPadHeld] + and START + jr z, .start + +; start btn + ld a, [wScrollMenuScrollOffset] + ld [wTempScrollMenuScrollOffset], a + ld b, a + ld a, [wCurScrollMenuItem] + ld [wTempScrollMenuItem], a + add b + ld c, a + inc a + or $80 + ld [wCurDeck], a + + ; get pointer to selected deck cards + ; and if it's an empty deck, jump to start + ld a, c + call Func_3afb8 + push hl + farcall CheckIfDeckHasCards + pop hl + jr c, .start + +; show deck confirmation screen with deck cards +; and return carry set + push hl + ld bc, DECK_NAME_SIZE + add hl, bc + ld d, h + ld e, l + pop hl + ld a, $01 + farcall PlayAcceptOrDeclineSFX + farcall OpenDeckConfirmationMenu + ld a, [wTempScrollMenuScrollOffset] + ld [wScrollMenuScrollOffset], a + call ClearScreenAndDrawDeckMachineScreen + call DrawListScrollArrows + call PrintNumSavedDecks + ld a, [wTempScrollMenuItem] + ld [wCurScrollMenuItem], a + scf + ret + +.selection_made + call HandleScrollMenu.draw_visible_cursor + ld a, [wScrollMenuScrollOffset] + ld [wTempScrollMenuScrollOffset], a + ld a, [wCurScrollMenuItem] + ld [wTempScrollMenuItem], a + ld a, [hCurMenuItem] + or a + ret + +; handles right and left input for jumping several entries at once +; returns carry if jump was made +.HandleListJumps + ld a, [wScrollMenuScrollOffset] + ld c, a + ldh a, [hDPadHeld] + cp D_RIGHT + jr z, .d_right + cp D_LEFT + jr z, .d_left + or a + ret + +.d_right + ld a, [wScrollMenuScrollOffset] + add NUM_DECK_MACHINE_VISIBLE_DECKS + ld b, a + add NUM_DECK_MACHINE_VISIBLE_DECKS + ld hl, wNumDeckMachineEntries + cp [hl] + jr c, .got_new_pos + ld a, [wNumDeckMachineEntries] + sub NUM_DECK_MACHINE_VISIBLE_DECKS + ld b, a + jr .got_new_pos + +.d_left + ld a, [wScrollMenuScrollOffset] + sub NUM_DECK_MACHINE_VISIBLE_DECKS + ld b, a + jr nc, .got_new_pos + ld b, 0 ; first entry + +.got_new_pos + ld a, b + ld [wScrollMenuScrollOffset], a + cp c + jr z, .set_carry + ; play SFX if jump was made + ; and update UI + ld a, SFX_01 + call PlaySFX + call DrawDeckMachineScreen + call PrintNumSavedDecks +.set_carry + scf + ret + +; returns carry if deck corresponding to the +; entry selected in the Deck Machine menu is empty +CheckIfSelectedDeckMachineEntryIsEmpty: + ld a, [wSelectedDeckMachineEntry] + call Func_3afb8 + farcall CheckIfDeckHasCards + ret +; 0x3af66 + +SECTION "Bank e@6f66", ROMX[$6f66], BANK[$e] + +ClearScreenAndDrawDeckMachineScreen: + xor a + ld [wTileMapFill], a + call ZeroObjectPositions + call EmptyScreen + ld a, $01 + ld [wVBlankOAMCopyToggle], a + call LoadSymbolsFont + call LoadDuelCardSymbolTiles + bank1call SetDefaultPalettes + lb de, $3c, $ff + call SetupText + lb de, 0, 0 + lb bc, 20, 13 + call DrawRegularTextBox + call SetDeckMachineTitleText + call GetSavedDeckPointers + call PrintVisibleDeckMachineEntries + call GetSavedDeckCount + call EnableLCD + ret + +; prints wDeckMachineTitleText as title text +SetDeckMachineTitleText: + ld hl, wDeckMachineTitleText + ld a, [hli] + ld h, [hl] + ld l, a + lb de, 1, 0 + call Func_2c4b + ret + +CopyBBytesFromHLToDE_Bank0e: +.loop + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .loop + ret +; 0x3afb1 + +SECTION "Bank e@6fb8", ROMX[$6fb8], BANK[$e] + +; a = deck index in wMachineDeckPtrs +Func_3afb8: + push bc + push de + add a ; *2 + ld c, a + ld b, $00 + ld hl, wMachineDeckPtrs + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld a, h + cp HIGH(STARTOF(WRAM0)) + jr c, .done ; done if not from WRAM + + call SwitchToWRAM2 + push hl + ld hl, wc000 + ld de, w2d58e + ld b, $80 + call CopyBBytesFromHLToDE_Bank0e + pop hl + ld de, wc000 + ld b, $80 + call CopyBBytesFromHLToDE_Bank0e + + call SwitchToWRAM1 + ld hl, wc000 + ld de, wd4c8 + ld b, $80 + call CopyBBytesFromHLToDE_Bank0e + call SwitchToWRAM2 + ld hl, w2d58e + ld de, wc000 + ld b, $80 + call CopyBBytesFromHLToDE_Bank0e + call SwitchToWRAM1 + ld hl, wd4c8 +.done + pop de + pop bc + ret + +; save all sSavedDecks pointers in wMachineDeckPtrs +GetSavedDeckPointers: + ld a, NUM_DECK_SAVE_MACHINE_SLOTS + add NUM_DECK_SAVE_MACHINE_SLOTS ; add a is better + ld hl, wMachineDeckPtrs + farcall ClearNBytesFromHL + ld de, wMachineDeckPtrs + ld hl, sSavedDecks + ld bc, DECK_COMPRESSED_STRUCT_SIZE + ld a, NUM_DECK_SAVE_MACHINE_SLOTS +.loop_saved_decks + push af + ld a, l + ld [de], a + inc de + ld a, h + ld [de], a + inc de + add hl, bc + pop af + dec a + jr nz, .loop_saved_decks + ret + +; given the cursor position in the deck machine menu +; prints the deck names of all entries that are visible +PrintVisibleDeckMachineEntries: + ld a, [wScrollMenuScrollOffset] + lb de, 2, 2 + ld b, NUM_DECK_MACHINE_VISIBLE_DECKS +.loop + push af + push bc + push de + call PrintDeckMachineEntry + pop de + pop bc + pop af + ret c ; jump never made? + dec b + ret z ; no more entries + inc a + inc e + inc e + jr .loop +; 0x3b043 + +SECTION "Bank e@7048", ROMX[$7048], BANK[$e] + +DrawDeckMachineScreen: + call DrawListScrollArrows + ld hl, hffbb + ld [hl], $01 + call SetDeckMachineTitleText + lb de, 1, 14 + call InitTextPrinting + ld hl, wDeckMachineText + ld a, [hli] + ld h, [hl] + ld l, a + call ProcessTextFromID + ld hl, hffbb + ld [hl], $00 + jr PrintVisibleDeckMachineEntries +; 0x3b069 + +SECTION "Bank e@7096", ROMX[$7096], BANK[$e] + +; prints the deck name of the deck corresponding +; to index in register a, from wMachineDeckPtrs +; also checks whether the deck can be built +; either by dismantling other decks or not, +; and places the corresponding symbol next to the name +PrintDeckMachineEntry: + ld b, a + push bc + ld hl, wDefaultText + inc a + farcall ConvertToNumericalDigits + ld [hl], "FW0_・" + inc hl + ld [hl], TX_END + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + pop af + +; get the deck corresponding to input index +; and append its name to wDefaultText + push af + call Func_3afb8 + inc d + inc d + inc d + push de + farcall AppendDeckName + pop de + pop bc + jr nc, .valid_deck + +; invalid deck, give it the default +; empty deck name ("--------------") + call InitTextPrinting + ldtx hl, Text02d2 ; EmptyDeckNameText + call ProcessTextFromID + ld d, 12 + inc e + call InitTextPrinting + ld hl, .text + call ProcessText + scf + ret + +.valid_deck + push de + push bc + + ld a, $0 ; no decks dismantled + call CheckIfCanBuildSavedDeck + pop bc + ld hl, wDefaultText + jr c, .cannot_build + + ; deck can be built + xor a + ld [wd49b], a + ld hl, wd49f + ld d, $00 + ld e, b + sla e ; *2 + add hl, de + ld [hl], a + ld [wd49e], a + ld hl, wd49f + ld d, $00 + ld e, b + sla e + inc e ; *2 + 1 + add hl, de + ld [hl], a + lb de, TX_FULLWIDTH4, "FW4_○" ; can build + jp .asm_3b18e + +.cannot_build + ; deck cannot be built + lb de, TX_FULLWIDTH0, "FW0_ " + call Func_22ca + + ; figure out how many cards are being + ; used on the other decks + push bc + call .CountCardsNeededToBuildInBuiltDecks + ld [wd49b], a + pop bc + ld hl, wd49f + ld d, $00 + ld e, b + sla e ; *2 + add hl, de + ld [hl], a + + push bc + ld a, $ff ; all decks + call .CountCardsNeededToBuildInCardCollection + ld [wd49e], a + pop bc + ld hl, wd49f + ld d, $00 + ld e, b + sla e + inc e ; *2 + 1 + add hl, de + ld [hl], a + pop de + + push af + push de + ld d, 12 + inc e + call InitTextPrinting + ld hl, .text + call ProcessText + pop de + pop af + push de + or a + jr z, .need_dismantle + + ; players doesn't own all necessary cards + pop de + push de + inc e + ld d, $10 + call InitTextPrinting + lb de, TX_FULLWIDTH0, "FW0_×" + call Func_22ca + ld a, [wd49e] + ld hl, wDefaultText + farcall ConvertToNumericalDigits + ld [hl], TX_END + ld hl, wDefaultText + call ProcessText + +.need_dismantle + pop de + ld a, [wd49b] + or a + jr z, .asm_3b18c + inc e + ld d, 12 + call InitTextPrinting + lb de, TX_FULLWIDTH4, "FW4_※" + call Func_22ca + ld a, [wd49b] + ld hl, wDefaultText + farcall ConvertToNumericalDigits + ld [hl], TX_END + ld hl, wDefaultText + call ProcessText +.asm_3b18c + or a + ret + +.asm_3b18e + call Func_22ca + pop de + ld d, 12 + inc e + call InitTextPrinting + ld hl, .text + call ProcessText + or a + ret + +.text + db "" + done + +; de = card ID +.GetCardCountInScratchCardCollection: + call SwitchToWRAM2 + push hl + ld hl, wScratchCardCollection + add hl, de + ld a, [hl] + pop hl + call SwitchToWRAM1 + ret + +; de = card ID +.DecrementCardCountInScratchCardCollection: + call SwitchToWRAM2 + push hl + ld hl, wScratchCardCollection + add hl, de + dec [hl] + pop hl + call SwitchToWRAM1 + ret + +; b = saved deck index +.CountCardsNeededToBuildInBuiltDecks: + push bc + ld a, $80 ; only cards that are in built decks + farcall CreateCardCollectionListWithDeckCards + + ; copy to wScratchCardCollection + call SwitchToWRAM2 + ld hl, wTempCardCollection + ld de, wScratchCardCollection + ld b, 0 ; $100 bytes + call CopyBBytesFromHLToDE_Bank0e + ld hl, wTempCardCollection + $100 + ld de, wScratchCardCollection + $100 + ld b, 0 ; $100 bytes + call CopyBBytesFromHLToDE_Bank0e + call SwitchToWRAM1 + + xor a ; all owned cards + farcall CreateCardCollectionListWithDeckCards + pop bc + + ; here, wTempCardCollection holds all cards that + ; the player owns, including in and out of decks + ; wScratchCardCollection holds all cards that + ; are in built decks only + + ld a, b + call Func_3afb8 + ld bc, DECK_NAME_SIZE + add hl, bc + ld d, h + ld e, l + ld hl, wTempSavedDeckCards + farcall CopyDeckFromSRAM + + ld hl, wTempSavedDeckCards + lb bc, DECK_SIZE + 1, 0 +.loop_deck + dec b + jr z, .got_count_1 + ld e, [hl] + inc hl + ld d, [hl] + inc hl + push hl + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + and CARD_COUNT_MASK + or a + jr z, .zero_count + dec [hl] + pop hl + jr .loop_deck +.zero_count + call .GetCardCountInScratchCardCollection + or a + jr z, .next_card + call .DecrementCardCountInScratchCardCollection + inc c +.next_card + pop hl + jr .loop_deck +.got_count_1 + ld a, c ; total number of cards found in built decks + ret + +; b = saved deck index +.CountCardsNeededToBuildInCardCollection: + push bc + farcall CreateCardCollectionListWithDeckCards + pop bc + + ld a, b + call Func_3afb8 + ld bc, DECK_NAME_SIZE + add hl, bc + ld d, h + ld e, l + ld hl, wTempSavedDeckCards + farcall CopyDeckFromSRAM + ld hl, wTempSavedDeckCards + lb bc, DECK_SIZE + 1, 0 +.loop_collection + dec b + jr z, .got_count_2 + ld e, [hl] + inc hl + ld d, [hl] + inc hl + push hl + ld hl, wc000 + add hl, de + ld a, [hl] + and CARD_COUNT_MASK + or a + jr z, .next_card_in_collection + dec a + ld [hl], a + pop hl + jr .loop_collection +.next_card_in_collection + inc c + pop hl + jr .loop_collection +.got_count_2 + ld a, c + ret + +; counts how many decks in sSavedDecks are not empty +; stores value in wNumSavedDecks +GetSavedDeckCount: + call EnableSRAM + ld hl, sSavedDecks + ld bc, DECK_COMPRESSED_STRUCT_SIZE + ld d, NUM_DECK_SAVE_MACHINE_SLOTS + ld e, 0 +.loop + ld a, [hl] + or a + jr z, .empty_slot + inc e +.empty_slot + dec d + jr z, .got_count + add hl, bc + jr .loop +.got_count + ld a, e + ld [wNumSavedDecks], a + call DisableSRAM + ret + +; prints "[wNumSavedDecks]/50" +PrintNumSavedDecks: + ld a, [wNumSavedDecks] + ld hl, wDefaultText + farcall ConvertToNumericalDigits + ld a, TX_SYMBOL + ld [hli], a + ld a, SYM_SLASH + ld [hli], a + ld a, NUM_DECK_SAVE_MACHINE_SLOTS + farcall ConvertToNumericalDigits + ld [hl], TX_END + lb de, 14, 1 + call InitTextPrinting + ld hl, wDefaultText + call ProcessText + ret +; 0x3b2af + +SECTION "Bank e@7366", ROMX[$7366], BANK[$e] + +GetSelectedSavedDeckPtr: + push af + push de + ld a, [wSelectedDeckMachineEntry] + call Func_3afb8 + pop de + pop af + ret + +; checks if it's possible to build saved deck with index b +; includes cards from already built decks from flags in a +; returns carry if cannot build the deck with the given criteria +; a = DECK_* flags for which decks to include in the collection +; b = saved deck index +CheckIfCanBuildSavedDeck: + push bc + farcall CreateCardCollectionListWithDeckCards + pop bc + ld a, b + call Func_3afb8 + ld bc, DECK_NAME_SIZE + add hl, bc + call CheckIfHasEnoughCardsToBuildDeck + ret + +SwitchToWRAM1: + push af + ld a, [wce4c] + cp $01 + jr z, .skip + ld a, $01 + ld [wce4c], a + ldh [rSVBK], a +.skip + pop af + ret + +SwitchToWRAM2: + push af + ld a, [wce4c] + cp $02 + jr z, .skip + ld a, $02 + ld [wce4c], a + ldh [rSVBK], a +.skip + pop af + ret + +; returns carry if wTempCardCollection does not +; have enough cards to build deck pointed by hl +; hl = pointer to cards of deck to check +CheckIfHasEnoughCardsToBuildDeck: + ld d, h + ld e, l + ld hl, wTempSavedDeckCards + farcall CopyDeckFromSRAM + ld hl, wTempSavedDeckCards + ld b, DECK_SIZE + 1 +.loop + dec b + jr z, .no_carry + ld e, [hl] + inc hl + ld d, [hl] + inc hl + push hl + ld hl, wTempCardCollection + add hl, de + ld a, [hl] + or a + jr z, .set_carry + cp CARD_NOT_OWNED + jr z, .set_carry + dec a + ld [hl], a + pop hl + jr .loop + +.set_carry + pop hl + scf + ret + +.no_carry + or a + ret +; 0x3b3d1 + +SECTION "Bank e@742b", ROMX[$742b], BANK[$e] + +DrawListScrollArrows: + ld a, [wScrollMenuScrollOffset] + or a + jr z, .no_up_cursor + ld a, SYM_CURSOR_U + jr .got_tile_1 +.no_up_cursor + ld a, SYM_BOX_RIGHT +.got_tile_1 + lb bc, 19, 1 + call WriteByteToBGMap0 + + ld a, [wScrollMenuScrollOffset] + add NUM_DECK_MACHINE_VISIBLE_DECKS + 1 + ld b, a + ld a, [wNumDeckMachineEntries] + cp b + jr c, .no_down_cursor + xor a ; FALSE + ld [wUnableToScrollDown], a + ld a, SYM_CURSOR_D + jr .got_tile_2 +.no_down_cursor + ld a, TRUE + ld [wUnableToScrollDown], a + ld a, SYM_BOX_RIGHT +.got_tile_2 + lb bc, 19, 11 + call WriteByteToBGMap0 + ret +; 0x3b45f + +SECTION "Bank e@7a9c", ROMX[$7a9c], BANK[$e] + +_PrinterMenu_DeckConfiguration: + xor a + ld [wScrollMenuScrollOffset], a + call ClearScreenAndDrawDeckMachineScreen + ld a, NUM_DECK_SAVE_MACHINE_SLOTS + ld [wNumDeckMachineEntries], a + + xor a +.start_selection + ld hl, DeckMachineSelectionParams + farcall InitializeScrollMenuParameters + call DrawListScrollArrows + call PrintNumSavedDecks + ldtx hl, Text02f7 ; PleaseChooseDeckConfigurationToPrintText + call DrawWideTextBox_PrintText + ldtx de, Text02f7 ; PleaseChooseDeckConfigurationToPrintText + call InitDeckMachineDrawingParams +.loop_input + call HandleDeckMachineSelection + jr c, .start_selection + cp $ff + ret z + + ld b, a + ld a, [wScrollMenuScrollOffset] + add b + ld [wSelectedDeckMachineEntry], a + call CheckIfSelectedDeckMachineEntryIsEmpty + jr c, .loop_input + call DrawWideTextBox + ldtx hl, Text02f8 ; PrintThisDeckText + call YesOrNoMenuWithText + jr c, .no + call GetSelectedSavedDeckPtr + ld de, DECK_NAME_SIZE + add hl, de + ld d, h + ld e, l + ld hl, wCurDeckCards + farcall CopyDeckFromSRAM + farcall SortCurDeckCardsByID + ld a, [wSelectedDeckMachineEntry] + farcall PrintDeckConfiguration + call ClearScreenAndDrawDeckMachineScreen + +.no + ld a, [wTempScrollMenuItem] + ld [wCurScrollMenuItem], a + jp .start_selection +; 0x3bb09 diff --git a/src/engine/glossary.asm b/src/engine/glossary.asm new file mode 100644 index 0000000..e706400 --- /dev/null +++ b/src/engine/glossary.asm @@ -0,0 +1,368 @@ +Glossary: + xor a + ld [wd0d2], a + bank1call SetDefaultPalettes + lb de, $38, $9f + call SetupText + jr .asm_186ba + ld a, $01 + ld [wd0d2], a + +.asm_186ba + xor a +.main_menu + ld hl, .MainMenuParameters + call InitializeMenuParameters + xor a + ld [wTileMapFill], a + call ZeroObjectPositions + ld a, $01 + ld [wVBlankOAMCopyToggle], a + call DoFrame + call EmptyScreen + farcall LoadMenuCursorTile + ld hl, .MainMenuItems + call PlaceTextItems + ldtx hl, Text03d0 + call DrawWideTextBox_PrintText +.loop_input + call DoFrame + call HandleMenuInput + jr nc, .loop_input + cp -1 + ret z ; return + + ; selection was made + call EraseCursor + ldh a, [hCurScrollMenuItem] + ld [wGlossaryMenu], a + cp GLOSSARY_EXIT + ret z ; exit Glossary + + call .ShowMenuContent + ld a, [wGlossaryMenu] + cp GLOSSARY_STATUS_WINNING_LOSING + jr nz, .has_10_topics +; GLOSSARY_STATUS_WINNING_LOSING + xor a + ld de, GlossaryTransitionTable_8Topics + jr .got_transition_table +.has_10_topics + cp GLOSSARY_SPECIAL_DUEL_RULES + jr nz, .not_special_duel_rules +; GLOSSARY_SPECIAL_DUEL_RULES + ld a, [wSpecialRule] + or a + jr z, .asm_18714 + dec a +.asm_18714 + ld de, GlossaryTransitionTable_10Topics + jr .got_transition_table +.not_special_duel_rules + xor a + ld de, GlossaryTransitionTable_10Topics +.got_transition_table + ld [wd0c1], a + ld hl, wTransitionTablePtr + ld [hl], e + inc hl + ld [hl], d + ld a, $ff + ld [wd0c4], a + + xor a + ld [wScrollMenuCursorBlinkCounter], a +.topic_menu + ld a, $01 + ld [wVBlankOAMCopyToggle], a + call DoFrame + ld a, [wd0d2] + or a + call nz, .Func_18763 + farcall HandleMultiDirectionalMenu + jr nc, .topic_menu + cp $ff + jr nz, .selected_topic + farcall ZeroObjectPositionsWithCopyToggleOn + ldh a, [hCurScrollMenuItem] + jp .main_menu + +.selected_topic + push af + farcall ZeroObjectPositionsWithCopyToggleOn + pop af + call .ShowExplanation + call .ShowMenuContent + xor a + ld [wScrollMenuCursorBlinkCounter], a + jr .topic_menu + +.Func_18763: + ld a, [wGlossaryMenu] + cp GLOSSARY_SPECIAL_DUEL_RULES + ret nz ; not in special duel rules menu + ld a, [wSpecialRule] + or a + ret z ; no special rules + dec a + sla a + ld c, a + ld hl, wScrollMenuCursorBlinkCounter + ld a, [hl] + and $0f + ret nz + lb de, 4, "FW4_★" + bit 4, [hl] + jr z, .got_tile + lb de, 0, "FW0_ " +.got_tile + ld b, $00 + ld hl, .rule_coords + add hl, bc + push de + ld e, [hl] + inc hl + ld d, [hl] + call InitTextPrinting + pop de + call Func_22ca + ret + +.rule_coords + ; x, y + db 3, 8 ; CHLOROPHYLL + db 5, 8 ; THUNDER_CHARGE + db 7, 8 ; FLAME_ARMOR + db 9, 7 ; SMALL_BENCH + db 11, 7 ; RUNNING_WATER + db 3, 18 ; EARTH_POWER + db 5, 17 ; LOW_RESISTANCE + db 7, 17 ; ENERGY_RETURN + db 9, 17 ; TOUGH_ESCAPE + db 11, 18 ; BLACK_HOLE + +.MainMenuParameters: + db 1, 3 ; cursor x, cursor y + db 2 ; y displacement between items + db 5 ; number of items + db SYM_CURSOR_R ; cursor tile number + db SYM_SPACE ; tile behind cursor + dw NULL ; function pointer if non-0 + +.MainMenuItems: + textitem 2, 1, Text03c6 + textitem 3, 3, Text03c7 + textitem 3, 5, Text03c8 + textitem 3, 7, Text03c9 + textitem 3, 9, Text03ca + textitem 3, 11, Text03cb + db $ff + +; shows which topics are inside this Glossary menu +; each menu has a text ID for title and for the items +.ShowMenuContent: + xor a + ld [wTileMapFill], a + call EmptyScreen + ld a, [wGlossaryMenu] + or a + jr nz, .asm_187df +; GLOSSARY_GAME_BASICS + ldtx hl, Text03c7 + ldtx de, Text03cc + jr .got_title_and_topics +.asm_187df + cp GLOSSARY_CARD_TYPE_EXPLANATIONS + jr nz, .asm_187eb +; GLOSSARY_CARD_TYPE_EXPLANATIONS + ldtx hl, Text03c8 + ldtx de, Text03cd + jr .got_title_and_topics +.asm_187eb + cp GLOSSARY_STATUS_WINNING_LOSING + jr nz, .asm_187f7 +; GLOSSARY_STATUS_WINNING_LOSING + ldtx hl, Text03c9 + ldtx de, Text03ce + jr .got_title_and_topics +.asm_187f7 +; GLOSSARY_SPECIAL_DUEL_RULES + lb de, 6, 1 + call InitTextPrinting + ldtx hl, Text03ca + ldtx de, Text03cf + push de + jr .skip_init_text + +; hl = title +; de = topics +.got_title_and_topics + push de + push hl + lb de, 3, 1 + call InitTextPrinting + pop hl +.skip_init_text + call ProcessTextFromID + lb de, 1, 3 + call InitTextPrinting + pop hl + call ProcessTextFromID + ldtx hl, Text03d0 + call DrawWideTextBox_PrintText + ret + +; shows a big box with the explanation of the +; selected topic, each topic has data +; related to the x position of the topic title text +; and the text IDs of the information shown +; waits for the player to press the B button +.ShowExplanation: + push af + xor a + ld [wTileMapFill], a + call EmptyScreen + lb de, 0, 4 + lb bc, 20, 14 + call DrawRegularTextBox + + ld a, [wGlossaryMenu] + or a + jr nz, .asm_18847 +; GLOSSARY_GAME_BASICS + ld hl, .ExplanationTextData_GameBasics + push hl + ldtx hl, Text03d1 + push hl + lb de, 2, 0 + jr .got_explanation_data + +.asm_18847 + cp GLOSSARY_CARD_TYPE_EXPLANATIONS + jr nz, .asm_18858 +; GLOSSARY_CARD_TYPE_EXPLANATIONS + ld hl, .ExplanationTextData_CardTypes + push hl + ldtx hl, Text03d2 + push hl + lb de, 2, 0 + jr .got_explanation_data + +.asm_18858 + cp GLOSSARY_STATUS_WINNING_LOSING + jr nz, .asm_18869 +; GLOSSARY_STATUS_WINNING_LOSING + ld hl, .ExplanationTextData_StatusWinningLosing + push hl + ldtx hl, Text03d3 + push hl + lb de, 2, 0 + jr .got_explanation_data + +.asm_18869 +; GLOSSARY_SPECIAL_DUEL_RULES + ld hl, .ExplanationTextData_SpecialDuelRules + push hl + ldtx hl, Text03d4 + push hl + lb de, 5, 0 +.got_explanation_data + call InitTextPrinting + pop hl + call ProcessTextFromID + pop hl + pop af + ld c, a + ld b, $00 + add hl, bc + sla a + sla a ; *4 + ld c, a + add hl, bc + + ; topic title + ld a, [hli] + push hl + ld d, a ; x + ld e, 2 + call InitTextPrinting + ld a, [hli] + ld h, [hl] + ld l, a + call ProcessTextFromID + pop hl + + ; topic explanation + lb de, 1, 5 + call InitTextPrinting + inc hl + inc hl + ld a, [hli] + ld h, [hl] + ld l, a + ld a, $1 + ld [wLineSeparation], a + call ProcessTextFromID + xor a + ld [wLineSeparation], a + call EnableLCD +.loop_wait_b_btn + call DoFrame + ldh a, [hKeysPressed] + and B_BUTTON + jr z, .loop_wait_b_btn + ld a, $ff + farcall PlayAcceptOrDeclineSFX + ret + +MACRO explanation + db \1 ; title x position + tx \2 ; title text ID + tx \3 ; explanation text ID +ENDM + +.ExplanationTextData_GameBasics: + explanation 5, Text03d5, Text03fb + explanation 6, Text03d6, Text03fc + explanation 4, Text03d7, Text03fd + explanation 6, Text03d8, Text03fe + explanation 5, Text03d9, Text03ff + explanation 5, Text03da, Text0400 + explanation 4, Text03db, Text0401 + explanation 3, Text03dc, Text0402 + explanation 4, Text03dd, Text0403 + explanation 2, Text03de, Text0404 + +.ExplanationTextData_CardTypes: + explanation 3, Text03df, Text0405 + explanation 3, Text03e0, Text0406 + explanation 4, Text03e1, Text0407 + explanation 4, Text03e2, Text0408 + explanation 3, Text03e3, Text0409 + explanation 6, Text03e4, Text040a + explanation 5, Text03e5, Text040b + explanation 6, Text03e6, Text040c + explanation 5, Text03e7, Text040d + explanation 5, Text03e8, Text040e + +.ExplanationTextData_StatusWinningLosing: + explanation 5, Text03e9, Text040f + explanation 5, Text03ea, Text0410 + explanation 4, Text03eb, Text0411 + explanation 4, Text03ec, Text0412 + explanation 3, Text03ed, Text0413 + explanation 3, Text03ee, Text0414 + explanation 3, Text03ef, Text0415 + explanation 4, Text03f0, Text0416 + +.ExplanationTextData_SpecialDuelRules: + explanation 3, Text03f1, Text0417 + explanation 3, Text03f2, Text0418 + explanation 3, Text03f3, Text0419 + explanation 4, Text03f4, Text041a + explanation 4, Text03f5, Text041b + explanation 3, Text03f6, Text041c + explanation 4, Text03f7, Text041d + explanation 4, Text03f8, Text041e + explanation 4, Text03f9, Text041f + explanation 3, Text03fa, Text0420 diff --git a/src/engine/scenes.asm b/src/engine/scenes.asm index bd27205..3aa023b 100644 --- a/src/engine/scenes.asm +++ b/src/engine/scenes.asm @@ -57,43 +57,43 @@ _LoadScene:: ret SceneDataPointers: - dw .SceneSpecialRules ; SCENE_SPECIAL_RULES - dw .SceneSlotMachine ; SCENE_SLOT_MACHINE - dw .SceneBeginningPack ; SCENE_BEGINNING_PACK - dw .SceneLegendaryPack ; SCENE_LEGENDARY_PACK - dw .SceneFossilPack ; SCENE_FOSSIL_PACK - dw .ScenePsychicPack ; SCENE_PSYCHIC_PACK - dw .SceneFlyingPack ; SCENE_FLYING_PACK - dw .SceneRocketPack ; SCENE_ROCKET_PACK - dw .SceneAmbitionPack ; SCENE_AMBITION_PACK - dw .ScenePresentPack ; SCENE_PRESENT_PACK - dw .SceneIntroBaseSet ; SCENE_INTRO_BASE_SET - dw .SceneIntroJungle ; SCENE_INTRO_JUNGLE - dw .SceneIntroFossil ; SCENE_INTRO_FOSSIL - dw .SceneIntroTeamRocket ; SCENE_INTRO_TEAM_ROCKET - dw .SceneTournamentTable ; SCENE_TOURNAMENT_TABLE - dw .SceneCardPopMenu ; SCENE_CARD_POP_MENU - dw .SceneCardPop ; SCENE_CARD_POP - dw .SceneCardPopError ; SCENE_CARD_POP_ERROR - dw .SceneLink ; SCENE_LINK - dw .SceneRareCardPop ; SCENE_RARE_CARD_POP - dw .SceneRareCardPopError ; SCENE_RARE_CARD_POP_ERRORR - dw .SceneBlackBox ; SCENE_BLACK_BOX - dw .SceneTitleScreen1 ; SCENE_TITLE_SCREEN_1 - dw .SceneTitleScreen2 ; SCENE_TITLE_SCREEN_2 - dw .SceneTitleScreen3 ; SCENE_TITLE_SCREEN_3 - dw .SceneTitleScreen4 ; SCENE_TITLE_SCREEN_4 - dw .ScenePrinter1 ; SCENE_PRINTER_1 - dw .ScenePrinter2 ; SCENE_PRINTER_2 - dw .SceneFullMailbox ; SCENE_FULL_MAILBOX - dw .SceneGotMail ; SCENE_GOT_MAIL - dw .SceneMailbox ; SCENE_MAILBOX - dw .SceneDeckDiagnosis ; SCENE_DECK_DIAGNOSIS - dw .SceneLinkIntro1 ; SCENE_LINK_INTRO_1 - dw .SceneLinkIntro2 ; SCENE_LINK_INTRO_2 - dw .SceneCoinTossResult1 ; SCENE_COIN_TOSS_RESULT_1 - dw .SceneCoinTossResult2 ; SCENE_COIN_TOSS_RESULT_2 - dw .SceneGBCOnlyDisclaimer ; SCENE_GBC_ONLY_DISCLAIMER + dw .SceneSpecialRules ; SCENE_SPECIAL_RULES + dw .SceneSlotMachine ; SCENE_SLOT_MACHINE + dw .SceneBeginningPack ; SCENE_BEGINNING_PACK + dw .SceneLegendaryPack ; SCENE_LEGENDARY_PACK + dw .SceneFossilPack ; SCENE_FOSSIL_PACK + dw .ScenePsychicPack ; SCENE_PSYCHIC_PACK + dw .SceneFlyingPack ; SCENE_FLYING_PACK + dw .SceneRocketPack ; SCENE_ROCKET_PACK + dw .SceneAmbitionPack ; SCENE_AMBITION_PACK + dw .ScenePresentPack ; SCENE_PRESENT_PACK + dw .SceneIntroBaseSet ; SCENE_INTRO_BASE_SET + dw .SceneIntroJungle ; SCENE_INTRO_JUNGLE + dw .SceneIntroFossil ; SCENE_INTRO_FOSSIL + dw .SceneIntroTeamRocket ; SCENE_INTRO_TEAM_ROCKET + dw .SceneTournamentTable ; SCENE_TOURNAMENT_TABLE + dw .SceneCardPopMenu ; SCENE_CARD_POP_MENU + dw .SceneCardPop ; SCENE_CARD_POP + dw .SceneCardPopError ; SCENE_CARD_POP_ERROR + dw .SceneLink ; SCENE_LINK + dw .SceneRareCardPop ; SCENE_RARE_CARD_POP + dw .SceneRareCardPopError ; SCENE_RARE_CARD_POP_ERRORR + dw .SceneBlackBox ; SCENE_BLACK_BOX + dw .SceneTitleScreen1 ; SCENE_TITLE_SCREEN_1 + dw .SceneTitleScreen2 ; SCENE_TITLE_SCREEN_2 + dw .SceneTitleScreen3 ; SCENE_TITLE_SCREEN_3 + dw .SceneTitleScreen4 ; SCENE_TITLE_SCREEN_4 + dw .ScenePrinterTransmitting ; SCENE_GAMEBOY_PRINTER_TRANSMITTING + dw .ScenePrinterNotConnected ; SCENE_GAMEBOY_PRINTER_NOT_CONNECTED + dw .SceneFullMailbox ; SCENE_FULL_MAILBOX + dw .SceneGotMail ; SCENE_GOT_MAIL + dw .SceneMailbox ; SCENE_MAILBOX + dw .SceneDeckDiagnosis ; SCENE_DECK_DIAGNOSIS + dw .SceneLinkIntro1 ; SCENE_LINK_INTRO_1 + dw .SceneLinkIntro2 ; SCENE_LINK_INTRO_2 + dw .SceneCoinTossResult1 ; SCENE_COIN_TOSS_RESULT_1 + dw .SceneCoinTossResult2 ; SCENE_COIN_TOSS_RESULT_2 + dw .SceneGBCOnlyDisclaimer ; SCENE_GBC_ONLY_DISCLAIMER .SceneSpecialRules dw TILESET_SPECIAL_RULES @@ -299,7 +299,7 @@ SceneDataPointers: dw PALETTE_173 db $ff, $ff ; end -.ScenePrinter1 +.ScenePrinterTransmitting dw TILESET_PRINTER_SCENE dw PALETTE_179 dw TILEMAP_22F @@ -311,7 +311,7 @@ SceneDataPointers: dw PALETTE_17A db $ff, $ff ; end -.ScenePrinter2 +.ScenePrinterNotConnected dw TILESET_PRINTER_SCENE dw PALETTE_179 dw TILEMAP_22F diff --git a/src/gfx/menu_cursor.png b/src/gfx/menu_cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..83ef4c9329dbdac4ed8b6d128d5336326310d9e3 GIT binary patch literal 89 zcmeAS@N?(olHy`uVBq!ia0vp^93adDBp6m-`S}e*n!lwBL@6A8> mPq=xnaxZ)7e(5aPxbB^mw}ZxvX%>U literal 0 HcmV?d00001 diff --git a/src/home/card_collection.asm b/src/home/card_collection.asm index 1779073..08f7b54 100644 --- a/src/home/card_collection.asm +++ b/src/home/card_collection.asm @@ -134,7 +134,7 @@ AddCardToCollection: push hl push bc push de - bank1call $6a0c ; CreateTempCardCollection + bank1call CreateTempCardCollection pop de call EnableSRAM ld hl, wTempCardCollection diff --git a/src/home/card_data.asm b/src/home/card_data.asm index c69a802..27993be 100644 --- a/src/home/card_data.asm +++ b/src/home/card_data.asm @@ -87,7 +87,7 @@ LoadCardDataToHL_FromCardID: ret ; return in a the type (TYPE_* constant) of the card with id at de -GetCardType: +GetCardType:: push hl call GetCardPointer jr c, .done @@ -120,7 +120,7 @@ Func_2d3f: ret ; return in de the 2-byte text id of the name of the card with id at de -GetCardName: +GetCardName:: push hl call GetCardPointer jr c, .done @@ -138,7 +138,7 @@ GetCardName: ret ; from the card id in de, returns type into a, rarity into b, and set into c -GetCardTypeRarityAndSet: +GetCardTypeRarityAndSet:: push hl push de call GetCardPointer @@ -168,12 +168,7 @@ GetCardPointer: ld a, d or e jr z, .invalid - ld a, d - cp HIGH(NUM_CARDS + 1) - jr nz, .check - ld a, e - cp LOW(NUM_CARDS + 1) -.check + cp16 NUM_CARDS + 1 jr c, .valid .invalid scf @@ -211,17 +206,17 @@ LoadCardGfx:: call BankswitchROM ret -Func_2dc4: +Func_2dc4:: ldh a, [hBankROM] push af call LoadCardPalettes ld a, l - ld [wcde5], a + ld [wcde5 + 0], a ld a, h ld [wcde5 + 1], a - ld hl, $cd92 - ld bc, $3000 -.asm_2dd8 + ld hl, wCardAttrMap + lb bc, $30, 0 +.loop_copy ld a, [hl] and $3f ld [hli], a @@ -233,20 +228,20 @@ Func_2dc4: add hl, hl add hl, hl add hl, hl - add hl, hl - ld a, [wcde5] + add hl, hl ; *TILE_SIZE + ld a, [wcde5 + 0] add l ld l, a ld a, [wcde5 + 1] adc h ld h, a - ld b, $10 + ld b, TILE_SIZE call SafeCopyDataHLtoDE pop bc pop hl inc c dec b - jr nz, .asm_2dd8 + jr nz, .loop_copy pop af call BankswitchROM ret @@ -258,23 +253,23 @@ LoadCardPalettes: ld a, h srl a srl a - srl a + srl a ; /8 add BANK(CardGraphics) call BankswitchROM pop hl add hl, hl add hl, hl - add hl, hl + add hl, hl ; *8 res 7, h set 6, h ; $4000 ≤ hl ≤ $7fff - ld b, $48 + ld b, 3 palettes + $30 ; palettes + attributes ld de, wCardPalettes -.asm_2e1c +.loop_copy ld a, [hli] ld [de], a inc de dec b - jr nz, .asm_2e1c + jr nz, .loop_copy pop de pop bc ret diff --git a/src/home/double_speed.asm b/src/home/double_speed.asm index b39c3d6..afa063a 100644 --- a/src/home/double_speed.asm +++ b/src/home/double_speed.asm @@ -1,12 +1,12 @@ ; switch to CGB Normal Speed Mode if playing on CGB and current mode is Double Speed Mode -SwitchToCGBNormalSpeed: +SwitchToCGBNormalSpeed:: ld hl, rKEY1 bit 7, [hl] ret z jr CGBSpeedSwitch ; switch to CGB Double Speed Mode if playing on CGB and current mode is Normal Speed Mode -SwitchToCGBDoubleSpeed: +SwitchToCGBDoubleSpeed:: ld hl, rKEY1 bit 7, [hl] ret nz diff --git a/src/home/duel.asm b/src/home/duel.asm index 59981dd..056da80 100644 --- a/src/home/duel.asm +++ b/src/home/duel.asm @@ -54,7 +54,7 @@ CopyDeckData: ret ; return, in register a, the amount of prizes that the turn holder has not yet drawn -CountPrizes: +CountPrizes:: push hl ld a, DUELVARS_PRIZES get_turn_duelist_var @@ -223,19 +223,14 @@ Func_0ffa: push de ld c, a call GetCardIDFromDeckIndex - ld a, d - cp HIGH(RECYCLE_ENERGY) - jr nz, .asm_1008 - ld a, e - cp LOW(RECYCLE_ENERGY) -.asm_1008 + cp16 RECYCLE_ENERGY ld a, c pop de pop bc jr nz, PutCardInDiscardPile push bc ld c, a - ld a, [wcc10] + ld a, [wSpecialRule] cp $0a ld a, c pop bc @@ -490,7 +485,7 @@ ShuffleCards: ; returns, in register de, the id of the card with the deck index (0-59) specified by register a ; preserves af and hl -GetCardIDFromDeckIndex: +GetCardIDFromDeckIndex:: push af push hl call _GetCardIDFromDeckIndex @@ -584,7 +579,7 @@ _GetCardIDFromDeckIndex: ret ; load data of card with deck index a (0-59) to wLoadedCard1 -LoadCardDataToBuffer1_FromDeckIndex: +LoadCardDataToBuffer1_FromDeckIndex:: push hl push de push bc @@ -600,7 +595,7 @@ LoadCardDataToBuffer1_FromDeckIndex: ret ; load data of card with deck index a (0-59) to wLoadedCard2 -LoadCardDataToBuffer2_FromDeckIndex: +LoadCardDataToBuffer2_FromDeckIndex:: push hl push de push bc @@ -888,7 +883,7 @@ PutHandCardInPlayArea: ret Func_12fc: - ld a, [wcc10] + ld a, [wSpecialRule] cp $08 jr nz, MovePlayAreaCardToDiscardPile call EmptyPlayAreaSlot @@ -1086,7 +1081,7 @@ SwapPlayAreaPokemon: ; or a Pokemon card in the bench, depending on the value of register e. ; input: e = location to check, i.e. PLAY_AREA_* ; Feedback is returned in wAttachedEnergies and wTotalAttachedEnergies. -GetPlayAreaCardAttachedEnergies: +GetPlayAreaCardAttachedEnergies:: push hl push de push bc @@ -1206,7 +1201,7 @@ GetTurnDuelistVariable: ; returns [([hWhoseTurn] ^ $1) << 8 + a] in a and in [hl] ; i.e. duelvar a of the player whose turn it is not -GetNonTurnDuelistVariable: +GetNonTurnDuelistVariable:: ld l, a ldh a, [hWhoseTurn] ld h, OPPONENT_TURN @@ -1720,7 +1715,7 @@ ApplyDamageModifiers_DamageToTarget: and b jr z, .check_pluspower_and_defender ; jump if not resistant ld hl, -30 - ld a, [wcc10] + ld a, [wSpecialRule] cp $07 jr nz, .asm_1801 ld hl, -10 @@ -2044,7 +2039,7 @@ DealDamageToPlayAreaPokemon: ret Func_1bb4: - call $3c55 ; Func_3c55 + call FinishQueuedAnimations bank1call $4cd7 ; DrawDuelMainScene bank1call $4d82 ; DrawDuelHUDs xor a @@ -2174,7 +2169,7 @@ CheckLoadedAttackFlag: ; As a side effect, this also returns a duelist variable in a similar manner to ; GetNonTurnDuelistVariable, but this function appears to be ; only called to swap the turn value. -SwapTurn: +SwapTurn:: push af push hl call GetNonTurnDuelistVariable @@ -2185,7 +2180,7 @@ SwapTurn: ret ; copy the TX_END-terminated player's name from sPlayerName to de -CopyPlayerName: +CopyPlayerName:: call EnableSRAM ld hl, sPlayerName .loop diff --git a/src/home/menus.asm b/src/home/menus.asm index c715890..6d146b2 100644 --- a/src/home/menus.asm +++ b/src/home/menus.asm @@ -10,7 +10,7 @@ InitializeCardListParameters:: ld a, e ld [wCurMenuItem], a add d - ldh [hCurMenuItem], a + ldh [hCurScrollMenuItem], a ld a, [hli] ld [wCursorXPosition], a ld a, [hli] @@ -20,7 +20,7 @@ InitializeCardListParameters:: ld a, [hli] ld [wListItemNameMaxLength], a ld a, [hli] - ld [wNumMenuItems], a + ld [wNumScrollMenuItems], a ld a, [hli] ld [wCursorTile], a ld a, [hli] @@ -46,18 +46,18 @@ HandleCardListInput:: ld d, a ld a, [wCurMenuItem] ld e, a - ldh a, [hCurMenuItem] + ldh a, [hCurScrollMenuItem] scf ret ; initializes parameters for a menu, given the 8 bytes starting at hl, ; which are loaded to the following addresses: -; wCursorXPosition, wCursorYPosition, wYDisplacementBetweenMenuItems, wNumMenuItems, +; wCursorXPosition, wCursorYPosition, wYDisplacementBetweenMenuItems, wNumScrollMenuItems, ; wCursorTile, wTileBehindCursor, wMenuFunctionPointer. ; also sets the current menu item (wCurMenuItem) to the one specified in register a. InitializeMenuParameters:: ld [wCurMenuItem], a - ldh [hCurMenuItem], a + ldh [hCurScrollMenuItem], a ld de, wCursorXPosition ld b, wMenuFunctionPointer + $2 - wCursorXPosition .loop @@ -80,7 +80,7 @@ HandleMenuInput:: or a jr z, .up_down_done ld b, a - ld a, [wNumMenuItems] + ld a, [wNumScrollMenuItems] ld c, a ld a, [wCurMenuItem] bit D_UP_F, b @@ -88,7 +88,7 @@ HandleMenuInput:: dec a bit 7, a jr z, .handle_up_or_down - ld a, [wNumMenuItems] + ld a, [wNumScrollMenuItems] dec a ; wrapping around, so load the bottommost item jr .handle_up_or_down .not_up @@ -109,7 +109,7 @@ HandleMenuInput:: ld [wCursorBlinkCounter], a .up_down_done ld a, [wCurMenuItem] - ldh [hCurMenuItem], a + ldh [hCurScrollMenuItem], a ld hl, wMenuFunctionPointer ; call the function if non-0 (periodically) ld a, [hli] or [hl] @@ -117,7 +117,7 @@ HandleMenuInput:: ld a, [hld] ld l, [hl] ld h, a - ldh a, [hCurMenuItem] + ldh a, [hCurScrollMenuItem] call CallHL jr nc, RefreshMenuCursor_CheckPlaySFX .A_pressed_draw_cursor @@ -126,7 +126,7 @@ HandleMenuInput:: call PlayOpenOrExitScreenSFX ld a, [wCurMenuItem] ld e, a - ldh a, [hCurMenuItem] + ldh a, [hCurScrollMenuItem] scf ret .check_A_or_B @@ -139,16 +139,16 @@ HandleMenuInput:: ld a, [wCurMenuItem] ld e, a ld a, $ff - ldh [hCurMenuItem], a + ldh [hCurScrollMenuItem], a call PlayOpenOrExitScreenSFX scf ret -; plays an "open screen" sound (SFX_02) if [hCurMenuItem] != 0xff -; plays an "exit screen" sound (SFX_03) if [hCurMenuItem] == 0xff +; plays an "open screen" sound (SFX_02) if [hCurScrollMenuItem] != 0xff +; plays an "exit screen" sound (SFX_03) if [hCurScrollMenuItem] == 0xff PlayOpenOrExitScreenSFX:: push af - ldh a, [hCurMenuItem] + ldh a, [hCurScrollMenuItem] inc a jr z, .play_exit_sfx ld a, SFX_02 @@ -214,10 +214,10 @@ DrawCursor2:: ld a, [wCursorTile] jr DrawCursor -; set wCurMenuItem, and hCurMenuItem to a, and zero wCursorBlinkCounter +; set wCurMenuItem, and hCurScrollMenuItem to a, and zero wCursorBlinkCounter SetMenuItem:: ld [wCurMenuItem], a - ldh [hCurMenuItem], a + ldh [hCurScrollMenuItem], a xor a ld [wCursorBlinkCounter], a ret @@ -263,7 +263,7 @@ HandleDuelMenuInput:: call .erase_cursor pop af ld [wCurMenuItem], a - ldh [hCurMenuItem], a + ldh [hCurScrollMenuItem], a xor a ld [wCursorBlinkCounter], a jr .blink_cursor @@ -345,14 +345,14 @@ ReloadCardListItems:: call WriteByteToBGMap0 ld e, SYM_SPACE ld a, [wListScrollOffset] - ld hl, wNumMenuItems + ld hl, wNumScrollMenuItems add [hl] ld hl, wNumListItems cp [hl] jr nc, .cant_go_down ld e, SYM_CURSOR_D .cant_go_down - ld a, [wNumMenuItems] + ld a, [wNumScrollMenuItems] add a add c dec a @@ -364,7 +364,7 @@ ReloadCardListItems:: ld d, $00 ld hl, wDuelTempList add hl, de - ld a, [wNumMenuItems] + ld a, [wNumScrollMenuItems] ld b, a ld a, [wListItemXPosition] ld d, a @@ -404,10 +404,10 @@ ReloadCardListItems:: ; reload a list of cards, except don't print their names Func_2827:: ld a, $01 - ldh [hffb0], a + ldh [hffbb], a call ReloadCardListItems xor a - ldh [hffb0], a + ldh [hffbb], a ret ; convert the number at a to TX_SYMBOL text format and write it to wDefaultText @@ -429,7 +429,7 @@ OneByteNumberToTxSymbol_TrimLeadingZerosAndAlign:: CardListMenuFunction:: ldh a, [hDPadHeld] ld b, a - ld a, [wNumMenuItems] + ld a, [wNumScrollMenuItems] dec a ld c, a ld a, [wCurMenuItem] @@ -484,7 +484,7 @@ CardListMenuFunction:: ld a, [wListScrollOffset] or a jr z, .continue - ld hl, wNumMenuItems + ld hl, wNumScrollMenuItems sub [hl] jr c, .top_of_page_reached ld [wListScrollOffset], a @@ -496,7 +496,7 @@ CardListMenuFunction:: ld hl, wCurMenuItem add [hl] ld c, a - ld hl, wNumMenuItems + ld hl, wNumScrollMenuItems sub [hl] jr nc, .asm_28c4 add [hl] @@ -510,12 +510,12 @@ CardListMenuFunction:: .not_left bit D_RIGHT_F, b jr z, .continue - ld a, [wNumMenuItems] + ld a, [wNumScrollMenuItems] ld hl, wNumListItems cp [hl] jr nc, .continue ld a, [wListScrollOffset] - ld hl, wNumMenuItems + ld hl, wNumScrollMenuItems add [hl] ld c, a add [hl] @@ -534,7 +534,7 @@ CardListMenuFunction:: add [hl] ld c, a ld a, [wNumListItems] - ld hl, wNumMenuItems + ld hl, wNumScrollMenuItems sub [hl] ld [wListScrollOffset], a ld b, a @@ -549,13 +549,13 @@ CardListMenuFunction:: ld a, [wListScrollOffset] ld hl, wCurMenuItem add [hl] - ldh [hCurMenuItem], a + ldh [hCurScrollMenuItem], a ld a, [wCardListIndicatorYPosition] cp $ff jr z, .skip_printing_indicator ; print / ld c, a - ldh a, [hCurMenuItem] + ldh a, [hCurScrollMenuItem] inc a call OneByteNumberToTxSymbol_TrimLeadingZeros ld b, 14 @@ -577,7 +577,7 @@ CardListMenuFunction:: ld a, [hld] ld l, [hl] ld h, a - ldh a, [hCurMenuItem] + ldh a, [hCurScrollMenuItem] jp hl ; execute the function at wListFunctionPointer .no_list_function ldh a, [hKeysPressed] @@ -589,7 +589,7 @@ CardListMenuFunction:: ret .pressed_b ld a, $ff - ldh [hCurMenuItem], a + ldh [hCurScrollMenuItem], a scf ret @@ -811,7 +811,7 @@ SetCursorParametersForTextBox:: inc hl ld [hl], 0 ; wYDisplacementBetweenMenuItems inc hl - ld [hl], 1 ; wNumMenuItems + ld [hl], 1 ; wNumScrollMenuItems inc hl ld [hl], b ; wCursorTile inc hl @@ -1031,7 +1031,7 @@ HandleYesOrNoMenu:: jr .wait_button_loop .a_pressed ld a, [wCurMenuItem] - ldh [hCurMenuItem], a + ldh [hCurScrollMenuItem], a or a jr nz, .no ;.yes @@ -1041,7 +1041,7 @@ HandleYesOrNoMenu:: xor a ld [wDefaultYesOrNo], a ; 0 ld a, 1 - ldh [hCurMenuItem], a + ldh [hCurScrollMenuItem], a scf ret diff --git a/src/home/print_text.asm b/src/home/print_text.asm index 92ea930..50df820 100644 --- a/src/home/print_text.asm +++ b/src/home/print_text.asm @@ -500,7 +500,7 @@ Func_2c4b:: call PrintTextNoDelay_Init pop de pop hl - ldh a, [hffb0] + ldh a, [hffbb] or a ret nz ldh a, [hTextLineCurPos] diff --git a/src/home/printer.asm b/src/home/printer.asm index 5ddbb56..4876c82 100644 --- a/src/home/printer.asm +++ b/src/home/printer.asm @@ -1,57 +1,67 @@ -; serial transfer-related -SendPrinterPacket: +; send printer packet: +; - d = PRINTERPKT_* constant +; - e = in case of PRINTERPKT_DATA, whether it's compressed +; - bc = number of bytes in data +SendPrinterPacket:: push hl - ld hl, wce64 + ld hl, wPrinterPacket ; Preamble ld a, $88 - ld [hli], a ; [wce64] ← $88 + ld [hli], a ; [wPrinterPacketPreamble + 0] ← $88 ld a, $33 - ld [hli], a ; [wce65] ← $33 + ld [hli], a ; [wPrinterPacketPreamble + 1] ← $33 ; Header - ld [hl], d ; [wce66] ← d + ld [hl], d ; [wPrinterPacketInstructions + 0] ← d inc hl - ld [hl], e ; [wce67] ← e + ld [hl], e ; [wPrinterPacketInstructions + 1] ← e inc hl - ld [hl], c ; [wce68] ← c + ld [hl], c ; [wPrinterPacketDataSize + 0] ← c inc hl - ld [hl], b ; [wce69] ← b + ld [hl], b ; [wPrinterPacketDataSize + 1] ← b inc hl + ; Data pointer pop de - ld [hl], e ; [wPrinterPacketDataPtr] ← l + ld [hl], e ; [wPrinterPacketDataPtr + 0] ← l inc hl - ld [hl], d ; [wce6b] ← h + ld [hl], d ; [wPrinterPacketDataPtr + 1] ← h inc hl - ld de, $ff45 - ld [hl], e ; [wce6c] ← $45 + ld de, -$bb + ld [hl], e ; [wPrinterPacketChecksum + 0] ← $45 inc hl - ld [hl], d ; [wce6d] ← $ff + ld [hl], d ; [wPrinterPacketChecksum + 1] ← $ff + ld hl, wSerialDataPtr - ld [hl], LOW(wce64) ; [wSerialDataPtr] ← $64 + ld [hl], LOW(wPrinterPacket) ; [wSerialDataPtr] ← $64 inc hl - ld [hl], HIGH(wce64) ; [wSerialDataPtr] ← $ce + ld [hl], HIGH(wPrinterPacket) ; [wSerialDataPtr] ← $ce + call Func_0e8e + ld a, $1 - ld [wce63], a ; [wce63] ← 1 - call Func_31fc -.asm_315d + ld [wPrinterPacketSequence], a ; [wPrinterPacketSequence] ← 1 + call SendNextPrinterPacketByte +.wait_printer_packet_transmission call DoFrame - ld a, [wce63] + ld a, [wPrinterPacketSequence] or a - jr nz, .asm_315d + jr nz, .wait_printer_packet_transmission call ResetSerial ld bc, 1500 -.asm_316c +.post_transmission_delay dec bc ld a, b or c - jr nz, .asm_316c + jr nz, .post_transmission_delay - ld a, [wce6e] + ; we expect printer to send $81 + ; as the device number, any other value + ; means that a second device in connected + ld a, [wSerialTransferData] cp $81 - jr nz, .asm_3182 + jr nz, .unexpected_device_number ld a, [wPrinterStatus] ld l, a and $f1 @@ -60,46 +70,53 @@ SendPrinterPacket: scf ret -.asm_3182 +.unexpected_device_number ld a, $ff ld [wPrinterStatus], a scf ret -Func_3189: - ld hl, PointerTable_3190 +; a = which sequence to execute +ExecutePrinterPacketSequence:: + ld hl, .SequencePointers dec a jp JumpToFunctionInTable -PointerTable_3190: - dw Func_2fe7 - dw Func_2fe7 - dw Func_2fe7 - dw Func_2fe7 - dw Func_2fe7 - dw Func_31b0 - dw Func_31ca - dw Func_31dd - dw Func_31e5 - dw Func_31ef - dw Func_31ea - dw Func_31f2 +.SequencePointers: + ; each entry corresponds to value in wPrinterPacketSequence + dw .SendPreambleOrHeaderByte ; 1: send wPrinterPacketPreamble + 1 + dw .SendPreambleOrHeaderByte ; 2: send wPrinterPacketInstructions + 0 + dw .SendPreambleOrHeaderByte ; 3: send wPrinterPacketInstructions + 1 + dw .SendPreambleOrHeaderByte ; 4: send wPrinterPacketDataSize + 0 + dw .SendPreambleOrHeaderByte ; 5: send wPrinterPacketDataSize + 1 + dw .StartDataSection ; 6 + dw .SendRestOfDataSection ; 7 + dw .SendChecksumByte1 ; 8 + dw .SendChecksumByte2 ; 9 + dw .SendDummyByte ; 10 + dw .GetDeviceNumber ; 11 + dw .GetStatusAndFinishSequence ; 12 -Func_2fe7: - call Func_31fc -Func_31ab: - ld hl, wce63 +; send next byte and increment sequence +.SendPreambleOrHeaderByte: + call SendNextPrinterPacketByte +.increment_sequence + ld hl, wPrinterPacketSequence inc [hl] ret -Func_31b0: - call Func_31ab - ld hl, wce68 +; check if there is data to send +; if so, then update serial data pointer +; otherwise, skip sending data section +.StartDataSection: + call .increment_sequence + ld hl, wPrinterPacketDataSize ld a, [hli] or [hl] jr nz, .set_data_ptr - call Func_31ab - jr Func_31dd + ; no data to send + call .increment_sequence + jr .SendChecksumByte1 .set_data_ptr ld hl, wPrinterPacketDataPtr @@ -111,47 +128,60 @@ Func_31b0: ld [de], a ; fallthrough -Func_31ca: - call Func_31fc - ld hl, wce68 +; sends next byte in data section +; only increment sequence when +; there are no more bytes to send +.SendRestOfDataSection: + call SendNextPrinterPacketByte + ld hl, wPrinterPacketDataSize ld a, [hl] dec [hl] or a - jr nz, .asm_31d8 + jr nz, .finish_data_section inc hl dec [hl] dec hl -.asm_31d8 +.finish_data_section ld a, [hli] or [hl] - jr z, Func_31ab + jr z, .increment_sequence ret -Func_31dd: - ld a, [wce6c] -Func_31e0: - call Func_3212 - jr Func_31ab +; sends first byte of checksum +.SendChecksumByte1: + ld a, [wPrinterPacketChecksum + 0] +.send_byte_and_increment_sequence + call SendByteThroughSerialData + jr .increment_sequence -Func_31e5: - ld a, [wce6d] - jr Func_31e0 +; sends second byte of checksum +.SendChecksumByte2: + ld a, [wPrinterPacketChecksum + 1] + jr .send_byte_and_increment_sequence -Func_31ea: +; gets number of device, and sends a dummy byte +.GetDeviceNumber: ldh a, [rSB] - ld [wce6e], a -Func_31ef: - xor a - jr Func_31e0 + ld [wSerialTransferData], a +; fallthrough -Func_31f2: +; sends a dummy byte +.SendDummyByte: + xor a + jr .send_byte_and_increment_sequence + +; gets the printer status, then finishes sequence +.GetStatusAndFinishSequence: ldh a, [rSB] ld [wPrinterStatus], a xor a - ld [wce63], a + ld [wPrinterPacketSequence], a ret -Func_31fc: +; sends byte pointed by wSerialDataPtr to printer +; then increments this pointer to point to next byte +; for next iteration, and adds byte value to checksum +SendNextPrinterPacketByte:: ld hl, wSerialDataPtr ld e, [hl] inc hl @@ -163,7 +193,7 @@ Func_31fc: ld [hl], e ld e, a - ld hl, wce6c + ld hl, wPrinterPacketChecksum add [hl] ld [hli], a ld a, $0 @@ -172,7 +202,8 @@ Func_31fc: ld a, e ; fallthrough -Func_3212: +; a = byte to send through serial data transfer +SendByteThroughSerialData: ldh [rSB], a ld a, SC_INTERNAL ldh [rSC], a diff --git a/src/home/process_text.asm b/src/home/process_text.asm index cfb95c5..78c0941 100644 --- a/src/home/process_text.asm +++ b/src/home/process_text.asm @@ -90,7 +90,7 @@ ProcessSpecialTextCharacter:: call TerminateHalfWidthText pop af ld [wFontWidth], a - ldh a, [hffb0] + ldh a, [hffbb] or a jr nz, .skip_placing_tile ld a, [hl] @@ -146,7 +146,7 @@ SetupText:: ldh [hffa8], a call InitTextFormat xor a - ldh [hffb0], a + ldh [hffbb], a ldh [hffa9], a ld a, $88 ld [wTilePatternSelector], a @@ -206,15 +206,15 @@ InitTextPrinting:: ret ; requests a text tile to be generated and prints it in the screen -; different modes depending on hffb0: - ; hffb0 == $0: generate and place text tile - ; hffb0 == $2 (bit 1 set): only generate text tile? - ; hffb0 == $1 (bit 0 set): not even generate it, but just update text buffers? +; different modes depending on hffbb: + ; hffbb == $0: generate and place text tile + ; hffbb == $2 (bit 1 set): only generate text tile? + ; hffbb == $1 (bit 0 set): not even generate it, but just update text buffers? Func_22ca:: push hl push de push bc - ldh a, [hffb0] + ldh a, [hffbb] and $1 jr nz, .asm_22ed call Func_2325 @@ -223,7 +223,7 @@ Func_22ca:: jr nz, .done call GenerateTextTile .tile_already_exists - ldh a, [hffb0] + ldh a, [hffbb] and $2 jr nz, .done ldh a, [hffa9] diff --git a/src/home/serial.asm b/src/home/serial.asm index 9be7c93..cd2f765 100644 --- a/src/home/serial.asm +++ b/src/home/serial.asm @@ -99,12 +99,12 @@ SerialHandler: push hl push de push bc - ld a, [wce63] ; - or a ; - jr z, .asm_d35 ; if [wce63] nonzero: - call $2fc8 ; Func_3189 ; ? - jr .done ; return -.asm_d35 + ld a, [wPrinterPacketSequence] ; + or a ; + jr z, .not_printer_sequence ; if [wPrinterPacketSequence] nonzero: + call ExecutePrinterPacketSequence + jr .done ; return +.not_printer_sequence ld a, [wSerialOp] ; or a ; jr z, .asm_d55 ; skip ahead if [wSerialOp] zero diff --git a/src/home/text_box.asm b/src/home/text_box.asm index c710e10..4988399 100644 --- a/src/home/text_box.asm +++ b/src/home/text_box.asm @@ -168,7 +168,7 @@ DrawRegularTextBox:: jr z, DrawRegularTextBoxCGB ; fallthrough -DrawRegularTextBoxDMG: +DrawRegularTextBoxDMG:: call DECoordToBGMap0Address ; top line (border) of the text box ld a, SYM_BOX_TOP @@ -197,7 +197,7 @@ ContinueDrawingTextBoxDMGorSGB: ; e = value of byte b ; a = value of bytes [1, b-1] ; b is supposed to be BG_MAP_WIDTH or smaller, else the stack would get corrupted -CopyLine: +CopyLine:: add sp, -BG_MAP_WIDTH push hl push bc diff --git a/src/home/tiles.asm b/src/home/tiles.asm index a97131c..d45af6d 100644 --- a/src/home/tiles.asm +++ b/src/home/tiles.asm @@ -82,15 +82,17 @@ LoadDuelDrawCardsScreenTiles:: ld b, $08 jp CopyFontsOrDuelGraphicsTiles -Func_1da5:: +; load the face down basic / stage1 / stage2 card images shown in the check Pokemon screens +LoadDuelFaceDownCardTiles:: ld b, $10 - jr Func_1da9.asm_1dab + jr LoadDuelCheckPokemonScreenTiles.got_num_tiles -Func_1da9:: +; same as LoadDuelFaceDownCardTiles, plus also load the ACT / BPx tiles +LoadDuelCheckPokemonScreenTiles:: ld b, $24 ; fallthrough -.asm_1dab +.got_num_tiles ld hl, $4000 ld de, v0Tiles1 + $50 tiles call CopyFontsOrDuelGraphicsTiles diff --git a/src/home/unsorted.asm b/src/home/unsorted.asm index 7792221..6d62bdc 100644 --- a/src/home/unsorted.asm +++ b/src/home/unsorted.asm @@ -436,7 +436,7 @@ Func_32d8:: Func_32f6:: ldh a, [hKeysHeld] - and D_RIGHT | D_LEFT | D_UP | D_DOWN + and D_PAD jr z, .set_carry ld b, NORTH bit D_UP_F, a @@ -852,7 +852,7 @@ CallMappedFunction:: .loop_entries ld a, [hli] cp $ff - jr z, .set_carry + jr z, .not_found cp c jr nz, .next ldh a, [hBankROM] @@ -880,7 +880,7 @@ CallMappedFunction:: inc hl jr .loop_entries -.set_carry +.not_found scf ret @@ -2236,26 +2236,26 @@ Func_3c3d:: Func_3c42:: push af - call Func_3c55 - farcall $7, $5fb9 + call FinishQueuedAnimations + farcall Func_1dfb9 farcall Func_110b9 ld a, $01 - ld [$dc57], a + ld [wdc57], a pop af ret -Func_3c55:: +FinishQueuedAnimations:: push af - ld a, [$dc57] + ld a, [wdc57] and a jr z, .asm_3c60 farcall Func_110c2 .asm_3c60 xor a - ld [$dc57], a - ld [$dc5e], a - ld [$dc5f], a - farcall $7, $5fb9 + ld [wdc57], a + ld [wdc5e + 0], a + ld [wdc5e + 1], a + farcall Func_1dfb9 pop af ret @@ -2348,14 +2348,14 @@ SetNoMusic:: pop af ret -Func_3cfe:: +CallPlaySFX:: call PlaySFX ret Func_3d02:: push af xor a - call Func_3cfe + call CallPlaySFX pop af ret @@ -2603,7 +2603,11 @@ Func_3e54:: farcall Func_10d40 ret -Func_3e5d:: +; input +; a = scene ID (SCENE_* constant) +; b = base X position in tiles +; c = base Y position in tiles +EmptyScreenAndLoadScene:: push af farcall ClearSpriteAnimsAndSetInitialGraphicsConfiguration call EmptyScreen diff --git a/src/home/vram.asm b/src/home/vram.asm index 1d16160..0d64b57 100644 --- a/src/home/vram.asm +++ b/src/home/vram.asm @@ -1,5 +1,5 @@ ; set current dest VRAM bank to 0 -BankswitchVRAM0: +BankswitchVRAM0:: push af xor a ldh [hBankVRAM], a @@ -8,7 +8,7 @@ BankswitchVRAM0: ret ; set current dest VRAM bank to 1 -BankswitchVRAM1: +BankswitchVRAM1:: push af ld a, $1 ldh [hBankVRAM], a diff --git a/src/hram.asm b/src/hram.asm index 4e6b5e2..6d75282 100644 --- a/src/hram.asm +++ b/src/hram.asm @@ -88,7 +88,7 @@ hTemp_ffa0:: ; ffa2 ds $10 -; hffa8 through hffb0 belong to the text engine +; hffa8 through hffbb belong to the text engine hffa8:: ; ffb3 ds $1 @@ -122,9 +122,18 @@ hTextLineLength:: ; ffb9 hJapaneseSyllabary:: ; ffba ds $1 -hffb0:: ; ffbb +hffbb:: ; ffbb ds $1 ; unlike wCurMenuItem, this accounts for the scroll offset (wListScrollOffset) -hCurMenuItem:: ; ffbc +hCurScrollMenuItem:: ; ffbc + ds $1 + +hCurMenuItem:: ; ffbd + ds $1 + +hffbe:: ; ffbe + ds $1 + +hffbf:: ; ffbf ds $1 diff --git a/src/layout.link b/src/layout.link index 7281106..0ba4379 100644 --- a/src/layout.link +++ b/src/layout.link @@ -48,6 +48,8 @@ ROMX $09 "Bank 9" ROMX $0c "Bank c" +ROMX $0e + "Bank e" ROMX $0f "Bank f" ROMX $10 @@ -221,28 +223,30 @@ WRAM0 "WRAM0 Serial Transfer" org $cbda "WRAM0 Duels 2" - org $cc01 - "WRAM0 Duels 2@cc01" org $cc29 "WRAM0 Duels 2@cc29" org $cd5b "WRAM0 2" - org $cdc2 - "WRAM0 2@cdc2" WRAMX 1 "WRAM1" org $d0bf "WRAM1@d0bf" - org $d0e3 - "WRAM1@d0e3" - org $d393 - "WRAM1@d393" + org $d0e1 + "WRAM1@d0e1" + org $d380 + "WRAM1@d380" + org $d4c8 + "WRAM1@d4c8" org $d54c "WRAM1@d54c" org $dc06 "WRAM1@dc06" org $dd02 "WRAM1@dd02" +WRAMX 2 + "WRAM2" + org $d58e + "WRAM2@d58e" WRAMX 3 "WRAM3" WRAMX 7 @@ -257,3 +261,5 @@ SRAM $01 "SRAM1" SRAM $02 "SRAM2" +SRAM $03 + "SRAM3" diff --git a/src/macros/code.asm b/src/macros/code.asm index 9eb88c7..b457bdb 100644 --- a/src/macros/code.asm +++ b/src/macros/code.asm @@ -38,3 +38,12 @@ MACRO retbc push bc ret ENDM + +MACRO cp16 + ld a, d + cp HIGH(\1) + jr nz, :+ + ld a, e + cp LOW(\1) +: +ENDM diff --git a/src/macros/data.asm b/src/macros/data.asm index 8c4cda6..420748f 100644 --- a/src/macros/data.asm +++ b/src/macros/data.asm @@ -118,6 +118,17 @@ MACRO textitem tx \3 ; text ID ENDM +; cursor x / cursor y / attribute / idx-up / idx-down / idx-right / idx-left +; idx-[direction] means the index to get when the input is in the direction. +; its attribute is used for drawing a flipped cursor. +MACRO cursor_transition + db \1, \2, \3 + REPT 4 + db \4 + SHIFT + ENDR +ENDM + ; key-value pairs ; for function maps MACRO key_func diff --git a/src/macros/wram.asm b/src/macros/wram.asm index 3e33a48..c8336b4 100644 --- a/src/macros/wram.asm +++ b/src/macros/wram.asm @@ -4,7 +4,7 @@ MACRO card_data_struct \1Name:: ds 2 \1Rarity:: ds 1 \1Set:: ds 1 - ds 1 ; ??? +\1Unk07:: ds 1 ; ??? \1ID:: ds 2 \1EffectCommands:: ; ds 2 \1HP:: ds 1 @@ -18,11 +18,12 @@ MACRO card_data_struct \1Resistance:: ds 1 \1Category:: ds 2 \1PokedexNumber:: ds 1 -\1Unknown1:: ds 1 +\1Unk3a:: ds 1 \1Level:: ds 1 -\1Length:: ds 2 +\1Length:: ds 1 \1Weight:: ds 2 \1Description:: ds 2 + ds 1 ;\1Unknown2:: ds 1 ENDM diff --git a/src/main.asm b/src/main.asm index a5e3964..829eaf4 100644 --- a/src/main.asm +++ b/src/main.asm @@ -34,6 +34,9 @@ INCLUDE "engine/gbc_only_disclaimer.asm" SECTION "Bank c", ROMX INCLUDE "engine/bank0c.asm" +SECTION "Bank e", ROMX +INCLUDE "engine/bank0e.asm" + SECTION "Bank f", ROMX INCLUDE "engine/bank0f.asm" diff --git a/src/sram.asm b/src/sram.asm index e966c4c..4eef727 100644 --- a/src/sram.asm +++ b/src/sram.asm @@ -66,7 +66,17 @@ ENDR sCurrentlySelectedDeck:: ; b7a0 ds $1 - ds $6 +s0b7a1:: ; b7a1 + ds $1 + + ds $1 + +; each bit represents whether the player has +; obtained a card from a given set +sBoosterPacksObtained:: ; b7a3 + ds $1 + + ds $3 sCardAndDeckSaveDataEnd:: @@ -93,6 +103,10 @@ s1a100:: ; a100 SECTION "SRAM2", SRAM + + +SECTION "SRAM3", SRAM + ; buffers used to temporary store gfx related data ; such as tiles or BG maps sGfxBuffer0:: ; a000 diff --git a/src/wram.asm b/src/wram.asm index d065323..f059978 100644 --- a/src/wram.asm +++ b/src/wram.asm @@ -8,7 +8,7 @@ SECTION "WRAM0", WRAM0 UNION wTempCardCollection:: ; c000 - ds $100 + ds CARD_COLLECTION_SIZE NEXTU @@ -33,8 +33,6 @@ wDecompressionSecondaryBufferStart:: ; c0ef ENDU - ds $100 - SECTION "WRAM0 Duels 1", WRAM0 wPlayerDuelVariables:: ; c200 @@ -299,6 +297,50 @@ wSerialRecvBuf:: ; cb9f wSerialEnd:: ; cbbf + ds $1 + +; When we're viewing a card's information, the page we are currently at. +; For Pokemon cards, values from $1 to $6 (two pages for attack descriptions) +; For Energy cards, it's always $9 +; For Trainer cards, $d or $e (two pages for trainer card descriptions) +; see CARDPAGE_* constants +wCardPageNumber:: ; cbc0 + ds $1 + + ds $1 + +; selects a PLAY_AREA_* slot in order to display information related to it. used by functions +; such as PrintPlayAreaCardLocation, PrintPlayAreaCardInformation and PrintPlayAreaCardHeader +wCurPlayAreaSlot:: ; cbc2 + +; X position to display the attached energies, HP bar, and Pluspower/Defender icons +; obviously different for player and opponent side. used by DrawDuelHUD. +wHUDEnergyAndHPBarsX:: ; cbc2 + ds $1 + +; current Y coordinate where some play area information is being printed at. used by functions +; such as PrintPlayAreaCardLocation, PrintPlayAreaCardInformation and PrintPlayAreaCardHeader +wCurPlayAreaY:: ; cbc3 + +; current Y coordinate where some play area information is being printed at. used by functions +; such as PrintPlayAreaCardLocation, PrintPlayAreaCardInformation and PrintPlayAreaCardHeader +wHUDEnergyAndHPBarsY:: ; cbc3 + ds $1 + + ds $6 + +; CARDPAGETYPE_PLAY_AREA or CARDPAGETYPE_NOT_PLAY_AREA +; some of the elements displayed in a card page change depending on which value +wCardPageType:: ; cbca + ds $1 + + ds $5 + +; when viewing a card page, which keys (among B_BUTTON, D_UP, and D_DOWN) will exit the page, +; either to go back to the previous menu or list, or to load the card page of the card above/below it +wCardPageExitKeys:: ; cbd0 + ds $1 + SECTION "WRAM0 Duels 2", WRAM0 wOppRNG1:: ; cbda @@ -318,7 +360,16 @@ wDuelReturnAddress:: ; cbdd wTempSerialBuf:: ; cbe2 ds $8 -SECTION "WRAM0 Duels 2@cc01", WRAM0 + ds $13 + +wcbfd:: ; cbfd + ds $1 + + ds $2 + +; current duel is a [wDuelInitialPrizes]-prize match +wDuelInitialPrizes:: ; cc00 + ds $1 wcc01:: ; cc01 ds $1 @@ -327,11 +378,16 @@ wcc01:: ; cc01 wDuelType:: ; cc02 ds $1 - ds $6 + ds $3 + +wGoopGasAttackActive:: ; cc06 + ds $1 + + ds $2 ; this holds the current opponent's deck minus 2 (that is, a *_DECK_ID constant), ; in order to account for the two unused pointers at the beginning of DeckPointers. -wOpponentDeckID:: ; cc0e +wOpponentDeckID:: ; cc09 ds $1 ds $1 @@ -353,7 +409,8 @@ wPlayerAttackingCardID:: ; cc0d wIsPracticeDuel:: ; cc0f ds $1 -wcc10:: ; cc10 +; index of special rules for this duel +wSpecialRule:: ; cc10 ds $1 ds $1 @@ -616,8 +673,6 @@ wCardPalettes:: ; cd7a wCardAttrMap:: ; cd92 ds $30 -SECTION "WRAM0 2@cdc2", WRAM0 - ; information about the text being currently processed, including font width, ; the rom bank, and the memory address of the next character to be printed. ; supports up to four nested texts (used with TX_RAM). @@ -678,39 +733,30 @@ wcde5:: ; cde5 wCoinTossScreenTextID:: ; cde7 ds $2 -wce63:: ; cde9 +; which routine in ExecutePrinterPacketSequence to run +wPrinterPacketSequence:: ; cde9 ds $1 -wce64:: ; cdea - ds $1 +wPrinterPacket:: ; cdea -wce65:: ; cdeb - ds $1 +wPrinterPacketPreamble:: + ds $2 -wce66:: ; cdec - ds $1 +wPrinterPacketInstructions:: ; cdec + ds $2 -wce67:: ; cded - ds $1 - -wce68:: ; cdee - ds $1 - -wce69:: ; cdef - ds $1 +wPrinterPacketDataSize:: ; cdee + ds $2 ; pointer to memory of data to send ; in the data packet to the printer wPrinterPacketDataPtr:: ; cdf0 ds $2 -wce6c:: ; cdf2 - ds $1 +wPrinterPacketChecksum:: ; cdf2 + ds $2 -wce6d:: ; cdf3 - ds $1 - -wce6e:: ; cdf4 +wSerialTransferData:: ; cdf4 ds $1 wPrinterStatus:: ; cdf5 @@ -721,7 +767,77 @@ wPrinterStatus:: ; cdf5 wSerialDataPtr:: ; cdf6 ds $2 - ds $55 + ds $10 + +wTempCardID_ce08:: ; ce08 + ds $2 + + ds $2 + +wce0c:: ; ce0c + ds $1 + + ds $1 + +wVBlankFunctionTrampolineBackup:: ; ce0e + ds $2 + +wTempPrinterSRAM:: ; ce10 + ds $1 + +wPrinterHorizontalOffset:: ; ce11 + ds $1 + +; the count of some card ID in the deck to be printed +wPrinterCardCount:: ; ce12 + ds $1 + +; total card count of list to be printed +wPrinterTotalCardCount:: ; ce13 + ds $2 + +wCurPrinterCardType:: ; ce15 + ds $1 + +; total card count of the current card type +; in list to be printed +wPrinterCurCardTypeCount:: ; ce16 + ds $2 + +wPrinterNumCardTypes:: ; ce18 + ds $2 + +; related to printer functions +; only written to but never read +wce98:: ; ce1a + ds $1 + +wPrinterContrastLevel:: ; ce1b + ds $1 + + ds $1 + +wPrinterNumberLineFeeds:: ; ce1d + ds $1 + +wPrintOnlyStarRarity:: ; ce1e + ds $1 + +; only used in unreferenced function Func_1a14b +; otherwise unused +wce9d:: ; ce1f + ds $1 + +wPrinterInitAttempts:: ; ce20 + ds $1 + +wce9f:: ; ce21 + ds $1 + + ds $2a + +wce4c:: ; ce4c + ds $1 wWRAMBank:: ; ce4d ds $1 @@ -766,7 +882,7 @@ wCursorYPosition:: ; d00e wYDisplacementBetweenMenuItems:: ; d00f ds $1 -wNumMenuItems:: ; d010 +wNumScrollMenuItems:: ; d010 ds $1 wCursorTile:: ; d011 @@ -828,7 +944,17 @@ wCheckMenuPlayAreaWhichDuelist:: ; d0bf wCheckMenuPlayAreaWhichLayout:: ; d0c0 ds $1 - ds $7 +wd0c1:: ; d0c1 + ds $1 + +; pointer to transition table data +wTransitionTablePtr:: ; d0c2 + ds $2 + +wd0c4:: ; d0c4 + ds $1 + + ds $3 ; number of prize cards still to be ; picked by the player @@ -842,31 +968,251 @@ wNumberOfPrizeCardsToSelect:: ; d0c8 wInPlayAreaFromSelectButton:: ; d0cf ds $1 -SECTION "WRAM1@d0e3", WRAMX +wd0d0:: ; d0d0 + ds $1 +; GLOSSARY_* constant +wGlossaryMenu:: ; d0d1 + ds $1 + +wd0d2:: ; d0d2 + ds $1 + +SECTION "WRAM1@d0e1", WRAMX + +wScrollMenuScrollOffset:: ; d0e1 + ds $1 + + ds $1 + +wScrollMenuCursorBlinkCounter:: ; d0e3 wNamingScreenCursorBlinkCounter:: ; d0e3 ds $1 +; used to temporarily store wCurCardTypeFilter +; to check whether a new filter is to be applied +wTempCardTypeFilter:: ; d0e4 + +wCurScrollMenuItem:: ; d0e4 + wNamingScreenCursorY:: ; d0e4 ds $1 - ds $4 +wMenuParams:: +wMenuCursorXOffset:: ; d0e5 + ds $1 + +wMenuCursorYOffset:: ; d0e6 + ds $1 + +wMenuYSeparation:: ; d0e7 + ds $1 + +wMenuXSeparation:: ; d0e8 + ds $1 + +wNumMenuItems:: ; d0e9 wNamingScreenNumRows:: ; d0e9 ds $1 -wVisibleCursorTile:: ; d0ea +wMenuVisibleCursorTile:: ; d0ea ds $1 -wInvisibleCursorTile:: ; d0eb +wMenuInvisibleCursorTile:: ; d0eb ds $1 -SECTION "WRAM1@d393", WRAMX +; if non-NULL, the function loaded here is called once per frame by HandleMenuInput +wMenuUpdateFunc:: ; d0ec + ds $2 -wNamingScreenInputSFX:: ; d393 +wMenuParamsEnd:: + +; number of cards that are listed +; in the current filtered list +wNumEntriesInCurFilter:: + +wBoosterPackCardListSize:: ; d0ee ds $1 - ds $3 + ds $2 + +; deck selected by the player in the Decks screen +wCurDeck:: ; d0f1 + ds $1 + + ds $4 + +; holds symbols for representing a number in decimal +; goes up in magnitude (first byte is ones place, +; second byte is tens place, etc) up to 5 digits +wDecimalDigitsSymbols:: ; d0f6 + ds $5 + +UNION + +; each of these stores the card count +; of each filter in the deck building screen +; the order follows CardTypeFilters +wCardFilterCounts:: ; d0fb + ds NUM_FILTERS + +NEXTU + +; represents which Booster Packs have been +; collected by the player in the Card Album +; - $0 is obtained +; - non-$0 is not obtained yet +wBoosterPackItems:: ; d0fb + ds NUM_CARD_SETS + +ENDU + +; buffer used to show which card IDs +; are visible in a given list +wVisibleListCardIDs:: ; d104 + ds $e + +; number of visible entries +; when showing a list of cards +wNumVisibleCardListEntries:: ; d112 + ds $1 + +wTotalCardCount:: ; d113 + ds $1 + +; is TRUE if list cannot be scrolled down +; past the last visible entry +wUnableToScrollDown:: ; d114 + ds $1 + +wScrollMenuScrollFunc:: ; d115 + ds $2 + +; holds y and x coordinates (in that order) +; of start of card list (top-left corner) +wCardListCoords:: ; d117 + ds $2 + +wd119:: ; d119 + ds $1 + +; the current filter being used +; from the CardTypeFilters list +wCurCardTypeFilter:: ; d11a + ds $1 + +; temporarily stores wCurMenuItem value +wTempCurMenuItem:: ; d11b + ds $1 + + ds $2 + +wced7:: ; d11e + ds $1 + + ds $1 + +; stores how many different cards there are in a deck +wNumUniqueCards:: ; d120 + ds $1 + +wd121:: ; d121 + ds $1 + +; cards that belong to a Booster Pack +; for showing in the Card Album +wBoosterPackCardList:: ; d122 + +; temporary card list for multiple purposes +wTempCardList:: ; d122 + ds 2 * 80 + + ds $2 + +; holds cards for the current deck +wCurDeckCards:: ; d1c4 + ds $a2 + +; list of all the different cards in a deck configuration +wUniqueDeckCardList:: ; d266 + +; stores the count number of cards owned +; can be 0 in the case that a card is not available +; i.e. already inside a built deck +wOwnedCardsCountList:: + +wBoosterPackCardCounts:: ; d266 + ds $51 + + ds $29 + +; name of the selected deck +wCurDeckName:: ; d2e0 + +wBoosterPackCardListPrefixBuffer:: ; d2e0 + ds DECK_NAME_SIZE + + ds $6 + +wTempSavedDeckCards:: ; d2fe + ds 2 * DECK_SIZE + +SECTION "WRAM1@d380", WRAMX + +; max number of cards that are allowed +; to include when building a deck configuration +wMaxNumCardsAllowed:: ; d380 + ds $1 + +wd381:: ; d381 + ds $1 + +; max number of cards with same name that are allowed +; to be included when building a deck configuration +wSameNameCardsLimit:: ; d382 + ds $1 + + ds $5 + +wCurCardListPtr:: ; d388 + ds $1 + + ds $5 + +; the tile to draw in place of the cursor, in case +; the cursor is not to be drawn +wCursorAlternateTile:: ; d38e + ds $1 + +wTempScrollMenuNumVisibleItems:: ; d38f + ds $1 + +; which Booster Pack was selected +; in the Card Album menu +wCardAlbumBoosterPack:: ; d390 + ds $1 + +wBoosterPackCardListNumItems:: ; d391 + ds $1 + + +wOwnedPhantomCards:: ; d392 + ds $1 + +; value containing a SFX to play +; due to a menu input +wMenuInputSFX:: ; d393 + ds $1 + +wSelectedPrinterMenuItem:: ; d394 + ds $1 + +wFirstOwnedCardIndex:: ; d395 + ds $1 + +wNumCardListEntries:: ; d396 + ds $1 wNamingScreenBuffer:: ; d397 ds NAMING_SCREEN_BUFFER_LENGTH @@ -903,6 +1249,53 @@ wNamingScreenMode:: ; d3eb wd3ef:: ; d3ef ds $1 + ds $26 + +; pointers to all decks of current deck machine +wMachineDeckPtrs:: ; d416 + ds 2 * NUM_DECK_SAVE_MACHINE_SLOTS + +wNumSavedDecks:: ; d47a + ds $1 + +wTempScrollMenuItem:: ; d47b + ds $1 + +wTempScrollMenuScrollOffset:: ; d47c + ds $1 + +; which list entry was selected in the Deck Machine screen +wSelectedDeckMachineEntry:: ; d47d + ds $1 + + ds $19 + +wDeckMachineTitleText:: ; d497 + ds $2 + +wNumDeckMachineEntries:: ; d499 + ds $1 + + ds $1 + +wd49b:: ; d49b + ds $1 + +; text ID to print in the text box when +; inside the Deck Machine menu +wDeckMachineText:: ; d49c + ds $2 + +wd49e:: ; d49e + ds $1 + +wd49f:: ; d49f + ds $1 + +SECTION "WRAM1@d4c8", WRAMX + +wd4c8:: ; d4c8 + ds $80 SECTION "WRAM1@d54c", WRAMX @@ -1355,7 +1748,7 @@ wTextBoxFrameColor:: ; d9d6 ds $5 -wd9dc:: ; d9dc +wPCMenuCursorPosition:: ; d9dc ds $1 ; $0 = no fading @@ -1800,6 +2193,16 @@ wde64:: ; de64 wde69:: ; de69 ds $2 +SECTION "WRAM2", WRAMX + +wScratchCardCollection:: ; d000 + ds CARD_COLLECTION_SIZE + +SECTION "WRAM2@d58e", WRAMX + +w2d58e:: ; d58e + ds $80 + SECTION "WRAM3", WRAMX w3d000:: ; d000 @@ -1810,14 +2213,18 @@ w3d000:: ; d000 w3d400:: ; d400 ds $1 +; pointers to BG map w3d401:: ; d401 - ds $1 - - ds $13 + ds 2 * 10 w3d415:: ; d415 ds $1 + ds $b0 + +w3d4c6:: ; d4c6 + ds $415 + SECTION "WRAM7 Audio", WRAMX wSVBKBackup:: ; d000 From a02c032e5942b7a4311f3e7c319fb679ff74e0df Mon Sep 17 00:00:00 2001 From: ElectroDeoxys Date: Fri, 2 Feb 2024 17:18:33 +0000 Subject: [PATCH 2/2] Label TYPE_PKMN_RAINBOW --- src/constants/card_data_constants.asm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/constants/card_data_constants.asm b/src/constants/card_data_constants.asm index e3c6f12..0b281cc 100644 --- a/src/constants/card_data_constants.asm +++ b/src/constants/card_data_constants.asm @@ -111,8 +111,8 @@ DEF TYPE_PKMN_WATER EQU WATER DEF TYPE_PKMN_FIGHTING EQU FIGHTING DEF TYPE_PKMN_PSYCHIC EQU PSYCHIC DEF TYPE_PKMN_COLORLESS EQU COLORLESS -DEF TYPE_PKMN_UNUSED EQU RAINBOW - const_def TYPE_PKMN_UNUSED + 1 - TYPE_PKMN_FIRE +DEF TYPE_PKMN_RAINBOW EQU RAINBOW + const_def TYPE_PKMN_RAINBOW + 1 - TYPE_PKMN_FIRE DEF TYPE_ENERGY EQU const_value const TYPE_ENERGY_FIRE ; $08 const TYPE_ENERGY_GRASS ; $09