diff --git a/assets/sprites/ghost.ppm b/assets/sprites/ghost_down.ppm similarity index 100% rename from assets/sprites/ghost.ppm rename to assets/sprites/ghost_down.ppm diff --git a/assets/sprites/ghost_left.ppm b/assets/sprites/ghost_left.ppm new file mode 100644 index 0000000..5e63261 Binary files /dev/null and b/assets/sprites/ghost_left.ppm differ diff --git a/assets/sprites/ghost_right.ppm b/assets/sprites/ghost_right.ppm new file mode 100644 index 0000000..e72da9a Binary files /dev/null and b/assets/sprites/ghost_right.ppm differ diff --git a/assets/sprites/ghost_up.ppm b/assets/sprites/ghost_up.ppm new file mode 100644 index 0000000..c0f2bf7 Binary files /dev/null and b/assets/sprites/ghost_up.ppm differ diff --git a/assets/sprites/robot.ppm b/assets/sprites/robot.ppm deleted file mode 100644 index 3060135..0000000 Binary files a/assets/sprites/robot.ppm and /dev/null differ diff --git a/assets/sprites/robot_down.ppm b/assets/sprites/robot_down.ppm new file mode 100644 index 0000000..20b694a Binary files /dev/null and b/assets/sprites/robot_down.ppm differ diff --git a/assets/sprites/robot_left.ppm b/assets/sprites/robot_left.ppm new file mode 100644 index 0000000..68b44fa Binary files /dev/null and b/assets/sprites/robot_left.ppm differ diff --git a/assets/sprites/robot_right.ppm b/assets/sprites/robot_right.ppm new file mode 100644 index 0000000..9470f98 Binary files /dev/null and b/assets/sprites/robot_right.ppm differ diff --git a/assets/sprites/robot_up.ppm b/assets/sprites/robot_up.ppm new file mode 100644 index 0000000..dc649d1 Binary files /dev/null and b/assets/sprites/robot_up.ppm differ diff --git a/build.ts b/build.ts index fcb59e6..a7f6bdf 100755 --- a/build.ts +++ b/build.ts @@ -18,8 +18,14 @@ const spritesPath = { "sprite_wall_end": "assets/sprites/wall_end.ppm", "sprite_wall_straight": "assets/sprites/wall_straight.ppm", "sprite_wall_corner": "assets/sprites/wall_corner.ppm", - "sprite_robot": "assets/sprites/robot.ppm", - "sprite_ghost": "assets/sprites/ghost.ppm", + "sprite_robot_up": "assets/sprites/robot_up.ppm", + "sprite_robot_right": "assets/sprites/robot_right.ppm", + "sprite_robot_down": "assets/sprites/robot_down.ppm", + "sprite_robot_left": "assets/sprites/robot_left.ppm", + "sprite_ghost_up": "assets/sprites/ghost_up.ppm", + "sprite_ghost_right": "assets/sprites/ghost_right.ppm", + "sprite_ghost_down": "assets/sprites/ghost_down.ppm", + "sprite_ghost_left": "assets/sprites/ghost_left.ppm", "sprite_coin": "assets/sprites/coin.ppm", }; diff --git a/src/consts/game.asm b/src/consts/game.asm index 9ef3ae8..f73bb21 100644 --- a/src/consts/game.asm +++ b/src/consts/game.asm @@ -2,18 +2,3 @@ pub const game.direction_up = 0 pub const game.direction_right = 1 pub const game.direction_down = 2 pub const game.direction_left = 3 -pub const game.direction_still = 4 - -/* -; 1_000_000_000 nano second = 0x0000_0000_3B9A_CA00 -pub const game.tick_duration_0 = 0xCA00 -pub const game.tick_duration_1 = 0x3B9A -pub const game.tick_duration_2 = 0x0000 -pub const game.tick_duration_3 = 0x0000 -*/ - -; 0.5 second = 500_000_000 nano second = 0x0000_0000_1DCD_6500 -pub const game.tick_duration_0 = 0x6500 -pub const game.tick_duration_1 = 0x1DCD -pub const game.tick_duration_2 = 0x0000 -pub const game.tick_duration_3 = 0x0000 \ No newline at end of file diff --git a/src/consts/sprites.asm b/src/consts/sprites.asm index 8c6f485..e156bc8 100644 --- a/src/consts/sprites.asm +++ b/src/consts/sprites.asm @@ -7,12 +7,23 @@ pub const sprites.rotation_90 = 1 pub const sprites.rotation_180 = 2 pub const sprites.rotation_270 = 3 -pub const sprites.empty = 0 +pub const sprites.empty = 0 ; must stay 0 (some code avoid addition when it knows the tile is empty) pub const sprites.unimplemented = 1 pub const sprites.wall_end = 2 pub const sprites.wall_straight = 3 pub const sprites.wall_corner = 4 + pub const sprites.robot = 5 -pub const sprites.ghost = 6 -pub const sprites.coin = 7 -pub const sprites.max = 7 ; for lookup table +pub const sprites.robot_up = 5 +pub const sprites.robot_right = 6 +pub const sprites.robot_down = 7 +pub const sprites.robot_left = 8 + +pub const sprites.ghost = 9 +pub const sprites.ghost_up = 9 +pub const sprites.ghost_right = 10 +pub const sprites.ghost_down = 11 +pub const sprites.ghost_left = 12 + +pub const sprites.coin = 13 +pub const sprites.max = 13 ; for lookup table diff --git a/src/lib/drawing.asm b/src/lib/drawing.asm index 1f7b553..1634fb4 100644 --- a/src/lib/drawing.asm +++ b/src/lib/drawing.asm @@ -41,6 +41,58 @@ pub drawing.draw_whole_map: ret +/* Draw the tile corresponding to the given coordinate with it's map content + + Inputs: + r1, r2: Map coordinates x, y + + Locals: + r3: tile value / sprite id / sprite address offset + r9: pointer + r13: screen address +*/ +pub drawing.clear_tile: + push r1 + push r2 + push r3 + push r9 + push r13 + + add r9, r1, map + push r2 + pub drawing.clear_tile_row_loop: + cmp r2, 0 + je drawing.clear_tile_row_loop_end + sub r2, r2, 1 + add r9, r9, map.width + jmp drawing.clear_tile_row_loop + pub drawing.clear_tile_row_loop_end: + pop r2 + + load_8 r3, [r9] + cmp r3, map.tiles.coin + add r9, zr, ptr.textures_addresses + jne drawing.clear_tile_get_screen_address + ; coin + mov r3, sprites.coin + lsl r3, r3, arch.instruction_increment_shift + add r9, r9, r3 + + pub drawing.clear_tile_get_screen_address: + call get_tile_address + + mov r1, r13 + load_32 r2, [r9] + mov r3, sprites.rotation_0 + call draw_sprite + + pop r13 + pop r9 + pop r3 + pop r2 + pop r1 + ret + /* Return the top-left pixel address of the tile at the given map coordinates Inputs: @@ -100,6 +152,7 @@ get_tile_address: pop r3 ret + /* Get address of given sprite id Inputs: diff --git a/src/lib/u64.asm b/src/lib/u64.asm new file mode 100644 index 0000000..a0d8e6b --- /dev/null +++ b/src/lib/u64.asm @@ -0,0 +1,18 @@ +/* Add two unsigned 64 bit + + Input: + r1, r2: A.high, A.low + r3, r4: B.high, B.low + + Output: + r5, r6: C.high, C.low +*/ +pub u64.add: + add r5, r1, r3 + add r6, r2, r4 + cmp r6, r2 + jae u64.add_no_low_overflow + add r5, r5, 1 ; overflow + + pub u64.add_no_low_overflow: + ret \ No newline at end of file diff --git a/src/main.asm b/src/main.asm index 9282b9c..d57c8b0 100644 --- a/src/main.asm +++ b/src/main.asm @@ -17,10 +17,34 @@ include sections/init_timers game_loop: include sections/handle_event - include sections/characters_movement + + /* + For all timers: + r1, r2: tick duration high, low + r7, r8: now high, low + */ + add r9, zr, ptr.tick_duration_high + load_32 r1, [r9] + add r9, zr, ptr.tick_duration_low + load_32 r2, [r9] + time_0 r8 + time_1 r7 + + push r1 + push r2 + push r7 + push r8 + include sections/timer_robot + pop r8 + pop r7 + pop r2 + pop r1 + + include sections/timer_ghost jmp game_loop +include lib/u64 include lib/game include lib/drawing include lib/sprite_rotation @@ -30,8 +54,14 @@ include dist/placeholder include dist/wall_end include dist/wall_straight include dist/wall_corner -include dist/robot -include dist/ghost +include dist/robot_up +include dist/robot_right +include dist/robot_down +include dist/robot_left +include dist/ghost_up +include dist/ghost_right +include dist/ghost_down +include dist/ghost_left include dist/coin include dist/map diff --git a/src/reserved_space.asm b/src/reserved_space.asm index f513191..2540222 100644 --- a/src/reserved_space.asm +++ b/src/reserved_space.asm @@ -5,8 +5,14 @@ U32 0 ; placeholder U32 0 ; wall_end U32 0 ; wall_straight U32 0 ; wall_corner -U32 0 ; robot -U32 0 ; ghost +U32 0 ; robot up +U32 0 ; robot right +U32 0 ; robot down +U32 0 ; robot left +U32 0 ; ghost up +U32 0 ; ghost right +U32 0 ; ghost down +U32 0 ; ghost left U32 0 ; coin ; 0.5 second = 500_000_000 nano second = 0x0000_0000_1DCD_6500 @@ -17,8 +23,11 @@ pub ptr.tick_duration_low: U32 0x1DCD_6500 ; pub ptr.tick_duration_high: U32 0x0000_0000 ; pub ptr.tick_duration_low: U32 0x3B9A_CA00 -pub ptr.next_tick_high: U32 0 -pub ptr.next_tick_low: U32 0 +pub ptr.timer_robot_next_tick_high: U32 0x0000_0000 +pub ptr.timer_robot_next_tick_low: U32 0x1DCD_6500 + +pub ptr.timer_ghost_next_tick_high: U32 0 +pub ptr.timer_ghost_next_tick_low: U32 0 pub ptr.state_robot: U8 0 ; x coord diff --git a/src/sections/characters_movement.asm b/src/sections/characters_movement.asm deleted file mode 100644 index b5afced..0000000 --- a/src/sections/characters_movement.asm +++ /dev/null @@ -1,231 +0,0 @@ -/* 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.rotation_0 -mov r4, sprites.empty -call drawing.draw_sprite_at_map_coord - -; draw robot on new position -mov r1, r5 -mov r2, r6 -mov r3, sprites.rotation_0 -mov r4, 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 -push r2 -mov r1, r2 -mov r2, r3 -call game.get_tile_address_from_map_coord -mov r9, r13 -pop r2 - -; draw tile at previous position -load_8 r1, [r9] -cmp r1, map.tiles.coin -je game_loop_ghost_movement_old_tile_coin -; old tile empty -mov r4, sprites.empty -jmp game_loop_ghost_movement_draw_old_tile -game_loop_ghost_movement_old_tile_coin: -mov r4, sprites.coin - -game_loop_ghost_movement_draw_old_tile: -mov r1, r2 -mov r2, r3 -mov r3, sprites.rotation_0 -call drawing.draw_sprite_at_map_coord - -; draw ghost on new position -mov r1, r7 -mov r2, r8 -mov r3, sprites.rotation_0 -mov r4, 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: \ No newline at end of file diff --git a/src/sections/init_ghost_state.asm b/src/sections/init_ghost_state.asm index 5bb41d0..24321dc 100644 --- a/src/sections/init_ghost_state.asm +++ b/src/sections/init_ghost_state.asm @@ -13,5 +13,5 @@ add r6, r6, 1 store_8 [r6], r5 mov r3, sprites.rotation_0 -mov r4, sprites.ghost +mov r4, sprites.ghost_down call drawing.draw_sprite_at_map_coord \ No newline at end of file diff --git a/src/sections/init_robot_state.asm b/src/sections/init_robot_state.asm index 383244a..9cde727 100644 --- a/src/sections/init_robot_state.asm +++ b/src/sections/init_robot_state.asm @@ -13,5 +13,5 @@ add r6, r6, 1 store_8 [r6], r5 mov r3, sprites.rotation_0 -mov r4, sprites.robot +mov r4, sprites.robot_down call drawing.draw_sprite_at_map_coord \ No newline at end of file diff --git a/src/sections/init_sprite_lookup_table.asm b/src/sections/init_sprite_lookup_table.asm index 1960054..ba5592e 100644 --- a/src/sections/init_sprite_lookup_table.asm +++ b/src/sections/init_sprite_lookup_table.asm @@ -35,18 +35,57 @@ lsl r2, r1, arch.instruction_increment_shift add r2, r2, ptr.textures_addresses add r3, zr, sprite_wall_corner store_32 [r2], r3 -; sprite_robot -add r1, zr, sprites.robot + +; sprite_robot_up +add r1, zr, sprites.robot_up lsl r2, r1, arch.instruction_increment_shift add r2, r2, ptr.textures_addresses -add r3, zr, sprite_robot +add r3, zr, sprite_robot_up store_32 [r2], r3 -; sprite_ghost -add r1, zr, sprites.ghost +; sprite_robot_right +add r1, zr, sprites.robot_right lsl r2, r1, arch.instruction_increment_shift add r2, r2, ptr.textures_addresses -add r3, zr, sprite_ghost +add r3, zr, sprite_robot_right store_32 [r2], r3 +; sprite_robot_down +add r1, zr, sprites.robot_down +lsl r2, r1, arch.instruction_increment_shift +add r2, r2, ptr.textures_addresses +add r3, zr, sprite_robot_down +store_32 [r2], r3 +; sprite_robot_left +add r1, zr, sprites.robot_left +lsl r2, r1, arch.instruction_increment_shift +add r2, r2, ptr.textures_addresses +add r3, zr, sprite_robot_left +store_32 [r2], r3 + +; sprite_ghost_up +add r1, zr, sprites.ghost_up +lsl r2, r1, arch.instruction_increment_shift +add r2, r2, ptr.textures_addresses +add r3, zr, sprite_ghost_up +store_32 [r2], r3 +; sprite_ghost_right +add r1, zr, sprites.ghost_right +lsl r2, r1, arch.instruction_increment_shift +add r2, r2, ptr.textures_addresses +add r3, zr, sprite_ghost_right +store_32 [r2], r3 +; sprite_ghost_down +add r1, zr, sprites.ghost_down +lsl r2, r1, arch.instruction_increment_shift +add r2, r2, ptr.textures_addresses +add r3, zr, sprite_ghost_down +store_32 [r2], r3 +; sprite_ghost_left +add r1, zr, sprites.ghost_left +lsl r2, r1, arch.instruction_increment_shift +add r2, r2, ptr.textures_addresses +add r3, zr, sprite_ghost_left +store_32 [r2], r3 + ; sprite_coin add r1, zr, sprites.coin lsl r2, r1, arch.instruction_increment_shift diff --git a/src/sections/init_timers.asm b/src/sections/init_timers.asm index 415be9a..0835cc5 100644 --- a/src/sections/init_timers.asm +++ b/src/sections/init_timers.asm @@ -1,18 +1,34 @@ -add r1, zr, ptr.tick_duration_low -load_32 r2, [r1] -add r1, zr, ptr.tick_duration_high -load_32 r3, [r1] +/* + r1, r2: now high, low + r3, r4: initial delay high, low + r5, r6: next tick high, low + r7: pointer +*/ +time_0 r2 +time_1 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 +; Robot +add r7, zr, ptr.timer_robot_next_tick_high +load_32 r3, [r7] +add r7, zr, ptr.timer_robot_next_tick_low +load_32 r4, [r7] -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 \ No newline at end of file +call u64.add + +add r7, zr, ptr.timer_robot_next_tick_high +store_32 [r7], r5 +add r7, zr, ptr.timer_robot_next_tick_low +store_32 [r7], r6 + +; Ghost +add r7, zr, ptr.timer_ghost_next_tick_high +load_32 r3, [r7] +add r7, zr, ptr.timer_ghost_next_tick_low +load_32 r4, [r7] + +call u64.add + +add r7, zr, ptr.timer_ghost_next_tick_high +store_32 [r7], r5 +add r7, zr, ptr.timer_ghost_next_tick_low +store_32 [r7], r6 \ No newline at end of file diff --git a/src/sections/timer_ghost.asm b/src/sections/timer_ghost.asm new file mode 100644 index 0000000..b866d58 --- /dev/null +++ b/src/sections/timer_ghost.asm @@ -0,0 +1,99 @@ +/* Timer comparison / update + r1, r2: tick duration high, low [IN] + r3, r4: next tick high, low + r5, r6: tick after this one high, low + r7, r8: now high, low [IN] + r9: pointer +*/ +add r9, zr, ptr.timer_ghost_next_tick_high +load_32 r3, [r9] +add r9, zr, ptr.timer_ghost_next_tick_low +load_32 r4, [r9] + +cmp r7, r3 +jb timer_ghost.end +ja timer_ghost.trigger +cmp r8, r4 +jb timer_ghost.end + +pub timer_ghost.trigger: +; udate next_tick +call u64.add +add r9, zr, ptr.timer_ghost_next_tick_high +store_32 [r9], r5 +add r9, zr, ptr.timer_ghost_next_tick_low +store_32 [r9], r6 + + +/* Movement + r1, r2: x, y + r3: rotation + r4: direction / sprite id + r5, r6: increments x, y + r7, r8: [RESERVED] + r9: pointer + r10: tile content + r13: tile address +*/ +add r9, zr, ptr.state_ghost +load_8 r1, [r9] +add r9, r9, 1 +load_8 r2, [r9] +add r9, r9, 1 +load_8 r4, [r9] + +call drawing.clear_tile + +mov r5, 0 +mov r6, 0 + +lsl r9, r4, 3 ; 2 * instruction size = 8 +add r9, r9, timer_ghost.direction_jump_table +jmp r9 + +pub timer_ghost.direction_jump_table: +; direction_up +sub r6, r6, 1 +jmp timer_ghost.move +; direction_right +add r5, r5, 1 +jmp timer_ghost.move +; direction_down +add r6, r6, 1 +jmp timer_ghost.move +; direction_left +sub r5, r5, 1 +;jmp timer_ghost.move + +pub timer_ghost.move: +add r1, r1, r5 +add r2, r2, r6 +add r9, zr, ptr.state_ghost +store_8 [r9], r1 +add r9, r9, 1 +store_8 [r9], r2 + +; draw ghost on new position +mov r3, sprites.rotation_0 +add r4, r4, sprites.ghost +call drawing.draw_sprite_at_map_coord + +/* + Check ahead for direction change +*/ +add r1, r1, r5 +add r2, r2, r6 +call game.get_tile_address_from_map_coord + +load_8 r10, [r13] +cmp r10, map.tiles.wall +jne timer_ghost.end +; increment direction +add r9, zr, ptr.state_ghost +add r9, r9, 2 +load_8 r4, [r9] +add r4, r4, 1 +and r4, r4, 0b11 ; modulo 3 +store_8 [r9], r4 + +pub timer_ghost.end: \ No newline at end of file diff --git a/src/sections/timer_robot.asm b/src/sections/timer_robot.asm new file mode 100644 index 0000000..419e678 --- /dev/null +++ b/src/sections/timer_robot.asm @@ -0,0 +1,99 @@ +/* Timer comparison / update + r1, r2: tick duration high, low [IN] + r3, r4: next tick high, low + r5, r6: tick after this one high, low + r7, r8: now high, low [IN] + r9: pointer +*/ +add r9, zr, ptr.timer_robot_next_tick_high +load_32 r3, [r9] +add r9, zr, ptr.timer_robot_next_tick_low +load_32 r4, [r9] + +cmp r7, r3 +jb timer_robot.end +ja timer_robot.trigger +cmp r8, r4 +jb timer_robot.end + +pub timer_robot.trigger: +; udate next_tick +call u64.add +add r9, zr, ptr.timer_robot_next_tick_high +store_32 [r9], r5 +add r9, zr, ptr.timer_robot_next_tick_low +store_32 [r9], r6 + + +/* Movement + r1, r2: x, y + r3: rotation + r4: direction / sprite id + r5, r6: increments x, y + r7, r8: [RESERVED] + r9: pointer + r10: tile content + r13: tile address +*/ +add r9, zr, ptr.state_robot +load_8 r1, [r9] +add r9, r9, 1 +load_8 r2, [r9] +add r9, r9, 1 +load_8 r4, [r9] + +call drawing.clear_tile + +mov r5, 0 +mov r6, 0 + +lsl r9, r4, 3 ; 2 * instruction size = 8 +add r9, r9, timer_robot.direction_jump_table +jmp r9 + +pub timer_robot.direction_jump_table: +; direction_up +sub r6, r6, 1 +jmp timer_robot.try_move +; direction_right +add r5, r5, 1 +jmp timer_robot.try_move +; direction_down +add r6, r6, 1 +jmp timer_robot.try_move +; direction_left +sub r5, r5, 1 +;jmp timer_robot.try_move + +/* + Collision handling +*/ +pub timer_robot.try_move: +add r1, r1, r5 +add r2, r2, r6 +call game.get_tile_address_from_map_coord +load_8 r10, [r13] +cmp r10, map.tiles.wall +jne timer_robot.move +; hit wall -> cancel movement +sub r1, r1, r5 +sub r2, r2, r6 +jmp timer_robot.draw + +pub timer_robot.move: +; TODO: handle coin and empty differently +mov r10, map.tiles.empty +store_8 [r13], r10 + +add r9, zr, ptr.state_robot +store_8 [r9], r1 +add r9, r9, 1 +store_8 [r9], r2 + +pub timer_robot.draw: +; draw robot on new position +mov r3, sprites.rotation_0 +add r4, r4, sprites.robot +call drawing.draw_sprite_at_map_coord + +pub timer_robot.end: \ No newline at end of file