summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorentrpntr <entrpntr@gmail.com>2020-04-29 18:39:24 -0400
committerentrpntr <entrpntr@gmail.com>2020-04-29 18:48:23 -0400
commita308a1adadc1f782577c23ca62c0b3abd715b0ce (patch)
treee0eb39bcc341ccc3e33c98cc3aec61c50b752061
parent70d3a3fdbc508eeb4557ddc43d78ba12ed41963e (diff)
Add bank 9 files before trainer card.
-rw-r--r--data/items/apricorn_balls.asm10
-rw-r--r--data/mon_menu.asm46
-rw-r--r--data/text/common_2.asm2
-rw-r--r--data/text_buffers.asm9
-rw-r--r--engine/battle/menu.asm94
-rw-r--r--engine/events/pokepic.asm48
-rwxr-xr-xengine/events/specials.asm4
-rw-r--r--engine/items/buy_sell_toss.asm218
-rw-r--r--engine/items/switch_items.asm272
-rw-r--r--engine/items/update_item_description.asm13
-rw-r--r--engine/menus/menu.asm676
-rw-r--r--engine/menus/menu_2.asm298
-rw-r--r--engine/menus/naming_screen.asm4
-rw-r--r--engine/menus/scrolling_menu.asm519
-rw-r--r--engine/overworld/map_objects_2.asm70
-rw-r--r--engine/pokemon/mon_submenu.asm290
-rw-r--r--gfx/overworld/heal_machine.pngbin137 -> 137 bytes
-rw-r--r--home/menu.asm2
-rw-r--r--main.asm80
-rw-r--r--wram.asm67
20 files changed, 2623 insertions, 99 deletions
diff --git a/data/items/apricorn_balls.asm b/data/items/apricorn_balls.asm
new file mode 100644
index 00000000..814aeab2
--- /dev/null
+++ b/data/items/apricorn_balls.asm
@@ -0,0 +1,10 @@
+ApricornBalls:
+ ; apricorn, ball
+ db RED_APRICORN, LEVEL_BALL
+ db BLU_APRICORN, LURE_BALL
+ db YLW_APRICORN, MOON_BALL
+ db GRN_APRICORN, FRIEND_BALL
+ db WHT_APRICORN, FAST_BALL
+ db BLK_APRICORN, HEAVY_BALL
+ db PNK_APRICORN, LOVE_BALL
+ db -1
diff --git a/data/mon_menu.asm b/data/mon_menu.asm
new file mode 100644
index 00000000..f2b9f3ac
--- /dev/null
+++ b/data/mon_menu.asm
@@ -0,0 +1,46 @@
+; MonMenuOptionStrings indexes
+ const_def 1
+ const MONMENUVALUE_STATS ; 1
+ const MONMENUVALUE_SWITCH ; 2
+ const MONMENUVALUE_ITEM ; 3
+ const MONMENUVALUE_CANCEL ; 4
+ const MONMENUVALUE_MOVE ; 5
+ const MONMENUVALUE_MAIL ; 6
+ const MONMENUVALUE_ERROR ; 7
+
+MonMenuOptionStrings:
+; entries correspond to MONMENUVALUE_* constants
+ db "STATS@"
+ db "SWITCH@"
+ db "ITEM@"
+ db "CANCEL@"
+ db "MOVE@"
+ db "MAIL@"
+ db "ERROR!@"
+
+MonMenuOptions:
+; category, item, value; actions are in PokemonActionSubmenu (see engine/pokemon/mon_menu.asm)
+; moves
+ db MONMENU_FIELD_MOVE, MONMENUITEM_CUT, CUT
+ db MONMENU_FIELD_MOVE, MONMENUITEM_FLY, FLY
+ db MONMENU_FIELD_MOVE, MONMENUITEM_SURF, SURF
+ db MONMENU_FIELD_MOVE, MONMENUITEM_STRENGTH, STRENGTH
+ db MONMENU_FIELD_MOVE, MONMENUITEM_FLASH, FLASH
+ db MONMENU_FIELD_MOVE, MONMENUITEM_WATERFALL, WATERFALL
+ db MONMENU_FIELD_MOVE, MONMENUITEM_WHIRLPOOL, WHIRLPOOL
+ db MONMENU_FIELD_MOVE, MONMENUITEM_DIG, DIG
+ db MONMENU_FIELD_MOVE, MONMENUITEM_TELEPORT, TELEPORT
+ db MONMENU_FIELD_MOVE, MONMENUITEM_SOFTBOILED, SOFTBOILED
+ db MONMENU_FIELD_MOVE, MONMENUITEM_HEADBUTT, HEADBUTT
+ db MONMENU_FIELD_MOVE, MONMENUITEM_ROCKSMASH, ROCK_SMASH
+ db MONMENU_FIELD_MOVE, MONMENUITEM_MILKDRINK, MILK_DRINK
+ db MONMENU_FIELD_MOVE, MONMENUITEM_SWEETSCENT, SWEET_SCENT
+; options
+ db MONMENU_MENUOPTION, MONMENUITEM_STATS, MONMENUVALUE_STATS
+ db MONMENU_MENUOPTION, MONMENUITEM_SWITCH, MONMENUVALUE_SWITCH
+ db MONMENU_MENUOPTION, MONMENUITEM_ITEM, MONMENUVALUE_ITEM
+ db MONMENU_MENUOPTION, MONMENUITEM_CANCEL, MONMENUVALUE_CANCEL
+ db MONMENU_MENUOPTION, MONMENUITEM_MOVE, MONMENUVALUE_MOVE
+ db MONMENU_MENUOPTION, MONMENUITEM_MAIL, MONMENUVALUE_MAIL
+ db MONMENU_MENUOPTION, MONMENUITEM_ERROR, MONMENUVALUE_ERROR
+ db -1
diff --git a/data/text/common_2.asm b/data/text/common_2.asm
index 05ee596f..d61544e2 100644
--- a/data/text/common_2.asm
+++ b/data/text/common_2.asm
@@ -1310,7 +1310,7 @@ UnknownText_0x1c4693::
line "area was exceeded."
done
-UnknownText_0x1c46b7::
+_WindowPoppingErrorText::
text "No windows avail-"
line "able for popping."
done
diff --git a/data/text_buffers.asm b/data/text_buffers.asm
new file mode 100644
index 00000000..7c28c11e
--- /dev/null
+++ b/data/text_buffers.asm
@@ -0,0 +1,9 @@
+StringBufferPointers::
+; entries correspond to arguments for text_buffer (TX_STRINGBUFFER)
+ dw wStringBuffer3 ; 0
+ dw wStringBuffer4 ; 1
+ dw wStringBuffer5 ; 2
+ dw wStringBuffer2 ; 3
+ dw wStringBuffer1 ; 4
+ dw wEnemyMonNick ; 5
+ dw wBattleMonNick ; 6
diff --git a/engine/battle/menu.asm b/engine/battle/menu.asm
new file mode 100644
index 00000000..f75d4114
--- /dev/null
+++ b/engine/battle/menu.asm
@@ -0,0 +1,94 @@
+LoadBattleMenu:
+ ld hl, BattleMenuHeader
+ call LoadMenuHeader
+ jr Function24e78
+
+SafariBattleMenu:
+ ; untranslated
+ ld hl, MenuHeader_0x24eae
+ call LoadMenuHeader
+ jr Function24e78
+
+ContestBattleMenu:
+ ld hl, MenuHeader_0x24ee9
+ call LoadMenuHeader
+; fallthrough
+Function24e78:
+ ld a, [wBattleMenuCursorBuffer]
+ ld [wMenuCursorBuffer], a
+ call _2DMenu
+ ld a, [wMenuCursorBuffer]
+ ld [wBattleMenuCursorBuffer], a
+ call ExitMenu
+ ret
+
+BattleMenuHeader:
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 8, 12, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
+ dw MenuData_0x24e93
+ db 1 ; default option
+
+MenuData_0x24e93:
+ db STATICMENU_CURSOR | STATICMENU_DISABLE_B ; flags
+ dn 2, 2 ; rows, columns
+ db 6 ; spacing
+ dba Strings24e9c
+ dbw BANK(MenuData_0x24e93), 0
+
+Strings24e9c:
+ db "FIGHT@"
+ db "<PK><MN>@"
+ db "PACK@"
+ db "RUN@"
+
+MenuHeader_0x24eae:
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 0, 12, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
+ dw MenuData_0x24eb6
+ db 1 ; default option
+
+MenuData_0x24eb6:
+ db STATICMENU_CURSOR | STATICMENU_DISABLE_B ; flags
+ dn 2, 2 ; rows, columns
+ db 11 ; spacing
+ dba Strings24ebf
+ dba Function24edc
+
+Strings24ebf:
+ db "サファりボール×  @" ; "SAFARI BALL× @"
+ db "エサをなげる@" ; "THROW BAIT"
+ db "いしをなげる@" ; "THROW ROCK"
+ db "にげる@" ; "RUN"
+
+Function24edc:
+ hlcoord 17, 13
+ ld de, wSafariBallsRemaining
+ lb bc, PRINTNUM_LEADINGZEROS | 1, 2
+ call PrintNum
+ ret
+
+MenuHeader_0x24ee9:
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 2, 12, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
+ dw MenuData_0x24ef1
+ db 1 ; default option
+
+MenuData_0x24ef1:
+ db STATICMENU_CURSOR | STATICMENU_DISABLE_B ; flags
+ dn 2, 2 ; rows, columns
+ db 12 ; spacing
+ dba Strings24efa
+ dba Strings24f13
+
+Strings24efa:
+ db "FIGHT@"
+ db "<PK><MN>@"
+ db "PARKBALL× @"
+ db "RUN@"
+
+Strings24f13:
+ hlcoord 13, 16
+ ld de, wParkBallsRemaining
+ lb bc, PRINTNUM_LEADINGZEROS | 1, 2
+ call PrintNum
+ ret
diff --git a/engine/events/pokepic.asm b/engine/events/pokepic.asm
new file mode 100644
index 00000000..523c5df5
--- /dev/null
+++ b/engine/events/pokepic.asm
@@ -0,0 +1,48 @@
+Pokepic::
+ ld hl, PokepicMenuHeader
+ call CopyMenuHeader
+ call MenuBox
+ call UpdateSprites
+ call ApplyTilemap
+ ld b, SCGB_POKEPIC
+ call GetSGBLayout
+ xor a
+ ldh [hBGMapMode], a
+ ld a, [wCurPartySpecies]
+ ld [wCurSpecies], a
+ call GetBaseData
+ ld de, vTiles1
+ predef GetMonFrontpic
+ ld a, [wMenuBorderTopCoord]
+ inc a
+ ld b, a
+ ld a, [wMenuBorderLeftCoord]
+ inc a
+ ld c, a
+ call Coord2Tile
+ ld a, $80
+ ldh [hGraphicStartTile], a
+ lb bc, 7, 7
+ predef PlaceGraphic
+ call WaitBGMap
+ ret
+
+ClosePokepic::
+ ld hl, PokepicMenuHeader
+ call CopyMenuHeader
+ call ClearMenuBoxInterior
+ call WaitBGMap
+ call GetMemSGBLayout
+ xor a
+ ldh [hBGMapMode], a
+ call OverworldTextModeSwitch
+ call ApplyTilemap
+ call UpdateSprites
+ call LoadStandardFont
+ ret
+
+PokepicMenuHeader:
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 6, 4, 14, 13
+ dw NULL
+ db 1 ; default option
diff --git a/engine/events/specials.asm b/engine/events/specials.asm
index 1086861a..8e93a048 100755
--- a/engine/events/specials.asm
+++ b/engine/events/specials.asm
@@ -470,8 +470,8 @@ CountUnown: ; c5ac (3:45ac)
jr c, .asm_c5b1
ret
-SelectApricornForKurt: ; c5bb (3:45bb)
- farcall Function24b8d
+SelectApricornForKurt:
+ farcall Kurt_SelectApricorn
ld a, c
ld [wScriptVar], a
and a
diff --git a/engine/items/buy_sell_toss.asm b/engine/items/buy_sell_toss.asm
new file mode 100644
index 00000000..45c3dfcf
--- /dev/null
+++ b/engine/items/buy_sell_toss.asm
@@ -0,0 +1,218 @@
+SelectQuantityToToss:
+ ld hl, TossItem_MenuHeader
+ call LoadMenuHeader
+ call Toss_Sell_Loop
+ ret
+
+SelectQuantityToBuy:
+ farcall GetItemPrice
+ ld a, d
+ ld [wBuffer1], a
+ ld a, e
+ ld [wBuffer2], a
+ ld hl, BuyItem_MenuHeader
+ call LoadMenuHeader
+ call Toss_Sell_Loop
+ ret
+
+SelectQuantityToSell:
+ farcall GetItemPrice
+ ld a, d
+ ld [wBuffer1], a
+ ld a, e
+ ld [wBuffer2], a
+ ld hl, SellItem_MenuHeader
+ call LoadMenuHeader
+ call Toss_Sell_Loop
+ ret
+
+Toss_Sell_Loop:
+ ld a, 1
+ ld [wItemQuantityChangeBuffer], a
+.loop
+ call BuySellToss_UpdateQuantityDisplay ; update display
+ call BuySellToss_InterpretJoypad ; joy action
+ jr nc, .loop
+ cp -1
+ jr nz, .nope ; pressed B
+ scf
+ ret
+
+.nope
+ and a
+ ret
+
+BuySellToss_InterpretJoypad:
+ call JoyTextDelay_ForcehJoyDown ; get joypad
+ bit B_BUTTON_F, c
+ jr nz, .b
+ bit A_BUTTON_F, c
+ jr nz, .a
+ bit D_DOWN_F, c
+ jr nz, .down
+ bit D_UP_F, c
+ jr nz, .up
+ bit D_LEFT_F, c
+ jr nz, .left
+ bit D_RIGHT_F, c
+ jr nz, .right
+ and a
+ ret
+
+.b
+ ld a, -1
+ scf
+ ret
+
+.a
+ ld a, 0
+ scf
+ ret
+
+.down
+ ld hl, wItemQuantityChangeBuffer
+ dec [hl]
+ jr nz, .finish_down
+ ld a, [wItemQuantityBuffer]
+ ld [hl], a
+
+.finish_down
+ and a
+ ret
+
+.up
+ ld hl, wItemQuantityChangeBuffer
+ inc [hl]
+ ld a, [wItemQuantityBuffer]
+ cp [hl]
+ jr nc, .finish_up
+ ld [hl], 1
+
+.finish_up
+ and a
+ ret
+
+.left
+ ld a, [wItemQuantityChangeBuffer]
+ sub 10
+ jr c, .load_1
+ jr z, .load_1
+ jr .finish_left
+
+.load_1
+ ld a, 1
+
+.finish_left
+ ld [wItemQuantityChangeBuffer], a
+ and a
+ ret
+
+.right
+ ld a, [wItemQuantityChangeBuffer]
+ add 10
+ ld b, a
+ ld a, [wItemQuantityBuffer]
+ cp b
+ jr nc, .finish_right
+ ld b, a
+
+.finish_right
+ ld a, b
+ ld [wItemQuantityChangeBuffer], a
+ and a
+ ret
+
+BuySellToss_UpdateQuantityDisplay:
+ call MenuBox
+ call MenuBoxCoord2Tile
+ ld de, SCREEN_WIDTH + 1
+ add hl, de
+ ld [hl], "×"
+ inc hl
+ ld de, wItemQuantityChangeBuffer
+ lb bc, PRINTNUM_LEADINGZEROS | 1, 2
+ call PrintNum
+ ld a, [wMenuDataPointer]
+ ld e, a
+ ld a, [wMenuDataPointer + 1]
+ ld d, a
+ push de
+ ret
+
+ret_24ff3:
+ ret
+
+DisplayPurchasePrice:
+ call BuySell_MultiplyPrice
+ call BuySell_DisplaySubtotal
+ ret
+
+DisplaySellingPrice:
+ call BuySell_MultiplyPrice
+ call Sell_HalvePrice
+ call BuySell_DisplaySubtotal
+ ret
+
+BuySell_MultiplyPrice:
+ xor a
+ ldh [hMultiplicand + 0], a
+ ld a, [wBuffer1]
+ ldh [hMultiplicand + 1], a
+ ld a, [wBuffer2]
+ ldh [hMultiplicand + 2], a
+ ld a, [wItemQuantityChangeBuffer]
+ ldh [hMultiplier], a
+ push hl
+ call Multiply
+ pop hl
+ ret
+
+Sell_HalvePrice:
+ push hl
+ ld hl, hProduct + 1
+ ld a, [hl]
+ srl a
+ ld [hli], a
+ ld a, [hl]
+ rra
+ ld [hli], a
+ ld a, [hl]
+ rra
+ ld [hl], a
+ pop hl
+ ret
+
+BuySell_DisplaySubtotal:
+ push hl
+ ld hl, hMoneyTemp
+ ldh a, [hProduct + 1]
+ ld [hli], a
+ ldh a, [hProduct + 2]
+ ld [hli], a
+ ldh a, [hProduct + 3]
+ ld [hl], a
+ pop hl
+ inc hl
+ ld de, hMoneyTemp
+ lb bc, PRINTNUM_MONEY | 3, 6
+ call PrintNum
+ call WaitBGMap
+ ret
+
+TossItem_MenuHeader:
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 15, 9, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw ret_24ff3
+ db 0 ; default option
+
+BuyItem_MenuHeader:
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 7, 15, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
+ dw DisplayPurchasePrice
+ db -1 ; default option
+
+SellItem_MenuHeader:
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 7, 15, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
+ dw DisplaySellingPrice
+ db 0 ; default option
diff --git a/engine/items/switch_items.asm b/engine/items/switch_items.asm
new file mode 100644
index 00000000..283823e4
--- /dev/null
+++ b/engine/items/switch_items.asm
@@ -0,0 +1,272 @@
+SwitchItemsInBag:
+ ld a, [wSwitchItem]
+ and a
+ jr z, .init
+ ld b, a
+ ld a, [wScrollingMenuCursorPosition]
+ inc a
+ cp b
+ jr z, .trivial
+ ld a, [wScrollingMenuCursorPosition]
+ call ItemSwitch_GetNthItem
+ ld a, [hl]
+ cp -1
+ ret z
+ ld a, [wSwitchItem]
+ dec a
+ ld [wSwitchItem], a
+ call Function248cf
+ jp c, Function248f9
+ ld a, [wScrollingMenuCursorPosition]
+ ld c, a
+ ld a, [wSwitchItem]
+ cp c
+ jr c, .asm_248a2
+ jr .asm_24872
+
+.init
+ ld a, [wScrollingMenuCursorPosition]
+ inc a
+ ld [wSwitchItem], a
+ ret
+
+.trivial
+ xor a
+ ld [wSwitchItem], a
+ ret
+
+.asm_24872
+ ld a, [wSwitchItem]
+ call Function24968
+ ld a, [wScrollingMenuCursorPosition]
+ ld d, a
+ ld a, [wSwitchItem]
+ ld e, a
+ call Function24994
+ push bc
+ ld a, [wSwitchItem]
+ call ItemSwitch_GetNthItem
+ dec hl
+ push hl
+ call ItemSwitch_ConvertItemFormatToDW
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ pop bc
+ call Function249d3
+ ld a, [wScrollingMenuCursorPosition]
+ call Function24975
+ xor a
+ ld [wSwitchItem], a
+ ret
+
+.asm_248a2
+ ld a, [wSwitchItem]
+ call Function24968
+ ld a, [wScrollingMenuCursorPosition]
+ ld d, a
+ ld a, [wSwitchItem]
+ ld e, a
+ call Function24994
+ push bc
+ ld a, [wSwitchItem]
+ call ItemSwitch_GetNthItem
+ ld d, h
+ ld e, l
+ call ItemSwitch_ConvertItemFormatToDW
+ add hl, bc
+ pop bc
+ call CopyBytes
+ ld a, [wScrollingMenuCursorPosition]
+ call Function24975
+ xor a
+ ld [wSwitchItem], a
+ ret
+
+Function248cf:
+ ld a, [wSwitchItem]
+ call ItemSwitch_GetNthItem
+ ld d, h
+ ld e, l
+ ld a, [wScrollingMenuCursorPosition]
+ call ItemSwitch_GetNthItem
+ ld a, [de]
+ cp [hl]
+ jr nz, .asm_249cd
+ ld a, [wScrollingMenuCursorPosition]
+ call Function249bf
+ cp 99
+ jr z, .asm_249cd
+ ld a, [wSwitchItem]
+ call Function249bf
+ cp 99
+ jr nz, .asm_249cf
+.asm_249cd
+ and a
+ ret
+
+.asm_249cf
+ scf
+ ret
+
+Function248f9:
+ ld a, [wSwitchItem]
+ call ItemSwitch_GetNthItem
+ inc hl
+ push hl
+ ld a, [wScrollingMenuCursorPosition]
+ call ItemSwitch_GetNthItem
+ inc hl
+ ld a, [hl]
+ pop hl
+ add [hl]
+ cp 100
+ jr c, .asm_24a01
+ sub 99
+ push af
+ ld a, [wScrollingMenuCursorPosition]
+ call ItemSwitch_GetNthItem
+ inc hl
+ ld [hl], 99
+ ld a, [wSwitchItem]
+ call ItemSwitch_GetNthItem
+ inc hl
+ pop af
+ ld [hl], a
+ xor a
+ ld [wSwitchItem], a
+ ret
+
+.asm_24a01
+ push af
+ ld a, [wScrollingMenuCursorPosition]
+ call ItemSwitch_GetNthItem
+ inc hl
+ pop af
+ ld [hl], a
+ ld hl, wMenuData_ItemsPointerAddr
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wSwitchItem]
+ cp [hl]
+ jr nz, .asm_24a25
+ dec [hl]
+ ld a, [wSwitchItem]
+ call ItemSwitch_GetNthItem
+ ld [hl], $ff
+ xor a
+ ld [wSwitchItem], a
+ ret
+
+.asm_24a25
+ dec [hl]
+ call ItemSwitch_ConvertItemFormatToDW
+ push bc
+ ld a, [wSwitchItem]
+ call ItemSwitch_GetNthItem
+ pop bc
+ push hl
+ add hl, bc
+ pop de
+.asm_24a34
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp $ff
+ jr nz, .asm_24a34
+ xor a
+ ld [wSwitchItem], a
+ ret
+
+Function24968:
+ call ItemSwitch_GetNthItem
+ ld de, wceed
+ call ItemSwitch_ConvertItemFormatToDW
+ call CopyBytes
+ ret
+
+Function24975:
+ call ItemSwitch_GetNthItem
+ ld d, h
+ ld e, l
+ ld hl, wceed
+ call ItemSwitch_ConvertItemFormatToDW
+ call CopyBytes
+ ret
+
+ItemSwitch_GetNthItem:
+ push af
+ call ItemSwitch_ConvertItemFormatToDW
+ ld hl, wMenuData_ItemsPointerAddr
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ inc hl
+ pop af
+ call AddNTimes
+ ret
+
+Function24994:
+ push hl
+ call ItemSwitch_ConvertItemFormatToDW
+ ld a, d
+ sub e
+ jr nc, .dont_negate
+ dec a
+ cpl
+.dont_negate
+ ld hl, 0
+ call AddNTimes
+ ld b, h
+ ld c, l
+ pop hl
+ ret
+
+ItemSwitch_ConvertItemFormatToDW:
+ push hl
+ ld a, [wMenuData_ScrollingMenuItemFormat]
+ ld c, a
+ ld b, 0
+ ld hl, .format_dws
+ add hl, bc
+ add hl, bc
+ ld c, [hl]
+ inc hl
+ ld b, [hl]
+ pop hl
+ ret
+
+.format_dws
+ dw 0
+ dw 1
+ dw 2
+
+Function249bf:
+ push af
+ call ItemSwitch_ConvertItemFormatToDW
+ ld a, c
+ cp 2
+ jr nz, .not_2
+ pop af
+ call ItemSwitch_GetNthItem
+ inc hl
+ ld a, [hl]
+ ret
+
+.not_2
+ pop af
+ ld a, $1
+ ret
+
+Function249d3:
+.loop
+ ld a, [hld]
+ ld [de], a
+ dec de
+ dec bc
+ ld a, b
+ or c
+ jr nz, .loop
+ ret
diff --git a/engine/items/update_item_description.asm b/engine/items/update_item_description.asm
new file mode 100644
index 00000000..da56732a
--- /dev/null
+++ b/engine/items/update_item_description.asm
@@ -0,0 +1,13 @@
+UpdateItemDescription:
+ ld a, [wMenuSelection]
+ ld [wCurSpecies], a
+ hlcoord 0, 12
+ ld b, 4
+ ld c, SCREEN_WIDTH - 2
+ call Textbox
+ ld a, [wMenuSelection]
+ cp -1
+ ret z
+ decoord 1, 14
+ farcall PrintItemDescription
+ ret
diff --git a/engine/menus/menu.asm b/engine/menus/menu.asm
new file mode 100644
index 00000000..2073e5ca
--- /dev/null
+++ b/engine/menus/menu.asm
@@ -0,0 +1,676 @@
+_2DMenu_::
+ xor a
+ ldh [hBGMapMode], a
+ call MenuBox
+ call Place2DMenuItemStrings
+ call UpdateSprites
+ call ApplyTilemap
+ call Init2DMenuCursorPosition
+ call StaticMenuJoypad
+ call MenuClickSound
+ ld a, [wMenuDataFlags]
+ bit 1, a
+ jr z, .skip
+ call GetMenuJoypad
+ bit SELECT_F, a
+ jr nz, .quit1
+
+.skip
+ ld a, [wMenuDataFlags]
+ bit 0, a
+ jr nz, .skip2
+ call GetMenuJoypad
+ bit B_BUTTON_F, a
+ jr nz, .quit2
+
+.skip2
+ ld a, [w2DMenuNumCols]
+ ld c, a
+ ld a, [wMenuCursorY]
+ dec a
+ call SimpleMultiply
+ ld c, a
+ ld a, [wMenuCursorX]
+ add c
+ ld [wMenuCursorBuffer], a
+ and a
+ ret
+
+.quit1
+ scf
+ ret
+
+.quit2
+ scf
+ ret
+
+Get2DMenuNumberOfColumns:
+ ld a, [wMenuData_2DMenuDimensions]
+ and $f
+ ret
+
+Get2DMenuNumberOfRows:
+ ld a, [wMenuData_2DMenuDimensions]
+ swap a
+ and $f
+ ret
+
+Place2DMenuItemStrings:
+ ld hl, wMenuData_2DMenuItemStringsAddr
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ call GetMenuTextStartCoord
+ call Coord2Tile
+ call Get2DMenuNumberOfRows
+ ld b, a
+.row
+ push bc
+ push hl
+ call Get2DMenuNumberOfColumns
+ ld c, a
+.col
+ push bc
+ ld a, [wMenuData_2DMenuItemStringsBank]
+ call Place2DMenuItemName
+ inc de
+ ld a, [wMenuData_2DMenuSpacing]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ pop bc
+ dec c
+ jr nz, .col
+ pop hl
+ ld bc, 2 * SCREEN_WIDTH
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .row
+ ld hl, wMenuData_2DMenuFunctionAddr
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ or h
+ ret z
+ ld a, [wMenuData_2DMenuFunctionBank]
+ rst FarCall
+ ret
+
+Init2DMenuCursorPosition:
+ call GetMenuTextStartCoord
+ ld a, b
+ ld [w2DMenuCursorInitY], a
+ dec c
+ ld a, c
+ ld [w2DMenuCursorInitX], a
+ call Get2DMenuNumberOfRows
+ ld [w2DMenuNumRows], a
+ call Get2DMenuNumberOfColumns
+ ld [w2DMenuNumCols], a
+ call .InitFlags_a
+ call .InitFlags_b
+ call .InitFlags_c
+ ld a, [w2DMenuNumCols]
+ ld e, a
+ ld a, [wMenuCursorBuffer]
+ ld b, a
+ xor a
+ ld d, 0
+.loop
+ inc d
+ add e
+ cp b
+ jr c, .loop
+ sub e
+ ld c, a
+ ld a, b
+ sub c
+ and a
+ jr z, .reset1
+ cp e
+ jr z, .okay1
+ jr c, .okay1
+.reset1
+ ld a, 1
+.okay1
+ ld [wMenuCursorX], a
+ ld a, [w2DMenuNumRows]
+ ld e, a
+ ld a, d
+ and a
+ jr z, .reset2
+ cp e
+ jr z, .okay2
+ jr c, .okay2
+.reset2
+ ld a, 1
+.okay2
+ ld [wMenuCursorY], a
+ xor a
+ ld [wCursorOffCharacter], a
+ ld [wCursorCurrentTile], a
+ ld [wCursorCurrentTile + 1], a
+ ret
+
+.InitFlags_a:
+ xor a
+ ld hl, w2DMenuFlags1
+ ld [hli], a
+ ld [hld], a
+ ld a, [wMenuDataFlags]
+ bit 5, a
+ ret z
+ set 5, [hl]
+ set 4, [hl]
+ ret
+
+.InitFlags_b:
+ ld a, [wMenuData_2DMenuSpacing]
+ or $20
+ ld [w2DMenuCursorOffsets], a
+ ret
+
+.InitFlags_c:
+ ld hl, wMenuDataFlags
+ ld a, A_BUTTON
+ bit 0, [hl]
+ jr nz, .skip
+ or B_BUTTON
+.skip
+ bit 1, [hl]
+ jr z, .skip2
+ or SELECT
+.skip2
+ ld [wMenuJoypadFilter], a
+ ret
+
+_StaticMenuJoypad::
+ call Place2DMenuCursor
+_ScrollingMenuJoypad::
+ ld hl, w2DMenuFlags2
+ res 7, [hl]
+ ldh a, [hBGMapMode]
+ push af
+
+.menu_joypad_loop
+ call Move2DMenuCursor
+ ldh a, [hOAMUpdate]
+ push af
+ ld a, $1
+ ldh [hOAMUpdate], a
+ call WaitBGMap
+ pop af
+ ldh [hOAMUpdate], a
+ xor a
+ ldh [hBGMapMode], a
+
+.loopRTC
+ call UpdateTimeAndPals
+ call Menu_WasButtonPressed
+ jr c, .pressed
+ ld a, [w2DMenuFlags1]
+ bit 7, a
+ jp nz, .done
+ jr .loopRTC
+
+.pressed
+ call _2DMenuInterpretJoypad
+ jp c, .done
+ ld a, [w2DMenuFlags1]
+ bit 7, a
+ jr nz, .done
+ call GetMenuJoypad
+ ld b, a
+ ld a, [wMenuJoypadFilter]
+ and b
+ jp z, .menu_joypad_loop
+
+.done
+ pop af
+ ldh [hBGMapMode], a
+ call GetMenuJoypad
+ ret
+
+Menu_WasButtonPressed:
+ ld a, [w2DMenuFlags1]
+ bit 6, a
+ jr z, .skip_to_joypad
+ callfar PlaySpriteAnimationsAndDelayFrame
+
+.skip_to_joypad
+ call JoyTextDelay
+ call GetMenuJoypad
+ and a
+ ret z
+ scf
+ ret
+
+_2DMenuInterpretJoypad:
+ call GetMenuJoypad
+ bit A_BUTTON_F, a
+ jp nz, .a_b_start_select
+ bit B_BUTTON_F, a
+ jp nz, .a_b_start_select
+ bit SELECT_F, a
+ jp nz, .a_b_start_select
+ bit START_F, a
+ jp nz, .a_b_start_select
+ bit D_RIGHT_F, a
+ jr nz, .d_right
+ bit D_LEFT_F, a
+ jr nz, .d_left
+ bit D_UP_F, a
+ jr nz, .d_up
+ bit D_DOWN_F, a
+ jr nz, .d_down
+ and a
+ ret
+
+.set_bit_7
+ ld hl, w2DMenuFlags2
+ set 7, [hl]
+ scf
+ ret
+
+.d_down
+ ld hl, wMenuCursorY
+ ld a, [w2DMenuNumRows]
+ cp [hl]
+ jr z, .check_wrap_around_down
+ inc [hl]
+ xor a
+ ret
+
+.check_wrap_around_down
+ ld a, [w2DMenuFlags1]
+ bit 5, a
+ jr nz, .wrap_around_down
+ bit 3, a
+ jp nz, .set_bit_7
+ xor a
+ ret
+
+.wrap_around_down
+ ld [hl], $1
+ xor a
+ ret
+
+.d_up
+ ld hl, wMenuCursorY
+ ld a, [hl]
+ dec a
+ jr z, .check_wrap_around_up
+ ld [hl], a
+ xor a
+ ret
+
+.check_wrap_around_up
+ ld a, [w2DMenuFlags1]
+ bit 5, a
+ jr nz, .wrap_around_up
+ bit 2, a
+ jp nz, .set_bit_7
+ xor a
+ ret
+
+.wrap_around_up
+ ld a, [w2DMenuNumRows]
+ ld [hl], a
+ xor a
+ ret
+
+.d_left
+ ld hl, wMenuCursorX
+ ld a, [hl]
+ dec a
+ jr z, .check_wrap_around_left
+ ld [hl], a
+ xor a
+ ret
+
+.check_wrap_around_left
+ ld a, [w2DMenuFlags1]
+ bit 4, a
+ jr nz, .wrap_around_left
+ bit 1, a
+ jp nz, .set_bit_7
+ xor a
+ ret
+
+.wrap_around_left
+ ld a, [w2DMenuNumCols]
+ ld [hl], a
+ xor a
+ ret
+
+.d_right
+ ld hl, wMenuCursorX
+ ld a, [w2DMenuNumCols]
+ cp [hl]
+ jr z, .check_wrap_around_right
+ inc [hl]
+ xor a
+ ret
+
+.check_wrap_around_right
+ ld a, [w2DMenuFlags1]
+ bit 4, a
+ jr nz, .wrap_around_right
+ bit 0, a
+ jp nz, .set_bit_7
+ xor a
+ ret
+
+.wrap_around_right
+ ld [hl], $1
+ xor a
+ ret
+
+.a_b_start_select
+ xor a
+ ret
+
+Move2DMenuCursor:
+ ld hl, wCursorCurrentTile
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [hl]
+ cp "▶"
+ jr nz, Place2DMenuCursor
+ ld a, [wCursorOffCharacter]
+ ld [hl], a
+Place2DMenuCursor:
+ ld a, [w2DMenuCursorInitY]
+ ld b, a
+ ld a, [w2DMenuCursorInitX]
+ ld c, a
+ call Coord2Tile
+ ld a, [w2DMenuCursorOffsets]
+ swap a
+ and $f
+ ld c, a
+ ld a, [wMenuCursorY]
+ ld b, a
+ xor a
+ dec b
+ jr z, .got_row
+.row_loop
+ add c
+ dec b
+ jr nz, .row_loop
+
+.got_row
+ ld c, SCREEN_WIDTH
+ call AddNTimes
+ ld a, [w2DMenuCursorOffsets]
+ and $f
+ ld c, a
+ ld a, [wMenuCursorX]
+ ld b, a
+ xor a
+ dec b
+ jr z, .got_col
+.col_loop
+ add c
+ dec b
+ jr nz, .col_loop
+
+.got_col
+ ld c, a
+ add hl, bc
+ ld a, [hl]
+ cp "▶"
+ jr z, .cursor_on
+ ld [wCursorOffCharacter], a
+ ld [hl], "▶"
+
+.cursor_on
+ ld a, l
+ ld [wCursorCurrentTile], a
+ ld a, h
+ ld [wCursorCurrentTile + 1], a
+ ret
+
+_PushWindow::
+ xor a ; BANK(sWindowStack)
+ call OpenSRAM
+
+ ld hl, wWindowStackPointer
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ push de
+ ld b, $10
+ ld hl, wMenuFlags
+.loop
+ ld a, [hli]
+ ld [de], a
+ dec de
+ dec b
+ jr nz, .loop
+
+; If bit 6 or 7 of the menu flags is set, set bit 0 of the address
+; at 7:[wWindowStackPointer], and draw the menu using the coordinates from the header.
+; Otherwise, reset bit 0 of 7:[wWindowStackPointer].
+ ld a, [wMenuFlags]
+ bit 6, a
+ jr nz, .bit_6
+ bit 7, a
+ jr z, .not_bit_7
+
+.bit_6
+ ld hl, wWindowStackPointer
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ set 0, [hl]
+ call MenuBoxCoord2Tile
+ call GetMenuBoxDims
+ inc b
+ inc c
+ call .ret ; empty function
+
+.row
+ push bc
+ push hl
+
+.col
+ ld a, [hli]
+ ld [de], a
+ dec de
+ dec c
+ jr nz, .col
+
+ pop hl
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .row
+ jr .done
+
+.not_bit_7
+ pop hl ; last-pushed register was de
+ push hl
+ ld a, [hld]
+ ld l, [hl]
+ ld h, a
+ res 0, [hl]
+
+.done
+ pop hl
+ call .ret ; empty function
+ ld a, h
+ ld [de], a
+ dec de
+ ld a, l
+ ld [de], a
+ dec de
+ ld hl, wWindowStackPointer
+ ld [hl], e
+ inc hl
+ ld [hl], d
+
+ call CloseSRAM
+ ld hl, wWindowStackSize
+ inc [hl]
+ ret
+
+.ret
+ ret
+
+_ExitMenu::
+ xor a
+ ldh [hBGMapMode], a
+
+ xor a ; BANK(sWindowStack)
+ call OpenSRAM
+
+ call GetWindowStackTop
+ ld a, l
+ or h
+ jp z, Error_Cant_ExitMenu
+ ld a, l
+ ld [wWindowStackPointer], a
+ ld a, h
+ ld [wWindowStackPointer + 1], a
+ call PopWindow
+ ld a, [wMenuFlags]
+ bit 0, a
+ jr z, .loop
+ ld d, h
+ ld e, l
+ call RestoreTileBackup
+
+.loop
+ call GetWindowStackTop
+ ld a, h
+ or l
+ jr z, .done
+ call PopWindow
+
+.done
+ call CloseSRAM
+ ld hl, wWindowStackSize
+ dec [hl]
+ call Function2434b
+ ld a, [wSpriteUpdatesEnabled]
+ cp 0
+ ret z
+
+ call Functiond2a
+ ret
+
+Function2434b:
+ ld a, [wVramState]
+ bit 0, a
+ ret z
+ xor a ; sScratch
+ call OpenSRAM
+ hlcoord 0, 0
+ ld de, sScratch
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ call CopyBytes
+ call CloseSRAM
+ call OverworldTextModeSwitch
+ xor a ; sScratch
+ call OpenSRAM
+ ld hl, sScratch
+ decoord 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+.loop
+ ld a, [hl]
+ cp $61
+ jr c, .next
+ ld [de], a
+.next
+ inc hl
+ inc de
+ dec bc
+ ld a, c
+ or b
+ jr nz, .loop
+ call CloseSRAM
+ ret
+
+Error_Cant_ExitMenu:
+ ld hl, .WindowPoppingErrorText
+ call PrintText
+ call WaitBGMap
+.infinite_loop
+ jr .infinite_loop
+
+.WindowPoppingErrorText:
+ text_far _WindowPoppingErrorText
+ text_end
+
+_InitVerticalMenuCursor::
+ ld a, [wMenuDataFlags]
+ ld b, a
+ ld hl, w2DMenuCursorInitY
+ ld a, [wMenuBorderTopCoord]
+ inc a
+ bit 6, b
+ jr nz, .skip_offset
+ inc a
+.skip_offset
+ ld [hli], a
+; w2DMenuCursorInitX
+ ld a, [wMenuBorderLeftCoord]
+ inc a
+ ld [hli], a
+; w2DMenuNumRows
+ ld a, [wMenuDataItems]
+ ld [hli], a
+; w2DMenuNumCols
+ ld a, 1
+ ld [hli], a
+; w2DMenuFlags1
+ ld [hl], $0
+ bit 5, b
+ jr z, .skip_bit_5
+ set 5, [hl]
+.skip_bit_5
+ ld a, [wMenuFlags]
+ bit 4, a
+ jr z, .skip_bit_6
+ set 6, [hl]
+.skip_bit_6
+ inc hl
+; w2DMenuFlags2
+ xor a
+ ld [hli], a
+; w2DMenuCursorOffsets
+ ln a, 2, 0
+ ld [hli], a
+; wMenuJoypadFilter
+ ld a, A_BUTTON
+ bit 0, b
+ jr nz, .skip_bit_1
+ add B_BUTTON
+.skip_bit_1
+ ld [hli], a
+; wMenuCursorY
+ ld a, [wMenuCursorBuffer]
+ and a
+ jr z, .load_at_the_top
+ ld c, a
+ ld a, [wMenuDataItems]
+ cp c
+ jr nc, .load_position
+.load_at_the_top
+ ld c, 1
+.load_position
+ ld [hl], c
+ inc hl
+; wMenuCursorX
+ ld a, 1
+ ld [hli], a
+; wCursorOffCharacter, wCursorCurrentTile
+ xor a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ret
diff --git a/engine/menus/menu_2.asm b/engine/menus/menu_2.asm
new file mode 100644
index 00000000..50214545
--- /dev/null
+++ b/engine/menus/menu_2.asm
@@ -0,0 +1,298 @@
+PlaceMenuItemName:
+ push de
+ ld a, [wMenuSelection]
+ ld [wNamedObjectIndexBuffer], a
+ call GetItemName
+ pop hl
+ call PlaceString
+ ret
+
+PlaceMenuItemQuantity:
+ push de
+ ld a, [wMenuSelection]
+ ld [wCurItem], a
+ farcall _CheckTossableItem
+ ld a, [wItemAttributeParamBuffer]
+ pop hl
+ and a
+ jr nz, .done
+ ld de, $15
+ add hl, de
+ ld [hl], "×"
+ inc hl
+ ld de, wMenuSelectionQuantity
+ lb bc, 1, 2
+ call PrintNum
+
+.done
+ ret
+
+PlaceMoneyTopRight:
+ ld hl, MenuHeader_0x24b15
+ call CopyMenuHeader
+ jr PlaceMoneyTextbox
+
+PlaceMoneyBottomLeft:
+ ld hl, MenuHeader_0x24b1d
+ call CopyMenuHeader
+ jr PlaceMoneyTextbox
+
+PlaceMoneyAtTopLeftOfTextbox:
+ ld hl, MenuHeader_0x24b15
+ lb de, 0, 11
+ call OffsetMenuHeader
+
+PlaceMoneyTextbox:
+ call MenuBox
+ call MenuBoxCoord2Tile
+ ld de, SCREEN_WIDTH + 1
+ add hl, de
+ ld de, wMoney
+ lb bc, PRINTNUM_MONEY | 3, 6
+ call PrintNum
+ ret
+
+MenuHeader_0x24b15:
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 11, 0, SCREEN_WIDTH - 1, 2
+ dw NULL
+ db 1 ; default option
+
+MenuHeader_0x24b1d:
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 0, 11, 8, 13
+ dw NULL
+ db 1 ; default option
+
+DisplayCoinCaseBalance:
+ ; Place a text box of size 1x7 at 11, 0.
+ hlcoord 11, 0
+ ld b, 1
+ ld c, 7
+ call Textbox
+ hlcoord 12, 0
+ ld de, CoinString
+ call PlaceString
+ hlcoord 17, 1
+ ld de, ShowMoney_TerminatorString
+ call PlaceString
+ ld de, wCoins
+ lb bc, 2, 4
+ hlcoord 13, 1
+ call PrintNum
+ ret
+
+DisplayMoneyAndCoinBalance:
+ hlcoord 5, 0
+ ld b, 3
+ ld c, 13
+ call Textbox
+ hlcoord 6, 1
+ ld de, MoneyString
+ call PlaceString
+ hlcoord 12, 1
+ ld de, wMoney
+ lb bc, PRINTNUM_MONEY | 3, 6
+ call PrintNum
+ hlcoord 6, 3
+ ld de, CoinString
+ call PlaceString
+ hlcoord 15, 3
+ ld de, wCoins
+ lb bc, 2, 4
+ call PrintNum
+ ret
+
+MoneyString:
+ db "MONEY@"
+CoinString:
+ db "COIN@"
+ShowMoney_TerminatorString:
+ db "@@"
+
+Unreferenced_Function24ab8:
+; related to safari?
+ ld hl, wOptions
+ ld a, [hl]
+ push af
+ set NO_TEXT_SCROLL, [hl]
+ hlcoord 0, 0
+ ld b, 3
+ ld c, 7
+ call Textbox
+ hlcoord 1, 1
+ ld de, wSafariTimeRemaining
+ lb bc, 2, 3
+ call PrintNum
+ hlcoord 4, 1
+ ld de, .slash_500
+ call PlaceString
+ hlcoord 1, 3
+ ld de, .booru_ko
+ call PlaceString
+ hlcoord 5, 3
+ ld de, wSafariBallsRemaining
+ lb bc, 1, 2
+ call PrintNum
+ pop af
+ ld [wOptions], a
+ ret
+
+.slash_500
+ db "/500@"
+.booru_ko
+ db "ボール   こ@"
+
+StartMenu_DrawBugContestStatusBox:
+ hlcoord 0, 0
+ ld b, 5
+ ld c, 17
+ call Textbox
+ ret
+
+StartMenu_PrintBugContestStatus:
+ ld hl, wOptions
+ ld a, [hl]
+ push af
+ set NO_TEXT_SCROLL, [hl]
+ call StartMenu_DrawBugContestStatusBox
+ hlcoord 1, 5
+ ld de, .Balls_EN
+ call PlaceString
+ hlcoord 8, 5
+ ld de, wParkBallsRemaining
+ lb bc, PRINTNUM_LEFTALIGN | 1, 2
+ call PrintNum
+ hlcoord 1, 1
+ ld de, .CAUGHT
+ call PlaceString
+ ld a, [wContestMon]
+ and a
+ ld de, .None
+ jr z, .no_contest_mon
+ ld [wNamedObjectIndexBuffer], a
+ call GetPokemonName
+
+.no_contest_mon
+ hlcoord 8, 1
+ call PlaceString
+ ld a, [wContestMon]
+ and a
+ jr z, .skip_level
+ hlcoord 1, 3
+ ld de, .LEVEL
+ call PlaceString
+ ld a, [wContestMonLevel]
+ ld h, b
+ ld l, c
+ inc hl
+ ld c, 3
+ call Print8BitNumLeftAlign
+
+.skip_level
+ pop af
+ ld [wOptions], a
+ ret
+
+.Balls_JP:
+ db "ボール   こ@"
+.CAUGHT:
+ db "CAUGHT@"
+.Balls_EN:
+ db "BALLS:@"
+.None:
+ db "None@"
+.LEVEL:
+ db "LEVEL@"
+
+Kurt_SelectApricorn:
+ call FindApricornsInBag
+ jr c, .nope
+ ld hl, .MenuHeader
+ call LoadMenuHeader
+ call DoNthMenu
+ call CloseWindow
+ jr c, .nope
+ ld a, [wMenuSelection]
+ jr .done
+
+.nope
+ xor a ; FALSE
+
+.done
+ ld c, a
+ ret
+
+.MenuHeader:
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 0, 0, 14, 17
+ dw .MenuData
+ db 1 ; default option
+
+.MenuData:
+ db SCROLLINGMENU_ENABLE_SELECT | SCROLLINGMENU_ENABLE_FUNCTION3
+ dbw 0, wBuffer1
+ dw .Name
+ dw NULL
+
+.Name:
+ ld a, [wMenuSelection]
+ and a
+ jp nz, PlaceMenuItemName
+ ld h, d
+ ld l, e
+ ld de, .Cancel
+ call PlaceString
+ ret
+
+.Cancel
+ db "CANCEL@"
+
+FindApricornsInBag:
+; Checks the bag for Apricorns.
+ ld hl, wBuffer1
+ xor a
+ ld [hli], a
+ dec a
+ ld bc, 10
+ call ByteFill
+
+ ld hl, ApricornBalls
+.loop
+ ld a, [hl]
+ cp -1
+ jr z, .done
+ push hl
+ ld [wCurItem], a
+ ld hl, wNumItems
+ call CheckItem
+ pop hl
+ jr nc, .nope
+ ld a, [hl]
+ call .addtobuffer
+.nope
+ inc hl
+ inc hl
+ jr .loop
+
+.done
+ xor a
+ call .addtobuffer
+ ld a, [wBuffer1]
+ cp 1
+ ret nz
+ scf
+ ret
+
+.addtobuffer
+ push hl
+ ld hl, wBuffer1
+ inc [hl]
+ ld e, [hl]
+ ld d, 0
+ add hl, de
+ ld [hl], a
+ pop hl
+ ret
+
+INCLUDE "data/items/apricorn_balls.asm"
diff --git a/engine/menus/naming_screen.asm b/engine/menus/naming_screen.asm
index 945e5d01..a528b3a8 100644
--- a/engine/menus/naming_screen.asm
+++ b/engine/menus/naming_screen.asm
@@ -290,7 +290,7 @@ Function11cd4:
bit 7, a
jr nz, .asm_11cef
call Function11d27
- farcall PlaySpriteAnimationsAndDelay
+ farcall PlaySpriteAnimationsAndDelayFrame
call Function11cff
call DelayFrame
and a
@@ -963,7 +963,7 @@ Function1238d:
bit 7, a
jr nz, .asm_123a8
call Function123d5
- farcall PlaySpriteAnimationsAndDelay
+ farcall PlaySpriteAnimationsAndDelayFrame
call Function123b8
call DelayFrame
and a
diff --git a/engine/menus/scrolling_menu.asm b/engine/menus/scrolling_menu.asm
new file mode 100644
index 00000000..6b0572a6
--- /dev/null
+++ b/engine/menus/scrolling_menu.asm
@@ -0,0 +1,519 @@
+_InitScrollingMenu::
+ xor a
+ ld [wMenuJoypad], a
+ ldh [hBGMapMode], a
+ inc a
+ ldh [hInMenu], a
+ call InitScrollingMenuCursor
+ call ScrollingMenu_InitFlags
+ call ScrollingMenu_ValidateSwitchItem
+ call ScrollingMenu_InitDisplay
+ call ApplyTilemap
+ xor a
+ ldh [hBGMapMode], a
+ ret
+
+_ScrollingMenu::
+.loop
+ call ScrollingMenuJoyAction
+ jp c, .exit
+ call z, .zero
+ jr .loop
+
+.exit
+ call MenuClickSound
+ ld [wMenuJoypad], a
+ ld a, 0
+ ldh [hInMenu], a
+ ret
+
+.zero
+ call ScrollingMenu_InitDisplay
+ ld a, 1
+ ldh [hBGMapMode], a
+ ld c, 3
+ call DelayFrames
+ xor a
+ ldh [hBGMapMode], a
+ ret
+
+ScrollingMenu_InitDisplay:
+ xor a
+ ldh [hBGMapMode], a
+ ld hl, wOptions
+ ld a, [hl]
+ push af
+ set NO_TEXT_SCROLL, [hl]
+ call ScrollingMenu_UpdateDisplay
+ call ScrollingMenu_PlaceCursor
+ call ScrollingMenu_CheckCallFunction3
+ pop af
+ ld [wOptions], a
+ ret
+
+ScrollingMenuJoyAction:
+.loop
+ call ScrollingMenuJoypad
+ ldh a, [hJoyLast]
+ and D_PAD
+ ld b, a
+ ldh a, [hJoyPressed]
+ and BUTTONS
+ or b
+ bit A_BUTTON_F, a
+ jp nz, .a_button
+ bit B_BUTTON_F, a
+ jp nz, .b_button
+ bit SELECT_F, a
+ jp nz, .select
+ bit START_F, a
+ jp nz, .start
+ bit D_RIGHT_F, a
+ jp nz, .d_right
+ bit D_LEFT_F, a
+ jp nz, .d_left
+ bit D_UP_F, a
+ jp nz, .d_up
+ bit D_DOWN_F, a
+ jp nz, .d_down
+ jr .loop
+
+.unreferenced ; unused
+ ld a, -1
+ and a
+ ret
+
+.a_button
+ call PlaceHollowCursor
+ ld a, [wMenuCursorY]
+ dec a
+ call ScrollingMenu_GetListItemCoordAndFunctionArgs
+ ld a, [wMenuSelection]
+ ld [wCurItem], a
+ ld a, [wMenuSelectionQuantity]
+ ld [wItemQuantityBuffer], a
+ call ScrollingMenu_GetCursorPosition
+ dec a
+ ld [wScrollingMenuCursorPosition], a
+ ld [wCurItemQuantity], a
+ ld a, [wMenuSelection]
+ cp -1
+ jr z, .b_button
+ ld a, A_BUTTON
+ scf
+ ret
+
+.b_button
+ ld a, B_BUTTON
+ scf
+ ret
+
+.select
+ ld a, [wMenuDataFlags]
+ bit 7, a
+ jp z, xor_a_dec_a
+ ld a, [wMenuCursorY]
+ dec a
+ call ScrollingMenu_GetListItemCoordAndFunctionArgs
+ ld a, [wMenuSelection]
+ cp -1
+ jp z, xor_a_dec_a
+ call ScrollingMenu_GetCursorPosition
+ dec a
+ ld [wScrollingMenuCursorPosition], a
+ ld a, SELECT
+ scf
+ ret
+
+.start
+ ld a, [wMenuDataFlags]
+ bit 6, a
+ jp z, xor_a_dec_a
+ ld a, START
+ scf
+ ret
+
+.d_left
+ ld hl, w2DMenuFlags2
+ bit 7, [hl]
+ jp z, xor_a_dec_a
+ ld a, [wMenuDataFlags]
+ bit 3, a
+ jp z, xor_a_dec_a
+ ld a, D_LEFT
+ scf
+ ret
+
+.d_right
+ ld hl, w2DMenuFlags2
+ bit 7, [hl]
+ jp z, xor_a_dec_a
+ ld a, [wMenuDataFlags]
+ bit 2, a
+ jp z, xor_a_dec_a
+ ld a, D_RIGHT
+ scf
+ ret
+
+.d_up
+ ld hl, w2DMenuFlags2
+ bit 7, [hl]
+ jp z, xor_a
+ ld hl, wMenuScrollPosition
+ ld a, [hl]
+ and a
+ jr z, .xor_dec_up
+ dec [hl]
+ jp xor_a
+
+.xor_dec_up
+ jp xor_a_dec_a
+
+.d_down
+ ld hl, w2DMenuFlags2
+ bit 7, [hl]
+ jp z, xor_a
+ ld hl, wMenuScrollPosition
+ ld a, [wMenuData_ScrollingMenuHeight]
+ add [hl]
+ ld b, a
+ ld a, [wScrollingMenuListSize]
+ cp b
+ jr c, .xor_dec_down
+ inc [hl]
+ jp xor_a
+
+.xor_dec_down
+ jp xor_a_dec_a
+
+ScrollingMenu_GetCursorPosition:
+ ld a, [wMenuScrollPosition]
+ ld c, a
+ ld a, [wMenuCursorY]
+ add c
+ ld c, a
+ ret
+
+ScrollingMenu_ClearLeftColumn:
+ call MenuBoxCoord2Tile
+ ld de, SCREEN_WIDTH
+ add hl, de
+ ld de, 2 * SCREEN_WIDTH
+ ld a, [wMenuData_ScrollingMenuHeight]
+.loop
+ ld [hl], " "
+ add hl, de
+ dec a
+ jr nz, .loop
+ ret
+
+InitScrollingMenuCursor:
+ ld hl, wMenuData_ItemsPointerAddr
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wMenuData_ItemsPointerBank]
+ call GetFarByte
+ ld [wScrollingMenuListSize], a
+ ld a, [wMenuData_ScrollingMenuHeight]
+ ld c, a
+ ld a, [wMenuScrollPosition]
+ add c
+ ld c, a
+ ld a, [wScrollingMenuListSize]
+ inc a
+ cp c
+ jr nc, .skip
+ ld a, [wMenuData_ScrollingMenuHeight]
+ ld c, a
+ ld a, [wScrollingMenuListSize]
+ inc a
+ sub c
+ jr nc, .store
+ xor a
+
+.store
+ ld [wMenuScrollPosition], a
+
+.skip
+ ld a, [wMenuScrollPosition]
+ ld c, a
+ ld a, [wMenuCursorBuffer]
+ add c
+ ld b, a
+ ld a, [wScrollingMenuListSize]
+ inc a
+ cp b
+ jr c, .wrap
+ jr nc, .done
+
+.wrap
+ xor a
+ ld [wMenuScrollPosition], a
+ ld a, $1
+ ld [wMenuCursorBuffer], a
+
+.done
+ ret
+
+ScrollingMenu_InitFlags:
+ ld a, [wMenuDataFlags]
+ ld c, a
+ ld a, [wScrollingMenuListSize]
+ ld b, a
+ ld a, [wMenuBorderTopCoord]
+ add 1
+ ld [w2DMenuCursorInitY], a
+ ld a, [wMenuBorderLeftCoord]
+ add 0
+ ld [w2DMenuCursorInitX], a
+ ld a, [wMenuData_ScrollingMenuHeight]
+ cp b
+ jr c, .no_extra_row
+ jr z, .no_extra_row
+ ld a, b
+ inc a
+.no_extra_row
+ ld [w2DMenuNumRows], a
+ ld a, 1
+ ld [w2DMenuNumCols], a
+ ld a, $8c
+ bit 2, c
+ jr z, .skip_set_0
+ set 0, a
+
+.skip_set_0
+ bit 3, c
+ jr z, .skip_set_1
+ set 1, a
+
+.skip_set_1
+ ld [w2DMenuFlags1], a
+ xor a
+ ld [w2DMenuFlags2], a
+ ld a, $20
+ ld [w2DMenuCursorOffsets], a
+ ld a, A_BUTTON | B_BUTTON | D_UP | D_DOWN
+ bit 7, c
+ jr z, .disallow_select
+ add SELECT
+
+.disallow_select
+ bit 6, c
+ jr z, .disallow_start
+ add START
+
+.disallow_start
+ ld [wMenuJoypadFilter], a
+ ld a, [w2DMenuNumRows]
+ ld b, a
+ ld a, [wMenuCursorBuffer]
+ and a
+ jr z, .reset_cursor
+ cp b
+ jr z, .cursor_okay
+ jr c, .cursor_okay
+
+.reset_cursor
+ ld a, 1
+
+.cursor_okay
+ ld [wMenuCursorY], a
+ ld a, 1
+ ld [wMenuCursorX], a
+ xor a
+ ld [wCursorCurrentTile], a
+ ld [wCursorCurrentTile + 1], a
+ ld [wCursorOffCharacter], a
+ ret
+
+ScrollingMenu_ValidateSwitchItem:
+ ld a, [wScrollingMenuListSize]
+ ld c, a
+ ld a, [wSwitchItem]
+ and a
+ jr z, .done
+ dec a
+ cp c
+ jr c, .done
+ xor a
+ ld [wSwitchItem], a
+
+.done
+ ret
+
+ScrollingMenu_UpdateDisplay:
+ call ClearWholeMenuBox
+ ld a, [wMenuDataFlags]
+ bit 4, a ; place arrows
+ jr z, .okay
+ ld a, [wMenuScrollPosition]
+ and a
+ jr z, .okay
+ ld a, [wMenuBorderTopCoord]
+ ld b, a
+ ld a, [wMenuBorderRightCoord]
+ ld c, a
+ call Coord2Tile
+ ld [hl], "▲"
+
+.okay
+ call MenuBoxCoord2Tile
+ ld bc, SCREEN_WIDTH + 1
+ add hl, bc
+ ld a, [wMenuData_ScrollingMenuHeight]
+ ld b, a
+ ld c, $0
+.loop
+ ld a, [wMenuScrollPosition]
+ add c
+ ld [wScrollingMenuCursorPosition], a
+ ld a, c
+ call ScrollingMenu_GetListItemCoordAndFunctionArgs
+ ld a, [wMenuSelection]
+ cp -1
+ jr z, .cancel
+ push bc
+ push hl
+ call ScrollingMenu_CallFunctions1and2
+ pop hl
+ ld bc, 2 * SCREEN_WIDTH
+ add hl, bc
+ pop bc
+ inc c
+ ld a, c
+ cp b
+ jr nz, .loop
+ ld a, [wMenuDataFlags]
+ bit 4, a ; place arrows
+ jr z, .done
+ ld a, [wMenuBorderBottomCoord]
+ ld b, a
+ ld a, [wMenuBorderRightCoord]
+ ld c, a
+ call Coord2Tile
+ ld [hl], "▼"
+
+.done
+ ret
+
+.cancel
+ ld a, [wMenuDataFlags]
+ bit 0, a ; call function on cancel
+ jr nz, .call_function
+ ld de, .string_2485f
+ call PlaceString
+ ret
+
+.string_2485f
+ db "CANCEL@"
+
+.call_function
+ ld d, h
+ ld e, l
+ ld hl, wMenuData_ScrollingMenuFunction1
+ jp CallPointerAt
+
+ScrollingMenu_CallFunctions1and2:
+ push hl
+ ld d, h
+ ld e, l
+ ld hl, wMenuData_ScrollingMenuFunction1
+ call CallPointerAt
+ pop hl
+ ld a, [wMenuData_ScrollingMenuWidth]
+ and a
+ jr z, .done
+ ld e, a
+ ld d, $0
+ add hl, de
+ ld d, h
+ ld e, l
+ ld hl, wMenuData_ScrollingMenuFunction2
+ call CallPointerAt
+
+.done
+ ret
+
+ScrollingMenu_PlaceCursor:
+ ld a, [wSwitchItem]
+ and a
+ jr z, .done
+ ld b, a
+ ld a, [wMenuScrollPosition]
+ cp b
+ jr nc, .done
+ ld c, a
+ ld a, [wMenuData_ScrollingMenuHeight]
+ add c
+ cp b
+ jr c, .done
+ ld a, b
+ sub c
+ dec a
+ add a
+ add $1
+ ld c, a
+ ld a, [wMenuBorderTopCoord]
+ add c
+ ld b, a
+ ld a, [wMenuBorderLeftCoord]
+ add $0
+ ld c, a
+ call Coord2Tile
+ ld [hl], "▷"
+
+.done
+ ret
+
+ScrollingMenu_CheckCallFunction3:
+ ld a, [wMenuDataFlags]
+ bit 5, a ; call function 3
+ ret z
+ bit 1, a ; call function 3 if not switching items
+ jr z, .call
+ ld a, [wSwitchItem]
+ and a
+ ret nz
+
+.call
+ ld a, [wMenuCursorY]
+ dec a
+ call ScrollingMenu_GetListItemCoordAndFunctionArgs
+ ld hl, wMenuData_ScrollingMenuFunction3
+ call CallPointerAt
+ ret
+
+ScrollingMenu_GetListItemCoordAndFunctionArgs:
+ push de
+ push hl
+ ld e, a
+ ld a, [wMenuScrollPosition]
+ add e
+ ld e, a
+ ld d, $0
+ ld hl, wMenuData_ItemsPointerAddr
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ inc hl ; items
+ ld a, [wMenuData_ScrollingMenuItemFormat]
+ cp SCROLLINGMENU_ITEMS_NORMAL
+ jr z, .got_spacing
+ cp SCROLLINGMENU_ITEMS_QUANTITY
+ jr z, .pointless_jump
+.pointless_jump
+ add hl, de
+.got_spacing
+ add hl, de
+ ld a, [wMenuData_ItemsPointerBank]
+ call GetFarByte
+ ld [wMenuSelection], a
+ ld [wCurItem], a
+ inc hl
+ ld a, [wMenuData_ItemsPointerBank]
+ call GetFarByte
+ ld [wMenuSelectionQuantity], a
+ pop hl
+ pop de
+ ret
diff --git a/engine/overworld/map_objects_2.asm b/engine/overworld/map_objects_2.asm
new file mode 100644
index 00000000..d89d95fc
--- /dev/null
+++ b/engine/overworld/map_objects_2.asm
@@ -0,0 +1,70 @@
+LoadObjectMasks:
+ ld hl, wObjectMasks
+ xor a
+ ld bc, NUM_OBJECTS
+ call ByteFill
+ nop
+ ld bc, wMapObjects
+ ld de, wObjectMasks
+ xor a
+.loop
+ push af
+ push bc
+ push de
+ call GetObjectTimeMask
+ jr c, .next
+ call CheckObjectFlag
+.next
+ pop de
+ ld [de], a
+ inc de
+ pop bc
+ ld hl, MAPOBJECT_LENGTH
+ add hl, bc
+ ld b, h
+ ld c, l
+ pop af
+ inc a
+ cp NUM_OBJECTS
+ jr nz, .loop
+ ret
+
+CheckObjectFlag:
+ ld hl, MAPOBJECT_SPRITE
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .masked
+ ld hl, MAPOBJECT_EVENT_FLAG
+ add hl, bc
+ ld a, [hli]
+ ld e, a
+ ld a, [hl]
+ ld d, a
+ cp -1
+ jr nz, .check
+ ld a, e
+ cp -1
+ jr z, .unmasked
+ jr .masked
+.check
+ ld b, CHECK_FLAG
+ call EventFlagAction
+ ld a, c
+ and a
+ jr nz, .masked
+.unmasked
+ xor a
+ ret
+
+.masked
+ ld a, -1
+ scf
+ ret
+
+GetObjectTimeMask:
+ call CheckObjectTime
+ ld a, -1
+ ret c
+ xor a
+ ret
diff --git a/engine/pokemon/mon_submenu.asm b/engine/pokemon/mon_submenu.asm
new file mode 100644
index 00000000..148f1da6
--- /dev/null
+++ b/engine/pokemon/mon_submenu.asm
@@ -0,0 +1,290 @@
+INCLUDE "data/mon_menu.asm"
+
+MonSubmenu:
+ xor a
+ ldh [hBGMapMode], a
+ call GetMonSubmenuItems
+ farcall FreezeMonIcons
+ ld hl, .MenuHeader
+ call LoadMenuHeader
+ call .GetTopCoord
+ call PopulateMonMenu
+
+ ld a, 1
+ ldh [hBGMapMode], a
+ call MonMenuLoop
+ ld [wMenuSelection], a
+
+ call ExitMenu
+ ret
+
+.MenuHeader:
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 6, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
+ dw 0
+ db 1 ; default option
+
+.GetTopCoord:
+; TopCoord = 1 + BottomCoord - 2 * (NumSubmenuItems + 1)
+ ld a, [wBuffer1]
+ inc a
+ add a
+ ld b, a
+ ld a, [wMenuBorderBottomCoord]
+ sub b
+ inc a
+ ld [wMenuBorderTopCoord], a
+ call MenuBox
+ ret
+
+MonMenuLoop:
+.loop
+ ld a, MENU_UNUSED_3 | MENU_BACKUP_TILES_2 ; flags
+ ld [wMenuDataFlags], a
+ ld a, [wBuffer1] ; items
+ ld [wMenuDataItems], a
+ call InitVerticalMenuCursor
+ ld hl, w2DMenuFlags1
+ set 6, [hl]
+ call StaticMenuJoypad
+ ld de, SFX_READ_TEXT_2
+ call PlaySFX
+ ldh a, [hJoyPressed]
+ bit A_BUTTON_F, a
+ jr nz, .select
+ bit B_BUTTON_F, a
+ jr nz, .cancel
+ jr .loop
+
+.cancel
+ ld a, MONMENUITEM_CANCEL
+ ret
+
+.select
+ ld a, [wMenuCursorY]
+ dec a
+ ld c, a
+ ld b, 0
+ ld hl, wBuffer2
+ add hl, bc
+ ld a, [hl]
+ ret
+
+PopulateMonMenu:
+ call MenuBoxCoord2Tile
+ ld bc, 2 * SCREEN_WIDTH + 2
+ add hl, bc
+ ld de, wBuffer2
+.loop
+ ld a, [de]
+ inc de
+ cp -1
+ ret z
+ push de
+ push hl
+ call GetMonMenuString
+ pop hl
+ call PlaceString
+ ld bc, 2 * SCREEN_WIDTH
+ add hl, bc
+ pop de
+ jr .loop
+
+GetMonMenuString:
+ ld hl, MonMenuOptions + 1
+ ld de, 3
+ call IsInArray
+ dec hl
+ ld a, [hli]
+ cp MONMENU_MENUOPTION
+ jr z, .NotMove
+ inc hl
+ ld a, [hl]
+ ld [wNamedObjectIndexBuffer], a
+ call GetMoveName
+ ret
+
+.NotMove:
+ inc hl
+ ld a, [hl]
+ dec a
+ ld hl, MonMenuOptionStrings
+ call GetNthString
+ ld d, h
+ ld e, l
+ ret
+
+GetMonSubmenuItems:
+ call ResetMonSubmenu
+ ld a, [wCurPartySpecies]
+ cp EGG
+ jr z, .egg
+ ld a, [wLinkMode]
+ and a
+ jr nz, .skip_moves
+ ld a, MON_MOVES
+ call GetPartyParamLocation
+ ld d, h
+ ld e, l
+ ld c, NUM_MOVES
+.loop
+ push bc
+ push de
+ ld a, [de]
+ and a
+ jr z, .next
+ push hl
+ call IsFieldMove
+ pop hl
+ jr nc, .next
+ call AddMonMenuItem
+
+.next
+ pop de
+ inc de
+ pop bc
+ dec c
+ jr nz, .loop
+
+.skip_moves
+ ld a, MONMENUITEM_STATS
+ call AddMonMenuItem
+ ld a, MONMENUITEM_SWITCH
+ call AddMonMenuItem
+ ld a, MONMENUITEM_MOVE
+ call AddMonMenuItem
+ ld a, [wLinkMode]
+ and a
+ jr nz, .skip2
+ push hl
+ ld a, MON_ITEM
+ call GetPartyParamLocation
+ ld d, [hl]
+ farcall ItemIsMail
+ pop hl
+ ld a, MONMENUITEM_MAIL
+ jr c, .ok
+ ld a, MONMENUITEM_ITEM
+
+.ok
+ call AddMonMenuItem
+
+.skip2
+ ld a, [wBuffer1]
+ cp NUM_MONMENU_ITEMS
+ jr z, .ok2
+ ld a, MONMENUITEM_CANCEL
+ call AddMonMenuItem
+
+.ok2
+ call TerminateMonSubmenu
+ ret
+
+.egg
+ ld a, MONMENUITEM_STATS
+ call AddMonMenuItem
+ ld a, MONMENUITEM_SWITCH
+ call AddMonMenuItem
+ ld a, MONMENUITEM_CANCEL
+ call AddMonMenuItem
+ call TerminateMonSubmenu
+ ret
+
+IsFieldMove:
+ ld b, a
+ ld hl, MonMenuOptions
+.next
+ ld a, [hli]
+ cp -1
+ jr z, .nope
+ cp MONMENU_MENUOPTION
+ jr z, .nope
+ ld d, [hl]
+ inc hl
+ ld a, [hli]
+ cp b
+ jr nz, .next
+ ld a, d
+ scf
+
+.nope
+ ret
+
+ResetMonSubmenu:
+ xor a
+ ld [wBuffer1], a
+ ld hl, wBuffer2
+ ld bc, NUM_MONMENU_ITEMS + 1
+ call ByteFill
+ ret
+
+TerminateMonSubmenu:
+ ld a, [wBuffer1]
+ ld e, a
+ ld d, 0
+ ld hl, wBuffer2
+ add hl, de
+ ld [hl], -1
+ ret
+
+AddMonMenuItem:
+ push hl
+ push de
+ push af
+ ld a, [wBuffer1]
+ ld e, a
+ inc a
+ ld [wBuffer1], a
+ ld d, 0
+ ld hl, wBuffer2
+ add hl, de
+ pop af
+ ld [hl], a
+ pop de
+ pop hl
+ ret
+
+BattleMonMenu:
+ ld hl, MenuHeader_0x24e44
+ call CopyMenuHeader
+ xor a
+ ldh [hBGMapMode], a
+ call MenuBox
+ call UpdateSprites
+ call PlaceVerticalMenuItems
+ call WaitBGMap
+ call CopyMenuData
+ ld a, [wMenuDataFlags]
+ bit 7, a
+ jr z, .set_carry
+ call InitVerticalMenuCursor
+ ld hl, w2DMenuFlags1
+ set 6, [hl]
+ call StaticMenuJoypad
+ ld de, SFX_READ_TEXT_2
+ call PlaySFX
+ ldh a, [hJoyPressed]
+ bit B_BUTTON_F, a
+ jr z, .clear_carry
+ ret z
+
+.set_carry
+ scf
+ ret
+
+.clear_carry
+ and a
+ ret
+
+MenuHeader_0x24e44:
+ db 0 ; flags
+ menu_coords 11, 11, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
+ dw MenuData_0x24e4c
+ db 1 ; default option
+
+MenuData_0x24e4c:
+ db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags
+ db 3 ; items
+ db "SWITCH@"
+ db "STATS@"
+ db "CANCEL@"
diff --git a/gfx/overworld/heal_machine.png b/gfx/overworld/heal_machine.png
index f58d6be3..ccb93402 100644
--- a/gfx/overworld/heal_machine.png
+++ b/gfx/overworld/heal_machine.png
Binary files differ
diff --git a/home/menu.asm b/home/menu.asm
index 1c473072..d8dd353d 100644
--- a/home/menu.asm
+++ b/home/menu.asm
@@ -777,7 +777,7 @@ Place2DMenuItemName::
_2DMenu::
call CopyMenuData
ldh a, [hROMBank]
- ld [wMenuDataBank], a
+ ld [wMenuData_2DMenuItemStringsBank], a
push af
ld a, BANK(_2DMenu_)
rst Bankswitch
diff --git a/main.asm b/main.asm
index aa47d03b..1dde3d43 100644
--- a/main.asm
+++ b/main.asm
@@ -229,70 +229,17 @@ EggMovePointers::
SECTION "bank9", ROMX
-StringBufferPointers::
- dr $24000, $2400e
-_2DMenu_::
- dr $2400e, $24136
-_StaticMenuJoypad::
- dr $24136, $24139
-_ScrollingMenuJoypad::
- dr $24139, $242a0
-_PushWindow::
- dr $242a0, $24307
-_ExitMenu::
- dr $24307, $24395
-_InitVerticalMenuCursor::
- dr $24395, $243eb
-UpdateItemDescription::
- dr $243eb, $2440b
-Pokepic::
- dr $2440b, $24450
-ClosePokepic::
- dr $24450, $24477
-LoadObjectMasks::
- dr $24477, $244d7
-_InitScrollingMenu::
- dr $244d7, $244f3
-_ScrollingMenu::
- dr $244f3, $2462e
-ScrollingMenu_ClearLeftColumn::
- dr $2462e, $24834
-SwitchItemsInBag::
- dr $24834, $249dc
-PlaceMenuItemName::
- dr $249dc, $249eb
-PlaceMenuItemQuantity::
- dr $249eb, $24a10
-PlaceMoneyTopRight::
- dr $24a10, $24a18
-PlaceMoneyBottomLeft::
- dr $24a18, $24a20
-PlaceMoneyAtTopLeftOfTextbox::
- dr $24a20, $24a4d
-DisplayCoinCaseBalance::
- dr $24a4d, $24a76
-DisplayMoneyAndCoinBalance::
- dr $24a76, $24b05
-StartMenu_DrawBugContestStatusBox::
- dr $24b05, $24b10
-StartMenu_PrintBugContestStatus::
- dr $24b10, $24b8d
-Function24b8d::
- dr $24b8d, $24c89
-MonSubmenu::
- dr $24c89, $24e09
-BattleMonMenu::
- dr $24e09, $24e62
-LoadBattleMenu::
- dr $24e62, $24e72
-ContestBattleMenu::
- dr $24e72, $24f20
-SelectQuantityToToss::
- dr $24f20, $24f2a
-SelectQuantityToBuy::
- dr $24f2a, $24f42
-SelectQuantityToSell::
- dr $24f42, $25061
+INCLUDE "data/text_buffers.asm"
+INCLUDE "engine/menus/menu.asm"
+INCLUDE "engine/items/update_item_description.asm"
+INCLUDE "engine/events/pokepic.asm"
+INCLUDE "engine/overworld/map_objects_2.asm"
+INCLUDE "engine/menus/scrolling_menu.asm"
+INCLUDE "engine/items/switch_items.asm"
+INCLUDE "engine/menus/menu_2.asm"
+INCLUDE "engine/pokemon/mon_submenu.asm"
+INCLUDE "engine/battle/menu.asm"
+INCLUDE "engine/items/buy_sell_toss.asm"
TrainerCard::
dr $25061, $267af
@@ -405,6 +352,7 @@ JohtoGrassWildMons::
SECTION "bankb", ROMX
+PrintItemDescription::
dr $2c000, $2c033
BattleStart_TrainerHuds::
dr $2c033, $2c045
@@ -445,6 +393,7 @@ TilesetParkGFX::
dr $309e0, $30e40
TilesetParkMeta::
dr $30e40, $31240
+
TilesetParkColl::
dr $31240, $31340
TilesetRuinsOfAlphGFX::
@@ -468,6 +417,7 @@ TilesetUndergroundColl::
dr $32c90, $32d90
TilesetIcePathGFX::
dr $32d90, $331d0
+
TilesetIcePathMeta::
dr $331d0, $335d0
TilesetIcePathColl::
@@ -700,7 +650,7 @@ MagnetTrain::
ClearSpriteAnims::
dr $8d174, $8d183
-PlaySpriteAnimationsAndDelay::
+PlaySpriteAnimationsAndDelayFrame::
dr $8d183, $8d18a
PlaySpriteAnimations::
dr $8d18a, $8d1f7
diff --git a/wram.asm b/wram.asm
index f0174890..913d2b5b 100644
--- a/wram.asm
+++ b/wram.asm
@@ -1846,12 +1846,12 @@ wTilePermissions:: ds 1 ; cea7
wWindowData::
wWindowStackPointer:: dw ; cea8
-wMenuJoypad:: ds 1 ; ceaa
-wMenuSelection:: ds 1 ; ceab
-wceac:: ds 1 ; ceac
-wWhichIndexSet:: ds 1 ; cead
+wMenuJoypad:: db ; ceaa
+wMenuSelection:: db ; ceab
+wMenuSelectionQuantity:: db ; ceac
+wWhichIndexSet:: db ; cead
wScrollingMenuCursorPosition:: db ; ceae
-wceaf:: ds 1 ; ceaf
+wWindowStackSize:: db ; ceaf
wceb0:: ds 1 ; ceb0
wceb1:: ds 1 ; ceb1
wceb2:: ds 1 ; ceb2
@@ -1882,20 +1882,34 @@ wMenuHeaderEnd::
wMenuData::
wMenuDataFlags:: ds 1 ; cec8
-wMenuDataItems:: ds 1 ; cec9
-wMenuDataIndicesPointer:: ds 1 ; ceca
-wMenuDataBank:: ds 1 ; cecb
+
+UNION ; cec9
+; Vertical Menu/DoNthMenu/SetUpMenu
+wMenuDataItems:: db ; cec9
+wMenuDataIndicesPointer:: dw ; ceca
wMenuDataDisplayFunctionPointer:: dw ; cecc
-wMenuDataPointerTableAddr:: ds 1 ; cece
-wcecf:: ds 1 ; cecf
-wced0:: ds 1 ; ced0
-wced1:: ds 1 ; ced1
-wced2:: ds 1 ; ced2
-wced3:: ds 1 ; ced3
-wced4:: ds 1 ; ced4
-wced5:: ds 1 ; ced5
-wced6:: ds 1 ; ced6
-wced7:: ds 1 ; ced7
+wMenuDataPointerTableAddr:: dw ; cece
+
+NEXTU ; cec9
+; 2D Menu
+wMenuData_2DMenuDimensions:: db ; cec9
+wMenuData_2DMenuSpacing:: db ; ceca
+wMenuData_2DMenuItemStringsBank:: db ; cecb
+wMenuData_2DMenuItemStringsAddr:: dw ; cecc
+wMenuData_2DMenuFunctionBank:: db ; cece
+wMenuData_2DMenuFunctionAddr:: dw ; cecf
+
+NEXTU ; cec9
+; Scrolling Menu
+wMenuData_ScrollingMenuHeight:: db ; cec9
+wMenuData_ScrollingMenuWidth:: db ; ceca
+wMenuData_ScrollingMenuItemFormat:: db ; cecb
+wMenuData_ItemsPointerBank:: db ; cecc
+wMenuData_ItemsPointerAddr:: dw ; cecd
+wMenuData_ScrollingMenuFunction1:: ds 3 ; cecf
+wMenuData_ScrollingMenuFunction2:: ds 3 ; ced2
+wMenuData_ScrollingMenuFunction3:: ds 3 ; ced5
+ENDU ; ced8
wMenuDataEnd::
w2DMenuData::
@@ -1919,13 +1933,10 @@ wMenuJoypadFilter:: db ; cedf
w2DMenuDataEnd::
wMenuCursorY:: db ; cee0
wMenuCursorX:: db ; cee1
-wcee2:: ds 1 ; cee2
-wCursorCurrentTile:: ds 1 ; cee3
-wcee4:: ds 1 ; cee4
-wcee5:: ds 1 ; cee5
-wcee6:: ds 1 ; cee6
-wcee7:: ds 1 ; cee7
-wMenuData3End::
+wCursorOffCharacter:: db ; cee2
+wCursorCurrentTile:: dw ; cee3
+
+ ds 3
wOverworldDelay:: ds 1 ; cee8
wTextDelayFrames:: ds 1 ; cee9
@@ -3268,9 +3279,9 @@ wPoisonStepCount:: db ; d9be
ds 2
wHappinessStepCount:: db ; d9c1
ds 1
-wParkBallsRemaining:: db ; d9c3
-wd9c4:: ds 1 ; d9c4
-wd9c5:: ds 1 ; d9c5
+wParkBallsRemaining::
+wSafariBallsRemaining:: db ; d9c3
+wSafariTimeRemaining:: dw ; d9c4
wd9c6:: ds 1 ; d9c6
wd9c7:: ds 1 ; d9c7
wd9c8:: ds 1 ; d9c8