[comp.sources.amiga] v90i253: DKBTrace 2.01 - DKBtrace Ray-Tracer, Part05/10

amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (09/04/90)

Submitted-by: David Schanen <mtv@milton.u.washington.edu>
Posting-number: Volume 90, Issue 253
Archive-name: applications/dkbtrace-2.01/part05

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 5 (of 10)."
# Contents:  src/frame.h src/gifdecod.c src/render.c src/trace.c
# Wrapped by tadguy@abcfd20 on Mon Sep  3 19:21:19 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/frame.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/frame.h'\"
else
echo shar: Extracting \"'src/frame.h'\" \(14642 characters\)
sed "s/^X//" >'src/frame.h' <<'END_OF_FILE'
X/*****************************************************************************
X*
X*                                   frame.h
X*
X*   from DKBTrace (c) 1990  David Buck
X*
X*  This header file is included by all C modules in DKBTrace.  It defines all
X*  globally-accessible types and constants.
X*
X* This software is freely distributable. The source and/or object code may be
X* copied or uploaded to communications services so long as this notice remains
X* at the top of each file.  If any changes are made to the program, you must
X* clearly indicate in the documentation and in the programs startup message
X* who it was who made the changes. The documentation should also describe what
X* those changes were. This software may not be included in whole or in
X* part into any commercial package without the express written consent of the
X* author.  It may, however, be included in other public domain or freely
X* distributed software so long as the proper credit for the software is given.
X*
X* This software is provided as is without any guarantees or warranty. Although
X* the author has attempted to find and correct any bugs in the software, he
X* is not responsible for any damage caused by the use of the software.  The
X* author is under no obligation to provide service, corrections, or upgrades
X* to this package.
X*
X* Despite all the legal stuff above, if you do find bugs, I would like to hear
X* about them.  Also, if you have any comments or questions, you may contact me
X* at the following address:
X*
X*     David Buck
X*     22C Sonnet Cres.
X*     Nepean Ontario
X*     Canada, K2H 8W7
X*
X*  I can also be reached on the following bulleton boards:
X*
X*     ATX              (613) 526-4141
X*     OMX              (613) 731-3419
X*     Mystic           (613) 731-0088 or (613) 731-6698
X*
X*  Fidonet:   1:163/109.9
X*  Internet:  David_Buck@Carleton.CA
X*
X*  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
X*
X*     Lattice BBS                      (708) 916-1200
X*     The Information Exchange BBS     (708) 945-5575
X*     Stillwaters BBS                  (708) 403-2826
X*
X*****************************************************************************/
X
X
X/* Generic header for all modules */
X
X#include "config.h"
X#include <stdio.h>
X#include <string.h>
X#include <math.h>
X
X#ifndef TRUE
X#define TRUE 1
X#define FALSE 0
X#endif
X
X#ifndef FILE_NAME_LENGTH
X#define FILE_NAME_LENGTH 150
X#endif
X
X#ifndef DBL
X#define DBL double
X#endif
X
X#ifndef HUGE_VAL
X#define HUGE_VAL 1.0e+17
X#endif
X
X#ifndef DBL_FORMAT_STRING
X#define DBL_FORMAT_STRING "%lf"
X#endif
X
X#ifndef TEST_ABORT
X#define TEST_ABORT
X#endif
X
X/* These values determine the minumum and maximum distances
X   that qualify as ray-object intersections */
X#define Small_Tolerance 0.001
X#define Max_Distance 1.0e7
X
X/* Maximum gif bitmap size allowed. */
X#define BITMAP_X_SIZE 640
X#define BITMAP_Y_SIZE 480
X
Xtypedef struct q_entry INTERSECTION;
Xtypedef struct Vector_Struct VECTOR;
Xtypedef DBL MATRIX [4][4];
Xtypedef struct Colour_Struct COLOUR;
Xtypedef struct Colour_Map_Entry COLOUR_MAP_ENTRY;
Xtypedef struct Colour_Map_Struct COLOUR_MAP;
Xtypedef struct Transformation_Struct TRANSFORMATION;
Xtypedef struct Image_Struct IMAGE;
Xtypedef struct Texture_Struct TEXTURE;
Xtypedef struct Method_Struct METHODS;
Xtypedef struct Viewpoint_Struct VIEWPOINT;
Xtypedef struct Object_Shape SHAPE;
Xtypedef struct Object_Struct OBJECT;
Xtypedef struct Sphere_Shape SPHERE;
Xtypedef struct Quadric_Shape QUADRIC;
Xtypedef struct Triangle_Shape TRIANGLE;
Xtypedef struct Smooth_Triangle_Shape SMOOTH_TRIANGLE;
Xtypedef struct Plane_Shape PLANE;
Xtypedef struct CSG_Type CSG_SHAPE;
Xtypedef struct Composite_Object_Struct COMPOSITE;
Xtypedef struct Ray_Struct RAY;
Xtypedef struct Frame_Struct FRAME;
Xtypedef struct prioq_struct PRIOQ;
Xtypedef enum Token_Type TOKEN;
Xtypedef enum Constant_Type CONSTANT;
Xtypedef struct Chunk_Header_Struct CHUNK_HEADER;
X
Xstruct Vector_Struct
X   {
X   DBL x, y, z;
X   };
X
X
X
Xstruct Colour_Struct
X   {
X   DBL Red, Green, Blue, Alpha;
X   };
X
X
Xstruct Colour_Map_Entry
X   {
X   DBL start, end;
X   COLOUR Start_Colour, End_Colour;
X   };
X
X
Xstruct Colour_Map_Struct
X   {
X   int Number_Of_Entries;
X   COLOUR_MAP_ENTRY *Colour_Map_Entries;
X   };
X
X
Xstruct Transformation_Struct
X   {
X   MATRIX matrix;
X   MATRIX inverse;
X   };
X
X
Xstruct Image_Struct
X   {
X   DBL width, height;
X   int iwidth, iheight;
X   unsigned char *red, *green, *blue;
X   };
X
X
Xenum Texture_Type { NO_TEXTURE, BOZO_TEXTURE, MARBLE_TEXTURE, WOOD_TEXTURE, CHECKER_TEXTURE, SPOTTED_TEXTURE, AGATE_TEXTURE, GRANITE_TEXTURE, GRADIENT_TEXTURE, IMAGEMAP_TEXTURE } ;
X
Xenum Bump_Type { NO_BUMPS, WAVES, RIPPLES, WRINKLES, BUMPS, DENTS };
X
Xstruct Texture_Struct
X   {
X   DBL Object_Reflection;
X   DBL Object_Ambient;
X   DBL Object_Diffuse, Object_Brilliance;
X   DBL Object_Index_Of_Refraction;
X   DBL Object_Refraction;
X   DBL Object_Specular, Object_Roughness;
X   DBL Object_Phong, Object_PhongSize;
X   DBL Bump_Amount;
X   DBL Texture_Randomness;
X   DBL Frequency;
X   DBL Phase;
X   enum Texture_Type Texture_Number ;
X   enum Bump_Type Bump_Number;
X   TRANSFORMATION *Texture_Transformation;
X   COLOUR Colour1;
X   COLOUR Colour2;
X   DBL Turbulence;
X   VECTOR Texture_Gradient;
X   COLOUR_MAP *Colour_Map;
X   IMAGE *Image;
X   short Once_Flag;
X   };
X
Xenum Object_Type {SPHERE_TYPE, TRIANGLE_TYPE, SMOOTH_TRIANGLE_TYPE, PLANE_TYPE,
X                  QUADRIC_TYPE, COMPOSITE_TYPE, OBJECT_TYPE,
X                  CSG_UNION_TYPE, CSG_INTERSECTION_TYPE, CSG_DIFFERENCE_TYPE,
X                  VIEWPOINT_TYPE };
X
Xstruct Object_Struct
X   {
X   METHODS *Methods;
X   enum Object_Type Type;
X   struct Object_Struct *Next_Object;
X   struct Object_Struct *Next_Light_Source;
X   SHAPE *Bounding_Shapes;
X   SHAPE *Shape;
X   char Light_Source_Flag;
X   char Transparency;
X   VECTOR  Object_Center;
X   COLOUR Object_Colour;
X   TEXTURE *Object_Texture;
X   };
X
X
Xtypedef INTERSECTION *(*INTERSECTION_METHOD)PARAMS((OBJECT *, RAY *));
Xtypedef int (*ALL_INTERSECTIONS_METHOD)PARAMS((OBJECT *, RAY *, PRIOQ *));
Xtypedef int (*INSIDE_METHOD)PARAMS((VECTOR *, OBJECT *));
Xtypedef void (*NORMAL_METHOD)PARAMS((VECTOR *, OBJECT *, VECTOR *));
Xtypedef void *(*COPY_METHOD)PARAMS((OBJECT *));
Xtypedef void (*TRANSLATE_METHOD)PARAMS((OBJECT *, VECTOR *));
Xtypedef void (*ROTATE_METHOD)PARAMS((OBJECT *, VECTOR *));
Xtypedef void (*SCALE_METHOD)PARAMS((OBJECT *, VECTOR *));
Xtypedef void (*INVERT_METHOD)PARAMS((OBJECT *));
X
Xstruct Method_Struct
X   {
X   INTERSECTION_METHOD Intersection_Method;
X   ALL_INTERSECTIONS_METHOD All_Intersections_Method;
X   INSIDE_METHOD Inside_Method;
X   NORMAL_METHOD Normal_Method;
X   COPY_METHOD Copy_Method;
X   TRANSLATE_METHOD Translate_Method;
X   ROTATE_METHOD Rotate_Method;
X   SCALE_METHOD Scale_Method;
X   INVERT_METHOD Invert_Method;
X   };
X
X
X#define All_Intersections(x,y,z) ((*((x)->Methods->All_Intersections_Method)) (x,y,z))
X#define Intersection(x,y) ((*((x)->Methods->Intersection_Method)) (x,y))
X#define Inside(x,y) ((*((y)->Methods->Inside_Method)) (x,y))
X#define Normal(x,y,z) ((*((y)->Methods->Normal_Method)) (x,y,z))
X#define Copy(x) ((*((x)->Methods->Copy_Method)) (x))
X#define Translate(x,y) ((*((x)->Methods->Translate_Method)) (x,y))
X#define Scale(x,y) ((*((x)->Methods->Scale_Method)) (x,y))
X#define Rotate(x,y) ((*((x)->Methods->Rotate_Method)) (x,y))
X#define Invert(x) ((*((x)->Methods->Invert_Method)) (x))
X
Xstruct Viewpoint_Struct
X   {
X   METHODS *Methods;
X   enum Object_Type Type;
X   VECTOR Location;
X   VECTOR Direction;
X   VECTOR Up;
X   VECTOR Right;
X   VECTOR Sky;
X   };
X
X
Xstruct Object_Shape
X   {
X   METHODS *Methods;
X   enum Object_Type Type;
X   struct Object_Shape *Next_Object;
X   void *Parent_Object;
X   };
X
X
Xstruct Sphere_Shape
X   {
X   METHODS *Methods;
X   enum Object_Type Type;
X   SHAPE *Next_Object;
X   OBJECT *Parent_Object;
X   VECTOR  Center;
X   DBL     Radius;
X   DBL     Radius_Squared;
X   DBL     Inverse_Radius;
X   VECTOR  VPOtoC;
X   DBL     VPOCSquared;
X   short   VPinside, VPCached, Inverted;
X   };
X
X
Xstruct Quadric_Shape
X   {
X   METHODS *Methods;
X   enum Object_Type Type;
X   SHAPE *Next_Object;
X   OBJECT *Parent_Object;
X   VECTOR  Object_2_Terms;
X   VECTOR  Object_Mixed_Terms;
X   VECTOR  Object_Terms;
X   DBL Object_Constant;
X   DBL Object_VP_Constant;
X   int Constant_Cached;
X   int Non_Zero_Square_Term;
X   };
X
X
X#define X_AXIS 0
X#define Y_AXIS 1
X#define Z_AXIS 2
X
Xstruct Triangle_Shape
X   {
X   METHODS *Methods;
X   enum Object_Type Type;
X   SHAPE *Next_Object;
X   OBJECT *Parent_Object;
X   VECTOR  Normal_Vector;
X   DBL     Distance;
X   DBL     VPNormDotOrigin;
X   unsigned int  VPCached:1;
X   unsigned int  Dominant_Axis:2;
X   unsigned int  Inverted:1;
X   unsigned int  vAxis:2;         /* used only for smooth triangles */
X   VECTOR  P1, P2, P3;
X   };
X
X
Xstruct Smooth_Triangle_Shape
X   {
X   METHODS *Methods;
X   enum Object_Type Type;
X   SHAPE *Next_Object;
X   OBJECT *Parent_Object;
X   VECTOR  Normal_Vector;
X   DBL     Distance;
X   DBL     VPNormDotOrigin;
X   unsigned int  VPCached:1;
X   unsigned int  Dominant_Axis:2;
X   unsigned int  Inverted:1;
X   unsigned int  vAxis:2;         /* used only for smooth triangles */
X   VECTOR  P1, P2, P3;
X   VECTOR  N1, DN12, DN13, Perp;
X   DBL  BaseDelta;
X   };
X
X
X
Xstruct Plane_Shape
X   {
X   METHODS *Methods;
X   enum Object_Type Type;
X   SHAPE *Next_Object;
X   OBJECT *Parent_Object;
X   VECTOR  Normal_Vector;
X   DBL     Distance;
X   DBL     VPNormDotOrigin;
X   int     VPCached;
X   };
X
X
Xstruct CSG_Type
X   {
X   METHODS *Methods;
X   enum Object_Type Type;
X   SHAPE *Next_Object;
X   OBJECT *Parent_Object;
X   SHAPE *Shapes;
X   };
X   
X
Xstruct Composite_Object_Struct
X   {
X   METHODS *Methods;
X   enum Object_Type Type;
X   OBJECT *Next_Object;
X   OBJECT *Next_Light_Source;
X   SHAPE *Bounding_Shapes;
X   OBJECT *Objects;
X   };
X
X
X#define MAX_CONTAINING_OBJECTS 5
X
Xstruct Ray_Struct
X   {
X   VECTOR Initial;               /*  Xo  Yo  Zo  */
X   VECTOR Direction;             /*  Xv  Yv  Zv  */
X   VECTOR Initial_2;             /*  Xo^2  Yo^2  Zo^2  */
X   VECTOR Direction_2;           /*  Xv^2  Yv^2  Zv^2  */
X   VECTOR Initial_Direction;     /*  XoXv  YoYv  ZoZv  */
X   VECTOR Mixed_Initial_Initial; /*  XoYo  XoZo  YoZo  */
X   VECTOR Mixed_Dir_Dir;         /*  XvYv  XvZv  YvZv  */
X   VECTOR Mixed_Init_Dir;        /*  XoYv+XvYo  XoZv+XvZo  YoZv+YvZo  */
X   int Containing_Index;
X   OBJECT *Containing_Objects [MAX_CONTAINING_OBJECTS];
X   DBL Containing_IORs [MAX_CONTAINING_OBJECTS];
X   int Quadric_Constants_Cached;
X   };
X
X
Xstruct Frame_Struct
X   {
X   VIEWPOINT View_Point;
X   int Screen_Height, Screen_Width;
X   OBJECT *Light_Sources;
X   OBJECT *Objects;
X   DBL Atmosphere_IOR, Antialias_Threshold;
X   DBL Fog_Distance;
X   COLOUR Fog_Colour;
X   };
X
X
X#define DISPLAY 1
X#define VERBOSE 2
X#define DISKWRITE 4
X#define PROMPTEXIT 8
X#define ANTIALIAS 16
X#define DEBUGGING 32
X#define RGBSEPARATE 64
X#define TARGA 128
X#define EXITENABLE 256
X
X#define Make_Colour(c,r,g,b) { (c)->Red=(r);(c)->Green=(g);(c)->Blue=(b); (c)->Alpha=0.0; }
X
X#define Make_Vector(v,a,b,c) { (v)->x=(a);(v)->y=(b);(v)->z=(c); }
X
X/* Definitions for PRIOQ structure */
X
Xstruct q_entry
X   {
X   DBL Depth;
X   OBJECT *Object;
X   VECTOR Point;
X   SHAPE *Shape;
X   };
X
Xstruct prioq_struct
X   {
X   struct prioq_struct *next_pq;
X   struct q_entry *queue;
X   unsigned int current_entry, queue_size;
X   };
X
X
X/* Token Definitions for Parser */
X
Xenum Token_Type
X   {
X   AGATE_TOKEN,
X   ALPHA_TOKEN,
X   AMBIENT_TOKEN,
X   AMPERSAND_TOKEN,
X   AT_TOKEN,
X   BACK_QUOTE_TOKEN,
X   BACK_SLASH_TOKEN,
X   BAR_TOKEN,
X   BLUE_TOKEN,
X   BRILLIANCE_TOKEN,
X   BOZO_TOKEN,
X   BOUNDED_TOKEN,
X   BUMPS_TOKEN,
X   CHECKER_TOKEN,
X   COLON_TOKEN,
X   COLOR_TOKEN,
X   COLOUR_TOKEN,
X   COLOR_MAP_TOKEN,
X   COLOUR_MAP_TOKEN,
X   COMMA_TOKEN,
X   COMPOSITE_TOKEN,
X   DASH_TOKEN,
X   DECLARE_TOKEN,
X   DENTS_TOKEN,
X   DIFFERENCE_TOKEN,
X   DIFFUSE_TOKEN,
X   DIRECTION_TOKEN,
X   DOLLAR_TOKEN,
X   END_BOUNDED_TOKEN,
X   END_COLOR_MAP_TOKEN,
X   END_COLOUR_MAP_TOKEN,
X   END_COMPOSITE_TOKEN,
X   END_DIFFERENCE_TOKEN,
X   END_FOG_TOKEN,
X   END_INTERSECTION_TOKEN,
X   END_OBJECT_TOKEN,
X   END_OF_FILE_TOKEN,
X   END_PLANE_TOKEN,
X   END_POINTS_TOKEN,
X   END_POLYGON_TOKEN,
X   END_QUADRIC_TOKEN,
X   END_SHAPE_TOKEN,
X   END_SPHERE_TOKEN,
X   END_TEXTURE_TOKEN,
X   END_TRIANGLE_TOKEN,
X   END_UNION_TOKEN,
X   END_VIEW_POINT_TOKEN,
X   EQUALS_TOKEN,
X   EXCLAMATION_TOKEN,
X   FLOAT_TOKEN,
X   FOG_TOKEN,
X   FREQUENCY_TOKEN,
X   GIF_TOKEN,
X   GRADIENT_TOKEN,
X   GRANITE_TOKEN,
X   GREEN_TOKEN,
X   HASH_TOKEN,
X   HAT_TOKEN,
X   IDENTIFIER_TOKEN,
X   IFF_TOKEN,
X   IMAGEMAP_TOKEN,
X   INCLUDE_TOKEN,
X   INTERSECTION_TOKEN,
X   INVERSE_TOKEN,
X   IOR_TOKEN,
X   LEFT_ANGLE_TOKEN,
X   LEFT_BRACKET_TOKEN,
X   LEFT_SQUARE_TOKEN,
X   LIGHT_SOURCE_TOKEN,
X   LOCATION_TOKEN,
X   LOOK_AT_TOKEN,
X   MARBLE_TOKEN,
X   OBJECT_TOKEN,
X   ONCE_TOKEN,
X   PERCENT_TOKEN,
X   PHASE_TOKEN,
X   PHONG_TOKEN,
X   PHONGSIZE_TOKEN,
X   PLANE_TOKEN,
X   PLUS_TOKEN,
X   POINTS_TOKEN,
X   POLYGON_TOKEN,
X   QUADRIC_TOKEN,
X   QUESTION_TOKEN,
X   RAW_TOKEN,
X   RED_TOKEN,
X   REFLECTION_TOKEN,
X   REFRACTION_TOKEN,
X   REVOLVE_TOKEN,
X   RIGHT_TOKEN,
X   RIGHT_ANGLE_TOKEN,
X   RIGHT_BRACKET_TOKEN,
X   RIGHT_SQUARE_TOKEN,
X   RIPPLES_TOKEN,
X   ROTATE_TOKEN,
X   ROUGHNESS_TOKEN,
X   SCALE_TOKEN,
X   SEMI_COLON_TOKEN,
X   SHAPE_TOKEN,
X   SINGLE_QUOTE_TOKEN,
X   SIZE_TOKEN,
X   SKY_TOKEN,
X   SLASH_TOKEN,
X   SMOOTH_TRIANGLE_TOKEN,
X   SPECULAR_TOKEN,
X   SPHERE_TOKEN,
X   SPOTTED_TOKEN,
X   STAR_TOKEN,
X   STRING_TOKEN,
X   TEXTURE_TOKEN,
X   TILDE_TOKEN,
X   TRANSLATE_TOKEN,
X   TRIANGLE_TOKEN,
X   TURBULENCE_TOKEN,
X   UNION_TOKEN,
X   UP_TOKEN,
X   VIEW_POINT_TOKEN,
X   WAVES_TOKEN,
X   WOOD_TOKEN,
X   WRINKLES_TOKEN,
X   LAST_TOKEN };
X
X
Xstruct Reserved_Word_Struct
X   {
X   TOKEN Token_Number;
X   char *Token_Name;
X   };
X
X/* Here's where you dump the information on the current token (fm. PARSE.C) */
X
Xstruct Token_Struct
X   {
X   TOKEN Token_Id;
X   int Token_Line_No;
X   char Token_String[FILE_NAME_LENGTH];
X   DBL Token_Float;
X   int Identifier_Number;
X   int Unget_Token, End_Of_File;
X   };
X
X/* Types of constants allowed in DECLARE statement (fm. PARSE.C) */
X
Xenum Constant_Type
X   {
X   OBJECT_CONSTANT,
X   VIEW_POINT_CONSTANT,
X   VECTOR_CONSTANT,
X   FLOAT_CONSTANT,
X   COLOUR_CONSTANT,
X   QUADRIC_CONSTANT,
X   SPHERE_CONSTANT,
X   PLANE_CONSTANT,
X   TRIANGLE_CONSTANT,
X   SMOOTH_TRIANGLE_CONSTANT,
X   CSG_INTERSECTION_CONSTANT,
X   CSG_UNION_CONSTANT,
X   CSG_DIFFERENCE_CONSTANT,
X   COMPOSITE_CONSTANT,
X   TEXTURE_CONSTANT
X   };
X
X
Xstruct Constant_Struct
X   {
X   int Identifier_Number;
X   CONSTANT Constant_Type;
X   char *Constant_Data;
X   };
X
X/* Types for reading IFF files. */
Xtypedef struct {
X   unsigned short Red, Green, Blue;
X   } IMAGE_COLOUR;
X
Xstruct Chunk_Header_Struct {
X   long name;
X   long size;
X   };
END_OF_FILE
if test 14642 -ne `wc -c <'src/frame.h'`; then
    echo shar: \"'src/frame.h'\" unpacked with wrong size!
