怎样在DOS平台下置取调色板

2009年11月5日 由 admin 留言 »

说实话,在DOS平台下置取调色板可要比在Windows平台下简单多了,而且置了之后决对正确,不会出现象DirectDraw那样置了还未必起作用的情况。

好了,言归正传,我来详细讲述一下置调色板的办法。对于读调色板就不再介绍了,因为每一个优秀的C/C++程序员都不会笨到去读取调色板。调色板是什么样的,随时都掌握在他们的程序中,要什么调色板就设置成什么样的,从来不去读调色板。

假设我们对调色板的定义如下:

uvar8 Palette[256][3];

uvar8表示8位无符号变量,表示范围是0-255。Palette变量中有256种颜色,以Palette[颜色号]来表示。每个颜色中均保存红、 绿、蓝三原色的值。Palette[0][0]就表示第0种颜色的红色值,同样Palette[0][1]就表示第0种颜色的绿色值。

在DOS平台下,设置调色板的办法是多种多样的,以下我将逐一介绍:


方法一:16位DOS平台下,调用中断进行设置

由于16位DOS平台下,主流编程工具Borland C/C++与Turbo C/C++只支持16色,所以显得很无用。所以我们只好自己调用中断进行设置了,源程序如下:void SetPalette(uvar8 pal[256][3])
{
union REGS r;
struct SREGS s;
r.h.ah=0x10;
r.h.al=0x12;
r.x.bx=0;
r.x.cx=256;
s.es=FP_SEG(pal);
r.x.dx=FP_OFF(pal);
int86x(0x10,&r,&r,&s);
}

方法二:16位DOS平台下,直接写DAC进行设置

相比之下,在16位DOS平台下,置调色板最快的手法莫过于直接写DAC了,源程序如下:void SetDac(uvar8 idx,uvar8 red,uvar8 green,uvar8 blue)
{
asm {
mov dx,3c8h
mov al,idx
out dx,al

mov cl,2
inc dx
mov al,red
shr al,cl
out dx,al
mov al,green
shr al,cl
out dx,al
mov al,blue
shr al,cl
out dx,al
}
}

void SetPalette(uvar8 pal[256][3])
{
for(uvar16 i=0;i<256;i++)SetDac(i,pal[i][0],pal[i][1],pal[i][2]);
}

不要问我那倒数第二行为什么要用uvar16来定义i,而不用uvar8,您自己试一下就知道了。


方法三:32位DOS平台下,使用Watcom C/C++编程时直接使用其图形函数进行设置

Watcom C/C++不愧为优秀的32位DOS平台开发工具,它的图形函数直接用来编游戏都没问题,所以速度上也绝对慢不了。源程序如下:void SetPalette(uvar8 pal[256][3])
{
uvar32 pal256[256];
uvar16 i;
for(i=0;i<256;i++)pal256[i]=pal[i][2]/4*0x10000+pal[i][1]/4*0x100+pal[i][0]/4;
_remapallpalette(&pal256);
}
当然,这个程序还未做过优化,留着您自己优化吧!这里我只讲怎么设置调色板。

方法四:32位DOS平台下,调用中断进行设置

不过是方法一的16位转32位吧了,没什么大的变化,源程序如下:void SetPalette(uvar8 pal[256][3])
{
union REGS r;
struct SREGS s;
r.h.ah=0x10;
r.h.al=0x12;
r.w.bx=0;
r.w.cx=256;
s.es=FP_SEG(pal);
r.x.dx=FP_OFF(pal);
int386x(0x10,&r,&r,&s);
}

当然,32位DOS环境也可以直接写DAC以便取得最快的速度,但是32位DOS下的汇编程序是很难写的(其实不难,只不过写出来很长),所以我就偷懒不写了,反正以上四种方法也够用了。

广告位

发表回复

你必须 登陆 方可发表评论.
鄂ICP备09027626号