; b: tile id
; a: tile flags
act_get_tile:
-
; load tile positions
- ld hl, act_hi_y
+ ld hl, act_y
add hl, de ; hl = actor y
ld a, [hl+]
add a, b ; offset by b
-#ifdef DEBUG
- ldh [debug_col_point_y], a
-#endif
div8 a
; b = y tile
ld b, a
- inc hl ; move past lo x
+ ; hl = x tile
ld a, [hl]
add a, c ; offset by c
-#ifdef DEBUG
- ldh [debug_col_point_x], a
-#endif
div8 a
; c = x tile
; hl = map ptr
ld de, MAP_W
-
- ; save coordinate
- ld a, b
- ldh [col_tile_y], a
- ld a, c
- ldh [col_tile_x], a
; add MAP_W
; to map ptr y times
; b = tile id
; a = tile flags
ret
-
- ; checks actor for wall position
- ; inputs:
- ; $1: y offset
- ; $2: x offset
- ; de: actor ptr
- ; modifies:
- ; registers: all
- ; preserves: de
- ; sets col_flag++ if collision occured
-#macro act_move_wall_check
- push de
- ld b, $1 & 0xFF
- ld c, $2 & 0xFF
- call act_get_tile
- and a, TILE_F_WALL
-
- pop de
-
- call nz, act_inc_col_flag
-#endmacro
-
- ; increments col flag
-act_inc_col_flag:
- ; if we called this col_flag should be 1
- ldh a, [col_flag]
- inc a
- ldh [col_flag], a
- ret
-
- ; resets position
- ; if col_flag > 0
- ; to tmp_lo/tmp_hi
- ; inputs:
- ; hl: hl point to reset if wall
- ; tmp_lo/hi: original position
- ; returns:
- ; a: 0 no reset
- ; a: 1 reset
-act_move_reset:
- ldh a, [col_flag]
- cp a, 0
- jr z, @no_reset REL
-
- ldh a, [tmp_lo]
- ld [hl+], a
- ldh a, [tmp_hi]
- ld [hl], a
-
- ld a, 1
- ret
-@no_reset:
- ld a, 0
- ret
; moves an actor up
; inputs:
; de: actor ptr
- ; b: lo value to move by
- ; c: hi value to move by
+ ; b: value to move by
; returns:
; a: 0 -> move was made
; a: 1 -> move failed
act_move_up:
- xor a, a
- ldh [col_flag], a
-
- ld hl, act_lo_y
+ ld hl, act_y
add hl, de
-
- push hl
; lo -= b
ld a, [hl]
- ldh [tmp_lo], a
sub a, b
ld [hl+], a
-
- ; hi -= carry
- ld a, [hl]
- ldh [tmp_hi], a
- sbc a, c
- ld [hl], a
- act_move_wall_check 0, 4
- act_move_wall_check 0, 2
-
- pop hl
- call act_move_reset
-
+ ld a, 1
ret
; same as move up
act_move_down:
- xor a, a
- ldh [col_flag], a
-
- ld hl, act_lo_y
+ ld hl, act_y
add hl, de
- push hl
-
; lo += b
ld a, [hl]
- ldh [tmp_lo], a
add a, b
ld [hl+], a
-
- ; hi += carry
- ld a, [hl]
- ldh [tmp_hi], a
- adc a, c
- ld [hl], a
- act_move_wall_check 6, 4
- act_move_wall_check 6, 2
-
- pop hl
- call act_move_reset
+ ld a, 1
ret
; moves an actor left
; a: 0 -> move was made
; a: 1 -> move failed
act_move_left:
- xor a, a
- ldh [col_flag], a
-
- ld hl, act_lo_x
+ ld hl, act_x
add hl, de
- push hl
-
; lo -= b
ld a, [hl]
- ldh [tmp_lo], a
sub a, b
ld [hl+], a
- ; hi -= carry
- ld a, [hl]
- ldh [tmp_hi], a
- sbc a, c
- ld [hl], a
-
- act_move_wall_check 4, 1
- act_move_wall_check 2, 1
-
- pop hl
- call act_move_reset
-
+ ld a, 1
ret
; same as move right
act_move_right:
- xor a, a
- ldh [col_flag], a
-
- ld hl, act_lo_x
+ ld hl, act_x
add hl, de
-
- push hl
; lo += b
ld a, [hl]
- ldh [tmp_lo], a
add a, b
ld [hl+], a
-
- ; hi += carry
- ld a, [hl]
- ldh [tmp_hi], a
- adc a, c
- ld [hl], a
- act_move_wall_check 4, 6
- act_move_wall_check 2, 6
- pop hl
- call act_move_reset
+ ld a, 1
ret
; creates a new player actor
player_init:
ld a, 48
- ld [player+act_hi_y], a
+ ld [player+act_y], a
ld a, 64
- ld [player+act_hi_x], a
-
- ld hl, player_draw_idle
- call player_set_draw
-
- ld hl, player_update_falling
- call player_set_update
+ ld [player+act_x], a
ret
; updates player
player_update:
- ld a, [player_update_routine]
- ld l, a
- ld a, [player_update_routine+1]
- ld h, a
- jp hl
-
-
- ; sets update routine
- ; inputs:
- ; hl: new routine
-player_set_update:
- ld a, l
- ld [player_update_routine], a
- ld a, h
- ld [player_update_routine+1], a
- ret
-
- ; sets player draw routine
- ; inputs:
- ; hl: new routine
-player_set_draw:
- ld a, l
- ld [player_draw_routine], a
- ld a, h
- ld [player_draw_routine+1], a
- ret
-
- ; falling state
- ; jumping is not possible
-player_update_falling:
- ld hl, player_draw_fall
- call player_set_draw
-
- call player_update_move_left_right
- call player_apply_gravity
- ret
-
- ; updates the player object
-player_update_grounded:
- ld hl, player_draw_idle
- call player_set_draw
-
- ; check inputs
- call player_update_move_left_right
-
- ; gravity
- call player_apply_gravity
-
- ld b, BTNA
- input_just_pressed
- call nz, player_go_to_jump_state
-
-
- ret
-
- ; jumping state
-player_update_jump:
- ld hl, player_draw_jump
- call player_set_draw
-
- call player_update_move_left_right
- call player_jump
-
- ld b, BTNA
+ ld b, BTNUP
input_held
- ld hl, player_update_falling
- call z, player_set_update
-
-
- ret
+ ld de, player
+ ld b, 1
+ call nz, act_move_up
-player_go_to_jump_state:
- ld hl, player_update_jump
- call player_set_update
- ret
+ ld b, BTNDOWN
+ input_held
+ ld de, player
+ ld b, 1
+ call nz, act_move_down
- ; common update code for moving left and right
- ; most update routines want to call this
-player_update_move_left_right:
ld b, BTNLEFT
- input_held
- ld b, 128
- ld c, 0
+ input_held
ld de, player
- call nz, player_move_left
+ ld b, 1
+ call nz, act_move_left
ld b, BTNRIGHT
input_held
- ld b, 128
- ld c, 0
- ld de, player
- call nz, player_move_right
- ret
-
- ; causes the player to jump
- ; but only as long as jump timer > 0
-player_jump:
- ld a, [player_jump_timer]
- cp a, 0
- jr z, @done REL
-
- sub a, 1
- ld [player_jump_timer], a
-
- ld b, 200
- ld c, 0
ld de, player
- call act_move_up
- cp a, 1
- ret nz ; not wall
+ ld b, 1
+ call nz, act_move_right
- ; if wall is hit set to 0
- xor a, a
- ld [player_jump_timer], a
-
-@done:
- ld hl, player_update_falling
- call player_set_update
-
- ret
-
- ; player movement calls
- ; same as act_move
- ; but also modifies player_draw ptr
-player_move_left:
- call act_move_left
- cp a, 1
- ld hl, player_draw_hug_left_wall
- call z, player_set_draw
- ret
+ ld de, player
+ call act_get_tile
+ ld a, b
+ ldh [cursor_tile_id], a
-player_move_right:
- call act_move_right
- cp a, 1
- ld hl, player_draw_hug_right_wall
- call z, player_set_draw
ret
- ; applies gravity by moving the player down
-player_apply_gravity:
- ld b, 0
- ld c, 1
- call act_move_down
- cp a, 1
- jr nz, @falling REL ; not on ground
- ld a, PLAYER_JUMP_TIMER
- ld [player_jump_timer], a
-
- ; if on the ground go idle
- ld hl, player_update_grounded
- call player_set_update
- ret
-@falling:
- ld hl, player_update_falling
- call player_set_update
- ret
-
- ; draw player to oam
player_draw:
- ld a, [player_draw_routine]
- ld l, a
- ld a, [player_draw_routine+1]
- ld h, a
- jp hl
-
-
-player_draw_idle:
ld hl, player_soam
- ld a, [player+act_hi_y]
+ ; draw aligned to tile
+
+ ; 1) draw cursor
+ ld a, [player+act_y]
+ add a, 4
+ div8 a
+ mul8 a
add a, OBJ_OFF_Y
-
- ld [hl+], a
- ld a, [player+act_hi_x]
- add a, OBJ_OFF_X
ld [hl+], a
- ld a, PLAYER_TILE_IDLE
- ld [hl+], a
-
- xor a, a
- ld [hl], a
-
- ret
-
-player_draw_fall:
- ld hl, player_soam
-
- ld a, [player+act_hi_y]
- add a, OBJ_OFF_Y
-
- ld [hl+], a
- ld a, [player+act_hi_x]
+ ld a, [player+act_x]
+ add a, 4
+ div8 a
+ mul8 a
add a, OBJ_OFF_X
ld [hl+], a
- ld a, PLAYER_TILE_FALL
+ ld a, PLAYER_TILE_CURSOR
ld [hl+], a
xor a, a
- ld [hl], a
-
- ret
-
-player_draw_jump:
- ld hl, player_soam
-
- ld a, [player+act_hi_y]
+ ld [hl+], a
+
+
+ ; 2) draw semi-transparent highlight
+ ; every other frame
+ ld a, [frame_count]
+ and a, 1
+ jr nz, @skip REL
+
+ ; draw aligned to tile as well
+ ld a, [player+act_y]
+ add a, 4
+ div8 a
+ mul8 a
add a, OBJ_OFF_Y
-
ld [hl+], a
- ld a, [player+act_hi_x]
+
+ ld a, [player+act_x]
+ add a, 4
+ div8 a
+ mul8 a
add a, OBJ_OFF_X
ld [hl+], a
- ld a, PLAYER_TILE_JUMP
+ ld a, PLAYER_TILE_CURSOR_BG
ld [hl+], a
xor a, a
ld [hl], a
ret
-
-player_draw_hug_left_wall:
- ld hl, player_soam
-
- ld a, [player+act_hi_y]
- add a, OBJ_OFF_Y
-
- ld [hl+], a
- ld a, [player+act_hi_x]
- add a, OBJ_OFF_X-2
+@skip:
+ ; do not draw this frame
+ xor a, a
ld [hl+], a
-
- ld a, PLAYER_TILE_HUG_LEFT_WALL
ld [hl+], a
- xor a, a
- ld [hl], a
ret
-player_draw_hug_right_wall:
- ld hl, player_soam
-
- ld a, [player+act_hi_y]
- add a, OBJ_OFF_Y
- ld [hl+], a
- ld a, [player+act_hi_x]
- add a, OBJ_OFF_X+2
- ld [hl+], a
-
- ld a, PLAYER_TILE_HUG_LEFT_WALL
- ld [hl+], a
-
- ld a, OAM_FXFLIP
- ld [hl], a
- ret