mirror of
https://github.com/pret/pokered.git
synced 2024-10-22 22:55:31 +00:00
526 lines
11 KiB
NASM
526 lines
11 KiB
NASM
; INPUT:
|
||
; [wListMenuID] = list menu ID
|
||
; [wListPointer] = address of the list (2 bytes)
|
||
DisplayListMenuID::
|
||
xor a
|
||
ldh [hAutoBGTransferEnabled], a ; disable auto-transfer
|
||
ld a, 1
|
||
ldh [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
|
||
hlcoord 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 ; PCPOKEMONLISTMENU?
|
||
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
|
||
ldh [hAutoBGTransferEnabled], a ; disable transfer
|
||
call PrintListMenuEntries
|
||
ld a, 1
|
||
ldh [hAutoBGTransferEnabled], a ; enable transfer
|
||
call Delay3
|
||
ld a, [wBattleType]
|
||
and a ; is it the Old Man battle?
|
||
jr z, .notOldManBattle
|
||
.oldManBattle
|
||
ld a, "▶"
|
||
ldcoord_a 5, 4 ; place menu cursor in front of first menu entry
|
||
ld c, 80
|
||
call DelayFrames
|
||
xor a
|
||
ld [wCurrentMenuItem], a
|
||
hlcoord 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 ; PCPOKEMONLISTMENU?
|
||
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
|
||
ldh [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
|
||
hlcoord 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
|
||
hlcoord 7, 9
|
||
ld b, 1 ; height
|
||
ld c, 11 ; width
|
||
.drawTextBox
|
||
call TextBoxBorder
|
||
hlcoord 16, 10
|
||
ld a, [wListMenuID]
|
||
cp PRICEDITEMLISTMENU
|
||
jr nz, .printInitialQuantity
|
||
hlcoord 8, 10
|
||
.printInitialQuantity
|
||
ld de, InitialQuantityText
|
||
call PlaceString
|
||
xor a
|
||
ld [wItemQuantity], a ; initialize current quantity to 0
|
||
jp .incrementQuantity
|
||
.waitForKeyPressLoop
|
||
call JoypadLowSensitivity
|
||
ldh 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
|
||
hlcoord 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
|
||
ldh a, [hHalveItemPrices]
|
||
and a ; should the price be halved (for selling items)?
|
||
jr z, .skipHalvingPrice
|
||
xor a
|
||
ldh [hDivideBCDDivisor], a
|
||
ldh [hDivideBCDDivisor + 1], a
|
||
ld a, $02
|
||
ldh [hDivideBCDDivisor + 2], a
|
||
predef DivideBCDPredef3 ; halves the price
|
||
; store the halved price
|
||
ldh a, [hDivideBCDQuotient]
|
||
ldh [hMoney], a
|
||
ldh a, [hDivideBCDQuotient + 1]
|
||
ldh [hMoney + 1], a
|
||
ldh a, [hDivideBCDQuotient + 2]
|
||
ldh [hMoney + 2], a
|
||
.skipHalvingPrice
|
||
hlcoord 12, 10
|
||
ld de, SpacesBetweenQuantityAndPriceText
|
||
call PlaceString
|
||
ld de, hMoney ; total price
|
||
ld c, $a3
|
||
call PrintBCDNumber
|
||
hlcoord 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
|
||
ldh [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::
|
||
hlcoord 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
|
||
hlcoord 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 ; PCPOKEMONLISTMENU?
|
||
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 ; PCPOKEMONLISTMENU?
|
||
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, "▷"
|
||
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@"
|