summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rw-r--r--engine/events/catch_tutorial.asm81
-rw-r--r--engine/events/catch_tutorial_input.asm43
-rw-r--r--engine/events/mom_phone.asm231
-rw-r--r--engine/events/npc_trade.asm478
-rw-r--r--engine/link/mystery_gift_3.asm190
-rw-r--r--engine/link/mystery_gift_gfx.asm31
-rw-r--r--engine/menus/debug.asm1464
-rw-r--r--engine/menus/main_menu.asm4
-rw-r--r--engine/pokedex/pokedex_3.asm165
-rw-r--r--engine/pokegear/townmap_convertlinebreakcharacters.asm21
-rw-r--r--engine/printer/print_party.asm360
-rw-r--r--engine/rtc/print_hours_mins.asm76
-rw-r--r--engine/rtc/restart_clock.asm236
-rw-r--r--engine/tilesets/map_palettes.asm4
-rw-r--r--engine/tilesets/mapgroup_roofs.asm18
-rw-r--r--engine/tilesets/tileset_anims.asm753
16 files changed, 4151 insertions, 4 deletions
diff --git a/engine/events/catch_tutorial.asm b/engine/events/catch_tutorial.asm
new file mode 100644
index 00000000..5c12a02f
--- /dev/null
+++ b/engine/events/catch_tutorial.asm
@@ -0,0 +1,81 @@
+CatchTutorial::
+ ld a, [wBattleType]
+ dec a
+ ld c, a
+ ld hl, .dw
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+.dw
+ dw .DudeTutorial
+ dw .DudeTutorial
+ dw .DudeTutorial
+
+.DudeTutorial:
+; Back up your name to your Mom's name.
+ ld hl, wPlayerName
+ ld de, wMomsName
+ ld bc, NAME_LENGTH
+ call CopyBytes
+; Copy Dude's name to your name
+ ld hl, .Dude
+ ld de, wPlayerName
+ ld bc, NAME_LENGTH
+ call CopyBytes
+
+ call .LoadDudeData
+
+ xor a
+ ldh [hJoyDown], a
+ ldh [hJoyPressed], a
+ ld a, [wOptions]
+ push af
+ and $ff ^ TEXT_DELAY_MASK
+ add TEXT_DELAY_MED
+ ld [wOptions], a
+ ld hl, .AutoInput
+ ld a, BANK(.AutoInput)
+ call StartAutoInput
+ callfar StartBattle
+ call StopAutoInput
+ pop af
+
+ ld [wOptions], a
+ ld hl, wMomsName
+ ld de, wPlayerName
+ ld bc, NAME_LENGTH
+ call CopyBytes
+ ret
+
+.LoadDudeData:
+ ld hl, wDudeNumItems
+ ld [hl], 1
+ inc hl
+ ld [hl], POTION
+ inc hl
+ ld [hl], 1
+ inc hl
+ ld [hl], -1
+ ld hl, wDudeNumKeyItems
+ ld [hl], 0
+ inc hl
+ ld [hl], -1
+ ld hl, wDudeNumBalls
+ ld a, 1
+ ld [hli], a
+ ld a, POKE_BALL
+ ld [hli], a
+ ld [hli], a
+ ld [hl], -1
+ ret
+
+.Dude:
+ db "DUDE@"
+
+.AutoInput:
+ db NO_INPUT, $ff ; end
diff --git a/engine/events/catch_tutorial_input.asm b/engine/events/catch_tutorial_input.asm
new file mode 100644
index 00000000..cca2db2d
--- /dev/null
+++ b/engine/events/catch_tutorial_input.asm
@@ -0,0 +1,43 @@
+_DudeAutoInput_A::
+ ld hl, DudeAutoInput_A
+ jr _DudeAutoInput
+
+_DudeAutoInput_RightA:
+ ld hl, DudeAutoInput_RightA
+ jr _DudeAutoInput
+
+_DudeAutoInput_DownA:
+ ld hl, DudeAutoInput_DownA
+ jr _DudeAutoInput
+
+_DudeAutoInput:
+ ld a, BANK(DudeAutoInputs)
+ call StartAutoInput
+ ret
+
+DudeAutoInputs: ; used only for BANK(DudeAutoInputs)
+
+DudeAutoInput_A:
+ db NO_INPUT, $50
+ db A_BUTTON, $00
+ db NO_INPUT, $ff ; end
+
+DudeAutoInput_RightA:
+ db NO_INPUT, $08
+ db D_RIGHT, $00
+ db NO_INPUT, $08
+ db A_BUTTON, $00
+ db NO_INPUT, $ff ; end
+
+DudeAutoInput_DownA:
+ db NO_INPUT, $fe
+ db NO_INPUT, $fe
+ db NO_INPUT, $fe
+ db NO_INPUT, $fe
+ db D_DOWN, $00
+ db NO_INPUT, $fe
+ db NO_INPUT, $fe
+ db NO_INPUT, $fe
+ db NO_INPUT, $fe
+ db A_BUTTON, $00
+ db NO_INPUT, $ff ; end
diff --git a/engine/events/mom_phone.asm b/engine/events/mom_phone.asm
new file mode 100644
index 00000000..cbd91327
--- /dev/null
+++ b/engine/events/mom_phone.asm
@@ -0,0 +1,231 @@
+NUM_MOM_ITEMS_1 EQUS "((MomItems_1.End - MomItems_1) / 8)"
+NUM_MOM_ITEMS_2 EQUS "((MomItems_2.End - MomItems_2) / 8)"
+
+ const_def 1
+ const MOM_ITEM
+ const MOM_DOLL
+
+MomTriesToBuySomething::
+ ld a, [wMapReentryScriptQueueFlag]
+ and a
+ ret nz
+ call GetMapPhoneService
+ and a
+ ret nz
+ xor a
+ ld [wWhichMomItemSet], a
+ call CheckBalance_MomItem2
+ ret nc
+ call Mom_GiveItemOrDoll
+ ret nc
+ ld b, BANK(.Script)
+ ld de, .Script
+ farcall LoadScriptBDE
+ scf
+ ret
+
+.Script:
+ callasm .ASMFunction
+ farsjump Script_ReceivePhoneCall
+
+.ASMFunction:
+ call MomBuysItem_DeductFunds
+ call Mom_GetScriptPointer
+ ld a, [wWhichMomItemSet]
+ and a
+ jr nz, .ok
+ ld hl, wWhichMomItem
+ inc [hl]
+.ok
+ ld a, PHONE_MOM
+ ld [wCurCaller], a
+ ld bc, wCallerContact
+ ld hl, PHONE_CONTACT_TRAINER_CLASS
+ add hl, bc
+ ld [hl], TRAINER_NONE
+ inc hl
+ ld [hl], PHONE_MOM
+ ld hl, PHONE_CONTACT_SCRIPT2_BANK
+ add hl, bc
+ ld a, BANK(Mom_GetScriptPointer)
+ ld [hli], a
+ ld a, e
+ ld [hli], a
+ ld a, d
+ ld [hl], a
+ ret
+
+CheckBalance_MomItem2:
+ ld a, [wWhichMomItem]
+ cp NUM_MOM_ITEMS_2
+ jr nc, .nope
+ call GetItemFromMom
+ ld a, [hli]
+ ldh [hMoneyTemp], a
+ ld a, [hli]
+ ldh [hMoneyTemp + 1], a
+ ld a, [hli]
+ ldh [hMoneyTemp + 2], a
+ ld de, wMomsMoney
+ ld bc, hMoneyTemp
+ farcall CompareMoney
+ jr nc, .have_enough_money
+
+.nope
+ jr .check_have_2300
+
+.have_enough_money
+ scf
+ ret
+
+.check_have_2300
+ ld hl, hMoneyTemp
+ ld [hl], HIGH(MOM_MONEY >> 8)
+ inc hl
+ ld [hl], HIGH(MOM_MONEY) ; mid
+ inc hl
+ ld [hl], LOW(MOM_MONEY)
+.loop
+ ld de, wMomItemTriggerBalance
+ ld bc, wMomsMoney
+ farcall CompareMoney
+ jr z, .exact
+ jr nc, .less_than
+ call .AddMoney
+ jr .loop
+
+.less_than
+ xor a
+ ret
+
+.exact
+ call .AddMoney
+ ld a, NUM_MOM_ITEMS_1
+ call RandomRange
+ inc a
+ ld [wWhichMomItemSet], a
+ scf
+ ret
+
+.AddMoney:
+ ld de, wMomItemTriggerBalance
+ ld bc, hMoneyTemp
+ farcall AddMoney
+ ret
+
+MomBuysItem_DeductFunds:
+ call GetItemFromMom
+ ld de, 3 ; cost
+ add hl, de
+ ld a, [hli]
+ ldh [hMoneyTemp], a
+ ld a, [hli]
+ ldh [hMoneyTemp + 1], a
+ ld a, [hli]
+ ldh [hMoneyTemp + 2], a
+ ld de, wMomsMoney
+ ld bc, hMoneyTemp
+ farcall TakeMoney
+ ret
+
+Mom_GiveItemOrDoll:
+ call GetItemFromMom
+ ld de, 6 ; item type
+ add hl, de
+ ld a, [hli]
+ cp MOM_ITEM
+ jr z, .not_doll
+ ld a, [hl]
+ ld c, a
+ ld b, 1
+ farcall DecorationFlagAction_c
+ scf
+ ret
+
+.not_doll
+ ld a, [hl]
+ ld [wCurItem], a
+ ld a, 1
+ ld [wItemQuantityChangeBuffer], a
+ ld hl, wNumPCItems
+ call ReceiveItem
+ ret
+
+Mom_GetScriptPointer:
+ call GetItemFromMom
+ ld de, 6 ; item type
+ add hl, de
+ ld a, [hli]
+ ld de, .ItemScript
+ cp MOM_ITEM
+ ret z
+ ld de, .DollScript
+ ret
+
+.ItemScript:
+ writetext MomHiHowAreYouText
+ writetext MomFoundAnItemText
+ writetext MomBoughtWithYourMoneyText
+ writetext MomItsInPCText
+ end
+
+.DollScript:
+ writetext MomHiHowAreYouText
+ writetext MomFoundADollText
+ writetext MomBoughtWithYourMoneyText
+ writetext MomItsInYourRoomText
+ end
+
+GetItemFromMom:
+ ld a, [wWhichMomItemSet]
+ and a
+ jr z, .zero
+ dec a
+ ld de, MomItems_1
+ jr .GetFromList1
+
+.zero
+ ld a, [wWhichMomItem]
+ cp NUM_MOM_ITEMS_2
+ jr c, .ok
+ xor a
+
+.ok
+ ld de, MomItems_2
+
+.GetFromList1:
+ ld l, a
+ ld h, 0
+rept 3 ; multiply hl by 8
+ add hl, hl
+endr
+ add hl, de
+ ret
+
+INCLUDE "data/items/mom_phone.asm"
+
+ db 0, 0, 0 ; unused
+
+MomHiHowAreYouText:
+ text_far _MomHiHowAreYouText
+ text_end
+
+MomFoundAnItemText:
+ text_far _MomFoundAnItemText
+ text_end
+
+MomBoughtWithYourMoneyText:
+ text_far _MomBoughtWithYourMoneyText
+ text_end
+
+MomItsInPCText:
+ text_far _MomItsInPCText
+ text_end
+
+MomFoundADollText:
+ text_far _MomFoundADollText
+ text_end
+
+MomItsInYourRoomText:
+ text_far _MomItsInYourRoomText
+ text_end
diff --git a/engine/events/npc_trade.asm b/engine/events/npc_trade.asm
new file mode 100644
index 00000000..ce8a64d6
--- /dev/null
+++ b/engine/events/npc_trade.asm
@@ -0,0 +1,478 @@
+NPCTrade::
+ ld a, e
+ ld [wJumptableIndex], a
+ call Trade_GetDialog
+ ld b, CHECK_FLAG
+ call TradeFlagAction
+ ld a, TRADE_DIALOG_AFTER
+ jr nz, .done
+
+ ld a, TRADE_DIALOG_INTRO
+ call PrintTradeText
+
+ call YesNoBox
+ ld a, TRADE_DIALOG_CANCEL
+ jr c, .done
+
+; Select givemon from party
+ ld b, PARTYMENUACTION_GIVE_MON
+ farcall SelectTradeOrDayCareMon
+ ld a, TRADE_DIALOG_CANCEL
+ jr c, .done
+
+ ld e, NPCTRADE_GIVEMON
+ call GetTradeAttribute
+ ld a, [wCurPartySpecies]
+ cp [hl]
+ ld a, TRADE_DIALOG_WRONG
+ jr nz, .done
+
+ call CheckTradeGender
+ ld a, TRADE_DIALOG_WRONG
+ jr c, .done
+
+ ld b, SET_FLAG
+ call TradeFlagAction
+
+ ld hl, NPCTradeCableText
+ call PrintText
+
+ call DoNPCTrade
+ call .TradeAnimation
+ call GetTradeMonNames
+
+ ld hl, TradedForText
+ call PrintText
+
+ call RestartMapMusic
+
+ ld a, TRADE_DIALOG_COMPLETE
+
+.done
+ call PrintTradeText
+ ret
+
+.TradeAnimation:
+ call DisableSpriteUpdates
+ ld a, [wJumptableIndex]
+ push af
+ ld a, [wce64]
+ push af
+ predef TradeAnimation
+ pop af
+ ld [wce64], a
+ pop af
+ ld [wJumptableIndex], a
+ call ReturnToMapWithSpeechTextbox
+ ret
+
+CheckTradeGender:
+ xor a
+ ld [wMonType], a
+
+ ld e, NPCTRADE_GENDER
+ call GetTradeAttribute
+ ld a, [hl]
+ and a ; TRADE_GENDER_EITHER
+ jr z, .matching
+ cp TRADE_GENDER_MALE
+ jr z, .check_male
+ ; TRADE_GENDER_FEMALE
+ farcall GetGender
+ jr nz, .not_matching
+ jr .matching
+
+.check_male
+ farcall GetGender
+ jr z, .not_matching
+
+.matching
+ and a
+ ret
+
+.not_matching
+ scf
+ ret
+
+TradeFlagAction:
+ ld hl, wTradeFlags
+ ld a, [wJumptableIndex]
+ ld c, a
+ predef SmallFarFlagAction
+ ld a, c
+ and a
+ ret
+
+Trade_GetDialog:
+ ld e, NPCTRADE_DIALOG
+ call GetTradeAttribute
+ ld a, [hl]
+ ld [wce64], a
+ ret
+
+DoNPCTrade:
+ ld e, NPCTRADE_GIVEMON
+ call GetTradeAttribute
+ ld a, [hl]
+ ld [wPlayerTrademonSpecies], a
+
+ ld e, NPCTRADE_GETMON
+ call GetTradeAttribute
+ ld a, [hl]
+ ld [wOTTrademonSpecies], a
+
+ ld a, [wPlayerTrademonSpecies]
+ ld de, wPlayerTrademonSpeciesName
+ call GetTradeMonName
+ call CopyTradeName
+
+ ld a, [wOTTrademonSpecies]
+ ld de, wOTTrademonSpeciesName
+ call GetTradeMonName
+ call CopyTradeName
+
+ ld hl, wPartyMonOT
+ ld bc, NAME_LENGTH
+ call Trade_GetAttributeOfCurrentPartymon
+ ld de, wPlayerTrademonOTName
+ call CopyTradeName
+
+ ld hl, wPlayerName
+ ld de, wPlayerTrademonSenderName
+ call CopyTradeName
+
+ ld hl, wPartyMon1ID
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call Trade_GetAttributeOfCurrentPartymon
+ ld de, wPlayerTrademonID
+ call Trade_CopyTwoBytes
+
+ ld hl, wPartyMon1DVs
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call Trade_GetAttributeOfCurrentPartymon
+ ld de, wPlayerTrademonDVs
+ call Trade_CopyTwoBytes
+
+ ld hl, wPartyMon1Level
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call Trade_GetAttributeOfCurrentPartymon
+ ld a, [hl]
+ ld [wCurPartyLevel], a
+ ld a, [wOTTrademonSpecies]
+ ld [wCurPartySpecies], a
+ xor a
+ ld [wMonType], a ; PARTYMON
+ ld [wPokemonWithdrawDepositParameter], a ; REMOVE_PARTY
+ callfar RemoveMonFromPartyOrBox
+ predef TryAddMonToParty
+
+ ld e, NPCTRADE_NICK
+ call GetTradeAttribute
+ ld de, wOTTrademonNickname
+ call CopyTradeName
+
+ ld hl, wPartyMonNicknames
+ ld bc, MON_NAME_LENGTH
+ call Trade_GetAttributeOfLastPartymon
+ ld hl, wOTTrademonNickname
+ call CopyTradeName
+
+ ld e, NPCTRADE_OT_NAME
+ call GetTradeAttribute
+ push hl
+ ld de, wOTTrademonOTName
+ call CopyTradeName
+ pop hl
+ ld de, wOTTrademonSenderName
+ call CopyTradeName
+
+ ld hl, wPartyMonOT
+ ld bc, NAME_LENGTH
+ call Trade_GetAttributeOfLastPartymon
+ ld hl, wOTTrademonOTName
+ call CopyTradeName
+
+ ld e, NPCTRADE_DVS
+ call GetTradeAttribute
+ ld de, wOTTrademonDVs
+ call Trade_CopyTwoBytes
+
+ ld hl, wPartyMon1DVs
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call Trade_GetAttributeOfLastPartymon
+ ld hl, wOTTrademonDVs
+ call Trade_CopyTwoBytes
+
+ ld e, NPCTRADE_OT_ID
+ call GetTradeAttribute
+ ld de, wOTTrademonID + 1
+ call Trade_CopyTwoBytesReverseEndian
+
+ ld hl, wPartyMon1ID
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call Trade_GetAttributeOfLastPartymon
+ ld hl, wOTTrademonID
+ call Trade_CopyTwoBytes
+
+ ld e, NPCTRADE_ITEM
+ call GetTradeAttribute
+ push hl
+ ld hl, wPartyMon1Item
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call Trade_GetAttributeOfLastPartymon
+ pop hl
+ ld a, [hl]
+ ld [de], a
+
+ push af
+ push bc
+ push de
+ push hl
+ ld a, [wCurPartyMon]
+ push af
+ ld a, [wPartyCount]
+ dec a
+ ld [wCurPartyMon], a
+ farcall ComputeNPCTrademonStats
+ pop af
+ ld [wCurPartyMon], a
+ pop hl
+ pop de
+ pop bc
+ pop af
+ ret
+
+GetTradeAttribute:
+ ld d, 0
+ push de
+ ld a, [wJumptableIndex]
+ and $f
+ swap a
+ ld e, a
+ ld d, 0
+ ld hl, NPCTrades
+ add hl, de
+ add hl, de
+ pop de
+ add hl, de
+ ret
+
+Trade_GetAttributeOfCurrentPartymon:
+ ld a, [wCurPartyMon]
+ call AddNTimes
+ ret
+
+Trade_GetAttributeOfLastPartymon:
+ ld a, [wPartyCount]
+ dec a
+ call AddNTimes
+ ld e, l
+ ld d, h
+ ret
+
+GetTradeMonName:
+ push de
+ ld [wNamedObjectIndexBuffer], a
+ call GetBasePokemonName
+ ld hl, wStringBuffer1
+ pop de
+ ret
+
+CopyTradeName:
+ ld bc, NAME_LENGTH
+ call CopyBytes
+ ret
+
+Unreferenced_Functionfcdfb:
+ ld bc, 4
+ call CopyBytes
+ ld a, "@"
+ ld [de], a
+ ret
+
+Unreferenced_Functionfce05:
+ ld bc, 3
+ call CopyBytes
+ ld a, "@"
+ ld [de], a
+ ret
+
+Trade_CopyTwoBytes:
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ ret
+
+Trade_CopyTwoBytesReverseEndian:
+ ld a, [hli]
+ ld [de], a
+ dec de
+ ld a, [hl]
+ ld [de], a
+ ret
+
+GetTradeMonNames:
+ ld e, NPCTRADE_GETMON
+ call GetTradeAttribute
+ ld a, [hl]
+ call GetTradeMonName
+
+ ld de, wStringBuffer2
+ call CopyTradeName
+
+ ld e, NPCTRADE_GIVEMON
+ call GetTradeAttribute
+ ld a, [hl]
+ call GetTradeMonName
+
+ ld de, wMonOrItemNameBuffer
+ call CopyTradeName
+
+ ld hl, wStringBuffer1
+.loop
+ ld a, [hli]
+ cp "@"
+ jr nz, .loop
+
+ dec hl
+ push hl
+ ld e, NPCTRADE_GENDER
+ call GetTradeAttribute
+ ld a, [hl]
+ pop hl
+ and a ; TRADE_GENDER_EITHER
+ ret z
+ cp TRADE_GENDER_MALE
+ ld a, "♂"
+ jr z, .done
+ ; TRADE_GENDER_FEMALE
+ ld a, "♀"
+.done
+ ld [hli], a
+ ld [hl], "@"
+ ret
+
+INCLUDE "data/events/npc_trades.asm"
+
+PrintTradeText:
+ push af
+ call GetTradeMonNames
+ pop af
+ ld e, a
+ ld d, 0
+ ld hl, TradeTexts
+rept 6
+ add hl, de
+endr
+ ld a, [wce64]
+ ld e, a
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call PrintText
+ ret
+
+TradeTexts:
+; entries correspond to TRADE_DIALOG_* × TRADE_DIALOGSET_* constants
+; TRADE_DIALOG_INTRO
+ dw NPCTradeIntroText1
+ dw NPCTradeIntroText2
+ dw NPCTradeIntroText3
+; TRADE_DIALOG_CANCEL
+ dw NPCTradeCancelText1
+ dw NPCTradeCancelText2
+ dw NPCTradeCancelText3
+; TRADE_DIALOG_WRONG
+ dw NPCTradeWrongText1
+ dw NPCTradeWrongText2
+ dw NPCTradeWrongText3
+; TRADE_DIALOG_COMPLETE
+ dw NPCTradeCompleteText1
+ dw NPCTradeCompleteText2
+ dw NPCTradeCompleteText3
+; TRADE_DIALOG_AFTER
+ dw NPCTradeAfterText1
+ dw NPCTradeAfterText2
+ dw NPCTradeAfterText3
+
+NPCTradeCableText:
+ text_far _NPCTradeCableText
+ text_end
+
+TradedForText:
+ ; traded givemon for getmon
+ text_far Text_NPCTraded
+ text_asm
+ ld de, MUSIC_NONE
+ call PlayMusic
+ call DelayFrame
+ ld hl, .done
+ ret
+
+.done
+ text_far _NPCTradeFanfareText
+ text_end
+
+NPCTradeIntroText1:
+ text_far _NPCTradeIntroText1
+ text_end
+
+NPCTradeCancelText1:
+ text_far _NPCTradeCancelText1
+ text_end
+
+NPCTradeWrongText1:
+ text_far _NPCTradeWrongText1
+ text_end
+
+NPCTradeCompleteText1:
+ text_far _NPCTradeCompleteText1
+ text_end
+
+NPCTradeAfterText1:
+ text_far _NPCTradeAfterText1
+ text_end
+
+NPCTradeIntroText2:
+ text_far _NPCTradeIntroText2
+ text_end
+
+NPCTradeCancelText2:
+ text_far _NPCTradeCancelText2
+ text_end
+
+NPCTradeWrongText2:
+ text_far _NPCTradeWrongText2
+ text_end
+
+NPCTradeCompleteText2:
+ text_far _NPCTradeCompleteText2
+ text_end
+
+NPCTradeAfterText2:
+ text_far _NPCTradeAfterText2
+ text_end
+
+NPCTradeIntroText3:
+ text_far _NPCTradeIntroText3
+ text_end
+
+NPCTradeCancelText3:
+ text_far _NPCTradeCancelText3
+ text_end
+
+NPCTradeWrongText3:
+ text_far _NPCTradeWrongText3
+ text_end
+
+NPCTradeCompleteText3:
+ text_far _NPCTradeCompleteText3
+ text_end
+
+NPCTradeAfterText3:
+ text_far _NPCTradeAfterText3
+ text_end
diff --git a/engine/link/mystery_gift_3.asm b/engine/link/mystery_gift_3.asm
new file mode 100644
index 00000000..bc12d9c8
--- /dev/null
+++ b/engine/link/mystery_gift_3.asm
@@ -0,0 +1,190 @@
+StagePartyDataForMysteryGift:
+; You will be sending this data to your mystery gift partner.
+; Structure is the same as a trainer with species and moves
+; defined.
+ ld a, BANK(sPokemonData)
+ call OpenSRAM
+ ld de, wMysteryGiftStaging
+ ld bc, sPokemonData + wPartyMons - wPokemonData
+ ld hl, sPokemonData + wPartySpecies - wPokemonData
+.loop
+ ld a, [hli]
+ cp -1
+ jr z, .party_end
+ cp EGG
+ jr z, .next
+ push hl
+ ; copy level
+ ld hl, MON_LEVEL
+ add hl, bc
+ ld a, [hl]
+ ld [de], a
+ inc de
+ ; copy species
+ ld hl, MON_SPECIES
+ add hl, bc
+ ld a, [hl]
+ ld [de], a
+ inc de
+ ; copy moves
+ ld hl, MON_MOVES
+ add hl, bc
+ push bc
+ ld bc, NUM_MOVES
+ call CopyBytes
+ pop bc
+ pop hl
+.next
+ push hl
+ ld hl, PARTYMON_STRUCT_LENGTH
+ add hl, bc
+ ld b, h
+ ld c, l
+ pop hl
+ jr .loop
+.party_end
+ ld a, -1
+ ld [de], a
+ ld a, $26
+ ld [wc900], a
+ jp CloseSRAM
+
+InitMysteryGiftLayout:
+ call ClearBGPalettes
+ call DisableLCD
+ ld hl, MysteryGiftGFX
+ ld de, vTiles2 tile $00
+ ld a, BANK(MysteryGiftGFX)
+ ld bc, $20 tiles
+ call FarCopyBytes
+ farcall LoadMysteryGiftBackgroundGFX
+ farcall LoadMysteryGiftGFX2
+ ld hl, vTiles2 tile $3d
+ ld a, $ff
+ ld bc, 1 tiles
+ call ByteFill
+ hlcoord 0, 0
+ ld a, $3d
+ ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
+ call ByteFill
+ hlcoord 3, 7
+ lb bc, 9, 15
+ call ClearBox
+ hlcoord 0, 0
+ ld a, $1e
+ ld [hli], a
+ inc a
+ ld [hl], a
+ hlcoord 0, 1
+ ld a, $33
+ ld [hli], a
+ inc a
+ ld [hl], a
+ hlcoord 3, 1
+ ld a, 0
+ call .Load15GFX
+ hlcoord 3, 2
+ ld a, $f
+ call .Load15GFX
+ hlcoord 8, 0
+ ld a, $20
+ call .Load4GFX
+ hlcoord 9, 3
+ ld a, $24
+ call .Load3GFX
+ hlcoord 9, 4
+ ld [hl], $27
+ hlcoord 1, 2
+ ld a, $2e
+ call .Load15Column
+ hlcoord 18, 5
+ ld a, $2a
+ call .Load11Column
+ hlcoord 2, 5
+ ld a, $28
+ call .Load16Row
+ hlcoord 2, 16
+ ld a, $2c
+ call .Load16Row
+ hlcoord 2, 5
+ ld a, $35
+ call .Load4GFX
+ hlcoord 18, 5
+ ld [hl], $29
+ hlcoord 18, 16
+ ld [hl], $2b
+ hlcoord 1, 16
+ ld [hl], $2d
+ hlcoord 2, 6
+ ld a, $39
+ call .Load16Row
+ hlcoord 2, 15
+ ld a, $3b
+ call .Load16Row
+ hlcoord 2, 6
+ ld a, $3c
+ call .Load9Column
+ hlcoord 17, 6
+ ld a, $3a
+ call .Load9Column
+ hlcoord 2, 6
+ ld [hl], $2f
+ hlcoord 17, 6
+ ld [hl], $30
+ hlcoord 2, 15
+ ld [hl], $32
+ hlcoord 17, 15
+ ld [hl], $31
+ call EnableLCD
+ call WaitBGMap
+ ld b, SCGB_MYSTERY_GIFT
+ call GetSGBLayout
+ jp SetPalettes
+
+.Load3GFX:
+ ld b, 3
+ jr .gfx_loop
+
+.Load4GFX:
+ ld b, 4
+ jr .gfx_loop
+
+.Load15GFX:
+ ld b, 15
+
+.gfx_loop
+ ld [hli], a
+ inc a
+ dec b
+ jr nz, .gfx_loop
+ ret
+
+.Load9Column:
+ ld b, 9
+ jr .col_loop
+
+.Load11Column:
+ ld b, 11
+ jr .col_loop
+
+.Load15Column:
+ ld b, 15
+
+.col_loop
+ ld [hl], a
+ ld de, SCREEN_WIDTH
+ add hl, de
+ dec b
+ jr nz, .col_loop
+ ret
+
+.Load16Row:
+ ld b, 16
+.row_loop
+ ld [hli], a
+ dec b
+ jr nz, .row_loop
+ ret
+
+MysteryGiftGFX:
+INCBIN "gfx/mystery_gift/mystery_gift.2bpp"
diff --git a/engine/link/mystery_gift_gfx.asm b/engine/link/mystery_gift_gfx.asm
new file mode 100644
index 00000000..68701add
--- /dev/null
+++ b/engine/link/mystery_gift_gfx.asm
@@ -0,0 +1,31 @@
+LoadMysteryGiftBackgroundGFX:
+ ld hl, MysteryGiftBackgroundGFX
+ ld de, vTiles2 tile $20
+ ld a, BANK(MysteryGiftBackgroundGFX)
+ ld bc, wBGMapBufferEnd - wBGMapBuffer
+ call FarCopyBytesDouble
+ ld hl, vTiles2 tile $20
+ ld bc, wBGMapBufferEnd - wBGMapBuffer
+.loop:
+ ld [hl], $ff
+ inc hl
+ inc hl
+ dec bc
+ ld a, b
+ or c
+ jr nz, .loop
+ ret
+
+LoadMysteryGiftGFX2:
+ ld hl, MysteryGiftGFX2
+ ld de, vTiles2 tile $2f
+ ld a, BANK(MysteryGiftGFX2)
+ ld bc, 14 tiles
+ jp FarCopyBytes
+
+MysteryGiftBackgroundGFX:
+INCBIN "gfx/mystery_gift/question_mark.1bpp"
+INCBIN "gfx/mystery_gift/border.1bpp"
+
+MysteryGiftGFX2:
+INCBIN "gfx/mystery_gift/mystery_gift_2.2bpp"
diff --git a/engine/menus/debug.asm b/engine/menus/debug.asm
new file mode 100644
index 00000000..b1adf7d1
--- /dev/null
+++ b/engine/menus/debug.asm
@@ -0,0 +1,1464 @@
+; Left-over debug code from pokegold-debug
+
+ const_def $6a
+ const DEBUGTEST_TICKS_1 ; $6a
+ const DEBUGTEST_TICKS_2 ; $6b
+ const DEBUGTEST_WHITE ; $6c
+ const DEBUGTEST_LIGHT ; $6d
+ const DEBUGTEST_DARK ; $6e
+ const DEBUGTEST_BLACK ; $6f
+ const DEBUGTEST_0 ; $70
+ const DEBUGTEST_1 ; $71
+ const DEBUGTEST_2 ; $72
+ const DEBUGTEST_3 ; $73
+ const DEBUGTEST_4 ; $74
+ const DEBUGTEST_5 ; $75
+ const DEBUGTEST_6 ; $76
+ const DEBUGTEST_7 ; $77
+ const DEBUGTEST_8 ; $78
+ const DEBUGTEST_9 ; $79
+ const DEBUGTEST_A ; $7a
+ const DEBUGTEST_B ; $7b
+ const DEBUGTEST_C ; $7c
+ const DEBUGTEST_D ; $7d
+ const DEBUGTEST_E ; $7e
+ const DEBUGTEST_F ; $7f
+
+DebugColorPicker:
+; A debug menu to test monster and trainer palettes at runtime.
+
+ ldh a, [hCGB]
+ and a
+ jr nz, .set
+ ldh a, [hSGB]
+ and a
+ ret z
+
+.set
+ ldh a, [hInMenu]
+ push af
+ ld a, 1
+ ldh [hInMenu], a
+ call DisableLCD
+ call DebugColor_InitVRAM
+ call DebugColor_LoadGFX
+ call DebugColor_InitPalettes
+ call DebugColor_InitMonColor
+ call EnableLCD
+ ld de, MUSIC_NONE
+ call PlayMusic
+ xor a
+ ld [wJumptableIndex], a
+ ld [wce66], a
+ ld [wceee], a
+.loop
+ ld a, [wJumptableIndex]
+ bit 7, a
+ jr nz, .exit
+ call DebugColorMain
+ call DebugColor_PlaceCursor
+ call DelayFrame
+ jr .loop
+
+.exit
+ pop af
+ ldh [hInMenu], a
+ ret
+
+DebugColor_InitMonColor:
+ ld a, [wceed]
+ and a
+ jr nz, DebugColor_InitTrainerColor
+ ld hl, PokemonPalettes
+
+DebugColor_InitMonColor2:
+ ld de, wOverworldMapBlocks
+ ld c, NUM_POKEMON + 1
+.loop
+ push bc
+ push hl
+ call DebugColor_InitColor
+ pop hl
+ ld bc, 8
+ add hl, bc
+ pop bc
+ dec c
+ jr nz, .loop
+ ret
+
+DebugColor_InitTrainerColor:
+ ld hl, TrainerPalettes
+ ld de, wOverworldMapBlocks
+ ld c, NUM_TRAINER_CLASSES
+.loop
+ push bc
+ push hl
+ call DebugColor_InitColor
+ pop hl
+ ld bc, 4
+ add hl, bc
+ pop bc
+ dec c
+ jr nz, .loop
+ ret
+
+DebugColor_InitColor:
+ ld a, BANK(PokemonPalettes) ; aka BANK(TrainerPalettes)
+ call GetFarByte
+ ld [de], a
+ inc de
+ inc hl
+
+ ld a, BANK(PokemonPalettes) ; aka BANK(TrainerPalettes)
+ call GetFarByte
+ ld [de], a
+ inc de
+ inc hl
+
+ ld a, BANK(PokemonPalettes) ; aka BANK(TrainerPalettes)
+ call GetFarByte
+ ld [de], a
+ inc de
+ inc hl
+
+ ld a, BANK(PokemonPalettes) ; aka BANK(TrainerPalettes)
+ call GetFarByte
+ ld [de], a
+ inc de
+ ret
+
+DebugColor_InitVRAM:
+ ld a, 1
+ ldh [rVBK], a
+ ld hl, vTiles0
+ ld bc, sScratch - vTiles0
+ xor a
+ call ByteFill
+
+ ld a, 0
+ ldh [rVBK], a
+ ld hl, vTiles0
+ ld bc, sScratch - vTiles0
+ xor a
+ call ByteFill
+
+ hlcoord 0, 0, wAttrmap
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ xor a
+ call ByteFill
+
+ hlcoord 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ xor a
+ call ByteFill
+
+ call ClearSprites
+ ret
+
+DebugColor_LoadGFX:
+ ld hl, DebugColor_GFX
+ ld de, vTiles2 tile DEBUGTEST_TICKS_1
+ ld bc, 22 tiles
+ call CopyBytes
+ ld hl, DebugColor_UpArrowGFX
+ ld de, vTiles0
+ ld bc, 1 tiles
+ call CopyBytes
+ call LoadStandardFont
+ ld hl, vTiles1
+ lb bc, 8, 0
+.loop
+ ld a, [hl]
+ xor $ff
+ ld [hli], a
+ dec bc
+ ld a, c
+ or b
+ jr nz, .loop
+ ret
+
+DebugColor_InitPalettes:
+ ldh a, [hCGB]
+ and a
+ ret z
+ ld hl, Palette_DebugBG
+ ld de, wBGPals2
+ ld bc, 16 palettes
+ call CopyBytes
+ ld a, 1 << rBGPI_AUTO_INCREMENT
+ ldh [rBGPI], a
+ ld hl, Palette_DebugBG
+ ld c, 8 palettes
+ xor a
+.loop1
+ ldh [rBGPD], a
+ dec c
+ jr nz, .loop1
+
+ ld a, 1 << rOBPI_AUTO_INCREMENT
+ ldh [rOBPI], a
+ ld hl, Palette_DebugOB
+ ld c, 8 palettes
+.loop2
+ ld a, [hli]
+ ldh [rOBPD], a
+ dec c
+ jr nz, .loop2
+
+ ld a, $94
+ ld [wc508], a
+ ld a, $52
+ ld [wc508 + 1], a
+ ld a, $4a
+ ld [wc508 + 2], a
+ ld a, $29
+ ld [wc508 + 3], a
+ ret
+
+Palette_DebugBG:
+INCLUDE "gfx/debug/bg.pal"
+
+Palette_DebugOB:
+INCLUDE "gfx/debug/ob.pal"
+
+DebugColorMain:
+ call JoyTextDelay
+ ld a, [wJumptableIndex]
+ cp 4
+ jr nc, .asm_fd49e
+ ld hl, hJoyLast
+ ld a, [hl]
+ and SELECT
+ jr nz, .NextMon
+ ld a, [hl]
+ and START
+ jr nz, .PreviousMon
+
+.asm_fd49e
+ ld a, [wJumptableIndex]
+ ld e, a
+ ld d, 0
+ ld hl, Jumptable_fd4e2
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+.NextMon:
+ call DebugColor_BackupSpriteColors
+ call DebugColor_SetMaxNum
+ ld e, a
+ ld a, [wce66]
+ inc a
+ cp e
+ jr c, .SwitchMon
+ xor a
+ jr .SwitchMon
+
+.PreviousMon:
+ call DebugColor_BackupSpriteColors
+ ld a, [wce66]
+ dec a
+ cp -1
+ jr nz, .SwitchMon
+ call DebugColor_SetMaxNum
+ dec a
+
+.SwitchMon:
+ ld [wce66], a
+ ld a, 0 ; ScreenInitNo
+ ld [wJumptableIndex], a
+ ret
+
+DebugColor_SetMaxNum:
+ ld a, [wceed]
+ and a
+ jr nz, .trainer
+; .mon
+ ld a, NUM_POKEMON
+ ret
+.trainer
+ ld a, NUM_TRAINER_CLASSES - 1
+ ret
+
+Jumptable_fd4e2:
+ dw DebugColor_InitScreen
+ dw Functionfd62b
+ dw Functionfd646
+ dw Functionfd6cb
+ dw Functionfd797
+ dw Functionfd7b8
+
+DebugColor_InitScreen:
+ xor a
+ ldh [hBGMapMode], a
+ hlcoord 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ ld a, DEBUGTEST_BLACK
+ call ByteFill
+ hlcoord 1, 3
+ lb bc, 7, 18
+ ld a, DEBUGTEST_WHITE
+ call DebugColor_FillBoxWithByte
+ hlcoord 11, 0
+ lb bc, 2, 3
+ ld a, DEBUGTEST_LIGHT
+ call DebugColor_FillBoxWithByte
+ hlcoord 16, 0
+ lb bc, 2, 3
+ ld a, DEBUGTEST_DARK
+ call DebugColor_FillBoxWithByte
+ call DebugColor_LoadRGBMeter
+ call DebugColor_SetRGBMeter
+ ld a, [wce66]
+ inc a
+ ld [wCurPartySpecies], a
+ ld [wDeciramBuffer], a
+ hlcoord 0, 1
+ ld de, wDeciramBuffer
+ lb bc, PRINTNUM_LEADINGZEROS | 1, 3
+ call PrintNum
+ ld a, [wceed]
+ and a
+ jr nz, .Trainer
+
+.MonSpriteViewer:
+ ld a, 1
+ ld [wUnownLetter], a
+ call GetPokemonName
+ hlcoord 4, 1
+ call PlaceString
+ xor a
+ ld [wBoxAlignment], a
+ hlcoord 2, 3
+ call _PrepMonFrontpic
+ ld de, vTiles2 tile $31
+ predef GetMonBackpic
+ ld a, $31
+ ldh [hGraphicStartTile], a
+ hlcoord 12, 4
+ lb bc, 6, 6
+ predef PlaceGraphic
+ ld a, [wceee]
+ and a
+ jr z, .load_normal_text
+
+.load_shiny_text
+ ld de, DebugColor_ShinyText
+ jr .place_switch_text
+
+.load_normal_text
+ ld de, DebugColor_NormalText
+
+.place_switch_text
+ hlcoord 7, 17
+ call PlaceString
+ hlcoord 0, 17
+ ld de, DebugColor_SwitchText
+ call PlaceString
+ jr .asm_fd5bc
+
+.Trainer:
+ ld a, [wDeciramBuffer]
+ ld [wTrainerClass], a
+ callfar GetTrainerAttributes
+ ld de, wStringBuffer1
+ hlcoord 4, 1
+ call PlaceString
+ ld de, vTiles2
+ callfar GetTrainerPic
+ xor a
+ ld [wTempEnemyMonSpecies], a
+ ldh [hGraphicStartTile], a
+ hlcoord 2, 3
+ lb bc, 7, 7
+ predef PlaceGraphic
+
+.asm_fd5bc
+ ld a, 1
+ ld [wJumptableIndex], a
+ ret
+
+DebugColor_ShinyText:
+ db "レア", DEBUGTEST_BLACK, DEBUGTEST_BLACK, "@" ; Rare (shiny)
+
+DebugColor_NormalText:
+ db "ノーマル@" ; Normal
+
+DebugColor_SwitchText:
+ db DEBUGTEST_A, "きりかえ▶@" ; Switch
+
+DebugColor_LoadRGBMeter:
+ decoord 0, 11, wAttrmap
+ hlcoord 2, 11
+ ld a, 1
+ call Functionfd5f1
+ decoord 0, 13, wAttrmap
+ hlcoord 2, 13
+ ld a, 2
+ call Functionfd5f1
+ decoord 0, 15, wAttrmap
+ hlcoord 2, 15
+ ld a, 3
+
+Functionfd5f1:
+ push af
+ ld a, DEBUGTEST_TICKS_1
+ ld [hli], a
+ ld bc, 15
+ ld a, DEBUGTEST_TICKS_2
+ call ByteFill
+ ld l, e
+ ld h, d
+ pop af
+ ld bc, 20 * 2
+ call ByteFill
+ ret
+
+DebugColor_SetRGBMeter:
+ ld a, [wce66]
+ inc a
+ ld l, a
+ ld h, 0
+ add hl, hl
+ add hl, hl
+ ld de, wOverworldMapBlocks
+ add hl, de
+ ld de, wc508
+ ld bc, 4
+ call CopyBytes
+ xor a
+ ld [wce64], a
+ ld [wce65], a
+ ld de, wc508
+ call DebugColor_CalculateRGB
+ ret
+
+Functionfd62b:
+ ldh a, [hCGB]
+ and a
+ jr z, .asm_fd63d
+ ld a, 2
+ ldh [hBGMapMode], a
+ call DelayFrame
+ call DelayFrame
+ call DelayFrame
+
+.asm_fd63d
+ call WaitBGMap
+ ld a, 2
+ ld [wJumptableIndex], a
+ ret
+
+Functionfd646:
+ ldh a, [hCGB]
+ and a
+ jr z, .sgb
+
+.cgb
+ ld hl, wBGPals2
+ ld de, wc508
+ ld c, 1
+ call Functionfd8ec
+ hlcoord 10, 2
+ ld de, wc508
+ call Functionfd6b0
+ hlcoord 15, 2
+ ld de, wc508 + 2
+ call Functionfd6b0
+ ld a, 1
+ ldh [hCGBPalUpdate], a
+ ld a, 3
+ ld [wJumptableIndex], a
+ ret
+
+.sgb
+ ld hl, wSGBPals
+ ld a, 1
+ ld [hli], a
+ ld a, LOW(PALRGB_WHITE)
+ ld [hli], a
+ ld a, HIGH(PALRGB_WHITE)
+ ld [hli], a
+ ld a, [wc508]
+ ld [hli], a
+ ld a, [wc508 + 1]
+ ld [hli], a
+ ld a, [wc508 + 2]
+ ld [hli], a
+ ld a, [wc508 + 3]
+ ld [hli], a
+ xor a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld hl, wSGBPals
+ call Functionfd915
+ hlcoord 10, 2
+ ld de, wc508
+ call Functionfd6b0
+ hlcoord 15, 2
+ ld de, wc508 + 2
+ call Functionfd6b0
+ ld a, 3
+ ld [wJumptableIndex], a
+ ret
+
+Functionfd6b0:
+ inc hl
+ inc hl
+ inc hl
+ ld a, [de]
+ call Functionfd6c5
+ ld a, [de]
+ swap a
+ call Functionfd6c5
+ inc de
+ ld a, [de]
+ call Functionfd6c5
+ ld a, [de]
+ swap a
+
+Functionfd6c5:
+ and $f
+ add DEBUGTEST_0
+ ld [hld], a
+ ret
+
+Functionfd6cb:
+ ldh a, [hJoyLast]
+ and B_BUTTON
+ jr nz, .asm_fd6e8
+ ldh a, [hJoyLast]
+ and A_BUTTON
+ jr nz, .asm_fd6ee
+ ld a, [wce64]
+ and 3
+ ld e, a
+ ld d, 0
+ ld hl, Jumptable_fd70b
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+.asm_fd6e8
+ ld a, 4
+ ld [wJumptableIndex], a
+ ret
+
+.asm_fd6ee
+ ld a, [wceed]
+ and a
+ ret nz
+ ld a, [wceee]
+ xor 4
+ ld [wceee], a
+ ld c, a
+ ld b, 0
+ ld hl, PokemonPalettes
+ add hl, bc
+ call DebugColor_InitMonColor2
+ ld a, 0
+ ld [wJumptableIndex], a
+ ret
+
+Jumptable_fd70b:
+ dw DebugColor_SelectColorBox
+ dw DebugColor_ChangeRedValue
+ dw DebugColor_ChangeGreenValue
+ dw DebugColor_ChangeBlueValue
+
+DebugColor_SelectColorBox:
+ ld hl, hJoyLast
+ ld a, [hl]
+ and D_DOWN
+ jr nz, DebugColor_NextRGBColor
+ ld a, [hl]
+ and D_LEFT
+ jr nz, .lightcolor
+ ld a, [hl]
+ and D_RIGHT
+ jr nz, .darkcolor
+ ret
+
+.lightcolor:
+ xor a
+ ld [wce65], a
+ ld de, wc508
+ call DebugColor_CalculateRGB
+ ret
+
+.darkcolor:
+ ld a, 1
+ ld [wce65], a
+ ld de, wc508 + 2
+ call DebugColor_CalculateRGB
+ ret
+
+DebugColor_ChangeRedValue:
+ ld hl, hJoyLast
+ ld a, [hl]
+ and D_DOWN
+ jr nz, DebugColor_NextRGBColor
+ ld a, [hl]
+ and D_UP
+ jr nz, DebugColor_PreviousRGBColor
+ ld hl, wc508 + 10
+ jr DebugColor_UpdateSpriteColor
+
+DebugColor_ChangeGreenValue:
+ ld hl, hJoyLast
+ ld a, [hl]
+ and D_DOWN
+ jr nz, DebugColor_NextRGBColor
+ ld a, [hl]
+ and D_UP
+ jr nz, DebugColor_PreviousRGBColor
+ ld hl, wc508 + 11
+ jr DebugColor_UpdateSpriteColor
+
+DebugColor_ChangeBlueValue:
+ ld hl, hJoyLast
+ ld a, [hl]
+ and D_UP
+ jr nz, DebugColor_PreviousRGBColor
+ ld hl, wc508 + 12
+
+DebugColor_UpdateSpriteColor:
+ ldh a, [hJoyLast]
+ and D_RIGHT
+ jr nz, .increment_color_value
+ ldh a, [hJoyLast]
+ and D_LEFT
+ jr nz, .decrement_color_value
+ ret
+
+.increment_color_value
+ ld a, [hl]
+ cp $1f
+ ret nc
+ inc [hl]
+ jr .asm_fd784
+
+.decrement_color_value
+ ld a, [hl]
+ and a
+ ret z
+ dec [hl]
+
+.asm_fd784
+ call DebugColor_CalculatePalette
+ ld a, 2
+ ld [wJumptableIndex], a
+ ret
+
+DebugColor_PreviousRGBColor:
+ ld hl, wce64
+ dec [hl]
+ ret
+
+DebugColor_NextRGBColor:
+ ld hl, wce64
+ inc [hl]
+ ret
+
+Functionfd797:
+ hlcoord 0, 10
+ ld bc, 20 * 8
+ ld a, DEBUGTEST_BLACK
+ call ByteFill
+ hlcoord 2, 12
+ ld de, String_fd9d6
+ call PlaceString
+ xor a
+ ld [wceef], a
+ call Functionfd7fd
+ ld a, 5
+ ld [wJumptableIndex], a
+ ret
+
+Functionfd7b8:
+ ld hl, hJoyPressed
+ ld a, [hl]
+ and B_BUTTON
+ jr nz, .cancel
+; ld a,(hl)
+; and A_BUTTON
+; jr nz, .exit
+ call DebugColor_TMHMJoypad
+ ret
+
+.cancel
+ ld a, 0
+ ld [wJumptableIndex], a
+ ret
+
+.exit
+ ld hl, wJumptableIndex
+ set 7, [hl]
+ ret
+
+DebugColor_TMHMJoypad:
+ ld hl, hJoyLast
+ ld a, [hl]
+ and D_UP
+ jr nz, .asm_fd7de
+ ld a, [hl]
+ and D_DOWN
+ jr nz, .asm_fd7eb
+ ret
+
+.asm_fd7de
+ ld a, [wceef]
+ cp 56
+ jr z, .asm_fd7e8
+ inc a
+ jr .asm_fd7f6
+
+.asm_fd7e8
+ xor a
+ jr .asm_fd7f6
+
+.asm_fd7eb
+ ld a, [wceef]
+ and a
+ jr z, .asm_fd7f4
+ dec a
+ jr .asm_fd7f6
+
+.asm_fd7f4
+ ld a, 56
+
+.asm_fd7f6
+ ld [wceef], a
+ call Functionfd7fd
+ ret
+
+Functionfd7fd:
+ hlcoord 10, 11
+ call Functionfd867
+ hlcoord 10, 12
+ call Functionfd867
+ hlcoord 10, 13
+ call Functionfd867
+ hlcoord 10, 14
+ call Functionfd867
+ ld a, [wceef]
+ inc a
+ ld [wTempTMHM], a
+ predef GetTMHMMove
+ ld a, [wTempTMHM]
+ ld [wPutativeTMHMMove], a
+ call GetMoveName
+ hlcoord 10, 12
+ call PlaceString
+ ld a, [wceef]
+ call Functionfd85e
+ ld [wCurItem], a
+ predef CanLearnTMHMMove
+ ld a, c
+ and a
+ ld de, DebugColor_AbleText
+ jr nz, .place_string
+ ld de, DebugColor_NotAbleText
+
+.place_string
+ hlcoord 10, 14
+ call PlaceString
+ ret
+
+DebugColor_AbleText:
+ db "おぼえられる@" ; Learnable
+
+DebugColor_NotAbleText:
+ db "おぼえられない@" ; Not learnable
+
+Functionfd85e:
+ cp NUM_TMS
+ jr c, .tm
+.hm
+ inc a
+ inc a
+.tm
+ add TM01
+ ret
+
+Functionfd867:
+ ld bc, 10
+ ld a, DEBUGTEST_BLACK
+ call ByteFill
+ ret
+
+DebugColor_CalculatePalette:
+ ld a, [wc508 + 10]
+ and %00011111
+ ld e, a
+ ld a, [wc508 + 11]
+ and %00000111
+ sla a
+ swap a
+ or e
+ ld e, a
+ ld a, [wc508 + 11]
+ and %00011000
+ sla a
+ swap a
+ ld d, a
+ ld a, [wc508 + 12]
+ and %00011111
+ sla a
+ sla a
+ or d
+ ld d, a
+ ld a, [wce65]
+ and a
+ jr z, .LightPalette
+
+.DarkPalette
+ ld a, e
+ ld [wc508 + 2], a
+ ld a, d
+ ld [wc508 + 3], a
+ ret
+
+.LightPalette
+ ld a, e
+ ld [wc508], a
+ ld a, d
+ ld [wc508 + 1], a
+ ret
+
+DebugColor_CalculateRGB:
+ ld a, [de]
+ and $1f
+ ld [wc508 + 10], a
+ ld a, [de]
+ and $e0
+ swap a
+ srl a
+ ld b, a
+ inc de
+ ld a, [de]
+ and 3
+ swap a
+ srl a
+ or b
+ ld [wc508 + 11], a
+ ld a, [de]
+ and $7c
+ srl a
+ srl a
+ ld [wc508 + 12], a
+ ret
+
+DebugColor_BackupSpriteColors:
+ ld a, [wce66]
+ inc a
+ ld l, a
+ ld h, 0
+ add hl, hl
+ add hl, hl
+ ld de, wOverworldMapBlocks ; MonPalette
+ add hl, de
+ ld e, l
+ ld d, h
+ ld hl, wc508
+ ld bc, 4
+ call CopyBytes
+ ret
+
+Functionfd8ec:
+; Set palette buffer
+.loop
+ ld a, LOW(PALRGB_WHITE)
+ ld [hli], a
+ ld a, HIGH(PALRGB_WHITE)
+ ld [hli], a
+ ld a, [de]
+ inc de
+ ld [hli], a
+ ld a, [de]
+ inc de
+ ld [hli], a
+ ld a, [de]
+ inc de
+ ld [hli], a
+ ld a, [de]
+ inc de
+ ld [hli], a
+ xor a
+ ld [hli], a
+ ld [hli], a
+ dec c
+ jr nz, .loop
+ ret
+
+DebugColor_FillBoxWithByte:
+; For some reason, we have another copy of FillBoxWithByte here
+.row
+ push bc
+ push hl
+.col
+ ld [hli], a
+ dec c
+ jr nz, .col
+ pop hl
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .row
+ ret
+
+Functionfd915:
+; SGB Related
+
+ ld a, [wd8ba]
+ push af
+ set 7, a
+ ld [wd8ba], a
+ call Functionfd926
+ pop af
+ ld [wd8ba], a
+ ret
+
+Functionfd926:
+ ld a, [hl]
+ and 7
+ ret z
+ ld b, a
+.asm_fd92b
+ push bc
+ xor a
+ ldh [rJOYP], a
+ ld a, $30
+ ldh [rJOYP], a
+ ld b, $10
+.asm_fd935
+ ld e, 8
+ ld a, [hli]
+ ld d, a
+.asm_fd939
+ bit 0, d
+ ld a, $10
+ jr nz, .asm_fd941
+ ld a, $20
+.asm_fd941
+ ldh [rJOYP], a
+ ld a, $30
+ ldh [rJOYP], a
+ rr d
+ dec e
+ jr nz, .asm_fd939
+ dec b
+ jr nz, .asm_fd935
+ ld a, $20
+ ldh [rJOYP], a
+ ld a, $30
+ ldh [rJOYP], a
+ ld de, 7000
+.wait
+ nop
+ nop
+ nop
+ dec de
+ ld a, d
+ or e
+ jr nz, .wait
+ pop bc
+ dec b
+ jr nz, .asm_fd92b
+ ret
+
+DebugColor_PlaceCursor:
+ ld a, DEBUGTEST_BLACK
+ hlcoord 10, 0
+ ld [hl], a
+ hlcoord 15, 0
+ ld [hl], a
+ hlcoord 1, 11
+ ld [hl], a
+ hlcoord 1, 13
+ ld [hl], a
+ hlcoord 1, 15
+ ld [hl], a
+ ld a, [wJumptableIndex]
+ cp 3
+ jr nz, .clearsprites
+ ld a, [wce64]
+ and a
+ jr z, .asm_fd996
+ dec a
+ hlcoord 1, 11
+ ld bc, 2 * SCREEN_WIDTH
+ call AddNTimes
+ ld [hl], "▶"
+
+.asm_fd996
+ ld a, [wce65]
+ and a
+ jr z, .lightcolor
+
+.darkcolor
+ hlcoord 15, 0
+ jr .place
+
+.lightcolor
+ hlcoord 10, 0
+
+.place
+ ld [hl], "▶"
+ ld b, $70
+ ld c, 5
+ ld hl, wVirtualOAM
+ ld de, wc508 + 10
+ call .PlaceSprites
+ ld de, wc508 + 11
+ call .PlaceSprites
+ ld de, wc508 + 12
+ call .PlaceSprites
+ ret
+
+.PlaceSprites:
+ ld a, b
+ ld [hli], a ; y
+ ld a, [de]
+ add a
+ add a
+ add 3 * TILE_WIDTH
+ ld [hli], a ; x
+ xor a
+ ld [hli], a ; tile id
+ ld a, c
+ ld [hli], a ; attributes
+ ld a, 2 * TILE_WIDTH
+ add b
+ ld b, a
+ inc c
+ ret
+
+.clearsprites
+ call ClearSprites
+ ret
+
+String_fd9d6:
+ db "おわりますか?" ; Are you finished?
+ next "はい<DOT><DOT><DOT>", DEBUGTEST_A ; YES...(A)
+ next "いいえ<DOT><DOT>", DEBUGTEST_B ; NO..(B)
+ db "@"
+
+DebugColor_UpArrowGFX:
+INCBIN "gfx/debug/up_arrow.2bpp"
+
+DebugColor_GFX:
+INCBIN "gfx/debug/color_test.2bpp"
+
+TilesetColorTest:
+ ret
+; dummied out
+ xor a
+ ld [wJumptableIndex], a
+ ld [wce64], a
+ ld [wce65], a
+ ld [wce66], a
+ ldh [hMapAnims], a
+ call ClearSprites
+ call OverworldTextModeSwitch
+ call WaitBGMap2
+ xor a
+ ldh [hBGMapMode], a
+ ld de, DebugColor_GFX
+ ld hl, vTiles2 tile DEBUGTEST_TICKS_1
+ lb bc, BANK(DebugColor_GFX), 22
+ call Request2bpp
+ ld de, DebugColor_UpArrowGFX
+ ld hl, vTiles1
+ lb bc, BANK(DebugColor_UpArrowGFX), 1
+ call Request2bpp
+ ld a, HIGH(vBGMap1)
+ ldh [hBGMapAddress + 1], a
+ hlcoord 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ ld a, DEBUGTEST_BLACK
+ call ByteFill
+ hlcoord 0, 0, wAttrmap
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ ld a, 7
+ call ByteFill
+ ld de, $15
+ ld a, DEBUGTEST_WHITE
+ call Functionfdbdb
+ ld de, $1a
+ ld a, DEBUGTEST_LIGHT
+ call Functionfdbdb
+ ld de, $1f
+ ld a, DEBUGTEST_DARK
+ call Functionfdbdb
+ ld de, $24
+ ld a, DEBUGTEST_BLACK
+ call Functionfdbdb
+ call Functionfdbfd
+ call Functionfdc18
+ call WaitBGMap2
+ ld [wJumptableIndex], a
+ ld a, $40
+ ldh [hWY], a
+ ret
+
+Functionfdbdb:
+ hlcoord 0, 0
+ call Functionfdbe7
+
+Functionfdbe1:
+ ld a, [wce64]
+ hlcoord 0, 0, wAttrmap
+
+Functionfdbe7:
+ add hl, de
+rept 4
+ ld [hli], a
+endr
+ ld bc, $10
+ add hl, bc
+rept 4
+ ld [hli], a
+endr
+ ld bc, $10
+ add hl, bc
+rept 4
+ ld [hli], a
+endr
+ ret
+
+Functionfdbfd:
+ hlcoord 2, 4
+ call .Place
+ hlcoord 2, 6
+ call .Place
+ hlcoord 2, 8
+
+.Place:
+ ld a, DEBUGTEST_TICKS_1
+ ld [hli], a
+ ld bc, $10 - 1
+ ld a, DEBUGTEST_TICKS_2
+ call ByteFill
+ ret
+
+Functionfdc18:
+ ld a, [wce64]
+ ld l, a
+ ld h, 0
+ add hl, hl
+ add hl, hl
+ add hl, hl
+ ld de, wBGPals1
+ add hl, de
+ ld de, wc508
+ ld bc, 8
+ call CopyBytes
+ ld de, wc508
+ call DebugColor_CalculateRGB
+ ret
+
+DebugColorMain2:
+ ld hl, hJoyLast
+ ld a, [hl]
+ and SELECT
+ jr nz, .loop7
+ ld a, [hl]
+ and B_BUTTON
+ jr nz, .asm_fdc8e
+ call Functionfdcdb
+ ret
+
+.loop7
+ ld hl, wce64
+ ld a, [hl]
+ inc a
+ and 7
+ cp 7
+ jr nz, .asm_fdc52
+ xor a
+
+.asm_fdc52
+ ld [hl], a
+ ld de, $15
+ call Functionfdbe1
+ ld de, $1a
+ call Functionfdbe1
+ ld de, $1f
+ call Functionfdbe1
+ ld de, $24
+ call Functionfdbe1
+ ld hl, wBGPals2
+ ld a, [wce64]
+ ld bc, 1 palettes
+ call AddNTimes
+ ld de, wc508
+ ld bc, 1 palettes
+ call CopyBytes
+ ld a, 2
+ ldh [hBGMapMode], a
+ ld c, 3
+ call DelayFrames
+ ld a, 1
+ ldh [hBGMapMode], a
+ ret
+
+.asm_fdc8e
+ call ClearSprites
+ ldh a, [hWY]
+ xor $d0
+ ldh [hWY], a
+ ret
+
+Functionfdc98:
+ ld hl, wBGPals2
+ ld a, [wce64]
+ ld bc, 1 palettes
+ call AddNTimes
+ ld e, l
+ ld d, h
+ ld hl, wc508
+ ld bc, 1 palettes
+ call CopyBytes
+ hlcoord 1, 0
+ ld de, wc508
+ call Functionfd6b0
+ hlcoord 6, 0
+ ld de, wc508 + 2
+ call Functionfd6b0
+ hlcoord 11, 0
+ ld de, wc508 + 4
+ call Functionfd6b0
+ hlcoord 16, 0
+ ld de, wc508 + 6
+ call Functionfd6b0
+ ld a, 1
+ ldh [hCGBPalUpdate], a
+ call DelayFrame
+ ret
+
+Functionfdcdb:
+ ld a, [wce65]
+ and 3
+ ld e, a
+ ld d, 0
+ ld hl, .PointerTable
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+.PointerTable:
+ dw DebugColor_SelectColorBox2
+ dw Functionfdd24 ; Red
+ dw Functionfdd36 ; Green
+ dw Functionfdd48 ; Blue
+
+DebugColor_SelectColorBox2:
+ ld hl, hJoyLast
+ ld a, [hl]
+ and D_DOWN
+ jr nz, Functionfdd77
+ ld a, [hl]
+ and D_LEFT
+ jr nz, .asm_fdd07
+ ld a, [hl]
+ and D_RIGHT
+ jr nz, .asm_fdd0d
+ ret
+
+.asm_fdd07
+ ld a, [wce66]
+ dec a
+ jr .asm_fdd11
+
+.asm_fdd0d
+ ld a, [wce66]
+ inc a
+
+.asm_fdd11
+ and 3
+ ld [wce66], a
+ ld e, a
+ ld d, 0
+ ld hl, wc508
+ add hl, de
+ add hl, de
+ ld e, l
+ ld d, h
+ call DebugColor_CalculateRGB
+ ret
+
+Functionfdd24:
+ ld hl, hJoyLast
+ ld a, [hl]
+ and D_DOWN
+ jr nz, Functionfdd77
+ ld a, [hl]
+ and D_UP
+ jr nz, Functionfdd72
+ ld hl, wc508 + 10
+ jr Functionfdd53
+
+Functionfdd36:
+ ld hl, hJoyLast
+ ld a, [hl]
+ and D_DOWN
+ jr nz, Functionfdd77
+ ld a, [hl]
+ and D_UP
+ jr nz, Functionfdd72
+ ld hl, wc508 + 11
+ jr Functionfdd53
+
+Functionfdd48:
+ ld hl, hJoyLast
+ ld a, [hl]
+ and D_UP
+ jr nz, Functionfdd72
+ ld hl, wc508 + 12
+
+Functionfdd53:
+ ldh a, [hJoyLast]
+ and D_RIGHT
+ jr nz, .asm_fdd60
+ ldh a, [hJoyLast]
+ and D_LEFT
+ jr nz, .asm_fdd67
+ ret
+
+.asm_fdd60
+ ld a, [hl]
+ cp $1f
+ ret nc
+ inc [hl]
+ jr .asm_fdd6b
+
+.asm_fdd67
+ ld a, [hl]
+ and a
+ ret z
+ dec [hl]
+
+.asm_fdd6b
+ call Functionfdd7c
+ call Functionfdc98
+ ret
+
+Functionfdd72:
+ ld hl, wce65
+ dec [hl]
+ ret
+
+Functionfdd77:
+ ld hl, wce65
+ inc [hl]
+ ret
+
+Functionfdd7c:
+ ld a, [wc508 + 10]
+ and $1f
+ ld e, a
+ ld a, [wc508 + 11]
+ and 7
+ sla a
+ swap a
+ or e
+ ld e, a
+ ld a, [wc508 + 11]
+ and $18
+ sla a
+ swap a
+ ld d, a
+ ld a, [wc508 + 12]
+ and $1f
+ sla a
+ sla a
+ or d
+ ld d, a
+ ld a, [wce66]
+ ld c, a
+ ld b, 0
+ ld hl, wc508
+ add hl, bc
+ add hl, bc
+ ld a, e
+ ld [hli], a
+ ld [hl], d
+ ret
+
+DebugColor_PlaceCursor2:
+ ld a, DEBUGTEST_BLACK
+ hlcoord 0, 4
+ ld [hl], a
+ hlcoord 0, 6
+ ld [hl], a
+ hlcoord 0, 8
+ ld [hl], a
+ hlcoord 0, 2
+ ld [hl], a
+ hlcoord 5, 2
+ ld [hl], a
+ hlcoord 10, 2
+ ld [hl], a
+ hlcoord 15, 2
+ ld [hl], a
+ ld a, [wce65]
+ and a
+ jr z, .asm_fdde1
+ dec a
+ hlcoord 0, 4
+ ld bc, 2 * SCREEN_WIDTH
+ call AddNTimes
+ ld [hl], "▶"
+
+.asm_fdde1
+ ld a, [wce66]
+ hlcoord 0, 2
+ ld bc, 5
+ call AddNTimes
+ ld [hl], "▶"
+ ld b, $78
+ ld hl, wVirtualOAM
+ ld de, wc508 + 10
+ call .PlaceSprites
+ ld de, wc508 + 11
+ call .PlaceSprites
+ ld de, wc508 + 12
+ call .PlaceSprites
+ ret
+
+.PlaceSprites:
+ ld a, b
+ ld [hli], a ; y
+ ld a, [de]
+ add a
+ add a
+ add 3 * TILE_WIDTH
+ ld [hli], a ; x
+ ld a, 16 * TILE_WIDTH
+ ld [hli], a ; tile id
+ ld a, 5
+ ld [hli], a ; attributes
+ ld a, 2 * TILE_WIDTH
+ add b
+ ld b, a
+ inc c
+ ret
+
+; unused
+ call ClearSprites
+ ret
+
+; unused
+ ret
diff --git a/engine/menus/main_menu.asm b/engine/menus/main_menu.asm
index 4e9113a8..5907324d 100644
--- a/engine/menus/main_menu.asm
+++ b/engine/menus/main_menu.asm
@@ -176,7 +176,7 @@ MainMenu_PrintCurrentTimeAndDay:
call GetWeekday
ld b, a
decoord 1, 14
- call .PlaceCurrentDay
+ call PrintDayOfWeek
decoord 4, 16
ldh a, [hHours]
ld c, a
@@ -205,7 +205,7 @@ MainMenu_PrintCurrentTimeAndDay:
text_far _MainMenuTimeUnknownText
text_end
-.PlaceCurrentDay:
+PrintDayOfWeek:
push de
ld hl, .Days
ld a, b
diff --git a/engine/pokedex/pokedex_3.asm b/engine/pokedex/pokedex_3.asm
new file mode 100644
index 00000000..7cde4dc4
--- /dev/null
+++ b/engine/pokedex/pokedex_3.asm
@@ -0,0 +1,165 @@
+StubbedGetFrontpic::
+ ret
+
+LoadSGBPokedexGFX:
+ ld hl, SGBPokedexGFX_LZ
+ ld de, vTiles2 tile $31
+ call Decompress
+ ret
+
+LoadSGBPokedexGFX2:
+ ld hl, SGBPokedexGFX_LZ
+ ld de, vTiles2 tile $31
+ lb bc, BANK(SGBPokedexGFX_LZ), 58
+ call DecompressRequest2bpp
+ ret
+
+SGBPokedexGFX_LZ:
+INCBIN "gfx/pokedex/pokedex_sgb.2bpp.lz"
+
+LoadQuestionMarkPic:
+ ld hl, .QuestionMarkLZ
+ ld de, sScratch
+ call Decompress
+ ret
+
+.QuestionMarkLZ:
+INCBIN "gfx/pokedex/question_mark.2bpp.lz"
+
+DrawPokedexListWindow:
+ ld a, $32
+ hlcoord 0, 17
+ ld bc, 12
+ call ByteFill
+ hlcoord 0, 1
+ lb bc, 15, 11
+ call ClearBox
+ ld a, $34
+ hlcoord 0, 0
+ ld bc, 11
+ call ByteFill
+ ld a, $39
+ hlcoord 0, 16
+ ld bc, 11
+ call ByteFill
+ hlcoord 5, 0
+ ld [hl], $3f
+ hlcoord 5, 16
+ ld [hl], $40
+ ld a, [wCurDexMode]
+ cp DEXMODE_OLD
+ jr z, .OldMode
+; scroll bar
+ hlcoord 11, 0
+ ld [hl], $50
+ ld a, $51
+ hlcoord 11, 1
+ ld b, SCREEN_HEIGHT - 3
+ call Bank70_FillColumn
+ ld [hl], $52
+ jr .Done
+
+.OldMode:
+; no scroll bar
+ hlcoord 11, 0
+ ld [hl], $66
+ ld a, $67
+ hlcoord 11, 1
+ ld b, SCREEN_HEIGHT - 3
+ call Bank70_FillColumn
+ ld [hl], $68
+.Done:
+ ret
+
+DrawPokedexSearchResultsWindow:
+ ld a, $34
+ hlcoord 0, 0
+ ld bc, 11
+ call ByteFill
+ ld a, $39
+ hlcoord 0, 10
+ ld bc, 11
+ call ByteFill
+ hlcoord 5, 0
+ ld [hl], $3f
+ hlcoord 5, 10
+ ld [hl], $40
+ hlcoord 11, 0
+ ld [hl], $66
+ ld a, $67
+ hlcoord 11, 1
+ ld b, SCREEN_HEIGHT / 2
+ call Bank70_FillColumn
+ ld [hl], $68
+ ld a, $34
+ hlcoord 0, 11
+ ld bc, 11
+ call ByteFill
+ ld a, $39
+ hlcoord 0, 17
+ ld bc, 11
+ call ByteFill
+ hlcoord 11, 11
+ ld [hl], $66
+ ld a, $67
+ hlcoord 11, 12
+ ld b, 5
+ call Bank70_FillColumn
+ ld [hl], $68
+ hlcoord 0, 12
+ lb bc, 5, 11
+ call ClearBox
+ ld de, .esults_D
+ hlcoord 0, 12
+ call PlaceString
+ ret
+
+.esults_D
+; (SEARCH R)
+ db "ESULTS"
+ next ""
+; (### FOUN)
+ next "D!@"
+
+DrawDexEntryScreenRightEdge:
+ ldh a, [hBGMapAddress]
+ ld l, a
+ ldh a, [hBGMapAddress + 1]
+ ld h, a
+ push hl
+ inc hl
+ ld a, l
+ ldh [hBGMapAddress], a
+ ld a, h
+ ldh [hBGMapAddress + 1], a
+ hlcoord 19, 0
+ ld [hl], $66
+ hlcoord 19, 1
+ ld a, $67
+ ld b, 15
+ call Bank70_FillColumn
+ ld [hl], $68
+ hlcoord 19, 17
+ ld [hl], $3c
+ xor a
+ ld b, SCREEN_HEIGHT
+ hlcoord 19, 0, wAttrmap
+ call Bank70_FillColumn
+ call WaitBGMap2
+ pop hl
+ ld a, l
+ ldh [hBGMapAddress], a
+ ld a, h
+ ldh [hBGMapAddress + 1], a
+ ret
+
+Bank70_FillColumn:
+ push de
+ ld de, SCREEN_WIDTH
+.loop
+ ld [hl], a
+ add hl, de
+ dec b
+ jr nz, .loop
+ pop de
+ ret
diff --git a/engine/pokegear/townmap_convertlinebreakcharacters.asm b/engine/pokegear/townmap_convertlinebreakcharacters.asm
new file mode 100644
index 00000000..a881b926
--- /dev/null
+++ b/engine/pokegear/townmap_convertlinebreakcharacters.asm
@@ -0,0 +1,21 @@
+TownMap_ConvertLineBreakCharacters:
+ ld hl, wStringBuffer1
+.loop
+ ld a, [hl]
+ cp "@"
+ jr z, .end
+ cp "%"
+ jr z, .line_feed
+ cp "¯"
+ jr z, .line_feed
+ inc hl
+ jr .loop
+
+.line_feed
+ ld [hl], "<LF>"
+
+.end
+ ld de, wStringBuffer1
+ hlcoord 9, 0
+ call PlaceString
+ ret
diff --git a/engine/printer/print_party.asm b/engine/printer/print_party.asm
new file mode 100644
index 00000000..7b98a337
--- /dev/null
+++ b/engine/printer/print_party.asm
@@ -0,0 +1,360 @@
+PRINTPARTY_HP EQU "◀" ; $71
+
+PrintPage1:
+ hlcoord 0, 0
+ decoord 0, 0, wPrinterTilemapBuffer
+ ld bc, 17 * SCREEN_WIDTH
+ call CopyBytes
+ hlcoord 17, 1, wPrinterTilemapBuffer
+ ld a, $62
+ ld [hli], a
+ inc a
+ ld [hl], a
+ hlcoord 17, 2, wPrinterTilemapBuffer
+ ld a, $64
+ ld [hli], a
+ inc a
+ ld [hl], a
+ hlcoord 1, 9, wPrinterTilemapBuffer
+ ld a, " "
+ ld [hli], a
+ ld [hl], a
+ hlcoord 1, 10, wPrinterTilemapBuffer
+ ld a, $61
+ ld [hli], a
+ ld [hl], a
+ hlcoord 2, 11, wPrinterTilemapBuffer
+ lb bc, 5, 18
+ call ClearBox
+ ld a, [wTempSpecies]
+ dec a
+ call CheckCaughtMon
+ push af
+ ld a, [wTempSpecies]
+ ld b, a
+ ld c, 1 ; get page 1
+ farcall GetDexEntryPagePointer
+ pop af
+ ld a, b
+ hlcoord 1, 11, wPrinterTilemapBuffer
+ call nz, FarString
+ hlcoord 19, 0, wPrinterTilemapBuffer
+ ld [hl], $35
+ ld de, SCREEN_WIDTH
+ add hl, de
+ ld b, $f
+.column_loop
+ ld [hl], $37
+ add hl, de
+ dec b
+ jr nz, .column_loop
+ ld [hl], $3a
+ ret
+
+PrintPage2:
+ hlcoord 0, 0, wPrinterTilemapBuffer
+ ld bc, 8 * SCREEN_WIDTH
+ ld a, " "
+ call ByteFill
+ hlcoord 0, 0, wPrinterTilemapBuffer
+ ld a, $36
+ ld b, 6
+ call .FillColumn
+ hlcoord 19, 0, wPrinterTilemapBuffer
+ ld a, $37
+ ld b, 6
+ call .FillColumn
+ hlcoord 0, 6, wPrinterTilemapBuffer
+ ld [hl], $38
+ inc hl
+ ld a, $39
+ ld bc, SCREEN_HEIGHT
+ call ByteFill
+ ld [hl], $3a
+ hlcoord 0, 7, wPrinterTilemapBuffer
+ ld bc, SCREEN_WIDTH
+ ld a, $32
+ call ByteFill
+ ld a, [wTempSpecies]
+ dec a
+ call CheckCaughtMon
+ push af
+ ld a, [wTempSpecies]
+ ld b, a
+ ld c, 2 ; get page 2
+ farcall GetDexEntryPagePointer
+ pop af
+ hlcoord 1, 1, wPrinterTilemapBuffer
+ ld a, b
+ call nz, FarString
+ ret
+
+.FillColumn:
+ push de
+ ld de, SCREEN_WIDTH
+.column_loop
+ ld [hl], a
+ add hl, de
+ dec b
+ jr nz, .column_loop
+ pop de
+ ret
+
+GBPrinterStrings: ; used only for BANK(GBPrinterStrings)
+GBPrinterString_Null: db "@"
+GBPrinterString_CheckingLink: next " CHECKING LINK...@"
+GBPrinterString_Transmitting: next " TRANSMITTING...@"
+GBPrinterString_Printing: next " PRINTING...@"
+GBPrinterString_PrinterError1:
+ db " Printer Error 1"
+ next ""
+ next "Check the Game Boy"
+ next "Printer Manual."
+ db "@"
+GBPrinterString_PrinterError2:
+ db " Printer Error 2"
+ next ""
+ next "Check the Game Boy"
+ next "Printer Manual."
+ db "@"
+GBPrinterString_PrinterError3:
+ db " Printer Error 3"
+ next ""
+ next "Check the Game Boy"
+ next "Printer Manual."
+ db "@"
+GBPrinterString_PrinterError4:
+ db " Printer Error 4"
+ next ""
+ next "Check the Game Boy"
+ next "Printer Manual."
+ db "@"
+
+PrintPartyMonPage1:
+ call ClearBGPalettes
+ call ClearTilemap
+ call ClearSprites
+ xor a
+ ldh [hBGMapMode], a
+ call LoadFontsBattleExtra
+
+ ld de, GBPrinterHPIcon
+ ld hl, vTiles2 tile PRINTPARTY_HP
+ lb bc, BANK(GBPrinterHPIcon), 1
+ call Request1bpp
+
+ ld de, GBPrinterLvIcon
+ ld hl, vTiles2 tile "<LV>"
+ lb bc, BANK(GBPrinterLvIcon), 1
+ call Request1bpp
+
+ ld de, StatsScreenPageTilesGFX + 14 tiles ; shiny icon
+ ld hl, vTiles2 tile "⁂"
+ lb bc, BANK(StatsScreenPageTilesGFX), 1
+ call Get2bpp
+
+ xor a
+ ld [wMonType], a
+ farcall CopyMonToTempMon
+ hlcoord 0, 7
+ ld b, 9
+ ld c, 18
+ call Textbox
+ hlcoord 8, 2
+ ld a, [wTempMonLevel]
+ call PrintLevel_Force3Digits
+ hlcoord 12, 2
+ ld [hl], PRINTPARTY_HP
+ inc hl
+ ld de, wTempMonMaxHP
+ lb bc, 2, 3
+ call PrintNum
+ ld a, [wCurPartySpecies]
+ ld [wNamedObjectIndexBuffer], a
+ ld [wCurSpecies], a
+ ld hl, wPartyMonNicknames
+ call Function1c0375
+ hlcoord 8, 4
+ call PlaceString
+ hlcoord 9, 6
+ ld [hl], "/"
+ call GetPokemonName
+ hlcoord 10, 6
+ call PlaceString
+ hlcoord 8, 0
+ ld [hl], "№"
+ inc hl
+ ld [hl], "."
+ inc hl
+ ld de, wNamedObjectIndexBuffer
+ lb bc, PRINTNUM_LEADINGZEROS | 1, 3
+ call PrintNum
+ hlcoord 1, 9
+ ld de, String1c03b7
+ call PlaceString
+ ld hl, wPartyMonOT
+ call Function1c0375
+ hlcoord 4, 9
+ call PlaceString
+ hlcoord 1, 11
+ ld de, String1c03c0
+ call PlaceString
+ hlcoord 4, 11
+ ld de, wTempMonID
+ lb bc, PRINTNUM_LEADINGZEROS | 2, 5
+ call PrintNum
+ hlcoord 1, 14
+ ld de, String1c03bb
+ call PlaceString
+ hlcoord 7, 14
+ ld a, [wTempMonMoves + 0]
+ call Function1c0381
+ call Function1c0393
+ ld hl, wTempMonDVs
+ predef GetUnownLetter
+ hlcoord 0, 0
+ call PrepMonFrontpic
+ call WaitBGMap
+ ld b, SCGB_STATS_SCREEN_HP_PALS
+ call GetSGBLayout
+ call SetPalettes
+ ret
+
+PrintPartyMonPage2:
+ call ClearBGPalettes
+ call ClearTilemap
+ call ClearSprites
+ xor a
+ ldh [hBGMapMode], a
+ call LoadFontsBattleExtra
+
+ ld de, GBPrinterHPIcon
+ ld hl, vTiles2 tile PRINTPARTY_HP
+ lb bc, BANK(GBPrinterHPIcon), 1
+ call Request1bpp
+
+ ld de, GBPrinterLvIcon
+ ld hl, vTiles2 tile "<LV>"
+ lb bc, BANK(GBPrinterLvIcon), 1
+ call Request1bpp
+
+ ld de, StatsScreenPageTilesGFX + 14 tiles ; shiny icon
+ ld hl, vTiles2 tile "⁂"
+ lb bc, BANK(StatsScreenPageTilesGFX), 1
+ call Get2bpp
+
+ xor a
+ ld [wMonType], a
+ farcall CopyMonToTempMon
+ hlcoord 0, 0
+ ld b, 15
+ ld c, 18
+ call Textbox
+ ld bc, SCREEN_WIDTH
+ decoord 0, 0
+ hlcoord 0, 1
+ call CopyBytes
+ hlcoord 7, 0
+ ld a, [wTempMonMoves + 1]
+ call Function1c0381
+ hlcoord 7, 2
+ ld a, [wTempMonMoves + 2]
+ call Function1c0381
+ hlcoord 7, 4
+ ld a, [wTempMonMoves + 3]
+ call Function1c0381
+ hlcoord 7, 7
+ ld de, String1c03c3
+ call PlaceString
+ hlcoord 16, 7
+ ld de, wTempMonAttack
+ call .PrintTempMonStats
+ hlcoord 16, 9
+ ld de, wTempMonDefense
+ call .PrintTempMonStats
+ hlcoord 16, 11
+ ld de, wTempMonSpclAtk
+ call .PrintTempMonStats
+ hlcoord 16, 13
+ ld de, wTempMonSpclDef
+ call .PrintTempMonStats
+ hlcoord 16, 15
+ ld de, wTempMonSpeed
+ call .PrintTempMonStats
+ call WaitBGMap
+ ld b, SCGB_STATS_SCREEN_HP_PALS
+ call GetSGBLayout
+ call SetPalettes
+ ret
+
+.PrintTempMonStats:
+ lb bc, 2, 3
+ call PrintNum
+ ret
+
+Function1c0375:
+ ld bc, NAME_LENGTH
+ ld a, [wCurPartyMon]
+ call AddNTimes
+ ld e, l
+ ld d, h
+ ret
+
+Function1c0381:
+ and a
+ jr z, .no_move
+
+ ld [wNamedObjectIndexBuffer], a
+ call GetMoveName
+ jr .got_string
+
+.no_move
+ ld de, String1c03ea
+
+.got_string
+ call PlaceString
+ ret
+
+Function1c0393:
+ farcall GetGender
+ ld a, " "
+ jr c, .got_gender
+ ld a, "♂"
+ jr nz, .got_gender
+ ld a, "♀"
+
+.got_gender
+ hlcoord 17, 2
+ ld [hl], a
+ ld bc, wTempMonDVs
+ farcall CheckShininess
+ ret nc
+ hlcoord 18, 2
+ ld [hl], "⁂"
+ ret
+
+String1c03b7:
+ db "OT/@"
+
+String1c03bb:
+ db "MOVE@"
+
+String1c03c0:
+ db "<ID>№@"
+
+String1c03c3:
+ db "ATTACK"
+ next "DEFENSE"
+ next "SPCL.ATK"
+ next "SPCL.DEF"
+ next "SPEED"
+ db "@"
+
+String1c03ea:
+ db "------------@"
+
+GBPrinterHPIcon:
+INCBIN "gfx/printer/hp.1bpp"
+
+GBPrinterLvIcon:
+INCBIN "gfx/printer/lv.1bpp"
diff --git a/engine/rtc/print_hours_mins.asm b/engine/rtc/print_hours_mins.asm
new file mode 100644
index 00000000..faa69756
--- /dev/null
+++ b/engine/rtc/print_hours_mins.asm
@@ -0,0 +1,76 @@
+Unreferenced_Function1c0a0d:
+ ld a, b
+ ld b, c
+ ld c, a
+ push bc
+ push de
+ ld hl, sp+$2
+ ld d, h
+ ld e, l
+ pop hl
+ lb bc, PRINTNUM_LEADINGZEROS | 2, 5
+ call PrintNum
+ pop bc
+ ret
+
+PrintHoursMins:
+; Hours in b, minutes in c
+ ld a, b
+ cp 12
+ push af
+ jr c, .AM
+ jr z, .PM
+ sub 12
+ jr .PM
+.AM:
+ or a
+ jr nz, .PM
+ ld a, 12
+.PM:
+ ld b, a
+; Crazy stuff happening with the stack
+ push bc
+ ld hl, sp+$1
+ push de
+ push hl
+ pop de
+ pop hl
+ ld [hl], " "
+ lb bc, 1, 2
+ call PrintNum
+ ld [hl], ":"
+ inc hl
+ ld d, h
+ ld e, l
+ ld hl, sp+$0
+ push de
+ push hl
+ pop de
+ pop hl
+ lb bc, PRINTNUM_LEADINGZEROS | 1, 2
+ call PrintNum
+ pop bc
+ ld de, String_AM
+ pop af
+ jr c, .place_am_pm
+ ld de, String_PM
+.place_am_pm
+ inc hl
+ call PlaceString
+ ret
+
+String_AM: db "AM@"
+String_PM: db "PM@"
+
+UpdateTimePredef::
+ call UpdateTime
+ ld hl, wDSTBackupDay
+ ld a, [wCurDay]
+ ld [hli], a ; wDSTBackupDay
+ ldh a, [hHours]
+ ld [hli], a ; wDSTBackupHours
+ ldh a, [hMinutes]
+ ld [hli], a ; wDSTBackupMinutes
+ ldh a, [hSeconds]
+ ld [hli], a ; wDSTBackupSeconds
+ ret
diff --git a/engine/rtc/restart_clock.asm b/engine/rtc/restart_clock.asm
new file mode 100644
index 00000000..5dc98718
--- /dev/null
+++ b/engine/rtc/restart_clock.asm
@@ -0,0 +1,236 @@
+RestartClock_GetWraparoundTime:
+ push hl
+ dec a
+ ld e, a
+ ld d, 0
+ ld hl, .WrapAroundTimes
+rept 4
+ add hl, de
+endr
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+ ld b, [hl]
+ inc hl
+ ld c, [hl]
+ pop hl
+ ret
+
+.WrapAroundTimes:
+ dw wBuffer4
+ db 7, 4
+
+ dw wBuffer5
+ db 24, 12
+
+ dw wBuffer6
+ db 60, 15
+
+RestartClock:
+; If we're here, we had an RTC overflow.
+ ld hl, .ClockTimeMayBeWrongText
+ call PrintText
+ ld hl, wOptions
+ ld a, [hl]
+ push af
+ set NO_TEXT_SCROLL, [hl]
+ call LoadStandardMenuHeader
+ call ClearTilemap
+ ld hl, .ClockSetWithControlPadText
+ call PrintText
+ call .SetClock
+ call ExitMenu
+ pop bc
+ ld hl, wOptions
+ ld [hl], b
+ ld c, a
+ ret
+
+.ClockTimeMayBeWrongText:
+ text_far _ClockTimeMayBeWrongText
+ text_end
+
+.ClockSetWithControlPadText:
+ text_far _ClockSetWithControlPadText
+ text_end
+
+.SetClock:
+ ld a, 1
+ ld [wBuffer1], a ; which digit
+ ld [wBuffer2], a
+ ld a, 8
+ ld [wBuffer3], a
+ call UpdateTime
+ call GetWeekday
+ ld [wBuffer4], a
+ ldh a, [hHours]
+ ld [wBuffer5], a
+ ldh a, [hMinutes]
+ ld [wBuffer6], a
+
+.loop
+ call .joy_loop
+ jr nc, .loop
+ and a
+ ret nz
+ call .PrintTime
+ ld hl, .ClockIsThisOKText
+ call PrintText
+ call YesNoBox
+ jr c, .cancel
+ ld a, [wBuffer4]
+ ld [wStringBuffer2], a
+ ld a, [wBuffer5]
+ ld [wStringBuffer2 + 1], a
+ ld a, [wBuffer6]
+ ld [wStringBuffer2 + 2], a
+ xor a
+ ld [wStringBuffer2 + 3], a
+ call InitTime
+ call .PrintTime
+ ld hl, .ClockHasResetText
+ call PrintText
+ call WaitPressAorB_BlinkCursor
+ xor a
+ ret
+
+.cancel
+ ld a, $1
+ ret
+
+.ClockIsThisOKText:
+ text_far _ClockIsThisOKText
+ text_end
+
+.ClockHasResetText:
+ text_far _ClockHasResetText
+ text_end
+
+.joy_loop
+ call JoyTextDelay_ForcehJoyDown
+ ld c, a
+ push af
+ call .PrintTime
+ pop af
+ bit 0, a
+ jr nz, .press_A
+ bit 1, a
+ jr nz, .press_B
+ bit 6, a
+ jr nz, .pressed_up
+ bit 7, a
+ jr nz, .pressed_down
+ bit 5, a
+ jr nz, .pressed_left
+ bit 4, a
+ jr nz, .pressed_right
+ jr .joy_loop
+
+.press_A
+ ld a, $0
+ scf
+ ret
+
+.press_B
+ ld a, $1
+ scf
+ ret
+
+.pressed_up
+ ld a, [wBuffer1]
+ call RestartClock_GetWraparoundTime
+ ld a, [de]
+ inc a
+ ld [de], a
+ cp b
+ jr c, .done_scroll
+ ld a, $0
+ ld [de], a
+ jr .done_scroll
+
+.pressed_down
+ ld a, [wBuffer1]
+ call RestartClock_GetWraparoundTime
+ ld a, [de]
+ dec a
+ ld [de], a
+ cp -1
+ jr nz, .done_scroll
+ ld a, b
+ dec a
+ ld [de], a
+ jr .done_scroll
+
+.pressed_left
+ ld hl, wBuffer1
+ dec [hl]
+ jr nz, .done_scroll
+ ld [hl], $3
+ jr .done_scroll
+
+.pressed_right
+ ld hl, wBuffer1
+ inc [hl]
+ ld a, [hl]
+ cp $4
+ jr c, .done_scroll
+ ld [hl], $1
+
+.done_scroll
+ xor a
+ ret
+
+.PrintTime:
+ hlcoord 0, 5
+ ld b, 5
+ ld c, 18
+ call Textbox
+ decoord 1, 8
+ ld a, [wBuffer4]
+ ld b, a
+ farcall PrintDayOfWeek
+ ld a, [wBuffer5]
+ ld b, a
+ ld a, [wBuffer6]
+ ld c, a
+ decoord 11, 8
+ farcall PrintHoursMins
+ ld a, [wBuffer2]
+ lb de, " ", " "
+ call .PlaceChars
+ ld a, [wBuffer1]
+ lb de, "▲", "▼"
+ call .PlaceChars
+ ld a, [wBuffer1]
+ ld [wBuffer2], a
+ ret
+
+.unreferenced
+; unused
+ ld a, [wBuffer3]
+ ld b, a
+ call Coord2Tile
+ ret
+
+.PlaceChars:
+ push de
+ call RestartClock_GetWraparoundTime
+ ld a, [wBuffer3]
+ dec a
+ ld b, a
+ call Coord2Tile
+ pop de
+ ld [hl], d
+ ld bc, 2 * SCREEN_WIDTH
+ add hl, bc
+ ld [hl], e
+ ret
+
+UnreferencedString_HourJP:
+; unused
+ db "じ@" ; HR
+
+UnreferencedString_MinuteJP:
+; unused
+ db "ふん@" ; MIN
diff --git a/engine/tilesets/map_palettes.asm b/engine/tilesets/map_palettes.asm
index 858098e6..2cf1192b 100644
--- a/engine/tilesets/map_palettes.asm
+++ b/engine/tilesets/map_palettes.asm
@@ -37,7 +37,7 @@ _SwapTextboxPalettes::
.asm_8038
ld a, [wMapGroup]
dec a
- ld hl, Unknown85d7
+ ld hl, MapGroupPalettes
add l
ld l, a
jr nc, .asm_8044
@@ -93,7 +93,7 @@ _ScrollBGMapPalettes::
.asm_8083
ld a, [wMapGroup]
dec a
- ld hl, Unknown85d7
+ ld hl, MapGroupPalettes
add l
ld l, a
jr nc, .asm_808f
diff --git a/engine/tilesets/mapgroup_roofs.asm b/engine/tilesets/mapgroup_roofs.asm
new file mode 100644
index 00000000..b269e527
--- /dev/null
+++ b/engine/tilesets/mapgroup_roofs.asm
@@ -0,0 +1,18 @@
+LoadMapGroupRoof::
+ ld a, [wMapGroup]
+ ld e, a
+ ld d, 0
+ ld hl, MapGroupRoofs
+ add hl, de
+ ld a, [hl]
+ cp -1
+ ret z
+ ld hl, Roofs
+ ld bc, 9 tiles
+ call AddNTimes
+ ld de, vTiles2 tile $0a
+ ld bc, 9 tiles
+ call CopyBytes
+ ret
+
+INCLUDE "data/maps/roofs.asm"
diff --git a/engine/tilesets/tileset_anims.asm b/engine/tilesets/tileset_anims.asm
new file mode 100644
index 00000000..a7b35c54
--- /dev/null
+++ b/engine/tilesets/tileset_anims.asm
@@ -0,0 +1,753 @@
+ db 0 ; unused
+
+DummyPredef3A:
+ ret
+
+ ret ; unused
+
+_AnimateTileset::
+; Iterate over a given pointer array of
+; animation functions (one per frame).
+
+; Typically in wra1, vra0
+
+ ld a, [wTilesetAnim]
+ ld e, a
+ ld a, [wTilesetAnim + 1]
+ ld d, a
+
+ ldh a, [hTileAnimFrame]
+ ld l, a
+ inc a
+ ldh [hTileAnimFrame], a
+
+ ld h, 0
+ add hl, hl
+ add hl, hl
+ add hl, de
+
+; 2-byte parameter
+; All functions take input de.
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+
+; Function address
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+
+ jp hl
+
+Tileset0Anim::
+TilesetJohtoModernAnim::
+TilesetKantoAnim::
+TilesetParkAnim::
+TilesetForestAnim::
+ dw vTiles2 tile $14, AnimateWaterTile
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, AnimateWaterPalette
+ dw NULL, WaitTileAnimation
+ dw NULL, AnimateFlowerTile
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, StandingTileFrame8
+ dw NULL, DoneTileAnimation
+
+TilesetJohtoAnim:
+ dw vTiles2 tile $14, AnimateWaterTile
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, AnimateWaterPalette
+ dw NULL, WaitTileAnimation
+ dw NULL, AnimateFlowerTile
+ dw WhirlpoolFrames1, AnimateWhirlpoolTile
+ dw WhirlpoolFrames2, AnimateWhirlpoolTile
+ dw WhirlpoolFrames3, AnimateWhirlpoolTile
+ dw WhirlpoolFrames4, AnimateWhirlpoolTile
+ dw NULL, WaitTileAnimation
+ dw NULL, StandingTileFrame8
+ dw NULL, DoneTileAnimation
+
+UnusedTilesetAnim_fc07e:
+ dw vTiles2 tile $03, WriteTileToBuffer
+ dw wTileAnimBuffer, ScrollTileRightLeft
+ dw vTiles2 tile $03, WriteTileFromBuffer
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, AnimateFlowerTile
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, DoneTileAnimation
+
+UnusedTilesetAnim_fc0aa:
+ dw vTiles2 tile $14, WriteTileToBuffer
+ dw wTileAnimBuffer, ScrollTileRightLeft
+ dw vTiles2 tile $14, WriteTileFromBuffer
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, DoneTileAnimation
+
+TilesetPortAnim:
+ dw vTiles2 tile $14, AnimateWaterTile
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, AnimateWaterPalette
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, StandingTileFrame8
+ dw NULL, DoneTileAnimation
+
+TilesetEliteFourRoomAnim:
+ dw NULL, LavaBubbleAnim2
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, LavaBubbleAnim1
+ dw NULL, WaitTileAnimation
+ dw NULL, StandingTileFrame8
+ dw NULL, DoneTileAnimation
+
+UnusedTilesetAnim_fc126:
+ dw vTiles2 tile $53, WriteTileToBuffer
+ dw wTileAnimBuffer, ScrollTileDown
+ dw wTileAnimBuffer, ScrollTileDown
+ dw vTiles2 tile $53, WriteTileFromBuffer
+ dw vTiles2 tile $03, WriteTileToBuffer
+ dw wTileAnimBuffer, ScrollTileRightLeft
+ dw vTiles2 tile $03, WriteTileFromBuffer
+ dw vTiles2 tile $53, WriteTileToBuffer
+ dw wTileAnimBuffer, ScrollTileDown
+ dw wTileAnimBuffer, ScrollTileDown
+ dw vTiles2 tile $53, WriteTileFromBuffer
+ dw NULL, DoneTileAnimation
+
+UnusedTilesetAnim_fc156:
+ dw vTiles2 tile $54, WriteTileToBuffer
+ dw wTileAnimBuffer, ScrollTileDown
+ dw wTileAnimBuffer, ScrollTileDown
+ dw vTiles2 tile $54, WriteTileFromBuffer
+ dw NULL, WaitTileAnimation
+ dw vTiles2 tile $03, WriteTileToBuffer
+ dw wTileAnimBuffer, ScrollTileRightLeft
+ dw vTiles2 tile $03, WriteTileFromBuffer
+ dw NULL, WaitTileAnimation
+ dw vTiles2 tile $54, WriteTileToBuffer
+ dw wTileAnimBuffer, ScrollTileDown
+ dw wTileAnimBuffer, ScrollTileDown
+ dw vTiles2 tile $54, WriteTileFromBuffer
+ dw NULL, DoneTileAnimation
+
+TilesetCaveAnim:
+TilesetDarkCaveAnim:
+ dw vTiles2 tile $14, WriteTileToBuffer
+ dw NULL, FlickeringCaveEntrancePalette
+ dw wTileAnimBuffer, ScrollTileRightLeft
+ dw NULL, FlickeringCaveEntrancePalette
+ dw vTiles2 tile $14, WriteTileFromBuffer
+ dw NULL, FlickeringCaveEntrancePalette
+ dw NULL, AnimateWaterPalette
+ dw NULL, FlickeringCaveEntrancePalette
+ dw vTiles2 tile $40, WriteTileToBuffer
+ dw NULL, FlickeringCaveEntrancePalette
+ dw wTileAnimBuffer, ScrollTileDown
+ dw NULL, FlickeringCaveEntrancePalette
+ dw wTileAnimBuffer, ScrollTileDown
+ dw NULL, FlickeringCaveEntrancePalette
+ dw wTileAnimBuffer, ScrollTileDown
+ dw NULL, FlickeringCaveEntrancePalette
+ dw vTiles2 tile $40, WriteTileFromBuffer
+ dw NULL, FlickeringCaveEntrancePalette
+ dw NULL, DoneTileAnimation
+
+TilesetIcePathAnim:
+ dw vTiles2 tile $35, WriteTileToBuffer
+ dw NULL, FlickeringCaveEntrancePalette
+ dw wTileAnimBuffer, ScrollTileRightLeft
+ dw NULL, FlickeringCaveEntrancePalette
+ dw vTiles2 tile $35, WriteTileFromBuffer
+ dw NULL, FlickeringCaveEntrancePalette
+ dw NULL, AnimateWaterPalette
+ dw NULL, FlickeringCaveEntrancePalette
+ dw vTiles2 tile $31, WriteTileToBuffer
+ dw NULL, FlickeringCaveEntrancePalette
+ dw wTileAnimBuffer, ScrollTileDown
+ dw NULL, FlickeringCaveEntrancePalette
+ dw wTileAnimBuffer, ScrollTileDown
+ dw NULL, FlickeringCaveEntrancePalette
+ dw wTileAnimBuffer, ScrollTileDown
+ dw NULL, FlickeringCaveEntrancePalette
+ dw vTiles2 tile $31, WriteTileFromBuffer
+ dw NULL, FlickeringCaveEntrancePalette
+ dw NULL, DoneTileAnimation
+
+TilesetTowerAnim:
+ dw TowerPillarTilePointer9, AnimateTowerPillarTile
+ dw TowerPillarTilePointer10, AnimateTowerPillarTile
+ dw TowerPillarTilePointer7, AnimateTowerPillarTile
+ dw TowerPillarTilePointer8, AnimateTowerPillarTile
+ dw TowerPillarTilePointer5, AnimateTowerPillarTile
+ dw TowerPillarTilePointer6, AnimateTowerPillarTile
+ dw TowerPillarTilePointer3, AnimateTowerPillarTile
+ dw TowerPillarTilePointer4, AnimateTowerPillarTile
+ dw TowerPillarTilePointer1, AnimateTowerPillarTile
+ dw TowerPillarTilePointer2, AnimateTowerPillarTile
+ dw NULL, StandingTileFrame
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, DoneTileAnimation
+ dw vTiles2 tile $4f, WriteTileToBuffer
+ dw wTileAnimBuffer, ScrollTileRightLeft
+ dw vTiles2 tile $4f, WriteTileFromBuffer
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, DoneTileAnimation
+
+TilesetHouseAnim:
+TilesetPlayersHouseAnim:
+TilesetPokecenterAnim:
+TilesetGateAnim:
+TilesetLabAnim:
+TilesetFacilityAnim:
+TilesetMartAnim:
+TilesetMansionAnim:
+TilesetGameCornerAnim:
+TilesetTraditionalHouseAnim:
+TilesetTrainStationAnim:
+TilesetChampionsRoomAnim:
+TilesetLighthouseAnim:
+TilesetPlayersRoomAnim:
+TilesetRuinsOfAlphAnim:
+TilesetRadioTowerAnim:
+TilesetUndergroundAnim:
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, WaitTileAnimation
+ dw NULL, DoneTileAnimation
+
+DoneTileAnimation:
+; Reset the animation command loop.
+ xor a
+ ldh [hTileAnimFrame], a
+
+WaitTileAnimation:
+; Do nothing this frame.
+ ret
+
+StandingTileFrame8:
+ ld a, [wTileAnimationTimer]
+ inc a
+ and %111
+ ld [wTileAnimationTimer], a
+ ret
+
+ScrollTileRightLeft:
+; Scroll right for 4 ticks, then left for 4 ticks.
+ ld a, [wTileAnimationTimer]
+ inc a
+ and %111
+ ld [wTileAnimationTimer], a
+ and %100
+ jr nz, ScrollTileLeft
+ jr ScrollTileRight
+
+ScrollTileUpDown:
+; Scroll up for 4 ticks, then down for 4 ticks.
+ ld a, [wTileAnimationTimer]
+ inc a
+ and %111
+ ld [wTileAnimationTimer], a
+ and %100
+ jr nz, ScrollTileDown
+ jr ScrollTileUp
+
+ScrollTileLeft:
+ ld h, d
+ ld l, e
+ ld c, 4
+.loop
+rept 4
+ ld a, [hl]
+ rlca
+ ld [hli], a
+endr
+ dec c
+ jr nz, .loop
+ ret
+
+ScrollTileRight:
+ ld h, d
+ ld l, e
+ ld c, 4
+.loop
+rept 4
+ ld a, [hl]
+ rrca
+ ld [hli], a
+endr
+ dec c
+ jr nz, .loop
+ ret
+
+ScrollTileUp:
+ ld h, d
+ ld l, e
+ ld d, [hl]
+ inc hl
+ ld e, [hl]
+ ld bc, TILE_WIDTH * 2 - 2
+ add hl, bc
+ ld a, TILE_WIDTH / 2
+.loop
+ ld c, [hl]
+ ld [hl], e
+ dec hl
+ ld b, [hl]
+ ld [hl], d
+ dec hl
+ ld e, [hl]
+ ld [hl], c
+ dec hl
+ ld d, [hl]
+ ld [hl], b
+ dec hl
+ dec a
+ jr nz, .loop
+ ret
+
+ScrollTileDown:
+ ld h, d
+ ld l, e
+ ld de, TILE_WIDTH * 2 - 2
+ push hl
+ add hl, de
+ ld d, [hl]
+ inc hl
+ ld e, [hl]
+ pop hl
+ ld a, TILE_WIDTH / 2
+.loop
+ ld b, [hl]
+ ld [hl], d
+ inc hl
+ ld c, [hl]
+ ld [hl], e
+ inc hl
+ ld d, [hl]
+ ld [hl], b
+ inc hl
+ ld e, [hl]
+ ld [hl], c
+ inc hl
+ dec a
+ jr nz, .loop
+ ret
+
+AnimateWaterTile:
+; Draw a water tile for the current frame in VRAM tile at de.
+
+; Save sp in bc (see WriteTile).
+ ld hl, sp+0
+ ld b, h
+ ld c, l
+
+ ld a, [wTileAnimationTimer]
+
+; 4 tile graphics, updated every other frame.
+ and %110
+
+; 2 x 8 = 16 bytes per tile
+ add a
+ add a
+ add a
+
+ add LOW(WaterTileFrames)
+ ld l, a
+ ld a, 0
+ adc HIGH(WaterTileFrames)
+ ld h, a
+
+; The stack now points to the start of the tile for this frame.
+ ld sp, hl
+
+ ld l, e
+ ld h, d
+
+ jp WriteTile
+
+WaterTileFrames:
+ INCBIN "gfx/tilesets/water/water.2bpp"
+
+AnimateFlowerTile:
+; No parameters.
+
+; Save sp in bc (see WriteTile).
+ ld hl, sp+0
+ ld b, h
+ ld c, l
+
+; Alternate tile graphic every other frame
+ ld a, [wTileAnimationTimer]
+ and %10
+
+; CGB has different color mappings for flowers.
+ ld e, a
+ ldh a, [hCGB]
+ and 1
+ add e
+
+ swap a
+ ld e, a
+ ld d, 0
+ ld hl, FlowerTileFrames
+ add hl, de
+ ld sp, hl
+
+ ld hl, vTiles2 tile $03
+
+ jp WriteTile
+
+FlowerTileFrames:
+ INCBIN "gfx/tilesets/flower/dmg_1.2bpp"
+ INCBIN "gfx/tilesets/flower/cgb_1.2bpp"
+ INCBIN "gfx/tilesets/flower/dmg_2.2bpp"
+ INCBIN "gfx/tilesets/flower/cgb_2.2bpp"
+
+LavaBubbleAnim1:
+; Splash in the bottom-right corner of the fountain.
+ ld hl, sp+0
+ ld b, h
+ ld c, l
+ ld a, [wTileAnimationTimer]
+ and %110
+ srl a
+ inc a
+ inc a
+ and %011
+ swap a
+ ld e, a
+ ld d, 0
+ ld hl, LavaBubbleFrames
+ add hl, de
+ ld sp, hl
+ ld hl, vTiles2 tile $5b
+ jp WriteTile
+
+LavaBubbleAnim2:
+; Splash in the top-left corner of the fountain.
+ ld hl, sp+0
+ ld b, h
+ ld c, l
+ ld a, [wTileAnimationTimer]
+ and %110
+ add a
+ add a
+ add a
+ ld e, a
+ ld d, 0
+ ld hl, LavaBubbleFrames
+ add hl, de
+ ld sp, hl
+ ld hl, vTiles2 tile $38
+ jp WriteTile
+
+LavaBubbleFrames:
+ INCBIN "gfx/tilesets/lava/1.2bpp"
+ INCBIN "gfx/tilesets/lava/2.2bpp"
+ INCBIN "gfx/tilesets/lava/3.2bpp"
+ INCBIN "gfx/tilesets/lava/4.2bpp"
+
+AnimateTowerPillarTile:
+; Read from struct at de:
+; Destination (VRAM)
+; Address of the first tile in the frame array
+
+ ld hl, sp+0
+ ld b, h
+ ld c, l
+
+ ld a, [wTileAnimationTimer]
+ and %111
+
+; Get frame index a
+ ld hl, .frames
+ add l
+ ld l, a
+ ld a, 0
+ adc h
+ ld h, a
+ ld a, [hl]
+
+; Destination
+ ld l, e
+ ld h, d
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+
+; Add the frame index to the starting address
+ add [hl]
+ inc hl
+ ld h, [hl]
+ ld l, a
+ ld a, 0
+ adc h
+ ld h, a
+
+ ld sp, hl
+ ld l, e
+ ld h, d
+ jr WriteTile
+
+.frames
+ db $00, $10, $20, $30, $40, $30, $20, $10
+
+StandingTileFrame:
+ ld hl, wTileAnimationTimer
+ inc [hl]
+ ret
+
+AnimateWhirlpoolTile:
+; Update whirlpool tile using struct at de.
+
+; Struct:
+; VRAM address
+; Address of the first tile
+
+; Only does one of 4 tiles at a time.
+
+; Save sp in bc (see WriteTile).
+ ld hl, sp+0
+ ld b, h
+ ld c, l
+
+; de = VRAM address
+ ld l, e
+ ld h, d
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+; Tile address is now at hl.
+
+; Get the tile for this frame.
+ ld a, [wTileAnimationTimer]
+ and %11 ; 4 frames x2
+ swap a ; * 16 bytes per tile
+
+ add [hl]
+ inc hl
+ ld h, [hl]
+ ld l, a
+ ld a, 0
+ adc h
+ ld h, a
+
+; The stack now points to the desired frame.
+ ld sp, hl
+
+ ld l, e
+ ld h, d
+
+ jr WriteTile
+
+WriteTileFromBuffer:
+; Write tiledata at wTileAnimBuffer to de.
+; wTileAnimBuffer is loaded to sp for WriteTile.
+
+ ld hl, sp+0
+ ld b, h
+ ld c, l
+
+ ld hl, wTileAnimBuffer
+ ld sp, hl
+
+ ld h, d
+ ld l, e
+ jr WriteTile
+
+WriteTileToBuffer:
+; Write tiledata de to wTileAnimBuffer.
+; de is loaded to sp for WriteTile.
+
+ ld hl, sp+0
+ ld b, h
+ ld c, l
+
+ ld h, d
+ ld l, e
+ ld sp, hl
+
+ ld hl, wTileAnimBuffer
+
+ ; fallthrough
+
+WriteTile:
+; Write one 8x8 tile ($10 bytes) from sp to hl.
+
+; Warning: sp is saved in bc so we can abuse pop.
+; sp is restored to address bc. Save sp in bc before calling.
+
+ pop de
+ ld [hl], e
+ inc hl
+ ld [hl], d
+
+rept 7
+ pop de
+ inc hl
+ ld [hl], e
+ inc hl
+ ld [hl], d
+endr
+
+; restore sp
+ ld h, b
+ ld l, c
+ ld sp, hl
+ ret
+
+AnimateWaterPalette:
+; Transition between color values 0-2 for color 0 in palette 3.
+
+; No palette changes on DMG.
+ ldh a, [hCGB]
+ and a
+ ret z
+
+; We don't want to mess with non-standard palettes.
+ ldh a, [rBGP] ; BGP
+ cp %11100100
+ ret nz
+
+; Only update on even frames.
+ ld a, [wTileAnimationTimer]
+ ld l, a
+ and 1 ; odd
+ ret nz
+
+; Ready for BGPD input...
+
+ ld a, (1 << rBGPI_AUTO_INCREMENT) palette PAL_BG_WATER
+ ldh [rBGPI], a
+
+; Update color 0 in order 0 1 2 1
+ ld a, l
+ and %110 ; frames 0 2 4 6
+ jr z, .color0
+ cp %100 ; frame 4
+ jr z, .color2
+
+.color1
+ ld hl, wBGPals1 palette PAL_BG_WATER color 1
+ ld a, [hli]
+ ldh [rBGPD], a
+ ld a, [hli]
+ ldh [rBGPD], a
+ ret
+
+.color0
+ ld hl, wBGPals1 palette PAL_BG_WATER color 0
+ ld a, [hli]
+ ldh [rBGPD], a
+ ld a, [hli]
+ ldh [rBGPD], a
+ ret
+
+.color2
+ ld hl, wBGPals1 palette PAL_BG_WATER color 2
+ ld a, [hli]
+ ldh [rBGPD], a
+ ld a, [hli]
+ ldh [rBGPD], a
+ ret
+
+FlickeringCaveEntrancePalette:
+; No palette changes on DMG.
+ ldh a, [hCGB]
+ and a
+ ret z
+; We don't want to mess with non-standard palettes.
+ ldh a, [rBGP]
+ cp %11100100
+ ret nz
+; We only want to be here if we're in a dark cave.
+ ld a, [wTimeOfDayPalset]
+ cp %11111111 ; 3,3,3,3
+ ret nz
+
+; Ready for BGPD input...
+ ld a, (1 << rBGPI_AUTO_INCREMENT) palette PAL_BG_YELLOW
+ ldh [rBGPI], a
+ ldh a, [hVBlankCounter]
+ and %10
+ jr nz, .bit1set
+ ld hl, wBGPals1 palette PAL_BG_YELLOW
+ jr .okay
+
+.bit1set
+ ld hl, wBGPals1 palette PAL_BG_YELLOW color 1
+
+.okay
+ ld a, [hli]
+ ldh [rBGPD], a
+ ld a, [hli]
+ ldh [rBGPD], a
+ ret
+
+TowerPillarTilePointer1: dw vTiles2 tile $2d, TowerPillarTile1
+TowerPillarTilePointer2: dw vTiles2 tile $2f, TowerPillarTile2
+TowerPillarTilePointer3: dw vTiles2 tile $3d, TowerPillarTile3
+TowerPillarTilePointer4: dw vTiles2 tile $3f, TowerPillarTile4
+TowerPillarTilePointer5: dw vTiles2 tile $3c, TowerPillarTile5
+TowerPillarTilePointer6: dw vTiles2 tile $2c, TowerPillarTile6
+TowerPillarTilePointer7: dw vTiles2 tile $4d, TowerPillarTile7
+TowerPillarTilePointer8: dw vTiles2 tile $4f, TowerPillarTile8
+TowerPillarTilePointer9: dw vTiles2 tile $5d, TowerPillarTile9
+TowerPillarTilePointer10: dw vTiles2 tile $5f, TowerPillarTile10
+
+TowerPillarTile1: INCBIN "gfx/tilesets/tower-pillar/1.2bpp"
+TowerPillarTile2: INCBIN "gfx/tilesets/tower-pillar/2.2bpp"
+TowerPillarTile3: INCBIN "gfx/tilesets/tower-pillar/3.2bpp"
+TowerPillarTile4: INCBIN "gfx/tilesets/tower-pillar/4.2bpp"
+TowerPillarTile5: INCBIN "gfx/tilesets/tower-pillar/5.2bpp"
+TowerPillarTile6: INCBIN "gfx/tilesets/tower-pillar/6.2bpp"
+TowerPillarTile7: INCBIN "gfx/tilesets/tower-pillar/7.2bpp"
+TowerPillarTile8: INCBIN "gfx/tilesets/tower-pillar/8.2bpp"
+TowerPillarTile9: INCBIN "gfx/tilesets/tower-pillar/9.2bpp"
+TowerPillarTile10: INCBIN "gfx/tilesets/tower-pillar/10.2bpp"
+
+WhirlpoolFrames1: dw vTiles2 tile $32, WhirlpoolTiles1
+WhirlpoolFrames2: dw vTiles2 tile $33, WhirlpoolTiles2
+WhirlpoolFrames3: dw vTiles2 tile $42, WhirlpoolTiles3
+WhirlpoolFrames4: dw vTiles2 tile $43, WhirlpoolTiles4
+
+WhirlpoolTiles1: INCBIN "gfx/tilesets/whirlpool/1.2bpp"
+WhirlpoolTiles2: INCBIN "gfx/tilesets/whirlpool/2.2bpp"
+WhirlpoolTiles3: INCBIN "gfx/tilesets/whirlpool/3.2bpp"
+WhirlpoolTiles4: INCBIN "gfx/tilesets/whirlpool/4.2bpp"
+
+;unused
+ ret