summaryrefslogtreecommitdiff
path: root/engine/menu
diff options
context:
space:
mode:
Diffstat (limited to 'engine/menu')
-rw-r--r--engine/menu/bills_pc.asm585
-rwxr-xr-xengine/menu/diploma.asm109
-rwxr-xr-xengine/menu/league_pc.asm124
-rwxr-xr-xengine/menu/main_menu.asm726
-rwxr-xr-xengine/menu/naming_screen.asm515
-rwxr-xr-xengine/menu/oaks_pc.asm28
-rwxr-xr-xengine/menu/party_menu.asm328
-rwxr-xr-xengine/menu/pc.asm142
-rwxr-xr-xengine/menu/players_pc.asm302
-rwxr-xr-xengine/menu/pokedex.asm676
-rwxr-xr-xengine/menu/prize_menu.asm316
-rwxr-xr-xengine/menu/start_menu.asm88
-rwxr-xr-xengine/menu/start_sub_menus.asm875
-rwxr-xr-xengine/menu/status_screen.asm446
-rwxr-xr-xengine/menu/vending_machine.asm138
15 files changed, 5398 insertions, 0 deletions
diff --git a/engine/menu/bills_pc.asm b/engine/menu/bills_pc.asm
new file mode 100644
index 00000000..0c468a2b
--- /dev/null
+++ b/engine/menu/bills_pc.asm
@@ -0,0 +1,585 @@
+Func_213c8:: ; 213c8 (8:53c8)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ call SaveScreenTilesToBuffer2
+ ld a, [$d5a2]
+ and a
+ jr nz, .asm_213f3
+ ld a, [$d74b]
+ bit 5, a
+ jr z, .asm_213ea
+ ld a, [$d5a2]
+ and a
+ jr nz, .asm_213f3
+ ld hl, wTileMap
+ ld b, $8
+ ld c, $e
+ jr .asm_213fa
+.asm_213ea
+ ld hl, wTileMap
+ ld b, $6
+ ld c, $e
+ jr .asm_213fa
+.asm_213f3
+ ld hl, wTileMap
+ ld b, $a
+ ld c, $e
+.asm_213fa
+ call TextBoxBorder
+ call UpdateSprites
+ ld a, $3
+ ld [wMaxMenuItem], a ; $cc28
+ ld a, [$d7f1]
+ bit 0, a
+ jr nz, .asm_21414
+ FuncCoord 2, 2 ; $c3ca
+ ld hl, Coord
+ ld de, SomeonesPCText ; $548b
+ jr .asm_2141a
+.asm_21414
+ FuncCoord 2, 2 ; $c3ca
+ ld hl, Coord
+ ld de, BillsPCText ; $5497
+.asm_2141a
+ call PlaceString
+ FuncCoord 2, 4 ; $c3f2
+ ld hl, Coord
+ ld de, W_PLAYERNAME ; $d158
+ call PlaceString
+ ld l, c
+ ld h, b
+ ld de, PlayersPCText ; $54a0
+ call PlaceString
+ ld a, [$d74b]
+ bit 5, a
+ jr z, .asm_21462
+ FuncCoord 2, 6 ; $c41a
+ ld hl, Coord
+ ld de, OaksPCText ; $54a5
+ call PlaceString
+ ld a, [$d5a2]
+ and a
+ jr z, .asm_2145a
+ ld a, $4
+ ld [wMaxMenuItem], a ; $cc28
+ FuncCoord 2, 8 ; $c442
+ ld hl, Coord
+ ld de, PKMNLeaguePCText ; $54b2
+ call PlaceString
+ FuncCoord 2, 10 ; $c46a
+ ld hl, Coord
+ ld de, LogOffPCText ; $54ba
+ jr .asm_2146d
+.asm_2145a
+ FuncCoord 2, 8 ; $c442
+ ld hl, Coord
+ ld de, LogOffPCText ; $54ba
+ jr .asm_2146d
+.asm_21462
+ ld a, $2
+ ld [wMaxMenuItem], a ; $cc28
+ FuncCoord 2, 6 ; $c41a
+ ld hl, Coord
+ ld de, LogOffPCText ; $54ba
+.asm_2146d
+ call PlaceString
+ ld a, $3
+ ld [wMenuWatchedKeys], a ; $cc29
+ ld a, $2
+ ld [wTopMenuItemY], a ; $cc24
+ ld a, $1
+ ld [wTopMenuItemX], a ; $cc25
+ xor a
+ ld [wCurrentMenuItem], a ; $cc26
+ ld [wLastMenuItem], a ; $cc2a
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ret
+
+SomeonesPCText: ; 2148b (8:548b)
+ db "SOMEONE's PC@"
+
+BillsPCText: ; 21497 (8:5497)
+ db "BILL's PC@"
+
+PlayersPCText: ; 214a0 (8:54a0)
+ db "'s PC@"
+
+OaksPCText: ; 214a5 (8:54a5)
+ db "PROF.OAK's PC@"
+
+PKMNLeaguePCText: ; 214b2 (8:54b2)
+ db $4a,"LEAGUE@"
+
+LogOffPCText: ; 214ba (8:54ba)
+ db "LOG OFF@"
+
+Func_214c2:: ; 214c2 (8:54c2)
+BillsPC_:: ; 0x214c2
+ ld hl, $d730
+ set 6, [hl]
+ xor a
+ ld [$ccd3], a
+ inc a ; MONSTER_NAME
+ ld [W_LISTTYPE], a
+ call LoadHpBarAndStatusTilePatterns
+ ld a, [wListScrollOffset] ; $cc36
+ push af
+ ld a, [wFlags_0xcd60]
+ bit 3, a
+ jr nz, BillsPCMenu
+ ld a, $99
+ call PlaySound
+ ld hl, SwitchOnText
+ call PrintText
+
+Func_214e8: ; 214e8 (8:54e8)
+BillsPCMenu:
+ ld a, [$ccd3]
+ ld [wCurrentMenuItem], a ; $cc26
+ ld hl, $9780
+ ld de, PokeballTileGraphics ; $697e
+ ld bc, (BANK(PokeballTileGraphics) << 8) + $01
+ call CopyVideoData
+ call LoadScreenTilesFromBuffer2DisableBGTransfer
+ ld hl, wTileMap
+ ld b, $a
+ ld c, $c
+ call TextBoxBorder
+ FuncCoord 2, 2 ; $c3ca
+ ld hl, Coord
+ ld de, BillsPCMenuText ; $56e1
+ call PlaceString
+ ld hl, wTopMenuItemY ; $cc24
+ ld a, $2
+ ld [hli], a
+ dec a
+ ld [hli], a
+ inc hl
+ inc hl
+ ld a, $4
+ ld [hli], a
+ ld a, $3
+ ld [hli], a
+ xor a
+ ld [hli], a
+ ld [hli], a
+ ld hl, wListScrollOffset ; $cc36
+ ld [hli], a
+ ld [hl], a
+ ld [wPlayerMonNumber], a ; $cc2f
+ ld hl, WhatText
+ call PrintText
+ FuncCoord 9, 14 ; $c4c1
+ ld hl, Coord
+ ld b, $2
+ ld c, $9
+ call TextBoxBorder
+ ld a, [$d5a0]
+ and $7f
+ cp $9
+ jr c, .asm_2154f
+ sub $9
+ FuncCoord 17, 16 ; $c4f1
+ ld hl, Coord
+ ld [hl], $f7
+ add $f6
+ jr .asm_21551
+.asm_2154f
+ add $f7
+.asm_21551
+ FuncCoord 18, 16 ; $c4f2
+ ld [Coord], a
+ FuncCoord 10, 16 ; $c4ea
+ ld hl, Coord
+ ld de, BoxNoPCText ; $5713
+ call PlaceString
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ call Delay3
+ call HandleMenuInput
+ bit 1, a
+ jp nz, Func_21588 ; b button
+ call PlaceUnfilledArrowMenuCursor
+ ld a, [wCurrentMenuItem] ; $cc26
+ ld [$ccd3], a
+ and a
+ jp z, Func_21618 ; withdraw
+ cp $1
+ jp z, Func_215ac ; deposit
+ cp $2
+ jp z, Func_21673 ; release
+ cp $3
+ jp z, Func_216b3 ; change box
+
+Func_21588: ; 21588 (8:5588)
+ ld a, [wFlags_0xcd60]
+ bit 3, a
+ jr nz, .asm_2159a
+ call LoadTextBoxTilePatterns
+ ld a, $9a
+ call PlaySound
+ call WaitForSoundToFinish
+.asm_2159a
+ ld hl, wFlags_0xcd60
+ res 5, [hl]
+ call LoadScreenTilesFromBuffer2
+ pop af
+ ld [wListScrollOffset], a ; $cc36
+ ld hl, $d730
+ res 6, [hl]
+ ret
+
+Func_215ac: ; 215ac (8:55ac)
+BillsPCDeposit:
+ ld a, [W_NUMINPARTY] ; $d163
+ dec a
+ jr nz, .asm_215bb
+ ld hl, CantDepositLastMonText
+ call PrintText
+ jp BillsPCMenu
+.asm_215bb
+ ld a, [W_NUMINBOX] ; $da80
+ cp $14
+ jr nz, .asm_215cb
+ ld hl, BoxFullText ; $5802
+ call PrintText
+ jp BillsPCMenu
+.asm_215cb
+ ld hl, W_NUMINPARTY ; $d163
+ call Func_216be
+ jp c, BillsPCMenu
+ call Func_2174b
+ jp nc, BillsPCMenu
+ ld a, [$cf91]
+ call GetCryData
+ call PlaySoundWaitForCurrent
+ ld a, $1
+ ld [$cf95], a
+ call Func_3a68
+ xor a
+ ld [$cf95], a
+ call RemovePokemon
+ call WaitForSoundToFinish
+ ld hl, wWhichTrade ; $cd3d
+ ld a, [$d5a0]
+ and $7f
+ cp $9
+ jr c, .asm_2160a
+ sub $9
+ ld [hl], $f7
+ inc hl
+ add $f6
+ jr .asm_2160c
+.asm_2160a
+ add $f7
+.asm_2160c
+ ld [hli], a
+ ld [hl], $50
+ ld hl, MonWasStoredText ; $57f8
+ call PrintText
+ jp BillsPCMenu
+
+Func_21618: ; 21618 (8:5618)
+ ld a, [W_NUMINBOX] ; $da80
+ and a
+ jr nz, .asm_21627
+ ld hl, NoMonText ; $580c
+ call PrintText
+ jp Func_214e8
+.asm_21627
+ ld a, [W_NUMINPARTY] ; $d163
+ cp $6
+ jr nz, .asm_21637
+ ld hl, CantTakeMonText ; $5811
+ call PrintText
+ jp Func_214e8
+.asm_21637
+ ld hl, W_NUMINBOX ; $da80
+ call Func_216be
+ jp c, Func_214e8
+ call Func_2174b
+ jp nc, Func_214e8
+ ld a, [wWhichPokemon] ; $cf92
+ ld hl, $de06
+ call GetPartyMonName
+ ld a, [$cf91]
+ call GetCryData
+ call PlaySoundWaitForCurrent
+ xor a
+ ld [$cf95], a
+ call Func_3a68
+ ld a, $1
+ ld [$cf95], a
+ call RemovePokemon
+ call WaitForSoundToFinish
+ ld hl, MonIsTakenOutText ; $5807
+ call PrintText
+ jp Func_214e8
+
+Func_21673: ; 21673 (8:5673)
+ ld a, [W_NUMINBOX] ; $da80
+ and a
+ jr nz, .asm_21682
+ ld hl, NoMonText ; $580c
+ call PrintText
+ jp Func_214e8
+.asm_21682
+ ld hl, W_NUMINBOX ; $da80
+ call Func_216be
+ jp c, Func_214e8
+ ld hl, OnceReleasedText ; $581b
+ call PrintText
+ call YesNoChoice
+ ld a, [wCurrentMenuItem] ; $cc26
+ and a
+ jr nz, .asm_21682
+ inc a
+ ld [$cf95], a
+ call RemovePokemon
+ call WaitForSoundToFinish
+ ld a, [$cf91]
+ call PlayCry
+ ld hl, MonWasReleasedText ; $5820
+ call PrintText
+ jp Func_214e8
+
+Func_216b3: ; 216b3 (8:56b3)
+ callba Func_738a1
+ jp Func_214e8
+
+Func_216be: ; 216be (8:56be)
+ ld a, l
+ ld [$cf8b], a
+ ld a, h
+ ld [$cf8c], a
+ xor a
+ ld [$cf93], a
+ ld [wListMenuID], a ; $cf94
+ inc a ; MONSTER_NAME
+ ld [W_LISTTYPE], a
+ ld a, [$cc2b]
+ ld [wCurrentMenuItem], a ; $cc26
+ call DisplayListMenuID
+ ld a, [wCurrentMenuItem] ; $cc26
+ ld [$cc2b], a
+ ret
+
+BillsPCMenuText: ; 216e1 (8:56e1)
+ db "WITHDRAW ",$4a,$4e,"DEPOSIT ",$4a,$4e,"RELEASE ",$4a,$4e,"CHANGE BOX",$4e,"SEE YA!@"
+
+BoxNoPCText: ; 21713 (8:5713)
+ db "BOX No.@"
+
+Func_2171b:: ; 2171b (8:571b)
+ ld hl, $d173
+ ld bc, $002c
+ jr .asm_21729 ; 0x21721 $6
+ ld hl, $da9e
+ ld bc, $0021
+.asm_21729
+ ld a, [$cf92]
+ call AddNTimes
+ ld b, $4
+.asm_21731
+ ld a, [hli]
+ push hl
+ push bc
+ ld hl, HMMoveArray ; $5745
+ ld de, $0001
+ call IsInArray
+ pop bc
+ pop hl
+ ret c
+ dec b
+ jr nz, .asm_21731 ; 0x21741 $ee
+ and a
+ ret
+
+HMMoveArray: ; 21745 (8:5745)
+ db CUT
+ db FLY
+ db SURF
+ db STRENGTH
+ db FLASH
+ db $ff
+
+Func_2174b: ; 2174b (8:574b)
+ FuncCoord 9, 10 ; $c471
+ ld hl, Coord
+ ld b, $6
+ ld c, $9
+ call TextBoxBorder
+ ld a, [$ccd3]
+ and a
+ ld de, DepositPCText ; $57cb
+ jr nz, .asm_21761
+ ld de, WithdrawPCText ; $57d3
+.asm_21761
+ FuncCoord 11, 12 ; $c49b
+ ld hl, Coord
+ call PlaceString
+ FuncCoord 11, 14 ; $c4c3
+ ld hl, Coord
+ ld de, StatsCancelPCText ; $57dc
+ call PlaceString
+ ld hl, wTopMenuItemY ; $cc24
+ ld a, $c
+ ld [hli], a
+ ld a, $a
+ ld [hli], a
+ xor a
+ ld [hli], a
+ inc hl
+ ld a, $2
+ ld [hli], a
+ ld a, $3
+ ld [hli], a
+ xor a
+ ld [hl], a
+ ld hl, wListScrollOffset ; $cc36
+ ld [hli], a
+ ld [hl], a
+ ld [wPlayerMonNumber], a ; $cc2f
+ ld [$cc2b], a
+.asm_2178f
+ call HandleMenuInput
+ bit 1, a
+ jr nz, .asm_2179f
+ ld a, [wCurrentMenuItem] ; $cc26
+ and a
+ jr z, .asm_217a1
+ dec a
+ jr z, .asm_217a3
+.asm_2179f
+ and a
+ ret
+.asm_217a1
+ scf
+ ret
+.asm_217a3
+ call SaveScreenTilesToBuffer1
+ ld a, [$ccd3]
+ and a
+ ld a, $0
+ jr nz, .asm_217b0
+ ld a, $2
+.asm_217b0
+ ld [$cc49], a
+ ld a, $36
+ call Predef ; indirect jump to StatusScreen (12953 (4:6953))
+ ld a, $37
+ call Predef ; indirect jump to StatusScreen2 (12b57 (4:6b57))
+ call LoadScreenTilesFromBuffer1
+ call ReloadTilesetTilePatterns
+ call GoPAL_SET_CF1C
+ call LoadGBPal
+ jr .asm_2178f
+
+DepositPCText: ; 217cb (8:57cb)
+ db "DEPOSIT@"
+
+WithdrawPCText: ; 217d3 (8:57d3)
+ db "WITHDRAW@"
+
+StatsCancelPCText: ; 217dc (8:57dc)
+ db "STATS",$4e,"CANCEL@"
+
+SwitchOnText: ; 0x217e9
+ TX_FAR _SwitchOnText
+ db "@"
+
+WhatText: ; 0x217ee
+ TX_FAR _WhatText
+ db "@"
+
+DepositWhichMonText: ; 0x217f3
+ TX_FAR _DepositWhichMonText
+ db "@"
+
+MonWasStoredText: ; 0x217f8
+ TX_FAR _MonWasStoredText
+ db "@"
+
+CantDepositLastMonText: ; 0x217fd
+ TX_FAR _CantDepositLastMonText
+ db "@"
+
+BoxFullText: ; 0x21802
+ TX_FAR _BoxFullText
+ db "@"
+
+MonIsTakenOutText: ; 0x21807
+ TX_FAR _MonIsTakenOutText
+ db "@"
+
+NoMonText: ; 0x2180c
+ TX_FAR _NoMonText
+ db "@"
+
+CantTakeMonText: ; 0x21811
+ TX_FAR _CantTakeMonText
+ db "@"
+
+ReleaseWhichMonText: ; 0x21816
+ TX_FAR _ReleaseWhichMonText
+ db "@"
+
+OnceReleasedText: ; 0x2181b
+ TX_FAR _OnceReleasedText
+ db "@"
+
+MonWasReleasedText: ; 0x21820
+ TX_FAR _MonWasReleasedText
+ db "@"
+
+PrintJustAMomentText1:: ; 5824 (8:5825)
+ ld a, [$ffaa]
+ cp $1
+ ret z
+ ld a, [$c109]
+ cp $c
+ ret nz
+ ld a, [$d35e]
+ cp $ef
+ ld a, $2
+ jr z, .asm_2183a
+ inc a
+.asm_2183a
+ ld [$d12b], a
+ call EnableAutoTextBoxDrawing
+ ld a, $22
+ jp PrintPredefTextID
+
+PrintJustAMomentText2:: ; 5845 (8:5845)
+ ld a, [$ffaa]
+ cp $2
+ ret z
+ ld a, [$c109]
+ cp $8
+ ret nz
+ ld a, [$d35e]
+ cp $ef
+ ld a, $2
+ jr z, .asm_2185a
+ inc a
+.asm_2185a
+ ld [$d12b], a
+ call EnableAutoTextBoxDrawing
+ ld a, $22
+ jp PrintPredefTextID
+
+JustAMomentText:: ; 21865 (8:5865)
+ TX_FAR _JustAMomentText
+ db "@"
+
+ ld a, [$c109]
+ cp $4
+ ret nz
+ call EnableAutoTextBoxDrawing
+ ld a, $23
+ jp PrintPredefTextID
+
+PredefText23:: ; 21878 (8:5878)
+ db $FD ; FuncTX_BillsPC
+
diff --git a/engine/menu/diploma.asm b/engine/menu/diploma.asm
new file mode 100755
index 00000000..3b9413a2
--- /dev/null
+++ b/engine/menu/diploma.asm
@@ -0,0 +1,109 @@
+DisplayDiploma: ; 566e2 (15:66e2)
+ call SaveScreenTilesToBuffer2
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ xor a
+ ld [$cfcb], a
+ ld hl, $d730
+ set 6, [hl]
+ call DisableLCD
+ ld hl, CircleTile ; $7d88
+ ld de, $9700
+ ld bc, $0010
+ ld a, BANK(CircleTile)
+ call FarCopyData2
+ ld hl, wTileMap
+ ld bc, $1012
+ ld a, $27
+ call Predef
+ ld hl, DiplomaTextPointersAndCoords ; $6784
+ ld c, $5
+.asm_56715
+ push bc
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ push hl
+ ld h, [hl]
+ ld l, a
+ call PlaceString
+ pop hl
+ inc hl
+ pop bc
+ dec c
+ jr nz, .asm_56715 ; 0x56725 $ee
+ FuncCoord 10, 4 ; $c3fa
+ ld hl, Coord
+ ld de, W_PLAYERNAME
+ call PlaceString
+ callba Func_44dd
+ ld hl, $c301
+ ld bc, $8028
+.asm_5673e
+ ld a, [hl]
+ add $21
+ ld [hli], a
+ inc hl
+ ld a, b
+ ld [hli], a
+ inc hl
+ dec c
+ jr nz, .asm_5673e ; 0x56747 $f5
+ call EnableLCD
+ callba LoadTrainerInfoTextBoxTiles
+ ld b, $8
+ call GoPAL_SET
+ call Delay3
+ call GBPalNormal
+ ld a, $90
+ ld [$ff48], a
+ call WaitForTextScrollButtonPress
+ ld hl, $d730
+ res 6, [hl]
+ call GBPalWhiteOutWithDelay3
+ call Func_3dbe
+ call Delay3
+ jp GBPalNormal
+
+Func_56777: ; 56777 (15:6777)
+ ld hl, W_PLAYERNAME
+ ld bc, $ff00
+.asm_5677d
+ ld a, [hli]
+ cp $50
+ ret z
+ dec c
+ jr .asm_5677d ; 0x56782 $f9
+
+DiplomaTextPointersAndCoords: ; 56784 (15:6784)
+ dw DiplomaText
+ dw $c3cd
+ dw DiplomaPlayer
+ dw $c3f3
+ dw DiplomaEmptyText
+ dw $c3ff
+ dw DiplomaCongrats
+ dw $c41a
+ dw DiplomaGameFreak
+ dw $c4e9
+
+DiplomaText:
+ db $70,"Diploma",$70,"@"
+
+DiplomaPlayer:
+ db "Player@"
+
+DiplomaEmptyText:
+ db "@"
+
+DiplomaCongrats:
+ db "Congrats! This"
+ next "diploma certifies"
+ next "that you have"
+ next "completed your"
+ next "#DEX.@"
+
+DiplomaGameFreak:
+ db "GAME FREAK@"
diff --git a/engine/menu/league_pc.asm b/engine/menu/league_pc.asm
new file mode 100755
index 00000000..5e4e3436
--- /dev/null
+++ b/engine/menu/league_pc.asm
@@ -0,0 +1,124 @@
+PKMNLeaguePC: ; 0x7657e
+ ld hl, AccessedHoFPCText
+ call PrintText
+ ld hl, $D730
+ set 6, [hl]
+ push hl
+ ld a, [$CFCB]
+ push af
+ ld a, [$ffD7]
+ push af
+ xor a
+ ld [$ffD7], a
+ ld [W_SPRITEFLIPPED], a
+ ld [$CFCB], a
+ ld [$CD41], a
+ ld [$CD42], a
+ ld a, [$D5A2]
+ ld b, a
+ cp a, $33
+ jr c, .first
+ ld b, $32
+ sub b
+ ld [$CD42], a
+.first
+ ld hl, $CD42
+ inc [hl]
+ push bc
+ ld a, [$CD41]
+ ld [$CD3D], a
+ callba Func_73b3f
+ call Func_765e5
+ pop bc
+ jr c, .second
+ ld hl, $CD41
+ inc [hl]
+ ld a, [hl]
+ cp b
+ jr nz, .first
+.second
+ pop af
+ ld [$ffD7], a
+ pop af
+ ld [$CFCB], a
+ pop hl
+ res 6, [hl]
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ call GoPAL_SET_CF1C
+ jp GBPalNormal
+
+Func_765e5: ; 765e5 (1d:65e5)
+ ld c, 6
+.third
+ push bc
+ call Func_76610
+ call WaitForTextScrollButtonPress
+ ld a, [H_CURRENTPRESSEDBUTTONS]
+ bit 1, a
+ jr nz, .fifth
+ ld hl, $CC6B
+ ld de, $CC5B
+ ld bc, $0050
+ call CopyData
+ pop bc
+ ld a, [$CC5B]
+ cp a, $FF
+ jr z, .fourth
+ dec c
+ jr nz, .third
+.fourth
+ and a
+ ret
+.fifth
+ pop bc
+ scf
+ ret
+
+Func_76610: ; 76610 (1d:6610)
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ ld hl, $CC5B
+ ld a, [hli]
+ ld [$CD3D], a
+ ld [$CF91], a
+ ld [$D0B5], a
+ ld [$CFD9], a
+ ld [$CF1D], a
+ ld a, [hli]
+ ld [$CD3F], a
+ ld de, $CD6D
+ ld bc, $000B
+ call CopyData
+ ld b, $0B
+ ld c, 0
+ call GoPAL_SET
+ FuncCoord 12, 5 ; $c410
+ ld hl, Coord
+ call GetMonHeader
+ call LoadFrontSpriteByMonIndex
+ call GBPalNormal
+ FuncCoord 0, 13 ; $c4a4
+ ld hl, Coord
+ ld b, 2
+ ld c, $12
+ call TextBoxBorder
+ FuncCoord 1, 15 ; $c4cd
+ ld hl, Coord
+ ld de, HallOfFameNoText
+ call PlaceString
+ FuncCoord 16, 15 ; $c4dc
+ ld hl, Coord
+ ld de, $CD42
+ ld bc, $0103
+ call PrintNumber
+ ld b, BANK(Func_702f0)
+ ld hl, Func_702f0
+ jp Bankswitch
+
+HallOfFameNoText: ; 76670 (1d:6670)
+ db "HALL OF FAME No @"
+
+AccessedHoFPCText: ; 76683 (1d:6683)
+ TX_FAR _AccessedHoFPCText
+ db "@"
diff --git a/engine/menu/main_menu.asm b/engine/menu/main_menu.asm
new file mode 100755
index 00000000..7e34feca
--- /dev/null
+++ b/engine/menu/main_menu.asm
@@ -0,0 +1,726 @@
+MainMenu: ; 5af2 (1:5af2)
+; Check save file
+ call Func_5bff
+ xor a
+ ld [$D08A],a
+ inc a
+ ld [$D088],a
+ call Func_609e
+ jr nc,.next0
+
+ ; Predef 52 loads the save from SRAM to RAM
+ ld a,$52
+ call Predef
+
+.next0
+ ld c,20
+ call DelayFrames
+ xor a
+ ld [$D12B],a
+ ld hl,$CC2B
+ ld [hli],a
+ ld [hli],a
+ ld [hli],a
+ ld [hl],a
+ ld [$D07C],a
+ ld hl,$D72E
+ res 6,[hl]
+ call ClearScreen
+ call GoPAL_SET_CF1C
+ call LoadTextBoxTilePatterns
+ call LoadFontTilePatterns
+ ld hl,$D730
+ set 6,[hl]
+ ld a,[$D088]
+ cp a,1
+ jr z,.next1
+ FuncCoord 0,0
+ ld hl,Coord
+ ld b,6
+ ld c,13
+ call TextBoxBorder
+ FuncCoord 2,2
+ ld hl,Coord
+ ld de,ContinueText
+ call PlaceString
+ jr .next2
+.next1
+ FuncCoord 0,0
+ ld hl,Coord
+ ld b,4
+ ld c,13
+ call TextBoxBorder
+ FuncCoord 2,2
+ ld hl,Coord
+ ld de,NewGameText
+ call PlaceString
+.next2
+ ld hl,$D730
+ res 6,[hl]
+ call UpdateSprites ; OAM?
+ xor a
+ ld [$CC26],a
+ ld [$CC2A],a
+ ld [$CC34],a
+ inc a
+ ld [$CC25],a
+ inc a
+ ld [$CC24],a
+ ld a,$B
+ ld [$CC29],a
+ ld a,[$D088]
+ ld [$CC28],a
+ call HandleMenuInput
+ bit 1,a
+ jp nz,LoadTitlescreenGraphics ; load title screen (gfx and arrangement)
+ ld c,20
+ call DelayFrames
+ ld a,[$CC26]
+ ld b,a
+ ld a,[$D088]
+ cp a,2
+ jp z,.next3
+ inc b ; adjust MenuArrow_Counter
+.next3
+ ld a,b
+ and a
+ jr z,.next4 ; if press_A on Continue
+ cp a,1
+ jp z,Func_5d52 ; if press_A on NewGame
+ call DisplayOptionMenu ; if press_a on Options
+ ld a,1
+ ld [$D08A],a
+ jp .next0
+.next4
+ call ContinueGame
+ ld hl,$D126
+ set 5,[hl]
+.next6
+ xor a
+ ld [H_NEWLYPRESSEDBUTTONS],a
+ ld [H_NEWLYRELEASEDBUTTONS],a
+ ld [H_CURRENTPRESSEDBUTTONS],a
+ call GetJoypadState
+ ld a,[H_CURRENTPRESSEDBUTTONS]
+ bit 0,a
+ jr nz,.next5
+ bit 1,a
+ jp nz,.next0
+ jr .next6
+.next5
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ ld a,4
+ ld [$D52A],a
+ ld c,10
+ call DelayFrames
+ ld a,[$D5A2]
+ and a
+ jp z,Func_5d5f
+ ld a,[W_CURMAP] ; map ID
+ cp a,HALL_OF_FAME
+ jp nz,Func_5d5f
+ xor a
+ ld [$D71A],a
+ ld hl,$D732
+ set 2,[hl]
+ call Func_62ce
+ jp Func_5d5f
+Func_5bff: ; 5bff (1:5bff)
+ ld a,1
+ ld [$D358],a
+ ld a,3
+ ld [$D355],a
+ ret
+
+LinkMenu: ; 5c0a (1:5c0a)
+ xor a
+ ld [$d358], a
+ ld hl, $d72e
+ set 6, [hl]
+ ld hl, TextTerminator_6b20 ; $6b20
+ call PrintText
+ call SaveScreenTilesToBuffer1
+ ld hl, WhereWouldYouLikeText
+ call PrintText
+ FuncCoord 5, 5 ; $c409
+ ld hl, Coord
+ ld b, $6
+ ld c, $d
+ call TextBoxBorder
+ call UpdateSprites
+ FuncCoord 7, 7 ; $c433
+ ld hl, Coord
+ ld de, TradeCenterText
+ call PlaceString
+ xor a
+ ld [$cd37], a
+ ld [$d72d], a
+ ld hl, wTopMenuItemY ; $cc24
+ ld a, $7
+ ld [hli], a
+ ld a, $6
+ ld [hli], a
+ xor a
+ ld [hli], a
+ inc hl
+ ld a, $2
+ ld [hli], a
+ inc a
+ ld [hli], a
+ xor a
+ ld [hl], a
+.asm_5c52
+ call HandleMenuInput
+ and $3
+ add a
+ add a
+ ld b, a
+ ld a, [wCurrentMenuItem] ; $cc26
+ add b
+ add $d0
+ ld [$cc42], a
+ ld [$cc43], a
+.asm_5c66
+ call Func_2247
+ ld a, [$cc3d]
+ ld b, a
+ and $f0
+ cp $d0
+ jr z, .asm_5c7d
+ ld a, [$cc3e]
+ ld b, a
+ and $f0
+ cp $d0
+ jr nz, .asm_5c66
+.asm_5c7d
+ ld a, b
+ and $c
+ jr nz, .asm_5c8b
+ ld a, [$cc42]
+ and $c
+ jr z, .asm_5c52
+ jr .asm_5ca1
+.asm_5c8b
+ ld a, [$cc42]
+ and $c
+ jr z, .asm_5c98
+ ld a, [$ffaa]
+ cp $2
+ jr z, .asm_5ca1
+.asm_5c98
+ ld a, b
+ ld [$cc42], a
+ and $3
+ ld [wCurrentMenuItem], a ; $cc26
+.asm_5ca1
+ ld a, [$ffaa]
+ cp $2
+ jr nz, .asm_5cb1
+ call DelayFrame
+ call DelayFrame
+ ld a, $81
+ ld [$ff02], a
+.asm_5cb1
+ ld b, $7f
+ ld c, $7f
+ ld d, $ec
+ ld a, [$cc42]
+ and $8
+ jr nz, .asm_5ccc
+ ld a, [wCurrentMenuItem] ; $cc26
+ cp $2
+ jr z, .asm_5ccc
+ ld c, d
+ ld d, b
+ dec a
+ jr z, .asm_5ccc
+ ld b, c
+ ld c, d
+.asm_5ccc
+ ld a, b
+ FuncCoord 6, 7 ; $c432
+ ld [Coord], a
+ ld a, c
+ FuncCoord 6, 9 ; $c45a
+ ld [Coord], a
+ ld a, d
+ FuncCoord 6, 11 ; $c482
+ ld [Coord], a
+ ld c, $28
+ call DelayFrames
+ call LoadScreenTilesFromBuffer1
+ ld a, [$cc42]
+ and $8
+ jr nz, .asm_5d2d
+ ld a, [wCurrentMenuItem] ; $cc26
+ cp $2
+ jr z, .asm_5d2d
+ xor a
+ ld [$d700], a
+ ld a, [wCurrentMenuItem] ; $cc26
+ and a
+ ld a, TRADE_CENTER
+ jr nz, .asm_5cfc
+ ld a, BATTLE_CENTER
+.asm_5cfc
+ ld [$d72d], a
+ ld hl, PleaseWaitText
+ call PrintText
+ ld c, $32
+ call DelayFrames
+ ld hl, $d732
+ res 1, [hl]
+ ld a, [W_ANIMATIONID] ; $d07c
+ ld [$d71a], a
+ call Func_62ce
+ ld c, $14
+ call DelayFrames
+ xor a
+ ld [wMenuJoypadPollCount], a ; $cc34
+ ld [$cc42], a
+ inc a
+ ld [W_ISLINKBATTLE], a ; $d12b
+ ld [$cc47], a
+ jr Func_5d5f
+.asm_5d2d
+ xor a
+ ld [wMenuJoypadPollCount], a ; $cc34
+ call Delay3
+ call Func_72d7
+ ld hl, LinkCanceledText
+ call PrintText
+ ld hl, $d72e
+ res 6, [hl]
+ ret
+
+WhereWouldYouLikeText: ; 5d43 (1:5d43)
+ TX_FAR _WhereWouldYouLikeText
+ db "@"
+
+PleaseWaitText: ; 5d48 (1:5d48)
+ TX_FAR _PleaseWaitText
+ db "@"
+
+LinkCanceledText: ; 5d4d (1:5d4d)
+ TX_FAR _LinkCanceledText
+ db "@"
+
+Func_5d52: ; 5d52 (1:5d52)
+ ld hl, $d732
+ res 1, [hl]
+ call OakSpeech
+ ld c, $14
+ call DelayFrames
+
+Func_5d5f: ; 5d5f (1:5d5f)
+ xor a
+ ld [H_NEWLYPRESSEDBUTTONS], a
+ ld [H_CURRENTPRESSEDBUTTONS], a
+ ld [$ffb5], a
+ ld [$d72d], a
+ ld hl, $d732
+ set 0, [hl]
+ call ResetPlayerSpriteData
+ ld c, $14
+ call DelayFrames
+ ld a, [$cc47]
+ and a
+ ret nz
+ jp EnterMap
+
+ContinueText: ; 5d7e (1:5d7e)
+ db "CONTINUE", $4e
+
+NewGameText: ; 5d87 (1:5d87)
+ db "NEW GAME", $4e
+ db "OPTION@"
+
+TradeCenterText: ; 5d97 (1:5d97)
+ db "TRADE CENTER", $4e
+ db "COLOSSEUM", $4e
+ db "CANCEL@"
+
+ContinueGame: ; 5db5 (1:5db5)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ FuncCoord 4, 7 ; $c430
+ ld hl, Coord
+ ld b, $8
+ ld c, $e
+ call TextBoxBorder
+ FuncCoord 5, 9 ; $c459
+ ld hl, Coord
+ ld de, SaveScreenInfoText
+ call PlaceString
+ FuncCoord 12, 9 ; $c460
+ ld hl, Coord
+ ld de, W_PLAYERNAME ; $d158
+ call PlaceString
+ FuncCoord 17, 11 ; $c48d
+ ld hl, Coord
+ call Func_5e2f
+ FuncCoord 16, 13 ; $c4b4
+ ld hl, Coord
+ call Func_5e42
+ FuncCoord 13, 15 ; $c4d9
+ ld hl, Coord
+ call Func_5e55
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld c, $1e
+ jp DelayFrames
+
+PrintSaveScreenText: ; 5def (1:5def)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld hl, $c3a4
+ ld b, $8
+ ld c, $e
+ call TextBoxBorder
+ call LoadTextBoxTilePatterns
+ call UpdateSprites
+ ld hl, $c3cd
+ ld de, SaveScreenInfoText
+ call PlaceString
+ ld hl, $c3d4
+ ld de, W_PLAYERNAME
+ call PlaceString
+ ld hl, $c401
+ call Func_5e2f
+ ld hl, $c428
+ call Func_5e42
+ ld hl, $c44d
+ call Func_5e55
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld c, $1e
+ jp DelayFrames
+
+Func_5e2f: ; 5e2f (1:5e2f)
+ push hl
+ ld hl, W_OBTAINEDBADGES
+ ld b, $1
+ call CountSetBits
+ pop hl
+ ld de, $d11e
+ ld bc, $102
+ jp PrintNumber
+
+Func_5e42: ; 5e42 (1:5e42)
+ push hl
+ ld hl, wPokedexOwned ; $d2f7
+ ld b, wPokedexOwnedEnd - wPokedexOwned
+ call CountSetBits
+ pop hl
+ ld de, $d11e
+ ld bc, $103
+ jp PrintNumber
+
+Func_5e55: ; 5e55 (1:5e55)
+ ld de, $da41
+ ld bc, $103
+ call PrintNumber
+ ld [hl], $6d
+ inc hl
+ ld de, $da43
+ ld bc, $8102
+ jp PrintNumber
+
+SaveScreenInfoText: ; 5e6a (1:5e6a)
+ db "PLAYER"
+ next "BADGES "
+ next "#DEX "
+ next "TIME@"
+
+DisplayOptionMenu: ; 5e8a (1:5e8a)
+ FuncCoord 0,0
+ ld hl,Coord
+ ld b,3
+ ld c,18
+ call TextBoxBorder
+ FuncCoord 0,5
+ ld hl,Coord
+ ld b,3
+ ld c,18
+ call TextBoxBorder
+ FuncCoord 0,10
+ ld hl,Coord
+ ld b,3
+ ld c,18
+ call TextBoxBorder
+ FuncCoord 1,1
+ ld hl,Coord
+ ld de,TextSpeedOptionText
+ call PlaceString
+ FuncCoord 1,6
+ ld hl,Coord
+ ld de,BattleAnimationOptionText
+ call PlaceString
+ FuncCoord 1,11
+ ld hl,Coord
+ ld de,BattleStyleOptionText
+ call PlaceString
+ FuncCoord 2,16
+ ld hl,Coord
+ ld de,OptionMenuCancelText
+ call PlaceString
+ xor a
+ ld [wCurrentMenuItem],a
+ ld [wLastMenuItem],a
+ inc a
+ ld [$d358],a
+ ld [$cd40],a
+ ld a,3 ; text speed cursor Y coordinate
+ ld [wTopMenuItemY],a
+ call SetCursorPositionsFromOptions
+ ld a,[$cd3d] ; text speed cursor X coordinate
+ ld [wTopMenuItemX],a
+ ld a,$01
+ ld [H_AUTOBGTRANSFERENABLED],a ; enable auto background transfer
+ call Delay3
+.loop
+ call PlaceMenuCursor
+ call SetOptionsFromCursorPositions
+.getJoypadStateLoop
+ call GetJoypadStateLowSensitivity
+ ld a,[$ffb5]
+ ld b,a
+ and a,%11111011 ; any key besides select pressed?
+ jr z,.getJoypadStateLoop
+ bit 1,b ; B button pressed?
+ jr nz,.exitMenu
+ bit 3,b ; Start button pressed?
+ jr nz,.exitMenu
+ bit 0,b ; A button pressed?
+ jr z,.checkDirectionKeys
+ ld a,[wTopMenuItemY]
+ cp a,16 ; is the cursor on Cancel?
+ jr nz,.loop
+.exitMenu
+ ld a,(SFX_02_40 - SFX_Headers_02) / 3
+ call PlaySound ; play sound
+ ret
+.eraseOldMenuCursor
+ ld [wTopMenuItemX],a
+ call EraseMenuCursor
+ jp .loop
+.checkDirectionKeys
+ ld a,[wTopMenuItemY]
+ bit 7,b ; Down pressed?
+ jr nz,.downPressed
+ bit 6,b ; Up pressed?
+ jr nz,.upPressed
+ cp a,8 ; cursor in Battle Animation section?
+ jr z,.cursorInBattleAnimation
+ cp a,13 ; cursor in Battle Style section?
+ jr z,.cursorInBattleStyle
+ cp a,16 ; cursor on Cancel?
+ jr z,.loop
+.cursorInTextSpeed
+ bit 5,b ; Left pressed?
+ jp nz,.pressedLeftInTextSpeed
+ jp .pressedRightInTextSpeed
+.downPressed
+ cp a,16
+ ld b,-13
+ ld hl,$cd3d
+ jr z,.updateMenuVariables
+ ld b,5
+ cp a,3
+ inc hl
+ jr z,.updateMenuVariables
+ cp a,8
+ inc hl
+ jr z,.updateMenuVariables
+ ld b,3
+ inc hl
+ jr .updateMenuVariables
+.upPressed
+ cp a,8
+ ld b,-5
+ ld hl,$cd3d
+ jr z,.updateMenuVariables
+ cp a,13
+ inc hl
+ jr z,.updateMenuVariables
+ cp a,16
+ ld b,-3
+ inc hl
+ jr z,.updateMenuVariables
+ ld b,13
+ inc hl
+.updateMenuVariables
+ add b
+ ld [wTopMenuItemY],a
+ ld a,[hl]
+ ld [wTopMenuItemX],a
+ call PlaceUnfilledArrowMenuCursor
+ jp .loop
+.cursorInBattleAnimation
+ ld a,[$cd3e] ; battle animation cursor X coordinate
+ xor a,$0b ; toggle between 1 and 10
+ ld [$cd3e],a
+ jp .eraseOldMenuCursor
+.cursorInBattleStyle
+ ld a,[$cd3f] ; battle style cursor X coordinate
+ xor a,$0b ; toggle between 1 and 10
+ ld [$cd3f],a
+ jp .eraseOldMenuCursor
+.pressedLeftInTextSpeed
+ ld a,[$cd3d] ; text speed cursor X coordinate
+ cp a,1
+ jr z,.updateTextSpeedXCoord
+ cp a,7
+ jr nz,.fromSlowToMedium
+ sub a,6
+ jr .updateTextSpeedXCoord
+.fromSlowToMedium
+ sub a,7
+ jr .updateTextSpeedXCoord
+.pressedRightInTextSpeed
+ ld a,[$cd3d] ; text speed cursor X coordinate
+ cp a,14
+ jr z,.updateTextSpeedXCoord
+ cp a,7
+ jr nz,.fromFastToMedium
+ add a,7
+ jr .updateTextSpeedXCoord
+.fromFastToMedium
+ add a,6
+.updateTextSpeedXCoord
+ ld [$cd3d],a ; text speed cursor X coordinate
+ jp .eraseOldMenuCursor
+
+TextSpeedOptionText: ; 5fc0 (1:5fc0)
+ db "TEXT SPEED"
+ next " FAST MEDIUM SLOW@"
+
+BattleAnimationOptionText: ; 5fde (1:5fde)
+ db "BATTLE ANIMATION"
+ next " ON OFF@"
+
+BattleStyleOptionText: ; 5ffd (1:5ffd)
+ db "BATTLE STYLE"
+ next " SHIFT SET@"
+
+OptionMenuCancelText: ; 6018 (1:6018)
+ db "CANCEL@"
+
+; sets the options variable according to the current placement of the menu cursors in the options menu
+SetOptionsFromCursorPositions: ; 601f (1:601f)
+ ld hl,TextSpeedOptionData
+ ld a,[$cd3d] ; text speed cursor X coordinate
+ ld c,a
+.loop
+ ld a,[hli]
+ cp c
+ jr z,.textSpeedMatchFound
+ inc hl
+ jr .loop
+.textSpeedMatchFound
+ ld a,[hl]
+ ld d,a
+ ld a,[$cd3e] ; battle animation cursor X coordinate
+ dec a
+ jr z,.battleAnimationOn
+.battleAnimationOff
+ set 7,d
+ jr .checkBattleStyle
+.battleAnimationOn
+ res 7,d
+.checkBattleStyle
+ ld a,[$cd3f] ; battle style cursor X coordinate
+ dec a
+ jr z,.battleStyleShift
+.battleStyleSet
+ set 6,d
+ jr .storeOptions
+.battleStyleShift
+ res 6,d
+.storeOptions
+ ld a,d
+ ld [W_OPTIONS],a
+ ret
+
+; reads the options variable and places menu cursors in the correct positions within the options menu
+SetCursorPositionsFromOptions: ; 604c (1:604c)
+ ld hl,TextSpeedOptionData + 1
+ ld a,[W_OPTIONS]
+ ld c,a
+ and a,$3f
+ push bc
+ ld de,2
+ call IsInArray
+ pop bc
+ dec hl
+ ld a,[hl]
+ ld [$cd3d],a ; text speed cursor X coordinate
+ FuncCoord 0,3
+ ld hl,Coord
+ call .placeUnfilledRightArrow
+ sla c
+ ld a,1 ; On
+ jr nc,.storeBattleAnimationCursorX
+ ld a,10 ; Off
+.storeBattleAnimationCursorX
+ ld [$cd3e],a ; battle animation cursor X coordinate
+ FuncCoord 0,8
+ ld hl,Coord
+ call .placeUnfilledRightArrow
+ sla c
+ ld a,1
+ jr nc,.storeBattleStyleCursorX
+ ld a,10
+.storeBattleStyleCursorX
+ ld [$cd3f],a ; battle style cursor X coordinate
+ FuncCoord 0,13
+ ld hl,Coord
+ call .placeUnfilledRightArrow
+; cursor in front of Cancel
+ FuncCoord 0,16
+ ld hl,Coord
+ ld a,1
+.placeUnfilledRightArrow
+ ld e,a
+ ld d,0
+ add hl,de
+ ld [hl],$ec ; unfilled right arrow menu cursor
+ ret
+
+; table that indicates how the 3 text speed options affect frame delays
+; Format:
+; 00: X coordinate of menu cursor
+; 01: delay after printing a letter (in frames)
+TextSpeedOptionData: ; 6096 (1:6096)
+ db 14,5 ; Slow
+ db 7,3 ; Medium
+ db 1,1 ; Fast
+ db 7 ; default X coordinate (Medium)
+ db $ff ; terminator
+
+Func_609e: ; 609e (1:609e)
+ ld a, $a
+ ld [$0], a
+ ld a, $1
+ ld [$6000], a
+ ld [$4000], a
+ ld b, $b
+ ld hl, $a598
+.asm_60b0
+ ld a, [hli]
+ cp $50
+ jr z, .asm_60c1
+ dec b
+ jr nz, .asm_60b0
+ xor a
+ ld [$0], a
+ ld [$6000], a
+ and a
+ ret
+.asm_60c1
+ xor a
+ ld [$0], a
+ ld [$6000], a
+ scf
+ ret
diff --git a/engine/menu/naming_screen.asm b/engine/menu/naming_screen.asm
new file mode 100755
index 00000000..ea6f7de7
--- /dev/null
+++ b/engine/menu/naming_screen.asm
@@ -0,0 +1,515 @@
+AskForMonNickname: ; 64eb (1:64eb)
+ call SaveScreenTilesToBuffer1
+ call Load16BitRegisters
+ push hl
+ ld a, [W_ISINBATTLE] ; $d057
+ dec a
+ ld hl, wTileMap
+ ld b, $4
+ ld c, $b
+ call z, ClearScreenArea ; only if in wild batle
+ ld a, [$cf91]
+ ld [$d11e], a
+ call GetMonName
+ ld hl, DoYouWantToNicknameText
+ call PrintText
+ FuncCoord 14, 7 ; $c43a
+ ld hl, Coord
+ ld bc, $80f
+ ld a, $14
+ ld [$d125], a
+ call DisplayTextBoxID
+ pop hl
+ ld a, [wCurrentMenuItem] ; $cc26
+ and a
+ jr nz, .asm_654c
+ ld a, [$cfcb]
+ push af
+ xor a
+ ld [$cfcb], a
+ push hl
+ ld a, $2
+ ld [$d07d], a
+ call DisplayNamingScreen
+ ld a, [W_ISINBATTLE] ; $d057
+ and a
+ jr nz, .asm_653e
+ call Func_3e08
+.asm_653e
+ call LoadScreenTilesFromBuffer1
+ pop hl
+ pop af
+ ld [$cfcb], a
+ ld a, [$cf4b]
+ cp $50
+ ret nz
+.asm_654c
+ ld d, h
+ ld e, l
+ ld hl, $cd6d
+ ld bc, $000b
+ jp CopyData
+
+DoYouWantToNicknameText: ; 0x6557
+ TX_FAR _DoYouWantToNicknameText
+ db "@"
+
+Func_655c: ; 655c (1:655c)
+ ld hl, $cee9
+ xor a
+ ld [$cfcb], a
+ ld a, $2
+ ld [$d07d], a
+ call DisplayNamingScreen
+ call GBPalWhiteOutWithDelay3
+ call Func_3dbe
+ call LoadGBPal
+ ld a, [$cf4b]
+ cp $50
+ jr z, .asm_6594
+ ld hl, W_PARTYMON1NAME ; $d2b5
+ ld bc, $b
+ ld a, [wWhichPokemon] ; $cf92
+ call AddNTimes
+ ld e, l
+ ld d, h
+ ld hl, $cee9
+ ld bc, $b
+ call CopyData
+ and a
+ ret
+.asm_6594
+ scf
+ ret
+
+DisplayNamingScreen: ; 6596 (1:6596)
+ push hl
+ ld hl, $d730
+ set 6, [hl]
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ call UpdateSprites
+ ld b, $8
+ call GoPAL_SET
+ call LoadHpBarAndStatusTilePatterns
+ call LoadEDTile
+ callba Func_7176c
+ FuncCoord 0, 4 ; $c3f0
+ ld hl, Coord
+ ld b, $9
+ ld c, $12
+ call TextBoxBorder
+ call PrintNamingText
+ ld a, $3
+ ld [wTopMenuItemY], a ; $cc24
+ ld a, $1
+ ld [wTopMenuItemX], a ; $cc25
+ ld [wLastMenuItem], a ; $cc2a
+ ld [wCurrentMenuItem], a ; $cc26
+ ld a, $ff
+ ld [wMenuWatchedKeys], a ; $cc29
+ ld a, $7
+ ld [wMaxMenuItem], a ; $cc28
+ ld a, $50
+ ld [$cf4b], a
+ xor a
+ ld hl, $ceea
+ ld [hli], a
+ ld [hli], a
+ ld [W_SUBANIMTRANSFORM], a ; $d08b
+.asm_65ed
+ call PrintAlphabet
+ call GBPalNormal
+.asm_65f3
+ ld a, [$ceea]
+ and a
+ jr nz, .asm_662d
+ call Func_680e
+.asm_65fc
+ call PlaceMenuCursor
+.asm_65ff
+ ld a, [wCurrentMenuItem] ; $cc26
+ push af
+ callba AnimatePartyMon_ForceSpeed1
+ pop af
+ ld [wCurrentMenuItem], a ; $cc26
+ call GetJoypadStateLowSensitivity
+ ld a, [H_NEWLYPRESSEDBUTTONS]
+ and a
+ jr z, .asm_65ff
+ ld hl, .unknownPointerTable_665e ; $665e
+.asm_661a
+ sla a
+ jr c, .asm_6624
+ inc hl
+ inc hl
+ inc hl
+ inc hl
+ jr .asm_661a
+.asm_6624
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ push de
+ jp [hl]
+.asm_662d
+ pop de
+ ld hl, $cf4b
+ ld bc, $b
+ call CopyData
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ call CleanLCD_OAM
+ call GoPAL_SET_CF1C
+ call GBPalNormal
+ xor a
+ ld [W_SUBANIMTRANSFORM], a ; $d08b
+ ld hl, $d730
+ res 6, [hl]
+ ld a, [W_ISINBATTLE] ; $d057
+ and a
+ jp z, LoadTextBoxTilePatterns
+ ld hl, Func_3ee5b
+ ld b, BANK(Func_3ee5b)
+ jp Bankswitch
+
+.unknownPointerTable_665e: ; 665e (1:665e)
+ dw .asm_65fc
+ dw .asm_673e
+ dw .asm_65fc
+ dw .asm_672c
+ dw .asm_65fc
+ dw .asm_6718
+ dw .asm_65fc
+ dw .asm_6702
+ dw .asm_65f3
+ dw .asm_668c
+ dw .asm_65ed
+ dw .asm_6683
+ dw .asm_65f3
+ dw .deleteLetter
+ dw .asm_65f3
+ dw .asm_6692
+
+.asm_667e
+ pop de
+ ld de, .asm_65ed ; $65ed
+ push de
+.asm_6683
+ ld a, [$ceeb]
+ xor $1
+ ld [$ceeb], a
+ ret
+.asm_668c
+ ld a, $1
+ ld [$ceea], a
+ ret
+.asm_6692
+ ld a, [wCurrentMenuItem] ; $cc26
+ cp $5
+ jr nz, .asm_66a0
+ ld a, [wTopMenuItemX] ; $cc25
+ cp $11
+ jr z, .asm_668c
+.asm_66a0
+ ld a, [wCurrentMenuItem] ; $cc26
+ cp $6
+ jr nz, .asm_66ae
+ ld a, [wTopMenuItemX] ; $cc25
+ cp $1
+ jr z, .asm_667e
+.asm_66ae
+ ld hl, wMenuCursorLocation ; $cc30
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ inc hl
+ ld a, [hl]
+ ld [$ceed], a
+ call CalcStringLength
+ ld a, [$ceed]
+ cp $e5
+ ld de, Dakutens ; $6885
+ jr z, .asm_66e3
+ cp $e4
+ ld de, Handakutens ; $68d6
+ jr z, .asm_66e3
+ ld a, [$d07d]
+ cp $2
+ jr nc, .checkMonNameLength
+ ld a, [$cee9]
+ cp $7 ; max length of player/rival names
+ jr .checkNameLength
+.checkMonNameLength
+ ld a, [$cee9]
+ cp $a ; max length of pokemon nicknames
+.checkNameLength
+ jr c, .addLetter
+ ret
+.asm_66e3
+ push hl
+ call Func_6871
+ pop hl
+ ret nc
+ dec hl
+.addLetter
+ ld a, [$ceed]
+ ld [hli], a
+ ld [hl], $50
+ ld a, (SFX_02_40 - SFX_Headers_02) / 3
+ call PlaySound
+ ret
+.deleteLetter
+ ld a, [$cee9]
+ and a
+ ret z
+ call CalcStringLength
+ dec hl
+ ld [hl], $50
+ ret
+.asm_6702
+ ld a, [wCurrentMenuItem] ; $cc26
+ cp $6
+ ret z
+ ld a, [wTopMenuItemX] ; $cc25
+ cp $11
+ jp z, .asm_6714
+ inc a
+ inc a
+ jr .asm_6755
+.asm_6714
+ ld a, $1
+ jr .asm_6755
+.asm_6718
+ ld a, [wCurrentMenuItem] ; $cc26
+ cp $6
+ ret z
+ ld a, [wTopMenuItemX] ; $cc25
+ dec a
+ jp z, .asm_6728
+ dec a
+ jr .asm_6755
+.asm_6728
+ ld a, $11
+ jr .asm_6755
+.asm_672c
+ ld a, [wCurrentMenuItem] ; $cc26
+ dec a
+ ld [wCurrentMenuItem], a ; $cc26
+ and a
+ ret nz
+ ld a, $6
+ ld [wCurrentMenuItem], a ; $cc26
+ ld a, $1
+ jr .asm_6755
+.asm_673e
+ ld a, [wCurrentMenuItem] ; $cc26
+ inc a
+ ld [wCurrentMenuItem], a ; $cc26
+ cp $7
+ jr nz, .asm_6750
+ ld a, $1
+ ld [wCurrentMenuItem], a ; $cc26
+ jr .asm_6755
+.asm_6750
+ cp $6
+ ret nz
+ ld a, $1
+.asm_6755
+ ld [wTopMenuItemX], a ; $cc25
+ jp EraseMenuCursor
+
+LoadEDTile: ; 675b (1:675b)
+ ld de, ED_Tile
+ ld hl, $8f00
+ ld bc, $1
+ jp CopyVideoDataDouble
+
+ED_Tile: ; 6767 (1:6767)
+ INCBIN "gfx/ED_tile.1bpp"
+
+PrintAlphabet: ; 676f (1:676f)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ ld a, [$ceeb]
+ and a
+ ld de, LowerCaseAlphabet ; $679e
+ jr nz, .asm_677e
+ ld de, UpperCaseAlphabet ; $67d6
+.asm_677e
+ FuncCoord 2, 5 ; $c406
+ ld hl, Coord
+ ld bc, $509
+.asm_6784
+ push bc
+.asm_6785
+ ld a, [de]
+ ld [hli], a
+ inc hl
+ inc de
+ dec c
+ jr nz, .asm_6785
+ ld bc, $16
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .asm_6784
+ call PlaceString
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
+ jp Delay3
+
+LowerCaseAlphabet: ; 679e (1:679e)
+ db "abcdefghijklmnopqrstuvwxyz ×():;[]",$e1,$e2,"-?!♂♀/",$f2,",¥UPPER CASE@"
+
+UpperCaseAlphabet: ; 67d6 (1:67d6)
+ db "ABCDEFGHIJKLMNOPQRSTUVWXYZ ×():;[]",$e1,$e2,"-?!♂♀/",$f2,",¥lower case@"
+
+Func_680e: ; 680e (1:680e)
+ call CalcStringLength
+ ld a, c
+ ld [$cee9], a
+ FuncCoord 10, 2 ; $c3d2
+ ld hl, Coord
+ ld bc, $10a
+ call ClearScreenArea
+ FuncCoord 10, 2 ; $c3d2
+ ld hl, Coord
+ ld de, $cf4b
+ call PlaceString
+ FuncCoord 10, 3 ; $c3e6
+ ld hl, Coord
+ ld a, [$d07d]
+ cp $2
+ jr nc, .asm_6835
+ ld b, $7
+ jr .asm_6837
+.asm_6835
+ ld b, $a
+.asm_6837
+ ld a, $76
+.asm_6839
+ ld [hli], a
+ dec b
+ jr nz, .asm_6839
+ ld a, [$d07d]
+ cp $2
+ ld a, [$cee9]
+ jr nc, .asm_684b
+ cp $7
+ jr .asm_684d
+.asm_684b
+ cp $a
+.asm_684d
+ jr nz, .asm_6867
+ call EraseMenuCursor
+ ld a, $11
+ ld [wTopMenuItemX], a ; $cc25
+ ld a, $5
+ ld [wCurrentMenuItem], a ; $cc26
+ ld a, [$d07d]
+ cp $2
+ ld a, $9
+ jr nc, .asm_6867
+ ld a, $6
+.asm_6867
+ ld c, a
+ ld b, $0
+ FuncCoord 10, 3 ; $c3e6
+ ld hl, Coord
+ add hl, bc
+ ld [hl], $77
+ ret
+
+Func_6871: ; 6871 (1:6871)
+ push de
+ call CalcStringLength
+ dec hl
+ ld a, [hl]
+ pop hl
+ ld de, $2
+ call IsInArray
+ ret nc
+ inc hl
+ ld a, [hl]
+ ld [$ceed], a
+ ret
+
+Dakutens: ; 6885 (1:6885)
+ db "かが", "きぎ", "くぐ", "けげ", "こご"
+ db "さざ", "しじ", "すず", "せぜ", "そぞ"
+ db "ただ", "ちぢ", "つづ", "てで", "とど"
+ db "はば", "ひび", "ふぶ", "へべ", "ほぼ"
+ db "カガ", "キギ", "クグ", "ケゲ", "コゴ"
+ db "サザ", "シジ", "スズ", "セゼ", "ソゾ"
+ db "タダ", "チヂ", "ツヅ", "テデ", "トド"
+ db "ハバ", "ヒビ", "フブ", "へべ", "ホボ"
+ db $ff
+
+Handakutens: ; 68d6 (1:68d6)
+ db "はぱ", "ひぴ", "ふぷ", "へぺ", "ほぽ"
+ db "ハパ", "ヒピ", "フプ", "へぺ", "ホポ"
+ db $ff
+
+; calculates the length of the string at $cf4b and stores it in c
+CalcStringLength: ; 68eb (1:68eb)
+ ld hl, $cf4b
+ ld c, $0
+.asm_68f0
+ ld a, [hl]
+ cp $50
+ ret z
+ inc hl
+ inc c
+ jr .asm_68f0
+
+PrintNamingText: ; 68f8 (1:68f8)
+ FuncCoord 0, 1 ; $c3b4
+ ld hl, Coord
+ ld a, [$d07d]
+ ld de, YourTextString ; $693f
+ and a
+ jr z, .notNickname
+ ld de, RivalsTextString ; $6945
+ dec a
+ jr z, .notNickname
+ ld a, [$cf91]
+ ld [$cd5d], a
+ push af
+ callba Func_71882
+ pop af
+ ld [$d11e], a
+ call GetMonName
+ FuncCoord 4, 1 ; $c3b8
+ ld hl, Coord
+ call PlaceString
+ ld hl, $1
+ add hl, bc
+ ld [hl], $c9
+ FuncCoord 1, 3 ; $c3dd
+ ld hl, Coord
+ ld de, NicknameTextString ; $6953
+ jr .placeString
+.notNickname
+ call PlaceString
+ ld l, c
+ ld h, b
+ ld de, NameTextString ; $694d
+.placeString
+ jp PlaceString
+
+YourTextString: ; 693f (1:693f)
+ db "YOUR @"
+
+RivalsTextString: ; 6945 (1:6945)
+ db "RIVAL's @"
+
+NameTextString: ; 694d (1:694d)
+ db "NAME?@"
+
+NicknameTextString: ; 6953 (1:6953)
+ db "NICKNAME?@"
diff --git a/engine/menu/oaks_pc.asm b/engine/menu/oaks_pc.asm
new file mode 100755
index 00000000..937786c1
--- /dev/null
+++ b/engine/menu/oaks_pc.asm
@@ -0,0 +1,28 @@
+OpenOaksPC: ; 1e915 (7:6915)
+ call SaveScreenTilesToBuffer2
+ ld hl, AccessedOaksPCText
+ call PrintText
+ ld hl, GetDexRatedText
+ call PrintText
+ call YesNoChoice
+ ld a, [wCurrentMenuItem] ; $cc26
+ and a
+ jr nz, .asm_1e932
+ ld a, $56
+ call Predef ; indirect jump to DisplayDexRating (44169 (11:4169))
+.asm_1e932
+ ld hl, ClosedOaksPCText
+ call PrintText
+ jp LoadScreenTilesFromBuffer2
+
+GetDexRatedText: ; 1e93b (7:693b)
+ TX_FAR _GetDexRatedText
+ db "@"
+
+ClosedOaksPCText: ; 1e940 (7:6940)
+ TX_FAR _ClosedOaksPCText
+ db $0d,"@"
+
+AccessedOaksPCText: ; 1e946 (7:6946)
+ TX_FAR _AccessedOaksPCText
+ db "@"
diff --git a/engine/menu/party_menu.asm b/engine/menu/party_menu.asm
new file mode 100755
index 00000000..dbb6a40e
--- /dev/null
+++ b/engine/menu/party_menu.asm
@@ -0,0 +1,328 @@
+; [$D07D] = menu type / message ID
+; if less than $F0, it is a menu type
+; menu types:
+; 00: normal pokemon menu (e.g. Start menu)
+; 01: use healing item on pokemon menu
+; 02: in-battle switch pokemon menu
+; 03: learn TM/HM menu
+; 04: swap pokemon positions menu
+; 05: use evolution stone on pokemon menu
+; otherwise, it is a message ID
+; f0: poison healed
+; f1: burn healed
+; f2: freeze healed
+; f3: sleep healed
+; f4: paralysis healed
+; f5: HP healed
+; f6: health returned
+; f7: revitalized
+; f8: leveled up
+DrawPartyMenu_: ; 12cd2 (4:6cd2)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED],a
+ call ClearScreen
+ call UpdateSprites ; move sprites
+ callba Func_71791 ; load pokemon icon graphics
+
+RedrawPartyMenu_: ; 12ce3 (4:6ce3)
+ ld a,[$D07D]
+ cp a,$04
+ jp z,.printMessage
+ call ErasePartyMenuCursors
+ callba SendBlkPacket_PartyMenu ; loads some data to $cf2e
+ FuncCoord 3,0
+ ld hl,Coord
+ ld de,W_PARTYMON1
+ xor a
+ ld c,a
+ ld [$FF8C],a ; loop counter
+ ld [$CF2D],a
+.loop
+ ld a,[de]
+ cp a,$FF ; reached the terminator?
+ jp z,.afterDrawingMonEntries
+ push bc
+ push de
+ push hl
+ ld a,c
+ push hl
+ ld hl,W_PARTYMON1NAME
+ call GetPartyMonName
+ pop hl
+ call PlaceString ; print the pokemon's name
+ callba Func_71868 ; place the appropriate pokemon icon
+ ld a,[$FF8C] ; loop counter
+ ld [wWhichPokemon],a
+ inc a
+ ld [$FF8C],a
+ call LoadMonData
+ pop hl
+ push hl
+ ld a,[$CC35]
+ and a ; is the player swapping pokemon positions?
+ jr z,.skipUnfilledRightArrow
+; if the player is swapping pokemon positions
+ dec a
+ ld b,a
+ ld a,[wWhichPokemon]
+ cp b ; is the player swapping the current pokemon in the list?
+ jr nz,.skipUnfilledRightArrow
+; the player is swapping the current pokemon in the list
+ dec hl
+ dec hl
+ dec hl
+ ld a,$EC ; unfilled right arrow menu cursor
+ ld [hli],a ; place the cursor
+ inc hl
+ inc hl
+.skipUnfilledRightArrow
+ ld a,[$D07D] ; menu type
+ cp a,$03
+ jr z,.teachMoveMenu
+ cp a,$05
+ jr z,.evolutionStoneMenu
+ push hl
+ ld bc,14 ; 14 columns to the right
+ add hl,bc
+ ld de,$CF9C
+ call PrintStatusCondition
+ pop hl
+ push hl
+ ld bc,20 + 1 ; down 1 row and right 1 column
+ ld a,[$FFF6]
+ set 0,a
+ ld [$FFF6],a
+ add hl,bc
+ ld a,$60
+ call Predef ; draw HP bar and prints current / max HP
+ ld a,[$FFF6]
+ res 0,a
+ ld [$FFF6],a
+ call SetPartyMenuHealthBarColor ; color the HP bar (on SGB)
+ pop hl
+ jr .printLevel
+.teachMoveMenu
+ push hl
+ ld a,$43
+ call Predef ; check if the pokemon can learn the move
+ pop hl
+ ld de,.ableToLearnMoveText
+ ld a,c
+ and a
+ jr nz,.placeMoveLearnabilityString
+ ld de,.notAbleToLearnMoveText
+.placeMoveLearnabilityString
+ ld bc,20 + 9 ; down 1 row and right 9 columns
+ push hl
+ add hl,bc
+ call PlaceString
+ pop hl
+.printLevel
+ ld bc,10 ; move 10 columns to the right
+ add hl,bc
+ call PrintLevel
+ pop hl
+ pop de
+ inc de
+ ld bc,2 * 20
+ add hl,bc
+ pop bc
+ inc c
+ jp .loop
+.ableToLearnMoveText
+ db "ABLE@"
+.notAbleToLearnMoveText
+ db "NOT ABLE@"
+.evolutionStoneMenu
+ push hl
+ ld hl,EvosMovesPointerTable
+ ld b,0
+ ld a,[$CF98] ; pokemon ID
+ dec a
+ add a
+ rl b
+ ld c,a
+ add hl,bc
+ ld de,$CD6D
+ ld a,BANK(EvosMovesPointerTable)
+ ld bc,2
+ call FarCopyData
+ ld hl,$CD6D
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ ld de,$CD6D
+ ld a,BANK(EvosMovesPointerTable)
+ ld bc,13
+ call FarCopyData
+ ld hl,$CD6D
+ ld de,.notAbleToEvolveText
+; loop through the pokemon's evolution entries
+.checkEvolutionsLoop
+ ld a,[hli]
+ and a ; reached terminator?
+ jr z,.placeEvolutionStoneString ; if so, place the "NOT ABLE" string
+ inc hl
+ inc hl
+ cp a,EV_ITEM
+ jr nz,.checkEvolutionsLoop
+; if it's a stone evolution entry
+ dec hl
+ dec hl
+ ld b,[hl]
+ ld a,[$D156] ; evolution stone item ID
+ inc hl
+ inc hl
+ inc hl
+ cp b ; does the player's stone match this evolution entry's stone?
+ jr nz,.checkEvolutionsLoop
+; if it does match
+ ld de,.ableToEvolveText
+.placeEvolutionStoneString
+ ld bc,20 + 9 ; down 1 row and right 9 columns
+ pop hl
+ push hl
+ add hl,bc
+ call PlaceString
+ pop hl
+ jr .printLevel
+.ableToEvolveText
+ db "ABLE@"
+.notAbleToEvolveText
+ db "NOT ABLE@"
+.afterDrawingMonEntries
+ ld b,$0A
+ call GoPAL_SET
+.printMessage
+ ld hl,$D730
+ ld a,[hl]
+ push af
+ push hl
+ set 6,[hl] ; turn off letter printing delay
+ ld a,[$D07D] ; message ID
+ cp a,$F0
+ jr nc,.printItemUseMessage
+ add a
+ ld hl,PartyMenuMessagePointers
+ ld b,0
+ ld c,a
+ add hl,bc
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ call PrintText
+.done
+ pop hl
+ pop af
+ ld [hl],a
+ ld a,1
+ ld [H_AUTOBGTRANSFERENABLED],a
+ call Delay3
+ jp GBPalNormal
+.printItemUseMessage
+ and a,$0F
+ ld hl,PartyMenuItemUseMessagePointers
+ add a
+ ld c,a
+ ld b,0
+ add hl,bc
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ push hl
+ ld a,[$CF06]
+ ld hl,W_PARTYMON1NAME
+ call GetPartyMonName
+ pop hl
+ call PrintText
+ jr .done
+
+PartyMenuItemUseMessagePointers: ; 12e61 (4:6e61)
+ dw AntidoteText
+ dw BurnHealText
+ dw IceHealText
+ dw AwakeningText
+ dw ParlyzHealText
+ dw PotionText
+ dw FullHealText
+ dw ReviveText
+ dw RareCandyText
+
+PartyMenuMessagePointers: ; 12e73 (4:6e73)
+ dw PartyMenuNormalText
+ dw PartyMenuItemUseText
+ dw PartyMenuBattleText
+ dw PartyMenuUseTMText
+ dw PartyMenuSwapMonText
+ dw PartyMenuItemUseText
+
+PartyMenuNormalText: ; 12e7f (4:6e7f)
+ TX_FAR _PartyMenuNormalText
+ db "@"
+
+PartyMenuItemUseText: ; 12e84 (4:6e84)
+ TX_FAR _PartyMenuItemUseText
+ db "@"
+
+PartyMenuBattleText: ; 12e89 (4:6e89)
+ TX_FAR _PartyMenuBattleText
+ db "@"
+
+PartyMenuUseTMText: ; 12e8e (4:6e8e)
+ TX_FAR _PartyMenuUseTMText
+ db "@"
+
+PartyMenuSwapMonText: ; 12e93 (4:6e93)
+ TX_FAR _PartyMenuSwapMonText
+ db "@"
+
+PotionText: ; 12e98 (4:6e98)
+ TX_FAR _PotionText
+ db "@"
+
+AntidoteText: ; 12e9d (4:6e9d)
+ TX_FAR _AntidoteText
+ db "@"
+
+ParlyzHealText: ; 12ea2 (4:6ea2)
+ TX_FAR _ParlyzHealText
+ db "@"
+
+BurnHealText: ; 12ea7 (4:6ea7)
+ TX_FAR _BurnHealText
+ db "@"
+
+IceHealText: ; 12eac (4:6eac)
+ TX_FAR _IceHealText
+ db "@"
+
+AwakeningText: ; 12eb1 (4:6eb1)
+ TX_FAR _AwakeningText
+ db "@"
+
+FullHealText: ; 12eb6 (4:6eb6)
+ TX_FAR _FullHealText
+ db "@"
+
+ReviveText: ; 12ebb (4:6ebb)
+ TX_FAR _ReviveText
+ db "@"
+
+RareCandyText: ; 12ec0 (4:6ec0)
+ TX_FAR _RareCandyText
+ db $0B
+ db $06
+ db "@"
+
+SetPartyMenuHealthBarColor: ; 12ec7 (4:6ec7)
+ ld hl, $cf1f
+ ld a, [$cf2d]
+ ld c, a
+ ld b, $0
+ add hl, bc
+ call GetHealthBarColor
+ ld b, $fc
+ call GoPAL_SET
+ ld hl, $cf2d
+ inc [hl]
+ ret
diff --git a/engine/menu/pc.asm b/engine/menu/pc.asm
new file mode 100755
index 00000000..a860c4b3
--- /dev/null
+++ b/engine/menu/pc.asm
@@ -0,0 +1,142 @@
+ActivatePC: ; 17e2c (5:7e2c)
+ call SaveScreenTilesToBuffer2 ;XXX: copy background from wTileMap to wTileMapBackup2
+ ld a, (SFX_02_45 - SFX_Headers_02) / 3
+ call PlaySound ;XXX: play sound or stop music
+ ld hl, TurnedOnPC1Text
+ call PrintText
+ call WaitForSoundToFinish ;XXX: wait for sound to be done
+ ld hl, wFlags_0xcd60
+ set 3, [hl]
+ call LoadScreenTilesFromBuffer2 ;XXX: restore saved screen
+ call Delay3
+PCMainMenu: ; 17e48 (5:7e48)
+ callba Func_213c8
+ ld hl, wFlags_0xcd60
+ set 5, [hl]
+ call HandleMenuInput
+ bit 1, a ;if player pressed B
+ jp nz, LogOff
+ ld a, [wMaxMenuItem]
+ cp a, 2
+ jr nz, .next ;if not 2 menu items (not counting log off) (2 occurs before you get the pokedex)
+ ld a, [wCurrentMenuItem]
+ and a
+ jp z, BillsPC ;if current menu item id is 0, it's bills pc
+ cp a, 1
+ jr z, .playersPC ;if current menu item id is 1, it's players pc
+ jp LogOff ;otherwise, it's 2, and you're logging off
+.next
+ cp a, 3
+ jr nz, .next2 ;if not 3 menu items (not counting log off) (3 occurs after you get the pokedex, before you beat the pokemon league)
+ ld a, [wCurrentMenuItem]
+ and a
+ jp z, BillsPC ;if current menu item id is 0, it's bills pc
+ cp a, 1
+ jr z, .playersPC ;if current menu item id is 1, it's players pc
+ cp a, 2
+ jp z, OaksPC ;if current menu item id is 2, it's oaks pc
+ jp LogOff ;otherwise, it's 3, and you're logging off
+.next2
+ ld a, [wCurrentMenuItem]
+ and a
+ jp z, BillsPC ;if current menu item id is 0, it's bills pc
+ cp a, 1
+ jr z, .playersPC ;if current menu item id is 1, it's players pc
+ cp a, 2
+ jp z, OaksPC ;if current menu item id is 2, it's oaks pc
+ cp a, 3
+ jp z, PKMNLeague ;if current menu item id is 3, it's pkmnleague
+ jp LogOff ;otherwise, it's 4, and you're logging off
+.playersPC
+ ld hl, wFlags_0xcd60
+ res 5, [hl]
+ set 3, [hl]
+ ld a, (SFX_02_47 - SFX_Headers_02) / 3
+ call PlaySound ;XXX: play sound or stop music
+ call WaitForSoundToFinish ;XXX: wait for sound to be done
+ ld hl, AccessedMyPCText
+ call PrintText
+ callba PlayerPC
+ jr ReloadMainMenu
+OaksPC: ; 17ec0 (5:7ec0)
+ ld a, (SFX_02_47 - SFX_Headers_02) / 3
+ call PlaySound ;XXX: play sound or stop music
+ call WaitForSoundToFinish ;XXX: wait for sound to be done
+ callba OpenOaksPC
+ jr ReloadMainMenu
+PKMNLeague: ; 17ed2 (5:7ed2)
+ ld a, (SFX_02_47 - SFX_Headers_02) / 3
+ call PlaySound ;XXX: play sound or stop music
+ call WaitForSoundToFinish ;XXX: wait for sound to be done
+ callba PKMNLeaguePC
+ jr ReloadMainMenu
+BillsPC: ; 17ee4 (5:7ee4)
+ ld a, (SFX_02_47 - SFX_Headers_02) / 3
+ call PlaySound ;XXX: play sound or stop music
+ call WaitForSoundToFinish ;XXX: wait for sound to be done
+ ld a, [$D7F1] ;has to do with having met Bill
+ bit 0, a
+ jr nz, .billsPC ;if you've met bill, use that bill's instead of someone's
+ ld hl, AccessedSomeonesPCText
+ jr .printText
+.billsPC
+ ld hl, AccessedBillsPCText
+.printText
+ call PrintText
+ callba BillsPC_
+ReloadMainMenu: ; 17f06 (5:7f06)
+ xor a
+ ld [$CC3C], a
+ call ReloadMapData
+ call UpdateSprites ;XXX: moves sprites
+ jp PCMainMenu
+LogOff: ; 17f13 (5:7f13)
+ ld a, (SFX_02_46 - SFX_Headers_02) / 3
+ call PlaySound ;XXX: play sound or stop music
+ call WaitForSoundToFinish ;XXX: wait for sound to be done
+ ld hl, wFlags_0xcd60
+ res 3, [hl]
+ res 5, [hl]
+ ret
+
+TurnedOnPC1Text: ; 17f23 (5:7f23)
+ TX_FAR _TurnedOnPC1Text
+ db "@"
+
+AccessedBillsPCText: ; 17f28 (5:7f28)
+ TX_FAR _AccessedBillsPCText
+ db "@"
+
+AccessedSomeonesPCText: ; 17f2d (5:7f2d)
+ TX_FAR _AccessedSomeonesPCText
+ db "@"
+
+AccessedMyPCText: ; 17f32 (5:7f32)
+ TX_FAR _AccessedMyPCText
+ db "@"
+
+; removes one of the specified item ID [$FFdb] from bag (if existent)
+RemoveItemByID: ; 17f37 (5:7f37)
+ ld hl, wBagItems ; $d31e
+ ld a, [$ffdb]
+ ld b, a
+ xor a
+ ld [$ffdc], a
+.asm_17f40
+ ld a, [hli]
+ cp $ff
+ ret z
+ cp b
+ jr z, .asm_17f4f
+ inc hl
+ ld a, [$ffdc]
+ inc a
+ ld [$ffdc], a
+ jr .asm_17f40
+.asm_17f4f
+ ld a, $1
+ ld [$cf96], a
+ ld a, [$ffdc]
+ ld [wWhichPokemon], a ; $cf92
+ ld hl, wNumBagItems ; $d31d
+ jp RemoveItemFromInventory
diff --git a/engine/menu/players_pc.asm b/engine/menu/players_pc.asm
new file mode 100755
index 00000000..a89b745d
--- /dev/null
+++ b/engine/menu/players_pc.asm
@@ -0,0 +1,302 @@
+PlayerPC: ; 78e6 (1:78e6)
+ ld hl, $d730
+ set 6, [hl]
+ ld a, ITEM_NAME
+ ld [W_LISTTYPE], a
+ call SaveScreenTilesToBuffer1
+ xor a
+ ld [$cc2c], a
+ ld [$ccd3], a
+ ld a, [wFlags_0xcd60]
+ bit 3, a
+ jr nz, Func_790c
+ ld a, (SFX_02_45 - SFX_Headers_02) / 3
+ call PlaySound
+ ld hl, TurnedOnPC2Text
+ call PrintText
+
+Func_790c: ; 790c (1:790c)
+ ld a, [$ccd3]
+ ld [wCurrentMenuItem], a ; $cc26
+ ld hl, wFlags_0xcd60
+ set 5, [hl]
+ call LoadScreenTilesFromBuffer2
+ ld hl, wTileMap
+ ld b, $8
+ ld c, $e
+ call TextBoxBorder
+ call UpdateSprites
+ FuncCoord 2, 2 ; $c3ca
+ ld hl, Coord
+ ld de, PlayersPCMenuEntries ; $7af5
+ call PlaceString
+ ld hl, wTopMenuItemY ; $cc24
+ ld a, $2
+ ld [hli], a
+ dec a
+ ld [hli], a
+ inc hl
+ inc hl
+ ld a, $3
+ ld [hli], a
+ ld a, $3
+ ld [hli], a
+ xor a
+ ld [hl], a
+ ld hl, wListScrollOffset ; $cc36
+ ld [hli], a
+ ld [hl], a
+ ld [wPlayerMonNumber], a ; $cc2f
+ ld hl, WhatDoYouWantText
+ call PrintText
+ call HandleMenuInput
+ bit 1, a
+ jp nz, Func_796d
+ call PlaceUnfilledArrowMenuCursor
+ ld a, [wCurrentMenuItem] ; $cc26
+ ld [$ccd3], a
+ and a
+ jp z, Func_7a12
+ dec a
+ jp z, Func_7995
+ dec a
+ jp z, Func_7a8f
+
+Func_796d: ; 796d (1:796d)
+ ld a, [wFlags_0xcd60]
+ bit 3, a
+ jr nz, .asm_797c
+ ld a, (SFX_02_46 - SFX_Headers_02) / 3
+ call PlaySound
+ call WaitForSoundToFinish
+.asm_797c
+ ld hl, wFlags_0xcd60
+ res 5, [hl]
+ call LoadScreenTilesFromBuffer2
+ xor a
+ ld [wListScrollOffset], a ; $cc36
+ ld [$cc2c], a
+ ld hl, $d730
+ res 6, [hl]
+ xor a
+ ld [$cc3c], a
+ ret
+
+Func_7995: ; 7995 (1:7995)
+ xor a
+ ld [wCurrentMenuItem], a ; $cc26
+ ld [wListScrollOffset], a ; $cc36
+ ld a, [wNumBagItems] ; $d31d
+ and a
+ jr nz, Func_79ab
+ ld hl, NothingToDepositText
+ call PrintText
+ jp Func_790c
+
+Func_79ab: ; 79ab (1:79ab)
+ ld hl, WhatToDepositText
+ call PrintText
+ ld hl, wNumBagItems ; $d31d
+ ld a, l
+ ld [$cf8b], a
+ ld a, h
+ ld [$cf8c], a
+ xor a
+ ld [$cf93], a
+ ld a, $3
+ ld [wListMenuID], a ; $cf94
+ call DisplayListMenuID
+ jp c, Func_790c
+ call IsKeyItem
+ ld a, $1
+ ld [$cf96], a
+ ld a, [$d124]
+ and a
+ jr nz, .asm_79e7
+ ld hl, DepositHowManyText
+ call PrintText
+ call DisplayChooseQuantityMenu
+ cp $ff
+ jp z, Func_79ab
+.asm_79e7
+ ld hl, wNumBoxItems ; $d53a
+ call AddItemToInventory
+ jr c, .asm_79f8
+ ld hl, NoRoomToStoreText
+ call PrintText
+ jp Func_79ab
+.asm_79f8
+ ld hl, wNumBagItems ; $d31d
+ call RemoveItemFromInventory
+ call WaitForSoundToFinish
+ ld a, (SFX_02_55 - SFX_Headers_02) / 3
+ call PlaySound
+ call WaitForSoundToFinish
+ ld hl, ItemWasStoredText
+ call PrintText
+ jp Func_79ab
+
+Func_7a12: ; 7a12 (1:7a12)
+ xor a
+ ld [wCurrentMenuItem], a ; $cc26
+ ld [wListScrollOffset], a ; $cc36
+ ld a, [wNumBoxItems] ; $d53a
+ and a
+ jr nz, Func_7a28
+ ld hl, NothingStoredText
+ call PrintText
+ jp Func_790c
+
+Func_7a28: ; 7a28 (1:7a28)
+ ld hl, WhatToWithdrawText
+ call PrintText
+ ld hl, wNumBoxItems ; $d53a
+ ld a, l
+ ld [$cf8b], a
+ ld a, h
+ ld [$cf8c], a
+ xor a
+ ld [$cf93], a
+ ld a, $3
+ ld [wListMenuID], a ; $cf94
+ call DisplayListMenuID
+ jp c, Func_790c
+ call IsKeyItem
+ ld a, $1
+ ld [$cf96], a
+ ld a, [$d124]
+ and a
+ jr nz, .asm_7a64
+ ld hl, WithdrawHowManyText
+ call PrintText
+ call DisplayChooseQuantityMenu
+ cp $ff
+ jp z, Func_7a28
+.asm_7a64
+ ld hl, wNumBagItems ; $d31d
+ call AddItemToInventory
+ jr c, .asm_7a75
+ ld hl, CantCarryMoreText
+ call PrintText
+ jp Func_7a28
+.asm_7a75
+ ld hl, wNumBoxItems ; $d53a
+ call RemoveItemFromInventory
+ call WaitForSoundToFinish
+ ld a, (SFX_02_55 - SFX_Headers_02) / 3
+ call PlaySound
+ call WaitForSoundToFinish
+ ld hl, WithdrewItemText
+ call PrintText
+ jp Func_7a28
+
+Func_7a8f: ; 7a8f (1:7a8f)
+ xor a
+ ld [wCurrentMenuItem], a ; $cc26
+ ld [wListScrollOffset], a ; $cc36
+ ld a, [wNumBoxItems] ; $d53a
+ and a
+ jr nz, Func_7aa5
+ ld hl, NothingStoredText
+ call PrintText
+ jp Func_790c
+
+Func_7aa5: ; 7aa5 (1:7aa5)
+ ld hl, WhatToTossText
+ call PrintText
+ ld hl, wNumBoxItems ; $d53a
+ ld a, l
+ ld [$cf8b], a
+ ld a, h
+ ld [$cf8c], a
+ xor a
+ ld [$cf93], a
+ ld a, $3
+ ld [wListMenuID], a ; $cf94
+ push hl
+ call DisplayListMenuID
+ pop hl
+ jp c, Func_790c
+ push hl
+ call IsKeyItem
+ pop hl
+ ld a, $1
+ ld [$cf96], a
+ ld a, [$d124]
+ and a
+ jr nz, .asm_7aef
+ ld a, [$cf91]
+ call IsItemHM
+ jr c, .asm_7aef
+ push hl
+ ld hl, TossHowManyText
+ call PrintText
+ call DisplayChooseQuantityMenu
+ pop hl
+ cp $ff
+ jp z, Func_7aa5
+.asm_7aef
+ call TossItem
+ jp Func_7aa5
+
+PlayersPCMenuEntries: ; 7af5 (1:7af5)
+ db "WITHDRAW ITEM"
+ next "DEPOSIT ITEM"
+ next "TOSS ITEM"
+ next "LOG OFF@"
+
+TurnedOnPC2Text: ; 7b22 (1:7b22)
+ TX_FAR _TurnedOnPC2Text
+ db "@"
+
+WhatDoYouWantText: ; 7b27 (1:7b27)
+ TX_FAR _WhatDoYouWantText
+ db "@"
+
+WhatToDepositText: ; 7b2c (1:7b2c)
+ TX_FAR _WhatToDepositText
+ db "@"
+
+DepositHowManyText: ; 7b31 (1:7b31)
+ TX_FAR _DepositHowManyText
+ db "@"
+
+ItemWasStoredText: ; 7b36 (1:7b36)
+ TX_FAR _ItemWasStoredText
+ db "@"
+
+NothingToDepositText: ; 7b3b (1:7b3b)
+ TX_FAR _NothingToDepositText
+ db "@"
+
+NoRoomToStoreText: ; 7b40 (1:7b40)
+ TX_FAR _NoRoomToStoreText
+ db "@"
+
+WhatToWithdrawText: ; 7b45 (1:7b45)
+ TX_FAR _WhatToWithdrawText
+ db "@"
+
+WithdrawHowManyText: ; 7b4a (1:7b4a)
+ TX_FAR _WithdrawHowManyText
+ db "@"
+
+WithdrewItemText: ; 7b4f (1:7b4f)
+ TX_FAR _WithdrewItemText
+ db "@"
+
+NothingStoredText: ; 7b54 (1:7b54)
+ TX_FAR _NothingStoredText
+ db "@"
+
+CantCarryMoreText: ; 7b59 (1:7b59)
+ TX_FAR _CantCarryMoreText
+ db "@"
+
+WhatToTossText: ; 7b5e (1:7b5e)
+ TX_FAR _WhatToTossText
+ db "@"
+
+TossHowManyText: ; 7b63 (1:7b63)
+ TX_FAR _TossHowManyText
+ db "@"
diff --git a/engine/menu/pokedex.asm b/engine/menu/pokedex.asm
new file mode 100755
index 00000000..dbb9f57f
--- /dev/null
+++ b/engine/menu/pokedex.asm
@@ -0,0 +1,676 @@
+DisplayPokedexMenu_: ; 40000 (10:4000)
+ call GBPalWhiteOut
+ call ClearScreen
+ call UpdateSprites ; move sprites
+ ld a,[wListScrollOffset]
+ push af
+ xor a
+ ld [wCurrentMenuItem],a
+ ld [wListScrollOffset],a
+ ld [wLastMenuItem],a
+ inc a
+ ld [$d11e],a
+ ld [$ffb7],a
+.setUpGraphics
+ ld b,$08
+ call GoPAL_SET
+ callab LoadPokedexTilePatterns
+.doPokemonListMenu
+ ld hl,wTopMenuItemY
+ ld a,3
+ ld [hli],a ; top menu item Y
+ xor a
+ ld [hli],a ; top menu item X
+ inc a
+ ld [$cc37],a
+ inc hl
+ inc hl
+ ld a,6
+ ld [hli],a ; max menu item ID
+ ld [hl],%00110011 ; menu watched keys (Left, Right, B button, A button)
+ call HandlePokedexListMenu
+ jr c,.goToSideMenu ; if the player chose a pokemon from the list
+.exitPokedex
+ xor a
+ ld [$cc37],a
+ ld [wCurrentMenuItem],a
+ ld [wLastMenuItem],a
+ ld [$ffb7],a
+ ld [$cd3a],a
+ ld [$cd3b],a
+ pop af
+ ld [wListScrollOffset],a
+ call GBPalWhiteOutWithDelay3
+ call GoPAL_SET_CF1C
+ jp ReloadMapData
+.goToSideMenu
+ call HandlePokedexSideMenu
+ dec b
+ jr z,.exitPokedex ; if the player chose Quit
+ dec b
+ jr z,.doPokemonListMenu ; if pokemon not seen or player pressed B button
+ jp .setUpGraphics ; if pokemon data or area was shown
+
+; handles the menu on the lower right in the pokedex screen
+; OUTPUT:
+; b = reason for exiting menu
+; 00: showed pokemon data or area
+; 01: the player chose Quit
+; 02: the pokemon has not been seen yet or the player pressed the B button
+HandlePokedexSideMenu: ; 4006d (10:406d)
+ call PlaceUnfilledArrowMenuCursor
+ ld a,[wCurrentMenuItem]
+ push af
+ ld b,a
+ ld a,[wLastMenuItem]
+ push af
+ ld a,[wListScrollOffset]
+ push af
+ add b
+ inc a
+ ld [$d11e],a
+ ld a,[$d11e]
+ push af
+ ld a,[$cd3d]
+ push af
+ ld hl,wPokedexSeen
+ call IsPokemonBitSet
+ ld b,2
+ jr z,.exitSideMenu
+ call PokedexToIndex
+ ld hl,wTopMenuItemY
+ ld a,10
+ ld [hli],a ; top menu item Y
+ ld a,15
+ ld [hli],a ; top menu item X
+ xor a
+ ld [hli],a ; current menu item ID
+ inc hl
+ ld a,3
+ ld [hli],a ; max menu item ID
+ ld [hli],a ; menu watched keys (A button and B button)
+ xor a
+ ld [hli],a ; old menu item ID
+ ld [$cc37],a
+.handleMenuInput
+ call HandleMenuInput
+ bit 1,a ; was the B button pressed?
+ ld b,2
+ jr nz,.buttonBPressed
+ ld a,[wCurrentMenuItem]
+ and a
+ jr z,.choseData
+ dec a
+ jr z,.choseCry
+ dec a
+ jr z,.choseArea
+.choseQuit
+ ld b,1
+.exitSideMenu
+ pop af
+ ld [$cd3d],a
+ pop af
+ ld [$d11e],a
+ pop af
+ ld [wListScrollOffset],a
+ pop af
+ ld [wLastMenuItem],a
+ pop af
+ ld [wCurrentMenuItem],a
+ push bc
+ FuncCoord 0,3
+ ld hl,Coord
+ ld de,20
+ ld bc,$7f0d ; 13 blank tiles
+ call DrawTileLine ; cover up the menu cursor in the pokemon list
+ pop bc
+ ret
+.buttonBPressed
+ push bc
+ FuncCoord 15,10
+ ld hl,Coord
+ ld de,20
+ ld bc,$7f07 ; 7 blank tiles
+ call DrawTileLine ; cover up the menu cursor in the side menu
+ pop bc
+ jr .exitSideMenu
+.choseData
+ call ShowPokedexDataInternal
+ ld b,0
+ jr .exitSideMenu
+; play pokemon cry
+.choseCry
+ ld a,[$d11e]
+ call GetCryData ; get cry data
+ call PlaySound ; play sound
+ jr .handleMenuInput
+.choseArea
+ ld a,$4a
+ call Predef ; display pokemon areas
+ ld b,0
+ jr .exitSideMenu
+
+; handles the list of pokemon on the left of the pokedex screen
+; sets carry flag if player presses A, unsets carry flag if player presses B
+HandlePokedexListMenu: ; 40111 (10:4111)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED],a
+; draw the horizontal line separating the seen and owned amounts from the menu
+ FuncCoord 15,8
+ ld hl,Coord
+ ld a,$7a ; horizontal line tile
+ ld [hli],a
+ ld [hli],a
+ ld [hli],a
+ ld [hli],a
+ ld [hli],a
+ FuncCoord 14,0
+ ld hl,Coord
+ ld [hl],$71 ; vertical line tile
+ FuncCoord 14,1
+ ld hl,Coord
+ call DrawPokedexVerticalLine
+ FuncCoord 14,9
+ ld hl,Coord
+ call DrawPokedexVerticalLine
+ ld hl,wPokedexSeen
+ ld b,wPokedexSeenEnd - wPokedexSeen
+ call CountSetBits
+ ld de,$d11e
+ FuncCoord 16,3
+ ld hl,Coord
+ ld bc,$0103
+ call PrintNumber ; print number of seen pokemon
+ ld hl,wPokedexOwned
+ ld b,wPokedexOwnedEnd - wPokedexOwned
+ call CountSetBits
+ ld de,$d11e
+ FuncCoord 16,6
+ ld hl,Coord
+ ld bc,$0103
+ call PrintNumber ; print number of owned pokemon
+ FuncCoord 16,2
+ ld hl,Coord
+ ld de,PokedexSeenText
+ call PlaceString
+ FuncCoord 16,5
+ ld hl,Coord
+ ld de,PokedexOwnText
+ call PlaceString
+ FuncCoord 1,1
+ ld hl,Coord
+ ld de,PokedexContentsText
+ call PlaceString
+ FuncCoord 16,10
+ ld hl,Coord
+ ld de,PokedexMenuItemsText
+ call PlaceString
+; find the highest pokedex number among the pokemon the player has seen
+ ld hl,wPokedexSeenEnd - 1
+ ld b,153
+.maxSeenPokemonLoop
+ ld a,[hld]
+ ld c,8
+.maxSeenPokemonInnerLoop
+ dec b
+ sla a
+ jr c,.storeMaxSeenPokemon
+ dec c
+ jr nz,.maxSeenPokemonInnerLoop
+ jr .maxSeenPokemonLoop
+.storeMaxSeenPokemon
+ ld a,b
+ ld [$cd3d],a ; max seen pokemon
+.loop
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED],a
+ FuncCoord 4,2
+ ld hl,Coord
+ ld bc,$0e0a
+ call ClearScreenArea
+ FuncCoord 1,3
+ ld hl,Coord
+ ld a,[wListScrollOffset]
+ ld [$d11e],a
+ ld d,7
+ ld a,[$cd3d]
+ cp a,7
+ jr nc,.printPokemonLoop
+ ld d,a
+ dec a
+ ld [wMaxMenuItem],a
+; loop to print pokemon pokedex numbers and names
+; if the player has owned the pokemon, it puts a pokeball beside the name
+.printPokemonLoop
+ ld a,[$d11e]
+ inc a
+ ld [$d11e],a
+ push af
+ push de
+ push hl
+ ld de,-20
+ add hl,de
+ ld de,$d11e
+ ld bc,$8103
+ call PrintNumber ; print the pokedex number
+ ld de,20
+ add hl,de
+ dec hl
+ push hl
+ ld hl,wPokedexOwned
+ call IsPokemonBitSet
+ pop hl
+ ld a," "
+ jr z,.writeTile
+ ld a,$72 ; pokeball tile
+.writeTile
+ ld [hl],a ; put a pokeball next to pokemon that the player has owned
+ push hl
+ ld hl,wPokedexSeen
+ call IsPokemonBitSet
+ jr nz,.getPokemonName ; if the player has seen the pokemon
+ ld de,.dashedLine ; print a dashed line in place of the name if the player hasn't seen the pokemon
+ jr .skipGettingName
+.dashedLine ; for unseen pokemon in the list
+ db "----------@"
+.getPokemonName
+ call PokedexToIndex
+ call GetMonName
+.skipGettingName
+ pop hl
+ inc hl
+ call PlaceString
+ pop hl
+ ld bc,2 * 20
+ add hl,bc
+ pop de
+ pop af
+ ld [$d11e],a
+ dec d
+ jr nz,.printPokemonLoop
+ ld a,01
+ ld [H_AUTOBGTRANSFERENABLED],a
+ call Delay3
+ call GBPalNormal
+ call HandleMenuInput
+ bit 1,a ; was the B button pressed?
+ jp nz,.buttonBPressed
+.checkIfUpPressed
+ bit 6,a ; was Up pressed?
+ jr z,.checkIfDownPressed
+.upPressed ; scroll up one row
+ ld a,[wListScrollOffset]
+ and a
+ jp z,.loop
+ dec a
+ ld [wListScrollOffset],a
+ jp .loop
+.checkIfDownPressed
+ bit 7,a ; was Down pressed?
+ jr z,.checkIfRightPressed
+.downPressed ; scroll down one row
+ ld a,[$cd3d]
+ cp a,7
+ jp c,.loop
+ sub a,7
+ ld b,a
+ ld a,[wListScrollOffset]
+ cp b
+ jp z,.loop
+ inc a
+ ld [wListScrollOffset],a
+ jp .loop
+.checkIfRightPressed
+ bit 4,a ; was Right pressed?
+ jr z,.checkIfLeftPressed
+.rightPressed ; scroll down 7 rows
+ ld a,[$cd3d]
+ cp a,7
+ jp c,.loop
+ sub a,6
+ ld b,a
+ ld a,[wListScrollOffset]
+ add a,7
+ ld [wListScrollOffset],a
+ cp b
+ jp c,.loop
+ dec b
+ ld a,b
+ ld [wListScrollOffset],a
+ jp .loop
+.checkIfLeftPressed ; scroll up 7 rows
+ bit 5,a ; was Left pressed?
+ jr z,.buttonAPressed
+.leftPressed
+ ld a,[wListScrollOffset]
+ sub a,7
+ ld [wListScrollOffset],a
+ jp nc,.loop
+ xor a
+ ld [wListScrollOffset],a
+ jp .loop
+.buttonAPressed
+ scf
+ ret
+.buttonBPressed
+ and a
+ ret
+
+DrawPokedexVerticalLine: ; 4028e (10:428e)
+ ld c,9 ; height of line
+ ld de,20 ; width of screen
+ ld a,$71 ; vertical line tile
+.loop
+ ld [hl],a
+ add hl,de
+ xor a,1 ; toggle between vertical line tile and box tile
+ dec c
+ jr nz,.loop
+ ret
+
+PokedexSeenText: ; 4029d (10:429d)
+ db "SEEN@"
+
+PokedexOwnText: ; 402a2 (10:42a2)
+ db "OWN@"
+
+PokedexContentsText: ; 402a6 (10:42a6)
+ db "CONTENTS@"
+
+PokedexMenuItemsText: ; 402af (10:42af)
+ db "DATA"
+ next "CRY"
+ next "AREA"
+ next "QUIT@"
+
+; tests if a pokemon's bit is set in the seen or owned pokemon bit fields
+; INPUT:
+; [$d11e] = pokedex number
+; hl = address of bit field
+IsPokemonBitSet: ; 402c2 (10:42c2)
+ ld a,[$d11e]
+ dec a
+ ld c,a
+ ld b,2
+ ld a,$10
+ call Predef
+ ld a,c
+ and a
+ ret
+
+; function to display pokedex data from outside the pokedex
+ShowPokedexData: ; 402d1 (10:42d1)
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ call UpdateSprites
+ callab LoadPokedexTilePatterns ; load pokedex tiles
+
+; function to display pokedex data from inside the pokedex
+ShowPokedexDataInternal: ; 402e2 (10:42e2)
+ ld hl,$d72c
+ set 1,[hl]
+ ld a,$33 ; 3/7 volume
+ ld [$ff24],a
+ call GBPalWhiteOut ; zero all palettes
+ call ClearScreen
+ ld a,[$d11e] ; pokemon ID
+ ld [$cf91],a
+ push af
+ ld b,04
+ call GoPAL_SET
+ pop af
+ ld [$d11e],a
+ ld a,[$ffd7]
+ push af
+ xor a
+ ld [$ffd7],a
+ FuncCoord 0,0
+ ld hl,Coord
+ ld de,1
+ ld bc,$6414
+ call DrawTileLine ; draw top border
+ FuncCoord 0,17
+ ld hl,Coord
+ ld b,$6f
+ call DrawTileLine ; draw bottom border
+ FuncCoord 0,1
+ ld hl,Coord
+ ld de,20
+ ld bc,$6610
+ call DrawTileLine ; draw left border
+ FuncCoord 19,1
+ ld hl,Coord
+ ld b,$67
+ call DrawTileLine ; draw right border
+ FuncCoord 0,0
+ ld a,$63 ; upper left corner tile
+ ld [Coord],a
+ FuncCoord 19,0
+ ld a,$65 ; upper right corner tile
+ ld [Coord],a
+ FuncCoord 0,17
+ ld a,$6c ; lower left corner tile
+ ld [Coord],a
+ FuncCoord 19,17
+ ld a,$6e ; lower right corner tile
+ ld [Coord],a
+ FuncCoord 0,9
+ ld hl,Coord
+ ld de,PokedexDataDividerLine
+ call PlaceString ; draw horizontal divider line
+ FuncCoord 9,6
+ ld hl,Coord
+ ld de,HeightWeightText
+ call PlaceString
+ call GetMonName
+ FuncCoord 9,2
+ ld hl,Coord
+ call PlaceString
+ ld hl,PokedexEntryPointers
+ ld a,[$d11e]
+ dec a
+ ld e,a
+ ld d,0
+ add hl,de
+ add hl,de
+ ld a,[hli]
+ ld e,a
+ ld d,[hl] ; de = address of pokedex entry
+ FuncCoord 9,4
+ ld hl,Coord
+ call PlaceString ; print species name
+ ld h,b
+ ld l,c
+ push de
+ ld a,[$d11e]
+ push af
+ call IndexToPokedex
+ FuncCoord 2,8
+ ld hl,Coord
+ ld a, "№"
+ ld [hli],a
+ ld a,$f2
+ ld [hli],a
+ ld de,$d11e
+ ld bc,$8103
+ call PrintNumber ; print pokedex number
+ ld hl,wPokedexOwned
+ call IsPokemonBitSet
+ pop af
+ ld [$d11e],a
+ ld a,[$cf91]
+ ld [$d0b5],a
+ pop de
+ push af
+ push bc
+ push de
+ push hl
+ call Delay3
+ call GBPalNormal
+ call GetMonHeader ; load pokemon picture location
+ FuncCoord 1,1
+ ld hl,Coord
+ call LoadFlippedFrontSpriteByMonIndex ; draw pokemon picture
+ ld a,[$cf91]
+ call PlayCry ; play pokemon cry
+ pop hl
+ pop de
+ pop bc
+ pop af
+ ld a,c
+ and a
+ jp z,.waitForButtonPress ; if the pokemon has not been owned, don't print the height, weight, or description
+ inc de ; de = address of feet (height)
+ ld a,[de] ; reads feet, but a is overwritten without being used
+ FuncCoord 12,6
+ ld hl,Coord
+ ld bc,$0102
+ call PrintNumber ; print feet (height)
+ ld a,$60 ; feet symbol tile (one tick)
+ ld [hl],a
+ inc de
+ inc de ; de = address of inches (height)
+ FuncCoord 15,6
+ ld hl,Coord
+ ld bc,$8102
+ call PrintNumber ; print inches (height)
+ ld a,$61 ; inches symbol tile (two ticks)
+ ld [hl],a
+; now print the weight (note that weight is stored in tenths of pounds internally)
+ inc de
+ inc de
+ inc de ; de = address of upper byte of weight
+ push de
+; put weight in big-endian order at $ff8b
+ ld hl,$ff8b
+ ld a,[hl] ; save existing value of [$ff8b]
+ push af
+ ld a,[de] ; a = upper byte of weight
+ ld [hli],a ; store upper byte of weight in [$ff8b]
+ ld a,[hl] ; save existing value of [$ff8c]
+ push af
+ dec de
+ ld a,[de] ; a = lower byte of weight
+ ld [hl],a ; store lower byte of weight in [$ff8c]
+ FuncCoord 11,8
+ ld de,$ff8b
+ ld hl,Coord
+ ld bc,$0205 ; no leading zeroes, right-aligned, 2 bytes, 5 digits
+ call PrintNumber ; print weight
+ FuncCoord 14,8
+ ld hl,Coord
+ ld a,[$ff8c]
+ sub a,10
+ ld a,[$ff8b]
+ sbc a,0
+ jr nc,.next
+ ld [hl],"0" ; if the weight is less than 10, put a 0 before the decimal point
+.next
+ inc hl
+ ld a,[hli]
+ ld [hld],a ; make space for the decimal point by moving the last digit forward one tile
+ ld [hl],$f2 ; decimal point tile
+ pop af
+ ld [$ff8c],a ; restore original value of [$ff8c]
+ pop af
+ ld [$ff8b],a ; restore original value of [$ff8b]
+ pop hl
+ inc hl ; hl = address of pokedex description text
+ FuncCoord 1,11
+ ld bc,Coord
+ ld a,2
+ ld [$fff4],a
+ call TextCommandProcessor ; print pokedex description text
+ xor a
+ ld [$fff4],a
+.waitForButtonPress
+ call GetJoypadStateLowSensitivity
+ ld a,[$ffb5]
+ and a,%00000011 ; A button and B button
+ jr z,.waitForButtonPress
+ pop af
+ ld [$ffd7],a
+ call GBPalWhiteOut
+ call ClearScreen
+ call GoPAL_SET_CF1C
+ call LoadTextBoxTilePatterns
+ call GBPalNormal
+ ld hl,$d72c
+ res 1,[hl]
+ ld a,$77 ; max volume
+ ld [$ff24],a
+ ret
+
+HeightWeightText: ; 40448 (10:4448)
+ db "HT ?",$60,"??",$61,$4E,"WT ???lb@"
+
+; XXX does anything point to this?
+Unknown_4045D: ; 4045d (10:445d)
+ db $54,$50
+
+; horizontal line that divides the pokedex text description from the rest of the data
+PokedexDataDividerLine: ; 4045f (10:445f)
+ db $68,$69,$6B,$69,$6B
+ db $69,$6B,$69,$6B,$6B
+ db $6B,$6B,$69,$6B,$69
+ db $6B,$69,$6B,$69,$6A
+ db $50
+
+; draws a line of tiles
+; INPUT:
+; b = tile ID
+; c = number of tile ID's to write
+; de = amount to destination address after each tile (1 for horizontal, 20 for vertical)
+; hl = destination address
+DrawTileLine: ; 40474 (10:4474)
+ push bc
+ push de
+.loop
+ ld [hl],b
+ add hl,de
+ dec c
+ jr nz,.loop
+ pop de
+ pop bc
+ ret
+
+INCLUDE "data/pokedex_entries.asm"
+
+PokedexToIndex: ; 40ff9 (10:4ff9)
+ ; converts the Pokédex number at $D11E to an index
+ push bc
+ push hl
+ ld a,[$D11E]
+ ld b,a
+ ld c,0
+ ld hl,PokedexOrder
+
+.loop ; go through the list until we find an entry with a matching dex number
+ inc c
+ ld a,[hli]
+ cp b
+ jr nz,.loop
+
+ ld a,c
+ ld [$D11E],a
+ pop hl
+ pop bc
+ ret
+
+IndexToPokedex: ; 41010 (10:5010)
+ ; converts the indexédex number at $D11E to a Pokédex number
+ push bc
+ push hl
+ ld a,[$D11E]
+ dec a
+ ld hl,PokedexOrder
+ ld b,0
+ ld c,a
+ add hl,bc
+ ld a,[hl]
+ ld [$D11E],a
+ pop hl
+ pop bc
+ ret
+
+INCLUDE "data/pokedex_order.asm"
diff --git a/engine/menu/prize_menu.asm b/engine/menu/prize_menu.asm
new file mode 100755
index 00000000..79de7029
--- /dev/null
+++ b/engine/menu/prize_menu.asm
@@ -0,0 +1,316 @@
+CeladonPrizeMenu: ; 5271b (14:671b)
+ ld b,COIN_CASE
+ call IsItemInBag
+ jr nz,.havingCoinCase
+ ld hl,RequireCoinCaseTextPtr
+ jp PrintText
+.havingCoinCase
+ ld hl,$D730
+ set 6,[hl]
+ ld hl,ExchangeCoinsForPrizesTextPtr
+ call PrintText
+; the following are the menu settings
+ xor a
+ ld [$CC26],a
+ ld [$CC2A],a
+ ld a,$03
+ ld [$CC29],a
+ ld a,$03
+ ld [$CC28],a
+ ld a,$04
+ ld [$CC24],a
+ ld a,$01
+ ld [$CC25],a
+ call PrintPrizePrice ; 687A
+ FuncCoord 0,2
+ ld hl,Coord
+ ld b,$08
+ ld c,$10
+ call TextBoxBorder
+ call GetPrizeMenuId ;678E
+ call UpdateSprites
+ ld hl,WhichPrizeTextPtr
+ call PrintText
+ call HandleMenuInput ; menu choice handler
+ bit 1,a ; keypress = B (Cancel)
+ jr nz,.NoChoice
+ ld a,[$CC26]
+ cp a,$03 ; "NO,THANKS" choice
+ jr z,.NoChoice
+ call HandlePrizeChoice ; 14:68C6
+.NoChoice
+ ld hl,$D730
+ res 6,[hl]
+ ret
+
+RequireCoinCaseTextPtr: ; 5277e (14:677e)
+ TX_FAR _RequireCoinCaseText
+ db $0D
+ db "@"
+
+ExchangeCoinsForPrizesTextPtr: ; 52784 (14:6784)
+ TX_FAR _ExchangeCoinsForPrizesText
+ db "@"
+
+WhichPrizeTextPtr: ; 52789 (14:6789)
+ TX_FAR _WhichPrizeText
+ db "@"
+
+GetPrizeMenuId: ; 5278e (14:678e)
+; determine which one among the three
+; prize-texts has been selected
+; using the text ID (stored in [$FF8C])
+; load the three prizes at $D13D-$D13F
+; load the three prices at $D141-$D146
+; display the three prizes' names
+; (distinguishing between Pokemon names
+; and Items (specifically TMs) names)
+ ld a,[$FF8C]
+ sub a,$03 ; prize-texts' id are 3, 4 and 5
+ ld [$D12F],a ; prize-texts' id (relative, i.e. 0, 1 or 2)
+ add a
+ add a
+ ld d,$00
+ ld e,a
+ ld hl,PrizeDifferentMenuPtrs
+ add hl,de
+ ld a,[hli]
+ ld d,[hl]
+ ld e,a
+ inc hl
+ push hl
+ ld hl,W_PRIZE1
+ call CopyString ; XXX what does this do
+ pop hl
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ ld de,$D141
+ ld bc,$0006
+ call CopyData
+ ld a,[$D12F]
+ cp a,$02 ;is TM_menu?
+ jr nz,.putMonName
+ ld a,[W_PRIZE1]
+ ld [$D11E],a
+ call GetItemName
+ FuncCoord 2,4
+ ld hl,Coord
+ call PlaceString
+ ld a,[W_PRIZE2]
+ ld [$D11E],a
+ call GetItemName
+ FuncCoord 2,6
+ ld hl,Coord
+ call PlaceString
+ ld a,[W_PRIZE3]
+ ld [$D11E],a
+ call GetItemName
+ FuncCoord 2,8
+ ld hl,Coord
+ call PlaceString
+ jr .putNoThanksText
+.putMonName ; 14:67EC
+ ld a,[W_PRIZE1]
+ ld [$D11E],a
+ call GetMonName
+ FuncCoord 2,4
+ ld hl,Coord
+ call PlaceString
+ ld a,[W_PRIZE2]
+ ld [$D11E],a
+ call GetMonName
+ FuncCoord 2,6
+ ld hl,Coord
+ call PlaceString
+ ld a,[W_PRIZE3]
+ ld [$D11E],a
+ call GetMonName
+ FuncCoord 2,8
+ ld hl,Coord
+ call PlaceString
+.putNoThanksText ; 14:6819
+ FuncCoord 2,10
+ ld hl,Coord
+ ld de,NoThanksText
+ call PlaceString
+; put prices on the right side of the textbox
+ ld de,$D141
+ FuncCoord 13,5
+ ld hl,Coord
+; reg. c:
+; [low nybble] number of bytes
+; [bit 765 = %100] space-padding (not zero-padding)
+ ld c,(1 << 7 | 2)
+; Function $15CD displays BCD value (same routine
+; used by text-command $02)
+ call PrintBCDNumber ; Print_BCD
+ ld de,$D143
+ FuncCoord 13,7
+ ld hl,Coord
+ ld c,(%1 << 7 | 2)
+ call PrintBCDNumber
+ ld de,$D145
+ FuncCoord 13,9
+ ld hl,Coord
+ ld c,(1 << 7 | 2)
+ jp PrintBCDNumber
+
+INCLUDE "data/prizes.asm"
+
+PrintPrizePrice: ; 5287a (14:687a)
+ FuncCoord 11,0
+ ld hl,Coord
+ ld b,$01
+ ld c,$07
+ call TextBoxBorder
+ call UpdateSprites ; XXX save OAM?
+ FuncCoord 12,0
+ ld hl,Coord
+ ld de,.CoinText
+ call PlaceString
+ FuncCoord 13,1
+ ld hl,Coord
+ ld de,.SixSpacesText
+ call PlaceString
+ FuncCoord 13,1
+ ld hl,Coord
+ ld de,wPlayerCoins
+ ld c,%10000010
+ call PrintBCDNumber
+ ret
+
+.CoinText ; 14:68A5
+ db "COIN@"
+
+.SixSpacesText ; 14:68AA
+ db " @"
+
+LoadCoinsToSubtract: ; 528b1 (14:68b1)
+ ld a,[$D139] ; backup of selected menu_entry
+ add a
+ ld d,$00
+ ld e,a
+ ld hl,$D141 ; first prize's price
+ add hl,de ; get selected prize's price
+ xor a
+ ld [$FF9F],a
+ ld a,[hli]
+ ld [$FFA0],a
+ ld a,[hl]
+ ld [$FFA1],a
+ ret
+
+HandlePrizeChoice: ; 528c6 (14:68c6)
+ ld a,[$CC26] ; selected menu_entry
+ ld [$D139],a
+ ld d,$00
+ ld e,a
+ ld hl,W_PRIZE1
+ add hl,de
+ ld a,[hl]
+ ld [$D11E],a
+ ld a,[$D12F]
+ cp a,$02 ; is prize a TM?
+ jr nz,.GetMonName
+ call GetItemName
+ jr .GivePrize
+.GetMonName ; 14:68E3
+ call GetMonName
+.GivePrize ; 14:68E6
+ ld hl,SoYouWantPrizeTextPtr
+ call PrintText
+ call YesNoChoice ; yes/no textbox
+ ld a,[$CC26] ; yes/no answer (Y=0, N=1)
+ and a
+ jr nz,.PrintOhFineThen
+ call LoadCoinsToSubtract
+ call HasEnoughCoins
+ jr c,.NotEnoughCoins
+ ld a,[$D12F]
+ cp a,$02
+ jr nz,.GiveMon
+ ld a,[$D11E]
+ ld b,a
+ ld a,1
+ ld c,a
+ call GiveItem ; GiveItem
+ jr nc,.BagFull
+ jr .SubtractCoins
+.GiveMon ; 14:6912
+ ld a,[$D11E]
+ ld [$CF91],a
+ push af
+ call GetPrizeMonLevel ; 14:6977
+ ld c,a
+ pop af
+ ld b,a
+ call GivePokemon
+ push af
+ ld a,[$CCD3] ; XXX is there room?
+ and a
+ call z,WaitForTextScrollButtonPress
+ pop af
+ ret nc
+.SubtractCoins ; 14:692C
+ call LoadCoinsToSubtract
+ ld hl,$FFA1
+ ld de,wPlayerCoins + 1
+ ld c,$02 ; how many bytes
+ ld a,$0C
+ call Predef ; subtract coins (BCD daa operations)
+ jp PrintPrizePrice
+.BagFull
+ ld hl,PrizeRoomBagIsFullTextPtr
+ jp PrintText
+.NotEnoughCoins ; 14:6945
+ ld hl,SorryNeedMoreCoinsText
+ jp PrintText
+.PrintOhFineThen ; 14:694B
+ ld hl,OhFineThenTextPtr
+ jp PrintText
+
+UnknownData52951: ; 52951 (14:6951)
+; XXX what's this?
+ db $00,$01,$00,$01,$00,$01,$00,$00,$01
+
+HereYouGoTextPtr: ; 5295a (14:695a)
+ TX_FAR _HereYouGoText
+ db $0D
+ db "@"
+
+SoYouWantPrizeTextPtr: ; 52960 (14:6960)
+ TX_FAR _SoYouWantPrizeText
+ db "@"
+
+SorryNeedMoreCoinsText: ; 52965 (14:6965)
+ TX_FAR _SorryNeedMoreCoinsText
+ db $0D
+ db "@"
+
+PrizeRoomBagIsFullTextPtr: ; 5296b (14:696b)
+ TX_FAR _OopsYouDontHaveEnoughRoomText
+ db $0D
+ db "@"
+
+OhFineThenTextPtr: ; 52971 (14:6971)
+ TX_FAR _OhFineThenText
+ db $0D ; wait keypress (A/B) without blink
+ db "@"
+
+GetPrizeMonLevel: ; 52977 (14:6977)
+ ld a,[$CF91]
+ ld b,a
+ ld hl,PrizeMonLevelDictionary
+.loop ; 14:697E
+ ld a,[hli]
+ cp b
+ jr z,.matchFound
+ inc hl
+ jr .loop
+.matchFound ; 14:6985
+ ld a,[hl]
+ ld [$D127],a
+ ret
+
+INCLUDE "data/prize_mon_levels.asm"
diff --git a/engine/menu/start_menu.asm b/engine/menu/start_menu.asm
new file mode 100755
index 00000000..774f604d
--- /dev/null
+++ b/engine/menu/start_menu.asm
@@ -0,0 +1,88 @@
+DisplayStartMenu:: ; 2acd (0:2acd)
+ ld a,$04 ; hardcoded Bank, not sure what's it refers to
+ ld [H_LOADEDROMBANK],a
+ ld [$2000],a ; ROM bank 4
+ ld a,[$d700] ; walking/biking/surfing
+ ld [$d11a],a
+ ld a, (SFX_02_3f - SFX_Headers_02) / 3 ; Start menu sound
+ call PlaySound
+
+RedisplayStartMenu:: ; 2adf (0:2adf)
+ callba DrawStartMenu
+ callba PrintSafariZoneSteps ; print Safari Zone info, if in Safari Zone
+ call UpdateSprites ; move sprites
+.loop
+ call HandleMenuInput
+ ld b,a
+.checkIfUpPressed
+ bit 6,a ; was Up pressed?
+ jr z,.checkIfDownPressed
+ ld a,[wCurrentMenuItem] ; menu selection
+ and a
+ jr nz,.loop
+ ld a,[wLastMenuItem]
+ and a
+ jr nz,.loop
+; if the player pressed tried to go past the top item, wrap around to the bottom
+ ld a,[$d74b]
+ bit 5,a ; does the player have the pokedex?
+ ld a,6 ; there are 7 menu items with the pokedex, so the max index is 6
+ jr nz,.wrapMenuItemId
+ dec a ; there are only 6 menu items without the pokedex
+.wrapMenuItemId
+ ld [wCurrentMenuItem],a
+ call EraseMenuCursor
+ jr .loop
+.checkIfDownPressed
+ bit 7,a
+ jr z,.buttonPressed
+; if the player pressed tried to go past the bottom item, wrap around to the top
+ ld a,[$d74b]
+ bit 5,a ; does the player have the pokedex?
+ ld a,[wCurrentMenuItem]
+ ld c,7 ; there are 7 menu items with the pokedex
+ jr nz,.checkIfPastBottom
+ dec c ; there are only 6 menu items without the pokedex
+.checkIfPastBottom
+ cp c
+ jr nz,.loop
+; the player went past the bottom, so wrap to the top
+ xor a
+ ld [wCurrentMenuItem],a
+ call EraseMenuCursor
+ jr .loop
+.buttonPressed ; A, B, or Start button pressed
+ call PlaceUnfilledArrowMenuCursor
+ ld a,[wCurrentMenuItem]
+ ld [$cc2d],a ; save current menu item ID
+ ld a,b
+ and a,%00001010 ; was the Start button or B button pressed?
+ jp nz,CloseStartMenu
+ call SaveScreenTilesToBuffer2 ; copy background from wTileMap to wTileMapBackup2
+ ld a,[$d74b]
+ bit 5,a ; does the player have the pokedex?
+ ld a,[wCurrentMenuItem]
+ jr nz,.displayMenuItem
+ inc a ; adjust position to account for missing pokedex menu item
+.displayMenuItem
+ cp a,0
+ jp z,StartMenu_Pokedex
+ cp a,1
+ jp z,StartMenu_Pokemon
+ cp a,2
+ jp z,StartMenu_Item
+ cp a,3
+ jp z,StartMenu_TrainerInfo
+ cp a,4
+ jp z,StartMenu_SaveReset
+ cp a,5
+ jp z,StartMenu_Option
+
+; EXIT falls through to here
+CloseStartMenu:: ; 2b70 (0:2b70)
+ call GetJoypadState
+ ld a,[H_NEWLYPRESSEDBUTTONS]
+ bit 0,a ; was A button newly pressed?
+ jr nz,CloseStartMenu
+ call LoadTextBoxTilePatterns
+ jp CloseTextDisplay
diff --git a/engine/menu/start_sub_menus.asm b/engine/menu/start_sub_menus.asm
new file mode 100755
index 00000000..60893d81
--- /dev/null
+++ b/engine/menu/start_sub_menus.asm
@@ -0,0 +1,875 @@
+StartMenu_Pokedex: ; 13095 (4:7095)
+ ld a,$29
+ call Predef
+ call LoadScreenTilesFromBuffer2 ; restore saved screen
+ call Delay3
+ call LoadGBPal
+ call UpdateSprites
+ jp RedisplayStartMenu
+
+StartMenu_Pokemon: ; 130a9 (4:70a9)
+ ld a,[W_NUMINPARTY]
+ and a
+ jp z,RedisplayStartMenu
+ xor a
+ ld [$cc35],a
+ ld [$d07d],a
+ ld [$cfcb],a
+ call DisplayPartyMenu
+ jr .checkIfPokemonChosen
+.loop
+ xor a
+ ld [$cc35],a
+ ld [$d07d],a
+ call GoBackToPartyMenu
+.checkIfPokemonChosen
+ jr nc,.chosePokemon
+.exitMenu
+ call GBPalWhiteOutWithDelay3
+ call Func_3dbe
+ call LoadGBPal
+ jp RedisplayStartMenu
+.chosePokemon
+ call SaveScreenTilesToBuffer1 ; save screen
+ ld a,$04
+ ld [$d125],a
+ call DisplayTextBoxID ; display pokemon menu options
+ ld hl,$cd3d
+ ld bc,$020c ; max menu item ID, top menu item Y
+ ld e,5
+.adjustMenuVariablesLoop
+ dec e
+ jr z,.storeMenuVariables
+ ld a,[hli]
+ and a
+ jr z,.storeMenuVariables
+ inc b
+ dec c
+ dec c
+ jr .adjustMenuVariablesLoop
+.storeMenuVariables
+ ld hl,wTopMenuItemY
+ ld a,c
+ ld [hli],a ; top menu item Y
+ ld a,[$fff7]
+ ld [hli],a ; top menu item X
+ xor a
+ ld [hli],a ; current menu item ID
+ inc hl
+ ld a,b
+ ld [hli],a ; max menu item ID
+ ld a,%00000011 ; A button, B button
+ ld [hli],a ; menu watched keys
+ xor a
+ ld [hl],a
+ call HandleMenuInput
+ push af
+ call LoadScreenTilesFromBuffer1 ; restore saved screen
+ pop af
+ bit 1,a ; was the B button pressed?
+ jp nz,.loop
+; if the B button wasn't pressed
+ ld a,[wMaxMenuItem]
+ ld b,a
+ ld a,[wCurrentMenuItem] ; menu selection
+ cp b
+ jp z,.exitMenu ; if the player chose Cancel
+ dec b
+ cp b
+ jr z,.choseSwitch
+ dec b
+ cp b
+ jp z,.choseStats
+ ld c,a
+ ld b,0
+ ld hl,$cd3d
+ add hl,bc
+ jp .choseOutOfBattleMove
+.choseSwitch
+ ld a,[W_NUMINPARTY]
+ cp a,2 ; is there more than one pokemon in the party?
+ jp c,StartMenu_Pokemon ; if not, no switching
+ call SwitchPartyMon_Stats
+ ld a,$04 ; swap pokemon positions menu
+ ld [$d07d],a
+ call GoBackToPartyMenu
+ jp .checkIfPokemonChosen
+.choseStats
+ call CleanLCD_OAM
+ xor a
+ ld [$cc49],a
+ ld a,$36
+ call Predef
+ ld a,$37
+ call Predef
+ call ReloadMapData
+ jp StartMenu_Pokemon
+.choseOutOfBattleMove
+ push hl
+ ld a,[wWhichPokemon]
+ ld hl,W_PARTYMON1NAME
+ call GetPartyMonName
+ pop hl
+ ld a,[hl]
+ dec a
+ add a
+ ld b,0
+ ld c,a
+ ld hl,.outOfBattleMovePointers
+ add hl,bc
+ ld a,[hli]
+ ld h,[hl]
+ ld l,a
+ ld a,[W_OBTAINEDBADGES] ; badges obtained
+ jp [hl]
+.outOfBattleMovePointers
+ dw .cut
+ dw .fly
+ dw .surf
+ dw .surf
+ dw .strength
+ dw .flash
+ dw .dig
+ dw .teleport
+ dw .softboiled
+.fly
+ bit 2,a ; does the player have the Thunder Badge?
+ jp z,.newBadgeRequired
+ call CheckIfInOutsideMap
+ jr z,.canFly
+ ld a,[wWhichPokemon]
+ ld hl,W_PARTYMON1NAME
+ call GetPartyMonName
+ ld hl,.cannotFlyHereText
+ call PrintText
+ jp .loop
+.canFly
+ call ChooseFlyDestination
+ ld a,[$d732]
+ bit 3,a ; did the player decide to fly?
+ jp nz,.goBackToMap
+ call LoadFontTilePatterns
+ ld hl,$d72e
+ set 1,[hl]
+ jp StartMenu_Pokemon
+.cut
+ bit 1,a ; does the player have the Cascade Badge?
+ jp z,.newBadgeRequired
+ ld a,$3c
+ call Predef
+ ld a,[$cd6a]
+ and a
+ jp z,.loop
+ jp CloseTextDisplay
+.surf
+ bit 4,a ; does the player have the Soul Badge?
+ jp z,.newBadgeRequired
+ callba CheckForForcedBikeSurf
+ ld hl,$d728
+ bit 1,[hl]
+ res 1,[hl]
+ jp z,.loop
+ ld a,SURFBOARD
+ ld [$cf91],a
+ ld [$d152],a
+ call UseItem
+ ld a,[$cd6a]
+ and a
+ jp z,.loop
+ call GBPalWhiteOutWithDelay3
+ jp .goBackToMap
+.strength
+ bit 3,a ; does the player have the Rainbow Badge?
+ jp z,.newBadgeRequired
+ ld a,$5b
+ call Predef
+ call GBPalWhiteOutWithDelay3
+ jp .goBackToMap
+.flash
+ bit 0,a ; does the player have the Boulder Badge?
+ jp z,.newBadgeRequired
+ xor a
+ ld [$d35d],a
+ ld hl,.flashLightsAreaText
+ call PrintText
+ call GBPalWhiteOutWithDelay3
+ jp .goBackToMap
+.flashLightsAreaText
+ TX_FAR _FlashLightsAreaText
+ db "@"
+.dig
+ ld a,ESCAPE_ROPE
+ ld [$cf91],a
+ ld [$d152],a
+ call UseItem
+ ld a,[$cd6a]
+ and a
+ jp z,.loop
+ call GBPalWhiteOutWithDelay3
+ jp .goBackToMap
+.teleport
+ call CheckIfInOutsideMap
+ jr z,.canTeleport
+ ld a,[wWhichPokemon]
+ ld hl,W_PARTYMON1NAME
+ call GetPartyMonName
+ ld hl,.cannotUseTeleportNowText
+ call PrintText
+ jp .loop
+.canTeleport
+ ld hl,.warpToLastPokemonCenterText
+ call PrintText
+ ld hl,$d732
+ set 3,[hl]
+ set 6,[hl]
+ ld hl,$d72e
+ set 1,[hl]
+ res 4,[hl]
+ ld c,60
+ call DelayFrames
+ call GBPalWhiteOutWithDelay3 ; zero all three palettes and wait 3 V-blanks
+ jp .goBackToMap
+.warpToLastPokemonCenterText
+ TX_FAR _WarpToLastPokemonCenterText
+ db "@"
+.cannotUseTeleportNowText
+ TX_FAR _CannotUseTeleportNowText
+ db "@"
+.cannotFlyHereText
+ TX_FAR _CannotFlyHereText
+ db "@"
+.softboiled
+ ld hl,W_PARTYMON1_MAXHP
+ ld a,[wWhichPokemon]
+ ld bc,44
+ call AddNTimes
+ ld a,[hli]
+ ld [H_DIVIDEND],a
+ ld a,[hl]
+ ld [H_DIVIDEND + 1],a
+ ld a,5
+ ld [H_DIVISOR],a
+ ld b,2 ; number of bytes
+ call Divide
+ ld bc,-33
+ add hl,bc
+ ld a,[hld]
+ ld b,a
+ ld a,[H_QUOTIENT + 3]
+ sub b
+ ld b,[hl]
+ ld a,[H_QUOTIENT + 2]
+ sbc b
+ jp nc,.notHealthyEnough
+ ld a,[$cc2b]
+ push af
+ ld a,POTION
+ ld [$cf91],a
+ ld [$d152],a
+ call UseItem
+ pop af
+ ld [$cc2b],a
+ jp .loop
+.notHealthyEnough ; if current HP is less than 1/5 of max HP
+ ld hl,.notHealthyEnoughText
+ call PrintText
+ jp .loop
+.notHealthyEnoughText
+ TX_FAR _NotHealthyEnoughText
+ db "@"
+.goBackToMap
+ call Func_3dbe
+ jp CloseTextDisplay
+.newBadgeRequired
+ ld hl,.newBadgeRequiredText
+ call PrintText
+ jp .loop
+.newBadgeRequiredText
+ TX_FAR _NewBadgeRequiredText
+ db "@"
+
+; writes a blank tile to all possible menu cursor positions on the party menu
+ErasePartyMenuCursors: ; 132ed (4:72ed)
+ FuncCoord 0,1
+ ld hl,Coord
+ ld bc,2 * 20 ; menu cursor positions are 2 rows apart
+ ld a,6 ; 6 menu cursor positions
+.loop
+ ld [hl]," "
+ add hl,bc
+ dec a
+ jr nz,.loop
+ ret
+
+ItemMenuLoop: ; 132fc (4:72fc)
+ call LoadScreenTilesFromBuffer2DisableBGTransfer ; restore saved screen
+ call GoPAL_SET_CF1C
+
+StartMenu_Item: ; 13302 (4:7302)
+ ld a,[W_ISLINKBATTLE]
+ dec a
+ jr nz,.notInLinkBattle
+ ld hl,CannotUseItemsHereText
+ call PrintText
+ jr .exitMenu
+.notInLinkBattle
+ ld bc,wNumBagItems
+ ld hl,$cf8b
+ ld a,c
+ ld [hli],a
+ ld [hl],b ; store item bag pointer at $cf8b (for DisplayListMenuID)
+ xor a
+ ld [$cf93],a
+ ld a,ITEMLISTMENU
+ ld [wListMenuID],a
+ ld a,[$cc2c]
+ ld [wCurrentMenuItem],a
+ call DisplayListMenuID
+ ld a,[wCurrentMenuItem]
+ ld [$cc2c],a
+ jr nc,.choseItem
+.exitMenu
+ call LoadScreenTilesFromBuffer2 ; restore saved screen
+ call LoadTextBoxTilePatterns
+ call UpdateSprites ; move sprites
+ jp RedisplayStartMenu
+.choseItem
+; erase menu cursor (blank each tile in front of an item name)
+ ld a," "
+ FuncCoord 5,4
+ ld [Coord],a
+ FuncCoord 5,6
+ ld [Coord],a
+ FuncCoord 5,8
+ ld [Coord],a
+ FuncCoord 5,10
+ ld [Coord],a
+ call PlaceUnfilledArrowMenuCursor
+ xor a
+ ld [$cc35],a
+ ld a,[$cf91]
+ cp a,BICYCLE
+ jp z,.useOrTossItem
+.notBicycle1
+ ld a,$06 ; use/toss menu
+ ld [$d125],a
+ call DisplayTextBoxID
+ ld hl,wTopMenuItemY
+ ld a,11
+ ld [hli],a ; top menu item Y
+ ld a,14
+ ld [hli],a ; top menu item X
+ xor a
+ ld [hli],a ; current menu item ID
+ inc hl
+ inc a ; a = 1
+ ld [hli],a ; max menu item ID
+ ld a,%00000011 ; A button, B button
+ ld [hli],a ; menu watched keys
+ xor a
+ ld [hl],a ; old menu item id
+ call HandleMenuInput
+ call PlaceUnfilledArrowMenuCursor
+ bit 1,a ; was the B button pressed?
+ jr z,.useOrTossItem
+ jp ItemMenuLoop
+.useOrTossItem ; if the player made the choice to use or toss the item
+ ld a,[$cf91]
+ ld [$d11e],a
+ call GetItemName
+ call CopyStringToCF4B ; copy name to $cf4b
+ ld a,[$cf91]
+ cp a,BICYCLE
+ jr nz,.notBicycle2
+ ld a,[$d732]
+ bit 5,a
+ jr z,.useItem_closeMenu
+ ld hl,CannotGetOffHereText
+ call PrintText
+ jp ItemMenuLoop
+.notBicycle2
+ ld a,[wCurrentMenuItem]
+ and a
+ jr nz,.tossItem
+.useItem
+ ld [$d152],a
+ ld a,[$cf91]
+ cp a,HM_01
+ jr nc,.useItem_partyMenu
+ ld hl,UsableItems_CloseMenu
+ ld de,1
+ call IsInArray
+ jr c,.useItem_closeMenu
+ ld a,[$cf91]
+ ld hl,UsableItems_PartyMenu
+ ld de,1
+ call IsInArray
+ jr c,.useItem_partyMenu
+ call UseItem
+ jp ItemMenuLoop
+.useItem_closeMenu
+ xor a
+ ld [$d152],a
+ call UseItem
+ ld a,[$cd6a]
+ and a
+ jp z,ItemMenuLoop
+ jp CloseStartMenu
+.useItem_partyMenu
+ ld a,[$cfcb]
+ push af
+ call UseItem
+ ld a,[$cd6a]
+ cp a,$02
+ jp z,.partyMenuNotDisplayed
+ call GBPalWhiteOutWithDelay3
+ call Func_3dbe
+ pop af
+ ld [$cfcb],a
+ jp StartMenu_Item
+.partyMenuNotDisplayed
+ pop af
+ ld [$cfcb],a
+ jp ItemMenuLoop
+.tossItem
+ call IsKeyItem
+ ld a,[$d124]
+ and a
+ jr nz,.skipAskingQuantity
+ ld a,[$cf91]
+ call IsItemHM
+ jr c,.skipAskingQuantity
+ call DisplayChooseQuantityMenu
+ inc a
+ jr z,.tossZeroItems
+.skipAskingQuantity
+ ld hl,wNumBagItems
+ call TossItem
+.tossZeroItems
+ jp ItemMenuLoop
+
+CannotUseItemsHereText: ; 1342a (4:742a)
+ TX_FAR _CannotUseItemsHereText
+ db "@"
+
+CannotGetOffHereText: ; 1342f (4:742f)
+ TX_FAR _CannotGetOffHereText
+ db "@"
+
+; items which bring up the party menu when used
+UsableItems_PartyMenu: ; 13434 (4:7434)
+ db MOON_STONE
+ db ANTIDOTE
+ db BURN_HEAL
+ db ICE_HEAL
+ db AWAKENING
+ db PARLYZ_HEAL
+ db FULL_RESTORE
+ db MAX_POTION
+ db HYPER_POTION
+ db SUPER_POTION
+ db POTION
+ db FIRE_STONE
+ db THUNDER_STONE
+ db WATER_STONE
+ db HP_UP
+ db PROTEIN
+ db IRON
+ db CARBOS
+ db CALCIUM
+ db RARE_CANDY
+ db LEAF_STONE
+ db FULL_HEAL
+ db REVIVE
+ db MAX_REVIVE
+ db FRESH_WATER
+ db SODA_POP
+ db LEMONADE
+ db X_ATTACK
+ db X_DEFEND
+ db X_SPEED
+ db X_SPECIAL
+ db PP_UP
+ db ETHER
+ db MAX_ETHER
+ db ELIXER
+ db MAX_ELIXER
+ db $ff
+
+; items which close the item menu when used
+UsableItems_CloseMenu: ; 13459 (4:7459)
+ db ESCAPE_ROPE
+ db ITEMFINDER
+ db POKE_FLUTE
+ db OLD_ROD
+ db GOOD_ROD
+ db SUPER_ROD
+ db $ff
+
+StartMenu_TrainerInfo: ; 13460 (4:7460)
+ call GBPalWhiteOut
+ call ClearScreen
+ call UpdateSprites ; move sprites
+ ld a,[$ffd7]
+ push af
+ xor a
+ ld [$ffd7],a
+ call DrawTrainerInfo
+ ld a,$2e
+ call Predef ; draw badges
+ ld b,$0d
+ call GoPAL_SET
+ call GBPalNormal
+ call WaitForTextScrollButtonPress ; wait for button press
+ call GBPalWhiteOut
+ call LoadFontTilePatterns
+ call LoadScreenTilesFromBuffer2 ; restore saved screen
+ call GoPAL_SET_CF1C
+ call ReloadMapData
+ call LoadGBPal
+ pop af
+ ld [$ffd7],a
+ jp RedisplayStartMenu
+
+; loads tile patterns and draws everything except for gym leader faces / badges
+DrawTrainerInfo: ; 1349a (4:749a)
+ ld de,RedPicFront
+ ld bc,(BANK(RedPicFront) << 8) | $01
+ ld a,$3b
+ call Predef
+ call DisableLCD
+ FuncCoord 0,2
+ ld hl,Coord
+ ld a," "
+ call TrainerInfo_DrawVerticalLine
+ FuncCoord 1,2
+ ld hl,Coord
+ call TrainerInfo_DrawVerticalLine
+ ld hl,$9070
+ ld de,$9000
+ ld bc,$01c0
+ call CopyData
+ ld hl,TrainerInfoTextBoxTileGraphics ; $7b98 ; trainer info text box tile patterns
+ ld de,$9770
+ ld bc,$0080
+ push bc
+ call TrainerInfo_FarCopyData
+ ld hl,BlankLeaderNames ; $7c28
+ ld de,$9600
+ ld bc,$0170
+ call TrainerInfo_FarCopyData
+ pop bc
+ ld hl,BadgeNumbersTileGraphics ; $7d98 ; badge number tile patterns
+ ld de,$8d80
+ call TrainerInfo_FarCopyData
+ ld hl,GymLeaderFaceAndBadgeTileGraphics ; $6a9e ; gym leader face and badge tile patterns
+ ld de,$9200
+ ld bc,$0400
+ ld a,$03
+ call FarCopyData2
+ ld hl,TextBoxGraphics ; $6288
+ ld de,$00d0
+ add hl,de ; hl = colon tile pattern
+ ld de,$8d60
+ ld bc,$0010
+ ld a,$04
+ push bc
+ call FarCopyData2
+ pop bc
+ ld hl,TrainerInfoTextBoxTileGraphics + $80 ; $7c18 ; background tile pattern
+ ld de,$8d70
+ call TrainerInfo_FarCopyData
+ call EnableLCD
+ ld hl,$cd3d
+ ld a,18 + 1
+ ld [hli],a
+ dec a
+ ld [hli],a
+ ld [hl],1
+ FuncCoord 0,0
+ ld hl,Coord
+ call TrainerInfo_DrawTextBox
+ ld hl,$cd3d
+ ld a,16 + 1
+ ld [hli],a
+ dec a
+ ld [hli],a
+ ld [hl],3
+ FuncCoord 1,10
+ ld hl,Coord
+ call TrainerInfo_DrawTextBox
+ FuncCoord 0,10
+ ld hl,Coord
+ ld a,$d7
+ call TrainerInfo_DrawVerticalLine
+ FuncCoord 19,10
+ ld hl,Coord
+ call TrainerInfo_DrawVerticalLine
+ FuncCoord 6,9
+ ld hl,Coord
+ ld de,TrainerInfo_BadgesText
+ call PlaceString
+ FuncCoord 2,2
+ ld hl,Coord
+ ld de,TrainerInfo_NameMoneyTimeText
+ call PlaceString
+ FuncCoord 7,2
+ ld hl,Coord
+ ld de,W_PLAYERNAME
+ call PlaceString
+ FuncCoord 8,4
+ ld hl,Coord
+ ld de,wPlayerMoney
+ ld c,$e3
+ call PrintBCDNumber
+ FuncCoord 9,6
+ ld hl,Coord
+ ld de,$da41 ; hours
+ ld bc,$4103
+ call PrintNumber
+ ld [hl],$d6 ; colon tile ID
+ inc hl
+ ld de,$da43 ; minutes
+ ld bc,$8102
+ jp PrintNumber
+
+TrainerInfo_FarCopyData: ; 1357f (4:757f)
+ ld a,$0b
+ jp FarCopyData2
+
+TrainerInfo_NameMoneyTimeText: ; 13584 (4:7584)
+ db "NAME/"
+ next "MONEY/"
+ next "TIME/@"
+
+; $76 is a circle tile
+TrainerInfo_BadgesText: ; 13597 (4:7597)
+ db $76,"BADGES",$76,"@"
+
+; draws a text box on the trainer info screen
+; height is always 6
+; INPUT:
+; hl = destination address
+; [$cd3d] = width + 1
+; [$cd3e] = width
+; [$cd3f] = distance from the end of a text box row to the start of the next
+TrainerInfo_DrawTextBox: ; 135a0 (4:75a0)
+ ld a,$79 ; upper left corner tile ID
+ ld de,$7a7b ; top edge and upper right corner tile ID's
+ call TrainerInfo_DrawHorizontalEdge ; draw top edge
+ call TrainerInfo_NextTextBoxRow
+ ld a,[$cd3d] ; width of the text box plus one
+ ld e,a
+ ld d,0
+ ld c,6 ; height of the text box
+.loop
+ ld [hl],$7c ; left edge tile ID
+ add hl,de
+ ld [hl],$78 ; right edge tile ID
+ call TrainerInfo_NextTextBoxRow
+ dec c
+ jr nz,.loop
+ ld a,$7d ; lower left corner tile ID
+ ld de,$777e ; bottom edge and lower right corner tile ID's
+
+TrainerInfo_DrawHorizontalEdge: ; 135c3 (4:75c3)
+ ld [hli],a ; place left corner tile
+ ld a,[$cd3e] ; width of the text box
+ ld c,a
+ ld a,d
+.loop
+ ld [hli],a ; place edge tile
+ dec c
+ jr nz,.loop
+ ld a,e
+ ld [hl],a ; place right corner tile
+ ret
+
+TrainerInfo_NextTextBoxRow: ; 135d0 (4:75d0)
+ ld a,[$cd3f] ; distance to the start of the next row
+.loop
+ inc hl
+ dec a
+ jr nz,.loop
+ ret
+
+; draws a vertical line
+; INPUT:
+; hl = address of top tile in the line
+; a = tile ID
+TrainerInfo_DrawVerticalLine: ; 135d8 (4:75d8)
+ ld de,20
+ ld c,8
+.loop
+ ld [hl],a
+ add hl,de
+ dec c
+ jr nz,.loop
+ ret
+
+StartMenu_SaveReset: ; 135e3 (4:75e3)
+ ld a,[$d72e]
+ bit 6,a ; is the player using the link feature?
+ jp nz,InitGame
+ ld a,$3f
+ call Predef ; save the game
+ call LoadScreenTilesFromBuffer2 ; restore saved screen
+ jp HoldTextDisplayOpen
+
+StartMenu_Option: ; 135f6 (4:75f6)
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED],a
+ call ClearScreen
+ call UpdateSprites
+ callab DisplayOptionMenu
+ call LoadScreenTilesFromBuffer2 ; restore saved screen
+ call LoadTextBoxTilePatterns
+ call UpdateSprites
+ jp RedisplayStartMenu
+
+SwitchPartyMon: ; 13613 (4:7613)
+ call SwitchPartyMon_Stats
+ ld a, [wWhichTrade] ; $cd3d
+ call SwitchPartyMon_OAM
+ ld a, [wCurrentMenuItem] ; $cc26
+ call SwitchPartyMon_OAM
+ jp RedrawPartyMenu_
+
+SwitchPartyMon_OAM: ; 13625 (4:7625)
+ push af
+ ld hl, wTileMap
+ ld bc, $28
+ call AddNTimes
+ ld c, $28
+ ld a, $7f
+.asm_13633
+ ld [hli], a
+ dec c
+ jr nz, .asm_13633
+ pop af
+ ld hl, wOAMBuffer
+ ld bc, $10
+ call AddNTimes
+ ld de, $4
+ ld c, e
+.asm_13645
+ ld [hl], $a0
+ add hl, de
+ dec c
+ jr nz, .asm_13645
+ call WaitForSoundToFinish
+ ld a, (SFX_02_58 - SFX_Headers_02) / 3
+ jp PlaySound
+
+SwitchPartyMon_Stats: ; 13653 (4:7653)
+ ld a, [$cc35]
+ and a
+ jr nz, .asm_13661
+ ld a, [wWhichPokemon] ; $cf92
+ inc a
+ ld [$cc35], a
+ ret
+.asm_13661
+ xor a
+ ld [$d07d], a
+ ld a, [$cc35]
+ dec a
+ ld b, a
+ ld a, [wCurrentMenuItem] ; $cc26
+ ld [wWhichTrade], a ; $cd3d
+ cp b
+ jr nz, .asm_1367b
+ xor a
+ ld [$cc35], a
+ ld [$d07d], a
+ ret
+.asm_1367b
+ ld a, b
+ ld [$cc35], a
+ push hl
+ push de
+ ld hl, W_PARTYMON1 ; $d164
+ ld d, h
+ ld e, l
+ ld a, [wCurrentMenuItem] ; $cc26
+ add l
+ ld l, a
+ jr nc, .asm_1368e
+ inc h
+.asm_1368e
+ ld a, [$cc35]
+ add e
+ ld e, a
+ jr nc, .asm_13696
+ inc d
+.asm_13696
+ ld a, [hl]
+ ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
+ ld a, [de]
+ ld [hl], a
+ ld a, [H_DIVIDEND] ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
+ ld [de], a
+ ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
+ ld bc, $2c
+ ld a, [wCurrentMenuItem] ; $cc26
+ call AddNTimes
+ push hl
+ ld de, $cc97
+ ld bc, $2c
+ call CopyData
+ ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
+ ld bc, $2c
+ ld a, [$cc35]
+ call AddNTimes
+ pop de
+ push hl
+ ld bc, $2c
+ call CopyData
+ pop de
+ ld hl, $cc97
+ ld bc, $2c
+ call CopyData
+ ld hl, W_PARTYMON1OT ; $d273
+ ld a, [wCurrentMenuItem] ; $cc26
+ call SkipFixedLengthTextEntries
+ push hl
+ ld de, $cc97
+ ld bc, $b
+ call CopyData
+ ld hl, W_PARTYMON1OT ; $d273
+ ld a, [$cc35]
+ call SkipFixedLengthTextEntries
+ pop de
+ push hl
+ ld bc, $b
+ call CopyData
+ pop de
+ ld hl, $cc97
+ ld bc, $b
+ call CopyData
+ ld hl, W_PARTYMON1NAME ; $d2b5
+ ld a, [wCurrentMenuItem] ; $cc26
+ call SkipFixedLengthTextEntries
+ push hl
+ ld de, $cc97
+ ld bc, $b
+ call CopyData
+ ld hl, W_PARTYMON1NAME ; $d2b5
+ ld a, [$cc35]
+ call SkipFixedLengthTextEntries
+ pop de
+ push hl
+ ld bc, $b
+ call CopyData
+ pop de
+ ld hl, $cc97
+ ld bc, $b
+ call CopyData
+ ld a, [$cc35]
+ ld [wWhichTrade], a ; $cd3d
+ xor a
+ ld [$cc35], a
+ ld [$d07d], a
+ pop de
+ pop hl
+ ret
diff --git a/engine/menu/status_screen.asm b/engine/menu/status_screen.asm
new file mode 100755
index 00000000..cfce493e
--- /dev/null
+++ b/engine/menu/status_screen.asm
@@ -0,0 +1,446 @@
+; Predef 0x37
+StatusScreen: ; 12953 (4:6953)
+ call LoadMonData
+ ld a, [$cc49]
+ cp $2 ; 2 means we're in a PC box
+ jr c, .DontRecalculate ; 0x1295b $14
+ ld a, [$cf9b]
+ ld [$cfb9], a
+ ld [$d127], a
+ ld hl, $cfa8
+ ld de, $cfba
+ ld b, $1
+ call CalcStats ; Recalculate stats
+.DontRecalculate
+ ld hl, $d72c
+ set 1, [hl]
+ ld a, $33
+ ld [$ff24], a ; Reduce the volume
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ call UpdateSprites ; move sprites (?)
+ call LoadHpBarAndStatusTilePatterns
+ ld de, BattleHudTiles1 ; $6080 ; source
+ ld hl, $96d0 ; dest
+ ld bc, (BANK(BattleHudTiles1) << 8) + $03 ; bank bytes/8
+ call CopyVideoDataDouble ; ·│ :L and halfarrow line end
+ ld de, BattleHudTiles2 ; $6098
+ ld hl, $9780
+ ld bc, (BANK(BattleHudTiles2) << 8) + $01
+ call CopyVideoDataDouble ; │
+ ld de, BattleHudTiles3 ; $60b0
+ ld hl, $9760
+ ld bc, (BANK(BattleHudTiles3) << 8) + $02
+ call CopyVideoDataDouble ; ─┘
+ ld de, PTile
+ ld hl, $9720
+ ld bc,(BANK(PTile) << 8 | $01)
+ call CopyVideoDataDouble ; P (for PP), inline
+ ld a, [$ffd7]
+ push af
+ xor a
+ ld [$ffd7], a
+ FuncCoord 19,1
+ ld hl, Coord
+ ld bc, $060a
+ call DrawLineBox ; Draws the box around name, HP and status
+ ld de, $fffa
+ add hl, de
+ ld [hl], $f2 ; . after No ("." is a different one)
+ dec hl
+ ld [hl], "№"
+ FuncCoord 19,9
+ ld hl, Coord
+ ld bc, $0806
+ call DrawLineBox ; Draws the box around types, ID No. and OT
+ FuncCoord 10,9
+ ld hl, Coord
+ ld de, Type1Text
+ call PlaceString ; "TYPE1/"
+ FuncCoord 11,3
+ ld hl, Coord
+ PREDEF DrawHPBarPredef ; predef $5f
+ ld hl, $cf25
+ call GetHealthBarColor
+ ld b, $3
+ call GoPAL_SET ; SGB palette
+ FuncCoord 16,6
+ ld hl, Coord
+ ld de, $cf9c
+ call PrintStatusCondition
+ jr nz, .StatusWritten ; 0x129fc $9
+ FuncCoord 16,6
+ ld hl, Coord
+ ld de, OKText
+ call PlaceString ; "OK"
+.StatusWritten
+ FuncCoord 9,6
+ ld hl, Coord
+ ld de, StatusText
+ call PlaceString ; "STATUS/"
+ FuncCoord 14,2
+ ld hl, Coord
+ call PrintLevel ; Pokémon level
+ ld a, [$d0b8]
+ ld [$d11e], a
+ ld [$d0b5], a
+ ld a, $3a
+ call Predef
+ FuncCoord 3,7
+ ld hl, Coord
+ ld de, $d11e
+ ld bc, $8103 ; Zero-padded, 3
+ call PrintNumber ; Pokémon no.
+ FuncCoord 11,10
+ ld hl, Coord
+ ld a, $4b
+ call Predef ; Prints the type (?)
+ ld hl, NamePointers2 ; $6a9d
+ call .unk_12a7e
+ ld d, h
+ ld e, l
+ FuncCoord 9,1
+ ld hl, Coord
+ call PlaceString ; Pokémon name
+ ld hl, OTPointers ; $6a95
+ call .unk_12a7e
+ ld d, h
+ ld e, l
+ FuncCoord 12,16
+ ld hl, Coord
+ call PlaceString ; OT
+ FuncCoord 12,14
+ ld hl, Coord
+ ld de, $cfa4
+ ld bc, $8205 ; 5
+ call PrintNumber ; ID Number
+ ld d, $0
+ call PrintStatsBox
+ call Delay3
+ call GBPalNormal
+ FuncCoord 1, 0 ; $c3a1
+ ld hl, Coord
+ call LoadFlippedFrontSpriteByMonIndex ; draw Pokémon picture
+ ld a, [$cf91]
+ call PlayCry ; play Pokémon cry
+ call WaitForTextScrollButtonPress ; wait for button
+ pop af
+ ld [$ffd7], a
+ ret
+.unk_12a7e ; 0x12a7e ; I don't know what this does, iterates over pointers?
+ ld a, [$cc49]
+ add a
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [$cc49]
+ cp $3
+ ret z
+ ld a, [wWhichPokemon]
+ jp SkipFixedLengthTextEntries
+
+OTPointers: ; 12a95 (4:6a95)
+ dw W_PARTYMON1OT
+ dw W_ENEMYMON1OT
+ dw W_BOXMON1OT
+ dw W_DAYCAREMONOT
+
+NamePointers2: ; 12a9d (4:6a9d)
+ dw W_PARTYMON1NAME
+ dw W_ENEMYMON1NAME
+ dw W_BOXMON1NAME
+ dw W_DAYCAREMONNAME
+
+Type1Text: ; 12aa5 (4:6aa5)
+ db "TYPE1/", $4e
+
+Type2Text: ; 12aac (4:6aac)
+ db "TYPE2/", $4e
+
+IDNoText: ; 12ab3 (4:6ab3)
+ db $73, "№", "/", $4e
+
+OTText: ; 12ab7 (4:6ab7)
+ db "OT/", $4e, "@"
+
+StatusText: ; 12abc (4:6abc)
+ db "STATUS/@"
+
+OKText: ; 12ac4 (4:6ac4)
+ db "OK@"
+
+; Draws a line starting from hl high b and wide c
+DrawLineBox ; 0x12ac7
+ ld de, $0014 ; New line
+.PrintVerticalLine
+ ld [hl], $78 ; │
+ add hl, de
+ dec b
+ jr nz, .PrintVerticalLine ; 0x12ace $fa
+ ld [hl], $77 ; ┘
+ dec hl
+.PrintHorizLine
+ ld [hl], $76 ; ─
+ dec hl
+ dec c
+ jr nz, .PrintHorizLine ; 0x12ad7 $fa
+ ld [hl], $6f ; ← (halfarrow ending)
+ ret
+
+PTile: ; 12adc (4:6adc) ; This is a single 1bpp "P" tile
+ INCBIN "gfx/p_tile.1bpp"
+
+PrintStatsBox: ; 12ae4 (4:6ae4)
+ ld a, d
+ and a ; a is 0 from the status screen
+ jr nz, .DifferentBox ; 0x12ae6 $12
+ FuncCoord 0,8
+ ld hl, Coord
+ ld b, $8
+ ld c, $8
+ call TextBoxBorder ; Draws the box
+ FuncCoord 1,9 ; Start printing stats from here
+ ld hl, Coord
+ ld bc, $0019 ; Number offset
+ jr .PrintStats ; 0x12af8 $10
+.DifferentBox
+ FuncCoord 9,2
+ ld hl, Coord
+ ld b, $8
+ ld c, $9
+ call TextBoxBorder
+ FuncCoord 11, 3 ; $c3e7
+ ld hl, Coord
+ ld bc, $0018
+.PrintStats
+ push bc
+ push hl
+ ld de, StatsText
+ call PlaceString
+ pop hl
+ pop bc
+ add hl, bc
+ ld de, $cfbc
+ ld bc, $0203 ; three digits
+ call PrintStat
+ ld de, $cfbe
+ call PrintStat
+ ld de, $cfc0
+ call PrintStat
+ ld de, $cfc2
+ jp PrintNumber
+PrintStat
+ push hl
+ call PrintNumber
+ pop hl
+ ld de, $0028
+ add hl, de
+ ret
+
+StatsText: ; 12b3a (4:6b3a)
+ db "ATTACK"
+ next "DEFENSE"
+ next "SPEED"
+ next "SPECIAL@"
+
+StatusScreen2: ; 12b57 (4:6b57)
+ ld a, [$ffd7]
+ push af
+ xor a
+ ld [$ffd7], a
+ ld [$ffba], a
+ ld bc, $0005
+ ld hl, $d0dc
+ call FillMemory
+ ld hl, $cfa0
+ ld de, $d0dc
+ ld bc, $0004
+ call CopyData
+ callab Func_39b87
+ FuncCoord 9,2
+ ld hl, Coord
+ ld bc, $050a
+ call ClearScreenArea ; Clear under name
+ FuncCoord 19, 3 ; $c3ef
+ ld hl, Coord
+ ld [hl], $78
+ FuncCoord 0,8
+ ld hl, Coord
+ ld b, $8
+ ld c, $12
+ call TextBoxBorder ; Draw move container
+ FuncCoord 2,9
+ ld hl, Coord
+ ld de, $d0e1
+ call PlaceString ; Print moves
+ ld a, [$cd6c]
+ inc a
+ ld c, a
+ ld a, $4
+ sub c
+ ld b, a ; Number of moves ?
+ FuncCoord 11,10
+ ld hl, Coord
+ ld de, $0028
+ ld a, $72
+ call Func_12ccb ; Print "PP"
+ ld a, b
+ and a
+ jr z, .InitPP ; 0x12bb3 $6
+ ld c, a
+ ld a, "-"
+ call Func_12ccb ; Fill the rest with --
+.InitPP ; 12bbb
+ ld hl, $cfa0
+ FuncCoord 14,10
+ ld de, Coord
+ ld b, $0
+.PrintPP ; 12bc3
+ ld a, [hli]
+ and a
+ jr z, .PPDone ; 0x12bc5 $4a
+ push bc
+ push hl
+ push de
+ ld hl, wCurrentMenuItem
+ ld a, [hl]
+ push af
+ ld a, b
+ ld [hl], a
+ push hl
+ callab GetMaxPP
+ pop hl
+ pop af
+ ld [hl], a
+ pop de
+ pop hl
+ push hl
+ ld bc, $0014
+ add hl, bc
+ ld a, [hl]
+ and $3f
+ ld [$cd71], a
+ ld h, d
+ ld l, e
+ push hl
+ ld de, $cd71
+ ld bc, $0102
+ call PrintNumber
+ ld a, "/"
+ ld [hli], a
+ ld de, $d11e
+ ld bc, $0102
+ call PrintNumber
+ pop hl
+ ld de, $0028
+ add hl, de
+ ld d, h
+ ld e, l
+ pop hl
+ pop bc
+ inc b
+ ld a, b
+ cp $4
+ jr nz, .PrintPP ; 0x12c0f $b2
+.PPDone
+ FuncCoord 9,3
+ ld hl, Coord
+ ld de, EXPPointsText
+ call PlaceString
+ ld a, [$cfb9] ; level
+ push af
+ cp 100
+ jr z, .Level100 ; 0x12c20 $4
+ inc a
+ ld [$cfb9], a ; Increase temporarily if not 100
+.Level100
+ FuncCoord 14,6
+ ld hl, Coord
+ ld [hl], $70 ; 1-tile "to"
+ inc hl
+ inc hl
+ call PrintLevel
+ pop af
+ ld [$cfb9], a
+ ld de, $cfa6
+ FuncCoord 12,4
+ ld hl, Coord
+ ld bc, $0307
+ call PrintNumber ; exp
+ call .asm_12c86
+ ld de, $cfa6
+ FuncCoord 7,6
+ ld hl, Coord
+ ld bc, $0307
+ call PrintNumber
+ FuncCoord 9,0
+ ld hl, Coord
+ call Func_12cc3
+ FuncCoord 9,1
+ ld hl, Coord
+ call Func_12cc3
+ ld a, [$d0b8]
+ ld [$d11e], a
+ call GetMonName
+ FuncCoord 9,1
+ ld hl, Coord
+ call PlaceString
+ ld a, $1
+ ld [$ffba], a
+ call Delay3
+ call WaitForTextScrollButtonPress ; wait for button
+ pop af
+ ld [$ffd7], a
+ ld hl, $d72c
+ res 1, [hl]
+ ld a, $77
+ ld [$ff24], a
+ call GBPalWhiteOut
+ jp ClearScreen
+.asm_12c86 ; This does some magic with lvl/exp?
+ ld a, [$cfb9] ; Load level
+ cp $64
+ jr z, .asm_12ca7 ; 0x12c8b $1a ; If 100
+ inc a
+ ld d, a
+ callab CalcExperience
+ ld hl, $cfa8
+ ld a, [$ff98]
+ sub [hl]
+ ld [hld], a
+ ld a, [$ff97]
+ sbc [hl]
+ ld [hld], a
+ ld a, [$ff96]
+ sbc [hl]
+ ld [hld], a
+ ret
+.asm_12ca7
+ ld hl, $cfa6
+ xor a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ret
+
+EXPPointsText: ; 12caf (4:6caf)
+ db "EXP POINTS", $4e
+
+LevelUpText: ; 12cba (4:6cba)
+ db "LEVEL UP@"
+
+Func_12cc3: ; 12cc3 (4:6cc3)
+ ld bc, $a
+ ld a, $7f
+ jp FillMemory
+
+Func_12ccb: ; 12ccb (4:6ccb)
+ ld [hli], a
+ ld [hld], a
+ add hl, de
+ dec c
+ jr nz, Func_12ccb
+ ret
diff --git a/engine/menu/vending_machine.asm b/engine/menu/vending_machine.asm
new file mode 100755
index 00000000..1f0ed084
--- /dev/null
+++ b/engine/menu/vending_machine.asm
@@ -0,0 +1,138 @@
+VendingMachineMenu: ; 74ee0 (1d:4ee0)
+ ld hl, VendingMachineText1
+ call PrintText
+ ld a, $13
+ ld [$d125], a
+ call DisplayTextBoxID
+ xor a
+ ld [wCurrentMenuItem], a ; $cc26
+ ld [wLastMenuItem], a ; $cc2a
+ ld a, $3
+ ld [wMenuWatchedKeys], a ; $cc29
+ ld a, $3
+ ld [wMaxMenuItem], a ; $cc28
+ ld a, $5
+ ld [wTopMenuItemY], a ; $cc24
+ ld a, $1
+ ld [wTopMenuItemX], a ; $cc25
+ ld hl, $d730
+ set 6, [hl]
+ FuncCoord 0, 3 ; $c3dc
+ ld hl, Coord
+ ld b, $8
+ ld c, $c
+ call TextBoxBorder
+ call UpdateSprites
+ FuncCoord 2, 5 ; $c406
+ ld hl, Coord
+ ld de, DrinkText
+ call PlaceString
+ FuncCoord 9, 6 ; $c421
+ ld hl, Coord
+ ld de, DrinkPriceText
+ call PlaceString
+ ld hl, $d730
+ res 6, [hl]
+ call HandleMenuInput
+ bit 1, a
+ jr nz, .asm_74f93
+ ld a, [wCurrentMenuItem] ; $cc26
+ cp $3
+ jr z, .asm_74f93
+ xor a
+ ld [$ff9f], a
+ ld [$ffa1], a
+ ld a, $2
+ ld [$ffa0], a
+ call HasEnoughMoney
+ jr nc, .enoughMoney
+ ld hl, VendingMachineText4
+ jp PrintText
+.enoughMoney
+ call Func_74fe7
+ ld a, [$ffdb]
+ ld b, a
+ ld c, 1
+ call GiveItem
+ jr nc, .BagFull
+ ld b, $3c ; number of times to play the "brrrrr" sound
+.playDeliverySound ; 0x74f63
+ ld c, $2
+ call DelayFrames
+ push bc
+ ld a, (SFX_02_53 - SFX_Headers_02) / 3
+ call PlaySound
+ pop bc
+ dec b
+ jr nz, .playDeliverySound
+.asm_74f72
+ ld hl, VendingMachineText5
+ call PrintText
+ ld hl, $ffde
+ ld de, wPlayerMoney + 2 ; $d349
+ ld c, $3
+ ld a, $c
+ call Predef ; indirect jump to Func_f836 (f836 (3:7836))
+ ld a, $13
+ ld [$d125], a
+ jp DisplayTextBoxID
+.BagFull
+ ld hl, VendingMachineText6
+ jp PrintText
+.asm_74f93
+ ld hl, VendingMachineText7
+ jp PrintText
+
+VendingMachineText1: ; 74f99 (1d:4f99)
+ TX_FAR _VendingMachineText1
+ db "@"
+
+DrinkText: ; 74f9e (1d:4f9e)
+ db "FRESH WATER"
+ next "SODA POP"
+ next "LEMONADE"
+ next "CANCEL@"
+
+DrinkPriceText: ; 74fc3 (1d:4fc3)
+ db "¥200"
+ next "¥300"
+ next "¥350",$4E,"@"
+
+VendingMachineText4: ; 74fd3 (1d:4fd3)
+ TX_FAR _VendingMachineText4
+ db "@"
+
+VendingMachineText5: ; 74fd8 (1d:4fd8)
+ TX_FAR _VendingMachineText5
+ db "@"
+
+VendingMachineText6: ; 74fdd (1d:4fdd)
+ TX_FAR _VendingMachineText6
+ db "@"
+
+VendingMachineText7: ; 74fe2 (1d:4fe2)
+ TX_FAR _VendingMachineText7
+ db "@"
+
+Func_74fe7: ; 74fe7 (1d:4fe7)
+ ld hl, VendingPrices
+ ld a, [$cc26]
+ add a
+ add a
+ ld d, $0
+ ld e, a
+ add hl, de
+ ld a, [hli]
+ ld [$ffdb], a
+ ld a, [hli]
+ ld [$ffdc], a
+ ld a, [hli]
+ ld [$ffdd], a
+ ld a, [hl]
+ ld [$ffde], a
+ ret
+
+VendingPrices: ; 75000 (1d:5000)
+ db FRESH_WATER,$00,$02,$00
+ db SODA_POP, $00,$03,$00
+ db LEMONADE, $00,$03,$50