include ../consts/offsets include ../consts/map include ../consts/screen include ../consts/scene include ../consts/sprites include sprite_rotation ; /* Draw the whole (fill the screen memory with the values of the sprites based on the map) ; Inputs: ; Outputs: ; Locals: ; r1: x map coord ; r2: y map coord ; r3: sprite rotation ; r4: sprite id ; r12: rotation (returned by `sprite and rotation`) ; r13: sprite (returned by `get_sprite_id_and_rotation`) ; */ pub drawing.draw_whole_map: push r1 push r2 push r3 push r4 push r12 push r13 mov r1, 0 mov r2, 0 draw_whole_map_loop: call sprite_rotation.get_sprite_id_and_rotation mov r3, r12 mov r4, r13 call drawing.draw_sprite_at_map_coord add r1, r1, 1 cmp r1, map.width jne draw_whole_map_loop mov r1, 0 add r2, r2, 1 cmp r2, map.height jne draw_whole_map_loop pop r13 pop r12 pop r4 pop r3 pop r2 pop r1 ret ; /* Return the top-left pixel address of the tile at the given map coordinates ; Inputs: ; r1: map x coord ; r2: map y coord ; Locals: ; r3: counter ; r4: offset per tile row (screen width * tile height) ; Ouputs: ; r13: the pixel address ; */ get_tile_address: push r3 push r4 mov r3, 0 mov r4, 0 get_tile_address_offset_per_row_loop: add r4, r4, screen.width add r3, r3, 1 cmp r3, sprites.height jne get_tile_address_offset_per_row_loop add r13, zr, ptr.screen mov r3, 0 get_tile_address_margin_top_loop: cmp r3, scene.margin_top je get_tile_address_margin_top_loop_end add r13, r13, screen.width add r3, r3, 1 jmp get_tile_address_margin_top_loop get_tile_address_margin_top_loop_end: mov r3, 0 get_tile_address_tile_row_loop: cmp r3, r2 je get_tile_address_tile_row_loop_end add r13, r13, r4 add r3, r3, 1 jmp get_tile_address_tile_row_loop get_tile_address_tile_row_loop_end: add r13, r13, scene.margin_left mov r3, 0 get_tile_address_tile_column_loop: cmp r3, r1 je get_tile_address_tile_column_loop_end add r13, r13, sprites.width add r3, r3, 1 jmp get_tile_address_tile_column_loop get_tile_address_tile_column_loop_end: pop r4 pop r3 ret ; /* Get address of given sprite id ; Inputs: ; r1: sprite id ; Outputs: ; r13: address ; Locals: ; r2: pointer address ; */ get_sprite_address: push r1 push r2 cmp r1, sprites.max jbe get_sprite_address_ptr mov r1, sprites.unimplemented get_sprite_address_ptr: lsl r2, r1, arch.instruction_increment_shift add r2, r2, ptr.textures_addresses load_32 r13, [r2] pop r2 pop r1 ret ; /* Draw given sprite on the screen at given map coordinates ; Inputs: ; r1: map x coord ; r2: map y coord ; r3: sprite rotation ; r4: sprite id ; Outputs: ; Locals: ; r1: screen address ; r2: sprite address ; r13: value returned by call to `get_tile_address` and `get_sprite_address` ; */ pub drawing.draw_sprite_at_map_coord: push r1 push r2 push r3 push r4 push r13 call get_tile_address mov r1, r13 push r1 mov r1, r4 call get_sprite_address mov r2, r13 pop r1 call draw_sprite pop r13 pop r4 pop r3 pop r2 pop r1 ret ; /* Draw given sprite (by address) at given screen position (by address) with given rotation ; Inputs: ; r1: screen address ; r2: sprite address ; r3: rotation ; Outputs: ; Locals: ; r1: current screen pixel address ; r4: x ; r5: y ; r6: current sprite pixel address ; r7: color ; r8: x increment ; r9: y increment ; */ draw_sprite: push r1 push r2 push r3 push r4 push r5 push r6 push r7 push r8 push r9 mov r6, r2 ; rotation draw_sprite_cmp_rotation_0: cmp r3, sprites.rotation_0 jne draw_sprite_cmp_rotation_90 mov r8, 1 mov r9, 0 jmp draw_sprite_loop_init draw_sprite_cmp_rotation_90: cmp r3, sprites.rotation_90 jne draw_sprite_cmp_rotation_180 add r6, r6, sprites.size sub r6, r6, sprites.width sub r8, zr, sprites.width mov r9, sprites.size add r9, r9, 1 jmp draw_sprite_loop_init draw_sprite_cmp_rotation_180: cmp r3, sprites.rotation_180 jne draw_sprite_cmp_rotation_270 add r6, r6, sprites.size sub r6, r6, 1 sub r8, zr, 1 mov r9, 0 jmp draw_sprite_loop_init draw_sprite_cmp_rotation_270: add r6, r6, sprites.width sub r6, r6, 1 mov r8, sprites.width sub r9, zr, sprites.size sub r9, r9, 1 draw_sprite_loop_init: mov r4, 0 mov r5, 0 draw_sprite_loop: load_8 r7, [r6] store_8 [r1], r7 add r4, r4, 1 add r1, r1, 1 add r6, r6, r8 cmp r4, sprites.width jne draw_sprite_loop mov r4, 0 add r6, r6, r9 add r1, r1, screen.width sub r1, r1, sprites.width add r5, r5, 1 cmp r5, sprites.width jne draw_sprite_loop pop r9 pop r8 pop r7 pop r6 pop r5 pop r4 pop r3 pop r2 pop r1 ret