/**********************************************************


             Header file for Quick Ray Trace

                     Steve Koren

 **********************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#define TRUE  1
#define FALSE 0

#define BOOL short


/**********************************************************

                     MACHINE TYPES

 **********************************************************/

#undef	AMIGA
#undef  MAC_II
#undef  ATARI_ST
#undef  UNIX
#define IBM_OR_CLONE	TRUE
#undef  OS_2
#undef  XENIX
#undef  VMS


/**********************************************************

                   MISC MATH CONSTANTS

 **********************************************************/

#define PI  3.141592
#define PI2 1.570796


/**********************************************************

                     OBJECT  NUMBERS

 **********************************************************/

#define LINE               1
#define SPHERE             2
#define PARALLELOGRAM      3
#define TRIANGLE           4
#define LAMP               5
#define OBSERVER           6
#define GROUND             7
#define SKY                8
#define BBOX               9
#define RING               10
#define QUADRATIC          11


/**********************************************************

                   PROGRAM CONSTANTS

 **********************************************************/

#define SMALL    1.0e-3      /* a sorta small number    */
#define BIG      1.0e15      /* a sorta big number      */
#define CNUM     255         /* this many shades/color  */
#define SLEN     64          /* max string length       */
#define MAX_IX   4           /* maximum x interpolation */
#define MAX_IY   4           /* maximum y interpolation */
#define MAX_XRES 768         /* maximum X resolution    */
#define XYZZY    42          /* this is here for no     */
                             /* reason whatsoever       */


/**********************************************************

                      VECTOR STRUCTURES

 **********************************************************/

typedef struct vector {        /* a vector in 3 space   */
  double x,y,z;
} VECTOR, *VECT_PTR;

typedef struct svector {       /* an r,g,b color vector */
  short r,g,b;
} SVECTOR, *SVECT_PTR;

typedef struct cinfo_struct {  /* color information     */

  SVECTOR       amb,           /* ambient lighting      */
                diff,          /* diffuse lighting      */
                mirror,        /* % light reflected     */
                trans;         /* % light transmitted   */

  VECTOR        density;       /* density */

  double         sreflect,      /* specular refl coefficient */
                index;         /* index if refraction */

  short         fuzz,          /* currently unused */
                reflect,       /* percent specularly reflected */
                dither;        /* color dithering. 3..6 look ok */

} CINFO, *CINFO_PTR;


/**********************************************************

                PRECOMPUTED INFO FOR OBJECTS

 These fields can be used by object routines however
 they wish.  They just make object/line intersections
 faster.

 **********************************************************/

typedef struct _pre {

  double    sin1, cos1,         /* sin and cos */
           sin2, cos2,
           n1,                 /* misc number */
           len1, len2;         /* lengths of vectors */

  VECTOR   vect1,              /* misc vector */
           norm;               /* norm for planar objs */

} PRECOMP, PRECOMP_PTR;


/**********************************************************

                      PATTERN STRUCTURE

 **********************************************************/

typedef struct patt {
  short    type;               /* type of pattern */
  double    xsize,              /* pattern size */
           ysize,
           startx,
           starty,             /* x,y positions */
           endx,
           endy,
           radius;             /* rad for circles */

  CINFO    cinfo;              /* color information */

  char     *name;              /* pattern name */

  struct patt *child, *sibling, *link;

} PATTERN, *PATTERN_PTR;


/**********************************************************

                    OBJECT STRUCTURE

 **********************************************************/

typedef struct obj_struct {

  short         type,         /* object type */
                flag;         /* misc boolean flag */

  char          *name;        /* object name */

  VECTOR        loc,          /* object location */
                vect1,        /* three vectors */
                vect2,
                vect3,
                lower,        /* lower and upper bounds */
                upper;

  double         cterm,        /* for quadratic surfaces only */
                xmult,        /* x and y multipliers for patterns */
                ymult;

  CINFO         cinfo;        /* color information */

  PRECOMP       precomp;      /* precomputed information */

  struct obj_struct *nextobj, /* next obj in list */
                    *child;   /* child for bounding boxes only */

  PATTERN_PTR   pattern,      /* pointer to pattern structure */
                remove;       /* remove section of object */

} OBJ_STRUCT, *OBJ_PTR;


/**********************************************************

                   Plane Bbox structure

 **********************************************************/

typedef struct _PlaneBox {
  int      min_x, min_y,
           max_x, max_y;

  OBJ_PTR  object;

  struct _PlaneBox *next;
} PLANE_BBOX, *PLANE_BBOX_PTR;


