【发布时间】:2016-07-20 20:26:21
【问题描述】:
我正在尝试在 Assembly 中为 DOSBox 制作一个类似于绘画的小程序。我不确定 DOSBox 模拟什么 CPU 类型,但据我发现它可能是 386。
我进行了研究,并弄清楚了如何使用鼠标中断,33 小时。我还设法使用屏幕掩码和光标掩码来定义我自己的光标。但是,当用户切换到例如颜色采样器工具时,我希望稍后能够在程序中更改我的光标。当我尝试这样做时,光标变成了一个黑色方块。这是因为我不确切知道执行此类更改所需的步骤。
我是否应该隐藏光标,然后重置它,然后更改光标掩码,然后再次显示?我是否更改了面具,然后才重置?我根本不需要重置鼠标吗?这是我所有与鼠标相关的代码。
附:我知道我可以通过将一堆 proc 转换为宏来优化其中的大部分内容,并且一旦我解决了错误,我可能会在将来这样做。
stdBrush PROC
push bx cx ax dx
mov bx, stdBrushHotSpots
mov cx, stdBrushHotSpots + 2
mov ax, 9
mov dx, offset stdBrushMask
int 33h
pop dx ax cx bx
ret
stdBrush ENDP
pickerTool PROC
push bx cx ax dx
mov bx, pickerToolHotSpots
mov cx, pickerToolHotSpots + 2
mov ax, 9
mov dx, offset pickerToolMask
int 33h
pop dx ax cx bx
ret
pickerTool ENDP
mouseReset PROC
push ax
mov ax, 0
int 33h
pop ax
ret
mouseReset ENDP
showCursor PROC
push ax
mov ax, 1
int 33h
pop ax
ret
showCursor ENDP
hideCursor PROC
push ax
mov ax, 2
int 33h
pop ax
ret
hideCursor ENDP
getCursorStat PROC
push ax
mov ax, 3
int 33h
pop ax
ret
getCursorStat ENDP
initCursor PROC
mov ax, dseg
mov es, ax
call mouseReset
call stdBrush
call showCursor
mov ax, DISPLAY_SEG
mov es, ax
ret
initCursor ENDP
这些是用作使用 int 33h 不同功能的快捷方式的小程序。例外是 initCursor,它结合了这些快捷方式来在程序开始时初始化光标,以及 stdBrush 和 pickerTool 两者都将图形光标设置为特定光标(你可以猜到,stdBrush 是标准画笔光标,而 pickerTool 设置颜色采样器工具的光标)。
下面是我的两个光标的掩码。
stdBrushMask dw 1111111011111111b
dw 1111111011111111b
dw 1111111011111111b
dw 1111111011111111b
dw 1111111011111111b
dw 1111111011111111b
dw 1111111011111111b
dw 0000000100000000b
dw 1111111011111111b
dw 1111111011111111b
dw 1111111011111111b
dw 1111111011111111b
dw 1111111011111111b
dw 1111111011111111b
dw 1111111011111111b
dw 1111111011111111b
dw 0000000100000000b
dw 0000000100000000b
dw 0000000100000000b
dw 0000000100000000b
dw 0000000100000000b
dw 0000000100000000b
dw 0000000100000000b
dw 1111111011111111b
dw 0000000100000000b
dw 0000000100000000b
dw 0000000100000000b
dw 0000000100000000b
dw 0000000100000000b
dw 0000000100000000b
dw 0000000100000000b
dw 0000000100000000b
stdBrushHotSpots dw 7
dw 7
pickerToolMask dw 1111100001000001b
dw 1111100000000000b
dw 1111100000000000b
dw 1111100000000000b
dw 1111100000000000b
dw 1111000000000000b
dw 1110000000000000b
dw 1100000000000000b
dw 1000000000000000b
dw 1000000000000000b
dw 1000000000000000b
dw 1000000000011111b
dw 0000000000111111b
dw 0000000001111111b
dw 0000000011111111b
dw 0000111111111111b
dw 0000000000000000b
dw 0000001100011100b
dw 0000001111111110b
dw 0000000111111110b
dw 0000000111111110b
dw 0000001111111100b
dw 0000011111111100b
dw 0000111111111100b
dw 0001111111111110b
dw 0011111111100110b
dw 0001111111000000b
dw 0001111110000000b
dw 0011111100000000b
dw 0111001000000000b
dw 0110000000000000b
dw 0000000000000000b
pickerToolHotSpots dw 1
dw 14
由于将代码复制到 stackoverflow 导致了一些缩进差异,我懒得逐行修复它们。
这是程序中给我带来麻烦的部分:
paletteModeToggle PROC
push ax
call hideCursor
mov pos_backup, cx
mov pos_backup+2, dx
mov al, colorpicker_flag
not al
mov colorpicker_flag, al
test al, al
jz palette_mode_off
palette_mode_on:
call pickerTool
call backupScreen
call graphicsMode
call paletteDraw
call mouseReset
call showCursor
pop ax
jmp input_loop
palette_mode_off:
call stdBrush
call graphicsMode
call restoreScreen
call mouseReset
call showCursor
pop ax
jmp input_loop
paletteModeToggle ENDP
它显示了一个调色板,它应该将光标更改为颜色采样器工具光标。相反,光标变成黑色方块,即使在调色板模式关闭时也保持这种状态。我怀疑我在更改光标时没有采取正确的步骤。当光标尚未显示时,它在程序开始时工作得很好。
在此过程中,我隐藏光标,然后更改光标掩码,然后将鼠标重置为默认驱动程序值(甚至不确定是否有必要),然后再次使其可见。我做错了吗?
顺便说一句,如果你还没有注意到,我正在使用 TASM。
如果您需要查看我的代码的更多部分,请告诉我。
【问题讨论】: