一种利用VGA卡增加彩色显示的方法

Author: 青 岛 翁元祥 Date: 1993-11-12

        目前我们使用的16种颜色在显示卡上分别对应于各自的寄存器,它是一个18位的寄存器,红、绿、蓝各占6位,系统一开机,每一个色号所对应的寄存器中红绿蓝色度成一定的比例,就形成一个固定的颜色。如0色号,其红绿蓝均为0,呈黑色,当改变蓝色度为20时就会呈现蓝色,同样,当蓝绿值超过20,红不变时,颜色变为青,所以从以上分析可知,要想获得更多的彩色,只要改变红绿蓝各自的色度值,我们可以把红绿蓝看成三色调和,这样红色,蓝色,绿色值有0~63,其不同值的调和结果,彩色就会产生64×64×64种变化,为此笔者利用C语言中OOTPORTB宏向,指定的接口输出三基色,从而实现了彩色的任意变化。
        这里给出一个实用的获取任一彩色的原程序,程序运行后,首先出现一个色号为4的充满红色的矩型框,框的左边出现一行提示,请输入色号:(015之间选择),当你输入色号后,左下方即出现一个COLOR NUM RED BLUE GREEN分别表示色号、蓝色值、绿色值,这时你按下任意键,矩型框内的颜色随之发生变化,下方提示的红、绿、蓝比值数也发生变化,当你选中颜色后,按下“/”键,即退出该系统,用同样的方法可以改变其它色号所对应的颜色,之后你再用这16种色号时,颜色就变为你定义的了。
        程序为了实现通用性,采用了对VGA寄存器送三基色,这样中西文方式下均可使用。程序还考虑了彩色太小的变化人眼看不出的问题,三基色每个变化值控制在2,读者如要改变,可变三个FOR语句中的增量值,程序用TC 2.0编译通过,在有VGA显示卡的286、386机器上均能运行,附原程序如下
        :#include"dosh"
        #include"graphicsh"
        #include"stdioh"
        main()
        {
        int  colornum,red,
        green,blue;
        int  driver,mode,col
        or;
        driver=DETECT;
        mode=0;
        color=4;
        ini  tgraph(&driver,&mode,"");
        set  fill  style
        (SOLID  FILL,color);
        bar(400,100,620,300);
        goto_xy(9,10);
        printf("input  Color(0-15):");
        scanf("%d",&color);
        if(color==7)
        Vcolornum=color;
        if(color<6)
        colornum=color;
        if(color==6)colornum=color+14;
        if(color>7)
        colornum=color+48;
        for(red=63;red>0;red-=2 )
        {
        if(colornum==-1)
        break;
        for(green=0;green<64;green+=2){
        if(colornum==-1)
        break;
        for(blue=0;blue<64;blue+=2){
        if(colornum==-1)
        break;
        set  fill  style(SOLID-FILL,colornum);
        bar(400,100,620,300);
        outportb(0×3c8,colornum);
        out  portb(0×3c9,red);
        out  portb(0×3c9,green);
        out  portb(0×3c9,blue);
        goto_xy(10,10);
        printf("colornum=%2dred=%2dgreen=%2dblue=%2d\n",colornum,red,green,blue);
        if(getch()=='/,)
        colornum=-1;
        }}}
        }
        gotoxy(x,y)
        int  x,y;
        {
        unionREGSr;
        r:h:ah=2;
        r:h:dl=y;
        r:h:dh=x;
        r:h:bh=0
        int  86(0×10,&r,&r);
        }
        (青岛  翁元祥)