Level selection menu: function to compute valid directions and directional arrows OAM (#12)

This commit is contained in:
xCrystal 2023-08-22 12:42:53 +02:00
parent c6601a79d3
commit e866cdab48
7 changed files with 197 additions and 1 deletions

View File

@ -28,6 +28,7 @@ LevelSelectionMenu_Landmarks:
MACRO level_selection_menu_landmark_transition MACRO level_selection_menu_landmark_transition
; any number of (direction, num_steps (in tiles)) pairs ; any number of (direction, num_steps (in tiles)) pairs
const_skip
if (\2 != FALSE) if (\2 != FALSE)
rept ((_NARG + -1) / 2) ; repeat once for each (direction, num_steps) pair rept ((_NARG + -1) / 2) ; repeat once for each (direction, num_steps) pair
@ -41,6 +42,9 @@ endc
ENDM ENDM
LevelSelectionMenu_LandmarkTransitions: LevelSelectionMenu_LandmarkTransitions:
; the transitions are arranged by direction according to wWalkingDirection constants
const_def
; LANDMARK_LEVEL_1 ; LANDMARK_LEVEL_1
level_selection_menu_landmark_transition DOWN, FALSE level_selection_menu_landmark_transition DOWN, FALSE
level_selection_menu_landmark_transition UP, FALSE level_selection_menu_landmark_transition UP, FALSE
@ -71,6 +75,8 @@ LevelSelectionMenu_LandmarkTransitions:
level_selection_menu_landmark_transition LEFT, FALSE level_selection_menu_landmark_transition LEFT, FALSE
level_selection_menu_landmark_transition RIGHT, FALSE level_selection_menu_landmark_transition RIGHT, FALSE
assert const_value == NUM_LANDMARKS * NUM_DIRECTIONS
LevelSelectionMenu_PageGrid: LevelSelectionMenu_PageGrid:
db -1, -1, -1, -1 db -1, -1, -1, -1
db -1, 2, 3, -1 db -1, 2, 3, -1

View File

@ -55,11 +55,16 @@ DoNextFrameForAllSprites:
dec e dec e
jr nz, .loop jr nz, .loop
ld a, [wVramState]
bit 2, a
ret nz
; Clear (wShadowOAM + [wCurSpriteOAMAddr] --> wShadowOAMEnd)
ld a, [wCurSpriteOAMAddr] ld a, [wCurSpriteOAMAddr]
ld l, a ld l, a
ld h, HIGH(wShadowOAM) ld h, HIGH(wShadowOAM)
.loop2 ; Clear (wShadowOAM + [wCurSpriteOAMAddr] --> wShadowOAMEnd) .loop2
ld a, l ld a, l
cp LOW(wShadowOAMEnd) cp LOW(wShadowOAMEnd)
jr nc, .done jr nc, .done

View File

@ -1,6 +1,7 @@
LevelSelectionMenu:: LevelSelectionMenu::
xor a xor a
ldh [hInMenu], a ldh [hInMenu], a
ld a, 1 << 2 ; do not clear wShadowOAM during DoNextFrameForAllSprites
ld [wVramState], a ld [wVramState], a
call ClearBGPalettes call ClearBGPalettes
@ -33,13 +34,17 @@ LevelSelectionMenu::
ld a, [wLevelSelectionMenuCurrentLandmark] ld a, [wLevelSelectionMenuCurrentLandmark]
call LevelSelectionMenu_InitPlayerSprite call LevelSelectionMenu_InitPlayerSprite
call LevelSelectionMenu_InitLandmark
call LevelSelectionMenu_DrawDirectionalArrows
.main_loop .main_loop
farcall PlaySpriteAnimations farcall PlaySpriteAnimations
call DelayFrame call DelayFrame
call JoyTextDelay call JoyTextDelay
call LevelSelectionMenu_GetValidKeys
ld hl, hJoyPressed ld hl, hJoyPressed
ld a, [hl] ld a, [hl]
and c
bit A_BUTTON_F, a bit A_BUTTON_F, a
jp nz, .enter_level jp nz, .enter_level
bit B_BUTTON_F, a bit B_BUTTON_F, a
@ -79,6 +84,8 @@ LevelSelectionMenu::
call ClearBGPalettes call ClearBGPalettes
call ClearTilemap call ClearTilemap
call ClearSprites call ClearSprites
xor a
ld [wVramState], a
ld c, 20 ld c, 20
call DelayFrames call DelayFrames
@ -105,9 +112,12 @@ LevelSelectionMenu::
call ClearBGPalettes call ClearBGPalettes
call ClearTilemap call ClearTilemap
call ClearSprites call ClearSprites
xor a
ld [wVramState], a
ret ret
LevelSelectionMenu_LoadGFX: LevelSelectionMenu_LoadGFX:
; load gfx for the background tiles, and for the player and directional arrow sprites
ld hl, LevelSelectionMenuGFX ld hl, LevelSelectionMenuGFX
ld de, vTiles2 ld de, vTiles2
call Decompress call Decompress
@ -118,6 +128,10 @@ LevelSelectionMenu_LoadGFX:
ld de, vTiles0 ld de, vTiles0
ld bc, 24 tiles ld bc, 24 tiles
call FarCopyBytes call FarCopyBytes
ld hl, LevelSelectionMenuDirectionalArrowsGFX
; ld de, vTiles0 + 24 tiles
ld bc, 4 tiles
call FarCopyBytes
ret ret
LevelSelectionMenu_InitTilemap: LevelSelectionMenu_InitTilemap:
@ -170,6 +184,78 @@ LevelSelectionMenu_InitPlayerSprite:
ld [hl], d ld [hl], d
ret ret
LevelSelectionMenu_InitLandmark:
; make wLevelSelectionMenuCurrentLandmarkTransitionsPointer point
; to the start of the transition data of the current landmark.
ld a, [wLevelSelectionMenuCurrentLandmark]
ld e, a
ld hl, LevelSelectionMenu_LandmarkTransitions
ld b, -1
rept NUM_DIRECTIONS
ld c, e
call AdvanceNEntries
endr
ld de, wLevelSelectionMenuCurrentLandmarkTransitionsPointer
ld a, l
ld [de], a
inc de
ld a, h
ld [de], a
ret
LevelSelectionMenu_DrawDirectionalArrows:
; Draw directional arrows OAM around player sprite for the valid directions.
; Objects are drawn in OAM after player sprite objects in wWalkingDirection order.
; Depends on wLevelSelectionMenuCurrentLandmarkTransitionsPointer being initialized.
call LevelSelectionMenu_GetValidDirections
ld hl, .OAM
ld de, wShadowOAM + 4 * SPRITEOAMSTRUCT_LENGTH ; always goes after player sprite
bit D_DOWN_F, c
jr z, .next1
call .DrawArrow
.next1
ld hl, .OAM + $3
bit D_UP_F, c
jr z, .next2
call .DrawArrow
.next2
ld hl, .OAM + $6
bit D_LEFT_F, c
jr z, .next3
call .DrawArrow
.next3
ld hl, .OAM + $9
bit D_RIGHT_F, c
call nz, .DrawArrow
ret
.DrawArrow:
ld a, [wSpriteAnim1YCoord]
add [hl]
ld [de], a ; y coord
inc hl
inc de
ld a, [wSpriteAnim1XCoord]
add [hl]
ld [de], a ; x coord
inc hl
inc de
ld a, [hli]
ld [de], a ; tile id
inc de
gender_to_pal
ld [de], a ; attr (use the same pal as player sprite)
inc de
ret
.OAM:
; y offset against wSpriteAnim1YCoord, x offset against wSpriteAnim1XCoord, tile id
; tiles have been loaded to vTiles0 after the player sprites
db 8, -4, 24 + DOWN
db -16, -4, 24 + UP
db -4, -16, 24 + LEFT
db -4, 8, 24 + RIGHT
LevelSelectionMenu_GetLandmarkPage: LevelSelectionMenu_GetLandmarkPage:
; Return page number (a) of landmark a. ; Return page number (a) of landmark a.
push hl push hl
@ -233,6 +319,80 @@ LevelSelectionMenu_GetLandmarkSpawnPoint:
pop hl pop hl
ret ret
LevelSelectionMenu_GetValidKeys:
call LevelSelectionMenu_GetValidDirections
ld a, c
or A_BUTTON | B_BUTTON | SELECT | START
ld c, a
ret
LevelSelectionMenu_GetValidDirections:
; Return the valid directions according to landmark transitions and unlocked levels.
; Depends on wLevelSelectionMenuCurrentLandmarkTransitionsPointer being initialized.
; Return the result in c as a mask of D_<DIR>_F.
ld hl, wLevelSelectionMenuCurrentLandmarkTransitionsPointer
ld a, [hli]
ld h, [hl]
ld l, a
ld c, 0
ld a, [hli]
inc a
jr z, .next1
.loop1
ld a, [hli]
inc a
jr nz, .loop1
call .IsLevelUnlocked
jr z, .next1
set D_DOWN_F, c
.next1
ld a, [hli]
inc a
jr z, .next2
.loop2
ld a, [hli]
inc a
jr nz, .loop2
call .IsLevelUnlocked
jr z, .next2
set D_UP_F, c
.next2
ld a, [hli]
inc a
jr z, .next3
.loop3
ld a, [hli]
inc a
jr nz, .loop3
call .IsLevelUnlocked
jr z, .next3
set D_LEFT_F, c
.next3
ld a, [hli]
inc a
ret z
.loop4
ld a, [hli]
inc a
jr nz, .loop4
call .IsLevelUnlocked
ret z
set D_RIGHT_F, c
ret
.IsLevelUnlocked:
push hl
push bc
; the landmark byte of this transition is two bytes back
dec hl
dec hl
ld e, [hl]
ld b, CHECK_FLAG
call UnlockedLevelsFlagAction
pop bc
pop hl
ret
LevelSelectionMenu_Delay10Frames: LevelSelectionMenu_Delay10Frames:
; Delay 10 frames while playing sprite anims ; Delay 10 frames while playing sprite anims
ld a, 10 ld a, 10
@ -261,3 +421,6 @@ INCBIN "gfx/level_selection_menu/page_3.tilemap"
LevelSelectionMenuPage4Tilemap: LevelSelectionMenuPage4Tilemap:
INCBIN "gfx/level_selection_menu/page_4.tilemap" INCBIN "gfx/level_selection_menu/page_4.tilemap"
LevelSelectionMenuDirectionalArrowsGFX:
INCBIN "gfx/level_selection_menu/directional_arrows.2bpp"

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

View File

@ -42,3 +42,16 @@ AddNTimes::
dec a dec a
jr nz, .loop jr nz, .loop
ret ret
; advance c [b]-terminated table entries in hl
AdvanceNEntries::
ld a, c
and a
ret z
.loop
ld a, [hli]
cp b
jr nz, .loop
dec c
jr nz, .loop
ret

View File

@ -94,3 +94,10 @@ if _NARG == 0
sine_table 32 sine_table 32
endc endc
ENDM ENDM
; Abstractions
MACRO gender_to_pal
; preserve all registers but a
ld a, [wPlayerGender]
ENDM

View File

@ -1536,6 +1536,7 @@ SECTION UNION "Miscellaneous WRAM 1", WRAMX
; level selection menu ; level selection menu
wLevelSelectionMenuCurrentPage:: db wLevelSelectionMenuCurrentPage:: db
wLevelSelectionMenuCurrentLandmark:: db wLevelSelectionMenuCurrentLandmark:: db
wLevelSelectionMenuCurrentLandmarkTransitionsPointer:: dw
wLevelSelectionMenuStandingStill:: db wLevelSelectionMenuStandingStill:: db
@ -1726,6 +1727,7 @@ wSolvedUnownPuzzle::
wVramState:: wVramState::
; bit 0: overworld sprite updating on/off ; bit 0: overworld sprite updating on/off
; bit 1: something to do with sprite updates ; bit 1: something to do with sprite updates
; bit 2: do not clear wShadowOAM during DoNextFrameForAllSprites
; bit 6: something to do with text ; bit 6: something to do with text
; bit 7: on when surf initiates ; bit 7: on when surf initiates
; flickers when climbing waterfall ; flickers when climbing waterfall