265 lines
No EOL
4 KiB
NASM
265 lines
No EOL
4 KiB
NASM
; Player (a.k.a cursor) state
|
|
|
|
PLAYER_MIN_X equ -5
|
|
PLAYER_MAX_X equ 5
|
|
PLAYER_MIN_Y equ -10
|
|
PLAYER_MAX_Y equ 8
|
|
|
|
; read_key must have been called before
|
|
tick_player:
|
|
call update_cursor
|
|
call horizontal_collision
|
|
call vertical_collision
|
|
call tile_collisions
|
|
ret
|
|
|
|
update_cursor:
|
|
mov ax, 0 ; delta X
|
|
mov bx, 0 ; delta Y
|
|
cmp byte [key_held.left], 0
|
|
je .not_left
|
|
dec ax
|
|
.not_left:
|
|
cmp byte [key_held.right], 0
|
|
je .not_right
|
|
inc ax
|
|
.not_right:
|
|
cmp byte [key_held.up], 0
|
|
je .not_up
|
|
dec bx
|
|
.not_up:
|
|
cmp byte [key_held.down], 0
|
|
je .not_down
|
|
inc bx
|
|
.not_down:
|
|
|
|
add [cursor_x], ax
|
|
add [cursor_y], bx
|
|
mov [cursor_dx], ax
|
|
mov [cursor_dy], bx
|
|
|
|
cmp word [cursor_x], 0
|
|
jge .x_not_underflow
|
|
mov word [cursor_x], 0
|
|
.x_not_underflow:
|
|
cmp word [cursor_x], SCREEN_WIDTH
|
|
jl .x_not_overflow
|
|
mov word [cursor_x], SCREEN_WIDTH - 1
|
|
.x_not_overflow:
|
|
cmp word [cursor_y], 0
|
|
jge .y_not_underflow
|
|
mov word [cursor_y], 0
|
|
.y_not_underflow:
|
|
cmp word [cursor_y], PLAYFIELD_HEIGHT
|
|
jl .y_not_overflow
|
|
mov word [cursor_y], PLAYFIELD_HEIGHT - 1
|
|
.y_not_overflow:
|
|
|
|
ret
|
|
|
|
horizontal_collision:
|
|
sub [cursor_y], bx
|
|
cmp word [cursor_dx], 0
|
|
jl .towards_left
|
|
jg .towards_right
|
|
jmp .end
|
|
|
|
.towards_left:
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MIN_X
|
|
add bx, PLAYER_MIN_Y
|
|
call get_tile_at
|
|
cmp al, 'x'
|
|
je .collided
|
|
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MIN_X
|
|
call get_tile_at
|
|
cmp al, 'x'
|
|
je .collided
|
|
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MIN_X
|
|
add bx, PLAYER_MAX_Y
|
|
call get_tile_at
|
|
cmp al, 'x'
|
|
je .collided
|
|
|
|
jmp .end
|
|
|
|
.towards_right:
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MAX_X
|
|
add bx, PLAYER_MIN_Y
|
|
call get_tile_at
|
|
cmp al, 'x'
|
|
je .collided
|
|
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MAX_X
|
|
call get_tile_at
|
|
cmp al, 'x'
|
|
je .collided
|
|
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MAX_X
|
|
add bx, PLAYER_MAX_Y
|
|
call get_tile_at
|
|
cmp al, 'x'
|
|
je .collided
|
|
|
|
jmp .end
|
|
|
|
.collided:
|
|
mov ax, [cursor_dx]
|
|
sub [cursor_x], ax
|
|
|
|
.end:
|
|
mov bx, [cursor_dy]
|
|
add [cursor_y], bx
|
|
|
|
ret
|
|
|
|
vertical_collision:
|
|
cmp word [cursor_dy], 0
|
|
jl .upwards
|
|
jg .downwards
|
|
jmp .end
|
|
|
|
.upwards:
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MIN_X
|
|
add bx, PLAYER_MIN_Y
|
|
call get_tile_at
|
|
cmp al, 'x'
|
|
je .collided
|
|
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MAX_X
|
|
add bx, PLAYER_MIN_Y
|
|
call get_tile_at
|
|
cmp al, 'x'
|
|
je .collided
|
|
|
|
jmp .end
|
|
|
|
.downwards:
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MIN_X
|
|
add bx, PLAYER_MAX_Y
|
|
call get_tile_at
|
|
cmp al, 'x'
|
|
je .collided
|
|
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MAX_X
|
|
add bx, PLAYER_MAX_Y
|
|
call get_tile_at
|
|
cmp al, 'x'
|
|
je .collided
|
|
|
|
jmp .end
|
|
|
|
.collided:
|
|
mov bx, [cursor_dy]
|
|
sub [cursor_y], bx
|
|
|
|
.end:
|
|
ret
|
|
|
|
tile_collisions:
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MIN_X
|
|
add bx, PLAYER_MIN_Y
|
|
call .test_point
|
|
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MAX_X
|
|
add bx, PLAYER_MIN_Y
|
|
call .test_point
|
|
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MIN_X
|
|
call .test_point
|
|
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MAX_X
|
|
call .test_point
|
|
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MIN_X
|
|
add bx, PLAYER_MAX_Y
|
|
call .test_point
|
|
|
|
mov ax, [cursor_x]
|
|
mov bx, [cursor_y]
|
|
add ax, PLAYER_MAX_X
|
|
add bx, PLAYER_MAX_Y
|
|
call .test_point
|
|
|
|
jmp .end
|
|
|
|
.test_point:
|
|
call get_tile_at
|
|
cmp al, '@'
|
|
je .hazard
|
|
cmp al, 'W'
|
|
je .goal
|
|
ret
|
|
|
|
.hazard:
|
|
mov byte [level_state], STATE_LOSS
|
|
ret
|
|
|
|
.goal:
|
|
mov byte [level_state], STATE_WIN
|
|
ret
|
|
|
|
.end:
|
|
ret
|
|
|
|
; ax = X
|
|
; bx = Y
|
|
; dl = colour
|
|
draw_player:
|
|
pusha
|
|
mov si, ax
|
|
mov di, bx
|
|
sub di, 10
|
|
call draw_line
|
|
mov si, ax
|
|
mov di, bx
|
|
sub si, 5
|
|
add di, 8
|
|
call draw_line
|
|
mov si, ax
|
|
mov di, bx
|
|
add si, 5
|
|
add di, 8
|
|
call draw_line
|
|
popa
|
|
ret
|
|
|
|
section data
|
|
cursor_x resw 1
|
|
cursor_y resw 1
|
|
cursor_dx resw 1
|
|
cursor_dy resw 1
|
|
old_cursor_x resw 1
|
|
old_cursor_y resw 1
|
|
section code |