First Commit

Upload literally everything from the pokecrystal16 expand-move-ID branch
This commit is contained in:
Zeta_Null 2023-09-10 12:35:35 -04:00
commit 2f8a41f833
4618 changed files with 480386 additions and 0 deletions

View file

@ -0,0 +1,35 @@
_DeleteSaveData:
farcall BlankScreen
ld b, SCGB_DIPLOMA
call GetSGBLayout
call LoadStandardFont
call LoadFontsExtra
ld de, MUSIC_MAIN_MENU
call PlayMusic
ld hl, .ClearAllSaveDataText
call PrintText
ld hl, .NoYesMenuHeader
call CopyMenuHeader
call VerticalMenu
ret c
ld a, [wMenuCursorY]
cp 1
ret z
farcall EmptyAllSRAMBanks
ret
.ClearAllSaveDataText:
text_far _ClearAllSaveDataText
text_end
.NoYesMenuHeader:
db 0 ; flags
menu_coords 14, 7, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
dw .MenuData
db 1 ; default option
.MenuData:
db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags
db 2 ; items
db "NO@"
db "YES@"

View file

@ -0,0 +1,15 @@
EmptyAllSRAMBanks:
for x, NUM_SRAM_BANKS
ld a, x
call .EmptyBank
endr
ret
.EmptyBank:
call OpenSRAM
ld hl, SRAM_Begin
ld bc, SRAM_End - SRAM_Begin
xor a
call ByteFill
call CloseSRAM
ret

View file

@ -0,0 +1,101 @@
InitCrystalData:
ld a, $1
ld [wd474], a
xor a
ld [wd473], a
ld [wPlayerGender], a
ld [wd475], a
ld [wd476], a
ld [wd477], a
ld [wd478], a
ld [wd002], a
ld [wd003], a
ld a, [wd479]
res 0, a ; ???
ld [wd479], a
ld a, [wd479]
res 1, a ; ???
ld [wd479], a
ret
INCLUDE "mobile/mobile_12.asm"
InitGender:
call InitGenderScreen
call LoadGenderScreenPal
call LoadGenderScreenLightBlueTile
call WaitBGMap2
call SetPalettes
ld hl, AreYouABoyOrAreYouAGirlText
call PrintText
ld hl, .MenuHeader
call LoadMenuHeader
call WaitBGMap2
call VerticalMenu
call CloseWindow
ld a, [wMenuCursorY]
dec a
ld [wPlayerGender], a
ld c, 10
call DelayFrames
ret
.MenuHeader:
db MENU_BACKUP_TILES ; flags
menu_coords 6, 4, 12, 9
dw .MenuData
db 1 ; default option
.MenuData:
db STATICMENU_CURSOR | STATICMENU_WRAP | STATICMENU_DISABLE_B ; flags
db 2 ; items
db "Boy@"
db "Girl@"
AreYouABoyOrAreYouAGirlText:
text_far _AreYouABoyOrAreYouAGirlText
text_end
InitGenderScreen:
ld a, $10
ld [wMusicFade], a
ld a, LOW(MUSIC_NONE)
ld [wMusicFadeID], a
ld a, HIGH(MUSIC_NONE)
ld [wMusicFadeID + 1], a
ld c, 8
call DelayFrames
call ClearBGPalettes
call InitCrystalData
call LoadFontsExtra
hlcoord 0, 0
ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
ld a, $0
call ByteFill
hlcoord 0, 0, wAttrmap
ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
xor a
call ByteFill
ret
LoadGenderScreenPal:
ld hl, .Palette
ld de, wBGPals1
ld bc, 1 palettes
ld a, BANK(wBGPals1)
call FarCopyWRAM
farcall ApplyPals
ret
.Palette:
INCLUDE "gfx/new_game/gender_screen.pal"
LoadGenderScreenLightBlueTile:
ld de, .LightBlueTile
ld hl, vTiles2 tile $00
lb bc, BANK(.LightBlueTile), 1
call Get2bpp
ret
.LightBlueTile:
INCBIN "gfx/new_game/gender_screen.2bpp"

1385
engine/menus/intro_menu.asm Normal file

File diff suppressed because it is too large Load diff

384
engine/menus/main_menu.asm Normal file
View file

