delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1993/08/04/22:59:31

Date: Wed, 4 Aug 1993 22:05:07 -0400
From: garym AT argos DOT rose DOT utoronto DOT ca (Gary Lawrence Murphy)
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Subject: DKBTrace djgpp.c module

Here 'tis; no guarantees and no restrictions other than, should you improve
it, please offer me a copy :-)

I'm including a non-functional Makefile to show (1) how Makefiles _should_
be structured ;-) and (2) the libraries &c I had used.

(------------------------------------------ Makefile.gcc)

# Makefile for DKB Ray Tracing Program by David Buck and Aaron Collins
# This file is released to the public domain.
#
#
# MAKE Macros and Such...
#

#***************************************************************
#*
#*    GNU/DJP NDMakefile by Gary Lawrence Murphy
#*         garym AT virtual DOT rose DOT utoronto DOT ca
#*
#*	Doesn't work as it was, so commented out the 'include'
#*	(how do you do this in NDMAKE?)
#*
#***************************************************************

# The exact options may depend on your compiler.  Feel free to modify
# these as required.
CC=gcc

OBJ	= o
MACHINE	= djgpp.c

CFLAGS=		-c -O -DMATH_CO
LFLAGS =	-o dkbtrace -O -lm -lgrx -lpc -lg

# Make's implicit rules for making a .o file from a .c file...
#
.SUFFIXES: .o .p .c

DKBSRC = trace.c render.c tokenize.c parse.c \
	  objects.c spheres.c quadrics.c lighting.c \
	  prioq.c texture.c matrices.c csg.c dump.c \
	  colour.c viewpnt.c ray.c planes.c iff.c \
	  gif.c gifdecod.c triangle.c raw.c targa.c \
          quartics.c vect.c $(MACHINE).c

DKBOBJS=$(DKBSRC:.c=.o)

.c.o :
	$(CC) $(CFLAGS) $*.c

dkbtrace: depend $(DKBOBJS)
	>copts $(CFLAGS) -o $@ $(DKBOBJS)  $(LFLAGS)
	$(CC) @copts

depend: $(DKBSRC)
   	$(CC) $(CFLAGS) -M *.c > depend

#include depend


(------------------------------------------ djgpp.c)
#include <stdio.h>
#include <math.h>
#include <grx.h>
#include "frame.h"
#include "dkbproto.h"

#include "config.h"
#define SetColor(c,r,g,b) GrSetColor((c),(r)<<2,(g)<<2,(b)<<2)

struct exception 
{
/* Math Error exception struct format: */
	int type;		/* - exception type - see below */
	char *name;		/* - name of function where error occured */
	long double arg1;	/* - first argument to function */
	long double arg2;	/* - second argument (if any) to function */
	long double retval;	/* - value to be returned by function */
};

extern unsigned int Options;

/* djgpp.c */
void unix_init_dkb_trace PARAMS ((void ));
void pallete_init PARAMS ((void ));
void hsv_to_rgb PARAMS ((DBL hue , DBL s , DBL v , unsigned *r , unsigned *g , unsigned *b ));
void rgb_to_hsv PARAMS ((unsigned r , unsigned g , unsigned b , DBL *h , DBL *s , DBL *v ));

void unix_init_dkb_trace PARAMS ((void))
   {
   }

void display_finished ()
   { 
    if (Options & PROMPTEXIT)
	{
	printf ("\007\007");	/* long beep */
	while(!kbhit())		/* wait for key hit */
	   ;
	if (!getchar())		/* get another if ext. scancode */
	   getchar();
	}
   }

int screen_height, screen_width;

void display_init (int width, int height)
   {
	if (height<=200) GrSetMode(GR_320_200_graphics);
	else if (height<=480) GrSetMode(GR_width_height_graphics,640,480,256);
	else GrSetMode(GR_default_graphics);
	screen_height=height;
	screen_width=width;
	pallete_init();
   }

