2016-08-09 7 views
0

Я работаю в графическом режиме (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 
+0

Почему вы используете RET 6 в конце PrintPixel? Почему вы не используете только RET? Я имею в виду, вы можете заставить указатель выполнения перейти в цвет/координату [BP + 6]. –

+1

@DavidBS: Это выглядит хорошо для меня. 'ret 6' pops отклоняется от стека * после * popping обратного адреса. Это единственный эффективный способ реализации соглашения о вызове caller-cleans-the-stack. –

+0

@PeterCordes, он не будет истинным ТОЛЬКО, если после завершения мы не будем записывать все регистры и BP? Я не могу считать его регулярным, если выполняются все POP (включая оригинальное BP). –

ответ

1

Я не думаю, что они могут исчезнуть, пиксели не работают в режиме 320x200. Я уверен, что они там.

То, что вы называете «исчезающим», возможно, вы устанавливаете для них значение, которого вы не хотели, как ноль.

Чтобы стереть курсор мыши, вы должны установить пиксели, где курсор WAS имеет значения пикселей из фонового изображения, которое должно быть «под» курсором.

Вы можете сделать это, как (псевдо-код):

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 

О том копировать/Blit ... Распространено создать некоторую "спрайты" манипуляция процедуру, как, например:

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 

Процедуры для хранения/восстановления фонового изображения могут быть немного проще, так как им не нужно проверять прозрачность, но принцип тот же (копировать память из/в VRAM размера [sizex, sizey] в некоторый внутренний буфер, или из данных gfx).

Не используйте int 10h для пиксельного рисунка, рисунок непосредственно A000:xxxx VRAM очень прост в режиме 320x200 (вы должны увидеть организацию VRAM на ZX Spectrum, а еще лучше один, Atari 2600 консоль (подсказка: это не имеет никакого VRAM вообще), теперь они не были тривиальными, но режим 13h на VGA - это чистая радость использовать напрямую). Очень просто и намного намного быстрее, даже этот наивный неоптимизированный «blit_transparent_gfx» (написанный так, чтобы было легко понять, как он работает) будет невероятно быстрым по сравнению с чем-либо с вызовом int 10h.

PS. Я не отлаживал этот «blit_transparent_gfx» (очевидно, вы в первую очередь исправляете эти строки pseudo [param ...] с реальным кодом в любом случае, просто чтобы скомпилировать его), так что, возможно, я сделал там какую-то ошибку, не стесняйтесь отлаживать ее тогда (хотя я вроде бы он должен работать так, как есть, как только вы исправите синтаксис).