Add line drawing functions

This commit is contained in:
Juhani Krekelä 2022-03-11 20:48:00 +02:00
parent 6fb7da74e0
commit 5dcc4553cc
1 changed files with 204 additions and 10 deletions

View File

@ -51,18 +51,33 @@ mainloop:
mov [minute], cl
mov [second], dh
mov word [line_sx], 80
mov word [line_sy], 0
mov word [line_ex], 60
mov ax, [second]
mul word [six]
mov bx, ax
mov ax, [width]
shr ax, 1
shr ax, 1
call sinx
mov [line_ey], ax
call draw_line
mov bp, [width]
shr bp, 1
mov bp, ax
mov byte [es:bp], 7
mov word [line_sx], 80
mov word [line_sy], 60
mov word [line_ex], 60
mov ax, [second]
mov [line_ey], ax
call draw_line
mov word [line_sx], 80
mov word [line_sy], 0
mov word [line_ex], 20
mov ax, [second]
mov [line_ey], ax
call draw_line
mov word [line_sx], 80
mov word [line_sy], 60
mov word [line_ex], 20
mov ax, [second]
mov [line_ey], ax
call draw_line
.unchanged:
hlt
@ -89,6 +104,177 @@ clear_screen:
pop bp
ret
; in:
; [line_sx], [line_sy] = starting point
; [line_ex], [line_ey] = ending point
; clobbers:
; [line_sx], [line_sy], [line_ex], [line_ey]
draw_line:
; Bresenham's line algorithm
push ax
push cx
push dx
push bp
mov ax, [line_sy]
mul word [width]
mov bp, ax
add bp, [line_sx]
; dx = ex - sx
mov dx, [line_ex]
sub dx, [line_sx]
mov [line_dx], dx
; dy = ey - sy
mov ax, [line_ey]
sub ax, [line_sy]
mov [line_dy], ax
.abs_dx:
cmp dx, 0
jge .abs_dy
neg dx
.abs_dy:
cmp ax, 0
jge .abs_done
neg ax
.abs_done:
cmp ax, dx
ja draw_line_high ; dy > dx
draw_line_low:
mov ax, [line_sx]
cmp ax, [line_ex]
ja draw_line_swap_start_end
cmp word [line_dy], 0
jl .negative_dy
.positive_dy:
mov dx, [width]
jmp .y_adjust_done
.negative_dy:
mov ax, [line_dy]
neg ax
mov [line_dy], ax
xor dx, dx
sub dx, [width]
.y_adjust_done
; errorterm = 2·dy - dx
mov ax, [line_dy]
add ax, [line_dy]
sub ax, [line_dx]
mov cx, [line_dx]
test cx, cx
jz draw_line_end
.loop:
mov byte [es:bp], 7
cmp ax, 0
jle .no_y_adjust
; errorterm -= 2·dx
sub ax, [line_dx]
sub ax, [line_dx]
; y += y_adjust
add bp, dx
.no_y_adjust:
; errorterm += 2·dy
add ax, [line_dy]
add ax, [line_dy]
; x += 1
inc bp
loop .loop
jmp draw_line_end
draw_line_high:
mov ax, [line_sy]
cmp ax, [line_ey]
ja draw_line_swap_start_end
cmp word [line_dx], 0
jl .negative_dx
.positive_dx:
mov dx, 1
jmp .x_adjust_done
.negative_dx:
mov ax, [line_dx]
neg ax
mov [line_dx], ax
mov dx, -1
.x_adjust_done
; errorterm = 2·dx - dy
mov ax, [line_dx]
add ax, [line_dx]
sub ax, [line_dy]
mov cx, [line_dy]
test cx, cx
jz draw_line_end
.loop:
mov byte [es:bp], 7
cmp ax, 0
jle .no_x_adjust
; errorterm -= 2·dy
sub ax, [line_dy]
sub ax, [line_dy]
; x += x_adjust
add bp, dx
.no_x_adjust:
; errorterm += 2·dx
add ax, [line_dx]
add ax, [line_dx]
; y += 1
add bp, [width]
loop .loop
draw_line_end:
pop bp
pop dx
pop cx
pop ax
ret
draw_line_swap_start_end:
mov ax, [line_sx]
mov dx, [line_sy]
xchg ax, [line_ex]
xchg dx, [line_ey]
mov [line_sx], ax
mov [line_sy], dx
pop bp
pop dx
pop cx
pop ax
jmp draw_line
; in:
; ax = scale
; bx = angle
@ -268,4 +454,12 @@ hour dw 0
minute dw 0
second dw 0
line_sx dw 0
line_sy dw 0
line_ex dw 0
line_ey dw 0
line_dx dw 0
line_dy dw 0
original_video_mode db 0