You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

291 lines
4.2 KiB

INCLUDE "hardware.inc"
INCLUDE "input.inc"
INCLUDE "oam.inc"
INCLUDE "util.inc"
Section "Player Data", WRAM0
playerWorldX: dw
playerWorldY: dw
; player data
PLAYER_X:: db
PLAYER_Y:: db
PLAYER_DIR:: db
PLAYER_JUMPING:: db
PLAYER_VY:: dw
PLAYER_OLD_Y: db
Section "Player Code", ROM0
spriteData:
INCBIN "png/sprite/player.2bpp"
DEF SPRITE_OAM_IDX EQU 0
DEF SPRITE_IDX EQU 32 ; tile index, rename later
DEF SPRITE_WIDTH EQU 2
DEF SPRITE_HEIGHT EQU 2
DEF GRAVITY EQU (0 << 8) | 8
DEF INIT_VY EQU (2 << 8) | 40
Player_Init::
; Clear player data
ld hl, PLAYER_X
ld [hl], 0
inc hl
ld [hl], 144-32
inc hl
ld [hl], 0
inc hl
ld [hl], 0
inc hl
ld [hl], 0
inc hl
ld [hl], 0
; Copy sprite to VRAM
ld bc, _VRAM8000 + SPRITE_IDX * 16
ld hl, spriteData
ld d, 16 * (SPRITE_WIDTH * SPRITE_HEIGHT)
call memcpy
; Initialize OAM entries with player state
call update_oam
ret
Player_Update::
ld hl, keys
ld b, [hl]
; check for jump
ld a, b
and BTN_UP
jr z, .update_jump
; initialize jump state if not already jumping
ld hl, PLAYER_JUMPING
ld a, [hl]
or a
jr nz, .update_jump
ld [hl], 1
ld hl, PLAYER_VY
ld [hl], HIGH(INIT_VY)
inc hl
ld [hl], LOW(INIT_VY)
.update_jump:
ld hl, PLAYER_JUMPING
ld a, [hl]
or a
jr z, .right
; load y velocity into bc
ld hl, PLAYER_VY
ld b, [hl]
inc hl
ld c, [hl]
; adjust velocity by gravity
ld a, c
sub LOW(GRAVITY)
ld c, a
ld a, b
sbc HIGH(GRAVITY)
ld b, a
ld hl, PLAYER_VY
STORE16 bc
; old_y = y
ld hl, PLAYER_Y
ld a, [hl]
ld hl, PLAYER_OLD_Y
ld [hl], a
; y -= floor(vy)
ld hl, PLAYER_Y
ld a, [hl]
sub b
ld [hl], a
; roll back jump if there was a collision
call player_bg_collides
jr nz, .update_jump_oam
ld hl, PLAYER_OLD_Y
ld a, [hl]
ld hl, PLAYER_Y
ld b, [hl]
ld hl, PLAYER_VY
ld [hl], 0
; if colliding below, stop jump state
cp b
jr nc, .right
ld hl, PLAYER_JUMPING
ld [hl], 0
.update_jump_oam:
call update_oam
; check for move right
.right:
ld hl, keys
ld a, [hl]
and BTN_RIGHT
jr z, .left
; check for right boundary
ld hl, PLAYER_X
ld a, [hl]
add 16
cp SCRN_X
jr nc, .left
inc [hl]
inc [hl]
call player_bg_collides
jr z, .right_rollback
ld hl, PLAYER_DIR
ld [hl], 0
call update_oam
ret
.right_rollback:
ld hl, PLAYER_X
dec [hl]
dec [hl]
ret
.left:
; check for left button
ld hl, keys
ld a, [hl]
and BTN_LEFT
ret z
; check for left boundary
ld hl, PLAYER_X
ld a, [hl]
or a
ret z
dec [hl]
dec [hl]
call player_bg_collides
jr z, .left_rollback
ld hl, PLAYER_DIR
ld [hl], $ff
call update_oam
ret
.left_rollback:
ld hl, PLAYER_X
dec [hl]
inc [hl]
ret
; Update player metasprite with positional data
update_oam:
ld hl, PLAYER_DIR
ld a, [hl-] ; dir (0 = right , $ff = left)
and OAMF_XFLIP
ld c, a
ld a, [hl-] ; y
add 16
ld d, a
ld a, [hl] ; x
add 8
ld b, a
ld a, d
ld_OAM_y hl, SPRITE_OAM_IDX
; top left sprite
ld [hli], a
ld [hl], b
inc hl
ld [hl], SPRITE_IDX
inc hl
ld [hl], c
inc hl
; top right
ld d, a
ld a, b
add 8
ld b, a
ld a, d
ld [hli], a
ld [hl], b
inc hl
ld [hl], SPRITE_IDX + 1
inc hl
ld [hl], c
inc hl
; bottom left
add 8
ld d, a
ld a, b
sub 8
ld b, a
ld a, d
ld [hli], a
ld [hl], b
inc hl
ld [hl], SPRITE_IDX + 2
inc hl
ld [hl], c
inc hl
; bottom right
ld d, a
ld a, b
add 8
ld b, a
ld a, d
ld [hli], a
ld [hl], b
inc hl
ld [hl], SPRITE_IDX + 3
inc hl
ld [hl], c
; flip tile indices if necessary
ld a, c
or c
jr z, .done
ld_OAM_tile hl, SPRITE_OAM_IDX
ld [hl], SPRITE_IDX + 1
ld_OAM_tile hl, SPRITE_OAM_IDX + 1
ld [hl], SPRITE_IDX
ld_OAM_tile hl, SPRITE_OAM_IDX + 2
ld [hl], SPRITE_IDX + 3
ld_OAM_tile hl, SPRITE_OAM_IDX + 3
ld [hl], SPRITE_IDX + 2
.done:
ret