@ -0,0 +1,384 @@
; MainMenuItems indexes
const_def
const MAINMENU_NEW_GAME ; 0
const MAINMENU_CONTINUE ; 1
const MAINMENU_MOBILE_MYSTERY ; 2
const MAINMENU_MOBILE ; 3
const MAINMENU_MOBILE_STUDIUM ; 4
const MAINMENU_MYSTERY_MOBILE_STUDIUM ; 5
const MAINMENU_MYSTERY ; 6
const MAINMENU_MYSTERY_STUDIUM ; 7
const MAINMENU_STUDIUM ; 8
; MainMenu.Strings and MainMenu.Jumptable indexes
const_def
const MAINMENUITEM_CONTINUE ; 0
const MAINMENUITEM_NEW_GAME ; 1
const MAINMENUITEM_OPTION ; 2
const MAINMENUITEM_MYSTERY_GIFT ; 3
const MAINMENUITEM_MOBILE ; 4
const MAINMENUITEM_MOBILE_STUDIUM ; 5
const MAINMENUITEM_DEBUG_ROOM ; 6
MobileMenuGFX:
INCBIN "gfx/mobile/mobile_menu.2bpp"
MainMenu:
.loop
xor a
ld [wDisableTextAcceleration], a
call ClearTilemapEtc
ld b, SCGB_DIPLOMA
call GetSGBLayout
call SetPalettes
ld hl, wGameTimerPaused
res GAME_TIMER_PAUSED_F, [hl]
call MainMenu_GetWhichMenu
ld [wWhichIndexSet], a
call MainMenu_PrintCurrentTimeAndDay
ld hl, .MenuHeader
call LoadMenuHeader
call MainMenuJoypadLoop
call CloseWindow
jr c, .quit
call ClearTilemap
ld a, [wMenuSelection]
ld hl, .Jumptable
rst JumpTable
jr .loop
.quit
ret
.MenuHeader:
db MENU_BACKUP_TILES ; flags
menu_coords 0, 0, 16, 7
dw .MenuData
db 1 ; default option
.MenuData:
db STATICMENU_CURSOR ; flags
db 0 ; items
dw MainMenuItems
dw PlaceMenuStrings
dw .Strings
.Strings:
; entries correspond to MAINMENUITEM_* constants
db "CONTINUE@"
db "NEW GAME@"
db "OPTION@"
db "MYSTERY GIFT@"
db "MOBILE@"
db "MOBILE STUDIUM@"
if DEF(_DEBUG)
db "DEBUG ROOM@"
endc
.Jumptable:
; entries correspond to MAINMENUITEM_* constants
dw MainMenu_Continue
dw MainMenu_NewGame
dw MainMenu_Option
dw MainMenu_MysteryGift
dw MainMenu_Mobile
dw MainMenu_MobileStudium
if DEF(_DEBUG)
dw MainMenu_DebugRoom
endc
MainMenuItems:
; entries correspond to MAINMENU_* constants
; MAINMENU_NEW_GAME
db 2
db MAINMENUITEM_NEW_GAME
db MAINMENUITEM_OPTION
db -1
; MAINMENU_CONTINUE
db 3 + DEF(_DEBUG)
db MAINMENUITEM_CONTINUE
db MAINMENUITEM_NEW_GAME
db MAINMENUITEM_OPTION
if DEF(_DEBUG)
db MAINMENUITEM_DEBUG_ROOM
endc
db -1
; MAINMENU_MOBILE_MYSTERY
db 5 + DEF(_DEBUG)
db MAINMENUITEM_CONTINUE
db MAINMENUITEM_NEW_GAME
db MAINMENUITEM_OPTION
db MAINMENUITEM_MYSTERY_GIFT
db MAINMENUITEM_MOBILE
if DEF(_DEBUG)
db MAINMENUITEM_DEBUG_ROOM
endc
db -1
; MAINMENU_MOBILE
db 4 + DEF(_DEBUG)
db MAINMENUITEM_CONTINUE
db MAINMENUITEM_NEW_GAME
db MAINMENUITEM_OPTION
db MAINMENUITEM_MOBILE
if DEF(_DEBUG)
db MAINMENUITEM_DEBUG_ROOM
endc
db -1
; MAINMENU_MOBILE_STUDIUM
db 5 + DEF(_DEBUG)
db MAINMENUITEM_CONTINUE
db MAINMENUITEM_NEW_GAME
db MAINMENUITEM_OPTION
db MAINMENUITEM_MOBILE
db MAINMENUITEM_MOBILE_STUDIUM
if DEF(_DEBUG)
db MAINMENUITEM_DEBUG_ROOM
endc
db -1
; MAINMENU_MYSTERY_MOBILE_STUDIUM
db 6 + DEF(_DEBUG)
db MAINMENUITEM_CONTINUE
db MAINMENUITEM_NEW_GAME
db MAINMENUITEM_OPTION
db MAINMENUITEM_MYSTERY_GIFT
db MAINMENUITEM_MOBILE
db MAINMENUITEM_MOBILE_STUDIUM
if DEF(_DEBUG)
db MAINMENUITEM_DEBUG_ROOM
endc
db -1
; MAINMENU_MYSTERY
db 4 + DEF(_DEBUG)
db MAINMENUITEM_CONTINUE
db MAINMENUITEM_NEW_GAME
db MAINMENUITEM_OPTION
db MAINMENUITEM_MYSTERY_GIFT
if DEF(_DEBUG)
db MAINMENUITEM_DEBUG_ROOM
endc
db -1
; MAINMENU_MYSTERY_STUDIUM
db 5 + DEF(_DEBUG)
db MAINMENUITEM_CONTINUE
db MAINMENUITEM_NEW_GAME
db MAINMENUITEM_OPTION
db MAINMENUITEM_MYSTERY_GIFT
db MAINMENUITEM_MOBILE_STUDIUM
if DEF(_DEBUG)
db MAINMENUITEM_DEBUG_ROOM
endc
db -1
; MAINMENU_STUDIUM
db 4 + DEF(_DEBUG)
db MAINMENUITEM_CONTINUE
db MAINMENUITEM_NEW_GAME
db MAINMENUITEM_OPTION
db MAINMENUITEM_MOBILE_STUDIUM
if DEF(_DEBUG)
db MAINMENUITEM_DEBUG_ROOM
endc
db -1
MainMenu_GetWhichMenu:
nop
nop
nop
ld a, [wSaveFileExists]
and a
jr nz, .next
ld a, MAINMENU_NEW_GAME
ret
.next
ldh a, [hCGB]
cp TRUE
ld a, MAINMENU_CONTINUE
ret nz
ld a, BANK(sNumDailyMysteryGiftPartnerIDs)
call OpenSRAM
ld a, [sNumDailyMysteryGiftPartnerIDs]
cp -1 ; locked?
call CloseSRAM
jr nz, .mystery_gift
; This check makes no difference.
ld a, [wStatusFlags]
bit STATUSFLAGS_MAIN_MENU_MOBILE_CHOICES_F, a
ld a, MAINMENU_CONTINUE
jr z, .ok
jr .ok
.ok
jr .ok2
.ok2
ld a, MAINMENU_CONTINUE
ret
.mystery_gift
; This check makes no difference.
ld a, [wStatusFlags]
bit STATUSFLAGS_MAIN_MENU_MOBILE_CHOICES_F, a
jr z, .ok3
jr .ok3
.ok3
jr .ok4
.ok4
ld a, MAINMENU_MYSTERY
ret
MainMenuJoypadLoop:
call SetUpMenu
.loop
call MainMenu_PrintCurrentTimeAndDay
ld a, [w2DMenuFlags1]
set 5, a
ld [w2DMenuFlags1], a
call GetScrollingMenuJoypad
ld a, [wMenuJoypad]
cp B_BUTTON
jr z, .b_button
cp A_BUTTON
jr z, .a_button
jr .loop
.a_button
call PlayClickSFX
and a
ret
.b_button
scf
ret
MainMenu_PrintCurrentTimeAndDay:
ld a, [wSaveFileExists]
and a
ret z
xor a
ldh [hBGMapMode], a
call .PlaceBox
ld hl, wOptions
ld a, [hl]
push af
set NO_TEXT_SCROLL, [hl]
call .PlaceTime
pop af
ld [wOptions], a
ld a, $1
ldh [hBGMapMode], a
ret
.PlaceBox:
call CheckRTCStatus
and %10000000 ; Day count exceeded 16383
jr nz, .TimeFail
hlcoord 0, 14
ld b, 2
ld c, 18
call Textbox
ret
.TimeFail:
call SpeechTextbox
ret
.PlaceTime:
ld a, [wSaveFileExists]
and a
ret z
call CheckRTCStatus
and $80
jp nz, .PrintTimeNotSet
call UpdateTime
call GetWeekday
ld b, a
decoord 1, 15
call .PrintDayOfWeek
decoord 4, 16
ldh a, [hHours]
ld c, a
farcall PrintHour
ld [hl], ":"
inc hl
ld de, hMinutes
lb bc, PRINTNUM_LEADINGZEROS | 1, 2
call PrintNum
ret
.minString: ; unreferenced
db "min.@"
.PrintTimeNotSet:
hlcoord 1, 14
ld de, .TimeNotSetString
call PlaceString
ret
.TimeNotSetString:
db "TIME NOT SET@"
.MainMenuTimeUnknownText: ; unreferenced
text_far _MainMenuTimeUnknownText
text_end
.PrintDayOfWeek:
push de
ld hl, .Days
ld a, b
call GetNthString
ld d, h
ld e, l
pop hl
call PlaceString
ld h, b
ld l, c
ld de, .Day
call PlaceString
ret
.Days:
db "SUN@"
db "MON@"
db "TUES@"
db "WEDNES@"
db "THURS@"
db "FRI@"
db "SATUR@"
.Day:
db "DAY@"
ClearTilemapEtc:
xor a
ldh [hMapAnims], a
call ClearTilemap
call LoadFontsExtra
call LoadStandardFont
call ClearWindowData
ret
MainMenu_NewGame:
farcall NewGame
ret
MainMenu_Option:
farcall Option
ret
MainMenu_Continue:
farcall Continue
ret
MainMenu_MysteryGift:
farcall MysteryGift
ret

805
engine/menus/menu.asm Normal file
View file

