/*****************************************************************************
*
*                                   frame.h
*
*   from DKBTrace (c) 1990  David Buck
*
*  This header file is included by all C modules in DKBTrace.  It defines all
*  globally-accessible types and constants.
*
* 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
*
*****************************************************************************/


/* Generic header for all modules */

#include "config.h"
#include <stdio.h>
#include <string.h>
#include <math.h>

#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif

#ifndef FILE_NAME_LENGTH
#define FILE_NAME_LENGTH 150
#endif

#ifndef DBL
#define DBL double
#endif

#ifndef HUGE_VAL
#define HUGE_VAL 1.0e+17
#endif

#ifndef DBL_FORMAT_STRING
#define DBL_FORMAT_STRING "%lf"
#endif

#ifndef TEST_ABORT
#define TEST_ABORT
#endif

/* These values determine the minumum and maximum distances
   that qualify as ray-object intersections */
#define Small_Tolerance 0.001
#define Max_Distance 1.0e7

/* Maximum gif bitmap size allowed. */
#define BITMAP_X_SIZE 640
#define BITMAP_Y_SIZE 480

typedef struct q_entry INTERSECTION;
typedef struct Vector_Struct VECTOR;
typedef DBL MATRIX [4][4];
typedef struct Colour_Struct COLOUR;
typedef struct Colour_Map_Entry COLOUR_MAP_ENTRY;
typedef struct Colour_Map_Struct COLOUR_MAP;
typedef struct Transformation_Struct TRANSFORMATION;
typedef struct Image_Struct IMAGE;
typedef struct Texture_Struct TEXTURE;
typedef struct Method_Struct METHODS;
typedef struct Viewpoint_Struct VIEWPOINT;
typedef struct Object_Shape SHAPE;
typedef struct Object_Struct OBJECT;
typedef struct Sphere_Shape SPHERE;
typedef struct Quadric_Shape QUADRIC;
typedef struct Triangle_Shape TRIANGLE;
typedef struct Smooth_Triangle_Shape SMOOTH_TRIANGLE;
typedef struct Plane_Shape PLANE;
typedef struct CSG_Type CSG_SHAPE;
typedef struct Composite_Object_Struct COMPOSITE;
typedef struct Ray_Struct RAY;
typedef struct Frame_Struct FRAME;
typedef struct prioq_struct PRIOQ;
typedef enum Token_Type TOKEN;
typedef enum Constant_Type CONSTANT;
typedef struct Chunk_Header_Struct CHUNK_HEADER;

struct Vector_Struct
   {
   DBL x, y, z;
   };



struct Colour_Struct
   {
   DBL Red, Green, Blue, Alpha;
   };


struct Colour_Map_Entry
   {
   DBL start, end;
   COLOUR Start_Colour, End_Colour;
   };


struct Colour_Map_Struct
   {
   int Number_Of_Entries;
   COLOUR_MAP_ENTRY *Colour_Map_Entries;
   };


struct Transformation_Struct
   {
   MATRIX matrix;
   MATRIX inverse;
   };


struct Image_Struct
   {
   DBL width, height;
   int iwidth, iheight;
   unsigned char *red, *green, *blue;
   };


enum Texture_Type { NO_TEXTURE, BOZO_TEXTURE, MARBLE_TEXTURE, WOOD_TEXTURE, CHECKER_TEXTURE, SPOTTED_TEXTURE, AGATE_TEXTURE, GRANITE_TEXTURE, GRADIENT_TEXTURE, IMAGEMAP_TEXTURE } ;

enum Bump_Type { NO_BUMPS, WAVES, RIPPLES, WRINKLES, BUMPS, DENTS };

struct Texture_Struct
   {
   DBL Object_Reflection;
   DBL Object_Ambient;
   DBL Object_Diffuse, Object_Brilliance;
   DBL Object_Index_Of_Refraction;
   DBL Object_Refraction;
   DBL Object_Specular, Object_Roughness;
   DBL Object_Phong, Object_PhongSize;
   DBL Bump_Amount;
   DBL Texture_Randomness;
   DBL Frequency;
   DBL Phase;
   enum Texture_Type Texture_Number ;
   enum Bump_Type Bump_Number;
   TRANSFORMATION *Texture_Transformation;
   COLOUR Colour1;
   COLOUR Colour2;
   DBL Turbulence;
   VECTOR Texture_Gradient;
   COLOUR_MAP *Colour_Map;
   IMAGE *Image;
   short Once_Flag;
   };

enum Object_Type {SPHERE_TYPE, TRIANGLE_TYPE, SMOOTH_TRIANGLE_TYPE, PLANE_TYPE,
                  QUADRIC_TYPE, COMPOSITE_TYPE, OBJECT_TYPE,
                  CSG_UNION_TYPE, CSG_INTERSECTION_TYPE, CSG_DIFFERENCE_TYPE,
                  VIEWPOINT_TYPE };