/**********************************************************

                       WORLD STRUCTURE

 **********************************************************/

typedef struct world {
  OBJ_PTR   stack,            /* here are the objects */
            observer,         /* the observer */
            sky,              /* sky */
            lamps,            /* a lamp list */
            instances;        /* instance list */

  int       objcount,         /* # objects and lamps */
            lampcount;

  long      ray_intersects,   /* statistics */
            primary_traced,
            to_lamp,
            refl_trans,
            bbox_intersects,
            intersect_tests,
            pixels_hit,
            pattern_matches;

  VECTOR    obsright,         /* obs up dir */
            obsup;

  SVECTOR   skycolor_horiz,   /* skycolors */
            skycolor_zenith;

  PATTERN_PTR patlist;        /* the pattern stack */

  double     flength,          /* focal length */
            x_divisor,        /* used to find ray direction */
            y_divisor,
            globindex;        /* global index of refraction */

  char      *outfile;         /* output file name */
  FILE      *filept;          /* output file pointer */
} WORLD;


/**********************************************************

                  FUNCTIONS FOR OBJECT TYPES

 **********************************************************/

typedef struct obj_data {
  int  (*ColTest)();           /* collision test function ptr */
  void (*FindNorm)();          /* normal finding function ptr */
  void (*FindBbox)();          /* object bound function ptr   */
  void (*RelPos)();            /* object relative position    */
  void (*PreComp)();           /* info pre-computing routine  */
  void (*Offset)();            /* offset object by dx, dy, dz */
  void (*Resize)();            /* resize object by a multiple */
} OBJ_DATA;


/**********************************************************

                      MATH DEFINES

 **********************************************************/

#define sqr(x) ((x)*(x))
#define DotProd(v1,v2) (v1.x*v2.x+v1.y*v2.y+v1.z*v2.z)
#define MIN(x,y) ((x)<(y) ? (x) : (y))
#define MAX(x,y) ((x)>(y) ? (x) : (y))
#define IABS(x)  ((x)>0   ? (x) : (-(x)))


/**********************************************************

                      Default structure

 **********************************************************/

typedef struct def_struct {

  CINFO cinfo;             /* default colorinfo */

  short shadow,            /* shadows ? */
        vlamp,             /* lamps visible (not yet implimented) */
        int_x,             /* interpolate (def=1) */
        int_y,

        x_res,             /* X resolution of image */
        y_res,             /* Y resolution of image */
        x_center,          /* X center of image */
        y_center;          /* Y center of image */

  double threshold,         /* cutoff pt for min refl, refl rays */
        aspect;            /* aspect ratio for image            */


  short ithreshold;        /* integer version of above          */

} DEF, *DEF_PTR;


/**********************************************************

                     EXTERNAL DECLARATIONS

 **********************************************************/

extern DEF def;

extern OBJ_DATA ObjData[];

extern WORLD THEWORLD;


/**********************************************************

                       ERROR CODES

 **********************************************************/

#define ILLEGAL_PARAMETER 1
#define TOO_FEW_PARMS     2
#define ILLEGAL_OBJECT    3
#define MALLOC_FAILURE    4
#define SYNTAX_ERROR      5
#define INTERNAL_ERROR    6
#define FILE_ERROR        7
#define PATTERN_NOT_FOUND 8
#define PATTERN_EXISTS    9
#define NO_OBSERVER       10
#define UNDEFINED_PARAM   11
#define NON_HOMOGENIOUS   12
#define ZERO_INDEX        13
#define COLOR_VALUE_ERR   14
#define LESS_THAN_ZERO    15
#define ZERO_MULTIPLIER   16
#define UNDEFINED_NAME    17
#define LPAREN_EXPECTED   18
#define RPAREN_EXPECTED   19
#define ILLEGAL_VECTOR    20
#define ILLEGAL_SVECTOR   21
#define ILLEGAL_OPTION    22


/**********************************************************

                      WARNING CODES

 **********************************************************/

#define OBSOLETE_OPTION   1


/**********************************************************

 Define this flag for more robust code (HIGHLY recommended)

 **********************************************************/

#define	ROBUST	TRUE


/**********************************************************

  Ansi C stuff (global function prototypes, etc)

 **********************************************************/


  /* qrt.c */

void _Cdecl Tree_Walker(OBJ_PTR, int);
void _Cdecl Setup_Observer(void);
void _Cdecl init_world(void);
void _Cdecl Parse_CL_Args(int, char **);
  
  /* mth.c */

