include ../consts/offsets include ../consts/map include ../consts/screen include ../consts/scene include ../consts/sprites include sprite_rotation ; /* 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, 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 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 r13 call get_tile_address push r13 mov r1, r3 call get_sprite_address mov r2, r13 pop r13 mov r1, r13 call draw_sprite pop r13 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 ; Outputs: ; Locals: ; r1: current screen pixel address ; r2: current sprite pixel address ; r3: x ; r4: color ; r5: sprite last pixel address + 1 ; */ draw_sprite: push r1 push r2 push r3 push r4 push r5 add r5, r2, sprites.size mov r3, 0 draw_sprite_loop: load_8 r4, [r2] store_8 [r1], r4 add r1, r1, 1 add r2, r2, 1 add r3, r3, 1 cmp r3, sprites.width jne draw_sprite_loop mov r3, 0 add r1, r1, screen.width sub r1, r1, sprites.width cmp r5, r2 jne draw_sprite_loop pop r5 pop r4 pop r3 pop r2 pop r1 ret