struct Object_Struct
   {
   METHODS *Methods;
   enum Object_Type Type;
   struct Object_Struct *Next_Object;
   struct Object_Struct *Next_Light_Source;
   SHAPE *Bounding_Shapes;
   SHAPE *Shape;
   char Light_Source_Flag;
   char Transparency;
   VECTOR  Object_Center;
   COLOUR Object_Colour;
   TEXTURE *Object_Texture;
   };


typedef INTERSECTION *(*INTERSECTION_METHOD)PARAMS((OBJECT *, RAY *));
typedef int (*ALL_INTERSECTIONS_METHOD)PARAMS((OBJECT *, RAY *, PRIOQ *));
typedef int (*INSIDE_METHOD)PARAMS((VECTOR *, OBJECT *));
typedef void (*NORMAL_METHOD)PARAMS((VECTOR *, OBJECT *, VECTOR *));
typedef void *(*COPY_METHOD)PARAMS((OBJECT *));
typedef void (*TRANSLATE_METHOD)PARAMS((OBJECT *, VECTOR *));
typedef void (*ROTATE_METHOD)PARAMS((OBJECT *, VECTOR *));
typedef void (*SCALE_METHOD)PARAMS((OBJECT *, VECTOR *));
typedef void (*INVERT_METHOD)PARAMS((OBJECT *));

struct Method_Struct
   {
   INTERSECTION_METHOD Intersection_Method;
   ALL_INTERSECTIONS_METHOD All_Intersections_Method;
   INSIDE_METHOD Inside_Method;
   NORMAL_METHOD Normal_Method;
   COPY_METHOD Copy_Method;
   TRANSLATE_METHOD Translate_Method;
   ROTATE_METHOD Rotate_Method;
   SCALE_METHOD Scale_Method;
   INVERT_METHOD Invert_Method;
   };


#define All_Intersections(x,y,z) ((*((x)->Methods->All_Intersections_Method)) (x,y,z))
#define Intersection(x,y) ((*((x)->Methods->Intersection_Method)) (x,y))
#define Inside(x,y) ((*((y)->Methods->Inside_Method)) (x,y))
#define Normal(x,y,z) ((*((y)->Methods->Normal_Method)) (x,y,z))
#define Copy(x) ((*((x)->Methods->Copy_Method)) (x))
#define Translate(x,y) ((*((x)->Methods->Translate_Method)) (x,y))
#define Scale(x,y) ((*((x)->Methods->Scale_Method)) (x,y))
#define Rotate(x,y) ((*((x)->Methods->Rotate_Method)) (x,y))
#define Invert(x) ((*((x)->Methods->Invert_Method)) (x))

struct Viewpoint_Struct
   {
   METHODS *Methods;
   enum Object_Type Type;
   VECTOR Location;
   VECTOR Direction;
   VECTOR Up;
   VECTOR Right;
   VECTOR Sky;
   };


struct Object_Shape
   {
   METHODS *Methods;
   enum Object_Type Type;
   struct Object_Shape *Next_Object;
   void *Parent_Object;
   };


struct Sphere_Shape
   {
   METHODS *Methods;
   enum Object_Type Type;
   SHAPE *Next_Object;
   OBJECT *Parent_Object;
   VECTOR  Center;
   DBL     Radius;
   DBL     Radius_Squared;
   DBL     Inverse_Radius;
   VECTOR  VPOtoC;
   DBL     VPOCSquared;
   short   VPinside, VPCached, Inverted;
   };


struct Quadric_Shape
   {
   METHODS *Methods;
   enum Object_Type Type;
   SHAPE *Next_Object;
   OBJECT *Parent_Object;
   VECTOR  Object_2_Terms;
   VECTOR  Object_Mixed_Terms;
   VECTOR  Object_Terms;
   DBL Object_Constant;
   DBL Object_VP_Constant;
   int Constant_Cached;
   int Non_Zero_Square_Term;
   };


#define X_AXIS 0
#define Y_AXIS 1
#define Z_AXIS 2

struct Triangle_Shape
   {
   METHODS *Methods;
   enum Object_Type Type;
   SHAPE *Next_Object;
   OBJECT *Parent_Object;
   VECTOR  Normal_Vector;
   DBL     Distance;
   DBL     VPNormDotOrigin;
   unsigned int  VPCached:1;
   unsigned int  Dominant_Axis:2;
   unsigned int  Inverted:1;
   unsigned int  vAxis:2;         /* used only for smooth triangles */
   VECTOR  P1, P2, P3;
   };


