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.