int _Cdecl PsRand(void);
void _Cdecl VectEqZero(VECT_PTR);
void _Cdecl VectAddMult(VECT_PTR, double, VECT_PTR, double, VECT_PTR);
void _Cdecl VectNegate(VECT_PTR, VECT_PTR);
void _Cdecl VectorAdd(VECT_PTR, VECT_PTR, VECT_PTR);
void _Cdecl VectorMult(VECT_PTR, VECT_PTR, VECT_PTR);
void _Cdecl VecSubtract(VECT_PTR, VECT_PTR, VECT_PTR);
void _Cdecl VectScale(VECT_PTR, double);
void _Cdecl SVectEQ(SVECT_PTR, SVECT_PTR);
void _Cdecl VectEQ(VECT_PTR, VECT_PTR);
void _Cdecl CrossProd(VECT_PTR, VECT_PTR, VECT_PTR);
void _Cdecl Normalize(VECT_PTR);
void _Cdecl FindPos(VECT_PTR, OBJ_PTR, double);
void _Cdecl Reflect(VECT_PTR, VECT_PTR, VECT_PTR);
void _Cdecl Rot12(VECT_PTR, VECT_PTR, double, double, double, double);
void _Cdecl Rot21(VECT_PTR, VECT_PTR, double, double, double, double);
double _Cdecl atan2w(double, double);

  /* error.c */

void Err(void);
int Erri(void);
void _Cdecl Error(int, int);
void _Cdecl Warning(int, char *);

  /* stack.c */

void _Cdecl Do_Precomp(OBJ_PTR);
void _Cdecl Do_Precomp_Tree(OBJ_PTR);
void _Cdecl Make_Bbox(OBJ_PTR);
PATTERN_PTR _Cdecl find_pat(char *);
PATTERN_PTR _Cdecl new_pat(void);
OBJ_PTR _Cdecl new_obj(short,VECT_PTR,VECT_PTR,VECT_PTR,VECT_PTR,CINFO_PTR,PATTERN_PTR,PATTERN_PTR,char *,VECT_PTR,VECT_PTR,double,double,double);
OBJ_PTR _Cdecl new_line(void);
void _Cdecl add_lamp(OBJ_PTR);
void _Cdecl print_obj(OBJ_PTR);
void _Cdecl World_Stats(void);
void _Cdecl Open_File(void);
void _Cdecl Close_File(void);

/* inout.c */

int _Cdecl LoadWorld(void);
int _Cdecl Get_Default(void);
int _Cdecl GetOpt(char *, CINFO_PTR);
int _Cdecl GetLamp(void);
int _Cdecl GetObserver(void);
int _Cdecl GetSky(void);
int _Cdecl GetFocLength(void);
int _Cdecl GetAttrib(char *);
void _Cdecl def_colorinfo(CINFO_PTR);
void _Cdecl copy_colorinfo(CINFO_PTR, CINFO_PTR);
OBJ_PTR _Cdecl Get_Object(void);
OBJ_PTR _Cdecl GetSphere(void);
OBJ_PTR _Cdecl GetTriangle(void);
OBJ_PTR _Cdecl GetRing(void);
OBJ_PTR _Cdecl GetParallelogram(void);
OBJ_PTR _Cdecl GetQuadratic(void);
OBJ_PTR _Cdecl Get_Primitive(char *);


/* bbox.c */

void _Cdecl BboxBbox(VECT_PTR, VECT_PTR, OBJ_PTR);
void _Cdecl BboxSphere(VECT_PTR, VECT_PTR, OBJ_PTR);
void _Cdecl BboxParallelogram(VECT_PTR, VECT_PTR, OBJ_PTR);
void _Cdecl BboxTriangle(VECT_PTR, VECT_PTR, OBJ_PTR);
void _Cdecl BboxRing(VECT_PTR, VECT_PTR, OBJ_PTR);
void _Cdecl BboxQuadratic(VECT_PTR, VECT_PTR, OBJ_PTR);


/* lexer.c */

int _Cdecl GetRightParen(void);
char _Cdecl towhite(char);
char *_Cdecl Get_Next_Name(void);
void _Cdecl rmspace(void);
void _Cdecl Comment_Killer(void);
void _Cdecl GetToken(char *);
void _Cdecl GetLeftParen(void);
void _Cdecl GetVector(VECT_PTR);
void _Cdecl GetSVector(SVECT_PTR);
short _Cdecl Get_Color_Val(void);
double _Cdecl InRange(double);
double _Cdecl IsPos(double);
double _Cdecl Get_Next_Num(void);


/* instance.c */

