pokered/home/list_menu.asm

526 lines
12 KiB
NASM
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; INPUT:
; [wListMenuID] = list menu ID
; [wListPointer] = address of the list (2 bytes)
DisplayListMenuID::
xor a
ld [hAutoBGTransferEnabled], a ; disable auto-transfer
ld a, 1
ld [hJoy7], a ; joypad state update flag
ld a, [wBattleType]
and a ; is it the Old Man battle?
jr nz, .specialBattleType
ld a, $01 ; hardcoded bank
jr .bankswitch
.specialBattleType ; Old Man battle
ld a, BANK(DisplayBattleMenu)
.bankswitch
call BankswitchHome
ld hl, wd730
set 6, [hl] ; turn off letter printing delay
xor a
ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
ld [wListCount], a
ld a, [wListPointer]
ld l, a
ld a, [wListPointer + 1]
ld h, a ; hl = address of the list
ld a, [hl] ; the first byte is the number of entries in the list
ld [wListCount], a
ld a, LIST_MENU_BOX
ld [wTextBoxID], a
call DisplayTextBoxID ; draw the menu text box
call UpdateSprites ; disable sprites behind the text box
; the code up to .skipMovingSprites appears to be useless
coord hl, 4, 2 ; coordinates of upper left corner of menu text box
lb de, 9, 14 ; height and width of menu text box
ld a, [wListMenuID]
and a ; is it a PC pokemon list?
jr nz, .skipMovingSprites
call UpdateSprites
.skipMovingSprites
ld a, 1 ; max menu item ID is 1 if the list has less than 2 entries
ld [wMenuWatchMovingOutOfBounds], a
ld a, [wListCount]
cp 2 ; does the list have less than 2 entries?
jr c, .setMenuVariables
ld a, 2 ; max menu item ID is 2 if the list has at least 2 entries
.setMenuVariables
ld [wMaxMenuItem], a
ld a, 4
ld [wTopMenuItemY], a
ld a, 5
ld [wTopMenuItemX], a
ld a, A_BUTTON | B_BUTTON | SELECT
ld [wMenuWatchedKeys], a
ld c, 10
call DelayFrames
DisplayListMenuIDLoop::
xor a
ld [hAutoBGTransferEnabled], a ; disable transfer
call PrintListMenuEntries
ld a, 1
ld [hAutoBGTransferEnabled], a ; enable transfer
call Delay3
ld a, [wBattleType]
and a ; is it the Old Man battle?
jr z, .notOldManBattle
.oldManBattle
ld a, "▶"
Coorda 5, 4 ; place menu cursor in front of first menu entry
ld c, 80
call DelayFrames
xor a
ld [wCurrentMenuItem], a
coord hl, 5, 4
ld a, l
ld [wMenuCursorLocation], a
ld a, h
ld [wMenuCursorLocation + 1], a
jr .buttonAPressed
.notOldManBattle
call LoadGBPal
call HandleMenuInput
push af
call PlaceMenuCursor
pop af
bit 0, a ; was the A button pressed?
jp z, .checkOtherKeys
.buttonAPressed
ld a, [wCurrentMenuItem]
call PlaceUnfilledArrowMenuCursor
; pointless because both values are overwritten before they are read
ld a, $01
ld [wMenuExitMethod], a
ld [wChosenMenuItem], a
xor a
ld [wMenuWatchMovingOutOfBounds], a
ld a, [wCurrentMenuItem]
ld c, a
ld a, [wListScrollOffset]
add c
ld c, a
ld a, [wListCount]
and a ; is the list empty?
jp z, ExitListMenu ; if so, exit the menu
dec a
cp c ; did the player select Cancel?
jp c, ExitListMenu ; if so, exit the menu
ld a, c
ld [wWhichPokemon], a
ld a, [wListMenuID]
cp ITEMLISTMENU
jr nz, .skipMultiplying
; if it's an item menu
sla c ; item entries are 2 bytes long, so multiply by 2
.skipMultiplying
ld a, [wListPointer]
ld l, a
ld a, [wListPointer + 1]
ld h, a
inc hl ; hl = beginning of list entries
ld b, 0
add hl, bc
ld a, [hl]
ld [wcf91], a
ld a, [wListMenuID]
and a ; is it a PC pokemon list?
jr z, .pokemonList
push hl
call GetItemPrice
pop hl
ld a, [wListMenuID]
cp ITEMLISTMENU
jr nz, .skipGettingQuantity
; if it's an item menu
inc hl
ld a, [hl] ; a = item quantity
ld [wMaxItemQuantity], a
.skipGettingQuantity
ld a, [wcf91]
ld [wd0b5], a
ld a, BANK(ItemNames)
ld [wPredefBank], a
call GetName
jr .storeChosenEntry
.pokemonList
ld hl, wPartyCount
ld a, [wListPointer]
cp l ; is it a list of party pokemon or box pokemon?
ld hl, wPartyMonNicks
jr z, .getPokemonName
ld hl, wBoxMonNicks ; box pokemon names
.getPokemonName
ld a, [wWhichPokemon]
call GetPartyMonName
.storeChosenEntry ; store the menu entry that the player chose and return
ld de, wcd6d
call CopyStringToCF4B ; copy name to wcf4b
ld a, CHOSE_MENU_ITEM
ld [wMenuExitMethod], a
ld a, [wCurrentMenuItem]
ld [wChosenMenuItem], a
xor a
ld [hJoy7], a ; joypad state update flag
ld hl, wd730
res 6, [hl] ; turn on letter printing delay
jp BankswitchBack
.checkOtherKeys ; check B, SELECT, Up, and Down keys
bit 1, a ; was the B button pressed?
jp nz, ExitListMenu ; if so, exit the menu
bit 2, a ; was the select button pressed?
jp nz, HandleItemListSwapping ; if so, allow the player to swap menu entries
ld b, a
bit 7, b ; was Down pressed?
ld hl, wListScrollOffset
jr z, .upPressed
.downPressed
ld a, [hl]
add 3
ld b, a
ld a, [wListCount]
cp b ; will going down scroll past the Cancel button?
jp c, DisplayListMenuIDLoop
inc [hl] ; if not, go down
jp DisplayListMenuIDLoop
.upPressed
ld a, [hl]
and a
jp z, DisplayListMenuIDLoop
dec [hl]
jp DisplayListMenuIDLoop
DisplayChooseQuantityMenu::
; text box dimensions/coordinates for just quantity
coord hl, 15, 9
ld b, 1 ; height
ld c, 3 ; width
ld a, [wListMenuID]
cp PRICEDITEMLISTMENU
jr nz, .drawTextBox
; text box dimensions/coordinates for quantity and price
coord hl, 7, 9
ld b, 1 ; height
ld c, 11 ; width
.drawTextBox
call TextBoxBorder
coord hl, 16, 10
ld a, [wListMenuID]
cp PRICEDITEMLISTMENU
jr nz, .printInitialQuantity
coord hl, 8, 10
.printInitialQuantity
ld de, InitialQuantityText
call PlaceString
xor a
ld [wItemQuantity], a ; initialize current quantity to 0
jp .incrementQuantity
.waitForKeyPressLoop
call JoypadLowSensitivity
ld a, [hJoyPressed] ; newly pressed buttons
bit 0, a ; was the A button pressed?
jp nz, .buttonAPressed
bit 1, a ; was the B button pressed?
jp nz, .buttonBPressed
bit 6, a ; was Up pressed?
jr nz, .incrementQuantity
bit 7, a ; was Down pressed?
jr nz, .decrementQuantity
jr .waitForKeyPressLoop
.incrementQuantity
ld a, [wMaxItemQuantity]
inc a
ld b, a
ld hl, wItemQuantity ; current quantity
inc [hl]
ld a, [hl]
cp b
jr nz, .handleNewQuantity
; wrap to 1 if the player goes above the max quantity
ld a, 1
ld [hl], a
jr .handleNewQuantity
.decrementQuantity
ld hl, wItemQuantity ; current quantity
dec [hl]
jr nz, .handleNewQuantity
; wrap to the max quantity if the player goes below 1
ld a, [wMaxItemQuantity]
ld [hl], a
.handleNewQuantity
coord hl, 17, 10
ld a, [wListMenuID]
cp PRICEDITEMLISTMENU
jr nz, .printQuantity
.printPrice
ld c, $03
ld a, [wItemQuantity]
ld b, a
ld hl, hMoney ; total price
; initialize total price to 0
xor a
ld [hli], a
ld [hli], a
ld [hl], a
.addLoop ; loop to multiply the individual price by the quantity to get the total price
ld de, hMoney + 2
ld hl, hItemPrice + 2
push bc
predef AddBCDPredef ; add the individual price to the current sum
pop bc
dec b
jr nz, .addLoop
ld a, [hHalveItemPrices]
and a ; should the price be halved (for selling items)?
jr z, .skipHalvingPrice
xor a
ld [hDivideBCDDivisor], a
ld [hDivideBCDDivisor + 1], a
ld a, $02
ld [hDivideBCDDivisor + 2], a
predef DivideBCDPredef3 ; halves the price
; store the halved price
ld a, [hDivideBCDQuotient]
ld [hMoney], a
ld a, [hDivideBCDQuotient + 1]
ld [hMoney + 1], a
ld a, [hDivideBCDQuotient + 2]
ld [hMoney + 2], a
.skipHalvingPrice
coord hl, 12, 10
ld de, SpacesBetweenQuantityAndPriceText
call PlaceString
ld de, hMoney ; total price
ld c, $a3
call PrintBCDNumber
coord hl, 9, 10
.printQuantity
ld de, wItemQuantity ; current quantity
lb bc, LEADING_ZEROES | 1, 2 ; 1 byte, 2 digits
call PrintNumber
jp .waitForKeyPressLoop
.buttonAPressed ; the player chose to make the transaction
xor a
ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
ret
.buttonBPressed ; the player chose to cancel the transaction
xor a
ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
ld a, $ff
ret
InitialQuantityText::
db "×01@"
SpacesBetweenQuantityAndPriceText::
db " @"
ExitListMenu::
ld a, [wCurrentMenuItem]
ld [wChosenMenuItem], a
ld a, CANCELLED_MENU
ld [wMenuExitMethod], a
ld [wMenuWatchMovingOutOfBounds], a
xor a
ld [hJoy7], a
ld hl, wd730
res 6, [hl]
call BankswitchBack
xor a
ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
scf
ret
PrintListMenuEntries::
coord hl, 5, 3
ld b, 9
ld c, 14
call ClearScreenArea
ld a, [wListPointer]
ld e, a
ld a, [wListPointer + 1]
ld d, a
inc de ; de = beginning of list entries
ld a, [wListScrollOffset]
ld c, a
ld a, [wListMenuID]
cp ITEMLISTMENU
ld a, c
jr nz, .skipMultiplying
; if it's an item menu
; item entries are 2 bytes long, so multiply by 2
sla a
sla c
.skipMultiplying
add e
ld e, a
jr nc, .noCarry
inc d
.noCarry
coord hl, 6, 4 ; coordinates of first list entry name
ld b, 4 ; print 4 names
.loop
ld a, b
ld [wWhichPokemon], a
ld a, [de]
ld [wd11e], a
cp $ff
jp z, .printCancelMenuItem
push bc
push de
push hl
push hl
push de
ld a, [wListMenuID]
and a
jr z, .pokemonPCMenu
cp MOVESLISTMENU
jr z, .movesMenu
.itemMenu
call GetItemName
jr .placeNameString
.pokemonPCMenu
push hl
ld hl, wPartyCount
ld a, [wListPointer]
cp l ; is it a list of party pokemon or box pokemon?
ld hl, wPartyMonNicks
jr z, .getPokemonName
ld hl, wBoxMonNicks ; box pokemon names
.getPokemonName
ld a, [wWhichPokemon]
ld b, a
ld a, 4
sub b
ld b, a
ld a, [wListScrollOffset]
add b
call GetPartyMonName
pop hl
jr .placeNameString
.movesMenu
call GetMoveName
.placeNameString
call PlaceString
pop de
pop hl
ld a, [wPrintItemPrices]
and a ; should prices be printed?
jr z, .skipPrintingItemPrice
.printItemPrice
push hl
ld a, [de]
ld de, ItemPrices
ld [wcf91], a
call GetItemPrice ; get price
pop hl
ld bc, SCREEN_WIDTH + 5 ; 1 row down and 5 columns right
add hl, bc
ld c, $a3 ; no leading zeroes, right-aligned, print currency symbol, 3 bytes
call PrintBCDNumber
.skipPrintingItemPrice
ld a, [wListMenuID]
and a
jr nz, .skipPrintingPokemonLevel
.printPokemonLevel
ld a, [wd11e]
push af
push hl
ld hl, wPartyCount
ld a, [wListPointer]
cp l ; is it a list of party pokemon or box pokemon?
ld a, PLAYER_PARTY_DATA
jr z, .next
ld a, BOX_DATA
.next
ld [wMonDataLocation], a
ld hl, wWhichPokemon
ld a, [hl]
ld b, a
ld a, $04
sub b
ld b, a
ld a, [wListScrollOffset]
add b
ld [hl], a
call LoadMonData
ld a, [wMonDataLocation]
and a ; is it a list of party pokemon or box pokemon?
jr z, .skipCopyingLevel
.copyLevel
ld a, [wLoadedMonBoxLevel]
ld [wLoadedMonLevel], a
.skipCopyingLevel
pop hl
ld bc, $1c
add hl, bc
call PrintLevel
pop af
ld [wd11e], a
.skipPrintingPokemonLevel
pop hl
pop de
inc de
ld a, [wListMenuID]
cp ITEMLISTMENU
jr nz, .nextListEntry
.printItemQuantity
ld a, [wd11e]
ld [wcf91], a
call IsKeyItem ; check if item is unsellable
ld a, [wIsKeyItem]
and a ; is the item unsellable?
jr nz, .skipPrintingItemQuantity ; if so, don't print the quantity
push hl
ld bc, SCREEN_WIDTH + 8 ; 1 row down and 8 columns right
add hl, bc
ld a, "×"
ld [hli], a
ld a, [wd11e]
push af
ld a, [de]
ld [wMaxItemQuantity], a
push de
ld de, wd11e
ld [de], a
lb bc, 1, 2
call PrintNumber
pop de
pop af
ld [wd11e], a
pop hl
.skipPrintingItemQuantity
inc de
pop bc
inc c
push bc
inc c
ld a, [wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
and a ; is an item being swapped?
jr z, .nextListEntry
sla a
cp c ; is it this item?
jr nz, .nextListEntry
dec hl
ld a, $ec ; unfilled right arrow menu cursor to indicate an item being swapped
ld [hli], a
.nextListEntry
ld bc, 2 * SCREEN_WIDTH ; 2 rows
add hl, bc
pop bc
inc c
dec b
jp nz, .loop
ld bc, -8
add hl, bc
ld a, "▼"
ld [hl], a
ret
.printCancelMenuItem
ld de, ListMenuCancelText
jp PlaceString
ListMenuCancelText::
db "CANCEL@"