@ -0,0 +1,805 @@
_2DMenu_::
ld hl, CopyMenuData
ld a, [wMenuData_2DMenuItemStringsBank]
rst FarCall
call Draw2DMenu
call UpdateSprites
call ApplyTilemap
call Get2DMenuSelection
ret
_InterpretBattleMenu::
ld hl, CopyMenuData
ld a, [wMenuData_2DMenuItemStringsBank]
rst FarCall
call Draw2DMenu
farcall MobileTextBorder
call UpdateSprites
call ApplyTilemap
call Get2DMenuSelection
ret
_InterpretMobileMenu::
ld hl, CopyMenuData
ld a, [wMenuData_2DMenuItemStringsBank]
rst FarCall
call Draw2DMenu
farcall MobileTextBorder
call UpdateSprites
call ApplyTilemap
call Init2DMenuCursorPosition
ld hl, w2DMenuFlags1
set 7, [hl]
.loop
call DelayFrame
farcall Function10032e
ld a, [wcd2b]
and a
jr nz, .quit
call MobileMenuJoypad
ld a, [wMenuJoypadFilter]
and c
jr z, .loop
call Mobile_GetMenuSelection
ret
.quit
ld a, [w2DMenuNumCols]
ld c, a
ld a, [w2DMenuNumRows]
call SimpleMultiply
ld [wMenuCursorPosition], a
and a
ret
Draw2DMenu:
xor a
ldh [hBGMapMode], a
call MenuBox
call Place2DMenuItemStrings
ret
Get2DMenuSelection:
call Init2DMenuCursorPosition
call StaticMenuJoypad
call MenuClickSound
Mobile_GetMenuSelection:
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 [wMenuCursorPosition], 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, [wMenuCursorPosition]
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
call MenuJoypadLoop
pop af
ldh [hBGMapMode], a
ret
MobileMenuJoypad:
ld hl, w2DMenuFlags2
res 7, [hl]
ldh a, [hBGMapMode]
push af
call Move2DMenuCursor
call Do2DMenuRTCJoypad
jr nc, .skip_joypad
call _2DMenuInterpretJoypad
.skip_joypad
pop af
ldh [hBGMapMode], a
call GetMenuJoypad
ld c, a
ret
Function241d5: ; unreferenced
call Place2DMenuCursor
.loop
call Move2DMenuCursor
call HDMATransferTilemapToWRAMBank3 ; should be farcall
call .loop2
jr nc, .done
call _2DMenuInterpretJoypad
jr c, .done
ld a, [w2DMenuFlags1]
bit 7, a
jr nz, .done
call GetMenuJoypad
ld c, a
ld a, [wMenuJoypadFilter]
and c
jr z, .loop
.done
ret
.loop2
call Menu_WasButtonPressed
ret c
ld c, 1
ld b, 3
call AdvanceMobileInactivityTimerAndCheckExpired ; should be farcall
ret c
farcall Function100337
ret c
ld a, [w2DMenuFlags1]
bit 7, a
jr z, .loop2
and a
ret
MenuJoypadLoop:
.loop
call Move2DMenuCursor
call .BGMap_OAM
call Do2DMenuRTCJoypad
jr nc, .done
call _2DMenuInterpretJoypad
jr c, .done
ld a, [w2DMenuFlags1]
bit 7, a
jr nz, .done
call GetMenuJoypad
ld b, a
ld a, [wMenuJoypadFilter]
and b
jr z, .loop
.done
ret
.BGMap_OAM:
ldh a, [hOAMUpdate]
push af
ld a, $1
ldh [hOAMUpdate], a
call WaitBGMap
pop af
ldh [hOAMUpdate], a
xor a
ldh [hBGMapMode], a
ret
Do2DMenuRTCJoypad:
.loopRTC
call UpdateTimeAndPals
call Menu_WasButtonPressed
ret c
ld a, [w2DMenuFlags1]
bit 7, a
jr z, .loopRTC
and a
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
vc_hook Forbid_printing_photo_studio
scf
vc_hook Forbid_printing_PC_Box
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::
ldh a, [rSVBK]
push af
ld a, BANK(wWindowStack)
ldh [rSVBK], a
ld hl, wWindowStackPointer
ld e, [hl]
inc hl
ld d, [hl]
push de
ld b, wMenuHeaderEnd - wMenuHeader
ld hl, wMenuHeader
.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 .copy
call MenuBoxCoord2Attr
call .copy
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
pop af
ldh [rSVBK], a
ld hl, wWindowStackSize
inc [hl]
ret
.copy
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
ret
.ret
ret
_ExitMenu::
xor a
ldh [hBGMapMode], a
ldh a, [rSVBK]
push af
ld a, BANK(wWindowStack)
ldh [rSVBK], a
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
pop af
ldh [rSVBK], a
ld hl, wWindowStackSize
dec [hl]
ret
RestoreOverworldMapTiles: ; unreferenced
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, [wMenuCursorPosition]
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

253
engine/menus/menu_2.asm Normal file
View file