fi
# end of 'src/frame.h'
fi
if test -f 'src/gifdecod.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/gifdecod.c'\"
else
echo shar: Extracting \"'src/gifdecod.c'\" \(15767 characters\)
sed "s/^X//" >'src/gifdecod.c' <<'END_OF_FILE'
X/*****************************************************************************
X*
X*                                   gifdecod.c
X*
X*   from DKBTrace (c) 1990  David Buck
X*
X* This software is freely distributable. The source and/or object code may be
X* copied or uploaded to communications services so long as this notice remains
X* at the top of each file.  If any changes are made to the program, you must
X* clearly indicate in the documentation and in the programs startup message
X* who it was who made the changes. The documentation should also describe what
X* those changes were. This software may not be included in whole or in
X* part into any commercial package without the express written consent of the
X* author.  It may, however, be included in other public domain or freely
X* distributed software so long as the proper credit for the software is given.
X*
X* This software is provided as is without any guarantees or warranty. Although
X* the author has attempted to find and correct any bugs in the software, he
X* is not responsible for any damage caused by the use of the software.  The
X* author is under no obligation to provide service, corrections, or upgrades
X* to this package.
X*
X* Despite all the legal stuff above, if you do find bugs, I would like to hear
X* about them.  Also, if you have any comments or questions, you may contact me
X* at the following address:
X*
X*     David Buck
X*     22C Sonnet Cres.
X*     Nepean Ontario
X*     Canada, K2H 8W7
X*
X*  I can also be reached on the following bulleton boards:
X*
X*     ATX              (613) 526-4141
X*     OMX              (613) 731-3419
X*     Mystic           (613) 731-0088 or (613) 731-6698
X*
X*  Fidonet:   1:163/109.9
X*  Internet:  David_Buck@Carleton.CA
X*
X*  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
X*
X*     Lattice BBS                      (708) 916-1200
X*     The Information Exchange BBS     (708) 945-5575
X*     Stillwaters BBS                  (708) 403-2826
X*
X*****************************************************************************/
X
X/*
X   This module was freely borrowed from FRACTINT, so here is their entire
X   copyright to keep them happy:
X*/
X
X/* DECODER.C - An LZW decoder for GIF
X * Copyright (C) 1987, by Steven A. Bennett
X *
X * Permission is given by the author to freely redistribute and include
X * this code in any program as long as this credit is given where due.
X *
X * In accordance with the above, I want to credit Steve Wilhite who wrote
X * the code which this is heavily inspired by...
X *
X * GIF and 'Graphics Interchange Format' are trademarks (tm) of
X * Compuserve, Incorporated, an H&R Block Company.
X *
X * Release Notes: This file contains a decoder routine for GIF images
X * which is similar, structurally, to the original routine by Steve Wilhite.
X * It is, however, somewhat noticably faster in most cases.
X *
X == This routine was modified for use in FRACTINT in two ways.
X == 
X == 1) The original #includes were folded into the routine strictly to hold
X ==    down the number of files we were dealing with.
X ==
X == 2) The 'stack', 'suffix', 'prefix', and 'buf' arrays were changed from
X ==    static and 'malloc()'ed to external only so that the assembler
X ==    program could use the same array space for several independent
X ==    chunks of code.  Also, 'stack' was renamed to 'dstack' for TASM
X ==    compatibility.
X == 
X == 3) The 'out_line()' external function has been changed to reference 
X ==    '*outln()' for flexibility (in particular, 3D transformations)
X ==
X == 4) A call to 'keypressed()' has been added after the 'outln()' calls
X ==    to check for the presenc of a key-press as a bail-out signal
X ==
X == (Bert Tyler and Timothy Wegner)
X*/
X
X/* 
X   This routine was modified for DKBtrace in the following ways:
X
X   1)  Removed calls to buzzer() and keypressed() to get rid of ASM files.
X
X   2)  The dstack, suffix, and prefix arrays were made STATIC once again.
X
X   3)  Added the usual ANSI function prototypes, etc. in the DKB headers.
X*/
X
X#include "frame.h"
X#include "dkbproto.h"
X
X#define LOCAL static
X#define IMPORT extern
X
X#define FAST register
X
Xtypedef short WORD;
Xtypedef unsigned short UWORD;
Xtypedef char TEXT;
Xtypedef unsigned char UTINY;
Xtypedef long LONG;
Xtypedef unsigned long ULONG;
Xtypedef int INT;
X
X
X/* Various error codes used by decoder
X * and my own routines...   It's okay
X * for you to define whatever you want,
X * as long as it's negative...  It will be
X * returned intact up the various subroutine
X * levels...
X */
X#define OUT_OF_MEMORY -10
X#define BAD_CODE_SIZE -20
X#define READ_ERROR -1
X#define WRITE_ERROR -2
X#define OPEN_ERROR -3
X#define CREATE_ERROR -4
X
X
X/* IMPORT INT get_byte()
X *
X *   - This external (machine specific) function is expected to return
X * either the next byte from the GIF file, or a negative number, as
X * defined in ERRS.H.
X */
XIMPORT INT get_byte();
X
X/* IMPORT INT out_line(pixels, linelen)
X *     UBYTE pixels[];
X *     INT linelen;
X *
X *   - This function takes a full line of pixels (one byte per pixel) and
X * displays them (or does whatever your program wants with them...).  It
X * should return zero, or negative if an error or some other event occurs
X * which would require aborting the decode process...  Note that the length
X * passed will almost always be equal to the line length passed to the
X * decoder function, with the sole exception occurring when an ending code
X * occurs in an odd place in the GIF file...  In any case, linelen will be
X * equal to the number of pixels passed...
X */
XIMPORT INT out_line();
X
X/* IMPORT INT bad_code_count;
X *
X * This value is the only other global required by the using program, and
X * is incremented each time an out of range code is read by the decoder.
X * When this value is non-zero after a decode, your GIF file is probably
X * corrupt in some way...
X */
XINT bad_code_count;
X
X#define NULL   0L
X#define MAX_CODES   4095
X
X/* Static variables */
XLOCAL WORD curr_size;                     /* The current code size */
XLOCAL WORD clear;                         /* Value for a clear code */
XLOCAL WORD ending;                        /* Value for a ending code */
XLOCAL WORD newcodes;                      /* First available code */
XLOCAL WORD top_slot;                      /* Highest code for current size */
XLOCAL WORD slot;                          /* Last read code */
X
X/* The following static variables are used
X * for seperating out codes
X */
XLOCAL WORD navail_bytes = 0;              /* # bytes left in block */
XLOCAL WORD nbits_left = 0;                /* # bits left in current byte */
XLOCAL UTINY b1;                           /* Current byte */
XLOCAL UTINY byte_buff[257];               /* Current block */
XLOCAL UTINY *pbytes;                      /* Pointer to next byte in block */
X
XLOCAL LONG code_mask[13] = {
X     0,
X     0x0001, 0x0003,
X     0x0007, 0x000F,
X     0x001F, 0x003F,
X     0x007F, 0x00FF,
X     0x01FF, 0x03FF,
X     0x07FF, 0x0FFF
X     };
X
X
X/* This function initializes the decoder for reading a new image.
X */
XLOCAL WORD init_exp(size)
X   WORD size;
X   {
X   curr_size = size + 1;
X   top_slot = 1 << curr_size;
X   clear = 1 << size;
X   ending = clear + 1;
X   slot = newcodes = ending + 1;
X   navail_bytes = nbits_left = 0;
X   return(0);
X   }
X
X/* get_next_code()
X * - gets the next code from the GIF file.  Returns the code, or else
X * a negative number in case of file errors...
X */
XLOCAL WORD get_next_code()
X   {
X   WORD i, x;
X   ULONG ret;
X
X   if (nbits_left == 0)
X      {
X      if (navail_bytes <= 0)
X         {
X
X         /* Out of bytes in current block, so read next block
X          */
X         pbytes = byte_buff;
X         if ((navail_bytes = get_byte()) < 0)
X            return(navail_bytes);
X         else if (navail_bytes)
X            {
X            for (i = 0; i < navail_bytes; ++i)
X               {
X               if ((x = get_byte()) < 0)
X                  return(x);
X               byte_buff[i] = x;
X               }
X            }
X         }
X      b1 = *pbytes++;
X      nbits_left = 8;
X      --navail_bytes;
X      }
X
X   ret = b1 >> (8 - nbits_left);
X   while (curr_size > nbits_left)
X      {
X      if (navail_bytes <= 0)
X         {
X
X         /* Out of bytes in current block, so read next block
X          */
X         pbytes = byte_buff;
X         if ((navail_bytes = get_byte()) < 0)
X            return(navail_bytes);
X         else if (navail_bytes)
X            {
X            for (i = 0; i < navail_bytes; ++i)
X               {
X               if ((x = get_byte()) < 0)
X                  return(x);
X               byte_buff[i] = x;
X               }
X            }
X         }
X      b1 = *pbytes++;
X      ret |= b1 << nbits_left;
X      nbits_left += 8;
X      --navail_bytes;
X      }
X   nbits_left -= curr_size;
X   ret &= code_mask[curr_size];
X   return((WORD)(ret));
X   }
X
X
X/* The reason we have these seperated like this instead of using
X * a structure like the original Wilhite code did, is because this
X * stuff generally produces significantly faster code when compiled...
X * This code is full of similar speedups...  (For a good book on writing
X * C for speed or for space optomisation, see Efficient C by Tom Plum,
X * published by Plum-Hall Associates...)
X */
X
X/*
XI removed the LOCAL identifiers in the arrays below and replaced them
Xwith 'extern's so as to declare (and re-use) the space elsewhere.
XThe arrays are actually declared in the assembler source.
X                                                    Bert Tyler
X*/
X
XLOCAL UTINY dstack[MAX_CODES + 1];      /* Stack for storing pixels */
XLOCAL UTINY suffix[MAX_CODES + 1];      /* Suffix table */
XLOCAL UWORD prefix[MAX_CODES + 1];      /* Prefix linked list */
Xextern UTINY *decoderline;              /* decoded line goes here */
X
X/* WORD decoder(linewidth)
X *    WORD linewidth;               * Pixels per line of image *
X *
X * - This function decodes an LZW image, according to the method used
X * in the GIF spec.  Every *linewidth* "characters" (ie. pixels) decoded
X * will generate a call to out_line(), which is a user specific function
X * to display a line of pixels.  The function gets its codes from
X * get_next_code() which is responsible for reading blocks of data and
X * seperating them into the proper size codes.  Finally, get_byte() is
X * the global routine to read the next byte from the GIF file.
X *
X * It is generally a good idea to have linewidth correspond to the actual
X * width of a line (as specified in the Image header) to make your own
X * code a bit simpler, but it isn't absolutely necessary.
X *
X * Returns: 0 if successful, else negative.  (See ERRS.H)
X *
X */
X
XWORD decoder(linewidth)
X   WORD linewidth;
X   {
X   FAST UTINY *sp, *bufptr;
X   UTINY *buf;
X   FAST WORD code, fc, oc, bufcnt;
X   WORD c, size, ret;
X
X   /* Initialize for decoding a new image...
X    */
X   if ((size = get_byte()) < 0)
X      return(size);
X   if (size < 2 || 9 < size)
X      return(BAD_CODE_SIZE);
X   init_exp(size);
X
X   /* Initialize in case they forgot to put in a clear code.
X    * (This shouldn't happen, but we'll try and decode it anyway...)
X    */
X   oc = fc = 0;
X
X   buf = decoderline;
X
X   /* Set up the stack pointer and decode buffer pointer
X    */
X   sp = dstack;
X   bufptr = buf;
X   bufcnt = linewidth;
X
X   /* This is the main loop.  For each code we get we pass through the
X    * linked list of prefix codes, pushing the corresponding "character" for
X    * each code onto the stack.  When the list reaches a single "character"
X    * we push that on the stack too, and then start unstacking each
X    * character for output in the correct order.  Special handling is
X    * included for the clear code, and the whole thing ends when we get
X    * an ending code.
X    */
X   while ((c = get_next_code()) != ending)
X      {
X
X      /* If we had a file error, return without completing the decode
X       */
X      if (c < 0)
X         return(0);
X
X      /* If the code is a clear code, reinitialize all necessary items.
X       */
X      if (c == clear)
X         {
X         curr_size = size + 1;
X         slot = newcodes;
X         top_slot = 1 << curr_size;
X
X         /* Continue reading codes until we get a non-clear code
X          * (Another unlikely, but possible case...)
X          */
X         while ((c = get_next_code()) == clear)
X            ;
X
X         /* If we get an ending code immediately after a clear code
X          * (Yet another unlikely case), then break out of the loop.
X          */
X         if (c == ending)
X            break;
X
X         /* Finally, if the code is beyond the range of already set codes,
X          * (This one had better NOT happen...  I have no idea what will
X          * result from this, but I doubt it will look good...) then set it
X          * to color zero.
X          */
X         if (c >= slot)
X            c = 0;
X
X         oc = fc = c;
X
X         /* And let us not forget to put the char into the buffer... And
X          * if, on the off chance, we were exactly one pixel from the end
X          * of the line, we have to send the buffer to the out_line()
X          * routine...
X          */
X         *bufptr++ = c;
X         if (--bufcnt == 0)
X            {
X            if ((ret = out_line(buf, linewidth)) < 0)
X               return(ret);
X            bufptr = buf;
X            bufcnt = linewidth;
X            }
X         }
X      else
X         {
X
X         /* In this case, it's not a clear code or an ending code, so
X          * it must be a code code...  So we can now decode the code into
X          * a stack of character codes. (Clear as mud, right?)
X          */
X         code = c;
X
X         /* Here we go again with one of those off chances...  If, on the
X          * off chance, the code we got is beyond the range of those already
X          * set up (Another thing which had better NOT happen...) we trick
X          * the decoder into thinking it actually got the last code read.
X          * (Hmmn... I'm not sure why this works...  But it does...)
X          */
X         if (code >= slot)
X            {
X            if (code > slot)
X               ++bad_code_count;
X            code = oc;
X            *sp++ = fc;
X            }
X
X         /* Here we scan back along the linked list of prefixes, pushing
X          * helpless characters (ie. suffixes) onto the stack as we do so.
X          */
X         while (code >= newcodes)
X            {
X            *sp++ = suffix[code];
X            code = prefix[code];
X            }
X
X         /* Push the last character on the stack, and set up the new
X          * prefix and suffix, and if the required slot number is greater
X          * than that allowed by the current bit size, increase the bit
X          * size.  (NOTE - If we are all full, we *don't* save the new
X          * suffix and prefix...  I'm not certain if this is correct...
X          * it might be more proper to overwrite the last code...
X          */
X         *sp++ = code;
X         if (slot < top_slot)
X            {
X            suffix[slot] = fc = code;
X            prefix[slot++] = oc;
X            oc = c;
X            }
X         if (slot >= top_slot)
X            if (curr_size < 12)
X               {
X               top_slot <<= 1;
X               ++curr_size;
X               }
X
X         /* Now that we've pushed the decoded string (in reverse order)
X          * onto the stack, lets pop it off and put it into our decode
X          * buffer...  And when the decode buffer is full, write another
X          * line...
X          */
X         while (sp > dstack)
X            {
X            *bufptr++ = *(--sp);
X            if (--bufcnt == 0)
X               {
X               if ((ret = out_line(buf, linewidth)) < 0)
X                  return(ret);
X               bufptr = buf;
X               bufcnt = linewidth;
X               }
X            }
X         }
X      }
X   ret = 0;
X   if (bufcnt != linewidth)
X      ret = out_line(buf, (linewidth - bufcnt));
X   return(ret);
X   }
END_OF_FILE
if test 15767 -ne `wc -c <'src/gifdecod.c'`; then
    echo shar: \"'src/gifdecod.c'\" unpacked with wrong size!
