Files
Turing-Complete-PacMan/src/main.asm

338 lines
7.1 KiB
NASM

include consts/screen
include init
;
; State initialization
;
; Robot
const robot_initial_x = 1
const robot_initial_y = 1
const robot_initial_direction = game.direction_down
mov r1, robot_initial_x
mov r2, robot_initial_y
mov r5, robot_initial_direction
add r6, zr, ptr.state_robot
store_8 [r6], r1
add r6, r6, 1
store_8 [r6], r2
add r6, r6, 1
store_8 [r6], r5
mov r3, sprites.robot
call drawing.draw_sprite_at_map_coord
; Ghost
const ghost_initial_x = 13
const ghost_initial_y = 1
const ghost_initial_direction = game.direction_down
mov r1, ghost_initial_x
mov r2, ghost_initial_y
mov r5, ghost_initial_direction
add r6, zr, ptr.state_ghost
store_8 [r6], r1
add r6, r6, 1
store_8 [r6], r2
add r6, r6, 1
store_8 [r6], r5
mov r3, sprites.ghost
call drawing.draw_sprite_at_map_coord
;
; Time initialization
;
add r1, zr, ptr.tick_duration_low
load_32 r2, [r1]
add r1, zr, ptr.tick_duration_high
load_32 r3, [r1]
time_0 r4
time_1 r5
add r4, r4, r2
add r5, r5, r3
cmp r4, r2
jae init_store_next_tick
add r5, r5, 1 ; overflow
init_store_next_tick:
add r1, zr, ptr.next_tick_low
store_32 [r1], r4
add r1, zr, ptr.next_tick_high
store_32 [r1], r5
game_loop:
;
; Event handling
;
; r1 = keyboard event+key / direction
; r2 = keyboard key / direction address
; r3 = keyboard event
; r4 = jump address
keyboard r1
and r2, r1, keyboard.mask_key
and r3, r1, keyboard.mask_event
cmp r3, keyboard.event_pressed
jne game_loop_event_handling_end
cmp r2, keyboard.key_min
jb game_loop_event_handling_end
cmp r2, keyboard.key_max
ja game_loop_event_handling_end
sub r4, r2, keyboard.key_min ; so the first value is 0
lsl r4, r4, 3 ; 2 * instruction length = 8
add r4, r4, game_loop_key_jump_table_start
jmp r4
game_loop_key_jump_table_start:
; key_up
mov r1, game.direction_up
jmp game_loop_event_handling_store_direction
; key_right
mov r1, game.direction_right
jmp game_loop_event_handling_store_direction
; key_down:
mov r1, game.direction_down
jmp game_loop_event_handling_store_direction
; key_left:
mov r1, game.direction_left
; jmp game_loop_event_handling_end
game_loop_event_handling_store_direction:
add r2, zr, ptr.state_robot
add r2, r2, 2
store_8 [r2], r1
game_loop_event_handling_end:
;
; Elapsed time check
;
; r1: address
; r2: now low / delay low
; r3: now high / delay high
; r4: next tick low
; r5: next tick high
;
time_0 r2
time_1 r3
add r1, zr, ptr.next_tick_low
load_32 r4, [r1]
add r1, zr, ptr.next_tick_high
load_32 r5, [r1]
cmp r3, r5
jb game_loop
ja update_next_tick
cmp r2, r4
jb game_loop
update_next_tick:
add r1, zr, ptr.tick_duration_low
load_32 r2, [r1]
add r1, zr, ptr.tick_duration_high
load_32 r3, [r1]
add r4, r4, r2
add r5, r5, r3
cmp r4, r2
jae store_next_tick
add r5, r5, 1
store_next_tick:
add r1, zr, ptr.next_tick_low
store_32 [r1], r4
add r1, zr, ptr.next_tick_high
store_32 [r1], r5
;
; Robot movement
;
; r1 = robot's state address
; r2 = x
; r3 = y
; r4 = direction
; r5 = new x
; r6 = new y
; r7 = new position address
; r8 = new position content
; r9 = jump address
add r1, zr, ptr.state_robot
load_8 r2, [r1]
add r1, r1, 1
load_8 r3, [r1]
add r1, r1, 1
load_8 r4, [r1]
mov r5, r2
mov r6, r3
lsl r9, r4, 3 ; 2 * instruction size = 8
add r9, r9, game_loop_robot_movement_jump_table_start
jmp r9
game_loop_robot_movement_jump_table_start:
; direction_up
sub r6, r6, 1
jmp game_loop_robot_movement_try_move
; direction_right
add r5, r5, 1
jmp game_loop_robot_movement_try_move
; direction_down
add r6, r6, 1
jmp game_loop_robot_movement_try_move
; direction_left
sub r5, r5, 1
jmp game_loop_robot_movement_try_move
; direction_still
jmp game_loop_robot_movement_none
game_loop_robot_movement_try_move:
push r2
mov r1, r5
mov r2, r6
call game.get_tile_address_from_map_coord
mov r7, r13
pop r2
;
; Collision handling
;
load_8 r8, [r7]
cmp r8, map.tiles.wall
jne game_loop_robot_movement_some
; hit wall
add r1, zr, ptr.state_robot
add r1, r1, 2
mov r4, game.direction_still
store_8 [r1], r4
jmp game_loop_robot_movement_none
game_loop_robot_movement_some:
; TODO: handle coin and empty differently
mov r8, map.tiles.empty
store_8 [r7], r8
add r1, zr, ptr.state_robot
store_8 [r1], r5
add r1, r1, 1
store_8 [r1], r6
; clear old position
mov r1, r2
mov r2, r3
mov r3, sprites.empty
call drawing.draw_sprite_at_map_coord
; draw robot on new position
mov r1, r5
mov r2, r6
mov r3, sprites.robot
call drawing.draw_sprite_at_map_coord
game_loop_robot_movement_none:
;
; Ghost movement
;
; r1: ghost's state address
; r2: x
; r3: y
; r4: direction
; r5: x increment
; r6: y increment
; r7: new x
; r8: new y
; r9: new position address
; r10: new position content
; r11: jump address
add r1, zr, ptr.state_ghost
load_8 r2, [r1]
add r1, r1, 1
load_8 r3, [r1]
add r1, r1, 1
load_8 r4, [r1]
mov r5, 0
mov r6, 0
lsl r11, r4, 3 ; 2 * instruction size = 8
add r11, r11, game_loop_ghost_movement_jump_table_start
jmp r11
game_loop_ghost_movement_jump_table_start:
; direction_up
sub r6, r6, 1
jmp game_loop_ghost_movement_make_move
; direction_right
add r5, r5, 1
jmp game_loop_ghost_movement_make_move
; direction_down
add r6, r6, 1
jmp game_loop_ghost_movement_make_move
; direction_left
sub r5, r5, 1
;jmp game_loop_ghost_movement_make_move
; direction_still (should never happen)
game_loop_ghost_movement_make_move:
add r7, r2, r5
add r8, r3, r6
add r1, zr, ptr.state_ghost
store_8 [r1], r7
add r1, r1, 1
store_8 [r1], r8
; get tile at previous position
mov r1, r2
mov r2, r3
call game.get_tile_address_from_map_coord
load_8 r13, [r13]
; draw tile at previous position
cmp r13, map.tiles.coin
je game_loop_ghost_movement_old_tile_coin
; old tile empty
mov r3, sprites.empty
jmp game_loop_ghost_movement_draw_old_tile
game_loop_ghost_movement_old_tile_coin:
mov r3, sprites.coin
game_loop_ghost_movement_draw_old_tile:
call drawing.draw_sprite_at_map_coord
; draw ghost on new position
mov r1, r7
mov r2, r8
mov r3, sprites.ghost
call drawing.draw_sprite_at_map_coord
;
; Check ahead for direction change
;
add r1, r7, r5
add r2, r8, r6
call game.get_tile_address_from_map_coord
load_8 r10, [r13]
cmp r10, map.tiles.wall
jne game_loop_ghost_movement_end
; increment direction
add r1, zr, ptr.state_ghost
add r1, r1, 2
load_8 r4, [r1]
add r4, r4, 1
and r4, r4, 0b11 ; modulo 3
store_8 [r1], r4
game_loop_ghost_movement_end:
jmp game_loop
include lib/drawing