123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768 |
- ; function to draw various text boxes
- DisplayTextBoxID_:
- ld a, [wTextBoxID]
- cp TWO_OPTION_MENU
- jp z, DisplayTwoOptionMenu
- ld c, a
- ld hl, TextBoxFunctionTable
- ld de, 3
- call SearchTextBoxTable
- jr c, .functionTableMatch
- ld hl, TextBoxCoordTable
- ld de, 5
- call SearchTextBoxTable
- jr c, .coordTableMatch
- ld hl, TextBoxTextAndCoordTable
- ld de, 9
- call SearchTextBoxTable
- jr c, .textAndCoordTableMatch
- .done
- ret
- .functionTableMatch
- ld a, [hli]
- ld h, [hl]
- ld l, a ; hl = address of function
- ld de, .done
- push de
- jp hl ; jump to the function
- .coordTableMatch
- call GetTextBoxIDCoords
- call GetAddressOfScreenCoords
- call TextBoxBorder
- ret
- .textAndCoordTableMatch
- call GetTextBoxIDCoords
- push hl
- call GetAddressOfScreenCoords
- call TextBoxBorder
- pop hl
- call GetTextBoxIDText
- ld a, [wd730]
- push af
- ld a, [wd730]
- set 6, a ; no pauses between printing each letter
- ld [wd730], a
- call PlaceString
- pop af
- ld [wd730], a
- call UpdateSprites
- ret
- ; function to search a table terminated with $ff for a byte matching c in increments of de
- ; sets carry flag if a match is found and clears carry flag if not
- SearchTextBoxTable:
- dec de
- .loop
- ld a, [hli]
- cp $ff
- jr z, .notFound
- cp c
- jr z, .found
- add hl, de
- jr .loop
- .found
- scf
- .notFound
- ret
- ; function to load coordinates from the TextBoxCoordTable or the TextBoxTextAndCoordTable
- ; INPUT:
- ; hl = address of coordinates
- ; OUTPUT:
- ; b = height
- ; c = width
- ; d = row of upper left corner
- ; e = column of upper left corner
- GetTextBoxIDCoords:
- ld a, [hli] ; column of upper left corner
- ld e, a
- ld a, [hli] ; row of upper left corner
- ld d, a
- ld a, [hli] ; column of lower right corner
- sub e
- dec a
- ld c, a ; c = width
- ld a, [hli] ; row of lower right corner
- sub d
- dec a
- ld b, a ; b = height
- ret
- ; function to load a text address and text coordinates from the TextBoxTextAndCoordTable
- GetTextBoxIDText:
- ld a, [hli]
- ld e, a
- ld a, [hli]
- ld d, a ; de = address of text
- push de ; save text address
- ld a, [hli]
- ld e, a ; column of upper left corner of text
- ld a, [hl]
- ld d, a ; row of upper left corner of text
- call GetAddressOfScreenCoords
- pop de ; restore text address
- ret
- ; function to point hl to the screen coordinates
- ; INPUT:
- ; d = row
- ; e = column
- ; OUTPUT:
- ; hl = address of upper left corner of text box
- GetAddressOfScreenCoords:
- push bc
- coord hl, 0, 0
- ld bc, 20
- .loop ; loop to add d rows to the base address
- ld a, d
- and a
- jr z, .addedRows
- add hl, bc
- dec d
- jr .loop
- .addedRows
- pop bc
- add hl, de
- ret
- ; Format:
- ; 00: text box ID
- ; 01-02: function address
- TextBoxFunctionTable:
- dbw MONEY_BOX, DisplayMoneyBox
- dbw BUY_SELL_QUIT_MENU, DoBuySellQuitMenu
- dbw FIELD_MOVE_MON_MENU, DisplayFieldMoveMonMenu
- db $ff ; terminator
- ; Format:
- ; 00: text box ID
- ; 01: column of upper left corner
- ; 02: row of upper left corner
- ; 03: column of lower right corner
- ; 04: row of lower right corner
- TextBoxCoordTable:
- db MESSAGE_BOX, 0, 12, 19, 17
- db $03, 0, 0, 19, 14
- db $07, 0, 0, 11, 6
- db LIST_MENU_BOX, 4, 2, 19, 12
- db $10, 7, 0, 19, 17
- db MON_SPRITE_POPUP, 6, 4, 14, 13
- db $ff ; terminator
- ; Format:
- ; 00: text box ID
- ; 01: column of upper left corner
- ; 02: row of upper left corner
- ; 03: column of lower right corner
- ; 04: row of lower right corner
- ; 05-06: address of text
- ; 07: column of beginning of text
- ; 08: row of beginning of text
- ; table of window positions and corresponding text [key, start column, start row, end column, end row, text pointer [2 bytes], text column, text row]
- TextBoxTextAndCoordTable:
- db JP_MOCHIMONO_MENU_TEMPLATE
- db 0,0,14,17 ; text box coordinates
- dw JapaneseMochimonoText
- db 3,0 ; text coordinates
- db USE_TOSS_MENU_TEMPLATE
- db 13,10,19,14 ; text box coordinates
- dw UseTossText
- db 15,11 ; text coordinates
- db JP_SAVE_MESSAGE_MENU_TEMPLATE
- db 0,0,7,5 ; text box coordinates
- dw JapaneseSaveMessageText
- db 2,2 ; text coordinates
- db JP_SPEED_OPTIONS_MENU_TEMPLATE
- db 0,6,5,10 ; text box coordinates
- dw JapaneseSpeedOptionsText
- db 2,7 ; text coordinates
- db BATTLE_MENU_TEMPLATE
- db 8,12,19,17 ; text box coordinates
- dw BattleMenuText
- db 10,14 ; text coordinates
- db SAFARI_BATTLE_MENU_TEMPLATE
- db 0,12,19,17 ; text box coordinates
- dw SafariZoneBattleMenuText
- db 2,14 ; text coordinates
- db SWITCH_STATS_CANCEL_MENU_TEMPLATE
- db 11,11,19,17 ; text box coordinates
- dw SwitchStatsCancelText
- db 13,12 ; text coordinates
- db BUY_SELL_QUIT_MENU_TEMPLATE
- db 0,0,10,6 ; text box coordinates
- dw BuySellQuitText
- db 2,1 ; text coordinates
- db MONEY_BOX_TEMPLATE
- db 11,0,19,2 ; text box coordinates
- dw MoneyText
- db 13,0 ; text coordinates
- db JP_AH_MENU_TEMPLATE
- db 7,6,11,10 ; text box coordinates
- dw JapaneseAhText
- db 8,8 ; text coordinates
- db JP_POKEDEX_MENU_TEMPLATE
- db 11,8,19,17 ; text box coordinates
- dw JapanesePokedexMenu
- db 12,10 ; text coordinates
- ; note that there is no terminator
- BuySellQuitText:
- db "BUY"
- next "SELL"
- next "QUIT@@"
- UseTossText:
- db "USE"
- next "TOSS@"
- JapaneseSaveMessageText:
- db "きろく"
- next "メッセージ@"
- JapaneseSpeedOptionsText:
- db "はやい"
- next "おそい@"
- MoneyText:
- db "MONEY@"
- JapaneseMochimonoText:
- db "もちもの@"
- JapaneseMainMenuText:
- db "つづきから"
- next "さいしょから@"
- BattleMenuText:
- db "FIGHT ",$E1,$E2
- next "ITEM RUN@"
- SafariZoneBattleMenuText:
- db "BALL× BAIT"
- next "THROW ROCK RUN@"
- SwitchStatsCancelText:
- db "SWITCH"
- next "STATS"
- next "CANCEL@"
- JapaneseAhText:
- db "アッ!@"
- JapanesePokedexMenu:
- db "データをみる"
- next "なきごえ"
- next "ぶんぷをみる"
- next "キャンセル@"
- DisplayMoneyBox:
- ld hl, wd730
- set 6, [hl]
- ld a, MONEY_BOX_TEMPLATE
- ld [wTextBoxID], a
- call DisplayTextBoxID
- coord hl, 13, 1
- ld b, 1
- ld c, 6
- call ClearScreenArea
- coord hl, 12, 1
- ld de, wPlayerMoney
- ld c, $a3
- call PrintBCDNumber
- ld hl, wd730
- res 6, [hl]
- ret
- CurrencyString:
- db " ¥@"
- DoBuySellQuitMenu:
- ld a, [wd730]
- set 6, a ; no printing delay
- ld [wd730], a
- xor a
- ld [wChosenMenuItem], a
- ld a, BUY_SELL_QUIT_MENU_TEMPLATE
- ld [wTextBoxID], a
- call DisplayTextBoxID
- ld a, A_BUTTON | B_BUTTON
- ld [wMenuWatchedKeys], a
- ld a, $2
- ld [wMaxMenuItem], a
- ld a, $1
- ld [wTopMenuItemY], a
- ld a, $1
- ld [wTopMenuItemX], a
- xor a
- ld [wCurrentMenuItem], a
- ld [wLastMenuItem], a
- ld [wMenuWatchMovingOutOfBounds], a
- ld a, [wd730]
- res 6, a ; turn on the printing delay
- ld [wd730], a
- call HandleMenuInput
- call PlaceUnfilledArrowMenuCursor
- bit 0, a ; was A pressed?
- jr nz, .pressedA
- bit 1, a ; was B pressed? (always true since only A/B are watched)
- jr z, .pressedA
- ld a, CANCELLED_MENU
- ld [wMenuExitMethod], a
- jr .quit
- .pressedA
- ld a, CHOSE_MENU_ITEM
- ld [wMenuExitMethod], a
- ld a, [wCurrentMenuItem]
- ld [wChosenMenuItem], a
- ld b, a
- ld a, [wMaxMenuItem]
- cp b
- jr z, .quit
- ret
- .quit
- ld a, CANCELLED_MENU
- ld [wMenuExitMethod], a
- ld a, [wCurrentMenuItem]
- ld [wChosenMenuItem], a
- scf
- ret
- ; displays a menu with two options to choose from
- ; b = Y of upper left corner of text region
- ; c = X of upper left corner of text region
- ; hl = address where the text box border should be drawn
- DisplayTwoOptionMenu:
- push hl
- ld a, [wd730]
- set 6, a ; no printing delay
- ld [wd730], a
- ; pointless because both values are overwritten before they are read
- xor a
- ld [wChosenMenuItem], a
- ld [wMenuExitMethod], a
- ld a, A_BUTTON | B_BUTTON
- ld [wMenuWatchedKeys], a
- ld a, $1
- ld [wMaxMenuItem], a
- ld a, b
- ld [wTopMenuItemY], a
- ld a, c
- ld [wTopMenuItemX], a
- xor a
- ld [wLastMenuItem], a
- ld [wMenuWatchMovingOutOfBounds], a
- push hl
- ld hl, wTwoOptionMenuID
- bit 7, [hl] ; select second menu item by default?
- res 7, [hl]
- jr z, .storeCurrentMenuItem
- inc a
- .storeCurrentMenuItem
- ld [wCurrentMenuItem], a
- pop hl
- push hl
- push hl
- call TwoOptionMenu_SaveScreenTiles
- ld a, [wTwoOptionMenuID]
- ld hl, TwoOptionMenuStrings
- ld e, a
- ld d, $0
- ld a, $5
- .menuStringLoop
- add hl, de
- dec a
- jr nz, .menuStringLoop
- ld a, [hli]
- ld c, a
- ld a, [hli]
- ld b, a
- ld e, l
- ld d, h
- pop hl
- push de
- ld a, [wTwoOptionMenuID]
- cp TRADE_CANCEL_MENU
- jr nz, .notTradeCancelMenu
- call CableClub_TextBoxBorder
- jr .afterTextBoxBorder
- .notTradeCancelMenu
- call TextBoxBorder
- .afterTextBoxBorder
- call UpdateSprites
- pop hl
- ld a, [hli]
- and a ; put blank line before first menu item?
- ld bc, 20 + 2
- jr z, .noBlankLine
- ld bc, 2 * 20 + 2
- .noBlankLine
- ld a, [hli]
- ld e, a
- ld a, [hli]
- ld d, a
- pop hl
- add hl, bc
- call PlaceString
- ld hl, wd730
- res 6, [hl] ; turn on the printing delay
- ld a, [wTwoOptionMenuID]
- cp NO_YES_MENU
- jr nz, .notNoYesMenu
- ; No/Yes menu
- ; this menu type ignores the B button
- ; it only seems to be used when confirming the deletion of a save file
- xor a
- ld [wTwoOptionMenuID], a
- ld a, [wFlags_0xcd60]
- push af
- push hl
- ld hl, wFlags_0xcd60
- bit 5, [hl]
- set 5, [hl] ; don't play sound when A or B is pressed in menu
- pop hl
- .noYesMenuInputLoop
- call HandleMenuInput
- bit 1, a ; A button pressed?
- jr nz, .noYesMenuInputLoop ; try again if A was not pressed
- pop af
- pop hl
- ld [wFlags_0xcd60], a
- ld a, SFX_PRESS_AB
- call PlaySound
- jr .pressedAButton
- .notNoYesMenu
- xor a
- ld [wTwoOptionMenuID], a
- call HandleMenuInput
- pop hl
- bit 1, a ; A button pressed?
- jr nz, .choseSecondMenuItem ; automatically choose the second option if B is pressed
- .pressedAButton
- ld a, [wCurrentMenuItem]
- ld [wChosenMenuItem], a
- and a
- jr nz, .choseSecondMenuItem
- ; chose first menu item
- ld a, CHOSE_FIRST_ITEM
- ld [wMenuExitMethod], a
- ld c, 15
- call DelayFrames
- call TwoOptionMenu_RestoreScreenTiles
- and a
- ret
- .choseSecondMenuItem
- ld a, 1
- ld [wCurrentMenuItem], a
- ld [wChosenMenuItem], a
- ld a, CHOSE_SECOND_ITEM
- ld [wMenuExitMethod], a
- ld c, 15
- call DelayFrames
- call TwoOptionMenu_RestoreScreenTiles
- scf
- ret
- ; Some of the wider/taller two option menus will not have the screen areas
- ; they cover be fully saved/restored by the two functions below.
- ; The bottom and right edges of the menu may remain after the function returns.
- TwoOptionMenu_SaveScreenTiles:
- ld de, wBuffer
- lb bc, 5, 6
- .loop
- ld a, [hli]
- ld [de], a
- inc de
- dec c
- jr nz, .loop
- push bc
- ld bc, SCREEN_WIDTH - 6
- add hl, bc
- pop bc
- ld c, $6
- dec b
- jr nz, .loop
- ret
- TwoOptionMenu_RestoreScreenTiles:
- ld de, wBuffer
- lb bc, 5, 6
- .loop
- ld a, [de]
- inc de
- ld [hli], a
- dec c
- jr nz, .loop
- push bc
- ld bc, SCREEN_WIDTH - 6
- add hl, bc
- pop bc
- ld c, 6
- dec b
- jr nz, .loop
- call UpdateSprites
- ret
- ; Format:
- ; 00: byte width
- ; 01: byte height
- ; 02: byte put blank line before first menu item
- ; 03: word text pointer
- TwoOptionMenuStrings:
- db 4,3,0
- dw .YesNoMenu
- db 6,3,0
- dw .NorthWestMenu
- db 6,3,0
- dw .SouthEastMenu
- db 6,3,0
- dw .YesNoMenu
- db 6,3,0
- dw .NorthEastMenu
- db 7,3,0
- dw .TradeCancelMenu
- db 7,4,1
- dw .HealCancelMenu
- db 4,3,0
- dw .NoYesMenu
- .NoYesMenu
- db "NO"
- next "YES@"
- .YesNoMenu
- db "YES"
- next "NO@"
- .NorthWestMenu
- db "NORTH"
- next "WEST@"
- .SouthEastMenu
- db "SOUTH"
- next "EAST@"
- .NorthEastMenu
- db "NORTH"
- next "EAST@"
- .TradeCancelMenu
- db "TRADE"
- next "CANCEL@"
- .HealCancelMenu
- db "HEAL"
- next "CANCEL@"
- DisplayFieldMoveMonMenu:
- xor a
- ld hl, wFieldMoves
- ld [hli], a ; wFieldMoves
- ld [hli], a ; wFieldMoves + 1
- ld [hli], a ; wFieldMoves + 2
- ld [hli], a ; wFieldMoves + 3
- ld [hli], a ; wNumFieldMoves
- ld [hl], 12 ; wFieldMovesLeftmostXCoord
- call GetMonFieldMoves
- ld a, [wNumFieldMoves]
- and a
- jr nz, .fieldMovesExist
- ; no field moves
- coord hl, 11, 11
- ld b, 5
- ld c, 7
- call TextBoxBorder
- call UpdateSprites
- ld a, 12
- ld [hFieldMoveMonMenuTopMenuItemX], a
- coord hl, 13, 12
- ld de, PokemonMenuEntries
- jp PlaceString
- .fieldMovesExist
- push af
- ; Calculate the text box position and dimensions based on the leftmost X coord
- ; of the field move names before adjusting for the number of field moves.
- coord hl, 0, 11
- ld a, [wFieldMovesLeftmostXCoord]
- dec a
- ld e, a
- ld d, 0
- add hl, de
- ld b, 5
- ld a, 18
- sub e
- ld c, a
- pop af
- ; For each field move, move the top of the text box up 2 rows while the leaving
- ; the bottom of the text box at the bottom of the screen.
- ld de, -SCREEN_WIDTH * 2
- .textBoxHeightLoop
- add hl, de
- inc b
- inc b
- dec a
- jr nz, .textBoxHeightLoop
- ; Make space for an extra blank row above the top field move.
- ld de, -SCREEN_WIDTH
- add hl, de
- inc b
- call TextBoxBorder
- call UpdateSprites
- ; Calculate the position of the first field move name to print.
- coord hl, 0, 12
- ld a, [wFieldMovesLeftmostXCoord]
- inc a
- ld e, a
- ld d, 0
- add hl, de
- ld de, -SCREEN_WIDTH * 2
- ld a, [wNumFieldMoves]
- .calcFirstFieldMoveYLoop
- add hl, de
- dec a
- jr nz, .calcFirstFieldMoveYLoop
- xor a
- ld [wNumFieldMoves], a
- ld de, wFieldMoves
- .printNamesLoop
- push hl
- ld hl, FieldMoveNames
- ld a, [de]
- and a
- jr z, .donePrintingNames
- inc de
- ld b, a ; index of name
- .skipNamesLoop ; skip past names before the name we want
- dec b
- jr z, .reachedName
- .skipNameLoop ; skip past current name
- ld a, [hli]
- cp "@"
- jr nz, .skipNameLoop
- jr .skipNamesLoop
- .reachedName
- ld b, h
- ld c, l
- pop hl
- push de
- ld d, b
- ld e, c
- call PlaceString
- ld bc, SCREEN_WIDTH * 2
- add hl, bc
- pop de
- jr .printNamesLoop
- .donePrintingNames
- pop hl
- ld a, [wFieldMovesLeftmostXCoord]
- ld [hFieldMoveMonMenuTopMenuItemX], a
- coord hl, 0, 12
- ld a, [wFieldMovesLeftmostXCoord]
- inc a
- ld e, a
- ld d, 0
- add hl, de
- ld de, PokemonMenuEntries
- jp PlaceString
- FieldMoveNames:
- db "CUT@"
- db "FLY@"
- db "@"
- db "SURF@"
- db "STRENGTH@"
- db "FLASH@"
- db "DIG@"
- db "TELEPORT@"
- db "SOFTBOILED@"
- PokemonMenuEntries:
- db "STATS"
- next "SWITCH"
- next "CANCEL@"
- GetMonFieldMoves:
- ld a, [wWhichPokemon]
- ld hl, wPartyMon1Moves
- ld bc, wPartyMon2 - wPartyMon1
- call AddNTimes
- ld d, h
- ld e, l
- ld c, NUM_MOVES + 1
- ld hl, wFieldMoves
- .loop
- push hl
- .nextMove
- dec c
- jr z, .done
- ld a, [de] ; move ID
- and a
- jr z, .done
- ld b, a
- inc de
- ld hl, FieldMoveDisplayData
- .fieldMoveLoop
- ld a, [hli]
- cp $ff
- jr z, .nextMove ; if the move is not a field move
- cp b
- jr z, .foundFieldMove
- inc hl
- inc hl
- jr .fieldMoveLoop
- .foundFieldMove
- ld a, b
- ld [wLastFieldMoveID], a
- ld a, [hli] ; field move name index
- ld b, [hl] ; field move leftmost X coordinate
- pop hl
- ld [hli], a ; store name index in wFieldMoves
- ld a, [wNumFieldMoves]
- inc a
- ld [wNumFieldMoves], a
- ld a, [wFieldMovesLeftmostXCoord]
- cp b
- jr c, .skipUpdatingLeftmostXCoord
- ld a, b
- ld [wFieldMovesLeftmostXCoord], a
- .skipUpdatingLeftmostXCoord
- ld a, [wLastFieldMoveID]
- ld b, a
- jr .loop
- .done
- pop hl
- ret
- ; Format: [Move id], [name index], [leftmost tile]
- ; Move id = id of move
- ; Name index = index of name in FieldMoveNames
- ; Leftmost tile = -1 + tile column in which the first letter of the move's name should be displayed
- ; "SOFTBOILED" is $08 because it has 4 more letters than "SURF", for example, whose value is $0C
- FieldMoveDisplayData:
- db CUT, $01, $0C
- db FLY, $02, $0C
- db $B4, $03, $0C ; unused field move
- db SURF, $04, $0C
- db STRENGTH, $05, $0A
- db FLASH, $06, $0C
- db DIG, $07, $0C
- db TELEPORT, $08, $0A
- db SOFTBOILED, $09, $08
- db $ff ; list terminator
|