struct Smooth_Triangle_Shape
   {
   METHODS *Methods;
   enum Object_Type Type;
   SHAPE *Next_Object;
   OBJECT *Parent_Object;
   VECTOR  Normal_Vector;
   DBL     Distance;
   DBL     VPNormDotOrigin;
   unsigned int  VPCached:1;
   unsigned int  Dominant_Axis:2;
   unsigned int  Inverted:1;
   unsigned int  vAxis:2;         /* used only for smooth triangles */
   VECTOR  P1, P2, P3;
   VECTOR  N1, DN12, DN13, Perp;
   DBL  BaseDelta;
   };



struct Plane_Shape
   {
   METHODS *Methods;
   enum Object_Type Type;
   SHAPE *Next_Object;
   OBJECT *Parent_Object;
   VECTOR  Normal_Vector;
   DBL     Distance;
   DBL     VPNormDotOrigin;
   int     VPCached;
   };


struct CSG_Type
   {
   METHODS *Methods;
   enum Object_Type Type;
   SHAPE *Next_Object;
   OBJECT *Parent_Object;
   SHAPE *Shapes;
   };
   

struct Composite_Object_Struct
   {
   METHODS *Methods;
   enum Object_Type Type;
   OBJECT *Next_Object;
   OBJECT *Next_Light_Source;
   SHAPE *Bounding_Shapes;
   OBJECT *Objects;
   };


#define MAX_CONTAINING_OBJECTS 5

struct Ray_Struct
   {
   VECTOR Initial;               /*  Xo  Yo  Zo  */
   VECTOR Direction;             /*  Xv  Yv  Zv  */
   VECTOR Initial_2;             /*  Xo^2  Yo^2  Zo^2  */
   VECTOR Direction_2;           /*  Xv^2  Yv^2  Zv^2  */
   VECTOR Initial_Direction;     /*  XoXv  YoYv  ZoZv  */
   VECTOR Mixed_Initial_Initial; /*  XoYo  XoZo  YoZo  */
   VECTOR Mixed_Dir_Dir;         /*  XvYv  XvZv  YvZv  */
   VECTOR Mixed_Init_Dir;        /*  XoYv+XvYo  XoZv+XvZo  YoZv+YvZo  */
   int Containing_Index;
   OBJECT *Containing_Objects [MAX_CONTAINING_OBJECTS];
   DBL Containing_IORs [MAX_CONTAINING_OBJECTS];
   int Quadric_Constants_Cached;
   };


struct Frame_Struct
   {
   VIEWPOINT View_Point;
   int Screen_Height, Screen_Width;
   OBJECT *Light_Sources;
   OBJECT *Objects;
   DBL Atmosphere_IOR, Antialias_Threshold;
   DBL Fog_Distance;
   COLOUR Fog_Colour;
   };


#define DISPLAY 1
#define VERBOSE 2
#define DISKWRITE 4
#define PROMPTEXIT 8
#define ANTIALIAS 16
#define DEBUGGING 32
#define RGBSEPARATE 64
#define TARGA 128
#define EXITENABLE 256

#define Make_Colour(c,r,g,b) { (c)->Red=(r);(c)->Green=(g);(c)->Blue=(b); (c)->Alpha=0.0; }

#define Make_Vector(v,a,b,c) { (v)->x=(a);(v)->y=(b);(v)->z=(c); }

/* Definitions for PRIOQ structure */

struct q_entry
   {
   DBL Depth;
   OBJECT *Object;
   VECTOR Point;
   SHAPE *Shape;
   };

struct prioq_struct
   {
   struct prioq_struct *next_pq;
   struct q_entry *queue;
   unsigned int current_entry, queue_size;
   };


/* Token Definitions for Parser */

