我正在开发8086程序集中的游戏项目(在DOSBOX中)。
我有一个可以在图形模式下工作的蛇形游戏,以及一个可以在屏幕上打印BMP文件的菜单。
我唯一的问题是在打印过程中我将调色板更改为bmp调色板。
变色过程:
(这是将bmp打印到屏幕的代码的一部分)
proc ReadPalette
; Read BMP file color palette, 256 colors * 4 bytes (400h)
mov ah,3fh
mov cx,400h
mov dx,offset Palette
int 21h
ret
endp ReadPalette
proc CopyPal
; Copy the colors palette to the video memory registers
; The number of the first color should be sent to port 3C8h
; The palette is sent to port 3C9h
mov si,offset Palette
mov cx,256
mov dx,3C8h
mov al,0
; Copy starting color to port 3C8h
out dx,al
; Copy palette itself to port 3C9h
inc dx
PalLoop:
; Note: Colors in a BMP file are saved as BGR values rather than RGB.
mov al,[si+2] ; Get red value.
shr al,2 ; Max. is 255, but video palette maximal
; value is 63. Therefore dividing by 4.
out dx,al ; Send it.
mov al,[si+1] ; Get green value.
shr al,2
out dx,al ; Send it.
mov al,[si] ; Get blue value.
shr al,2
out dx,al ; Send it.
add si,4 ; Point to next color.
; (There is a null chr. after every color.)
loop PalLoop
ret
endp CopyPal
此代码不是我的,我所知道的是它改变了整个程序的调色板。
当我在打印图像后使用int 10h打印像素时,它仍在使用此调色板。
但是当我在打印任何图像之前打印一个像素时,该像素具有正常的BIOS颜色。
我想知道如何将调色板更改回BIOS调色板。
bmp调色板我发现:
答案 0 :(得分:2)
您必须在更改之前保存BIOS标准调色板,然后在完成后将其存储回来。
执行此操作的示例代码可能是
;WORD Buffer Segment
;WORD Buffer Offset
;DF = Direction of saving
SavePalette:
push bp
mov bp, sp
push es
push di
push ax
push dx
push cx
mov es, WORD [bp+06h]
mov di, WORD [bp+04h]
xor al, al
mov dx, 3c7h
out dx, al ;Read from index 0
inc dx
inc dx
mov cx, 300h ;3x256 reads
rep insb
pop cx
pop dx
pop ax
pop di
pop es
pop bp
ret 04h
;WORD Buffer Segment
;WORD Buffer Offset
;DF = Direction of loading
RestorePalette:
push bp
mov bp, sp
push ds
push si
push ax
push dx
push cx
mov ds, WORD [bp+06h]
mov si, WORD [bp+04h]
xor al, al
mov dx, 3c8h
out dx, al ;Write from index 0
inc dx
mov cx, 300h ;3x256 writes
rep outsb
pop cx
pop dx
pop ax
pop si
pop ds
pop bp
ret 04h
要使用此代码,您需要一个300h字节的缓冲区,假设它被称为PaletteBuffer
,它位于DS
段。
push ds
push WORD PaletteBuffer
call SavePalette
;Change palette for bitmap
push ds
push WORD PaletteBuffer
call RestorePalette
值得注意的是,更改整个调色板的速度很慢,请考虑更改代码以仅保存/恢复所需的颜色(可能是前16个)或仅将位图颜色映射到高索引(如果它们小于256)号。
这也是NASM程序集,我还没有对代码进行测试,只是草拟了它,因为我不想设置DosBox。
答案 1 :(得分:0)
http://www.cs.cmu.edu/~ralf/files.html - > inter61a.zip - > INTERRUP.A
--------V-101017-----------------------------
INT 10 - VIDEO - READ BLOCK OF DAC REGISTERS (VGA/MCGA)
AX = 1017h
BX = starting palette register
CX = number of palette registers to read
ES:DX -> buffer (3 * CX bytes in size) (see also AX=1012h)
Return: buffer filled with CX red, green and blue triples
SeeAlso: AX=1012h,AX=1015h,INT 62/AX=00A4h
--------V-101012-----------------------------
INT 10 - VIDEO - SET BLOCK OF DAC REGISTERS (VGA/MCGA)
AX = 1012h
BX = starting color register
CX = number of registers to set
ES:DX -> table of 3*CX bytes where each 3 byte group represents one
byte each of red, green and blue (0-63)
Return: nothing
SeeAlso: AX=1010h,AX=1017h,INT 62/AX=00A5h