@ -0,0 +1,253 @@
PlaceMenuItemName:
push de
ld a, [wMenuSelection]
ld [wNamedObjectIndex], a
call GetItemName
pop hl
call PlaceString
ret
PlaceMenuItemQuantity:
push de
ld a, [wMenuSelection]
ld [wCurItem], a
farcall _CheckTossableItem
ld a, [wItemAttributeValue]
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, MoneyTopRightMenuHeader
call CopyMenuHeader
jr PlaceMoneyTextbox
PlaceMoneyBottomLeft:
ld hl, MoneyBottomLeftMenuHeader
call CopyMenuHeader
jr PlaceMoneyTextbox
PlaceMoneyAtTopLeftOfTextbox:
ld hl, MoneyTopRightMenuHeader
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
MoneyTopRightMenuHeader:
db MENU_BACKUP_TILES ; flags
menu_coords 11, 0, SCREEN_WIDTH - 1, 2
dw NULL
db 1 ; default option
MoneyBottomLeftMenuHeader:
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 "@"
StartMenu_PrintSafariGameStatus: ; unreferenced
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 "@"
.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, .BallsString
call PlaceString
hlcoord 8, 5
ld de, wParkBallsRemaining
lb bc, PRINTNUM_LEFTALIGN | 1, 2
call PrintNum
hlcoord 1, 1
ld de, .CaughtString
call PlaceString
ld a, [wContestMon]
and a
ld de, .NoneString
jr z, .no_contest_mon
ld [wNamedObjectIndex], 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, .LevelString
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
.BallsJPString: ; unreferenced
db "ボール   こ@"
.CaughtString:
db "CAUGHT@"
.BallsString:
db "BALLS:@"
.NoneString:
db "None@"
.LevelString:
db "LEVEL@"
FindApricornsInBag:
; Checks the bag for Apricorns.
ld hl, wKurtApricornCount
xor a
ld [hli], a
assert wKurtApricornCount + 1 == wKurtApricornItems
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
ld a, [wKurtApricornCount]
and a
ret nz
scf
ret
.addtobuffer:
push hl
ld hl, wKurtApricornCount
inc [hl]
ld e, [hl]
ld d, 0
add hl, de
ld [hl], a
pop hl
ret
INCLUDE "data/items/apricorn_balls.asm"

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,560 @@
; GetOptionPointer.Pointers indexes
const_def
const OPT_TEXT_SPEED ; 0
const OPT_BATTLE_SCENE ; 1
const OPT_BATTLE_STYLE ; 2
const OPT_SOUND ; 3
const OPT_PRINT ; 4
const OPT_MENU_ACCOUNT ; 5
const OPT_FRAME ; 6
const OPT_CANCEL ; 7
DEF NUM_OPTIONS EQU const_value ; 8
_Option:
; BUG: Options menu fails to clear joypad state on initialization (see docs/bugs_and_glitches.md)
ld hl, hInMenu
ld a, [hl]
push af
ld [hl], TRUE
call ClearBGPalettes
hlcoord 0, 0
ld b, SCREEN_HEIGHT - 2
ld c, SCREEN_WIDTH - 2
call Textbox
hlcoord 2, 2
ld de, StringOptions
call PlaceString
xor a
ld [wJumptableIndex], a
; display the settings of each option when the menu is opened
ld c, NUM_OPTIONS - 2 ; omit frame type, the last option
.print_text_loop
push bc
xor a
ldh [hJoyLast], a
call GetOptionPointer
pop bc
ld hl, wJumptableIndex
inc [hl]
dec c
jr nz, .print_text_loop
call UpdateFrame ; display the frame type
xor a
ld [wJumptableIndex], a
inc a
ldh [hBGMapMode], a
call WaitBGMap
ld b, SCGB_DIPLOMA
call GetSGBLayout
call SetPalettes
.joypad_loop
call JoyTextDelay
ldh a, [hJoyPressed]
and START | B_BUTTON
jr nz, .ExitOptions
call OptionsControl
jr c, .dpad
call GetOptionPointer
jr c, .ExitOptions
.dpad
call Options_UpdateCursorPosition
ld c, 3
call DelayFrames
jr .joypad_loop
.ExitOptions:
ld de, SFX_TRANSACTION
call PlaySFX
call WaitSFX
pop af
ldh [hInMenu], a
ret
StringOptions:
db "TEXT SPEED<LF>"
db " :<LF>"
db "BATTLE SCENE<LF>"
db " :<LF>"
db "BATTLE STYLE<LF>"
db " :<LF>"
db "SOUND<LF>"
db " :<LF>"
db "PRINT<LF>"
db " :<LF>"
db "MENU ACCOUNT<LF>"
db " :<LF>"
db "FRAME<LF>"
db " :TYPE<LF>"
db "CANCEL@"
GetOptionPointer:
jumptable .Pointers, wJumptableIndex
.Pointers:
; entries correspond to OPT_* constants
dw Options_TextSpeed
dw Options_BattleScene
dw Options_BattleStyle
dw Options_Sound
dw Options_Print
dw Options_MenuAccount
dw Options_Frame
dw Options_Cancel
const_def
const OPT_TEXT_SPEED_FAST ; 0
const OPT_TEXT_SPEED_MED ; 1
const OPT_TEXT_SPEED_SLOW ; 2
Options_TextSpeed:
call GetTextSpeed
ldh a, [hJoyPressed]
bit D_LEFT_F, a
jr nz, .LeftPressed
bit D_RIGHT_F, a
jr z, .NonePressed
ld a, c ; right pressed
cp OPT_TEXT_SPEED_SLOW
jr c, .Increase
ld c, OPT_TEXT_SPEED_FAST - 1
.Increase:
inc c
ld a, e
jr .Save
.LeftPressed:
ld a, c
and a
jr nz, .Decrease
ld c, OPT_TEXT_SPEED_SLOW + 1
.Decrease:
dec c
ld a, d
.Save:
ld b, a
ld a, [wOptions]
and $f0
or b
ld [wOptions], a
.NonePressed:
ld b, 0
ld hl, .Strings
add hl, bc
add hl, bc
ld e, [hl]
inc hl
ld d, [hl]
hlcoord 11, 3
call PlaceString
and a
ret
.Strings:
; entries correspond to OPT_TEXT_SPEED_* constants
dw .Fast
dw .Mid
dw .Slow
.Fast: db "FAST@"
.Mid: db "MID @"
.Slow: db "SLOW@"
GetTextSpeed:
; converts TEXT_DELAY_* value in a to OPT_TEXT_SPEED_* value in c,
; with previous/next TEXT_DELAY_* values in d/e
ld a, [wOptions]
and TEXT_DELAY_MASK
cp TEXT_DELAY_SLOW
jr z, .slow
cp TEXT_DELAY_FAST
jr z, .fast
; none of the above
ld c, OPT_TEXT_SPEED_MED
lb de, TEXT_DELAY_FAST, TEXT_DELAY_SLOW
ret
.slow
ld c, OPT_TEXT_SPEED_SLOW
lb de, TEXT_DELAY_MED, TEXT_DELAY_FAST
ret
.fast
ld c, OPT_TEXT_SPEED_FAST
lb de, TEXT_DELAY_SLOW, TEXT_DELAY_MED
ret
Options_BattleScene:
ld hl, wOptions
ldh a, [hJoyPressed]
bit D_LEFT_F, a
jr nz, .LeftPressed
bit D_RIGHT_F, a
jr z, .NonePressed
bit BATTLE_SCENE, [hl]
jr nz, .ToggleOn
jr .ToggleOff
.LeftPressed:
bit BATTLE_SCENE, [hl]
jr z, .ToggleOff
jr .ToggleOn
.NonePressed:
bit BATTLE_SCENE, [hl]
jr z, .ToggleOn
jr .ToggleOff
.ToggleOn:
res BATTLE_SCENE, [hl]
ld de, .On
jr .Display
.ToggleOff:
set BATTLE_SCENE, [hl]
ld de, .Off
.Display:
hlcoord 11, 5
call PlaceString
and a
ret
.On: db "ON @"
.Off: db "OFF@"
Options_BattleStyle:
ld hl, wOptions
ldh a, [hJoyPressed]
bit D_LEFT_F, a
jr nz, .LeftPressed
bit D_RIGHT_F, a
jr z, .NonePressed
bit BATTLE_SHIFT, [hl]
jr nz, .ToggleShift
jr .ToggleSet
.LeftPressed:
bit BATTLE_SHIFT, [hl]
jr z, .ToggleSet
jr .ToggleShift
.NonePressed:
bit BATTLE_SHIFT, [hl]
jr nz, .ToggleSet
.ToggleShift:
res BATTLE_SHIFT, [hl]
ld de, .Shift
jr .Display
.ToggleSet:
set BATTLE_SHIFT, [hl]
ld de, .Set
.Display:
hlcoord 11, 7
call PlaceString
and a
ret
.Shift: db "SHIFT@"
.Set: db "SET @"
Options_Sound:
ld hl, wOptions
ldh a, [hJoyPressed]
bit D_LEFT_F, a
jr nz, .LeftPressed
bit D_RIGHT_F, a
jr z, .NonePressed
bit STEREO, [hl]
jr nz, .SetMono
jr .SetStereo
.LeftPressed:
bit STEREO, [hl]
jr z, .SetStereo
jr .SetMono
.NonePressed:
bit STEREO, [hl]
jr nz, .ToggleStereo
jr .ToggleMono
.SetMono:
res STEREO, [hl]
call RestartMapMusic
.ToggleMono:
ld de, .Mono
jr .Display
.SetStereo:
set STEREO, [hl]
call RestartMapMusic
.ToggleStereo:
ld de, .Stereo
.Display:
hlcoord 11, 9
call PlaceString
and a
ret
.Mono: db "MONO @"
.Stereo: db "STEREO@"
const_def
const OPT_PRINT_LIGHTEST ; 0
const OPT_PRINT_LIGHTER ; 1
const OPT_PRINT_NORMAL ; 2
const OPT_PRINT_DARKER ; 3
const OPT_PRINT_DARKEST ; 4
Options_Print:
call GetPrinterSetting
ldh a, [hJoyPressed]
bit D_LEFT_F, a
jr nz, .LeftPressed
bit D_RIGHT_F, a
jr z, .NonePressed
ld a, c
cp OPT_PRINT_DARKEST
jr c, .Increase
ld c, OPT_PRINT_LIGHTEST - 1
.Increase:
inc c
ld a, e
jr .Save
.LeftPressed:
ld a, c
and a
jr nz, .Decrease
ld c, OPT_PRINT_DARKEST + 1
.Decrease:
dec c
ld a, d
.Save:
ld b, a
ld [wGBPrinterBrightness], a
.NonePressed:
ld b, 0
ld hl, .Strings
add hl, bc
add hl, bc
ld e, [hl]
inc hl
ld d, [hl]
hlcoord 11, 11
call PlaceString
and a
ret
.Strings:
; entries correspond to OPT_PRINT_* constants
dw .Lightest
dw .Lighter
dw .Normal
dw .Darker
dw .Darkest
.Lightest: db "LIGHTEST@"
.Lighter: db "LIGHTER @"
.Normal: db "NORMAL @"
.Darker: db "DARKER @"
.Darkest: db "DARKEST @"
GetPrinterSetting:
; converts GBPRINTER_* value in a to OPT_PRINT_* value in c,
; with previous/next GBPRINTER_* values in d/e
ld a, [wGBPrinterBrightness]
and a
jr z, .IsLightest
cp GBPRINTER_LIGHTER
jr z, .IsLight
cp GBPRINTER_DARKER
jr z, .IsDark
cp GBPRINTER_DARKEST
jr z, .IsDarkest
; none of the above
ld c, OPT_PRINT_NORMAL
lb de, GBPRINTER_LIGHTER, GBPRINTER_DARKER
ret
.IsLightest:
ld c, OPT_PRINT_LIGHTEST
lb de, GBPRINTER_DARKEST, GBPRINTER_LIGHTER
ret
.IsLight:
ld c, OPT_PRINT_LIGHTER
lb de, GBPRINTER_LIGHTEST, GBPRINTER_NORMAL
ret
.IsDark:
ld c, OPT_PRINT_DARKER
lb de, GBPRINTER_NORMAL, GBPRINTER_DARKEST
ret
.IsDarkest:
ld c, OPT_PRINT_DARKEST
lb de, GBPRINTER_DARKER, GBPRINTER_LIGHTEST
ret
Options_MenuAccount:
ld hl, wOptions2
ldh a, [hJoyPressed]
bit D_LEFT_F, a
jr nz, .LeftPressed
bit D_RIGHT_F, a
jr z, .NonePressed
bit MENU_ACCOUNT, [hl]
jr nz, .ToggleOff
jr .ToggleOn
.LeftPressed:
bit MENU_ACCOUNT, [hl]
jr z, .ToggleOn
jr .ToggleOff
.NonePressed:
bit MENU_ACCOUNT, [hl]
jr nz, .ToggleOn
.ToggleOff:
res MENU_ACCOUNT, [hl]
ld de, .Off
jr .Display
.ToggleOn:
set MENU_ACCOUNT, [hl]
ld de, .On
.Display:
hlcoord 11, 13
call PlaceString
and a
ret
.Off: db "OFF@"
.On: db "ON @"
Options_Frame:
ld hl, wTextboxFrame
ldh a, [hJoyPressed]
bit D_LEFT_F, a
jr nz, .LeftPressed
bit D_RIGHT_F, a
jr nz, .RightPressed
and a
ret
.RightPressed:
ld a, [hl]
inc a
jr .Save
.LeftPressed:
ld a, [hl]
dec a
.Save:
maskbits NUM_FRAMES
ld [hl], a
UpdateFrame:
ld a, [wTextboxFrame]
hlcoord 16, 15 ; where on the screen the number is drawn
add "1"
ld [hl], a
call LoadFontsExtra
and a
ret
Options_Cancel:
ldh a, [hJoyPressed]
and A_BUTTON
jr nz, .Exit
and a
ret
.Exit:
scf
ret
OptionsControl:
ld hl, wJumptableIndex
ldh a, [hJoyLast]
cp D_DOWN
jr z, .DownPressed
cp D_UP
jr z, .UpPressed
and a
ret
.DownPressed:
ld a, [hl]
cp OPT_CANCEL ; maximum option index
jr nz, .CheckMenuAccount
ld [hl], OPT_TEXT_SPEED ; first option
scf
ret
.CheckMenuAccount: ; I have no idea why this exists...
cp OPT_MENU_ACCOUNT
jr nz, .Increase
ld [hl], OPT_MENU_ACCOUNT
.Increase:
inc [hl]
scf
ret
.UpPressed:
ld a, [hl]
; Another thing where I'm not sure why it exists
cp OPT_FRAME
jr nz, .NotFrame
ld [hl], OPT_MENU_ACCOUNT
scf
ret
.NotFrame:
and a ; OPT_TEXT_SPEED, minimum option index
jr nz, .Decrease
ld [hl], NUM_OPTIONS ; decrements to OPT_CANCEL, maximum option index
.Decrease:
dec [hl]
scf
ret
Options_UpdateCursorPosition:
hlcoord 1, 1
ld de, SCREEN_WIDTH
ld c, SCREEN_HEIGHT - 2
.loop
ld [hl], " "
add hl, de
dec c
jr nz, .loop
hlcoord 1, 2
ld bc, 2 * SCREEN_WIDTH
ld a, [wJumptableIndex]
call AddNTimes
ld [hl], "▶"
ret

