home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: Science
/
Science.zip
/
imdisp79.zip
/
PALUTIL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-03
|
32KB
|
990 lines
/*** IMDISP module PALUTIL.C
Palette manipulation Routines
Contains high level palette routines such as interactive palette
adjustment, palette reading and writing.
Separate module - 1/91 by A. Warnock, ST Systems Corp
***/
#define __MSC
/* * * * INCLUDE files * * * */
#include <conio.h>
#include <dos.h>
#ifdef __TURBOC__
#include <graphics.h>
#else
#include <graph.h>
#endif
#include <io.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "imdef.h"
#include "imdisp.h"
#include "imdutil.h"
#include "dispio.h"
#include "disputil.h"
#include "dispsub.h"
#include "fileio.h"
#include "fileutil.h"
#include "keywutil.h"
#include "imagutil.h"
#include "textutil.h"
#include "ativga.h"
#include "ev629.h"
/* * * * External functions * * * */
extern void pascal far mouses( int *, int *, int *, int * );
/* * * * Function declarations * * * */
int LoadPalette (char *);
int ReadPalette (Color *);
int WritePalette (Color *);
int DiddlePalette (int);
void ShowPalette (int);
void ErasePalette (int);
void GetPalette(void);
int CyclePalette (int);
void VAXFloat2Char(unsigned char *, unsigned char *, int);
/* * * * Global Variables * * * */
int LoadPalette(char * palettefile)
/* LoadPalette reads in the color palette from the given palette filename
(palettefile). This code originally resided in the DoPalette routine,
but was moved into its own routine to accomodate detached palette
processing -- Ron Baalke -- 07/27/90 */
{
int i, n, r, g, b, result;
unsigned char color[768];
char buffer[1024];
char filedata[133];
FILE *unit;
if (Palette != 0L)
{
lseek(FCB[0].handle, Palette, SEEK_SET);
read(FCB[0].handle, color, 768);
for (i=0;i<256;i++)
CT[i].r = color[i];
for (i=0;i<256;i++)
CT[i].g = color[256+i];
for (i=0;i<256;i++)
CT[i].b = color[512+i];
WritePalette (CT);
Palette = 0L; /* reset value to zero */
return(0);
}
if ((unit = fopen (palettefile, "r")) == NULL)
{
StatusLine(0,"Palette file not found.");
return(1);
}
fgets(filedata,132,unit);
/* zero out palette but make highest value white */
memset( &CT[0], 0, 3*255);
if (numDN == 256)
CT[255].r = CT[255].g = CT[255].b = 255;
else
CT[15].r = CT[15].g = CT[15].b = 255;
/* handle palettes with headers */
if (strnicmp(filedata,"CCSD",4) == 0 || strnicmp(filedata,"NJPL",4) == 0)
{
do
{
fgets(filedata,132,unit);
if (strnicmp(filedata,"END",3) == 0 &&
(strlen(filedata) <= 5 || filedata[3] == ' '))
break;
} while (!feof(unit));
fgets (filedata, 132, unit);
i = 0;
do
{
result = sscanf(filedata, "%d %d %d %d", &n,&r,&g,&b);
if (result == 1) /* try comma separated value */
result = sscanf(filedata, "%d,%d,%d,%d", &n,&r,&g,&b);
if (result == 3) /* no index value on line */
{CT[i].r = n; CT[i].g = r; CT[i].b = g;}
else if (result == 4 && (n >= 0 && n <= 256))
{
if (i==n-1) n = i; /* patch to handle old palettes */
/* with values from 1 to 256 */
CT[n].r = r; CT[n].g = g; CT[n].b = b;}
else
{
StatusLine (0,"Invalid Palette file format.");
fclose(unit); return(1);
}
i++;
fgets (filedata, 132, unit);
} while (! feof(unit) && i < 256);
if (numDN == 16 && i > 15)
for (i=0;i<16;i++)
{
CT[i].r = CT[i*16+8].r;
CT[i].g = CT[i*16+8].g;
CT[i].b = CT[i*16+8].b;
}
}
/* Handle VICAR color palettes - Ron Baalke 04/07/91 */
else if (strnicmp(filedata,"LBLS",4) == 0)
{
fclose(unit);
if ((unit = fopen (palettefile, "r+b")) == NULL)
{
StatusLine(0,"Palette file not found.");
return(1);
}
fseek(unit,1024L,SEEK_SET);
fread(buffer,1024,1,unit);
VAXFloat2Char(buffer,color,256);
for (i=0; i<256; i++)
CT[i].r = color[i];
fread(buffer,1024,1,unit);
VAXFloat2Char(buffer,color,256);
for (i=0; i<256; i++)
CT[i].g = color[i];
fread(buffer,1024,1,unit);
VAXFloat2Char(buffer,color,256);
for (i=0; i<256; i++)
CT[i].b = color[i];
if (numDN == 16)
for (i=0;i<16;i++)
{
CT[i].r = CT[i*16+8].r;
CT[i].g = CT[i*16+8].g;
CT[i].b = CT[i*16+8].b;
}
}
else /* handle naked palettes */
{
fgets (filedata, 132, unit);
i = 0;
do
{
result = sscanf(filedata, "%d %d %d %d", &n,&r,&g,&b);
if (result == 1) /* try comma separated value */
result = sscanf(filedata, "%d,%d,%d,%d", &n,&r,&g,&b);
if (result == 3) /* no index value on line */
{CT[i].r = n; CT[i].g = r; CT[i].b = g;}
else if (result == 4 && (n >= 0 && n <= 256))
{
if (i==n-1) n = i; /* patch to handle old palettes */
/* with values from 1 to 256 */
CT[n].r = r; CT[n].g = g; CT[n].b = b;}
else
{
StatusLine (0,"Invalid Palette file format.");
fclose(unit); return(1);
}
i++;
fgets (filedata, 132, unit);
} while (! feof(unit) && i < 256);
if (numDN == 16 && i > 15)
for (i=0;i<16;i++)
{
CT[i].r = CT[i*16+8].r;
CT[i].g = CT[i*16+8].g;
CT[i].b = CT[i*16+8].b;
}
}
WritePalette (CT);
fclose (unit);
}
int ReadPalette (Color * coltab)
/* int ReadPalette (struct Color * coltab) */
/*** ReadPalette returns the current color palette in coltab.
coltab is of type Color.
***/
{
int i;
memmove( &coltab[0], &PaletteTable[0], 3*numDN);
/*
for (i = 0; i < numDN; i++)
{
coltab[i].r = PaletteTable[i].r;
coltab[i].g = PaletteTable[i].g;
coltab[i].b = PaletteTable[i].b;
}
*/
}
int WritePalette (Color * coltab)
/* int WritePalette (struct Color * coltab) */
/***
WritePalette updates the display device palette with the
palette passed in coltab. coltab must be of type Color.
***/
{
int i;
unsigned char cmd[5], red, green, blue;
long pal_color;
union REGS inreg, outreg;
struct SREGS segregs;
Color DP[256];
unsigned int x,y;
unsigned char *colors, palbuf[256][3];
memmove( &PaletteTable[0], &coltab[0], 3*numDN);
switch (DisplayDevice)
{
case EGA350 : /* for ega displays */
case EGA480 : /* for ega displays */
case EVGA800 : /* for Everex EVGA */
for (i = 0; i <= 15; i++)
{
red = (coltab[i].r >> 2) & 0x3f;
green = (coltab[i].g >> 2) & 0x3f;
blue = (coltab[i].b >> 2) & 0x3f;
pal_color = ( ((long)blue) << 16)
| ( ((long)green) << 8)
| ((long)red) ;
#ifdef __TURBOC__
setpalette( i, pal_color);
#else
_remappalette( i, pal_color) ;
#endif
}
return(0);
case VGA480 : /* for vga displays */
for (i = 0; i <= 15; i++)
{
palbuf[i][0] = (coltab[i].r >> 2) & 0xff;
palbuf[i][1] = (coltab[i].g >> 2) & 0xff;
palbuf[i][2] = (coltab[i].b >> 2) & 0xff;
}
colors = &palbuf[0][0];
segregs.es = FP_SEG( colors );
inreg.x.dx = FP_OFF( colors );
inreg.x.ax = 0x1012;
inreg.x.bx = 0x0;
inreg.x.cx = 16;
int86x(0x10, &inreg, &outreg, &segregs);
return(0);
#ifndef __TURBOC__
case BIOS : /* for vga displays */
for (i = 0; i <= 15; i++)
{
red = (coltab[i].r >> 2) & 0x3f;
green = (coltab[i].g >> 2) & 0x3f;
blue = (coltab[i].b >> 2) & 0x3f;
pal_color = ( ((long)blue) << 16)
| ( ((long)green) << 8)
| ((long)red) ;
_remappalette( i, pal_color) ;
}
return(0);
#endif
case VGA200 : /* for vga displays */
case ORCHID480 : /* for Orchid Designer */
case ORCHID600 : /* for Orchid Designer */
case ORCHID768 : /* for Orchid Designer */
case EVGA640 : /* for Everex EVGA */
case EVGA512 : /* for Everex EVGA */
case PARADISE :
case TRIDENT :
case VESA :
case VESA800 :
case VESA640 :
for (i = 0; i <= 255; i++)
{
palbuf[i][0] = (coltab[i].r >> 2) & 0xff;
palbuf[i][1] = (coltab[i].g >> 2) & 0xff;
palbuf[i][2] = (coltab[i].b >> 2) & 0xff;
}
colors = &palbuf[0][0];
segregs.es = FP_SEG( colors );
inreg.x.dx = FP_OFF( colors );
inreg.x.ax = 0x1012;
inreg.x.bx = 0x0;
inreg.x.cx = 256;
int86x(0x10, &inreg, &outreg, &segregs);
return(0);
case PGA : /* for pga display */
for (i = 0; i <= 255; i++)
{
cmd[0] = 0x0EE;
cmd[1] = i;
cmd[2] = coltab[i].r >> 4;
cmd[3] = coltab[i].g >> 4;
cmd[4] = coltab[i].b >> 4;
PGAsend (cmd, 5); /* 'LUT numcol red green blue' */
}
return(0);
case ATI640 : /* for ATI VGA Wonder */
case ATI800 : /* for ATI VGA Wonder */
case ATI1024: /* for ATI VGA Wonder */
for(i=0;i<256;i++)
{
palbuf[i][0] = (coltab[i].r >> 2) & 0xff;
palbuf[i][1] = (coltab[i].g >> 2) & 0xff;
palbuf[i][2] = (coltab[i].b >> 2) & 0xff;
}
ATI_WritePalette(palbuf,0,256);
return(0) ;
case EV629 :
for(i=0;i<256;i++)
{
palbuf[i][0] = (coltab[i].r >> 2) & 0xff;
palbuf[i][1] = (coltab[i].g >> 2) & 0xff;
palbuf[i][2] = (coltab[i].b >> 2) & 0xff;
}
loadmp(palbuf);
return(0);
}
}
void ShowPalette( int numdiddle)
{
int samp, box, line, i;
int numbox, DNperbox, boxns, boxnl;
unsigned char PaletteLine[MAXDISPNS];
/* Set up some constants */
numbox = min (numDN, numdiddle);
DNperbox = numDN / numbox;
boxns = dispns / numbox;
boxnl = dispnl / 10;
samp = 0;
for (box = 0; box < numbox; box++)
for (i = 0; i < boxns; i++)
PaletteLine[samp++] = box*DNperbox;
for (line = dispnl-boxnl; line <= dispnl; line++)
DisplayLine (PaletteLine, line, 1, numbox*boxns);
}
void ErasePalette( int numdiddle)
{
int samp, box, line, i;
int numbox, DNperbox, boxns, boxnl;
unsigned char PaletteLine[MAXDISPNS];
/* Set up some constants */
numbox = min (numDN, numdiddle);
DNperbox = numDN / numbox;
boxns = dispns / numbox;
boxnl = dispnl / 10;
samp = 0;
for (box = 0; box < numbox; box++)
for (i = 0; i < boxns; i++)
PaletteLine[samp++] = 0;
for (line = dispnl-boxnl; line <= dispnl; line++)
DisplayLine (PaletteLine, line, 1, numbox*boxns);
}
int DiddlePalette( int numdiddle)
/*** DiddlePalette performs interactive adjustment of the color
palette. A wedge of numdiddle DN values, from 0 to the maximum,
is displayed at the bottom of the screen, and the palette is
changed to have only numdiddle distinct shades. Then a loop
for user input is entered. The active color is the one in the
wedge with the small black box inside it.
The following is a list of commands:
Character Action
7 (HOME) move to first color in wedge
4 (6) move to next lower (higher) color in wedge
^4 (^6) move 8 steps lower (higher) in wedge
r (R) decrease (increase) amount of red one notch
g (G) decrease (increase) amount of green one notch
b (B) decrease (increase) amount of blue one notch
S scroll palette right
s scroll palette left
2 (8) decrease (increase) amount of all colors one notch
1 (END) move to last color in wedge
x (X) invert color wedge
. exit from palette diddle mode
The wedge is erased after the user exits.
Parameter Type Description
numdiddle int number of colors in the wedge and resulting palette
***/
{
int line, samp, i, box, DN, numbox, DNperbox, shade, numcol;
int boxnl, boxns, linepos, samppos, h_marksize, v_marksize, len;
int colornum, m1, m2, m3, m4;
unsigned char ch; /* mdm 10/6/87 */
unsigned char PaletteLine[MAXDISPNS];
unsigned char hold;
Color coltab[256], hold_Color;
char dispstr[60];
/* Set up some constants */
numbox = min (numDN, numdiddle);
DNperbox = numDN / numbox;
boxns = dispns / numbox;
boxnl = dispnl / 10;
v_marksize = 8;
h_marksize = min(boxns, v_marksize);
linepos = dispnl - (boxnl / 2) - (h_marksize / 2);
/* Draw the palette on the bottom of the screen */
ShowPalette( numdiddle );
/* Reduce the number of colors in the palette to numbox */
ReadPalette (coltab);
for (box = 0; box < numbox; box++)
{
DN = box*DNperbox;
for (i = DN; i < DN+DNperbox; i++)
{ coltab[i].r = coltab[DN].r;
coltab[i].g = coltab[DN].g;
coltab[i].b = coltab[DN].b;
}
}
WritePalette (coltab);
if ( use_mouse )
{ /* Mouse? */
m1 = 11; /* Motion function */
mouses( &m1, &m2, &m3, &m4 ); /* Clear */
m1 = 5; /* Button function */
m2 = 0;
mouses( &m1, &m2, &m3, &m4 ); /* Clear left */
m1 = 5;
m2 = 1;
mouses( &m1, &m2, &m3, &m4 ); /* Clear right */
}
/* Draw the marker box on top of the palette */
box = numbox / 2;
samppos = box*boxns - (boxns / 2) - (h_marksize / 2);
DrawBox (linepos, samppos, v_marksize, h_marksize, 0);
shade = 256 / numshades ;
/* Interactively adjust the palette */
do
{
/* Save EGA settings in colornun: (red) (grn) (blue) */
if (DisplayDevice == EGA350 || DisplayDevice == EGA480
|| DisplayDevice == VGA480)
{
colornum = (int)(coltab[DN].r/64);
colornum = (colornum << 2) | (0x03 & (int)(coltab[DN].g/64));
colornum = (colornum << 2) | (0x03 & (int)(coltab[DN].b/64));
}
if ( use_mouse )
{ /* Mouse? */
ch = 0x00; /* Clear char */
do
{ /* Loop */
m1 = 11; /* Motion function */
mouses( &m1, &m2, &m3, &m4 ); /* Read motion */
if ( m3 != 0 )
{ /* Motion? */
DN = (box-1)*DNperbox; /* Yes clear box */
DrawBox (linepos, samppos, v_marksize, h_marksize, DN);
if ( m3 > 0 ) /* Right? */
box = min( box+m3, numbox ); /* Yes */
else /* Left? */
box = max( box+m3, 1 ); /* Yes */
goto Skip;
}
m1 = 3; /* Button function */
mouses( &m1, &m2, &m3, &m4 ); /* Check button */
if ( m2 == 3 ) /* Both? */
ch = '.'; /* Yes - set end char */
else if ( m2 == 1 ) /* Left? */
ch = '2'; /* Yes - set down char */
else if ( m2 == 2 ) /* Right? */
ch = '8'; /* Yes - set up char */
} while ( ( ch == 0x00) && ( !kbhit() ) ); /* Until key or function */
}
if ( ( !use_mouse ) || ( kbhit() ) )
{
if ((ch = getch()) == 0) /* mdm 10/9/87 */
ch = 0x80 | getch();
}
DN = (box-1)*DNperbox;
DrawBox (linepos, samppos, v_marksize, h_marksize, DN);
switch (ch)
{
case 'r' :
coltab[DN].r = coltab[DN].r - shade;
if (coltab[DN].r < 0) coltab[DN].r = 255;
break;
case 'R' :
coltab[DN].r = (coltab[DN].r + shade)%256;
break;
case 'g' :
coltab[DN].g = coltab[DN].g - shade;
if (coltab[DN].g < 0) coltab[DN].g = 255;
break;
case 'G' :
coltab[DN].g = (coltab[DN].g + shade)%256;
break;
case 'b' :
coltab[DN].b = max (coltab[DN].b - shade,0);
if (coltab[DN].b < 0) coltab[DN].b = 255;
break;
case 'B' :
coltab[DN].b = (coltab[DN].b + shade)%256;
break;
case 'X' : /* xchange color table values */
case 'x' :
for (i = 1; i <= numbox/2; i++)
{ hold = coltab[numbox-i].r;
coltab[numbox-i].r = coltab[i-1].r;
coltab[i-1].r = hold;
hold = coltab[numbox-i].g;
coltab[numbox-i].g = coltab[i-1].g;
coltab[i-1].g = hold;
hold = coltab[numbox-i].b;
coltab[numbox-i].b = coltab[i-1].b;
coltab[i-1].b = hold;
}
break;
case 'S' : /* shift color table one right */
memcpy ( &hold_Color, &coltab[numbox-1], sizeof(hold_Color) );
memmove( &coltab[1], &coltab[0], sizeof(hold_Color)*(numbox-1) );
memcpy ( &coltab[0], &hold_Color, sizeof(hold_Color) );
break;
case 's' : /* shift color table one left */
memcpy ( &hold_Color, &coltab[0], sizeof(hold_Color) );
memmove( &coltab[0], &coltab[1], sizeof(hold_Color)*(numbox-1) );
memcpy ( &coltab[numbox-1], &hold_Color, sizeof(hold_Color) );
break;
case DOWN_ARROW:
case '2' :
if ( (DisplayDevice == EGA350 || DisplayDevice == EGA480)
&& numshades == 4)
{
--colornum;
coltab[DN].b = 64 * (colornum & 0x03);
coltab[DN].g = 64 * ((colornum >> 2) & 0x03);
coltab[DN].r = 64 * ((colornum >> 4) & 0x03);
}
else
{
coltab[DN].r = coltab[DN].r - shade;
coltab[DN].g = coltab[DN].g - shade;
coltab[DN].b = coltab[DN].b - shade;
}
break;
case UP_ARROW:
case '8' :
if ( (DisplayDevice == EGA350 || DisplayDevice == EGA480)
&& numshades == 4)
{
++colornum;
coltab[DN].b = 64 * (colornum & 0x03);
coltab[DN].g = 64 * ((colornum >> 2) & 0x03);
coltab[DN].r = 64 * ((colornum >> 4) & 0x03);
} else {
coltab[DN].r = (coltab[DN].r + shade) % 256;
coltab[DN].g = (coltab[DN].g + shade) % 256;
coltab[DN].b = (coltab[DN].b + shade) % 256;
}
break;
case RIGHT_ARROW:
case '6' :
box = min (box+1, numbox);
/* goto Skip; */
break;
case LEFT_ARROW:
case '4' :
box = max (box-1, 1);
/* goto Skip; */
break;
case CONTROL_RIGHT_ARROW:
box = min (box+(numDN>>3), numbox);
/* goto Skip; */
break;
case CONTROL_LEFT_ARROW:
box = max (box-(numDN>>3), 1);
/* goto Skip; */
break;
case HOME:
case '7' :
box = 1;
/* goto Skip; */
break;
case END:
case '1' :
box = numbox;
/* goto Skip; */
break;
}
for (i = DN; i < DN+DNperbox; i++)
{
coltab[i].r = coltab[DN].r;
coltab[i].g = coltab[DN].g;
coltab[i].b = coltab[DN].b;
}
WritePalette (coltab);
Skip:
samppos = box*boxns - (boxns / 2) - (h_marksize / 2);
DrawBox (linepos, samppos, v_marksize, h_marksize, 0);
DN = (box-1)*DNperbox;
sprintf( dispstr, "color = %2d red = %3d green = %3d blue = %3d",
DN, coltab[DN].r, coltab[DN].g, coltab[DN].b);
LengthText( dispstr, TextHeight, &len);
EraseText( TextLine, 1, TextHeight, len, 0);
DrawText( dispstr, TextLine, 1, TextHeight, 0, numDN-1);
if (ch == RETURN || ch == ESCAPE) ch = '.';
}
while (ch != '.');
/* Erase the palette on the screen */
ErasePalette( numdiddle );
}
void GetPalette(void)
/* GetPalette will put up a directory selection menu, exactly the same one
as with the FIL command, but will select a palette instead.
Written by Ron Baalke, 02/03/91
*/
{
char filename[128];
filename[0] = '\0';
ChangeDir(PalettePath); /* Move to default palette directory */
FileSel(filename,2); /* Get the palette file */
if (filename[0] != '\0') /* If a palette is selected, load it in */
{
strcpy(CommandString,"PAL LOAD ");
strcat(CommandString,filename);
DoPalette();
}
DoRefresh(); /* Refresh the image */
}
int CyclePalette(int cycle)
/* Cycle Palette will through the color palette a number of interesting
ways. Any key will abort the cycling, a 'S' or 's' key will save the
palette in its current setting, any other key will restore the
palette.
Written by Ron Baalke, 02/04/91
Added FAST and TIME options - Ron Baalke, 07/91
*/
{
Color coltab[256], hold_Color;
unsigned char hold;
int i;
int j=0;
int k=0;
int temp;
int fast_flag, time_flag;
int seconds;
double total_seconds=0;
char dummy[40];
GetKeywordInteger (CommandString, "TIM", 20, &seconds, &time_flag);
GetKeywordString (CommandString, "FAS", "",dummy, &fast_flag);
if (fast_flag != -1)
fast_flag = TRUE;
else
fast_flag = FALSE;
ReadPalette (coltab);
srand( (unsigned)time( NULL ) ); /* Seed random number generator */
while (!kbhit())
{
switch (cycle)
{
case 0: /* "Blink" the palette */
DoNegative();
if (fast_flag)
Sleep(0.1);
else
Sleep(0.3);
break;
case 1 : /* Blink 4 times */
for (i=0; i<numDN/4; i++)
{
hold = coltab[i].r;
coltab[i].r = coltab[i+numDN/4].r;
coltab[i+numDN/4].r = coltab[i+numDN/2].r;
coltab[i+numDN/2].r = coltab[i+(numDN*3)/4].r;
coltab[i+(numDN*3)/4].r = hold;
hold = coltab[i].g;
coltab[i].g = coltab[i+numDN/4].g;
coltab[i+numDN/4].g = coltab[i+numDN/2].g;
coltab[i+numDN/2].g = coltab[i+(numDN*3)/4].g;
coltab[i+(numDN*3)/4].g = hold;
hold = coltab[i].b;
coltab[i].b = coltab[i+numDN/4].b;
coltab[i+numDN/4].b = coltab[i+numDN/2].b;
coltab[i+numDN/2].b = coltab[i+(numDN*3)/4].b;
coltab[i+(numDN*3)/4].b = hold;
}
WritePalette(coltab);
if (fast_flag)
Sleep(0.1);
else
Sleep(0.3);
break;
case 2: /* Rotate Palette left - AW */
memcpy ( &hold_Color, &coltab[0], 3 );
memmove( &coltab[0], &coltab[1], (numDN-1)*3 );
memcpy ( &coltab[numDN-1], &hold_Color, 3 );
WritePalette( coltab );
if (fast_flag)
Delay(50);
else
Delay(300);
break;
case 3: /* Rotate Palette right - AW */
memcpy ( &hold_Color, &coltab[numDN-1], 3 );
memmove( &coltab[1], &coltab[0], (numDN-1)*3 );
memcpy ( &coltab[0], &hold_Color, 3 );
WritePalette(coltab);
if (fast_flag)
Delay(50);
else
Delay(300);
break;
case 4: /* Rotate pallete & feed in a random color */
hold = coltab[0].r;
for (i=0; i<numDN-1; i++)
coltab[i].r = coltab[i+1].r;
coltab[numDN-1].r = hold;
hold = coltab[0].g;
for (i=0; i<numDN-1; i++)
coltab[i].g = coltab[i+1].g;
coltab[numDN-1].g = hold;
hold = coltab[0].b;
for (i=0; i<numDN-1; i++)
coltab[i].b = coltab[i+1].b;
coltab[numDN-1].b = hold;
if (j == 2 * numDN)
{
WritePalette(CT);
ReadPalette(coltab);
j = 0;
}
else
{
coltab[numDN-1].r = (rand() % numDN);
coltab[numDN-1].g = (rand() % numDN);
coltab[numDN-1].b = (rand() % numDN);
WritePalette(coltab);
j++;
}
if (fast_flag)
Sleep(0.1);
else
Sleep(0.3);
break;
case 5: /* Randomize the palette */
for (i=0; i<numDN; i++)
{
temp = (rand() % numDN);
coltab[i].r = (coltab[i].r + temp)/2;
temp = (rand() % numDN);
coltab[i].b = (coltab[i].b + temp)/2;
temp = (rand() % numDN);
coltab[i].g = (coltab[i].g + temp)/2;
}
WritePalette(coltab);
if (fast_flag)
Sleep(0.1);
else
Sleep(0.3);
break;
case 6: /* Double rotate the palette */
hold = coltab[numDN/2].r;
for (i=numDN/2; i<numDN-1; i++)
coltab[i].r = coltab[i+1].r;
coltab[numDN-1].r = hold;
hold = coltab[numDN/2].b;
for (i=numDN/2; i<numDN-1; i++)
coltab[i].b = coltab[i+1].b;
coltab[numDN-1].b = hold;
hold = coltab[numDN/2].g;
for (i=numDN/2; i<numDN-1; i++)
coltab[i].g = coltab[i+1].g;
coltab[numDN-1].g = hold;
hold = coltab[numDN/2-1].r;
for (i=numDN/2-1; i > 0; i--)
coltab[i].r = coltab[i-1].r;
coltab[0].r = hold;
hold = coltab[numDN/2-1].g;
for (i=numDN/2-1; i > 0; i--)
coltab[i].g = coltab[i-1].g;
coltab[0].g = hold;
hold = coltab[numDN/2-1].b;
for (i=numDN/2-1; i > 0; i--)
coltab[i].b = coltab[i-1].b;
coltab[0].b = hold;
WritePalette(coltab);
if (fast_flag)
Sleep(0.1);
else
Sleep(0.3);
break;
case 7: /* Random swaps of the palette */
i = (rand() % numDN);
j = (rand() % numDN);
hold = coltab[i].r;
coltab[i].r = coltab[j].r;
coltab[j].r = hold;
hold = coltab[i].b;
coltab[i].b = coltab[j].b;
coltab[j].b = hold;
hold = coltab[i].g;
coltab[i].g = coltab[j].g;
coltab[j].g = hold;
WritePalette(coltab);
if (fast_flag)
Sleep(0.1);
else
Sleep(0.3);
break;
default:
return(TRUE);
break;
} /* end switch */
if (time_flag != -1)
{
if (fast_flag)
total_seconds += 0.06;
else
total_seconds += 0.3;
if ((int)total_seconds >= seconds) return(FALSE);
}
} /* end while */
i = getch();
if ((i == 83) || (i == 115)) /* If 'S' or 's' */
return(TRUE);
else
return(FALSE);
}
/**************************************************************/
/* VAXFloat2Char */
/* */
/* Converts VAX floating point number to char */
/* */
/* Ron Baalke 04/07/91 */
/**************************************************************/
void VAXFloat2Char(unsigned char *vFloatBuf, unsigned char *charBuf,
int length)
/*
unsigned char vFloatBuf[]; in: buffer holding 32 bit VAX F_floating
unsigned char charBuf[]; out: converted buffer
int length; in: number of numbers to convert
*/
{
int i, j;
unsigned char exp; /* binary exponent */
short fraction;
for (i = 0, j = 0; i < length; i++, j += 4)
{
fraction = 0x0080 | vFloatBuf[j]; /* lst sig byte of frac */
exp = (vFloatBuf[j + 1] << 1) | (vFloatBuf[j] >> 7);
exp = 8 - (exp & 0x7F); /* convert from left shift to right shift */
charBuf[i] = fraction >> exp;
}
return;
}