Remap palette colors.
#include <graph.h>
short __far _remapallpalette( long __far *colors );
long __far _remappalette( short index, long color );
colors | Color value array | |
index | Color index to reassign | |
color | Color value to assign color index to |
The _remapallpalette function remaps the entire color palette simultaneously to the colors given in the colors array. The colors array is an array of long integers where the size of the array varies from 16 to 64 to 256, depending on the video mode. The number of colors mapped depends on the number of colors supported by the current video mode. The _remapallpalette function works in all video modes (except _ORESCOLOR mode), but only with EGA, MCGA, VGA, or SVGA hardware.
The default color values for color text or a 16-color graphics mode are shown below:
Number | Color | Number | Color |
0 | Black | 8 | Dark gray |
1 | Blue | 9 | Light blue |
2 | Green | 10 | Light green |
3 | Cyan | 11 | Light cyan |
4 | Red | 12 | Light red |
5 | Magenta | 13 | Light magenta |
6 | Brown | 14 | Yellow |
7 | White | 15 | Bright white |
The first array element specifies the new color value to be associated with
color index 0 (the background color in graphics modes). After the call to
_remapallpalette, calls to _setcolor will index into the new array of colors.
The mapping done by _remapallpalette affects the current display immediately.
The colors array can be larger than the number of colors supported by the current video mode, but only the first n elements are used, where n is the number of colors supported by the current video mode, as indicated by the numcolors element of the _videoconfig structure.
The long color value is defined by specifying three bytes of data representing the three component colors: red, green, and blue.
Each of the three bytes represents the intensity of one of the red, green, or blue component colors, and must be in the range 0–31. In other words, the low-order six bits of each byte specify the component's intensity and the high-order two bits should be zero. The fourth (high-order) byte in the long is unused and should be set to zero. The diagram below shows the ordering of bytes within the long value.
For example, to create a lighter shade of blue, start with lots of blue, add some green, and maybe a little bit of red. The three-byte color value would be:
blue byte green byte red byte
00011111 00101111 00011111
high ————————————————> low order
Manifest constants are defined in GRAPH.H for the default color values corresponding to color indices 0–15 in color text modes and 16-color graphics modes, as shown below:
Index | Constant | Index | Constant |
0 | _BLACK | 8 | _GRAY |
1 | _BLUE | 9 | _LIGHTBLUE |
2 | _GREEN | 10 | _LIGHTGREEN |
3 | _CYAN | 11 | _LIGHTCYAN |
4 | _RED | 12 | _LIGHTRED |
5 | _MAGENTA | 13 | _LIGHTMAGENTA |
6 | _BROWN | 14 | _YELLOW |
7 | _WHITE | 15 | _BRIGHTWHITE |
The VGA supports a palette of 262,144 (256K) colors in color modes, and the EGA supports a palette of only 64 different colors. Color values for EGA are specified in exactly the same way as with the VGA; however, the low-order four bits of each byte are simply ignored.
The _remappalette function assigns a new color value color to the color index given by index. This remapping affects the current display immediately.
The _remappalette function works in all graphics modes, but only with EGA, MCGA, VGA, or SVGA hardware. An error results if the function is called while using any other configuration.
The color value used in _remappalette is defined and used exactly as noted above for _remapallpalette. The range of color indices used with _remappalette depends on the number of colors supported by the video mode.
The _remapallpalette and _remappalette functions do not affect the presentation-graphics “palettes,” which are manipulated with the _pg_getpalette, _pg_setpalette, and _pg_resetpalette functions.
If a VGA or MCGA adapter is connected to an analog monochrome monitor, the color value is transformed into its gray-scale equivalent, based on the weighted sum of its red, green, and blue components (30% red + 50% green + 11% blue).
If successful, _remapallpalette returns nonzero value (short). In case of an error, _remapallpalette returns 0 (short).
If successful, _remappalette returns the color value previously assigned to index, or –1 if the function is inoperative (not EGA, VGA, SVGA, or MCGA), or if the color index is out of range. Note that _remapallpalette returns a short value and _remappalette returns a long value.
Standards:None
16-Bit:DOS
32-Bit:None
_getvideoconfig, _selectpalette, _setbkcolor, _setvideomode
/* RMPALPAL.C: This example illustrates functions for assigning
* color values to color indices. Functions illustrated include:
* _remappalette _remapallpalette
*/
#include <graph.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
/* Macro for mixing Red, Green, and Blue elements of color */
#define RGB(r,g,b) (((long) ((b) << 8 | (g)) << 8) | (r))
long tmp, pal[256];
void main( void )
{
short red, blue, green;
short inc, i, mode, cells, x, y, xinc, yinc;
char buf[40];
struct _videoconfig vc;
/* Make sure all palette numbers are valid. */
for( i = 0; i < 256; i++ )
pal[i] = _BLACK;
/* Loop through each graphics mode that supports palettes. */
for( mode = _MRES4COLOR; mode <= _MRES256COLOR; mode++ )
{
if( mode == _ERESNOCOLOR )
mode++;
if( !_setvideomode( mode ) )
continue;
/* Set variables for each mode. */
_getvideoconfig( &vc );
switch( vc.numcolors )
{
case 256: /* Active bits in this order: */
cells = 13;
inc = 12; /* ???????? ??bbbbbb ??gggggg ??rrrrrr */
break;
case 16:
cells = 4;
if( (vc.mode == _ERESCOLOR) || (vc.mode == _VRES16COLOR) )
inc = 16; /* ???????? ??bb???? ??gg???? ??rr???? */
else
inc = 32; /* ???????? ??Bb???? ??Gg???? ??Rr???? */
break;
case 4:
cells = 2;
inc = 32; /* ???????? ??Bb???? ??Gg???? ??Rr???? */
break;
default:
continue;
}
xinc = vc.numxpixels / cells;
yinc = vc.numypixels / cells;
/* Fill palette arrays in BGR order. */
for( i = 0, blue = 0; blue < 64; blue += inc )
for( green = 0; green < 64; green += inc )
for( red = 0; red < 64; red += inc )
{
pal[i] = RGB( red, green, blue );
/* Special case of using 6 bits to represent 16 colors.
* If both bits are on for any color, intensity is set.
* If one bit is set for a color, the color is on.
*/
if( inc == 32 )
pal[i + 8] = pal[i] | (pal[i] >> 1);
i++;
}
/* If palettes available, remap all palettes at once. */
if( !_remapallpalette( pal ) )
{
_setvideomode( _DEFAULTMODE );
_outtext( “Palettes not available with this adapter” );
exit( 1 );
}
/* Draw colored squares. */
for( i = 0, x = 0; x < ( xinc * cells ); x += xinc )
for( y = 0; y < ( yinc * cells); y += yinc )
{
_setcolor( i++ );
_rectangle( _GFILLINTERIOR, x, y, x + xinc, y + yinc );
}
/* Note that for 256-color mode, not all colors are shown. The number
* of colors from mixing three base colors can never be the same as
* the number that can be shown on a two-dimensional grid.
*/
sprintf( buf, “Mode %d has %d colors”, vc.mode, vc.numcolors );
_setcolor( vc.numcolors / 2 );
_outtext( buf );
_getch();
/* Change each palette entry separately in GRB order. */
for( i = 0, green = 0; green < 64; green += inc )
for( red = 0; red < 64; red += inc )
for(blue = 0; blue < 64; blue += inc )
{
tmp = RGB( red, green, blue );
_remappalette( i, tmp );
if( inc == 32 )
_remappalette( i + 8, tmp | (tmp >> 1) );
i++;
}
_getch();
}
_setvideomode( _DEFAULTMODE );
exit( 0 );
}