Я пытаюсь сделать небольшую программу, похожую на рисование, на ассемблере для DOSBox. Я не уверен, какой тип процессора эмулирует DOSBox, но из того, что я нашел, это может быть 386.
Я провел исследование и выяснил, как использовать прерывание мыши, 33h. Мне также удалось использовать маски экрана и маски курсора для определения собственного курсора. Однако я хочу иметь возможность изменить свой курсор позже в программе, когда пользователь переключится, например, на инструмент цветового сэмплера. Когда я пытался это сделать, курсор превращался в черный квадрат. Это потому, что я не знаю точно шаги, необходимые для выполнения такого изменения.
Я должен скрыть курсор, затем сбросить его, затем изменить маску курсора, а затем снова показать? Менять маску и только ПОТОМ сбрасывать? Мне вообще не нужно сбрасывать мышь? Вот весь мой код, связанный с мышью.
P.S. Я знаю, что многое из этого можно оптимизировать, превратив кучу процессов в макросы, и я мог бы сделать это в будущем, когда разберусь с ошибками.
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.
Если вам нужно увидеть какие-либо другие части моего кода, пожалуйста, дайте мне знать.