在打印像素上移动鼠标时,图形模式中的像素被删除

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 ...] 行,只是为了编译它),所以也许我在那里做了一些错误,随意调试它然后(虽然我有点确定它应该按原样工作,一旦你修复了语法)。