在打印像素上移动鼠标时,图形模式中的像素被删除
pixels in Graphic mode are deleted while moving the mouse on the printed pixels
我在图形模式下工作 (320X200)。
我写了一个代码,在鼠标光标被点击的地方打印一行。
是打印像素,但是当我移动鼠标时,一些像素消失了。
ParX equ [bp+8]
ParY equ [bp+6]
ParColor equ [bp+4]
proc PrintPixel
push bp
mov bp, sp
push ax
push bx
push cx
push dx
mov bh, 0
mov cx, ParX
mov dx, ParY
mov al, ParColor
mov ah, 0ch
int 10h
pop dx
pop cx
pop bx
pop ax
pop bp
ret 6
endp PrintPixel
;main
mov ax,0h
int 33h
mov ax,1h
int 33h
MouseLP:
mov ax,3h
int 33h
cmp bx, 01h ; check left mouse click
jne MouseLP
push cx
push dx
mov al, [color]
push ax
call CreateX
我认为它们不会消失,像素不会在 320x200 模式下消失。我很确定他们在那里。
你所说的 "disappear" 可能是你将它们设置为你不想要的值,比如零。
要擦除鼠标光标,您应该使用背景图像中的像素值设置光标所在的像素,这应该是 "under" 光标。
你可以这样做(伪代码):
drawCursor: ; draw cursor at x, y
; there should be no cursor at screen before calling this
mov [oldMouseX],x
mov [oldMouseY],y
copy_memory(to backgroundBuffer, from vram at x,y, cursor size x/y)
blit_cursor(at x, y, cursor gfx)
ret
hideCursor: ; before drawing it at new position
blit_memory(at [oldMouseX], [oldMouseY], from backgroundBuffer, cursor size x/y)
ret
关于那些 copy/blit...
创建一些 "sprite" 操作例程很常见,例如:
blit_transparent_gfx:
; params x, y, gfx data ptr, gfx data sizex, gfx data sizey
; globals word [ScreenSizeX] = 320, byte [transparent color]
; calculate direct address into VRAM into es:di
push 0a000h
pop es ; es pointing to VRAM
mov ax,[ScreenSizeX] ; 320
mul word [param y]
add ax,[param x]
mov di,ax ; es:di = VRAM address to write pixels
; prepare registers for outside line loop
mov ah,[transparent color]
mov si,[param gfx data ptr]
mov dx,[param gfx data sizey]
blit_transparent_line:
; outer line loop
mov cx,[param gfx data sizex]
push di
; inner loop drawing pixels
blit_transparent_pixel:
mov al,[si]
cmp al,ah
jz blit_transparent_pixel_skip
mov [es:di],al
blit_transparent_pixel_skip:
inc si
inc di
dec cx
jnz blit_transparent_pixel
; move VRAM pointer one line down
pop di
add di,[ScreenSizeX]
dec dx
jnz blit_transparent_line
ret
store/recover背景图片的例程可以稍微简单一些,因为它们不必测试透明度,但原理是相同的(复制内存from/to大小为[sizex的VRAM, sizey] 到某个内部缓冲区,或来自 gfx 数据)。
像素绘制不要使用int 10h
,直接绘制到A000:xxxx
VRAM在320x200模式下非常简单(你应该在ZX Spectrum上看到VRAM组织,或者更好的一个,Atari 2600 控制台(提示:它根本没有 VRAM),现在这些都不是微不足道的,但是 VGA 上的 13h 模式直接使用是纯粹的乐趣)。非常简单,而且速度要快得多,即使是这种天真的未优化 "blit_transparent_gfx"(这样写,应该很容易理解它是如何工作的)与涉及 int 10h
调用的任何东西相比,速度也会非常快。
PS。我没有调试那个 "blit_transparent_gfx" (显然你必须首先用真实代码修复那些伪 [param ...]
行,只是为了编译它),所以也许我在那里做了一些错误,随意调试它然后(虽然我有点确定它应该按原样工作,一旦你修复了语法)。
我在图形模式下工作 (320X200)。
我写了一个代码,在鼠标光标被点击的地方打印一行。
是打印像素,但是当我移动鼠标时,一些像素消失了。
ParX equ [bp+8]
ParY equ [bp+6]
ParColor equ [bp+4]
proc PrintPixel
push bp
mov bp, sp
push ax
push bx
push cx
push dx
mov bh, 0
mov cx, ParX
mov dx, ParY
mov al, ParColor
mov ah, 0ch
int 10h
pop dx
pop cx
pop bx
pop ax
pop bp
ret 6
endp PrintPixel
;main
mov ax,0h
int 33h
mov ax,1h
int 33h
MouseLP:
mov ax,3h
int 33h
cmp bx, 01h ; check left mouse click
jne MouseLP
push cx
push dx
mov al, [color]
push ax
call CreateX
我认为它们不会消失,像素不会在 320x200 模式下消失。我很确定他们在那里。
你所说的 "disappear" 可能是你将它们设置为你不想要的值,比如零。
要擦除鼠标光标,您应该使用背景图像中的像素值设置光标所在的像素,这应该是 "under" 光标。
你可以这样做(伪代码):
drawCursor: ; draw cursor at x, y
; there should be no cursor at screen before calling this
mov [oldMouseX],x
mov [oldMouseY],y
copy_memory(to backgroundBuffer, from vram at x,y, cursor size x/y)
blit_cursor(at x, y, cursor gfx)
ret
hideCursor: ; before drawing it at new position
blit_memory(at [oldMouseX], [oldMouseY], from backgroundBuffer, cursor size x/y)
ret
关于那些 copy/blit... 创建一些 "sprite" 操作例程很常见,例如:
blit_transparent_gfx:
; params x, y, gfx data ptr, gfx data sizex, gfx data sizey
; globals word [ScreenSizeX] = 320, byte [transparent color]
; calculate direct address into VRAM into es:di
push 0a000h
pop es ; es pointing to VRAM
mov ax,[ScreenSizeX] ; 320
mul word [param y]
add ax,[param x]
mov di,ax ; es:di = VRAM address to write pixels
; prepare registers for outside line loop
mov ah,[transparent color]
mov si,[param gfx data ptr]
mov dx,[param gfx data sizey]
blit_transparent_line:
; outer line loop
mov cx,[param gfx data sizex]
push di
; inner loop drawing pixels
blit_transparent_pixel:
mov al,[si]
cmp al,ah
jz blit_transparent_pixel_skip
mov [es:di],al
blit_transparent_pixel_skip:
inc si
inc di
dec cx
jnz blit_transparent_pixel
; move VRAM pointer one line down
pop di
add di,[ScreenSizeX]
dec dx
jnz blit_transparent_line
ret
store/recover背景图片的例程可以稍微简单一些,因为它们不必测试透明度,但原理是相同的(复制内存from/to大小为[sizex的VRAM, sizey] 到某个内部缓冲区,或来自 gfx 数据)。
像素绘制不要使用int 10h
,直接绘制到A000:xxxx
VRAM在320x200模式下非常简单(你应该在ZX Spectrum上看到VRAM组织,或者更好的一个,Atari 2600 控制台(提示:它根本没有 VRAM),现在这些都不是微不足道的,但是 VGA 上的 13h 模式直接使用是纯粹的乐趣)。非常简单,而且速度要快得多,即使是这种天真的未优化 "blit_transparent_gfx"(这样写,应该很容易理解它是如何工作的)与涉及 int 10h
调用的任何东西相比,速度也会非常快。
PS。我没有调试那个 "blit_transparent_gfx" (显然你必须首先用真实代码修复那些伪 [param ...]
行,只是为了编译它),所以也许我在那里做了一些错误,随意调试它然后(虽然我有点确定它应该按原样工作,一旦你修复了语法)。