TASM 精灵看起来很奇怪
TASM sprite looks weird
我最近开始使用 TASM 编写代码,目前正在研究精灵。在我的程序中,我收到一个精灵并将其打印在屏幕上(图形模式)。
该程序基本上运行良好,但打印的数字看起来很奇怪。本应位于彼此正下方的像素看起来有些距离。
我是这样调用函数的:
push 10 ; amount of lines
push 10 ; length of each line
push 4 ; color
push 100 ; y
push 160 ; x
push offset card2
call Sprite_Figure
函数如下:
proc Sprite_Figure
push bp
mov bp, sp
push ax
push bx
push cx
push dx
push si
mov si, [bp+4] ; sprite offset
mov cx, [bp+14] ; number of lines
loop1:
mov dx, [bp+12] ; size of one line
loop2:
push dx
xor dx, dx
cmp [byte ptr si], 0
je continue
print:
mov bx, [bp+8] ; current row
mov ax, 320
mul bx
mov bx, ax ; calculation to get location of pixel on screen
add bx, [bp+6] ; x
mov ax, [bp+10] ; color
mov [es:bx], al ; color location, es val is 0A000h
continue:
pop dx
inc si ; next element in array
dec dx
inc [bp+6] ; right by one
cmp dx, 0
jne loop2
mov ax, 320
sub ax, [bp+12] ; the size of one line
add [bp+6], ax ; new line
inc [bp+8] ; one line down
dec cx
cmp cx, 0
jne loop1
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
ret 12
endp Sprite_Figure
精灵在屏幕上的样子:
有没有人有什么想法?
代码混合了 2 种向下移动的方式!这解释了为什么代码在屏幕上以双倍速率下降,值 320 被添加两次。
基本上你有几种绘制字符矩阵的方法:
- 一对嵌套循环,您可以在其中改变 X 和 Y 坐标并每次计算屏幕上的地址。
- 一对嵌套循环,您计算一次屏幕左上角像素的地址,然后根据需要更改该地址。
行
inc [bp+8] ; one line down
适合第一种方法,而行
mov ax, 320
sub ax, [bp+12] ; the size of one line
add [bp+6], ax ; new line
适合第二种方法
方法一
因为内层循环重复递增了X坐标,为了恢复,必须减去总递增次数:
...
dec dx
jnz loop2
mov ax, [bp+12] ; Size of one line (number of increments)
sub [bp+6], ax ; X is now restored
inc [bp+8] ; Y+ one line down
dec cx
jnz loop1
方法2
坐标仅用于获取BX地址一次。之后只有地址有所不同。循环中的指令少了很多,这意味着这是一种更有效的方法。
mov ax, 320
mul [word ptr bp+8] ; Y
mov bx, ax
add bx, [bp+6] ; X
mov si, [bp+4] ; sprite offset
mov cx, [bp+14] ; number of lines
mov al, [bp+10] ; color
loop1:
mov dx, [bp+12] ; size of one line
loop2:
cmp [byte ptr si], 0
je continue
mov [es:bx], al ; ES val is 0A000h
continue:
inc si ; next byte in character pattern
inc bx ; X+ right by one on screen
dec dx
jnz loop2
sub bx, [bp+12] ; Address of left side
add bx, 320 ; Address of new line
dec cx
jnz loop1
我最近开始使用 TASM 编写代码,目前正在研究精灵。在我的程序中,我收到一个精灵并将其打印在屏幕上(图形模式)。
该程序基本上运行良好,但打印的数字看起来很奇怪。本应位于彼此正下方的像素看起来有些距离。
我是这样调用函数的:
push 10 ; amount of lines
push 10 ; length of each line
push 4 ; color
push 100 ; y
push 160 ; x
push offset card2
call Sprite_Figure
函数如下:
proc Sprite_Figure
push bp
mov bp, sp
push ax
push bx
push cx
push dx
push si
mov si, [bp+4] ; sprite offset
mov cx, [bp+14] ; number of lines
loop1:
mov dx, [bp+12] ; size of one line
loop2:
push dx
xor dx, dx
cmp [byte ptr si], 0
je continue
print:
mov bx, [bp+8] ; current row
mov ax, 320
mul bx
mov bx, ax ; calculation to get location of pixel on screen
add bx, [bp+6] ; x
mov ax, [bp+10] ; color
mov [es:bx], al ; color location, es val is 0A000h
continue:
pop dx
inc si ; next element in array
dec dx
inc [bp+6] ; right by one
cmp dx, 0
jne loop2
mov ax, 320
sub ax, [bp+12] ; the size of one line
add [bp+6], ax ; new line
inc [bp+8] ; one line down
dec cx
cmp cx, 0
jne loop1
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
ret 12
endp Sprite_Figure
精灵在屏幕上的样子:
有没有人有什么想法?
代码混合了 2 种向下移动的方式!这解释了为什么代码在屏幕上以双倍速率下降,值 320 被添加两次。
基本上你有几种绘制字符矩阵的方法:
- 一对嵌套循环,您可以在其中改变 X 和 Y 坐标并每次计算屏幕上的地址。
- 一对嵌套循环,您计算一次屏幕左上角像素的地址,然后根据需要更改该地址。
行
inc [bp+8] ; one line down
适合第一种方法,而行
mov ax, 320 sub ax, [bp+12] ; the size of one line add [bp+6], ax ; new line
适合第二种方法
方法一
因为内层循环重复递增了X坐标,为了恢复,必须减去总递增次数:
...
dec dx
jnz loop2
mov ax, [bp+12] ; Size of one line (number of increments)
sub [bp+6], ax ; X is now restored
inc [bp+8] ; Y+ one line down
dec cx
jnz loop1
方法2
坐标仅用于获取BX地址一次。之后只有地址有所不同。循环中的指令少了很多,这意味着这是一种更有效的方法。
mov ax, 320
mul [word ptr bp+8] ; Y
mov bx, ax
add bx, [bp+6] ; X
mov si, [bp+4] ; sprite offset
mov cx, [bp+14] ; number of lines
mov al, [bp+10] ; color
loop1:
mov dx, [bp+12] ; size of one line
loop2:
cmp [byte ptr si], 0
je continue
mov [es:bx], al ; ES val is 0A000h
continue:
inc si ; next byte in character pattern
inc bx ; X+ right by one on screen
dec dx
jnz loop2
sub bx, [bp+12] ; Address of left side
add bx, 320 ; Address of new line
dec cx
jnz loop1