多谢!!!
七.设置颜色寄存器
我们知道VGA显示卡具有显示256种颜色的能力,每种颜色能够用一个0-255之间的数值来表示,那么这些数值与我们在屏幕上实际见到的颜色之间有什么关系呢?其实这些数值只是VGA显示卡上的颜色寄存器的索引值,颜色寄存器里才保存了屏幕上颜色的真实值。VGA显示卡上有一个包含256个单元的颜色寄存器(又称为调色板),每个单元由三部份组成,这三部份分别代表颜色中的红、绿、蓝三种成份(显示器就是用这三种成份来组成任何我们所看到的颜色),用三个字节表示,颜色寄存器一共有768个字节(3*256=768)。当我们要在屏幕上显示某种颜色时,显示卡硬件就根据颜色的索引值在颜色寄存器中查找,找到后再从相应单元中取出颜色值显示在屏幕上,这个过程与画家使用调色板相似,颜色寄存器相当于调色板,颜色寄存器中的单元相当于调色板上的色格,在色格中装有预先调好的颜色,当画家需要用某种颜色作画时,就从装有那种颜色的色格中把颜色取出来。例如,我们要显示颜色索引值为30的颜色,显示卡硬件就去查找颜色寄存器的第30单元,30单元位于距颜色寄存器首址3*30=90处(因为每个单元有三个字节),然后取出90处记录有红、绿、蓝三种成份的三个字节作为在屏幕上显示的色彩信号。但是实际上每个字节只用了六位来表示颜色,其它两位没用,这六位表示的数的值域为0-63,所以每种颜色(红、绿、蓝)成份具有64种亮度的表现能力,三种颜色成份组合共可以产生64*64*64=262,144种颜色(VGA 13H模式从这262,144种颜色中取出256种在同一屏幕上显示)。我们可以通过事先设置颜色寄存器的值来使用我们自己的颜色。
设置颜色寄存器有多种方法,如调用BIOS功能,但是这种方法速度比较慢,游戏设计中通常采用直接访问VGA显示卡的I/O端口的方法来快速设置颜色寄存器,我们只需访问四个I/O端口就可以完成设置颜色寄存器的工作。这四个端口分别是: 0x3c6、0x3c7、0x3c8和0x3c9。
端口0x3c6称为调色板屏蔽寄存器,用来屏蔽所要求的调色板寄存器的位,如果你在这个寄存器中放入0xff,你就可以通过调色板索引寄存器0x3c7和0x3c8(一个用于读,一个用于写)访问任何你希望访问的颜色寄存器,端口0x3c9称为调色板数据寄存器,红、绿、蓝三种成份就是通过它进行读写(颜色值要读或写三次)。
我们定义一个结构来方便处理颜色寄存器:
typedef struct RGB_COLOR
{
unsigned char red;
unsigned char green;
unsigned char blue;
}RGBColor,*RGBColorPtr;
结构中的red、green和blue变量用来保存颜色的红、绿、蓝三种成份。
设置颜色寄存器值的函数:
void SetPaletteRegister(int index,RGBColorPtr color)
{
outportb(0x3c6,0xff);
outportb(0x3c8,index);
outportb(0x3c9,color->red);
outportb(0x3c9,color->green);
outportb(0x3c9,color->blue);
}
获取颜色寄存器值的函数:
void GetPaletteRegister(int index,RGBColorPtr color)
{
outportb(0x3c6,0xff);
outportb(0x3c7,index);
color->red=inportb(0x3c9);
color->green=inportb(0x3c9);
color->blue=inportb(0x3c9);
}