OBJ_PTR _Cdecl Name_Find(OBJ_PTR, char *);
OBJ_PTR _Cdecl Subtree_Copy(OBJ_PTR, int);
void _Cdecl Subtree_Offset(OBJ_PTR, VECT_PTR, int);
void _Cdecl Subtree_Scale(OBJ_PTR, VECT_PTR, int);
OBJ_PTR _Cdecl Get_Instance_Of(void);

/* intersec.c */

int _Cdecl LineBbox(OBJ_PTR, OBJ_PTR, double *);
int _Cdecl LineRing(OBJ_PTR, OBJ_PTR, double *);
int _Cdecl LineParallelogram(OBJ_PTR, OBJ_PTR, double *);
int _Cdecl LineTriangle(OBJ_PTR, OBJ_PTR, double *);
int _Cdecl LineSphere(OBJ_PTR, OBJ_PTR, double *);
int _Cdecl LineQuadratic(OBJ_PTR, OBJ_PTR, double *);

/* norm.c */

void _Cdecl SphereNorm(VECT_PTR, OBJ_PTR, VECT_PTR);
void _Cdecl PlaneNorm(VECT_PTR, OBJ_PTR);
void _Cdecl QuadraticNorm(VECT_PTR, OBJ_PTR, VECT_PTR);

/* offset.c */

void _Cdecl Standard_Offset(OBJ_PTR, VECT_PTR);
void _Cdecl Offset_Bbox(OBJ_PTR, VECT_PTR);

/* precomp.c */

void _Cdecl PreCompSphere(OBJ_PTR);
void _Cdecl PreCompPlane(OBJ_PTR);
void _Cdecl PreCompQuadratic(OBJ_PTR);
void _Cdecl PreCompNull(void);

/* pattern.c */

int _Cdecl Find_Color(OBJ_PTR,PATTERN_PTR,VECT_PTR,CINFO_PTR,double,double);
int _Cdecl Rect_Hit(double, double, PATTERN_PTR);
int _Cdecl Circle_Hit(double, double, PATTERN_PTR);
int _Cdecl line_intersect(double, double, double, double, double, double);
int _Cdecl Poly_Hit(double, double, PATTERN_PTR);

/* patterni.c */

PATTERN_PTR _Cdecl Attach_Pattern(void);
PATTERN_PTR _Cdecl Get_Circle_Pattern(void);
PATTERN_PTR _Cdecl Get_Rect_Pattern(void);
PATTERN_PTR _Cdecl Get_Poly_Pattern(void);
PATTERN_PTR _Cdecl Get_SubPattern(char *);
PATTERN_PTR _Cdecl GetPattern(void);

/* relpos.c */

void _Cdecl Find_Plane_Coords(VECT_PTR,VECT_PTR,VECT_PTR,double *,double *,double,double,double);
void _Cdecl Plane_Pos(OBJ_PTR, VECT_PTR, double *, double *, int);
void _Cdecl Sphere_Pos(OBJ_PTR, VECT_PTR, double *, double *);
void _Cdecl Quadratic_Pos(OBJ_PTR, VECT_PTR, double *, double *);

/* resize.c */

void _Cdecl Resize_Sphere(OBJ_PTR, VECT_PTR);
void _Cdecl Resize_Plane(OBJ_PTR, VECT_PTR);
void _Cdecl Resize_Quadratic(OBJ_PTR, VECT_PTR);
void _Cdecl Resize_Bbox(OBJ_PTR);

/* ray.c */

int _Cdecl Ray_Trace(OBJ_PTR, SVECT_PTR, double);
void _Cdecl DiffColor(SVECT_PTR, CINFO_PTR, VECT_PTR, VECT_PTR, OBJ_PTR);
void _Cdecl AmbColor(SVECT_PTR, CINFO_PTR);
void _Cdecl TransColor(SVECT_PTR,CINFO_PTR,VECT_PTR,VECT_PTR,OBJ_PTR,double);
void _Cdecl ReflectColor(SVECT_PTR,CINFO_PTR,VECT_PTR,VECT_PTR,OBJ_PTR,double);
void _Cdecl SkyColor(OBJ_PTR, SVECT_PTR);
void _Cdecl Dither(SVECT_PTR, CINFO_PTR);
void _Cdecl PixelLine(int, int, OBJ_PTR);
void _Cdecl Dump_Line(int, short *, short *, short *);
void _Cdecl Screen_Trace(void);
OBJ_PTR _Cdecl Ray_Hit(OBJ_PTR, OBJ_PTR, double *, short, short, VECT_PTR);

