home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
graphics
/
applications
/
dkbtrace
/
src
/
ibm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-26
|
11KB
|
361 lines
/*****************************************************************************
*
* ibm.c
*
* from DKBTrace (c) 1990 David Buck
*
* This module implements the IBM-specific routines for DKBTrace.
*
* This software is freely distributable. The source and/or object code may be
* copied or uploaded to communications services so long as this notice remains
* at the top of each file. If any changes are made to the program, you must
* clearly indicate in the documentation and in the programs startup message
* who it was who made the changes. The documentation should also describe what
* those changes were. This software may not be included in whole or in
* part into any commercial package without the express written consent of the
* author. It may, however, be included in other public domain or freely
* distributed software so long as the proper credit for the software is given.
*
* This software is provided as is without any guarantees or warranty. Although
* the author has attempted to find and correct any bugs in the software, he
* is not responsible for any damage caused by the use of the software. The
* author is under no obligation to provide service, corrections, or upgrades
* to this package.
*
* Despite all the legal stuff above, if you do find bugs, I would like to hear
* about them. Also, if you have any comments or questions, you may contact me
* at the following address:
*
* David Buck
* 22C Sonnet Cres.
* Nepean Ontario
* Canada, K2H 8W7
*
* I can also be reached on the following bulleton boards:
*
* ATX (613) 526-4141
* OMX (613) 731-3419
* Mystic (613) 731-0088 or (613) 731-6698
*
* Fidonet: 1:163/109.9
* Internet: David_Buck@Carleton.CA
*
* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
*
* Lattice BBS (708) 916-1200
* The Information Exchange BBS (708) 945-5575
* Stillwaters BBS (708) 403-2826
*
*****************************************************************************/
#include "frame.h"
#include "dkbproto.h"
/* IBM VGA "colour" output routines for MS/DOS by Aaron A. Collins. This
will deliver approximate colorings using HSV values for the approximation.
The pallette map is divided into 4 parts - upper and lower half generated
with full and half "value" (intensity), respectively. These halves are
further halved by full and half saturation values of each range (pastels).
There are three constant colors, black, white, and grey. They are used
when the saturation is low enough that the hue becomes undefined, and which
one is selected is based on a simple range map of "value". Usage of the
pallette is accomplished by converting the requested color RGB into an HSV
value. If the saturation is too low (< .25) then black, white or grey is
selected. If there is enough saturation to consider looking at the hue,
then the hue range of 1-63 is scaled into one of the 4 pallette quadrants
based on its "value" and "saturation" characteristics.
*/
#include <dos.h> /* MS-DOS specific - for int86() REGS struct, etc. */
void set_pallette_register(unsigned, unsigned, unsigned, unsigned);
void hsv_to_rgb(DBL, DBL, DBL, unsigned *, unsigned *, unsigned *);
void rgb_to_hsv(unsigned, unsigned, unsigned, DBL *, DBL *, DBL *);
extern unsigned _stklen = 32768U; /* HUGE stack for HEAVY recursion */
extern int Options;
void display_init()
{
union REGS inr, outr;
register unsigned m;
unsigned r, g, b;
register DBL hue, sat, val;
inr.x.ax = 0x0013; /* setup to VGA 320x200x256 (mode 13H) */
int86(0x10, &inr, &outr);
inr.x.ax = 0x1010; /* make pallette register 0 black */
inr.x.bx = 0;
inr.h.ch = inr.h.cl = inr.h.dh = 0; /* full off */
int86(0x10, &inr, &outr);
inr.x.ax = 0x1010; /* make pallette register 64 white */
inr.x.bx = 64;
inr.h.ch = inr.h.cl = inr.h.dh = 63; /* full on */
int86(0x10, &inr, &outr);
inr.x.ax = 0x1010; /* make pallette register 128 dark grey */
inr.x.bx = 128;
inr.h.ch = inr.h.cl = inr.h.dh = 31; /* half on (dark grey) */
int86(0x10, &inr, &outr);
inr.x.ax = 0x1010; /* make pallette register 192 lite grey */
inr.x.bx = 192;
inr.h.ch = inr.h.cl = inr.h.dh = 48; /* 3/4 on (lite grey) */
int86(0x10, &inr, &outr);
for (m = 1; m < 64; m++) /* for the 1st 64 colors... */
{
sat = 0.5; /* start with the saturation and intensity low */
val = 0.5;
hue = 360.0 * ((DBL)(m)) / 64.0; /* normalize to 360 */
hsv_to_rgb (hue, sat, val, &r, &g, &b);
set_pallette_register (m, r, g, b); /* set m to rgb value */
sat = 1.0; /* high saturation and half intensity (shades) */
val = 0.50;
hue = 360.0 * ((DBL)(m)) / 64.0; /* normalize to 360 */
hsv_to_rgb (hue, sat, val, &r, &g, &b);
set_pallette_register (m + 64, r, g, b); /* set m + 64 */
sat = 0.5; /* half saturation and high intensity (pastels) */
val = 1.0;
hue = 360.0 * ((DBL)(m)) / 64.0; /* normalize to 360 */
hsv_to_rgb (hue, sat, val, &r, &g, &b);
set_pallette_register (m + 128, r, g, b); /* set m + 128 */
sat = 1.0; /* normal full HSV set at full intensity */
val = 1.0;
hue = 360.0 * ((DBL)(m)) / 64.0; /* normalize to 360 */
hsv_to_rgb (hue, sat, val, &r, &g, &b);
set_pallette_register (m + 192, r, g, b); /* set m + 192 */
}
return;
}
void display_finished ()
{
if (Options & PROMPTEXIT)
{
printf ("\007\007"); /* long beep */
getch();
}
}
void display_close() /* setup to Text 80x25 (mode 3) */
{
union REGS inr, outr;
inr.x.ax = 0x0003;
int86(0x10, &inr, &outr);
return;
}
void display_plot (x, y, Red, Green, Blue) /* plot a single RGB pixel */
int x, y;
char Red, Green, Blue;
{
register unsigned char color;
unsigned char far *fp;
DBL h, s, v;
/* Translate RGB value to best of 256 pallete Colors (by HSV?) */
rgb_to_hsv((unsigned)Red,(unsigned)Green,(unsigned)Blue, &h, &s, &v);
if (s < 0.25) /* black or white if no saturation of color... */
{
if (v < 0.25)
color = 0; /* black */
else if (v > 0.75)
color = 64; /* white */
else if (v > 0.5)
color = 192; /* lite grey */
else
color = 128; /* dark grey */
}
else
{
color = (unsigned char) (64.0 * ((DBL)(h)) / 360.0);
if (!color)
color = 1; /* avoid black, white or grey */
if (color > 63)
color = 63; /* avoid same */
if (v > 0.50)
color |= 0x80; /* colors 128-255 for high inten. */
if (s > 0.50) /* more than half saturated? */
color |= 0x40; /* color range 64-128 or 192-255 */
}
fp = MK_FP(0xa000, 320 * y + x);
*fp = color; /* normalize color to 256 */
return;
}
void set_pallette_register (Val, Red, Green, Blue)
unsigned Val;
unsigned Red, Green, Blue;
{
union REGS Regs;
Regs.x.ax = 0x1010; /* Set one pallette register function */
Regs.x.bx = Val; /* the pallette register to set (color #) */
Regs.h.dh = (char) Red & 0xff; /* set the gun values (6 bits ea.) */
Regs.h.ch = (char) Green & 0xff;
Regs.h.cl = (char) Blue & 0xff;
int86(0x10, &Regs, &Regs); /* Do the video interrupt */
}
/* Conversion from Hue, Saturation, Value to Red, Green, and Blue and back */
/* From "Computer Graphics", Donald Hearn & M. Pauline Baker, p. 304 */
void hsv_to_rgb(hue, s, v, r, g, b)
DBL hue, s, v; /* hue (0.0 to 360.0) s and v are from 0.0 - 1.0) */
unsigned *r, *g, *b; /* values from 0 to 63 */
{
register DBL i, f, p1, p2, p3;
register DBL xh;
register DBL nr, ng, nb; /* rgb values of 0.0 - 1.0 */
if (hue == 360.0)
hue = 0.0; /* (THIS LOOKS BACKWARDS BUT OK) */
xh = hue / 60.0; /* convert hue to be in 0,6 */
i = floor(xh); /* i = greatest integer <= h */
f = xh - i; /* f = fractional part of h */
p1 = v * (1 - s);
p2 = v * (1 - (s * f));
p3 = v * (1 - (s * (1 - f)));
switch ((int) i)
{
case 0:
nr = v;
ng = p3;
nb = p1;
break;
case 1:
nr = p2;
ng = v;
nb = p1;
break;
case 2:
nr = p1;
ng = v;
nb = p3;
break;
case 3:
nr = p1;
ng = p2;
nb = v;
break;
case 4:
nr = p3;
ng = p1;
nb = v;
break;
case 5:
nr = v;
ng = p1;
nb = p2;
break;
}
*r = (unsigned)(nr * 63.0); /* Normalize the values to 63 */
*g = (unsigned)(ng * 63.0);
*b = (unsigned)(nb * 63.0);
return;
}
void rgb_to_hsv(r, g, b, h, s, v)
unsigned r, g, b;
DBL *h, *s, *v;
{
register DBL m, r1, g1, b1;
register DBL nr, ng, nb; /* rgb values of 0.0 - 1.0 */
register DBL nh, ns, nv; /* hsv local values */
nr = (DBL) r / 255.0;
ng = (DBL) g / 255.0;
nb = (DBL) b / 255.0;
nv = max (nr, max (ng, nb));
m = min (nr, min (ng, nb));
if (nv != 0.0) /* if no value, it's black! */
ns = (nv - m) / nv;
else
ns = 0.0; /* black = no colour saturation */
if (ns == 0.0) /* hue undefined if no saturation */
{
*h = 0.0; /* return black level (?) */
*s = 0.0;
*v = nv;
return;
}
r1 = (nv - nr) / (nv - m); /* distance of color from red */
g1 = (nv - ng) / (nv - m); /* distance of color from green */
b1 = (nv - nb) / (nv - m); /* distance of color from blue */
if (nv == nr)
{
if (m == ng)
nh = 5. + b1;
else
nh = 1. - g1;
}
if (nv == ng)
{
if (m == nb)
nh = 1. + r1;
else
nh = 3. - b1;
}
if (nv == nb)
{
if (m == nr)
nh = 3. + g1;
else
nh = 5. - r1;
}
*h = nh * 60.0; /* return h converted to degrees */
*s = ns;
*v = nv;
return;
}
#if !__STDC__
/* ANSI Standard random number generator */
static unsigned long int next = 1;
int rand()
{
next = next * 1103515245L + 12345L;
return ((int) (next / 0x10000L) & 0x7FFF);
}
void srand(seed)
unsigned int seed;
{
next = seed;
}
#endif