mirror of
https://gitlab.com/xCrystal/pokecrystal-board.git
synced 2024-11-16 11:27:33 -08:00
Level selection menu: main logic of landmark transitions involving page change (#12)
This commit is contained in:
parent
d5dc7b38df
commit
f067112be6
@ -1,9 +1,14 @@
|
||||
; TILE_WIDTH represents the top/left border tile, $8/$10 represent the OAM screen position offsets, and 4 are custom offsets
|
||||
; TILE_WIDTH represents the top/left border tile, $8/$10 represent the OAM screen position offsets,
|
||||
; and 4 are custom offsets to make the player sprite centered in a 8x8 tile rather than in a 16x16 square.
|
||||
DEF LEVELSELECTIONMENU_LANDMARK_OFFSET_X EQU TILE_WIDTH + $8 + 4
|
||||
DEF LEVELSELECTIONMENU_LANDMARK_OFFSET_Y EQU TILE_WIDTH + $10 + 4
|
||||
|
||||
MACRO level_selection_menu_landmark
|
||||
; page number, xcoord (in tiles), ycoord (in tiles), ptr to name, spawn point (SPAWN_*)
|
||||
; xcoord ranges between 0 and 17 (SCREEN_WIDTH points minus two)
|
||||
; when crossing pages, x=17 and x=0 are adjacent (one tile apart)
|
||||
; ycoord ranges between 0 and 13 (SCREEN_HEIGH points minus four)
|
||||
; when crossing pages, y=13 and y=0 are adjacent (one tile apart)
|
||||
db \1
|
||||
db LEVELSELECTIONMENU_LANDMARK_OFFSET_X + \2 * TILE_WIDTH
|
||||
db LEVELSELECTIONMENU_LANDMARK_OFFSET_Y + \3 * TILE_WIDTH
|
||||
@ -58,20 +63,20 @@ LevelSelectionMenu_LandmarkTransitions:
|
||||
level_selection_menu_landmark_transition RIGHT, FALSE
|
||||
|
||||
; LANDMARK_LEVEL_3
|
||||
level_selection_menu_landmark_transition DOWN, 6, LANDMARK_LEVEL_5
|
||||
level_selection_menu_landmark_transition DOWN, 7, DOWN, 1, LANDMARK_LEVEL_5
|
||||
level_selection_menu_landmark_transition UP, 5, RIGHT, 2, DOWN, 3, LANDMARK_LEVEL_2
|
||||
level_selection_menu_landmark_transition LEFT, 7, LEFT, 2, LANDMARK_LEVEL_4
|
||||
level_selection_menu_landmark_transition LEFT, 7, LEFT, 4, LANDMARK_LEVEL_4
|
||||
level_selection_menu_landmark_transition RIGHT, 7, LANDMARK_LEVEL_1
|
||||
|
||||
; LANDMARK_LEVEL_4
|
||||
level_selection_menu_landmark_transition DOWN, FALSE
|
||||
level_selection_menu_landmark_transition UP, FALSE
|
||||
level_selection_menu_landmark_transition LEFT, FALSE
|
||||
level_selection_menu_landmark_transition RIGHT, 7, RIGHT, 2, LANDMARK_LEVEL_3
|
||||
level_selection_menu_landmark_transition RIGHT, 7, RIGHT, 4, LANDMARK_LEVEL_3
|
||||
|
||||
; LANDMARK_LEVEL_5
|
||||
level_selection_menu_landmark_transition DOWN, FALSE
|
||||
level_selection_menu_landmark_transition UP, 6, LANDMARK_LEVEL_3
|
||||
level_selection_menu_landmark_transition UP, 7, UP, 1, LANDMARK_LEVEL_3
|
||||
level_selection_menu_landmark_transition LEFT, FALSE
|
||||
level_selection_menu_landmark_transition RIGHT, FALSE
|
||||
|
||||
@ -79,8 +84,9 @@ assert const_value == NUM_LANDMARKS * NUM_DIRECTIONS
|
||||
|
||||
LevelSelectionMenu_PageGrid:
|
||||
db -1, -1, -1, -1
|
||||
db -1, 2, 3, -1
|
||||
db -1, 0, 1, -1
|
||||
db -1, 1, 0, -1
|
||||
db -1, 3, 2, -1
|
||||
db -1, -1, -1, -1
|
||||
|
||||
DEF LEVELSELECTIONMENU_PAGE_GRID_WIDTH EQU 4
|
||||
DEF LEVELSELECTIONMENU_PAGE_GRID_WIDTH EQU 4
|
||||
DEF LEVELSELECTIONMENU_PAGE_GRID_HEIGHT EQU 4
|
||||
|
@ -29,6 +29,8 @@ LevelSelectionMenu::
|
||||
ld b, CGB_LEVEL_SELECTION_MENU
|
||||
call GetCGBLayout ; apply and commit attrmap (takes 4 frames) and pals
|
||||
call SetPalettes
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
|
||||
ld de, MUSIC_GAME_CORNER
|
||||
call PlayMusic
|
||||
@ -105,6 +107,7 @@ LevelSelectionMenu::
|
||||
; by setting wLevelSelectionMenuStandingStill to TRUE
|
||||
farcall PlaySpriteAnimations
|
||||
call DelayFrame
|
||||
call LevelSelectionMenu_DoPageChangeEvent
|
||||
ld a, [wLevelSelectionMenuStandingStill]
|
||||
and a
|
||||
jr z, .wait_transition_loop
|
||||
@ -136,8 +139,8 @@ LevelSelectionMenu::
|
||||
call DelayFrames
|
||||
|
||||
ld a, [wLevelSelectionMenuCurrentLandmark]
|
||||
ld [wDefaultSpawnpoint], a
|
||||
call LevelSelectionMenu_GetLandmarkSpawnPoint
|
||||
ld [wDefaultSpawnpoint], a
|
||||
ld a, MAPSETUP_WARP
|
||||
ld [hMapEntryMethod], a
|
||||
xor a
|
||||
@ -210,13 +213,10 @@ LevelSelectionMenu_InitPlayerSprite:
|
||||
; because ClearSpriteAnims was called before, it's always loaded to wSpriteAnim1
|
||||
push af
|
||||
depixel 0, 0
|
||||
; all the SPRITE_ANIM_* related to the level selection menu are sorted by direction, then by gender
|
||||
ld b, SPRITE_ANIM_INDEX_LEVEL_SELECTION_MENU_MALE_WALK_DOWN
|
||||
ld a, [wPlayerGender]
|
||||
bit PLAYERGENDER_FEMALE_F, a
|
||||
jr z, .got_gender
|
||||
ld b, SPRITE_ANIM_INDEX_LEVEL_SELECTION_MENU_FEMALE_WALK_DOWN
|
||||
.got_gender
|
||||
ld a, b
|
||||
add b
|
||||
call InitSpriteAnimStruct
|
||||
ld hl, SPRITEANIMSTRUCT_TILE_ID
|
||||
add hl, bc
|
||||
@ -224,6 +224,7 @@ LevelSelectionMenu_InitPlayerSprite:
|
||||
pop af
|
||||
ld e, a
|
||||
call LevelSelectionMenu_GetLandmarkCoords
|
||||
; wSpriteAnim1*Coord contain the coord of the bottom right object of the player sprite
|
||||
ld hl, SPRITEANIMSTRUCT_XCOORD
|
||||
add hl, bc
|
||||
ld [hl], e
|
||||
@ -330,6 +331,146 @@ LevelSelectionMenu_SetAnimSeqAndFrameset:
|
||||
ld [hl], a
|
||||
ret
|
||||
|
||||
LevelSelectionMenu_DoPageChangeEvent:
|
||||
ld de, .Events
|
||||
ld bc, wSpriteAnim1
|
||||
.loop
|
||||
ld a, [de] ; SPRITE_ANIM_SEQ_* or $00 table terminator
|
||||
and a
|
||||
ret z
|
||||
inc de
|
||||
ld hl, SPRITEANIMSTRUCT_ANIM_SEQ_ID
|
||||
add hl, bc
|
||||
cp [hl]
|
||||
jr nz, .next1
|
||||
ld a, [de] ; SPRITEANIMSTRUCT_YCOORD or SPRITEANIMSTRUCT_XCOORD
|
||||
ld l, a
|
||||
ld h, 0
|
||||
add hl, bc
|
||||
inc de
|
||||
ld a, [de] ; X/Y coordinate
|
||||
cp [hl]
|
||||
jr nz, .next2
|
||||
|
||||
; this entry matches
|
||||
inc de
|
||||
ld a, [de]
|
||||
ld l, a
|
||||
inc de
|
||||
ld a, [de]
|
||||
ld h, a
|
||||
jp hl
|
||||
|
||||
.next1
|
||||
inc de
|
||||
.next2
|
||||
inc de
|
||||
inc de
|
||||
inc de
|
||||
jr .loop
|
||||
|
||||
; LEVELSELECTIONMENU_PAGE_EDGE_* represent values when the player sprite is at:
|
||||
; UU
|
||||
; =========UU=========
|
||||
; =------------------=
|
||||
; =------------------=
|
||||
; =------------------=
|
||||
; =------------------=
|
||||
; =------------------=
|
||||
; =------------------=
|
||||
; =------------------=
|
||||
;LL------------------RR
|
||||
;LL------------------RR
|
||||
; =------------------=
|
||||
; =------------------=
|
||||
; =------------------=
|
||||
; =------------------=
|
||||
; =------------------=
|
||||
; =========DD=========
|
||||
; =========DD=========
|
||||
; ====================
|
||||
; for movements spanning two pages, when one edge is reached, the page change occurs
|
||||
; and the player appears in the other page at the coordinate of the new edge.
|
||||
; hence, for calculating movement length, it's as if both pages were adjacent without the border frame.
|
||||
DEF PAGE_EDGE_DOWN EQU $90
|
||||
DEF PAGE_EDGE_UP EQU $10
|
||||
DEF PAGE_EDGE_LEFT EQU $08
|
||||
DEF PAGE_EDGE_RIGHT EQU $a8
|
||||
|
||||
DEF PAGE_CHANGE_FADE_FRAMES EQU 16
|
||||
DEF PAGE_CHANGE_NON_FADE_FRAMES EQU 13
|
||||
; total frame delay of page change is 16 + 13 + 16 = 45 frames
|
||||
|
||||
MACRO page_change_event
|
||||
; SPRITE_ANIM_SEQ_* to match, Match object's X or Y, X/Y coordinate, Action if both SPRITE_ANIM_SEQ_* and X/Y match
|
||||
db \1, \2, \3
|
||||
dw \4
|
||||
ENDM
|
||||
|
||||
.Events:
|
||||
page_change_event SPRITE_ANIM_SEQ_LEVEL_SELECTION_MENU_WALK_DOWN, SPRITEANIMSTRUCT_YCOORD, PAGE_EDGE_DOWN, .PageChangeDown
|
||||
page_change_event SPRITE_ANIM_SEQ_LEVEL_SELECTION_MENU_WALK_UP, SPRITEANIMSTRUCT_YCOORD, PAGE_EDGE_UP, .PageChangeUp
|
||||
page_change_event SPRITE_ANIM_SEQ_LEVEL_SELECTION_MENU_WALK_LEFT, SPRITEANIMSTRUCT_XCOORD, PAGE_EDGE_LEFT, .PageChangeLeft
|
||||
page_change_event SPRITE_ANIM_SEQ_LEVEL_SELECTION_MENU_WALK_RIGHT, SPRITEANIMSTRUCT_XCOORD, PAGE_EDGE_RIGHT, .PageChangeRight
|
||||
db $0
|
||||
|
||||
.PageChangeDown:
|
||||
call .PageChangeFadeOut
|
||||
ld a, PAGE_EDGE_UP
|
||||
ld [wSpriteAnim1YCoord], a ; respawn in opposite edge
|
||||
ld e, DOWN
|
||||
jr .PageChange_Common
|
||||
|
||||
.PageChangeUp:
|
||||
call .PageChangeFadeOut
|
||||
ld a, PAGE_EDGE_DOWN
|
||||
ld [wSpriteAnim1YCoord], a ; respawn in opposite edge
|
||||
ld e, UP
|
||||
jr .PageChange_Common
|
||||
|
||||
.PageChangeLeft:
|
||||
call .PageChangeFadeOut
|
||||
ld a, PAGE_EDGE_RIGHT
|
||||
ld [wSpriteAnim1XCoord], a ; respawn in opposite edge
|
||||
ld e, LEFT
|
||||
jr .PageChange_Common
|
||||
|
||||
.PageChangeRight:
|
||||
call .PageChangeFadeOut
|
||||
ld a, PAGE_EDGE_LEFT
|
||||
ld [wSpriteAnim1XCoord], a ; respawn in opposite edge
|
||||
ld e, RIGHT
|
||||
jr .PageChange_Common
|
||||
|
||||
.PageChange_Common:
|
||||
; set new page and redraw screen
|
||||
call LevelSelectionMenu_GetNewPage
|
||||
ld [wLevelSelectionMenuCurrentPage], a
|
||||
call LevelSelectionMenu_InitTilemap
|
||||
ld b, CGB_LEVEL_SELECTION_MENU
|
||||
call GetCGBLayout
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
ld c, PAGE_CHANGE_NON_FADE_FRAMES
|
||||
call DelayFrames
|
||||
call .PageChangeFadeIn
|
||||
; adjust steps left for the "duplicate" movement of the player leaving and entering a page
|
||||
ld hl, wLevelSelectionMenuMovementStepsLeft
|
||||
ld a, [hl]
|
||||
add 2 * TILE_WIDTH
|
||||
ld [hl], a
|
||||
ret
|
||||
|
||||
.PageChangeFadeOut:
|
||||
ld c, PAGE_CHANGE_FADE_FRAMES
|
||||
call DelayFrames
|
||||
ret
|
||||
|
||||
.PageChangeFadeIn:
|
||||
ld c, PAGE_CHANGE_FADE_FRAMES
|
||||
call DelayFrames
|
||||
ret
|
||||
|
||||
LevelSelectionMenu_GetLandmarkPage:
|
||||
; Return page number (a) of landmark a.
|
||||
push hl
|
||||
@ -467,6 +608,42 @@ LevelSelectionMenu_GetValidDirections:
|
||||
pop hl
|
||||
ret
|
||||
|
||||
LevelSelectionMenu_GetNewPage:
|
||||
; return in a the new page that the player is ending up at during this movement involving page change.
|
||||
; direction (in wWalkingDirection order) is provided in e.
|
||||
ld hl, LevelSelectionMenu_PageGrid - 1
|
||||
ld c, LEVELSELECTIONMENU_PAGE_GRID_WIDTH * LEVELSELECTIONMENU_PAGE_GRID_HEIGHT + 1
|
||||
.loop
|
||||
inc hl
|
||||
dec c
|
||||
jr z, .out_of_bounds
|
||||
ld a, [wLevelSelectionMenuCurrentPage]
|
||||
cp [hl]
|
||||
jr nz, .loop
|
||||
|
||||
; find the next page in the grid according to movement direction
|
||||
ld a, e
|
||||
ld bc, LEVELSELECTIONMENU_PAGE_GRID_WIDTH
|
||||
cp DOWN
|
||||
jr z, .ok
|
||||
ld bc, -LEVELSELECTIONMENU_PAGE_GRID_WIDTH
|
||||
cp UP
|
||||
jr z, .ok
|
||||
ld bc, -1
|
||||
cp LEFT
|
||||
jr z, .ok
|
||||
ld bc, 1
|
||||
.ok
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
cp -1
|
||||
jr z, .out_of_bounds
|
||||
ret
|
||||
|
||||
.out_of_bounds
|
||||
ld a, 1
|
||||
ret
|
||||
|
||||
LevelSelectionMenu_Delay10Frames:
|
||||
; Delay 10 frames while playing sprite anims
|
||||
ld a, 10
|
||||
@ -500,9 +677,11 @@ _LevelSelectionMenuHandleTransition:
|
||||
.not_first_step
|
||||
and a
|
||||
jr z, .movement_over
|
||||
; one less step left to finish this movement
|
||||
|
||||
; one less step left to finish this movement
|
||||
dec a
|
||||
ld [de], a
|
||||
.done
|
||||
; return carry to signal back to apply a displacement during this frame
|
||||
scf
|
||||
ret
|
||||
|
Loading…
Reference in New Issue
Block a user