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.