/************************************************************************
 *									*
 *		    Copyright (c) 1988, David B. Wecker			*
 *			    All Rights Reserved				*
 *									*
 * This file is part of DBW_uRAY					*
 *									*
 * DBW_uRAY is distributed in the hope that it will be useful, but	*
 * WITHOUT ANY WARRANTY. No author or distributor accepts		*
 * responsibility to anyone for the consequences of using it or for	*
 * whether it serves any particular purpose or works at all, unless	*
 * he says so in writing. Refer to the DBW_uRAY General Public		*
 * License for full details.						*
 *									*
 * Everyone is granted permission to copy, modify and redistribute	*
 * DBW_uRAY, but only under the conditions described in the		*
 * DBW_uRAY General Public License. A copy of this license is		*
 * supposed to have been given to you along with DBW_uRAY so you	*
 * can know your rights and responsibilities. It should be in a file	*
 * named COPYING. Among other things, the copyright notice and this	*
 * notice must be preserved on all copies.				*
 ************************************************************************
 *									*
 * Authors:								*
 *	DBW - David B. Wecker						*
 *									*
 * Versions:								*
 *	V1.0 881023 DBW	- First released version			*
 *	V1.1 881110 DBW - Fixed scan coherence code			*
 *	V1.2 881125 DBW - Removed ALL scan coherence code (useless)	*
 *			  added "fat" extent boxes			*
 *									*
 ************************************************************************/

#define VERSION "uRAY v1.2 881125 (C) 1988 D. Wecker - all rights reserved\n"

/************************************************************************/
/************* global definitions for uray software *********************/
/************************************************************************/

#ifdef URAY_MAIN
#   define  MAINDEF
#   define  MAINVAL(a)	= a
#else
#   define  MAINDEF	extern
#   define  MAINVAL(a)
#   endif


/******************** include files **************************************/

#include <stdio.h>
#include <math.h>
#include <signal.h>

#ifdef U__X
#include <sys/types.h>
#include <sys/times.h>
#endif

#ifdef VMS
#include <types.h>
#include <time.h>
#endif

#ifdef AMIGA
#ifndef SIGINT
#   define  SIGINT  1
#   endif
#include <exec/types.h>
#include <intuition/intuition.h>
#endif


/********************** floating point defs ******************************/

#if DODOUBLE
#   define FLTDBL   double
#   define MYHUGE   ((double)1.0e+30)
#   define TOL	    ((FLTDBL)1.0e-7)	    /* minimum tolerance */
#   ifdef AMIGA
#	define BIGF
#	endif
#else
#   define FLTDBL   float
#   define MYHUGE   ((float)1.0e+17)
#   define TOL	    ((FLTDBL)1.0e-4)	    /* minimum tolerance */
#   endif

#ifdef BIGF
#   define SCAN1    "%s %F"
#   define SCAN2    "%s %F %F %F"
#   define SCAN3    "%F %F %F %F %F %F %F %F %F %F %d %d %F %F %F %F %F %F"
#   define SCAN4    "%F %F %F %F %F %F %F"
#   define SCAN5    "%s %d %F %F %F %F"
#   define SCAN6    "%s %d %F %F %F %F %F %F %F %F %F"
#   define SCAN7    "%s %d %F %F %F %F %F %F %F %F %F %F %F"
#else
#   define SCAN1    "%s %f"
#   define SCAN2    "%s %f %f %f"
#   define SCAN3    "%f %f %f %f %f %f %f %f %f %f %d %d %f %f %f %f %f %f"
#   define SCAN4    "%f %f %f %f %f %f %f"
#   define SCAN5    "%s %d %f %f %f %f"
#   define SCAN6    "%s %d %f %f %f %f %f %f %f %f %f"
#   define SCAN7    "%s %d %f %f %f %f %f %f %f %f %f %f %f"
#   endif

/********************** debug defs ****************************************/


#define DEBUG_dumpnodes	0   /* dump a tree of all nodes and extents */
#define DEBUG_ilbm	0   /* show ILBM output info */
#define DEBUG_pixels	0   /* show pixel RGB values */


/*********************** global defs **************************************/

#define MAXCOLS	1024			    /* maximum compute width */

#define ABS(a)		(((a) < 0)   ? -(a) : (a))
#define FABS(a)		(((a) < 0.0) ? -(a) : (a))
#define MIN(a,b)	(((a) < (b)) ?  (a) : (b))
#define MAX(a,b)	(((a) > (b)) ?  (a) : (b))

