I am working on a game project in 8086 assembly (in DOSBOX).
I have a working snake game that workes on graphic mode, and a menu that works on printing BMP files to the screen.
My only problem is that in the printing process i change the color palette to the bmp color palette.
the color changing procces:
(this is a part of the code that prints a bmp to the screen)
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
This code is not mine and all i know is that it changes the color palette for the whole program.
When I use int 10h to print a pixel after printing an image it still is using this color palette.
But when i print a pixel before printing any image, the pixel has the normal BIOS colors.
I would like to know how to change the color palette back to the BIOS color palette.
bmp color palette I've found:
You have to save the BIOS standard palette before changing it and then store it back when done.
Sample code to do this may be
;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
To use this code you need a buffer of 300h bytes, assume it is called PaletteBuffer
and it is located in the DS
segment.
push ds
push WORD PaletteBuffer
call SavePalette
;Change palette for bitmap
push ds
push WORD PaletteBuffer
call RestorePalette
It is worth noting that changing the whole palette is slow, consider changing the code to save/restore only the colors you need (likely the first 16) or map the bitmap colors to high index only if they are less than 256 in number.
Also this is NASM assembly and I haven't tested the code, just sketched it as I don't feel like setting a DosBox up.