INCLUDE "oam.inc" SECTION "Collision", ROM0 ; Determines if player has hit the background ; @return NZ = false, Z = true player_bg_collides:: ; c = x % 8 == 0 ? x/8 : x/8 + 1 ld a, [PLAYER_X] ld c, a and %111 jr z, .skip_inc_c ld a, c add 8 ld c, a .skip_inc_c: srl c srl c srl c ; b = y % 8 == 0 ? y/8 : y/8 + 1 ld a, [PLAYER_Y] ld b, a and %111 jr z, .skip_inc_b ld a, b add 8 ld b, a .skip_inc_b: srl b srl b srl b ; top left call can_move_to ret nz ; top right inc c call can_move_to ret nz ; bottom left dec c inc b call can_move_to ret nz ; bottom right inc c call can_move_to ret ; Check if the player is in mid-air ; @note NZ = false, Z = true player_in_air:: ; c = x % 8 == 0 ? x/8 : x/8 + 1 ld a, [PLAYER_X] ld c, a and %111 jr z, .skip_inc_c ld a, c add 8 ld c, a .skip_inc_c: srl c srl c srl c ; b = y % 8 == 0 ? y/8 : y/8 + 1 ld a, [PLAYER_Y] ld b, a and %111 jr z, .skip_inc_b ld a, b add 8 ld b, a .skip_inc_b: srl b srl b srl b ; check underneath player (2 tiles down from top-left sprite) inc b inc b call can_move_to ret nz 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 = false, Z = true can_move_to: ; todo: should be aware of scx/scy push bc push hl ld a, [CURRENT_MAP_COLLISION] ld h, a ld a, [CURRENT_MAP_COLLISION + 1] ld l, 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 ; check [hl] = 1 ld a, [hl] cp 1 pop hl pop bc ret