#define vdot(A,B)	(A[0]*B[0] + A[1]*B[1] + A[2]*B[2])
#define vnorm(A)	sqrt(vdot(A,A))
#define vcopy(A,B)	B[0]=A[0]; B[1]=A[1]; B[2]=A[2]
#define vscale(v,A,B)	B[0]=(v)*A[0]; B[1]=(v)*A[1]; B[2]=(v)*A[2]
#define vcomb(v,A,B,C)	C[0]=(v)*A[0]+B[0]; C[1]=(v)*A[1]+B[1]; C[2]=(v)*A[2]+B[2]
#define vadd(A,B,C)	C[0]=A[0]+B[0]; C[1]=A[1]+B[1]; C[2]=A[2]+B[2]
#define vsub(A,B,C)	C[0]=A[0]-B[0]; C[1]=A[1]-B[1]; C[2]=A[2]-B[2]
#define vmul(A,B,C)	C[0]=A[0]*B[0]; C[1]=A[1]*B[1]; C[2]=A[2]*B[2]
#define vdir(A,B,C)	vsub(B,A,C); vunit(C,C)
#define vcross(A,B,C)	C[0]=(A[1] * B[2]) - (B[1] * A[2]); \
			C[1]=(A[2] * B[0]) - (B[2] * A[0]); \
			C[2]=(A[0] * B[1]) - (B[0] * A[1]);

/******************* ILBM file header defines *****************************/

#ifndef HIRES
#   define HIRES    0x8000L
#   endif
#ifndef HAM
#   define HAM	    0x800L
#   endif
#ifndef LACE
#   define LACE	    0x4L
#   endif
#define DEPTH	    6
#define MAXBYTE	    (cols >> 3)
#define BMHDsize    20L			/* chunk sizes */
#define CMAPsize    96L
#define CAMGsize    4L
#define BODYsize    (((long)rows)*((long)(MAXBYTE))*(long)(DEPTH))
#define FORMsize    (BODYsize+CAMGsize+CMAPsize+BMHDsize+36L)


/************************** object types *********************************/

#define TYP_E	0	/* extent */
#define TYP_S	1	/* sphere */
#define TYP_Q	2	/* quad */
#define TYP_T	3	/* triangle */
#define TYP_R	4	/* ring */
#define TYP_L	5	/* light */


/************************** typedefs **************************************/

typedef FLTDBL VEC[3];

typedef struct _ATT {
    VEC		    color;
    FLTDBL	    kd, ks, kt, ir, kl, dist, kf;
    short	    wave, tex;
    VEC		    p1,p2;
    } ATT;
typedef struct _WAVE {
    VEC		    cen;
    FLTDBL	    phase, length, damp, amp;
    } WAVE;
typedef struct _NODE {
    struct _NODE    *next;
    unsigned char   typ;
    ATT		    *att;
    VEC		    cen;
    } NODE;
typedef struct _EXTENT {
    NODE	    *next;
    unsigned char   typ;
    VEC		    min,max;
    NODE	    *child;
    } EXTENT;
typedef struct _SPHERE {
    NODE	    *next;
    unsigned char   typ;
    ATT		    *att;
    VEC		    cen;
    FLTDBL	    rad;
    } SPHERE;
typedef struct _QUAD {
    NODE	    *next;
    unsigned char   typ;
    ATT		    *att;
    VEC		    p0, v1, v2;
    } QUAD;
typedef struct _TRIANGLE {
    NODE	    *next;
    unsigned char   typ;
    ATT		    *att;
    VEC		    p0, v1, v2;
    } TRIANGLE;
typedef struct _RING {
    NODE	    *next;
    unsigned char   typ;
    ATT		    *att;
    VEC		    p0, v1, v2;
    FLTDBL	    rad1,rad2;
    } RING;
typedef struct _LIGHT {
    struct _LIGHT   *next;
    NODE	    *child;
    } LIGHT;


/*************************** routines ***********************************/

char		*malloc(),
		*calloc(),
		*my_malloc(),
		*my_calloc();
void		leave(),
		vunit(),
		planenormal(),
		spherenormal(),
		gettex(),
		getamb(),
		getlights(),
		getspecular(),
		gettrans(),
		readinput(),
		wfil(),
		unionvector(),
		unionextent(),
		getextent(),
		doextents(),
		dumpnodes(),
		coutputs(),
		woutputs(),
		trace(),
		calcripple();
short		rfil(),
		PackRow();
NODE		*intersection(),
		*intersection2(),
		*hitextent(),
		*hitsphere(),
		*sortext(),
		*doalloc(),
		*srtext();
FLTDBL		rnd(),
		findnormal();
long		random();



/*************************** variables ***********************************/

MAINDEF long		seed	    MAINVAL(257);
MAINDEF char		str[256],
			cmd[256],
			*basnam	    MAINVAL("uray");