1387
engine/menus/save.asm Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,84 @@
SaveMenu_CopyTilemapAtOnce:
ldh a, [hCGB]
and a
jp z, WaitBGMap
; The following is a modified version of _CopyTilemapAtOnce
; that waits for [rLY] to be $60 instead of $80 - 1.
ldh a, [hBGMapMode]
push af
xor a
ldh [hBGMapMode], a
ldh a, [hMapAnims]
push af
xor a
ldh [hMapAnims], a
.wait
ldh a, [rLY]
cp $60
jr c, .wait
di
ld a, BANK(vBGMap2)
ldh [rVBK], a
hlcoord 0, 0, wAttrmap
call .CopyBGMapViaStack
ld a, BANK(vBGMap0)
ldh [rVBK], a
hlcoord 0, 0
call .CopyBGMapViaStack
.wait2
ldh a, [rLY]
cp $60
jr c, .wait2
ei
pop af
ldh [hMapAnims], a
pop af
ldh [hBGMapMode], a
ret
.CopyBGMapViaStack:
; Copy all tiles to vBGMap
ld [hSPBuffer], sp
ld sp, hl
ldh a, [hBGMapAddress + 1]
ld h, a
ld l, 0
ld a, SCREEN_HEIGHT
ldh [hTilesPerCycle], a
ld b, 1 << 1 ; not in v/hblank
ld c, LOW(rSTAT)
.loop
rept SCREEN_WIDTH / 2
pop de
; if in v/hblank, wait until not in v/hblank
.loop\@
ldh a, [c]
and b
jr nz, .loop\@
; load vBGMap
ld [hl], e
inc l
ld [hl], d
inc l
endr
ld de, BG_MAP_WIDTH - SCREEN_WIDTH
add hl, de
ldh a, [hTilesPerCycle]
dec a
ldh [hTilesPerCycle], a
jr nz, .loop
ldh a, [hSPBuffer]
ld l, a
ldh a, [hSPBuffer + 1]
ld h, a
ld sp, hl
ret

View file

@ -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
.no_zero_no_carry ; unreferenced
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 [wItemQuantity], 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, [wMenuCursorPosition]
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 [wMenuCursorPosition], 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, [wMenuCursorPosition]
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, .CancelString
call PlaceString
ret
.CancelString
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

541
engine/menus/start_menu.asm Normal file
View file

