diff --git a/data/level_selection_menu.asm b/data/level_selection_menu.asm index 7c812ea40..3773472c3 100755 --- a/data/level_selection_menu.asm +++ b/data/level_selection_menu.asm @@ -28,6 +28,7 @@ LevelSelectionMenu_Landmarks: MACRO level_selection_menu_landmark_transition ; any number of (direction, num_steps (in tiles)) pairs + const_skip if (\2 != FALSE) rept ((_NARG + -1) / 2) ; repeat once for each (direction, num_steps) pair @@ -41,6 +42,9 @@ endc ENDM LevelSelectionMenu_LandmarkTransitions: +; the transitions are arranged by direction according to wWalkingDirection constants + const_def + ; LANDMARK_LEVEL_1 level_selection_menu_landmark_transition DOWN, 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 RIGHT, FALSE +assert const_value == NUM_LANDMARKS * NUM_DIRECTIONS + LevelSelectionMenu_PageGrid: db -1, -1, -1, -1 db -1, 2, 3, -1 diff --git a/engine/gfx/sprites.asm b/engine/gfx/sprites.asm index 5133987a8..9c5b72ae0 100644 --- a/engine/gfx/sprites.asm +++ b/engine/gfx/sprites.asm @@ -55,11 +55,16 @@ DoNextFrameForAllSprites: dec e jr nz, .loop + ld a, [wVramState] + bit 2, a + ret nz + +; Clear (wShadowOAM + [wCurSpriteOAMAddr] --> wShadowOAMEnd) ld a, [wCurSpriteOAMAddr] ld l, a ld h, HIGH(wShadowOAM) -.loop2 ; Clear (wShadowOAM + [wCurSpriteOAMAddr] --> wShadowOAMEnd) +.loop2 ld a, l cp LOW(wShadowOAMEnd) jr nc, .done diff --git a/engine/menus/level_selection_menu.asm b/engine/menus/level_selection_menu.asm index 07ca7e6cb..9ba70172a 100755 --- a/engine/menus/level_selection_menu.asm +++ b/engine/menus/level_selection_menu.asm @@ -1,6 +1,7 @@ LevelSelectionMenu:: xor a ldh [hInMenu], a + ld a, 1 << 2 ; do not clear wShadowOAM during DoNextFrameForAllSprites ld [wVramState], a call ClearBGPalettes @@ -33,13 +34,17 @@ LevelSelectionMenu:: ld a, [wLevelSelectionMenuCurrentLandmark] call LevelSelectionMenu_InitPlayerSprite + call LevelSelectionMenu_InitLandmark + call LevelSelectionMenu_DrawDirectionalArrows .main_loop farcall PlaySpriteAnimations call DelayFrame call JoyTextDelay + call LevelSelectionMenu_GetValidKeys ld hl, hJoyPressed ld a, [hl] + and c bit A_BUTTON_F, a jp nz, .enter_level bit B_BUTTON_F, a @@ -79,6 +84,8 @@ LevelSelectionMenu:: call ClearBGPalettes call ClearTilemap call ClearSprites + xor a + ld [wVramState], a ld c, 20 call DelayFrames @@ -105,9 +112,12 @@ LevelSelectionMenu:: call ClearBGPalettes call ClearTilemap call ClearSprites + xor a + ld [wVramState], a ret LevelSelectionMenu_LoadGFX: +; load gfx for the background tiles, and for the player and directional arrow sprites ld hl, LevelSelectionMenuGFX ld de, vTiles2 call Decompress @@ -118,6 +128,10 @@ LevelSelectionMenu_LoadGFX: ld de, vTiles0 ld bc, 24 tiles call FarCopyBytes + ld hl, LevelSelectionMenuDirectionalArrowsGFX +; ld de, vTiles0 + 24 tiles + ld bc, 4 tiles + call FarCopyBytes ret LevelSelectionMenu_InitTilemap: @@ -170,6 +184,78 @@ LevelSelectionMenu_InitPlayerSprite: ld [hl], d 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: ; Return page number (a) of landmark a. push hl @@ -233,6 +319,80 @@ LevelSelectionMenu_GetLandmarkSpawnPoint: pop hl 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_