MAINDEF char		*TYPstr	    MAINVAL("ESQTRLF");
MAINDEF VEC		NEAR
#ifdef URAY_MAIN
			    = {0.0, 0.0, 1.0}
#endif
			    ;
MAINDEF VEC		FAR	    
#ifdef URAY_MAIN
			    = {0.0, 0.0, 1.0}
#endif
			    ;
MAINDEF VEC		GROUND	    
#ifdef URAY_MAIN
			    = {0.6, 0.3, 0.3}
#endif
			    ;
MAINDEF VEC		BLACK	    
#ifdef URAY_MAIN
			    = { 0.0, 0.0, 0.0 }
#endif
			    ;
MAINDEF VEC		from,
			direction,
			dirinv;
MAINDEF NODE		*nodes	    MAINVAL(NULL);
MAINDEF FILE		*fp	    MAINVAL(NULL);
MAINDEF FILE		*fp2	    MAINVAL(NULL);
MAINDEF unsigned char	outary[3][MAXCOLS];
MAINDEF short		rows	    MAINVAL(400);
MAINDEF short		startrow    MAINVAL(0);
MAINDEF short		endrow	    MAINVAL(400);
MAINDEF short		cols	    MAINVAL(320);
MAINDEF short		bpp	    MAINVAL(12);
MAINDEF short		sline;
MAINDEF short		obpsl;
MAINDEF short		aov	    MAINVAL(90);
MAINDEF short		depth	    MAINVAL(20);
MAINDEF int		natts	    MAINVAL(0);
MAINDEF ATT		*atts	    MAINVAL(NULL);
MAINDEF int		nwaves	    MAINVAL(0);
MAINDEF WAVE		*waves	    MAINVAL(NULL);
MAINDEF int		row,
			col;
MAINDEF int		fnhits	    MAINVAL(0),
			gnhits	    MAINVAL(0),
			fehits	    MAINVAL(0),
			gehits	    MAINVAL(0);
MAINDEF EXTENT		*ext;
MAINDEF SPHERE		*sph;
MAINDEF QUAD		*qua;
MAINDEF TRIANGLE	*tri;
MAINDEF RING		*rin;
MAINDEF LIGHT		*lights	    MAINVAL(NULL);
MAINDEF int		extcnt	    MAINVAL(0);
MAINDEF int		objcnt	    MAINVAL(0);
MAINDEF FLTDBL		aspect	    MAINVAL(0.544);
MAINDEF FLTDBL		base	    MAINVAL(0.25);
MAINDEF long		lng,
			pos1,
			pos2,
			pos3,
			lsize;
MAINDEF short		wrd;
MAINDEF unsigned char	byt;
MAINDEF int		lstcolor    MAINVAL(0);
MAINDEF unsigned char	colors[16][3];
MAINDEF long		randtbl[ 63 ]
#ifdef URAY_MAIN
			= {
			0x00000001, 0x41c67ea6, 0x967eb0e7,
			0x2781e494, 0xc46b9b3d, 0xf94bdf32, 0x95fb7483,
			0xd9e2b600, 0x9cfbae39, 0xbf54bc7e, 0x0ff6d5df,
			0x0abd322c, 0x31dff4f5, 0x237c228a, 0xaf1cf0fb,
			0x7de14518, 0xc487eb71, 0xe201dd56, 0xd2bfa1d7,
			0xe2319ac4, 0xe3decdad, 0xe95678e2, 0x93728473,
			0x500f9f30, 0x284797a9, 0x2c67412e, 0x7566f4cf,
			0x42877e5c, 0xb3590565, 0x4daa423a, 0xe4880eeb,
			0xf73c2448, 0xef5992e1, 0xeeea4806, 0x5656aec7,
			0xe1133cf4, 0xca7b7c1d, 0x31d2de92, 0xad857063,
			0x99a13460, 0x69d8bd19, 0xb53c51de, 0x3b54afbf,
			0x7d55368c, 0x102f11d5, 0x1b37adea, 0x7aae88db,
			0xde652f78, 0xb45bf651, 0xe3dabeb6, 0x6102d7b7,
			0x7a79cb24, 0x8398a68d, 0x28cc1042, 0xe0e33853,
			0x9f1a7590, 0x4b761e89, 0x858eee8e, 0xfa5f06af,
			0x28d95abc, 0x87991a45, 0x388f659a, 0x751f5ecb }
#endif
			;

MAINDEF long	*fptr		    MAINVAL(&randtbl[ 2 ]);
MAINDEF long	*rptr		    MAINVAL(&randtbl[ 0 ]);
MAINDEF long	*end_ptr	    MAINVAL(&randtbl[ 63 ]);

#ifdef AMIGA
    MAINDEF struct IntuitionBase *IntuitionBase;
#   endif