void pallete_init()		/* Fill VGA 256 color palette with colors! */
    {
	register unsigned m;
	unsigned r, g, b;
	register DBL hue, sat, val;

	GrSetColor(0,0,0,0); /* black */
	GrSetColor(64,63,63,63); /* white */
	GrSetColor(128,31,31,31); /* dark grey */
	GrSetColor(192,48,48,48); /* light grey */
	for (m=1; m < 64; m++) {
	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);
	SetColor (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);
	SetColor (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);
	SetColor (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);
	SetColor (m + 192, r, g, b); /* set m + 192 */
	}
}

void display_close ()
   {
     GrSetMode(GR_default_text);
   }

void display_plot (x, y, Red, Green, Blue)
   int x, y;
   char Red, Green, Blue;
   {
   register unsigned char color;
   DBL h, s, v, fx, fy;
   static int lasty=-1, lastline=-1, lastx=-1;

   if (!x)			/* first pixel on this line? */
	{
	lastx = -1;		/* reset cache, make sure we do the 1st one */
	lasty = lastline;	/* set last line do to prior line */
	}

   if (screen_height > GrMaxY())	/* auto-scale Y */
	{
	fy = (DBL)y / ((DBL)screen_height / (DBL)GrMaxY());
	y = (int)fy;		/* scale y to svga_height */
	if (y <= lasty)		/* discard if repeated line */
	    return;
	lastline = y;		/* save current working line */
	}

   if (screen_width > GrMaxX())		/* auto-scale X */
	{
	fx = (DBL)x / ((DBL)screen_width / (DBL)GrMaxX());
	x = (int)fx;		/* scale x to svga_width */
	if (x <= lastx)		/* discard if repeated pixel */
	    return;
	lastx = x;		/* save most recent pixel done */
	}

   /* 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.20)   /* black or white if no saturation of color... */
   {
      if (v < 0.25)
         color = 0;        /* black */
      else if (v > 0.8)
         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 */
      }

     if ( (x<GrMaxX())&&(y<GrMaxY()) )
       {
	 GrPlot(x,y,color);
       }
   return;
   }

/* 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-360.0) s and v 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 = 0.0, ng = 0.0, nb = 0.0;	/* 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 = 0.0, 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 psuedo-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


/* Math Error exception struct format:
	int type;		- exception type - see below
	char _FAR_ *name;	- name of function where error occured
	long double arg1;	- first argument to function
	long double arg2;	- second argument (if any) to function
	long double retval;	- value to be returned by function
*/

int matherr(e)
   struct exception *e;
   {
   if (Options & DEBUGGING) {
      /* Since we are just making pictures, not keeping nuclear power under
         control - it really isn't important if there is a minor math problem.
         This routine traps and ignores them.  Note: the most common one is
         a DOMAIN error coming out of "acos". */
      switch (e->type) {
	 case DOMAIN   : printf("DOMAIN error in '%s'\n", e->name); break;
	 case SING     : printf("SING   error in '%s'\n", e->name); break;
	 case OVERFLOW : printf("OVERFLOW error in '%s'\n", e->name); break;
	 case UNDERFLOW: printf("UNDERFLOW error in '%s'\n", e->name); break;
	 case TLOSS    : printf("TLOSS error in '%s'\n", e->name); break;
	 case PLOSS    : printf("PLOSS error in '%s'\n", e->name); break;
/*	 case EDOM     : printf("EDOM error in '%s'\n", e->name); break;
 *	 case ERANGE   : printf("ERANGE error in '%s'\n", e->name); break;
*/
	 default       : printf("Unknown math error in '%s'\n",e->name);break;
         }
      }
   return (1);	/* Indicate the math error was corrected... */
   }
(--------------------------------------------)
Gary Lawrence Murphy ---------------- garym AT virtual DOT rose DOT utoronto DOT ca
University of Toronto, Industrial Eng Dept    fax:    (416) 978-3453
4 Taddle Creek Rd, Toronto, Ont M5S 1A4       voice:  (416) 978-3776
The true destination is always just here, now ----------------------


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019