Files
Turing-Complete-PacMan/src/lib/drawing.asm

178 lines
2.9 KiB
NASM

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