@ -0,0 +1,541 @@
; StartMenu.Items indexes
const_def
const STARTMENUITEM_POKEDEX ; 0
const STARTMENUITEM_POKEMON ; 1
const STARTMENUITEM_PACK ; 2
const STARTMENUITEM_STATUS ; 3
const STARTMENUITEM_SAVE ; 4
const STARTMENUITEM_OPTION ; 5
const STARTMENUITEM_EXIT ; 6
const STARTMENUITEM_POKEGEAR ; 7
const STARTMENUITEM_QUIT ; 8
StartMenu::
call ClearWindowData
ld de, SFX_MENU
call PlaySFX
farcall ReanchorBGMap_NoOAMUpdate
ld hl, wStatusFlags2
bit STATUSFLAGS2_BUG_CONTEST_TIMER_F, [hl]
ld hl, .MenuHeader
jr z, .GotMenuData
ld hl, .ContestMenuHeader
.GotMenuData:
call LoadMenuHeader
call .SetUpMenuItems
ld a, [wBattleMenuCursorPosition]
ld [wMenuCursorPosition], a
call .DrawMenuAccount
call DrawVariableLengthMenuBox
call .DrawBugContestStatusBox
call SafeUpdateSprites
call _OpenAndCloseMenu_HDMATransferTilemapAndAttrmap
farcall LoadFonts_NoOAMUpdate
call .DrawBugContestStatus
call UpdateTimePals
jr .Select
.Reopen:
call UpdateSprites
call UpdateTimePals
call .SetUpMenuItems
ld a, [wBattleMenuCursorPosition]
ld [wMenuCursorPosition], a
.Select:
call .GetInput
jr c, .Exit
call ._DrawMenuAccount
ld a, [wMenuCursorPosition]
ld [wBattleMenuCursorPosition], a
call PlayClickSFX
call PlaceHollowCursor
call .OpenMenu
; Menu items have different return functions.
; For example, saving exits the menu.
ld hl, .MenuReturns
ld e, a
ld d, 0
add hl, de
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
jp hl
.MenuReturns:
dw .Reopen
dw .Exit
dw .ExitMenuCallFuncCloseText
dw .ExitMenuRunScriptCloseText
dw .ExitMenuRunScript
dw .ReturnEnd
dw .ReturnRedraw
.Exit:
ldh a, [hOAMUpdate]
push af
ld a, 1
ldh [hOAMUpdate], a
call LoadFontsExtra
pop af
ldh [hOAMUpdate], a
.ReturnEnd:
call ExitMenu
.ReturnEnd2:
call CloseText
call UpdateTimePals
ret
.GetInput:
; Return carry on exit, and no-carry on selection.
xor a
ldh [hBGMapMode], a
call ._DrawMenuAccount
call SetUpMenu
ld a, $ff
ld [wMenuSelection], a
.loop
call .PrintMenuAccount
call GetScrollingMenuJoypad
ld a, [wMenuJoypad]
cp B_BUTTON
jr z, .b
cp A_BUTTON
jr z, .a
jr .loop
.a
call PlayClickSFX
and a
ret
.b
scf
ret
.ExitMenuRunScript:
call ExitMenu
ld a, HMENURETURN_SCRIPT
ldh [hMenuReturn], a
ret
.ExitMenuRunScriptCloseText:
call ExitMenu
ld a, HMENURETURN_SCRIPT
ldh [hMenuReturn], a
jr .ReturnEnd2
.ExitMenuCallFuncCloseText:
call ExitMenu
ld hl, wQueuedScriptAddr
ld a, [hli]
ld h, [hl]
ld l, a
ld a, [wQueuedScriptBank]
rst FarCall
jr .ReturnEnd2
.ReturnRedraw:
call .Clear
jp .Reopen
.Clear:
call ClearBGPalettes
call ExitMenu
call ReloadTilesetAndPalettes
call .DrawMenuAccount
call DrawVariableLengthMenuBox
call .DrawBugContestStatus
call UpdateSprites
call FinishExitMenu
ret
.MenuHeader:
db MENU_BACKUP_TILES ; flags
menu_coords 10, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
dw .MenuData
db 1 ; default selection
.ContestMenuHeader:
db MENU_BACKUP_TILES ; flags
menu_coords 10, 2, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
dw .MenuData
db 1 ; default selection
.MenuData:
db STATICMENU_CURSOR | STATICMENU_WRAP | STATICMENU_ENABLE_START ; flags
dn 0, 0 ; rows, columns
dw wMenuItemsList
dw .MenuString
dw .Items
.Items:
; entries correspond to STARTMENUITEM_* constants
dw StartMenu_Pokedex, .PokedexString, .PokedexDesc
dw StartMenu_Pokemon, .PartyString, .PartyDesc
dw StartMenu_Pack, .PackString, .PackDesc
dw StartMenu_Status, .StatusString, .StatusDesc
dw StartMenu_Save, .SaveString, .SaveDesc
dw StartMenu_Option, .OptionString, .OptionDesc
dw StartMenu_Exit, .ExitString, .ExitDesc
dw StartMenu_Pokegear, .PokegearString, .PokegearDesc
dw StartMenu_Quit, .QuitString, .QuitDesc
.PokedexString: db "#DEX@"
.PartyString: db "#MON@"
.PackString: db "PACK@"
.StatusString: db "<PLAYER>@"
.SaveString: db "SAVE@"
.OptionString: db "OPTION@"
.ExitString: db "EXIT@"
.PokegearString: db "<POKE>GEAR@"
.QuitString: db "QUIT@"
.PokedexDesc:
db "#MON"
next "database@"
.PartyDesc:
db "Party <PKMN>"
next "status@"
.PackDesc:
db "Contains"
next "items@"
.PokegearDesc:
db "Trainer's"
next "key device@"
.StatusDesc:
db "Your own"
next "status@"
.SaveDesc:
db "Save your"
next "progress@"
.OptionDesc:
db "Change"
next "settings@"
.ExitDesc:
db "Close this"
next "menu@"
.QuitDesc:
db "Quit and"
next "be judged.@"
.OpenMenu:
ld a, [wMenuSelection]
call .GetMenuAccountTextPointer
ld a, [hli]
ld h, [hl]
ld l, a
jp hl
.MenuString:
push de
ld a, [wMenuSelection]
call .GetMenuAccountTextPointer
inc hl
inc hl
ld a, [hli]
ld d, [hl]
ld e, a
pop hl
call PlaceString
ret
.MenuDesc:
push de
ld a, [wMenuSelection]
cp $ff
jr z, .none
call .GetMenuAccountTextPointer
rept 4
inc hl
endr
ld a, [hli]
ld d, [hl]
ld e, a
pop hl
call PlaceString
ret
.none
pop de
ret
.GetMenuAccountTextPointer:
ld e, a
ld d, 0
ld hl, wMenuDataPointerTableAddr
ld a, [hli]
ld h, [hl]
ld l, a
rept 6
add hl, de
endr
ret
.SetUpMenuItems:
xor a
ld [wWhichIndexSet], a
call .FillMenuList
ld hl, wStatusFlags
bit STATUSFLAGS_POKEDEX_F, [hl]
jr z, .no_pokedex
ld a, STARTMENUITEM_POKEDEX
call .AppendMenuList
.no_pokedex
ld a, [wPartyCount]
and a
jr z, .no_pokemon
ld a, STARTMENUITEM_POKEMON
call .AppendMenuList
.no_pokemon
ld a, [wLinkMode]
and a
jr nz, .no_pack
ld hl, wStatusFlags2
bit STATUSFLAGS2_BUG_CONTEST_TIMER_F, [hl]
jr nz, .no_pack
ld a, STARTMENUITEM_PACK
call .AppendMenuList
.no_pack
ld hl, wPokegearFlags
bit POKEGEAR_OBTAINED_F, [hl]
jr z, .no_pokegear
ld a, STARTMENUITEM_POKEGEAR
call .AppendMenuList
.no_pokegear
ld a, STARTMENUITEM_STATUS
call .AppendMenuList
ld a, [wLinkMode]
and a
jr nz, .no_save
ld hl, wStatusFlags2
bit STATUSFLAGS2_BUG_CONTEST_TIMER_F, [hl]
ld a, STARTMENUITEM_QUIT
jr nz, .write
ld a, STARTMENUITEM_SAVE
.write
call .AppendMenuList
.no_save
ld a, STARTMENUITEM_OPTION
call .AppendMenuList
ld a, STARTMENUITEM_EXIT
call .AppendMenuList
ld a, c
ld [wMenuItemsList], a
ret
.FillMenuList:
xor a
ld hl, wMenuItemsList
ld [hli], a
ld a, -1
ld bc, wMenuItemsListEnd - (wMenuItemsList + 1)
call ByteFill
ld de, wMenuItemsList + 1
ld c, 0
ret
.AppendMenuList:
ld [de], a
inc de
inc c
ret
.DrawMenuAccount:
jp ._DrawMenuAccount
.PrintMenuAccount:
call .IsMenuAccountOn
ret z
call ._DrawMenuAccount
decoord 0, 14
jp .MenuDesc
._DrawMenuAccount:
call .IsMenuAccountOn
ret z
hlcoord 0, 13
lb bc, 5, 10
call ClearBox
hlcoord 0, 13
ld b, 3
ld c, 8
jp TextboxPalette
.IsMenuAccountOn:
ld a, [wOptions2]
and 1 << MENU_ACCOUNT
ret
.DrawBugContestStatusBox:
ld hl, wStatusFlags2
bit STATUSFLAGS2_BUG_CONTEST_TIMER_F, [hl]
ret z
farcall StartMenu_DrawBugContestStatusBox
ret
.DrawBugContestStatus:
ld hl, wStatusFlags2
bit STATUSFLAGS2_BUG_CONTEST_TIMER_F, [hl]
jr nz, .contest
ret
.contest
farcall StartMenu_PrintBugContestStatus
ret
StartMenu_Exit:
; Exit the menu.
ld a, 1
ret
StartMenu_Quit:
; Retire from the bug catching contest.
ld hl, .StartMenuContestEndText
call StartMenuYesNo
jr c, .DontEndContest
ld a, BANK(BugCatchingContestReturnToGateScript)
ld hl, BugCatchingContestReturnToGateScript
call FarQueueScript
ld a, 4
ret
.DontEndContest:
ld a, 0
ret
.StartMenuContestEndText:
text_far _StartMenuContestEndText
text_end
StartMenu_Save:
; Save the game.
call BufferScreen
farcall SaveMenu
jr nc, .saved
ld a, 0
ret
.saved
ld a, 1
ret
StartMenu_Option:
; Game options.
call FadeToMenu
farcall Option
ld a, 6
ret
StartMenu_Status:
; Player status.
call FadeToMenu
farcall TrainerCard
call CloseSubmenu
ld a, 0
ret
StartMenu_Pokedex:
ld a, [wPartyCount]
and a
jr z, .empty
call FadeToMenu
farcall Pokedex
call CloseSubmenu
.empty
ld a, 0
ret
StartMenu_Pokegear:
call FadeToMenu
farcall PokeGear
call CloseSubmenu
ld a, 0
ret
StartMenu_Pack:
call FadeToMenu
farcall Pack
ld a, [wPackUsedItem]
and a
jr nz, .used_item
call CloseSubmenu
ld a, 0
ret
.used_item
call ExitAllMenus
ld a, 4
ret
StartMenu_Pokemon:
ld a, [wPartyCount]
and a
jr z, .return
call FadeToMenu
.choosemenu
xor a
ld [wPartyMenuActionText], a ; Choose a POKéMON.
call ClearBGPalettes
.menu
farcall LoadPartyMenuGFX
farcall InitPartyMenuWithCancel
farcall InitPartyMenuGFX
.menunoreload
farcall WritePartyMenuTilemap
farcall PrintPartyMenuText
call WaitBGMap
call SetPalettes ; load regular palettes?
call DelayFrame
farcall PartyMenuSelect
jr c, .return ; if cancelled or pressed B
call PokemonActionSubmenu
cp 3
jr z, .menu
cp 0
jr z, .choosemenu
cp 1
jr z, .menunoreload
cp 2
jr z, .quit
.return
call CloseSubmenu
ld a, 0
ret
.quit
ld a, b
push af
call ExitAllMenus
pop af
ret

