From 425b83b1bb84a52f88d23bc90be4da748422bace Mon Sep 17 00:00:00 2001 From: Robin Chappatte Date: Fri, 1 May 2026 18:48:12 +0200 Subject: [PATCH] split code in sections --- src/main.asm | 345 +----------------- src/sections/characters_movement.asm | 231 ++++++++++++ src/sections/handle_event.asm | 43 +++ src/sections/init_ghost_state.asm | 17 + src/sections/init_robot_state.asm | 17 + src/sections/init_screen.asm | 10 + .../init_sprite_lookup_table.asm} | 15 - src/sections/init_timers.asm | 18 + 8 files changed, 343 insertions(+), 353 deletions(-) create mode 100644 src/sections/characters_movement.asm create mode 100644 src/sections/handle_event.asm create mode 100644 src/sections/init_ghost_state.asm create mode 100644 src/sections/init_robot_state.asm create mode 100644 src/sections/init_screen.asm rename src/{init.asm => sections/init_sprite_lookup_table.asm} (85%) create mode 100644 src/sections/init_timers.asm diff --git a/src/main.asm b/src/main.asm index 1465223..9282b9c 100644 --- a/src/main.asm +++ b/src/main.asm @@ -6,349 +6,18 @@ include consts/scene include consts/screen include consts/sprites -include init +include sections/init_sprite_lookup_table +include sections/init_screen call drawing.draw_whole_map -/* - 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.rotation_0 -mov r4, 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.rotation_0 -mov r4, 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 +include sections/init_robot_state +include sections/init_ghost_state +include sections/init_timers 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.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: + include sections/handle_event + include sections/characters_movement jmp game_loop diff --git a/src/sections/characters_movement.asm b/src/sections/characters_movement.asm new file mode 100644 index 0000000..b5afced --- /dev/null +++ b/src/sections/characters_movement.asm @@ -0,0 +1,231 @@ +/* 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/handle_event.asm b/src/sections/handle_event.asm new file mode 100644 index 0000000..f219eab --- /dev/null +++ b/src/sections/handle_event.asm @@ -0,0 +1,43 @@ +/* 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 handle_event_end +cmp r2, keyboard.key_min +jb handle_event_end +cmp r2, keyboard.key_max +ja handle_event_end + +sub r4, r2, keyboard.key_min ; so the first value is 0 +lsl r4, r4, 3 ; 2 * instruction length = 8 +add r4, r4, handle_event_jump_table_start +jmp r4 + +handle_event_jump_table_start: +; key_up +mov r1, game.direction_up +jmp handle_event_store_direction +; key_right +mov r1, game.direction_right +jmp handle_event_store_direction +; key_down: +mov r1, game.direction_down +jmp handle_event_store_direction +; key_left: +mov r1, game.direction_left +;jmp handle_event_end + +handle_event_store_direction: +add r2, zr, ptr.state_robot +add r2, r2, 2 +store_8 [r2], r1 + +handle_event_end: \ No newline at end of file diff --git a/src/sections/init_ghost_state.asm b/src/sections/init_ghost_state.asm new file mode 100644 index 0000000..5bb41d0 --- /dev/null +++ b/src/sections/init_ghost_state.asm @@ -0,0 +1,17 @@ +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.rotation_0 +mov r4, sprites.ghost +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 new file mode 100644 index 0000000..383244a --- /dev/null +++ b/src/sections/init_robot_state.asm @@ -0,0 +1,17 @@ +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.rotation_0 +mov r4, sprites.robot +call drawing.draw_sprite_at_map_coord \ No newline at end of file diff --git a/src/sections/init_screen.asm b/src/sections/init_screen.asm new file mode 100644 index 0000000..aecff20 --- /dev/null +++ b/src/sections/init_screen.asm @@ -0,0 +1,10 @@ +; r1 = screen parameter value +mov r1, screen.mode_index +screen r1, screen.mode_value + +mov r1, screen.offset_index +add r2, zr, ptr.screen +screen r1, r2 + +mov r1, screen.resolution_index +screen r1, screen.resolution_value \ No newline at end of file diff --git a/src/init.asm b/src/sections/init_sprite_lookup_table.asm similarity index 85% rename from src/init.asm rename to src/sections/init_sprite_lookup_table.asm index fdda797..1960054 100644 --- a/src/init.asm +++ b/src/sections/init_sprite_lookup_table.asm @@ -53,18 +53,3 @@ lsl r2, r1, arch.instruction_increment_shift add r2, r2, ptr.textures_addresses add r3, zr, sprite_coin store_32 [r2], r3 - -/* - Screen initialization -*/ - -; r1 = screen parameter value -mov r1, screen.mode_index -screen r1, screen.mode_value - -mov r1, screen.offset_index -add r2, zr, ptr.screen -screen r1, r2 - -mov r1, screen.resolution_index -screen r1, screen.resolution_value diff --git a/src/sections/init_timers.asm b/src/sections/init_timers.asm new file mode 100644 index 0000000..415be9a --- /dev/null +++ b/src/sections/init_timers.asm @@ -0,0 +1,18 @@ +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 \ No newline at end of file