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