View file

@ -0,0 +1,626 @@
; TrainerCard.Jumptable indexes
const_def
const TRAINERCARDSTATE_PAGE1_LOADGFX ; 0
const TRAINERCARDSTATE_PAGE1_JOYPAD ; 1
const TRAINERCARDSTATE_PAGE2_LOADGFX ; 2
const TRAINERCARDSTATE_PAGE2_JOYPAD ; 3
const TRAINERCARDSTATE_PAGE3_LOADGFX ; 4
const TRAINERCARDSTATE_PAGE3_JOYPAD ; 5
const TRAINERCARDSTATE_QUIT ; 6
TrainerCard:
ld a, [wVramState]
push af
xor a
ld [wVramState], a
ld hl, wOptions
ld a, [hl]
push af
set NO_TEXT_SCROLL, [hl]
call .InitRAM
.loop
call UpdateTime
call JoyTextDelay
ld a, [wJumptableIndex]
bit 7, a
jr nz, .quit
ldh a, [hJoyLast]
and B_BUTTON
jr nz, .quit
call .RunJumptable
call DelayFrame
jr .loop
.quit
pop af
ld [wOptions], a
pop af
ld [wVramState], a
ret
.InitRAM:
call ClearBGPalettes
call ClearSprites
call ClearTilemap
call DisableLCD
farcall GetCardPic
ld hl, CardRightCornerGFX
ld de, vTiles2 tile $1c
ld bc, 1 tiles
ld a, BANK(CardRightCornerGFX)
call FarCopyBytes
ld hl, CardStatusGFX
ld de, vTiles2 tile $29
ld bc, 86 tiles
ld a, BANK(CardStatusGFX)
call FarCopyBytes
call TrainerCard_PrintTopHalfOfCard
hlcoord 0, 8
ld d, 6
call TrainerCard_InitBorder
call EnableLCD
call WaitBGMap
ld b, SCGB_TRAINER_CARD
call GetSGBLayout
call SetPalettes
call WaitBGMap
ld hl, wJumptableIndex
xor a ; TRAINERCARDSTATE_PAGE1_LOADGFX
ld [hli], a ; wJumptableIndex
ld [hli], a ; wTrainerCardBadgeFrameCounter
ld [hli], a ; wTrainerCardBadgeTileID
ld [hl], a ; wTrainerCardBadgeAttributes
ret
.RunJumptable:
jumptable .Jumptable, wJumptableIndex
.Jumptable:
; entries correspond to TRAINERCARDSTATE_* constants
dw TrainerCard_Page1_LoadGFX
dw TrainerCard_Page1_Joypad
dw TrainerCard_Page2_LoadGFX
dw TrainerCard_Page2_Joypad
dw TrainerCard_Page3_LoadGFX
dw TrainerCard_Page3_Joypad
dw TrainerCard_Quit
TrainerCard_IncrementJumptable:
ld hl, wJumptableIndex
inc [hl]
ret
TrainerCard_Quit:
ld hl, wJumptableIndex
set 7, [hl]
ret
TrainerCard_Page1_LoadGFX:
call ClearSprites
hlcoord 0, 8
ld d, 6
call TrainerCard_InitBorder
call WaitBGMap
ld de, CardStatusGFX
ld hl, vTiles2 tile $29
lb bc, BANK(CardStatusGFX), 86
call Request2bpp
call TrainerCard_Page1_PrintDexCaught_GameTime
call TrainerCard_IncrementJumptable
ret
TrainerCard_Page1_Joypad:
call TrainerCard_Page1_PrintGameTime
ld hl, hJoyLast
ld a, [hl]
and D_RIGHT | A_BUTTON
jr nz, .pressed_right_a
ret
.pressed_right_a
ld a, TRAINERCARDSTATE_PAGE2_LOADGFX
ld [wJumptableIndex], a
ret
.KantoBadgeCheck: ; unreferenced
ld a, [wKantoBadges]
and a
ret z
ld a, TRAINERCARDSTATE_PAGE3_LOADGFX
ld [wJumptableIndex], a
ret
TrainerCard_Page2_LoadGFX:
call ClearSprites
hlcoord 0, 8
ld d, 6
call TrainerCard_InitBorder
call WaitBGMap
ld de, LeaderGFX
ld hl, vTiles2 tile $29
lb bc, BANK(LeaderGFX), 86
call Request2bpp
ld de, BadgeGFX
ld hl, vTiles0 tile $00
lb bc, BANK(BadgeGFX), 44
call Request2bpp
call TrainerCard_Page2_3_InitObjectsAndStrings
call TrainerCard_IncrementJumptable
ret
TrainerCard_Page2_Joypad:
ld hl, TrainerCard_JohtoBadgesOAM
call TrainerCard_Page2_3_AnimateBadges
ld hl, hJoyLast
ld a, [hl]
and A_BUTTON
jr nz, .Quit
ld a, [hl]
and D_LEFT
jr nz, .d_left
ret
.d_left
ld a, TRAINERCARDSTATE_PAGE1_LOADGFX
ld [wJumptableIndex], a
ret
.KantoBadgeCheck: ; unreferenced
ld a, [wKantoBadges]
and a
ret z
ld a, TRAINERCARDSTATE_PAGE3_LOADGFX
ld [wJumptableIndex], a
ret
.Quit:
ld a, TRAINERCARDSTATE_QUIT
ld [wJumptableIndex], a
ret
TrainerCard_Page3_LoadGFX:
call ClearSprites
hlcoord 0, 8
ld d, 6
call TrainerCard_InitBorder
call WaitBGMap
ld de, LeaderGFX2
ld hl, vTiles2 tile $29
lb bc, BANK(LeaderGFX2), 86
call Request2bpp
ld de, BadgeGFX2
ld hl, vTiles0 tile $00
lb bc, BANK(BadgeGFX2), 44
call Request2bpp
call TrainerCard_Page2_3_InitObjectsAndStrings
call TrainerCard_IncrementJumptable
ret
TrainerCard_Page3_Joypad:
ld hl, TrainerCard_JohtoBadgesOAM
call TrainerCard_Page2_3_AnimateBadges
ld hl, hJoyLast
ld a, [hl]
and D_LEFT
jr nz, .left
ld a, [hl]
and D_RIGHT
jr nz, .right
ret
.left
ld a, TRAINERCARDSTATE_PAGE2_LOADGFX
ld [wJumptableIndex], a
ret
.right
ld a, TRAINERCARDSTATE_PAGE1_LOADGFX
ld [wJumptableIndex], a
ret
TrainerCard_PrintTopHalfOfCard:
hlcoord 0, 0
ld d, 5
call TrainerCard_InitBorder
hlcoord 2, 2
ld de, .Name_Money
call PlaceString
hlcoord 2, 4
ld de, .ID_No
call TrainerCardSetup_PlaceTilemapString
hlcoord 7, 2
ld de, wPlayerName
call PlaceString
hlcoord 5, 4
ld de, wPlayerID
lb bc, PRINTNUM_LEADINGZEROS | 2, 5
call PrintNum
hlcoord 7, 6
ld de, wMoney
lb bc, PRINTNUM_MONEY | 3, 6
call PrintNum
hlcoord 1, 3
ld de, .HorizontalDivider
call TrainerCardSetup_PlaceTilemapString
hlcoord 14, 1
lb bc, 5, 7
xor a
ldh [hGraphicStartTile], a
predef PlaceGraphic
ret
.Name_Money:
db "NAME/"
next ""
next "MONEY@"
.ID_No:
db $27, $28, -1 ; ID NO
.HorizontalDivider:
db $25, $25, $25, $25, $25, $25, $25, $25, $25, $25, $25, $25, $26, -1 ; ____________>
TrainerCard_Page1_PrintDexCaught_GameTime:
hlcoord 2, 10
ld de, .Dex_PlayTime
call PlaceString
hlcoord 10, 15
ld de, .Badges
call PlaceString
ld hl, wPokedexCaught
ld bc, wEndPokedexCaught - wPokedexCaught
call CountSetBits16
ld a, c
ld c, b
ld b, a
push bc
ld hl, sp + 0
ld d, h
ld e, l
hlcoord 15, 10
lb bc, 2, 3
call PrintNum
pop bc
call TrainerCard_Page1_PrintGameTime
hlcoord 2, 8
ld de, .StatusTilemap
call TrainerCardSetup_PlaceTilemapString
ld a, [wStatusFlags]
bit STATUSFLAGS_POKEDEX_F, a
ret nz
hlcoord 1, 9
lb bc, 2, 17
call ClearBox
ret
.Dex_PlayTime:
db "#DEX"
next "PLAY TIME@"
.Unused: ; unreferenced
db "@"
.Badges:
db " BADGES▶@"
.StatusTilemap:
db $29, $2a, $2b, $2c, $2d, -1
TrainerCard_Page2_3_InitObjectsAndStrings:
hlcoord 2, 8
ld de, .BadgesTilemap
call TrainerCardSetup_PlaceTilemapString
hlcoord 2, 10
ld a, $29
ld c, 4
.loop
call TrainerCard_Page2_3_PlaceLeadersFaces
rept 4
inc hl
endr
dec c
jr nz, .loop
hlcoord 2, 13
ld a, $51
ld c, 4
.loop2
call TrainerCard_Page2_3_PlaceLeadersFaces
rept 4
inc hl
endr
dec c
jr nz, .loop2
xor a
ld [wTrainerCardBadgeFrameCounter], a
ld hl, TrainerCard_JohtoBadgesOAM
call TrainerCard_Page2_3_OAMUpdate
ret
.BadgesTilemap:
db $79, $7a, $7b, $7c, $7d, -1 ; "BADGES"
TrainerCardSetup_PlaceTilemapString:
.loop
ld a, [de]
cp -1
ret z
ld [hli], a
inc de
jr .loop
TrainerCard_InitBorder:
ld e, SCREEN_WIDTH
.loop1
ld a, $23
ld [hli], a
dec e
jr nz, .loop1
ld a, $23
ld [hli], a
ld e, SCREEN_WIDTH - 3
ld a, " "
.loop2
ld [hli], a
dec e
jr nz, .loop2
ld a, $1c
ld [hli], a
ld a, $23
ld [hli], a
.loop3
ld a, $23
ld [hli], a
ld e, SCREEN_WIDTH - 2
ld a, " "
.loop4
ld [hli], a
dec e
jr nz, .loop4
ld a, $23
ld [hli], a
dec d
jr nz, .loop3
ld a, $23
ld [hli], a
ld a, $24
ld [hli], a
ld e, SCREEN_WIDTH - 3
ld a, " "
.loop5
ld [hli], a
dec e
jr nz, .loop5
ld a, $23
ld [hli], a
ld e, SCREEN_WIDTH
.loop6
ld a, $23
ld [hli], a
dec e
jr nz, .loop6
ret
TrainerCard_Page2_3_PlaceLeadersFaces:
push de
push hl
ld [hli], a
inc a
ld [hli], a
inc a
ld [hli], a
inc a
ld [hli], a
inc a
ld de, SCREEN_WIDTH - 3
add hl, de
ld [hli], a
inc a
ld [hli], a
inc a
ld [hli], a
inc a
ld de, SCREEN_WIDTH - 3
add hl, de
ld [hli], a
inc a
ld [hli], a
inc a
ld [hli], a
inc a
pop hl
pop de
ret
TrainerCard_Page1_PrintGameTime:
hlcoord 11, 12
ld de, wGameTimeHours
lb bc, 2, 4
call PrintNum
inc hl
ld de, wGameTimeMinutes
lb bc, PRINTNUM_LEADINGZEROS | 1, 2
call PrintNum
ldh a, [hVBlankCounter]
and $1f
ret nz
hlcoord 15, 12
ld a, [hl]
xor " " ^ $2e ; alternate between space and small colon ($2e) tiles
ld [hl], a
ret
TrainerCard_Page2_3_AnimateBadges:
ldh a, [hVBlankCounter]
and %111
ret nz
ld a, [wTrainerCardBadgeFrameCounter]
inc a
and %111
ld [wTrainerCardBadgeFrameCounter], a
jr TrainerCard_Page2_3_OAMUpdate
TrainerCard_Page2_3_OAMUpdate:
; copy flag array pointer
ld a, [hli]
ld e, a
ld a, [hli]
; get flag array
ld d, a
ld a, [de]
ld c, a
ld de, wShadowOAMSprite00
ld b, NUM_JOHTO_BADGES
.loop
srl c
push bc
jr nc, .skip_badge
push hl
ld a, [hli] ; y
ld b, a
ld a, [hli] ; x
ld c, a
ld a, [hli] ; pal
ld [wTrainerCardBadgeAttributes], a
ld a, [wTrainerCardBadgeFrameCounter]
add l
ld l, a
ld a, 0
adc h
ld h, a
ld a, [hl]
ld [wTrainerCardBadgeTileID], a
call .PrepOAM
pop hl
.skip_badge
ld bc, $b ; 3 + 2 * 4
add hl, bc
pop bc
dec b
jr nz, .loop
ret
.PrepOAM:
ld a, [wTrainerCardBadgeTileID]
and 1 << 7
jr nz, .xflip
ld hl, .facing1
jr .loop2
.xflip
ld hl, .facing2
.loop2
ld a, [hli]
cp -1
ret z
add b
ld [de], a ; y
inc de
ld a, [hli]
add c
ld [de], a ; x
inc de
ld a, [wTrainerCardBadgeTileID]
and ~(1 << 7)
add [hl]
ld [de], a ; tile id
inc hl
inc de
ld a, [wTrainerCardBadgeAttributes]
add [hl]
ld [de], a ; attributes
inc hl
inc de
jr .loop2
.facing1
dbsprite 0, 0, 0, 0, $00, 0
dbsprite 1, 0, 0, 0, $01, 0
dbsprite 0, 1, 0, 0, $02, 0
dbsprite 1, 1, 0, 0, $03, 0
db -1
.facing2
dbsprite 0, 0, 0, 0, $01, 0 | X_FLIP
dbsprite 1, 0, 0, 0, $00, 0 | X_FLIP
dbsprite 0, 1, 0, 0, $03, 0 | X_FLIP
dbsprite 1, 1, 0, 0, $02, 0 | X_FLIP
db -1
TrainerCard_JohtoBadgesOAM:
; Template OAM data for each badge on the trainer card.
; Format:
; y, x, palette
; cycle 1: face tile, in1 tile, in2 tile, in3 tile
; cycle 2: face tile, in1 tile, in2 tile, in3 tile
dw wJohtoBadges
; Zephyrbadge
db $68, $18, 0
db $00, $20, $24, $20 | (1 << 7)
db $00, $20, $24, $20 | (1 << 7)
; Hivebadge
db $68, $38, 0
db $04, $20, $24, $20 | (1 << 7)
db $04, $20, $24, $20 | (1 << 7)
; Plainbadge
db $68, $58, 0
db $08, $20, $24, $20 | (1 << 7)
db $08, $20, $24, $20 | (1 << 7)
; Fogbadge
db $68, $78, 0
db $0c, $20, $24, $20 | (1 << 7)
db $0c, $20, $24, $20 | (1 << 7)
; Mineralbadge
db $80, $38, 0
db $10, $20, $24, $20 | (1 << 7)
db $10, $20, $24, $20 | (1 << 7)
; Stormbadge
db $80, $18, 0
db $14, $20, $24, $20 | (1 << 7)
db $14, $20, $24, $20 | (1 << 7)
; Glacierbadge
db $80, $58, 0
db $18, $20, $24, $20 | (1 << 7)
db $18, $20, $24, $20 | (1 << 7)
; Risingbadge
; X-flips on alternate cycles.
db $80, $78, 0
db $1c, $20, $24, $20 | (1 << 7)
db $1c | (1 << 7), $20, $24, $20 | (1 << 7)
CardStatusGFX: INCBIN "gfx/trainer_card/card_status.2bpp"
LeaderGFX: INCBIN "gfx/trainer_card/leaders.2bpp"
LeaderGFX2: INCBIN "gfx/trainer_card/leaders.2bpp"
BadgeGFX: INCBIN "gfx/trainer_card/badges.2bpp"
BadgeGFX2: INCBIN "gfx/trainer_card/badges.2bpp"
CardRightCornerGFX: INCBIN "gfx/trainer_card/card_right_corner.2bpp"