INCLUDE "oam.inc"
|
|
|
|
SECTION "Collision", ROM0
|
|
|
|
DEF COLLF_WALK EQU (1 << 0)
|
|
DEF COLLF_LADDER EQU (1 << 1)
|
|
DEF COLLF_PORTAL EQU (1 << 2)
|
|
|
|
; Determines if player has hit the background
|
|
; @return NZ = false, Z = true
|
|
player_bg_collides::
|
|
; C = MAP X = PLAYER X / 8 + CAMERA X
|
|
ld a, [PLAYER_X]
|
|
call get_tile_coord
|
|
ld c, a
|
|
|
|
ld a, [CURRENT_CAMERA_X]
|
|
add c
|
|
ld c, a
|
|
|
|
; C < 0
|
|
ld a, c
|
|
cpl
|
|
bit 7, a
|
|
ret z
|
|
|
|
; C >= MAP WIDTH
|
|
ld a, [CURRENT_MAP_WIDTH]
|
|
cp c
|
|
jr nz, .load_y
|
|
|
|
ret
|
|
|
|
.load_y:
|
|
; B = MAP Y = PLAYER Y / 8 + CAMERA Y
|
|
ld a, [PLAYER_Y]
|
|
call get_tile_coord
|
|
ld b, a
|
|
|
|
ld a, [CURRENT_CAMERA_Y]
|
|
add b
|
|
ld b, a
|
|
|
|
; B < 0
|
|
ld a, b
|
|
cpl
|
|
bit 7, a
|
|
ret z
|
|
|
|
; B >= MAP HEIGHT
|
|
ld a, [CURRENT_MAP_HEIGHT]
|
|
cp b
|
|
jr nz, .check_tiles
|
|
|
|
; Set NZ
|
|
or $ff
|
|
ret
|
|
|
|
.check_tiles:
|
|
; top left
|
|
call can_move_to
|
|
ret z
|
|
|
|
; top right
|
|
inc c
|
|
call can_move_to
|
|
ret z
|
|
|
|
; bottom left
|
|
dec c
|
|
inc b
|
|
call can_move_to
|
|
ret z
|
|
|
|
; bottom right
|
|
inc c
|
|
call can_move_to
|
|
|
|
ret
|
|
|
|
; Check if the player is in mid-air
|
|
; @note NZ = true, Z = false
|
|
player_in_air::
|
|
; c = x % 8 == 0 ? x/8 : x/8 + 1
|
|
ld a, [PLAYER_X]
|
|
call get_tile_coord
|
|
ld c, a
|
|
|
|
ld a, [CURRENT_CAMERA_X]
|
|
add c
|
|
ld c, a
|
|
|
|
ld a, [PLAYER_Y]
|
|
call get_tile_coord
|
|
ld b, a
|
|
|
|
ld a, [CURRENT_CAMERA_Y]
|
|
add b
|
|
ld b, a
|
|
|
|
; check underneath player (2 tiles down from top-left sprite)
|
|
inc b
|
|
inc b
|
|
|
|
call can_move_to
|
|
ret z
|
|
|
|
inc c
|
|
call can_move_to
|
|
|
|
ret
|
|
|
|
; Check whether the location can be moved to or not
|
|
; @param b y-coordinate
|
|
; @param c x-coordinate
|
|
; @destroy a, d, e
|
|
; @note NZ = true, Z = false
|
|
can_move_to:
|
|
push bc
|
|
push hl
|
|
|
|
ld a, [CURRENT_MAP_COLLISION]
|
|
ld l, a
|
|
ld a, [CURRENT_MAP_COLLISION + 1]
|
|
ld h, a
|
|
|
|
ld a, [CURRENT_MAP_WIDTH]
|
|
ld d, 0
|
|
ld e, a
|
|
|
|
; compute map index (HL + B * (CURRENT_MAP_WIDTH + 1) + C)
|
|
.mul_y_width:
|
|
add hl, de
|
|
dec b
|
|
jr nz, .mul_y_width
|
|
add hl, bc
|
|
|
|
ld a, [hl]
|
|
and COLLF_WALK
|
|
|
|
pop hl
|
|
pop bc
|
|
|
|
ret
|
|
|
|
; Convert from pixel space to tile space
|
|
; @param a Screen pixel coordinate
|
|
; @destroys hl
|
|
; @returns Screen tile coordinate in A
|
|
get_tile_coord:
|
|
ld hl, sp - 1
|
|
ld [hl], a
|
|
|
|
and %111
|
|
ld a, [hl]
|
|
|
|
jr z, .skip_inc
|
|
add 8
|
|
|
|
.skip_inc:
|
|
srl a
|
|
srl a
|
|
srl a
|
|
|
|
ret
|