Level selection menu: entry transition events (#12) (#35) [commit 1]

This commit is contained in:
xCrystal 2024-01-28 17:57:11 +01:00
parent 2fdfa9057f
commit 52bb92028e
9 changed files with 109 additions and 37 deletions

View File

@ -27,6 +27,12 @@ DEF LSMTEXTBOX_LEVEL_NUMBERS_FIRST_TILE EQU $31 ; and $41
const LSMTEXTBOX_STAGE_3_INDICATOR_TILE ; $3d (and $4d) const LSMTEXTBOX_STAGE_3_INDICATOR_TILE ; $3d (and $4d)
const LSMTEXTBOX_STAGE_4_INDICATOR_TILE ; $3e (and $4e) const LSMTEXTBOX_STAGE_4_INDICATOR_TILE ; $3e (and $4e)
; events when entering Level Selection menu (wLevelSelectionMenuEntryEventQueue)
const_def
const LSMEVENT_SHOW_UNLOCKED_LEVELS ; 0
const LSMEVENT_ANIMATE_TIME_OF_DAY ; 1
DEF NUM_LSM_EVENTS EQU const_value
; used in CaughtData (legacy) ; used in CaughtData (legacy)
const_def $7f, -1 const_def $7f, -1
const LANDMARK_EVENT ; $7f const LANDMARK_EVENT ; $7f

View File

@ -131,3 +131,4 @@ if DEF(_DEBUG)
db DEBUGLEVEL_5 ; LANDMARK_DEBUGLEVEL_5 db DEBUGLEVEL_5 ; LANDMARK_DEBUGLEVEL_5
endc endc
assert_table_length NUM_LANDMARKS assert_table_length NUM_LANDMARKS
db $ff

View File

@ -100,6 +100,7 @@
- **wCurLevel**: initialized in LevelSelectionMenu (where it is also used), and stays static during the level. - **wCurLevel**: initialized in LevelSelectionMenu (where it is also used), and stays static during the level.
- **wDefaultLevelSelectionMenuLandmark**: used to know in which landmark to place the player when entering level selection menu. - **wDefaultLevelSelectionMenuLandmark**: used to know in which landmark to place the player when entering level selection menu.
- **wCurOverworldMiscPal** - **wCurOverworldMiscPal**
- **wLevelSelectionMenuEntryEventQueue**: which events have to be triggered the next time the player enters the level selection menu.
- These addresses share memory region with string buffers from *wStringBuffer3* onwards. They are placed in memory in the following order. - These addresses share memory region with string buffers from *wStringBuffer3* onwards. They are placed in memory in the following order.
- **wTempSpaceStruct**: Temporary scope. Same structure as *wCurSpaceStruct* - **wTempSpaceStruct**: Temporary scope. Same structure as *wCurSpaceStruct*
@ -119,6 +120,8 @@
- **wDisabledSpacesBackups**: preserved on save to **sDisabledSpacesBackups**. - **wDisabledSpacesBackups**: preserved on save to **sDisabledSpacesBackups**.
- **wMapObjectsBackups**: preserved on save to **sMapObjectsBackups**. - **wMapObjectsBackups**: preserved on save to **sMapObjectsBackups**.
- **wLevelSelectionMenu\*** addresses, union under the *"Miscellaneous WRAM 1"* section. Temporary scope during level selection menu, except for *wLevelSelectionMenuEntryEventQueue*.
- Other WRAM 0 addresses (not preserved on save): - Other WRAM 0 addresses (not preserved on save):
- **wText2bpp** - **wText2bpp**
- **wWhichHUD** - **wWhichHUD**

View File

@ -35,9 +35,7 @@ ClearedLevelScreen:
ld [wNumTempUnlockedLevels], a ld [wNumTempUnlockedLevels], a
ld a, $ff ld a, $ff
ld [wTempUnlockedLevels], a ld [wTempUnlockedLevels], a
call UnlockLevels jp UnlockLevels
ld c, 30
jp DelayFrames
.LevelCleared1Text: .LevelCleared1Text:
text " L E V E L" text " L E V E L"

View File

@ -93,6 +93,22 @@ GameMenuJoypadLoop:
ret ret
GameMenu_WorldMap: GameMenu_WorldMap:
; the following 500ms fading delay applies:
; - from post-level screen to level selection menu
; - from overworld to level selection menu
; - from selecting "WORLD MAP" in game menu to level selection menu (save outside ow)
; - from selecting "WORLD MAP" in game menu to overworld (save in ow)
ld a, 8
ld [wMusicFade], a
ld a, LOW(MUSIC_NONE)
ld [wMusicFadeID], a
ld a, HIGH(MUSIC_NONE)
ld [wMusicFadeID + 1], a
call ClearBGPalettes
call ClearTilemap
ld c, 30 - 8
call DelayFrames
ld a, [wSaveFileInOverworld] ld a, [wSaveFileInOverworld]
and a and a
jr z, .not_in_overworld jr z, .not_in_overworld
@ -102,6 +118,11 @@ GameMenu_WorldMap:
.not_in_overworld .not_in_overworld
farcall LevelSelectionMenu farcall LevelSelectionMenu
; dequeue all level selection menu events (which triggered during call above if set).
; game is not saved until player enters a level, so if game is turned off in the middle of
; an event or in the menu, the player will be able to replay the events when they come back.
ld a, 0
ld [wLevelSelectionMenuEntryEventQueue], a
ret nc ; if pressed B, go back to Game Menu ret nc ; if pressed B, go back to Game Menu
farcall ClearSpriteAnims farcall ClearSpriteAnims
@ -111,16 +132,6 @@ GameMenu_WorldMap:
.SpawnToMap: .SpawnToMap:
ldh [hMapEntryMethod], a ldh [hMapEntryMethod], a
ld a, $8
ld [wMusicFade], a
ld a, LOW(MUSIC_NONE)
ld [wMusicFadeID], a
ld a, HIGH(MUSIC_NONE)
ld [wMusicFadeID + 1], a
call ClearBGPalettes
call ClearTilemap
ld c, 20
call DelayFrames
farcall JumpRoamMons farcall JumpRoamMons
xor a xor a
ld [wDontPlayMapMusicOnReload], a ; play map music ld [wDontPlayMapMusicOnReload], a ; play map music
@ -137,11 +148,17 @@ GameMenu_WorldMap:
ld a, [wExitOverworldReason] ld a, [wExitOverworldReason]
cp CLEARED_LEVEL cp CLEARED_LEVEL
jr nz, .save_and_return jr nz, .save_and_return
call AdvanceTimeOfDay
farcall ClearedLevelScreen farcall ClearedLevelScreen
call AdvanceTimeOfDay
ld hl, wLevelSelectionMenuEntryEventQueue
set LSMEVENT_ANIMATE_TIME_OF_DAY, [hl]
ld a, [wNumTempUnlockedLevels]
and a
jr z, .save_and_return
set LSMEVENT_SHOW_UNLOCKED_LEVELS, [hl]
.save_and_return .save_and_return
farcall AutoSaveGameOutsideOverworld farcall AutoSaveGameOutsideOverworld
ret jp GameMenu_WorldMap
GameMenu_Shop: GameMenu_Shop:
ret ret

View File

@ -2,6 +2,8 @@ LevelSelectionMenu::
xor a xor a
ldh [hInMenu], a ldh [hInMenu], a
ldh [hMapAnims], a ldh [hMapAnims], a
ldh [hSCY], a
ldh [hSCX], a
ld a, 1 << 2 ; do not clear wShadowOAM during DoNextFrameForAllSprites ld a, 1 << 2 ; do not clear wShadowOAM during DoNextFrameForAllSprites
ld [wVramState], a ld [wVramState], a
@ -17,6 +19,59 @@ LevelSelectionMenu::
ld a, LCDC_DEFAULT ld a, LCDC_DEFAULT
ldh [rLCDC], a ldh [rLCDC], a
ld a, [wLevelSelectionMenuEntryEventQueue]
bit LSMEVENT_SHOW_UNLOCKED_LEVELS, a
jr z, .load_default_landmark
ld hl, wTempUnlockedLevels
.show_unlocked_levels_loop
ld a, [hli]
cp $ff
jr z, .load_default_landmark
push hl
; perform level-to-landmark lookup of wTempUnlockedLevels[i] in $ff-terminated LandmarkToLevelTable.
; stop at the first match and load it to wLevelSelectionMenuCurrentLandmark.
ld hl, LandmarkToLevelTable
ld c, 0
.level_to_landmark_loop
ld b, [hl]
inc b
jr z, .invalid_level ; if reached $ff byte of LandmarkToLevelTable
cp [hl]
jr z, .match
inc hl
inc c
jr .level_to_landmark_loop
.match
ld a, c
ld [wLevelSelectionMenuCurrentLandmark], a
call LevelSelectionMenu_GetLandmarkPage
ld [wLevelSelectionMenuCurrentPage], a
call LevelSelectionMenu_DrawTilemapAndAttrmap
call LevelSelectionMenu_DrawTimeOfDaySymbol
ld b, CGB_LEVEL_SELECTION_MENU
call GetCGBLayout ; apply and commit pals
call SetPalettes
ld c, 20 ;
call DelayFrames ; page shown --> page and textbox shown
call LevelSelectionMenu_PrintLevelAndLandmarkNameAndStageIndicators
call LevelSelectionMenu_DrawStageTrophies
call LevelSelectionMenu_RefreshTextboxAttrs
ld c, 60
call DelayFrames
ld b, RGBFADE_TO_BLACK_6BGP_1OBP2
call DoRGBFadeEffect
ld c, 30 ;
call DelayFrames ; black screen --> next landmark shown
.invalid_level
pop hl
jr .show_unlocked_levels_loop
.load_default_landmark
ld a, [wDefaultLevelSelectionMenuLandmark] ld a, [wDefaultLevelSelectionMenuLandmark]
ld [wLevelSelectionMenuCurrentLandmark], a ld [wLevelSelectionMenuCurrentLandmark], a
call LevelSelectionMenu_GetLandmarkPage call LevelSelectionMenu_GetLandmarkPage
@ -24,11 +79,7 @@ LevelSelectionMenu::
ld a, TRUE ld a, TRUE
ld [wLevelSelectionMenuStandingStill], a ld [wLevelSelectionMenuStandingStill], a
call LevelSelectionMenu_InitTilemap call LevelSelectionMenu_DrawTilemapAndAttrmap
call LevelSelectionMenu_InitAttrmap
call WaitBGMap2
xor a
ldh [hBGMapMode], a
call LevelSelectionMenu_DrawTimeOfDaySymbol call LevelSelectionMenu_DrawTimeOfDaySymbol
ld b, CGB_LEVEL_SELECTION_MENU ld b, CGB_LEVEL_SELECTION_MENU
call GetCGBLayout ; apply and commit pals call GetCGBLayout ; apply and commit pals
@ -38,7 +89,6 @@ LevelSelectionMenu::
call PlayMusic call PlayMusic
call DelayFrame ; wait for pal update call DelayFrame ; wait for pal update
ld a, [wLevelSelectionMenuCurrentLandmark]
call LevelSelectionMenu_InitPlayerSprite call LevelSelectionMenu_InitPlayerSprite
call LevelSelectionMenu_InitLandmark call LevelSelectionMenu_InitLandmark
call LevelSelectionMenu_PrintLevelAndLandmarkNameAndStageIndicators call LevelSelectionMenu_PrintLevelAndLandmarkNameAndStageIndicators
@ -136,6 +186,7 @@ LevelSelectionMenu::
call PlaySFX call PlaySFX
call LevelSelectionMenu_Delay10Frames call LevelSelectionMenu_Delay10Frames
call .EnterLevelFadeOut call .EnterLevelFadeOut
call WaitSFX
scf scf
ret ret
@ -231,10 +282,17 @@ LevelSelectionMenu_InitAttrmap:
jr nz, .loop jr nz, .loop
ret ret
LevelSelectionMenu_DrawTilemapAndAttrmap:
call LevelSelectionMenu_InitTilemap
call LevelSelectionMenu_InitAttrmap
call WaitBGMap2
xor a
ldh [hBGMapMode], a
ret
LevelSelectionMenu_InitPlayerSprite: LevelSelectionMenu_InitPlayerSprite:
; initialize the anim struct of the player's sprite. ; initialize the anim struct of the player's sprite.
; because ClearSpriteAnims was called before, it's always loaded to wSpriteAnim1 ; because ClearSpriteAnims was called before, it's always loaded to wSpriteAnim1
push af
depixel 0, 0 depixel 0, 0
; all the SPRITE_ANIM_* related to the level selection menu are sorted by direction, then by gender ; all the SPRITE_ANIM_* related to the level selection menu are sorted by direction, then by gender
ld b, SPRITE_ANIM_OBJ_LEVEL_SELECTION_MENU_MALE_WALK_DOWN ld b, SPRITE_ANIM_OBJ_LEVEL_SELECTION_MENU_MALE_WALK_DOWN
@ -244,7 +302,7 @@ LevelSelectionMenu_InitPlayerSprite:
ld hl, SPRITEANIMSTRUCT_TILE_ID ld hl, SPRITEANIMSTRUCT_TILE_ID
add hl, bc add hl, bc
ld [hl], $00 ld [hl], $00
pop af ld a, [wLevelSelectionMenuCurrentLandmark]
ld e, a ld e, a
call LevelSelectionMenu_GetLandmarkCoords call LevelSelectionMenu_GetLandmarkCoords
; wSpriteAnim1*Coord contain the coord of the bottom right object of the player sprite ; wSpriteAnim1*Coord contain the coord of the bottom right object of the player sprite
@ -747,11 +805,7 @@ ENDM
; set new page and redraw screen ; set new page and redraw screen
call LevelSelectionMenu_GetNewPage call LevelSelectionMenu_GetNewPage
ld [wLevelSelectionMenuCurrentPage], a ld [wLevelSelectionMenuCurrentPage], a
call LevelSelectionMenu_InitTilemap call LevelSelectionMenu_DrawTilemapAndAttrmap
call LevelSelectionMenu_InitAttrmap
call WaitBGMap2
xor a
ldh [hBGMapMode], a
call .PageChangeFadeIn call .PageChangeFadeIn
; adjust steps left for the "duplicate" movement of the player leaving and entering a page ; adjust steps left for the "duplicate" movement of the player leaving and entering a page
ld hl, wLevelSelectionMenuMovementStepsLeft ld hl, wLevelSelectionMenuMovementStepsLeft

View File

@ -40,4 +40,4 @@ AdvanceTimeOfDay::
ret ret
.TimeOfDayOrder: .TimeOfDayOrder:
db MORN_F, DAY_F, NITE_F, EVE_F, MORN_F db MORN_F, DAY_F, EVE_F, NITE_F, MORN_F

View File

@ -55,14 +55,6 @@ MACRO rgbpals_fade_apply
PURGE fade_from, fade_to, rgbch_red, rgbch_green, rgbch_blue, palred_value, palgreen_value, palblue_value PURGE fade_from, fade_to, rgbch_red, rgbch_green, rgbch_blue, palred_value, palgreen_value, palblue_value
ENDM ENDM
/* MACRO rgbpals_fade_end
rept _NARG
for i,
endr
shift
endr
ENDM */
DEF palettes EQUS "* PALETTE_SIZE" DEF palettes EQUS "* PALETTE_SIZE"
DEF palette EQUS "+ PALETTE_SIZE *" DEF palette EQUS "+ PALETTE_SIZE *"
DEF color EQUS "+ PAL_COLOR_SIZE *" DEF color EQUS "+ PAL_COLOR_SIZE *"

View File

@ -2546,6 +2546,7 @@ wKurtApricornQuantity:: db
wCurLevel:: db wCurLevel:: db
wDefaultLevelSelectionMenuLandmark:: db wDefaultLevelSelectionMenuLandmark:: db
wCurOverworldMiscPal:: db wCurOverworldMiscPal:: db
wLevelSelectionMenuEntryEventQueue:: flag_array NUM_LSM_EVENTS
wPlayerDataEnd:: wPlayerDataEnd::