[net.micro.pc] New palette.c

ksj@proper.UUCP (ksj) (07/02/86)

    Here is another version of the EGA PALETTE program posted recently.
This version makes it very easy to see all 64 available colors and
uses the whole screen, giving large color samples.
    -Kent Johnson
    -ucbvax!dual!proper!ksj
------------------------------ cut here -------------------------------
/*                            NEWPAL.C
 
    By Kent Johnson & Jeffrey William Gillette
    Inspired by Palette.c by Jeffrey William Gillette
    
    Newpal gives an easy way to review all 64 colors available with the EGA.
One color (R, G, B) is selected as the "z-axis" color.  Then the screen
displays the 16 colors which can be made with the other two colors.  Use
up-arrow or down-arrow to mix in varying amounts of the z-axis color.
Thus all 64 colors are shown in four screens and it is easy to compare
similar shades.

    A legend in each color block shows the actual value written 
to the palette register for that color.

    Press Esc to exit.  The text and background colors are reset to values
contained in the environment variables TEXTCOLOR & BACKCOLOR,
or 7 & 0 by default.

    Written with MSC 3.0.  To compile & link:  cl -Me newpal.c
    Requires ANSI.SYS

    This program is in the public domain and may be copied and used freely.
*/
 
#include <stdio.h>
#include <dos.h>
 
#define VIDSEG      0xb8000000
 
/*  ANSI escape codes                       */
#define SETCURSOR "\033[%d;%dH"
#define CLEARSCREEN "\033[2J"

/* masks for palette values */
int mask[4] = {0, 8, 1, 9};	/* off, low, med, hi intensity color */
int m1, m2, m3;			/* multipliers for masks */ 
 
main()
{
    int zax=0;			/* z-axis value */
    unsigned char c;

    printf("What color do you want on the Z axiz (r,g,b)? ");
    switch  (toupper(getch())) {
    case 'R' :
        m1 = 1; m2 = 2; m3 = 4; break;
    case 'G' :
        m1 = 1; m2 = 4; m3 = 2; break;
    case 'B' :
        m1 = 2; m2 = 4; m3 = 1; break;
    }

 
    printf(CLEARSCREEN);
    putover(0);			/* set overscan color to black */
    putruler();			/* init the screen display */

 
for (;;) {
    setpalette(zax);		/* put values in palette registers */
    if ((c = getch()) == 27)
        break;
 
    if (!c)
        switch (c = getch() ) {
        case 0x48:  /*  Up arrow - increase z-axis value        */
            zax = (zax + 1) % 4;
            break;
        case 0x50:  /*  Down arrow - decrease z-axiz value      */
            zax = (zax + 3) % 4;
            break;
        }
    }

    /* exit--reset palettes to something readable */
    setscreen();
    printf("\n\n");
    exit(0);
}


/* SETPALETTE
	Set up palette registers and draw legends.
*/
setpalette(zax)
int zax;
{
    int i, j, val;

    for (i=0; i<4; ++i)
        for (j=0; j<4; ++j) {
            val = m1*mask[i] + m2*mask[j] + m3*mask[zax];
            putval(i*4+j, val);
            printf(SETCURSOR, i*6+6, j*20+1);
            printf("%2d", val);
        }
}


/* SETSCREEN
    Read the environment and set text & background color
*/
setscreen()
{
    int bc, tc;
    char *getenv();

    tc = atoi(getenv("TEXTCOLOR"));
    bc = atoi(getenv("BACKCOLOR"));
    if (tc == bc) {
        tc = 7;
        bc = 0;
    }

    putval(0, bc);		/* set background color */
    putover(bc);		/* and overscan */

    putval(7, tc);		/* foreground color */
}

 
/* PUTVAL
	Modify the value of a pallette register.
*/
putval(reg, val)
int reg, val;        /*  # of pallette register to modify & new value */
{
    union REGS ireg;
 
    /*  Set pallette register - via EGA BIOS call   */
    ireg.x.ax = 0x1000;                     /*  Function 10h    */
    ireg.h.bl = reg;                        /*  register #      */
    ireg.h.bh = val;                        /*  RGBrgb value      */
    int86(0x10,&ireg,&ireg);
}
 
 
/* PUTRULER
	Write ruler line to screen - do it directly.
*/
putruler()
{
    char far *scrnbuf;
    int i, j;
 
    scrnbuf = (char far *)VIDSEG;
 
    /*  Move pallette ruler to screen   */
    for (j = 0; j < 24; ++j)
        for (i = 0; i < 80; ++i) {
            *scrnbuf++ = 0xdb;		/* block character */
            *scrnbuf++ = 4*(j/6) + (i/20); /* main color sample */
        }
}


/* PUTOVER
	Set the overscan color.
*/
putover(val)
int val;        /*  # of pallette register to modify & new value */
{
    union REGS ireg;

    /*  Set overscan color via EGA BIOS call   */
    ireg.x.ax = 0x1001;                     /*  Function 10h/1    */
    ireg.h.bh = val;			    /*  new irgb value      */
    int86(0x10,&ireg,&ireg);
}