enum Token_Type
   {
   AGATE_TOKEN,
   ALPHA_TOKEN,
   AMBIENT_TOKEN,
   AMPERSAND_TOKEN,
   AT_TOKEN,
   BACK_QUOTE_TOKEN,
   BACK_SLASH_TOKEN,
   BAR_TOKEN,
   BLUE_TOKEN,
   BRILLIANCE_TOKEN,
   BOZO_TOKEN,
   BOUNDED_TOKEN,
   BUMPS_TOKEN,
   CHECKER_TOKEN,
   COLON_TOKEN,
   COLOR_TOKEN,
   COLOUR_TOKEN,
   COLOR_MAP_TOKEN,
   COLOUR_MAP_TOKEN,
   COMMA_TOKEN,
   COMPOSITE_TOKEN,
   DASH_TOKEN,
   DECLARE_TOKEN,
   DENTS_TOKEN,
   DIFFERENCE_TOKEN,
   DIFFUSE_TOKEN,
   DIRECTION_TOKEN,
   DOLLAR_TOKEN,
   END_BOUNDED_TOKEN,
   END_COLOR_MAP_TOKEN,
   END_COLOUR_MAP_TOKEN,
   END_COMPOSITE_TOKEN,
   END_DIFFERENCE_TOKEN,
   END_FOG_TOKEN,
   END_INTERSECTION_TOKEN,
   END_OBJECT_TOKEN,
   END_OF_FILE_TOKEN,
   END_PLANE_TOKEN,
   END_POINTS_TOKEN,
   END_POLYGON_TOKEN,
   END_QUADRIC_TOKEN,
   END_SHAPE_TOKEN,
   END_SPHERE_TOKEN,
   END_TEXTURE_TOKEN,
   END_TRIANGLE_TOKEN,
   END_UNION_TOKEN,
   END_VIEW_POINT_TOKEN,
   EQUALS_TOKEN,
   EXCLAMATION_TOKEN,
   FLOAT_TOKEN,
   FOG_TOKEN,
   FREQUENCY_TOKEN,
   GIF_TOKEN,
   GRADIENT_TOKEN,
   GRANITE_TOKEN,
   GREEN_TOKEN,
   HASH_TOKEN,
   HAT_TOKEN,
   IDENTIFIER_TOKEN,
   IFF_TOKEN,
   IMAGEMAP_TOKEN,
   INCLUDE_TOKEN,
   INTERSECTION_TOKEN,
   INVERSE_TOKEN,
   IOR_TOKEN,
   LEFT_ANGLE_TOKEN,
   LEFT_BRACKET_TOKEN,
   LEFT_SQUARE_TOKEN,
   LIGHT_SOURCE_TOKEN,
   LOCATION_TOKEN,
   LOOK_AT_TOKEN,
   MARBLE_TOKEN,
   OBJECT_TOKEN,
   ONCE_TOKEN,
   PERCENT_TOKEN,
   PHASE_TOKEN,
   PHONG_TOKEN,
   PHONGSIZE_TOKEN,
   PLANE_TOKEN,
   PLUS_TOKEN,
   POINTS_TOKEN,
   POLYGON_TOKEN,
   QUADRIC_TOKEN,
   QUESTION_TOKEN,
   RAW_TOKEN,
   RED_TOKEN,
   REFLECTION_TOKEN,
   REFRACTION_TOKEN,
   REVOLVE_TOKEN,
   RIGHT_TOKEN,
   RIGHT_ANGLE_TOKEN,
   RIGHT_BRACKET_TOKEN,
   RIGHT_SQUARE_TOKEN,
   RIPPLES_TOKEN,
   ROTATE_TOKEN,
   ROUGHNESS_TOKEN,
   SCALE_TOKEN,
   SEMI_COLON_TOKEN,
   SHAPE_TOKEN,
   SINGLE_QUOTE_TOKEN,
   SIZE_TOKEN,
   SKY_TOKEN,
   SLASH_TOKEN,
   SMOOTH_TRIANGLE_TOKEN,
   SPECULAR_TOKEN,
   SPHERE_TOKEN,
   SPOTTED_TOKEN,
   STAR_TOKEN,
   STRING_TOKEN,
   TEXTURE_TOKEN,
   TILDE_TOKEN,
   TRANSLATE_TOKEN,
   TRIANGLE_TOKEN,
   TURBULENCE_TOKEN,
   UNION_TOKEN,
   UP_TOKEN,
   VIEW_POINT_TOKEN,
   WAVES_TOKEN,
   WOOD_TOKEN,
   WRINKLES_TOKEN,
   LAST_TOKEN };


struct Reserved_Word_Struct
   {
   TOKEN Token_Number;
   char *Token_Name;
   };

/* Here's where you dump the information on the current token (fm. PARSE.C) */

struct Token_Struct
   {
   TOKEN Token_Id;
   int Token_Line_No;
   char Token_String[FILE_NAME_LENGTH];
   DBL Token_Float;
   int Identifier_Number;
   int Unget_Token, End_Of_File;
   };

/* Types of constants allowed in DECLARE statement (fm. PARSE.C) */

enum Constant_Type
   {
   OBJECT_CONSTANT,
   VIEW_POINT_CONSTANT,
   VECTOR_CONSTANT,
   FLOAT_CONSTANT,
   COLOUR_CONSTANT,
   QUADRIC_CONSTANT,
   SPHERE_CONSTANT,
   PLANE_CONSTANT,
   TRIANGLE_CONSTANT,
   SMOOTH_TRIANGLE_CONSTANT,
   CSG_INTERSECTION_CONSTANT,
   CSG_UNION_CONSTANT,
   CSG_DIFFERENCE_CONSTANT,
   COMPOSITE_CONSTANT,
   TEXTURE_CONSTANT
   };


struct Constant_Struct
   {
   int Identifier_Number;
   CONSTANT Constant_Type;
   char *Constant_Data;
   };

/* Types for reading IFF files. */
typedef struct {
   unsigned short Red, Green, Blue;
   } IMAGE_COLOUR;

struct Chunk_Header_Struct {
   long name;
   long size;
   };
