- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于一个学校项目,我正在为 DOSBOX 编写一个汇编绘图程序。在我的程序中,用户使用鼠标左键以某种颜色绘制像素。为此,我在模式 13 中使用直接写入。用户可以通过右键单击来更改该颜色,这会读取鼠标指向的像素的颜色。
这工作得很好,直到用户启动某个旨在删除屏幕的子例程,并显示可供选择的调色板(具有相同的右键单击功能)。然后,用户右键单击调色板中的一种颜色,使用 int 10h,0dh 读取该颜色。无论用户在调色板屏幕的何处右击,用户随后写入屏幕的颜色始终为白色。
tl;dr 右键单击任意位置会正确更改画笔颜色,但如果在调色板模式下完成,后续颜色始终为白色。这是我的代码:
GRAPHICS equ 13h
H_HOTSPOT equ 7
V_HOTSPOT equ 7
H_RES equ 320
V_RES equ 200
PIXELCOUNT equ H_RES*V_RES
DISPLAY_SEG equ 0A000h
EXIT_KEY equ 1071h ; q key
COLORPICKER_KEY equ 1177h ; w key
PALETTE_SIZE equ 16
SQUARE_SIZE equ 10
SQUARE_PADDING equ 2
SQUARE_ROW_JUMP equ H_RES - SQUARE_SIZE
PALETTE_ROW_JUMP equ H_RES - (SQUARE_PADDING + SQUARE_SIZE)*PALETTE_SIZE
sseg SEGMENT
db 256 dup(?)
sseg ENDS
dseg SEGMENT
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
foreground_color dw 000fh
background_color dw 0000h
colorpicker_flag db 00
prev_position dw H_RES ; Cache of the last drawn pixel's coordinates, to avoid duplicate writes.
dw V_RES
pos_backup dw H_RES/2
dw V_RES/2 ; Cache of the mouse position before switching to palette mode or back.
video_mode_not_available db "Mode 13h is not supported on this computer. To use this program, get a VGA or MCGA graphics card / monitor.$"
display_backup db PIXELCOUNT dup(?)
dseg ENDS
cseg SEGMENT
assume cs:cseg, ds:dseg, ss:sseg
;---------------Mouse Procs-------------
stdBrush PROC
push bx cx ax dx
mov ax, dseg
mov es, ax
mov bx, stdBrushHotSpots
mov cx, stdBrushHotSpots + 2
mov ax, 9
mov dx, offset stdBrushMask
int 33h
mov ax, DISPLAY_SEG
mov es, ax
pop dx ax cx bx
ret
stdBrush ENDP
pickerTool PROC
push bx cx ax dx
mov ax, dseg
mov es, ax
mov bx, pickerToolHotSpots
mov cx, pickerToolHotSpots + 2
mov ax, 9
mov dx, offset pickerToolMask
int 33h
mov ax, DISPLAY_SEG
mov es, ax
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
;--------------------Graphics Procs-------------
graphicsCompat PROC
; Checks if mode 13h is supported on this machine.
mov ax, 1a00h
int 10h ; Get display combination
cmp al, 1ah
je mode_13_supported
mov ah, 9
mov dx, offset video_mode_not_available
int 21h ; Display error message
inc sp ; Discard the return address
inc sp
push offset exit ; Replace return address with exit procedure address
ret ; Return to exit procedure.
mode_13_supported:
;No error, mode 13 is supported
ret
graphicsCompat ENDP
graphicsMode PROC
mov ah, 0
mov al, GRAPHICS
int 10h
ret
graphicsMode ENDP
pixel PROC
push bp
mov bp, sp
push ax bx cx dx
xor bx, bx
mov cx, ss:[bp+6] ; x coord
mov dx, ss:[bp+4] ; y coord
cmp cx, H_RES
jnc pixel_outofbounds
cmp dx, V_RES
jnc pixel_outofbounds
mov ax, H_RES
mul dx
add ax, cx
mov di, ax ; Puts the pixel's offset in di
mov ax, ss:[bp+8] ; read color argument
stosb
pixel_outofbounds:
pop dx cx bx ax bp
ret 6
pixel ENDP
backupScreen PROC
push ax di si
mov ax, DISPLAY_SEG
mov ds, ax
mov ax, dseg
mov es, ax
mov cx, PIXELCOUNT
mov si, 0
mov di, offset display_backup
call hideCursor
rep movsb
call showCursor
mov ds, ax
mov ax, DISPLAY_SEG
mov es, ax
pop si di ax
ret
backupScreen ENDP
restoreScreen PROC
push di si
mov cx, PIXELCOUNT
mov si, offset display_backup
mov di, 0
rep movsb
pop si di
ret
restoreScreen ENDP
;-------------------Colorpicker Procs----------
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 backupScreen
call graphicsMode
call paletteDraw
call showCursor
call pickerTool
pop ax
jmp input_loop
palette_mode_off:
call graphicsMode
call restoreScreen
call showCursor
call stdBrush
pop ax
jmp input_loop
paletteModeToggle ENDP
paletteSquareDraw PROC
push bp
mov bp, sp
push ax cx dx
mov dx, ss:[bp+4] ; retrieves ypos
mov cx, ss:[bp+6] ; retrieves xpos
mov ax, H_RES
mul dx
add ax, cx
mov di, ax ; Puts the real pixel address in di.
mov ax, ss:[bp+8] ;retrieves color
xor ch, ch
square_loop:
xor cl, cl
square_row_loop:
stosb
inc cl ; increment horizontal counter
cmp cl, SQUARE_SIZE
jb square_row_loop
inc ch ; increment the vertical counter
add di, SQUARE_ROW_JUMP ; move di to the start of the next row
cmp ch, SQUARE_SIZE
jb square_loop
pop dx cx ax bp
ret 6
paletteSquareDraw ENDP
paletteDraw PROC
xor cx, cx ; xpos = 0
xor dx, dx ; ypos = 0
xor ax, ax ; color = 0
xor bx, bx ; squarecounter = 0
palette_loop: ; for i in paletterows:
xor bl, bl
add dx, SQUARE_PADDING
palette_row_loop: ; for j in palettecols:
add cx, SQUARE_PADDING ; xpos += padding
push ax
push cx
push dx
call paletteSquareDraw ; DrawSquare()
add cx, SQUARE_SIZE
inc ax ; next color
inc bl ; squarecounter++
cmp bl, PALETTE_SIZE
jb palette_row_loop
; prep for new row
xor bl, bl
xor cx, cx
add dx, SQUARE_SIZE
inc bh
cmp bh, PALETTE_SIZE
jb palette_loop
ret
paletteDraw ENDP
pickColor PROC
push bp
mov bp, sp
push ax dx si
mov dx, ss:[bp+4]
mov cx, ss:[bp+6]
xor bh, bh
mov ah, 0dh
int 10h
mov foreground_color, ax
pop si dx ax bp
ret 4
pickColor ENDP
;--------------------------Program Entry-------------------------
main:
mov ax, dseg
mov ds, ax
mov ax, sseg
mov ss, ax
mov ax, DISPLAY_SEG
mov es, ax
call graphicsCompat
call graphicsMode
call mouseReset
call stdBrush
call showCursor
mov ax, DISPLAY_SEG
mov es, ax
input_loop:
;------------Mouse Input Detection------------------------------------
call getCursorStat
shr bx, 1
jnc no_left_click
; Left click detected
mov al, colorpicker_flag
test al, al
jnz no_left_click ; no left clicks in palette mode.
shr cx, 1
cmp cx, prev_position
jnz draw_pixel
cmp dx, prev_position + 2
jz no_left_click
draw_pixel:
call hideCursor
mov ax, foreground_color
mov prev_position, cx
mov prev_position + 2, dx
push ax cx dx
call pixel
call showCursor
no_left_click:
mov bx, 1
mov ax, 6
int 33h
test bx, bx
jz keyboard_detection
; Right click detected
shr cx, 1
push cx dx
call pickColor
keyboard_detection:
;------------Keyboard Input Detection----------------------------------
mov ah, 1
int 16h
jz no_keystroke
xor ah, ah
int 16h
cmp ax, EXIT_KEY
je exit
cmp ax, COLORPICKER_KEY
jne no_palette_toggle
jmp paletteModeToggle
no_palette_toggle:
no_keystroke:
jmp input_loop
exit:
mov al, 3
mov ah, 0
int 10h
mov ax, 4c00h
int 21h
cseg ENDS
end main
为清楚起见,截图: 在绘图模式下使用蓝色笔刷。 切换到调色板模式后,我右键单击亮绿色方 block 。 切换回绘图模式后,画笔正在绘制白色像素。 在绘图模式下右键单击蓝色像素。 画笔颜色正确切换为蓝色。
在这个版本中我使用 int 10h,0dh 来读取像素,但是当我尝试直接从段 A000 读取时出现了同样的问题(在调试期间,当屏幕明显不是时,它似乎完全被零填充空的)。我转而使用 int 10h 来查看直接读取是否是问题所在。
虽然我确实使用了直接写入。
底线问题:我在读取这些像素时做错了什么?为什么我的程序最初能正确读取像素颜色,但在清空屏幕、更改光标并绘制一堆彩色方 block 后,它只读取白色?为什么在清除这些方 block 并将屏幕恢复到之前的状态后它又起作用了?
最佳答案
您的问题是鼠标驱动程序使用软件光标。 VGA 卡不支持硬件光标,这意味着为了显示光标,鼠标驱动程序需要将其绘制到 VGA 帧缓冲区。这意味着当显示选择器光标并且您读取当前鼠标位置的像素时,您实际上正在读取选择器光标热点的颜色,即白色。使用画笔光标时不会发生此问题,因为热点处的像素是透明的。
关于assembly - 在模式 13 中读取像素时出现错误数据(386 程序集 - DOS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38505867/
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!