fi
# end of 'src/gifdecod.c'
fi
if test -f 'src/render.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/render.c'\"
else
echo shar: Extracting \"'src/render.c'\" \(16452 characters\)
sed "s/^X//" >'src/render.c' <<'END_OF_FILE'
X/*****************************************************************************
X*
X*                                    render.c
X*
X*   from DKBTrace (c) 1990  David Buck
X*
X*  This module implements the main raytracing loop.
X*
X* This software is freely distributable. The source and/or object code may be
X* copied or uploaded to communications services so long as this notice remains
X* at the top of each file.  If any changes are made to the program, you must
X* clearly indicate in the documentation and in the programs startup message
X* who it was who made the changes. The documentation should also describe what
X* those changes were. This software may not be included in whole or in
X* part into any commercial package without the express written consent of the
X* author.  It may, however, be included in other public domain or freely
X* distributed software so long as the proper credit for the software is given.
X*
X* This software is provided as is without any guarantees or warranty. Although
X* the author has attempted to find and correct any bugs in the software, he
X* is not responsible for any damage caused by the use of the software.  The
X* author is under no obligation to provide service, corrections, or upgrades
X* to this package.
X*
X* Despite all the legal stuff above, if you do find bugs, I would like to hear
X* about them.  Also, if you have any comments or questions, you may contact me
X* at the following address:
X*
X*     David Buck
X*     22C Sonnet Cres.
X*     Nepean Ontario
X*     Canada, K2H 8W7
X*
X*  I can also be reached on the following bulleton boards:
X*
X*     ATX              (613) 526-4141
X*     OMX              (613) 731-3419
X*     Mystic           (613) 731-0088 or (613) 731-6698
X*
X*  Fidonet:   1:163/109.9
X*  Internet:  David_Buck@Carleton.CA
X*
X*  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
X*
X*     Lattice BBS                      (708) 916-1200
X*     The Information Exchange BBS     (708) 945-5575
X*     Stillwaters BBS                  (708) 403-2826
X*
X*****************************************************************************/
X
X
X#include "frame.h"
X#include "vector.h"
X#include "dkbproto.h"
X
Xextern FILE *bfp;
Xextern char Output_File_Name[30];
Xextern int File_Buffer_Size;
Xextern unsigned long Options;
Xextern int Quality;
Xvolatile int Stop_Flag;
Xextern int First_Line, Last_Line;
Xextern long Number_Of_Pixels, Number_Of_Rays, Number_Of_Pixels_Supersampled;
X
Xextern short *hashTable;
Xextern unsigned short crctab[256];
X#define rand3d(a,b) crctab[(int)(hashTable[(int)(hashTable[(int)((a)&0xfff)]^(b))&0xfff])&0xff]
X
XFRAME Frame;
XRAY *VP_Ray;
Xint Trace_Level;
X
X#define MAX_TRACE_LEVEL 5
X
Xvoid Create_Ray (ray, width, height, x, y)
X   RAY *ray;
X   int width, height;
X   DBL x, y;
X   {
X   register DBL X_Scalar, Y_Scalar;
X   VECTOR Temp_Vect_1, Temp_Vect_2;
X
X   /* Convert the X Coordinate to be a DBL from 0.0 to 1.0 */
X   X_Scalar = (x - (DBL) width / 2.0) / (DBL) width;
X
X   /* Convert the Y Coordinate to be a DBL from 0.0 to 1.0 */
X   Y_Scalar = (( (DBL)(Frame.Screen_Height - 1) - y) -
X	      (DBL) height / 2.0) / (DBL) height;
X
X   VScale (Temp_Vect_1, Frame.View_Point.Up, Y_Scalar);
X   VScale (Temp_Vect_2, Frame.View_Point.Right, X_Scalar);
X   VAdd (ray->Direction, Temp_Vect_1, Temp_Vect_2);
X   VAdd (ray->Direction, ray->Direction, Frame.View_Point.Direction);
X   VNormalize (ray->Direction, ray->Direction);
X   Initialize_Ray_Containers (ray);
X   ray->Quadric_Constants_Cached = FALSE;
X   }
X
Xvoid Write_Line (Line, y)
X   COLOUR *Line;
X   int y;
X   {
X   char Red, Green, Blue, temp[2];
X   register int x;
X
X   if (!(Options & TARGA))	/* Write out line in DKB/QRT RAW format */
X      {
X      temp[0] = y % 256;
X      putc (temp[0], bfp);
X      temp[0] = y / 256;
X      putc (temp[0], bfp);
X
X      for (x = 0 ; x < Frame.Screen_Width ; x++) {
X         Red = (char) floor (Line[x].Red * 255.0);
X         putc (Red, bfp);
X         }
X
X      for (x = 0 ; x < Frame.Screen_Width ; x++) {
X         Green = (char) floor (Line[x].Green * 255.0);
X         putc (Green, bfp);
X         }
X
X      for (x = 0 ; x < Frame.Screen_Width ; x++) {
X         Blue = (char) floor (Line[x].Blue * 255.0);
X         putc (Blue, bfp);
X         }
X      }
X   else       /* write out TrueVision Targa 24 format file */
X      {
X      for (x = 0; x < Frame.Screen_Width; x++) {
X         putc((char) floor (Line[x].Blue * 255.0), bfp);
X         putc((char) floor (Line[x].Green * 255.0), bfp);
X         putc((char) floor (Line[x].Red * 255.0), bfp);
X         }
X      }
X
X   if (File_Buffer_Size == 0) {
X      fflush(bfp);				       /* close and reopen file for */
X      bfp = freopen(Output_File_Name, "ab", bfp); /* integrity in case we crash*/
X      }
X   }
X
Xvoid Supersample (result, x, y, Width, Height)
X   COLOUR *result;
X   int x, y, Width, Height;
X   {
X   COLOUR colour;
X   register DBL dx, dy, Jitter_X, Jitter_Y;
X
X   dx = (DBL) x;
X   dy = (DBL) y;
X
X   Number_Of_Pixels_Supersampled++;
X
X   Make_Colour (result, 0.0, 0.0, 0.0);
X
X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Create_Ray (VP_Ray, Frame.Screen_Width, Frame.Screen_Height,
X	         dx + Jitter_X, dy + Jitter_Y);
X
X   Trace_Level = 0;
X   Trace (VP_Ray, &colour);
X   Clip_Colour (&colour, &colour);
X   Scale_Colour (&colour, &colour, 0.11111111);
X   Add_Colour (result, result, &colour);
X
X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X - 0.3333333,
X                                      dy + Jitter_Y - 0.3333333);
X   Trace_Level = 0;
X   Trace (VP_Ray, &colour);
X   Clip_Colour (&colour, &colour);
X   Scale_Colour (&colour, &colour, 0.11111111);
X   Add_Colour (result, result, &colour);
X
X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X - 0.3333333,
X                                      dy + Jitter_Y);
X   Trace_Level = 0;
X   Trace (VP_Ray, &colour);
X   Clip_Colour (&colour, &colour);
X   Scale_Colour (&colour, &colour, 0.11111111);
X   Add_Colour (result, result, &colour);
X
X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X - 0.3333333,
X                                      dy + Jitter_Y + 0.3333333);
X   Trace_Level = 0;
X   Trace (VP_Ray, &colour);
X   Clip_Colour (&colour, &colour);
X   Scale_Colour (&colour, &colour, 0.11111111);
X   Add_Colour (result, result, &colour);
X
X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X,
X                                      dy + Jitter_Y - 0.3333333);
X   Trace_Level = 0;
X   Trace (VP_Ray, &colour);
X   Clip_Colour (&colour, &colour);
X   Scale_Colour (&colour, &colour, 0.11111111);
X   Add_Colour (result, result, &colour);
X
X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X,
X                                      dy + Jitter_Y + 0.3333333);
X   Trace_Level = 0;
X   Trace (VP_Ray, &colour);
X   Clip_Colour (&colour, &colour);
X   Scale_Colour (&colour, &colour, 0.11111111);
X   Add_Colour (result, result, &colour);
X
X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X + 0.3333333,
X                                      dy + Jitter_Y - 0.3333333);
X   Trace_Level = 0;
X   Trace (VP_Ray, &colour);
X   Clip_Colour (&colour, &colour);
X   Scale_Colour (&colour, &colour, 0.11111111);
X   Add_Colour (result, result, &colour);
X
X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X + 0.3333333,
X                                      dy + Jitter_Y);
X   Trace_Level = 0;
X   Trace (VP_Ray, &colour);
X   Clip_Colour (&colour, &colour);
X   Scale_Colour (&colour, &colour, 0.11111111);
X   Add_Colour (result, result, &colour);
X
X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X + 0.3333333,
X                                      dy + Jitter_Y + 0.3333333);
X   Trace_Level = 0;
X   Trace (VP_Ray, &colour);
X   Clip_Colour (&colour, &colour);
X   Scale_Colour (&colour, &colour, 0.11111111);
X   Add_Colour (result, result, &colour);
X   }
X
Xvoid Start_Tracing ()
X   {
X   COLOUR Colour;
X   RAY Ray;
X   register int x, y, i, SuperSampleCount;
X   char Red, Green, Blue, Antialias_Center_Flag;
X   COLOUR *Previous_Line, *Current_Line, *Temp_Colour_Ptr;
X   char *Previous_Line_Antialiased_Flags, *Current_Line_Antialiased_Flags,
X        *Temp_Char_Ptr;
X
X
X   if (Options & VERBOSE) {
X       printf("Tracing...\n");
X       fflush (stdout);
X       }
X
X   VP_Ray = &Ray;
X
X   Previous_Line = (COLOUR *)   malloc (sizeof (COLOUR)*(Frame.Screen_Width + 1));
X   Current_Line = (COLOUR *) malloc (sizeof (COLOUR)*(Frame.Screen_Width + 1));
X
X   for (i = 0 ; i <= Frame.Screen_Width ; i++) {
X      Previous_Line[i].Red = 0.0;
X      Previous_Line[i].Green = 0.0;
X      Previous_Line[i].Blue = 0.0;
X
X      Current_Line[i].Red = 0.0;
X      Current_Line[i].Green = 0.0;
X      Current_Line[i].Blue = 0.0;
X      }
X
X   if (Options & ANTIALIAS) {
X      Previous_Line_Antialiased_Flags =
X          (char *) malloc (sizeof (char)*(Frame.Screen_Width + 1));
X      Current_Line_Antialiased_Flags =
X          (char *)  malloc (sizeof (char)*(Frame.Screen_Width + 1));
X
X      for (i = 0 ; i <= Frame.Screen_Width ; i++) {
X         Previous_Line_Antialiased_Flags[i] = 0;
X         Current_Line_Antialiased_Flags[i] = 0;
X         }
X      }
X
X   Ray.Initial = Frame.View_Point.Location;
X
X   for (y = (Options & ANTIALIAS)?First_Line-1:First_Line ; y<Last_Line ; y++) {
X
X      TEST_ABORT
X
X      if (Options & VERBOSE)
X         printf ("Line %3d", y);
X
X      if (Options & ANTIALIAS)
X         SuperSampleCount = 0;
X
X      for (x = 0 ; x < Frame.Screen_Width ; x++) {
X         Number_Of_Pixels++;
X         if (Stop_Flag) {
X            close_all();
X            exit(0);
X            }
X
X         Create_Ray (VP_Ray, Frame.Screen_Width, Frame.Screen_Height, (DBL) x, (DBL) y);
X         Trace_Level = 0;
X         Trace (&Ray, &Colour);
X         Clip_Colour (&Colour, &Colour);
X
X         Current_Line[x] = Colour;
X
X         if (Options & ANTIALIAS) {
X            Antialias_Center_Flag = 0;
X            Current_Line_Antialiased_Flags[x] = 0;
X
X            if (x != 0) {
X               if (Colour_Distance (&Current_Line[x-1], &Current_Line[x])
X                   >= Frame.Antialias_Threshold) {
X                  Antialias_Center_Flag = 1;
X                  if (!(Current_Line_Antialiased_Flags[x-1])) {
X                     Supersample (&Current_Line[x-1], 
X                                  x-1, y, Frame.Screen_Width, Frame.Screen_Height);
X                     Current_Line_Antialiased_Flags[x-1] = 1;
X                     SuperSampleCount++;
X                     }
X                  }
X               }
X
X            if (y != First_Line-1) {
X               if (Colour_Distance (&Previous_Line[x], &Current_Line[x])
X                    >= Frame.Antialias_Threshold) {
X                  Antialias_Center_Flag = 1;
X                  if (!(Previous_Line_Antialiased_Flags[x])) {
X                     Supersample (&Previous_Line[x],
X                                  x, y-1, Frame.Screen_Width, Frame.Screen_Height);
X                     Previous_Line_Antialiased_Flags[x] = 1;
X                     SuperSampleCount++;
X                     }
X                  }
X               }
X
X            if (Antialias_Center_Flag) {
X               Supersample (&Current_Line[x],
X                            x, y, Frame.Screen_Width, Frame.Screen_Height);
X               Current_Line_Antialiased_Flags[x] = 1;
X               Colour = Current_Line[x];
X               SuperSampleCount++;
X               }
X            }
X
X         if (y != First_Line-1) {
X            Red = (char) (Colour.Red * 255.0);
X            Green = (char) (Colour.Green * 255.0);
X            Blue = (char) (Colour.Blue * 255.0);
X
X            if (Options & DISPLAY)
X               display_plot (x, y, Red, Green, Blue);
X            }
X         }
X
X      if ((Options & DISKWRITE) || (Options & TARGA))
X         if (y > First_Line) {
X            Write_Line (Previous_Line, y-1);
X         }
X
X      if (Options & VERBOSE)
X         if (Options & ANTIALIAS)
X            printf (" supersampled %d times\n", SuperSampleCount);
X         else
X            putchar ('\n');
X
X      Temp_Colour_Ptr = Previous_Line;
X      Previous_Line = Current_Line;
X      Current_Line = Temp_Colour_Ptr;
X
X      Temp_Char_Ptr = Previous_Line_Antialiased_Flags;
X      Previous_Line_Antialiased_Flags = Current_Line_Antialiased_Flags;
X      Current_Line_Antialiased_Flags = Temp_Char_Ptr;
X      }
X
X   if ((Options & DISKWRITE) || (Options & TARGA)) {
X      Write_Line (Previous_Line, Last_Line - 1);
X      }
X   }
X
Xvoid Trace (Ray, Colour)
X   RAY *Ray;
X   COLOUR *Colour;
X   {
X   COLOUR Temp_Colour, Surface_Colour;
X   OBJECT *Object;
X   VECTOR Surface_Normal;
X   INTERSECTION *Local_Intersection, *New_Intersection;
X   register int Intersection_Found;
X   DBL Normal_Direction;
X
X   Number_Of_Rays++;
X   if (Frame.Fog_Distance == 0.0) {
X      Make_Colour (&Temp_Colour, 0.0, 0.0, 0.0);
X      }
X   else
X      Temp_Colour = Frame.Fog_Colour;
X
X   Intersection_Found = FALSE;
X   Local_Intersection = NULL;
X
X   if (Trace_Level > MAX_TRACE_LEVEL)
X      return;
X
X    /* What objects does this ray intersect? */
X   for (Object = Frame.Objects ; 
X        Object != NULL ;
X        Object = Object -> Next_Object) {
X
X      if (New_Intersection = Intersection (Object, Ray)) {
X         if (Intersection_Found) {
X            if (Local_Intersection -> Depth > New_Intersection -> Depth) {
X               free (Local_Intersection);
X               Local_Intersection = New_Intersection;
X               }
X            else
X               free (New_Intersection);
X            }
X         else
X            Local_Intersection = New_Intersection;
X
X         Intersection_Found = TRUE;
X         }
X      }
X
X   if (Intersection_Found) {
X      Make_Colour (&Temp_Colour, 0.0, 0.0, 0.0);
X      Make_Colour (&Surface_Colour, 0.0, 0.0, 0.0);
X
X      if (Quality > 5)
X         Colour_At (&Surface_Colour, Local_Intersection->Object,
X                    &Local_Intersection -> Point);
X      else
X         Surface_Colour = Local_Intersection->Object->Object_Colour;
X
X
X      if (Quality <= 1)
X         Temp_Colour = Surface_Colour;
X      else {
X         Normal (&Surface_Normal, (OBJECT *) Local_Intersection -> Shape,
X                 &Local_Intersection -> Point);
X         VDot (Normal_Direction, Surface_Normal, Ray->Direction);
X         if (Normal_Direction > 0.0) {
X            VScale (Surface_Normal, Surface_Normal, -1.0);
X            }
X
X         Ambient (Local_Intersection -> Object, &Local_Intersection -> Point,
X                    &Surface_Colour, &Temp_Colour);
X         Diffuse (Local_Intersection -> Object, &Local_Intersection -> Point, Ray,
X                    &Surface_Normal, &Surface_Colour, &Temp_Colour);
X
X         if (Quality > 7) {
X            Transmit (Local_Intersection -> Object, &Local_Intersection -> Point, Ray,
X                      &Surface_Normal, &Surface_Colour, &Temp_Colour);
X            Reflect (Local_Intersection -> Object, &Local_Intersection -> Point, Ray,
X                     &Surface_Normal, &Temp_Colour);
X            Refract (Local_Intersection -> Object, &Local_Intersection -> Point, Ray,
X                     &Surface_Normal, &Temp_Colour);
X
X            if (Frame.Fog_Distance != 0.0)
X               Fog (Local_Intersection->Depth, &Frame.Fog_Colour, Frame.Fog_Distance,
X                    &Temp_Colour);
X            }
X         }
X      free (Local_Intersection);
X      }
X
X   *Colour = Temp_Colour;
X   }
X
END_OF_FILE
if test 16452 -ne `wc -c <'src/render.c'`; then
    echo shar: \"'src/render.c'\" unpacked with wrong size!
fi
# end of 'src/render.c'
fi
if test -f 'src/trace.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/trace.c'\"
else
echo shar: Extracting \"'src/trace.c'\" \(15243 characters\)
sed "s/^X//" >'src/trace.c' <<'END_OF_FILE'
X/*****************************************************************************
X*
X*                                     trace.c
X*
X*   from DKBTrace (c) 1990  David Buck
X*
X*  This module contains the entry routine for the raytracer and the code to
X*  parse the parameters on the command line.
X*
X*
X* This software is freely distributable. The source and/or object code may be
X* copied or uploaded to communications services so long as this notice remains
X* at the top of each file.  If any changes are made to the program, you must
X* clearly indicate in the documentation and in the programs startup message
X* who it was who made the changes. The documentation should also describe what
X* those changes were. This software may not be included in whole or in
X* part into any commercial package without the express written consent of the
X* author.  It may, however, be included in other public domain or freely
X* distributed software so long as the proper credit for the software is given.
X*
X* This software is provided as is without any guarantees or warranty. Although
X* the author has attempted to find and correct any bugs in the software, he
X* is not responsible for any damage caused by the use of the software.  The
X* author is under no obligation to provide service, corrections, or upgrades
X* to this package.
X*
X* Despite all the legal stuff above, if you do find bugs, I would like to hear
X* about them.  Also, if you have any comments or questions, you may contact me
X* at the following address:
X*
X*     David Buck
X*     22C Sonnet Cres.
X*     Nepean Ontario
X*     Canada, K2H 8W7
X*
X*  I can also be reached on the following bulleton boards:
X*
X*     ATX              (613) 526-4141
X*     OMX              (613) 731-3419
X*     Mystic           (613) 731-0088 or (613) 731-6698
X*
X*  Fidonet:   1:163/109.9
X*  Internet:  David_Buck@Carleton.CA
X*
X*  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
X*
X*     Lattice BBS                      (708) 916-1200
X*     The Information Exchange BBS     (708) 945-5575
X*     Stillwaters BBS                  (708) 403-2826
X*
X*****************************************************************************/
X
X#include <ctype.h>
X#include "frame.h"		/* common to ALL modules in this program */
X#include "dkbproto.h"
X
X#define MAX_FILE_NAMES 1
Xunsigned long Options;
Xint Quality;
X
XFILE *bfp;
X
XFILE *Input_File, *Token_File, *Symbol_File, *Data_File;
Xextern FRAME Frame;
X
Xstatic char *File_Names[MAX_FILE_NAMES];
Xchar Input_File_Name[FILE_NAME_LENGTH], Output_File_Name[FILE_NAME_LENGTH];
Xchar *Output_File_Buffer;
Xint File_Buffer_Size;
Xstatic int Number_Of_Files;
XDBL VTemp;
XDBL Antialias_Threshold;
Xint First_Line, Last_Line;
X
X/* Stats kept by the ray tracer: */
Xlong Number_Of_Pixels, Number_Of_Rays, Number_Of_Pixels_Supersampled;
Xlong Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded;
Xlong Ray_Plane_Tests, Ray_Plane_Tests_Succeeded;
Xlong Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded;
Xlong Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded;
Xlong Bounding_Region_Tests, Bounding_Region_Tests_Succeeded;
Xlong Calls_To_Noise, Calls_To_DNoise;
Xlong Shadow_Ray_Tests, Shadow_Rays_Succeeded;
Xlong Reflected_Rays_Traced, Refracted_Rays_Traced;
Xlong Transmitted_Rays_Traced;
X
X
Xvoid main (argc, argv)
X  int argc;
X  char **argv;
X  {
X  register int i;
X  char temp[2];
X  
X  printf ("\n\n              DKB Ray Trace   Version 2.01\n");
X  printf ("              ----------------------------\n\n");
X  printf ("             Copyright (c) 1990  David Buck\n\n");
X  printf ("  Written by:\n");
X  printf ("  David K. Buck\n");
X  printf ("  22C Sonnet Cr.  Nepean, Ontario\n");
X  printf ("  Canada, K2H 8W7\n\n");
X  printf ("  This program is freely distributable.\n");
X
X  printf ("\n  Conversion to IBM P.C. w/TARGA output \n");
X  printf ("    and various improvements by Aaron A. Collins\n\n");
X
X  printf ("  GIF format file reader by Steve A. Bennett\n\n");
X
X  printf ("  Noise and DNoise functions by Robert Skinner\n\n");
X
X/* Parse the command line parameters */
X  if (argc == 1)
X    {
X    printf ("\nUsage:");
X    printf ("\n   trace  [+/-] Option1 [+/-] Option2");
X    printf ("\n");
X    printf ("\n Options:");
X    printf ("\n    d  = display");
X    printf ("\n    v  = verbose");
X    printf ("\n    p  = prompt exit");
X    printf ("\n    x  = enable early exit by key hit");
X    printf ("\n    f  = write DKB/QRT format output file");
X    printf ("\n    t  = write TARGA format output file");
X    printf ("\n    a  = perform antialiasing");
X/*  printf ("\n    z  = debug mode");	*/
X    printf ("\n    qx = image quality 0=rough, 9=full");
X    printf ("\n    wxxx = width of the screen");
X    printf ("\n    hxxx = height of the screen");
X    printf ("\n    sxxx = start at line number xxx");
X    printf ("\n    exxx = end at line number xxx");
X    printf ("\n    bxxx = Use xxx kilobytes for output file buffer space");
X    printf ("\n    ifilename = input file name");
X    printf ("\n    ofilename = output file name");
X    printf ("\n\n");
X    exit(0);
X    }
X
X  bfp = NULL;
X  File_Buffer_Size = 0;
X  Options = 0;
X  Quality = 9;
X  Number_Of_Files = 0;
X  First_Line = 0;
X  Last_Line = -1;
X
X  Number_Of_Pixels = 0L;
X  Number_Of_Rays = 0L;
X  Number_Of_Pixels_Supersampled = 0L;
X  Ray_Sphere_Tests = 0L;
X  Ray_Sphere_Tests_Succeeded = 0L;
X  Ray_Plane_Tests = 0L;
X  Ray_Plane_Tests_Succeeded = 0L;
X  Ray_Triangle_Tests = 0L;
X  Ray_Triangle_Tests_Succeeded = 0L;
X  Ray_Quadric_Tests = 0L;
X  Ray_Quadric_Tests_Succeeded = 0L;
X  Bounding_Region_Tests = 0L;
X  Bounding_Region_Tests_Succeeded = 0L;
X  Calls_To_Noise = 0L;
X  Calls_To_DNoise = 0L;
X  Shadow_Ray_Tests = 0L;
X  Shadow_Rays_Succeeded = 0L;
X  Reflected_Rays_Traced = 0L;
X  Refracted_Rays_Traced = 0L;
X  Transmitted_Rays_Traced = 0L;
X
X  Frame.Screen_Height = 100;
X  Frame.Screen_Width = 100;
X
X  Antialias_Threshold = 0.3;
X  strcpy (&Input_File_Name[0], "object.data");
X
X/* Read the default parameters from trace.def */
X  get_defaults();
X
X  strcpy (&Output_File_Name[0], "data.dis");
X
X  if (Options & TARGA)
X     strcpy (&Output_File_Name[0], "data.tga");
X
X  for (i = 1 ; i < argc ; i++ )
X    if ((*argv[i] == '+') || (*argv[i] == '-'))
X      parse_option(argv[i]);
X    else
X      parse_file_name(argv[i]);
X
X   if (Last_Line == -1)
X      Last_Line = Frame.Screen_Height;
X
X   Print_Options();
X
X/* Tokenize the input file */
X  if ((Input_File = fopen (Input_File_Name, "r")) == NULL)
X    {
X    printf ("Cannot open input file\n");
X    exit (0);
X    }
X
X  if ((Token_File = fopen ("Token.data", "w")) == NULL)
X    {
X    printf ("Cannot open token file for write\n");
X    exit (0);
X    }
X
X  if ((Symbol_File = fopen ("Symbols.data", "w")) == NULL)
X    {
X    printf ("Cannot open string file for writing\n");
X    exit(0);
X    }
X
X  printf ("Tokenizing...\n");
X  Tokenize (Input_File_Name, Input_File, Symbol_File, Token_File);
X  fclose (Input_File);
X  fclose (Token_File);
X  fclose (Symbol_File);
X
X/* parse the tokenize file */
X  if ((Token_File = fopen ("Token.data", "r")) == NULL)
X    exit (0);
X
X  if ((Symbol_File = fopen ("Symbols.data", "r")) == NULL)
X    {
X    printf ("Cannot open string file for reading\n");
X    exit(0);
X    }
X
X  printf ("Parsing...\n");
X  Parse (Token_File, &Frame);
X  fclose (Token_File);
X
X/* Get things ready for ray tracing */
X  if ((Options & DISKWRITE) || (Options & TARGA)) {
X    bfp = fopen (&Output_File_Name[0], "wb");
X    if (bfp == NULL) {
X        printf ("Cannot open output file\n");
X        exit (0);
X        }
X    if (File_Buffer_Size != 0) {
X       Output_File_Buffer = malloc (File_Buffer_Size);
X       setvbuf (bfp, Output_File_Buffer, _IOFBF, File_Buffer_Size);
X       }
X
X    if (Options & TARGA) {		/* Prefix TARGA format file header */
X	for (i = 0; i < 10; i++)	/* 00, 00, 02, then 7 00's... */
X	    if (i == 2)
X		 putc(i, bfp);
X	    else putc(0, bfp);
X        temp[0] = First_Line % 256;	/* y origin is set to "First_Line" */
X        putc (temp[0], bfp);
X        temp[0] = First_Line / 256;
X        putc (temp[0], bfp);
X        }
X
X    temp[0] = Frame.Screen_Width % 256;	/* write this to either file type */
X    putc (temp[0], bfp);
X    temp[0] = Frame.Screen_Width / 256;
X    putc (temp[0], bfp);
X    temp[0] = Frame.Screen_Height % 256;
X    putc (temp[0], bfp);
X    temp[0] = Frame.Screen_Height / 256;
X    putc (temp[0], bfp);
X
X    if (Options & TARGA) {	/* now finish the TARGA format file header */
X	putc(24, bfp);		/* 24 bits/pixel (16 million colors!) */
X	putc(32, bfp);		/* Not sure about this one, "out of 32" ? */
X	}
X    }
X
X  if (Options & DISPLAY)
X    {
X    printf ("Displaying...\n");
X    display_init();
X    }
X
X  pq_init();
X  Initialize_Noise();
X
X/* Ok, go for it - trace the picture */
X  Start_Tracing ();
X
X/* Wait for a CR if the user requested it. */
X
X/* Clean up and leave */
X  display_finished();
X
X  close_all ();
X  print_stats();
X  }
X
X/* Close all the stuff that has been opened. */
Xvoid close_all ()
X   {
X   if (Options & DISPLAY)
X     display_close();
X
X   if (bfp)
X      fclose (bfp);
X   }
X
X/* Read the default parameters from trace.def*/
Xvoid get_defaults()
X  {
X  read_options ("trace.def");
X  }
X
Xvoid read_options (file_name)
X  char *file_name;
X  {
X  FILE *default_file;
X  register int c, String_Index, Option_Started;
X  char Option_String[80];
X
X  String_Index = 0;
X  Option_Started = FALSE;
X  if (default_file = fopen(file_name, "r"))
X    while ((c = getc(default_file)) != EOF)
X      {
X      if (Option_Started)
X        if (isspace(c))
X          {
X          Option_String[String_Index] = '\0';
X          parse_option (Option_String);
X          Option_Started = FALSE;
X          }
X       else
X         Option_String[String_Index++] = (char) c;
X
X      else /* Option_Started */
X
X        if ((c == (int) '-') || (c == (int) '+'))
X          {
X          String_Index = 0;
X          Option_String[String_Index++] = (char) c;
X          Option_Started = TRUE;
X          }
X        else
X          if (!isspace(c))
X            {
X            printf ("\nBad default file format.  Offending char: (%c), val: %d.\n", (char) c, c);
X            exit (0);
X	    }
X      }
X
X  if (Option_Started)
X    {
X    Option_String[String_Index] = '\0';
X    parse_option (Option_String);
X    }
X  }
X
X/* parse the command line parameters */
Xvoid parse_option (Option_String)
X  char *Option_String;
X  {
X  register int Add_Option;
X  unsigned long Option_Number;
X  DBL threshold;
X
X  if (*(Option_String++) == '-')
X    Add_Option = FALSE;
X  else
X    Add_Option = TRUE;
X
X  switch (*Option_String)
X    {
X    case 'B':
X    case 'b':  sscanf (&Option_String[1], "%d", &File_Buffer_Size);
X               File_Buffer_Size *= 1024;
X               if (File_Buffer_Size < BUFSIZ)
X                  File_Buffer_Size = BUFSIZ;
X               Option_Number = 0;
X               break;
X
X    case 'D':
X    case 'd':  Option_Number = DISPLAY;
X               break;
X
X    case 'V':
X    case 'v':  Option_Number = VERBOSE;
X               break;
X
X    case 'W':
X    case 'w':  sscanf (&Option_String[1], "%d", &Frame.Screen_Width);
X	       Option_Number = 0;
X               break;
X
X    case 'H':
X    case 'h':  sscanf (&Option_String[1], "%d", &Frame.Screen_Height);
X	       Option_Number = 0;
X               break;
X
X    case 'F':
X    case 'f':  Option_Number = DISKWRITE;
X               break;
X
X    case 'P':
X    case 'p':  Option_Number = PROMPTEXIT;
X               break;
X
X    case 'I':
X    case 'i':  strncpy (&Input_File_Name[0], &Option_String[1], FILE_NAME_LENGTH);
X	       Option_Number = 0;
X               break;
X
X    case 'O':
X    case 'o':  strncpy (&Output_File_Name[0], &Option_String[1], FILE_NAME_LENGTH);
X	       Option_Number = 0;
X               break;
X
X    case 'A':
X    case 'a':  Option_Number = ANTIALIAS;
X               if (sscanf (&Option_String[1], DBL_FORMAT_STRING, &threshold) != EOF)
X                   Antialias_Threshold = threshold;
X               break;
X
X    case 'X':
X    case 'x':  Option_Number = EXITENABLE;
X               break;
X
X    case 'S':
X    case 's':  sscanf (&Option_String[1], "%d", &First_Line);
X	       Option_Number = 0;
X               break;
X
X    case 'E':
X    case 'e':  sscanf (&Option_String[1], "%d", &Last_Line);
X	       Option_Number = 0;
X               break;
X
X    case 'Q':
X    case 'q':  sscanf (&Option_String[1], "%d", &Quality);
X	       Option_Number = 0;
X               break;
X
X    case 'T':
X    case 't':  Option_Number = TARGA;
X               break;
X
X    case 'Z':
X    case 'z':  Option_Number = DEBUGGING;
X               break;
X
X    default:   printf ("\nInvalid option: %s\n\n", --Option_String);
X	       Option_Number = 0;
X    }
X
X  if (Option_Number != 0)
X      if (Add_Option)
X           Options |= Option_Number;
X      else Options &= ~Option_Number;
X  }
X
Xvoid Print_Options()
X   {
X   printf ("Options in effect: ");
X   if (Options & DISPLAY)
X      printf ("+d ");
X   else
X      printf ("-d ");
X
X   if (Options & VERBOSE)
X      printf ("+v ");
X   else
X      printf ("-v ");
X
X   if (Options & DISKWRITE)
X      printf ("+f ");
X   else
X      printf ("-f ");
X
X   if (Options & PROMPTEXIT)
X      printf ("+p ");
X   else
X      printf ("-p ");
X
X   if (Options & TARGA)
X      printf ("+t ");
X   else
X      printf ("-t ");
X
X   if (Options & EXITENABLE)
X      printf ("+x ");
X   else
X      printf ("-x ");
X
X   if (Options & ANTIALIAS)
X      printf ("+a%f ", Antialias_Threshold);
X   else
X      printf ("-a ");
X
X   if (File_Buffer_Size != 0)
X      printf ("-b%d ", File_Buffer_Size/1024);
X
X   printf ("-q%d -w%d -h%d -s%d -e%d -i%s ",
X           Quality, Frame.Screen_Width, Frame.Screen_Height,
X           First_Line, Last_Line, Input_File_Name);
X
X   if (Options & DISKWRITE)
X      printf ("-o%s", Output_File_Name);
X
X   printf ("\n");
X   }
X
Xvoid parse_file_name (File_Name)
X  char *File_Name;
X  {
X  File_Names [Number_Of_Files++] = File_Name;  
X  if (Number_Of_Files > MAX_FILE_NAMES)
X    {
X    printf ("\nOnly %d file names are allowed in a command line.", 
X             MAX_FILE_NAMES);
X    exit(0);
X    }
X  read_options (File_Name);
X  }
X
Xvoid print_stats()
X   {
X   printf ("                  Statistics\n");
X   printf ("                  ----------\n\n");
X   printf ("# Rays:  %10ld    # Pixels:  %10ld  # Pixels supersampled: %10ld\n\n",
X            Number_Of_Rays, Number_Of_Pixels, Number_Of_Pixels_Supersampled);
X
X   printf ("\nIntersection Tests:\n\n");
X   printf ("   Type       Tests    Succeeded\n");
X   printf ("   ----    ----------  ----------\n\n");
X   printf ("  Sphere   %10ld  %10ld\n", Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded);
X   printf ("  Plane    %10ld  %10ld\n", Ray_Plane_Tests, Ray_Plane_Tests_Succeeded);
X   printf ("  Triangle %10ld  %10ld\n", Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded);
X   printf ("  Quadric  %10ld  %10ld\n", Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded);
X   printf ("  Bounds   %10ld  %10ld\n\n", Bounding_Region_Tests, Bounding_Region_Tests_Succeeded);
X   printf ("  Calls to Noise:   %10ld\n", Calls_To_Noise);
X   printf ("  Calls to DNoise:  %10ld\n", Calls_To_DNoise);
X   printf ("  Shadow Ray Tests: %10ld     Blocking Objects Found:  %10ld\n",
X              Shadow_Ray_Tests, Shadow_Rays_Succeeded);
X   printf ("  Reflected Rays:   %10ld\n", Reflected_Rays_Traced);
X   printf ("  Refracted Rays:   %10ld\n", Refracted_Rays_Traced);
X   printf ("  Transmitted Rays: %10ld\n", Transmitted_Rays_Traced);
X   }
END_OF_FILE
if test 15243 -ne `wc -c <'src/trace.c'`; then
    echo shar: \"'src/trace.c'\" unpacked with wrong size!
fi
# end of 'src/trace.c'
fi
echo shar: End of archive 5 \(of 10\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.