home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / povsrc.sit / SOURCE / PARSE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-03  |  120.6 KB  |  3,994 lines

  1. /****************************************************************************
  2. *                parse.c
  3. *
  4. *  This module implements a parser for the scene description files.
  5. *
  6. *  from Persistence of Vision Raytracer 
  7. *  Copyright 1992 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. *  Copying, distribution and legal info is in the file povlegal.doc which
  10. *  should be distributed with this file. If povlegal.doc is not available
  11. *  or for more info please contact:
  12. *
  13. *       Drew Wells [POV-Team Leader] 
  14. *       CIS: 73767,1244  Internet: 73767.1244@compuserve.com
  15. *       Phone: (213) 254-4041
  16. * This program is based on the popular DKB raytracer version 2.12.
  17. * DKBTrace was originally written by David K. Buck.
  18. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  19. *
  20. *****************************************************************************/
  21.  
  22.  
  23. #include "frame.h"
  24. #include "vector.h"
  25. #include "povproto.h"
  26.  
  27.  
  28.  
  29. /* This file implements a simple recursive-descent parser for reading the
  30. input file.  */
  31.  
  32. static void Link_Shapes PARAMS((LIGHT_SHAPE *New_Object,LIGHT_SHAPE **Field,LIGHT_SHAPE **Old_Object_List));
  33. static void Post_Process_Object PARAMS((OBJECT *Object));
  34. static void Post_Process_Shape PARAMS((SHAPE *Shape));
  35.  
  36.  
  37.  
  38. extern DBL Max_Trace_Level;
  39. extern char VerboseFormat;
  40. extern unsigned int Options;
  41. extern char Stat_File_Name[FILE_NAME_LENGTH];
  42.  
  43.  
  44. FRAME *Parsing_Frame_Ptr;
  45.  
  46. extern METHODS Composite_Methods;
  47. extern METHODS Basic_Object_Methods;
  48. extern METHODS Sphere_Methods;
  49. extern METHODS Point_Methods;
  50. extern METHODS Quadric_Methods;
  51. extern METHODS Poly_Methods;
  52. extern METHODS Box_Methods;
  53. extern METHODS Blob_Methods;
  54. extern METHODS Bicubic_Patch_Methods;
  55. extern METHODS Viewpoint_Methods;
  56. extern METHODS Plane_Methods;
  57. extern METHODS Triangle_Methods;
  58. extern METHODS Smooth_Triangle_Methods;
  59. extern METHODS CSG_Union_Methods;
  60. extern METHODS CSG_Intersection_Methods;
  61. extern METHODS Height_Field_Methods;
  62.  
  63. extern struct Reserved_Word_Struct Reserved_Words [];
  64. extern DBL Antialias_Threshold;
  65.  
  66. extern int term_counts[MAX_ORDER+1];
  67. extern struct Token_Struct Token;
  68.  
  69. COLOUR_MAP_ENTRY *Construction_Map = NULL; /* moved here to allow reinitialization */
  70.  
  71. struct Constant_Struct Constants[MAX_CONSTANTS];
  72. int Number_Of_Constants;
  73. TEXTURE *Default_Texture;
  74. int Degenerate_Triangles;
  75.  
  76. /* Here we create our own little language for doing the parsing.  It
  77. makes the code easier to read. */
  78.  
  79. #define EXPECT { int Exit_Flag; Exit_Flag = FALSE; \
  80. while (!Exit_Flag) {Get_Token();  switch (Token.Token_Id) {
  81. #define CASE(x) case x:
  82. #define CASE2(x, y) case x: case y:
  83. #define CASE3(x, y, z) case x: case y: case z:
  84. #define CASE4(w, x, y, z) case w: case x: case y: case z:
  85. #define CASE5(v, w, x, y, z) case v: case w: case x: case y: case z:
  86. #define CASE6(u, v, w, x, y, z) case u: case v: case w: case x: case y: case z:
  87. #define END_CASE break;
  88. #define EXIT Exit_Flag = TRUE;
  89. #define OTHERWISE default:
  90. #define END_EXPECT } } }
  91. #define GET(x) Get_Token(); if (Token.Token_Id != x) Parse_Error (x)
  92. #define UNGET Unget_Token();
  93.  
  94.       /*
  95.  
  96. char *Coeff_terms[35] = {
  97.    "x^4", "x^3*y", "x^3*z", "x^3", "x^2*y^2", "x^2*y*z", "x^2*y", "x^2*z^2",
  98.    "x^2*z", "x^2", "x*y^3", "x*y^2*z", "x*y^2", "x*y*z^2", "x*y*z", "x*y",
  99.    "x*z^3", "x*z^2", "x*z", "x", "y^4", "y^3*z", "y^3", "y^2*z^2", "y^2*z",
  100.    "y^2", "y*z^3", "y*z^2", "y*z", "y", "z^4", "z^3", "z^2", "z", ""
  101.    };
  102.  
  103. void show_quartic(Coeffs)
  104. DBL *Coeffs;
  105. {
  106.    int i,j;
  107.    for (i=0,j=0;i<35;i++)
  108.       if (Coeffs[i] != 0.0) {
  109.      if (j) printf(" + ");
  110.      printf("%.5Lg %s", Coeffs[i], Coeff_terms[i]);
  111.      j = 1;
  112.      }
  113. }
  114.  
  115. */
  116.  
  117.       /* Parse the file into the given frame. */
  118.       void Parse (Frame_Ptr)
  119.          FRAME *Frame_Ptr;
  120.       {
  121.          OBJECT *Object;
  122.          Parsing_Frame_Ptr = Frame_Ptr;
  123.  
  124.          Degenerate_Triangles = FALSE;
  125.          Token_Init ();
  126.          Frame_Init ();
  127.          Parse_Frame ();
  128.          for (Object = Parsing_Frame_Ptr->Objects;
  129.                 Object != NULL;
  130.                 Object = Object->Next_Object)
  131.             Post_Process_Object (Object);
  132.          if (Degenerate_Triangles) {
  133.             fprintf (stderr, "Degenerate triangles were found and are being ignored.\n");
  134.             /* exit(1); Let's ignore degen tri instead of blowing up. CdW */
  135.          }
  136.       }
  137.  
  138.       void Token_Init ()
  139.       {
  140.          Number_Of_Constants = 0;
  141.          /*
  142.   Constants = (struct Constant_Struct *)malloc(
  143.       sizeof(struct Constant_Struct) *MAX_CONSTANTS);
  144.   */
  145.       }
  146.  
  147.  
  148.       /* Set up the fields in the frame to default values. */
  149.       void Frame_Init ()
  150.       {
  151.          Default_Texture = Get_Texture();
  152.          Init_Viewpoint(&(Parsing_Frame_Ptr -> View_Point));
  153.          Parsing_Frame_Ptr -> Light_Sources = NULL;
  154.          Parsing_Frame_Ptr -> Objects = NULL;
  155.          Parsing_Frame_Ptr -> Atmosphere_IOR = 1.0;
  156.          Parsing_Frame_Ptr -> Antialias_Threshold = Antialias_Threshold;
  157.          Parsing_Frame_Ptr -> Fog_Distance = 0.0;
  158.          Make_Colour (&(Parsing_Frame_Ptr->Fog_Colour), 0.0, 0.0, 0.0);
  159.       }
  160.  
  161.       /* Allocate and initialize a composite object. */
  162.       COMPOSITE *Get_Composite_Object()
  163.       {
  164.          COMPOSITE *New_Composite;
  165.  
  166.          if ((New_Composite = (COMPOSITE *) malloc (sizeof (COMPOSITE)))
  167.             == NULL)
  168.             Error ("Out of memory. Cannot allocate object");
  169.  
  170.          New_Composite -> Objects = NULL;
  171.          New_Composite -> Next_Object = NULL;
  172.          /*  New_Composite -> Next_Light_Source = NULL;*/
  173.          New_Composite -> Bounding_Shapes = NULL;
  174.          New_Composite -> Clipping_Shapes = NULL;
  175.          New_Composite -> Type = COMPOSITE_TYPE;
  176.          New_Composite -> Methods = &Composite_Methods;
  177.          return (New_Composite);
  178.       }
  179.  
  180.       /* Allocate and initialize a sphere. */
  181.       SPHERE *Get_Sphere_Shape()
  182.       {
  183.          SPHERE *New_Shape;
  184.  
  185.          if ((New_Shape = (SPHERE *) malloc (sizeof (SPHERE))) == NULL)
  186.             Error ("Out of memory. Cannot allocate shape");
  187.  
  188.          Make_Vector (&(New_Shape -> Center), 0.0, 0.0, 0.0);
  189.          New_Shape->Radius = 1.0;
  190.          New_Shape->Radius_Squared = 1.0;
  191.          New_Shape->Inverse_Radius = 1.0;
  192.          New_Shape -> Type = SPHERE_TYPE;
  193.          New_Shape -> Next_Object = NULL;
  194.          New_Shape -> Methods = &Sphere_Methods;
  195.          New_Shape -> VPCached = FALSE;
  196.          New_Shape -> Inverted = FALSE;
  197.          New_Shape -> Shape_Texture = NULL;
  198.          New_Shape -> Shape_Colour = NULL;
  199.          return (New_Shape);
  200.       }
  201.  
  202.       /* Allocate and initialize a light source. */
  203.       /* A point light source has no shape, but we'll treat it like it does */
  204.  
  205.       LIGHT_SHAPE *Get_Light_Source_Shape()
  206.       {
  207.          LIGHT_SHAPE *New_Shape;
  208.  
  209.          if ((New_Shape = (LIGHT_SHAPE *) malloc (sizeof (LIGHT_SHAPE))) == NULL)
  210.             Error ("Out of memory. Cannot allocate shape");
  211.          Make_Vector (&(New_Shape -> Center), 0.0, 0.0, 0.0);
  212.          Make_Vector (&(New_Shape -> Points_At), 0.0, 0.0, 1.0);
  213.          New_Shape -> Type = POINT_LIGHT_TYPE;
  214.          New_Shape -> Methods = &Point_Methods;
  215.          New_Shape -> Next_Object = NULL;
  216.          New_Shape -> Inverted = FALSE; /* needed so CSG routines don't blow up */
  217.          New_Shape -> Shape_Texture = NULL; /* always NULL */
  218.          New_Shape -> Shape_Colour = Get_Colour();  /* becomes light colour */
  219.          Make_Colour(New_Shape->Shape_Colour, 1.0, 1.0, 1.0);
  220.          New_Shape->Shape_Colour->Alpha = 0.0;
  221.          New_Shape -> Coeff   = 10.0;
  222.          New_Shape -> Radius  = 0.35;
  223.          New_Shape -> Falloff = 0.35;
  224.          return (New_Shape);
  225.       }
  226.  
  227.       /* Allocate and initialize a quadric surface. */
  228.       QUADRIC *Get_Quadric_Shape()
  229.       {
  230.          QUADRIC *New_Shape;
  231.  
  232.          if ((New_Shape = (QUADRIC *) malloc (sizeof (QUADRIC))) == NULL)
  233.             Error ("Out of memory. Cannot allocate shape");
  234.  
  235.          Make_Vector (&(New_Shape -> Object_2_Terms), 1.0, 1.0, 1.0);
  236.          Make_Vector (&(New_Shape -> Object_Mixed_Terms), 0.0, 0.0, 0.0);
  237.          Make_Vector (&(New_Shape -> Object_Terms), 0.0, 0.0, 0.0);
  238.          New_Shape -> Object_Constant = 1.0;
  239.          New_Shape -> Object_VP_Constant = HUGE_VAL;
  240.          New_Shape -> Constant_Cached = FALSE;
  241.          New_Shape -> Non_Zero_Square_Term = FALSE;
  242.          New_Shape -> Type = QUADRIC_TYPE;
  243.          New_Shape -> Next_Object = NULL;
  244.          New_Shape -> Methods = &Quadric_Methods;
  245.          New_Shape -> Shape_Texture = NULL;
  246.          New_Shape -> Shape_Colour = NULL;
  247.          return (New_Shape);
  248.       }
  249.       /* Allocate and initialize a polynomial surface. */
  250.       POLY *Get_Poly_Shape(order)
  251.          int order;
  252.       {
  253.          POLY *New_Shape;
  254.          int i;
  255.  
  256.          if ((New_Shape = (POLY *) malloc (sizeof (POLY))) == NULL)
  257.             Error ("Out of memory. Cannot allocate shape");
  258.  
  259.          New_Shape->Type = POLY_TYPE;
  260.          New_Shape->Next_Object = NULL;
  261.          New_Shape->Methods = &Poly_Methods;
  262.          New_Shape->Shape_Texture = NULL;
  263.          New_Shape->Shape_Colour = NULL;
  264.          New_Shape->Transform = NULL;
  265.          New_Shape->Inverted = 0;
  266.          New_Shape->Order = order;
  267.          New_Shape->Sturm_Flag = 0;
  268.          New_Shape->Coeffs = (DBL *)malloc(term_counts[order] * sizeof(DBL));
  269.          if (New_Shape->Coeffs == NULL)
  270.             Error("Out of memory. Cannot allocate coefficients for POLY");
  271.          for (i=0;i<term_counts[order];i++)
  272.             New_Shape->Coeffs[i] = 0.0;
  273.          return (New_Shape);
  274.       }
  275.  
  276.       /* Allocate and initialize a box. */
  277.       BOX *Get_Box_Shape()
  278.       {
  279.          BOX *New_Shape;
  280.  
  281.          if ((New_Shape = (BOX *) malloc (sizeof (BOX))) == NULL)
  282.             Error ("Out of memory. Cannot allocate shape");
  283.  
  284.          Make_Vector(&(New_Shape->bounds[0]), -1.0, -1.0, -1.0);
  285.          Make_Vector(&(New_Shape->bounds[1]),  1.0,  1.0,  1.0);
  286.          New_Shape -> Transform = NULL;
  287.          New_Shape -> Type = BOX_TYPE;
  288.          New_Shape -> Next_Object = NULL;
  289.          New_Shape -> Methods = &Box_Methods;
  290.          New_Shape -> Inverted = FALSE;
  291.          New_Shape -> Shape_Texture = NULL;
  292.          New_Shape -> Shape_Colour = NULL;
  293.          return (New_Shape);
  294.       }
  295.  
  296.       /* Allocate a blob. */
  297.       BLOB *Get_Blob_Shape()
  298.       {
  299.          BLOB *New_Shape;
  300.  
  301.          if ((New_Shape = (BLOB *) malloc (sizeof (BLOB))) == NULL)
  302.             Error ("Out of memory. Cannot allocate shape");
  303.  
  304.          New_Shape -> Transform = NULL;
  305.          New_Shape -> Type = BLOB_TYPE;
  306.          New_Shape -> Next_Object = NULL;
  307.          New_Shape -> Methods = &Blob_Methods;
  308.          New_Shape -> Inverted = FALSE;
  309.          New_Shape -> Shape_Texture = NULL;
  310.          New_Shape -> Shape_Colour = NULL;
  311.          return (New_Shape);
  312.       }
  313.  
  314.       /* Allocate and initialize a bicubic patch surface. */
  315.       BICUBIC_PATCH *Get_Bicubic_Patch_Shape()
  316.       {
  317.          BICUBIC_PATCH *New_Shape;
  318.  
  319.          if ((New_Shape = (BICUBIC_PATCH *) malloc (sizeof (BICUBIC_PATCH))) == NULL)
  320.             Error ("Out of memory. Cannot allocate shape");
  321.  
  322.          New_Shape->Type = BICUBIC_PATCH_TYPE;
  323.          New_Shape->Next_Object = NULL;
  324.          New_Shape->Methods = &Bicubic_Patch_Methods;
  325.          New_Shape->Shape_Texture = NULL;
  326.          New_Shape->Shape_Colour = NULL;
  327.          New_Shape->U_Steps = 0;
  328.          New_Shape->V_Steps = 0;
  329.          New_Shape->Intersection_Count = 0;
  330.          New_Shape->Interpolated_Grid = (VECTOR **)NULL;
  331.          New_Shape->Interpolated_Normals = (VECTOR **)NULL;
  332.          New_Shape->Smooth_Normals = (VECTOR **)NULL;
  333.          New_Shape->Interpolated_D = (DBL **)NULL;
  334.          return (New_Shape);
  335.       }       
  336.  
  337.       /* Allocate and intialize a Height Field */
  338.       HEIGHT_FIELD *Get_Height_Field_Shape()
  339.       {
  340.          HEIGHT_FIELD *New_Shape;
  341.  
  342.          if((New_Shape = (HEIGHT_FIELD *) malloc (sizeof(HEIGHT_FIELD))) == NULL)
  343.             Error ("Out of memory. Cannot allocate shape");
  344.          New_Shape -> bounding_box = Get_Box_Shape();
  345.          New_Shape -> Map = NULL;
  346.          New_Shape -> Transformation = Get_Transformation();
  347.          New_Shape -> Type = HEIGHT_FIELD_TYPE;
  348.          New_Shape -> Next_Object = NULL;
  349.          New_Shape -> Methods = &Height_Field_Methods;
  350.          New_Shape -> Shape_Texture = NULL;
  351.          New_Shape -> Shape_Colour = NULL;
  352.          return(New_Shape);
  353.       }
  354.  
  355.  
  356.       /* Allocate and initialize a plane. */
  357.       PLANE *Get_Plane_Shape()
  358.       {
  359.          PLANE *New_Shape;
  360.  
  361.          if ((New_Shape = (PLANE *) malloc (sizeof (PLANE))) == NULL)
  362.             Error ("Out of memory. Cannot allocate shape");
  363.  
  364.          Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0);
  365.          New_Shape->Distance = 0.0;
  366.          New_Shape -> Type = PLANE_TYPE;
  367.          New_Shape -> Next_Object = NULL;
  368.          New_Shape -> Methods = &Plane_Methods;
  369.          New_Shape -> VPCached = 0;
  370.          New_Shape -> Shape_Texture = NULL;
  371.          New_Shape -> Shape_Colour = NULL;
  372.          return (New_Shape);
  373.       }
  374.  
  375.       /* Allocate and initialize a triangle. */
  376.       TRIANGLE *Get_Triangle_Shape()
  377.       {
  378.          TRIANGLE *New_Shape;
  379.  
  380.          if ((New_Shape = (TRIANGLE *) malloc (sizeof (TRIANGLE))) == NULL)
  381.             Error ("Out of memory. Cannot allocate shape");
  382.  
  383.          Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0);
  384.          Make_Vector (&(New_Shape -> P1), 0.0, 0.0, 0.0);
  385.          Make_Vector (&(New_Shape -> P2), 1.0, 0.0, 0.0);
  386.          Make_Vector (&(New_Shape -> P3), 0.0, 1.0, 0.0);
  387.          New_Shape->Distance = 0.0;
  388.          New_Shape->Inverted = FALSE;
  389.          New_Shape -> Type = TRIANGLE_TYPE;
  390.          New_Shape -> Next_Object = NULL;
  391.          New_Shape -> Methods = &Triangle_Methods;
  392.          New_Shape -> VPCached = FALSE;
  393.          New_Shape -> Shape_Texture = NULL;
  394.          New_Shape -> Shape_Colour = NULL;
  395.          New_Shape -> Degenerate_Flag = FALSE;
  396.          return (New_Shape);
  397.       }
  398.  
  399.       /* Allocate and initialize a smooth triangle. */
  400.       SMOOTH_TRIANGLE *Get_Smooth_Triangle_Shape()
  401.       {
  402.          SMOOTH_TRIANGLE *New_Shape;
  403.  
  404.          if ((New_Shape = (SMOOTH_TRIANGLE *) malloc (sizeof (SMOOTH_TRIANGLE))) == NULL)
  405.             Error ("Out of memory. Cannot allocate shape");
  406.  
  407.          Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0);
  408.          Make_Vector (&(New_Shape -> P1), 0.0, 0.0, 0.0);
  409.          Make_Vector (&(New_Shape -> P2), 1.0, 0.0, 0.0);
  410.          Make_Vector (&(New_Shape -> P3), 0.0, 1.0, 0.0);
  411.          Make_Vector (&(New_Shape -> N1), 0.0, 1.0, 0.0);
  412.          Make_Vector (&(New_Shape -> N2), 0.0, 1.0, 0.0);
  413.          Make_Vector (&(New_Shape -> N3), 0.0, 1.0, 0.0);
  414.          New_Shape->Distance = 0.0;
  415.          New_Shape -> Type = SMOOTH_TRIANGLE_TYPE;
  416.          New_Shape->Inverted = FALSE;
  417.          New_Shape -> Next_Object = NULL;
  418.          New_Shape -> Methods = &Smooth_Triangle_Methods;
  419.          New_Shape -> VPCached = 0;
  420.          New_Shape -> Shape_Texture = NULL;
  421.          New_Shape -> Shape_Colour = NULL;
  422.          New_Shape -> Degenerate_Flag = FALSE;
  423.          return (New_Shape);
  424.       }
  425.  
  426.       CSG_SHAPE *Get_CSG_Shape()
  427.       {
  428.          CSG_SHAPE *New_Shape;
  429.  
  430.          if ((New_Shape = (CSG_SHAPE *) malloc (sizeof (CSG_SHAPE))) == NULL)
  431.             Error ("Out of memory. Cannot allocate shape");
  432.  
  433.          New_Shape -> Parent_Object = NULL;
  434.          New_Shape -> Next_Object = NULL;
  435.          New_Shape -> Shapes = NULL;
  436.          return (New_Shape);
  437.       }
  438.  
  439.       CSG_SHAPE *Get_CSG_Union()
  440.       {
  441.          CSG_SHAPE *New_Shape;
  442.  
  443.          New_Shape = Get_CSG_Shape();
  444.          New_Shape -> Methods = &CSG_Union_Methods;
  445.          New_Shape -> Type = CSG_UNION_TYPE;
  446.          return (New_Shape);
  447.       }
  448.  
  449.       CSG_SHAPE *Get_CSG_Intersection()
  450.       {
  451.          CSG_SHAPE *New_Shape;
  452.  
  453.          New_Shape = Get_CSG_Shape();
  454.          New_Shape -> Methods = &CSG_Intersection_Methods;
  455.          New_Shape -> Type = CSG_INTERSECTION_TYPE;
  456.          return (New_Shape);
  457.       }
  458.  
  459.       OBJECT *Get_Object ()
  460.       {
  461.          OBJECT *New_Object;
  462.  
  463.          if ((New_Object = (OBJECT *) malloc (sizeof (OBJECT))) == NULL)
  464.             Error ("Out of memory. Cannot allocate object");
  465.  
  466.          New_Object -> Next_Object = NULL;
  467.          /*  New_Object -> Next_Light_Source = NULL;*/
  468.          New_Object -> Shape = NULL;
  469.          New_Object -> Bounding_Shapes = NULL;
  470.          New_Object -> Clipping_Shapes = NULL;
  471.          New_Object -> Object_Texture = Default_Texture;
  472.  
  473.          New_Object->Object_Colour = NULL;
  474.  
  475.          New_Object -> No_Shadow_Flag = FALSE;
  476.          New_Object -> Type = OBJECT_TYPE;
  477.          New_Object -> Methods = &Basic_Object_Methods;
  478.          return (New_Object);
  479.       }
  480.  
  481.       TEXTURE *Get_Texture ()
  482.       {
  483.          TEXTURE *New_Texture;
  484.  
  485.          if ((New_Texture = (TEXTURE *) malloc (sizeof (TEXTURE))) == NULL)
  486.             Error ("Out of memory. Cannot allocate object");
  487.  
  488.          New_Texture -> Next_Texture = NULL;
  489.          New_Texture -> Next_Material = NULL;
  490.          New_Texture -> Number_Of_Materials = 0;
  491.          New_Texture -> Object_Reflection = 0.0;
  492.          New_Texture -> Object_Ambient = 0.1;
  493.          New_Texture -> Object_Diffuse = 0.6;
  494.          New_Texture -> Object_Brilliance = 1.0;
  495.          New_Texture -> Object_Specular = 0.0;
  496.          New_Texture -> Object_Roughness = 0.05;
  497.          New_Texture -> Object_Phong = 0.0;
  498.          New_Texture -> Object_PhongSize = 40;
  499.  
  500.          New_Texture -> Texture_Randomness= 0.0;
  501.          New_Texture -> Bump_Amount = 0.0;
  502.          New_Texture -> Phase = 0.0;
  503.          New_Texture -> Frequency = 1.0;
  504.          New_Texture -> Texture_Number = NO_TEXTURE;
  505.          New_Texture -> Texture_Transformation = NULL;
  506.          New_Texture -> Bump_Number = NO_BUMPS;
  507.          New_Texture -> Turbulence = 0.0;
  508.          New_Texture -> Colour_Map = NULL;
  509.          New_Texture -> Once_Flag = FALSE;
  510.          New_Texture -> Metallic_Flag = FALSE;
  511.          New_Texture -> Octaves = 6;         /* dmf, for turbulence functs */
  512.          New_Texture -> Mortar = 0.2;        /* rha, for brick texture */
  513.  
  514.          New_Texture -> Constant_Flag = TRUE;
  515.          New_Texture -> Colour1 = NULL;
  516.          New_Texture -> Colour2 = NULL;
  517.          Make_Vector (&New_Texture->Texture_Gradient, 0.0, 0.0, 0.0);
  518.  
  519.          New_Texture -> Object_Index_Of_Refraction = 1.0;
  520.          New_Texture -> Object_Transmit = 0.0;
  521.          New_Texture -> Object_Refraction = 0.0;
  522.          return (New_Texture);
  523.       }
  524.  
  525.  
  526.       VIEWPOINT *Get_Viewpoint ()
  527.       {
  528.          VIEWPOINT *New_Viewpoint;
  529.  
  530.          if ((New_Viewpoint = (VIEWPOINT *)malloc (sizeof (VIEWPOINT)))
  531.             == NULL)
  532.             Error ("Out of memory. Cannot allocate viewpoint");
  533.  
  534.          Init_Viewpoint (New_Viewpoint);
  535.          return (New_Viewpoint);
  536.       }
  537.  
  538.       COLOUR *Get_Colour ()
  539.       {
  540.          COLOUR *New_Colour;
  541.  
  542.          if ((New_Colour = (COLOUR *) malloc (sizeof (COLOUR))) == NULL)
  543.             Error ("Out of memory. Cannot allocate colour");
  544.  
  545.          Make_Colour (New_Colour, 0.0, 0.0, 0.0);
  546.          return (New_Colour);
  547.       }
  548.  
  549.       VECTOR *Get_Vector ()
  550.       {
  551.          VECTOR *New_Vector;
  552.  
  553.          if ((New_Vector = (VECTOR *) malloc (sizeof (VECTOR))) == NULL)
  554.             Error ("Out of memory. Cannot allocate vector");
  555.  
  556.          New_Vector -> x = 0.0;
  557.          New_Vector -> y = 0.0;
  558.          New_Vector -> z = 0.0;
  559.          return (New_Vector);
  560.       }
  561.  
  562.       DBL *Get_Float ()
  563.       {
  564.          DBL *New_Float;
  565.  
  566.          if ((New_Float = (DBL *) malloc (sizeof (DBL))) == NULL)
  567.             Error ("Out of memory. Cannot allocate float");
  568.  
  569.          *New_Float = 0.0;
  570.          return (New_Float);
  571.       }
  572.  
  573.       TRANSFORMATION *Get_Transformation()
  574.       {
  575.          TRANSFORMATION *New_Transformation;
  576.  
  577.          if ((New_Transformation =
  578.             (TRANSFORMATION *) malloc (sizeof (TRANSFORMATION))) == NULL)
  579.             Error ("Out of memory. Cannot allocate transformation");
  580.  
  581.          MIdentity ((MATRIX *) &(New_Transformation -> matrix[0][0]));
  582.          MIdentity ((MATRIX *) &(New_Transformation -> inverse[0][0]));
  583.          return (New_Transformation);
  584.       }
  585.  
  586.       /* Parse a float.  Doesn't handle exponentiation. */
  587.       DBL Parse_Float ()
  588.       {
  589.          DBL Local_Float = 0.0;
  590.          CONSTANT Constant_Id;
  591.          register int Negative, Sign_Parsed;
  592.  
  593.          Negative = FALSE;
  594.          Sign_Parsed = FALSE;
  595.  
  596.          EXPECT
  597.          CASE (IDENTIFIER_TOKEN)
  598.             if ((Constant_Id = Find_Constant()) != -1)
  599.                if (Constants[(int)Constant_Id].Constant_Type == FLOAT_CONSTANT)
  600.                {
  601.                   Local_Float = *((DBL *) Constants[(int)Constant_Id].Constant_Data);
  602.                   if (Negative)
  603.                      Local_Float *= -1.0;
  604.                }
  605.                else
  606.                   Type_Error ();
  607.             else
  608.                Undeclared ();
  609.          EXIT
  610.          END_CASE
  611.  
  612.          CASE (PLUS_TOKEN)
  613.             if (Sign_Parsed)
  614.                Parse_Error (FLOAT_TOKEN);
  615.          Sign_Parsed = TRUE;
  616.          END_CASE
  617.  
  618.          CASE (DASH_TOKEN)
  619.             if (Sign_Parsed)
  620.                Parse_Error (FLOAT_TOKEN);
  621.          Negative = TRUE;
  622.          Sign_Parsed = TRUE;
  623.          END_CASE
  624.  
  625.          CASE (FLOAT_TOKEN)
  626.             Local_Float = Token.Token_Float;
  627.          if (Negative)
  628.             Local_Float *= -1.0;
  629.          EXIT
  630.          END_CASE
  631.  
  632.          OTHERWISE
  633.          Parse_Error (FLOAT_TOKEN);
  634.          END_CASE
  635.          END_EXPECT
  636.  
  637.          return (Local_Float);
  638.       }
  639.  
  640.       void Parse_Vector (Given_Vector)
  641.          VECTOR *Given_Vector;
  642.       {
  643.          CONSTANT Constant_Id;
  644.  
  645.          EXPECT
  646.          CASE (IDENTIFIER_TOKEN)
  647.             if ((Constant_Id = Find_Constant()) != -1)
  648.                if (Constants[(int)Constant_Id].Constant_Type == VECTOR_CONSTANT)
  649.                   *Given_Vector = *((VECTOR *) Constants[(int)Constant_Id].Constant_Data);
  650.                else
  651.                   Type_Error ();
  652.             else
  653.                Undeclared ();
  654.          EXIT
  655.          END_CASE
  656.  
  657.          CASE (LEFT_ANGLE_TOKEN)
  658.             (Given_Vector -> x) = Parse_Float();
  659.          (Given_Vector -> y) = Parse_Float();
  660.          (Given_Vector -> z) = Parse_Float();
  661.          GET (RIGHT_ANGLE_TOKEN);
  662.          EXIT
  663.          END_CASE
  664.  
  665.          OTHERWISE 
  666.          Parse_Error (LEFT_ANGLE_TOKEN);
  667.          END_CASE
  668.          END_EXPECT
  669.       }
  670.  
  671.       void Parse_Coeffs(order, Given_Coeffs)
  672.          int order;
  673.       DBL *Given_Coeffs;
  674.       {
  675.          int i;
  676.  
  677.          EXPECT
  678.          CASE (LEFT_ANGLE_TOKEN)
  679.             for (i = 0; i < term_counts[order]; i++)
  680.                Given_Coeffs[i] = Parse_Float();
  681.          GET (RIGHT_ANGLE_TOKEN);
  682.          EXIT
  683.          END_CASE
  684.  
  685.          OTHERWISE 
  686.          Parse_Error (LEFT_ANGLE_TOKEN);
  687.          END_CASE
  688.          END_EXPECT
  689.       }
  690.  
  691.       void Parse_Colour (Given_Colour)
  692.          COLOUR *Given_Colour;
  693.       {
  694.          CONSTANT Constant_Id;
  695.          Make_Colour (Given_Colour, 0.0, 0.0, 0.0);
  696.          EXPECT
  697.          CASE (IDENTIFIER_TOKEN)
  698.             if ((Constant_Id = Find_Constant()) != -1)
  699.                if (Constants[(int)Constant_Id].Constant_Type == COLOUR_CONSTANT)
  700.                   *Given_Colour = *((COLOUR *) Constants[(int)Constant_Id].Constant_Data);
  701.                else
  702.                   Type_Error ();
  703.             else
  704.                Undeclared ();
  705.          END_CASE
  706.  
  707.          CASE (RED_TOKEN)
  708.             (Given_Colour -> Red) = Parse_Float();
  709.          END_CASE
  710.  
  711.          CASE (GREEN_TOKEN)
  712.             (Given_Colour -> Green) = Parse_Float();
  713.          END_CASE
  714.  
  715.          CASE (BLUE_TOKEN)
  716.             (Given_Colour -> Blue) = Parse_Float();
  717.          END_CASE
  718.  
  719.          CASE (ALPHA_TOKEN)
  720.             (Given_Colour -> Alpha) = Parse_Float();
  721.          END_CASE
  722.  
  723.          OTHERWISE
  724.          UNGET
  725.          EXIT
  726.          END_CASE
  727.          END_EXPECT
  728.       }
  729.  
  730.       COLOUR_MAP *Parse_Colour_Map ()
  731.       {
  732. #define MAX_ENTRIES 20
  733.          COLOUR_MAP *New_Colour_Map;
  734.  
  735.  
  736.          register int i, j;
  737.  
  738.          if ((New_Colour_Map = (COLOUR_MAP *) malloc (sizeof (COLOUR_MAP))) == NULL)
  739.             Error ("Not enough memory for colour map.");
  740.  
  741.  
  742.          if (Construction_Map == NULL)
  743.             if ((Construction_Map = (COLOUR_MAP_ENTRY *)
  744.                malloc(MAX_ENTRIES * sizeof (COLOUR_MAP_ENTRY))) == NULL)
  745.                Error ("Not enough memory for colour map.");
  746.  
  747.          i = 0;
  748.          New_Colour_Map->Transparency_Flag = FALSE;
  749.          GET(LEFT_CURLY_TOKEN);
  750.          EXPECT
  751.          CASE (LEFT_SQUARE_TOKEN)
  752.             Construction_Map [i].start = Parse_Float();
  753.          Construction_Map [i].end = Parse_Float();
  754.  
  755.          GET (COLOUR_TOKEN);
  756.          Parse_Colour (&(Construction_Map[i].Start_Colour));
  757.          if (Construction_Map[i].Start_Colour.Alpha != 0.0)
  758.             New_Colour_Map->Transparency_Flag = TRUE;
  759.  
  760.          GET (COLOUR_TOKEN);
  761.          Parse_Colour (&(Construction_Map[i].End_Colour));
  762.          if (Construction_Map[i].End_Colour.Alpha != 0.0)
  763.             New_Colour_Map->Transparency_Flag = TRUE;
  764.  
  765.          i++;
  766.          if (i > MAX_ENTRIES)
  767.             Error ("Colour_Map too long.");
  768.          GET (RIGHT_SQUARE_TOKEN);
  769.          END_CASE
  770.  
  771.          CASE (RIGHT_CURLY_TOKEN)
  772.             New_Colour_Map -> Number_Of_Entries = i;
  773.  
  774.          if ((New_Colour_Map -> Colour_Map_Entries = (COLOUR_MAP_ENTRY *)
  775.             malloc(sizeof(COLOUR_MAP_ENTRY) * i)) == NULL)
  776.             Error ("Not enough memory for colour map.");
  777.  
  778.          for (j = 0 ; j < i ; j++)
  779.             New_Colour_Map->Colour_Map_Entries[j] = Construction_Map[j];
  780.  
  781.          EXIT
  782.          END_CASE
  783.  
  784.          OTHERWISE
  785.          Parse_Error (RIGHT_CURLY_TOKEN);
  786.          END_CASE
  787.          END_EXPECT
  788.  
  789.          return (New_Colour_Map);
  790.       }
  791.  
  792.       TEXTURE *Copy_Texture (Texture)
  793.          TEXTURE *Texture;
  794.       {
  795.          TEXTURE *New_Texture, *Local_Texture, *First_Texture, *Previous_Texture;
  796.  
  797.          Previous_Texture = First_Texture = NULL;
  798.  
  799.          for (Local_Texture = Texture ; Local_Texture != NULL ; Local_Texture = Local_Texture->Next_Texture)  {
  800.             New_Texture = Get_Texture();
  801.             *New_Texture = *Local_Texture;
  802.  
  803.             if (First_Texture == NULL)
  804.                First_Texture = New_Texture;
  805.  
  806.             if (Previous_Texture != NULL)
  807.                Previous_Texture->Next_Texture = New_Texture;
  808.  
  809.             if (New_Texture->Texture_Transformation) {
  810.                if ((New_Texture->Texture_Transformation = (TRANSFORMATION *) malloc (sizeof (TRANSFORMATION))) == NULL)
  811.                   Error("Out of memory. Cannot allocate texture transformation");
  812.                *New_Texture->Texture_Transformation = *Local_Texture->Texture_Transformation;
  813.             }
  814.             New_Texture->Constant_Flag = FALSE;
  815.             Previous_Texture = New_Texture;
  816.          }            
  817.          return (First_Texture);
  818.       }
  819.  
  820.       TEXTURE *Parse_Texture ()
  821.       {
  822.          VECTOR Local_Vector;
  823.          TRANSFORMATION Local_Transformation;
  824.          CONSTANT Constant_Id;
  825.          TEXTURE *Texture, *Local_Texture, *First_Texture;
  826.          TEXTURE *temp_texture;
  827.          int reg;
  828.  
  829.          Texture = Default_Texture;
  830.  
  831.          GET(LEFT_CURLY_TOKEN);
  832.  
  833.          EXPECT
  834.          CASE (IDENTIFIER_TOKEN)
  835.             if ((Constant_Id = Find_Constant()) != -1)
  836.                if (Constants[(int)Constant_Id].Constant_Type == TEXTURE_CONSTANT) {
  837.                   Texture = ((TEXTURE *) Constants[(int)Constant_Id].Constant_Data);
  838.                }
  839.                else
  840.                   Type_Error ();
  841.             else
  842.                Undeclared ();
  843.          END_CASE
  844.  
  845.          CASE (FLOAT_TOKEN)
  846.             UNGET
  847.             if (Texture->Constant_Flag) {
  848.                Texture = Copy_Texture(Texture);
  849.                Texture->Constant_Flag = FALSE;
  850.             }
  851.          Texture -> Texture_Randomness = Parse_Float();
  852.          END_CASE
  853.  
  854.          CASE (ONCE_TOKEN)
  855.             if (Texture->Constant_Flag) {
  856.                Texture = Copy_Texture(Texture);
  857.                Texture->Constant_Flag = FALSE;
  858.             }
  859.          Texture->Once_Flag = TRUE;
  860.          END_CASE
  861.  
  862.          CASE (TURBULENCE_TOKEN)
  863.             if (Texture->Constant_Flag) {
  864.                Texture = Copy_Texture(Texture);
  865.                Texture->Constant_Flag = FALSE;
  866.             }
  867.          Texture -> Turbulence = Parse_Float();
  868.          END_CASE
  869.  
  870.          CASE (OCTAVES_TOKEN)                  /* dmf 02/05 for turb */
  871.             if (Texture->Constant_Flag) {
  872.                Texture = Copy_Texture(Texture);
  873.                Texture->Constant_Flag = FALSE;
  874.             }
  875.          Texture->Octaves = (int) Parse_Float();
  876.          if(Texture->Octaves < 1)
  877.             Texture->Octaves = 6;
  878.          if(Texture->Octaves > 10)  /* Avoid DOMAIN errors */
  879.             Texture->Octaves = 10;
  880.          END_CASE
  881.  
  882.          CASE (BOZO_TOKEN)
  883.             if (Texture->Constant_Flag) {
  884.                Texture = Copy_Texture (Texture);
  885.                Texture->Constant_Flag = FALSE;
  886.             }
  887.          Texture -> Texture_Number = BOZO_TEXTURE;
  888.          END_CASE
  889.  
  890.          CASE (MORTAR_TOKEN)
  891.             if (Texture->Constant_Flag) {
  892.                Texture = Copy_Texture (Texture);
  893.                Texture->Constant_Flag = FALSE;
  894.             }
  895.          Texture->Mortar = Parse_Float();
  896.          if (Texture->Mortar < 0)
  897.             Texture->Mortar = 0.2;
  898.          END_CASE
  899.  
  900.          CASE (BRICK_TOKEN)
  901.             if (Texture->Constant_Flag) {
  902.                Texture = Copy_Texture (Texture);
  903.                Texture->Constant_Flag = FALSE;
  904.             }
  905.          Texture -> Texture_Number = BRICK_TEXTURE;
  906.          EXPECT
  907.          CASE (COLOUR_TOKEN)
  908.             Texture->Colour1 = Get_Colour();
  909.          Texture->Colour2 = Get_Colour();
  910.          Parse_Colour (Texture -> Colour1);
  911.          GET (COLOUR_TOKEN);
  912.          Parse_Colour (Texture -> Colour2);
  913.          END_CASE
  914.  
  915.          OTHERWISE
  916.          UNGET
  917.          EXIT
  918.          END_CASE
  919.          END_EXPECT
  920.          END_CASE
  921.  
  922.          CASE (CHECKER_TOKEN)
  923.             if (Texture->Constant_Flag) {
  924.                Texture = Copy_Texture (Texture);
  925.                Texture->Constant_Flag = FALSE;
  926.             }
  927.          Texture -> Texture_Number = CHECKER_TEXTURE;
  928.          EXPECT
  929.          CASE (COLOUR_TOKEN)
  930.             Texture->Colour1 = Get_Colour();
  931.          Texture->Colour2 = Get_Colour();
  932.          Parse_Colour (Texture -> Colour1);
  933.          GET (COLOUR_TOKEN);
  934.          Parse_Colour (Texture -> Colour2);
  935.          END_CASE
  936.  
  937.          OTHERWISE
  938.          UNGET
  939.          EXIT
  940.          END_CASE
  941.          END_EXPECT
  942.          END_CASE
  943.  
  944.          CASE (CHECKER_TEXTURE_TOKEN)
  945.             if (Texture->Constant_Flag) {
  946.                Texture = Copy_Texture (Texture);
  947.                Texture->Constant_Flag = FALSE;
  948.             }
  949.          Texture -> Texture_Number = CHECKER_TEXTURE_TEXTURE;
  950.  
  951.          GET(LEFT_CURLY_TOKEN);
  952.  
  953.          EXPECT
  954.          CASE (TEXTURE_TOKEN)
  955.             Local_Texture = Parse_Texture ();
  956.          if (Local_Texture->Constant_Flag)
  957.             Local_Texture = Copy_Texture(Local_Texture);
  958.  
  959.          {
  960.             for (temp_texture = Local_Texture ;
  961.                            temp_texture->Next_Texture != NULL ;
  962.                            temp_texture = temp_texture->Next_Texture)
  963.             {}
  964.  
  965.             temp_texture->Next_Texture = (TEXTURE *) Texture->Colour1;
  966.             Texture->Colour1 = (COLOUR *) Local_Texture;
  967.          }
  968.          END_CASE
  969.          OTHERWISE
  970.          UNGET
  971.          EXIT
  972.          END_CASE
  973.          END_EXPECT
  974.  
  975.          GET (TILE2_TOKEN);
  976.          EXPECT
  977.          CASE (TEXTURE_TOKEN)
  978.             Local_Texture = Parse_Texture ();
  979.          if (Local_Texture->Constant_Flag)
  980.             Local_Texture = Copy_Texture(Local_Texture);
  981.  
  982.          {
  983.             for (temp_texture = Local_Texture ;
  984.                            temp_texture->Next_Texture != NULL ;
  985.                            temp_texture = temp_texture->Next_Texture)
  986.             {}
  987.  
  988.             temp_texture->Next_Texture = (TEXTURE *) Texture->Colour2;
  989.             Texture->Colour2 = (COLOUR *) Local_Texture;
  990.          }
  991.          END_CASE
  992.          OTHERWISE
  993.          UNGET
  994.          EXIT
  995.          END_CASE
  996.          END_EXPECT
  997.          GET (RIGHT_CURLY_TOKEN);
  998.          END_CASE
  999.  
  1000.          CASE (MARBLE_TOKEN)
  1001.             if (Texture->Constant_Flag) {
  1002.                Texture = Copy_Texture (Texture);
  1003.                Texture->Constant_Flag = FALSE;
  1004.             }
  1005.          Texture -> Texture_Number = MARBLE_TEXTURE;
  1006.          END_CASE
  1007.  
  1008.          CASE (WOOD_TOKEN)
  1009.             if (Texture->Constant_Flag) {
  1010.                Texture = Copy_Texture (Texture);
  1011.                Texture->Constant_Flag = FALSE;
  1012.             }
  1013.          Texture -> Texture_Number = WOOD_TEXTURE;
  1014.          END_CASE
  1015.  
  1016.          CASE (SPOTTED_TOKEN)
  1017.             if (Texture->Constant_Flag) {
  1018.                Texture = Copy_Texture (Texture);
  1019.                Texture->Constant_Flag = FALSE;
  1020.             }
  1021.          Texture -> Texture_Number = SPOTTED_TEXTURE;
  1022.          END_CASE
  1023.  
  1024.          CASE (AGATE_TOKEN)
  1025.             if (Texture->Constant_Flag) {
  1026.                Texture = Copy_Texture (Texture);
  1027.                Texture->Constant_Flag = FALSE;
  1028.             }
  1029.          Texture -> Texture_Number = AGATE_TEXTURE;
  1030.          END_CASE
  1031.  
  1032.          CASE (GRANITE_TOKEN)
  1033.             if (Texture->Constant_Flag) {
  1034.                Texture = Copy_Texture (Texture);
  1035.                Texture->Constant_Flag = FALSE;
  1036.             }
  1037.          Texture -> Texture_Number = GRANITE_TEXTURE;
  1038.          END_CASE
  1039.  
  1040.          CASE (GRADIENT_TOKEN)
  1041.             if (Texture->Constant_Flag) {
  1042.                Texture = Copy_Texture (Texture);
  1043.                Texture->Constant_Flag = FALSE;
  1044.             }
  1045.          Texture -> Texture_Number = GRADIENT_TEXTURE;
  1046.          Parse_Vector (&(Texture -> Texture_Gradient));
  1047.          END_CASE
  1048.  
  1049.          CASE (AMBIENT_TOKEN)
  1050.             if (Texture->Constant_Flag) {
  1051.                Texture = Copy_Texture (Texture);
  1052.                Texture->Constant_Flag = FALSE;
  1053.             }
  1054.          (Texture -> Object_Ambient) = Parse_Float ();
  1055.          END_CASE
  1056.  
  1057.          CASE (BRILLIANCE_TOKEN)
  1058.             if (Texture->Constant_Flag) {
  1059.                Texture = Copy_Texture (Texture);
  1060.                Texture->Constant_Flag = FALSE;
  1061.             }
  1062.          (Texture -> Object_Brilliance) = Parse_Float ();
  1063.          END_CASE
  1064.  
  1065.          CASE (ROUGHNESS_TOKEN)
  1066.             if (Texture->Constant_Flag) {
  1067.                Texture = Copy_Texture (Texture);
  1068.                Texture->Constant_Flag = FALSE;
  1069.             }
  1070.          (Texture -> Object_Roughness) = Parse_Float ();
  1071.          /* No training wheels */
  1072.          /* if (Texture -> Object_Roughness > 1.0)
  1073.         Texture -> Object_Roughness = 1.0;
  1074.      if (Texture -> Object_Roughness < 0.001)
  1075.         Texture -> Object_Roughness = 0.001; */
  1076.          END_CASE
  1077.  
  1078.          CASE (PHONGSIZE_TOKEN)
  1079.             if (Texture->Constant_Flag) {
  1080.                Texture = Copy_Texture (Texture);
  1081.                Texture->Constant_Flag = FALSE;
  1082.             }
  1083.          (Texture -> Object_PhongSize) = Parse_Float ();
  1084.          /* No training wheels */
  1085.          /*if (Texture -> Object_PhongSize < 1.0)
  1086.         Texture -> Object_PhongSize = 1.0;
  1087.      if (Texture -> Object_PhongSize > 100)
  1088.         Texture -> Object_PhongSize = 100; */
  1089.          END_CASE
  1090.  
  1091.          CASE (DIFFUSE_TOKEN)
  1092.             if (Texture->Constant_Flag) {
  1093.                Texture = Copy_Texture (Texture);
  1094.                Texture->Constant_Flag = FALSE;
  1095.             }
  1096.          (Texture -> Object_Diffuse) = Parse_Float ();
  1097.          END_CASE
  1098.  
  1099.          CASE (SPECULAR_TOKEN)
  1100.             if (Texture->Constant_Flag) {
  1101.                Texture = Copy_Texture (Texture);
  1102.                Texture->Constant_Flag = FALSE;
  1103.             }
  1104.          (Texture -> Object_Specular) = Parse_Float ();
  1105.          END_CASE
  1106.  
  1107.          CASE (PHONG_TOKEN)
  1108.             if (Texture->Constant_Flag) {
  1109.                Texture = Copy_Texture (Texture);
  1110.                Texture->Constant_Flag = FALSE;
  1111.             }
  1112.          (Texture -> Object_Phong) = Parse_Float ();
  1113.          END_CASE
  1114.  
  1115.          CASE (METALLIC_TOKEN)
  1116.             if (Texture->Constant_Flag) {
  1117.                Texture = Copy_Texture (Texture);
  1118.                Texture->Constant_Flag = FALSE;
  1119.             }
  1120.          Texture -> Metallic_Flag = TRUE;
  1121.          END_CASE
  1122.  
  1123.          CASE (IOR_TOKEN)
  1124.             if (Texture->Constant_Flag) {
  1125.                Texture = Copy_Texture (Texture);
  1126.                Texture->Constant_Flag = FALSE;
  1127.             }
  1128.          (Texture -> Object_Index_Of_Refraction) = Parse_Float ();
  1129.          END_CASE
  1130.  
  1131.          CASE (REFRACTION_TOKEN)
  1132.             if (Texture->Constant_Flag) {
  1133.                Texture = Copy_Texture (Texture);
  1134.                Texture->Constant_Flag = FALSE;
  1135.             }
  1136.          (Texture -> Object_Refraction) = Parse_Float ();
  1137.          END_CASE
  1138.  
  1139.          CASE (TRANSMIT_TOKEN)
  1140.             if (Texture->Constant_Flag) {
  1141.                Texture = Copy_Texture (Texture);
  1142.                Texture->Constant_Flag = FALSE;
  1143.             }
  1144.          (Texture -> Object_Transmit) = Parse_Float ();
  1145.          END_CASE
  1146.  
  1147.          CASE (REFLECTION_TOKEN)
  1148.             if (Texture->Constant_Flag) {
  1149.                Texture = Copy_Texture (Texture);
  1150.                Texture->Constant_Flag = FALSE;
  1151.             }
  1152.          (Texture -> Object_Reflection) = Parse_Float ();
  1153.          END_CASE
  1154.  
  1155.          CASE (IMAGEMAP_TOKEN)
  1156.             if (Texture->Constant_Flag) {
  1157.                Texture = Copy_Texture (Texture);
  1158.                Texture->Constant_Flag = FALSE;
  1159.             }
  1160.          Texture->Texture_Number = IMAGEMAP_TEXTURE;
  1161.          if ((Texture->Image = (IMAGE *)malloc(sizeof(IMAGE))) == NULL)
  1162.             Error("Out of memory. Cannot allocate imagemap texture");
  1163.          Make_Vector (&Texture->Image->Image_Gradient, 1.0, -1.0, 0.0);
  1164.          Texture->Image->Map_Type = PLANAR_MAP;  
  1165.          Texture->Image->Interpolation_Type = NO_INTERPOLATION;
  1166.          Texture->Image->Once_Flag = FALSE;
  1167.          Texture->Image->Use_Colour_Flag= TRUE;
  1168.  
  1169.          GET(LEFT_CURLY_TOKEN);   
  1170.  
  1171.          EXPECT
  1172.          CASE3 (DASH_TOKEN, PLUS_TOKEN, FLOAT_TOKEN)
  1173.             UNGET
  1174.             (Texture->Image->Map_Type) = (int) Parse_Float ();
  1175.          END_CASE
  1176.  
  1177.          CASE (LEFT_ANGLE_TOKEN)
  1178.             UNGET
  1179.             Parse_Vector (&(Texture -> Image->Image_Gradient));
  1180.          END_CASE
  1181.  
  1182.          CASE (IFF_TOKEN)
  1183.             GET (STRING_TOKEN);
  1184.          Read_Iff_Image(Texture->Image, Token.Token_String);
  1185.          EXIT
  1186.          END_CASE
  1187.  
  1188.          CASE (GIF_TOKEN)
  1189.             GET (STRING_TOKEN);
  1190.          Read_Gif_Image(Texture->Image, Token.Token_String);
  1191.          EXIT
  1192.          END_CASE
  1193.  
  1194.          CASE (TGA_TOKEN)
  1195.             GET (STRING_TOKEN);
  1196.          Read_Targa_Image(Texture->Image, Token.Token_String);
  1197.          EXIT
  1198.          END_CASE
  1199.  
  1200.          CASE (DUMP_TOKEN)
  1201.             GET (STRING_TOKEN);
  1202.          Read_Dump_Image(Texture->Image, Token.Token_String);
  1203.          EXIT
  1204.          END_CASE
  1205.  
  1206.          OTHERWISE
  1207.          Parse_Error (GIF_TOKEN);
  1208.          END_CASE
  1209.          END_EXPECT
  1210.  
  1211.          EXPECT
  1212.          CASE (ONCE_TOKEN)
  1213.             Texture->Image->Once_Flag=TRUE;
  1214.          END_CASE
  1215.  
  1216.          CASE (INTERPOLATE_TOKEN)
  1217.             Texture->Image->Interpolation_Type = (int)Parse_Float();
  1218.          END_CASE
  1219.  
  1220.          CASE (MAPTYPE_TOKEN)
  1221.             (Texture->Image->Map_Type) = (int) Parse_Float ();
  1222.          END_CASE
  1223.  
  1224.          CASE (USE_COLOUR_TOKEN)
  1225.             Texture ->Image->Use_Colour_Flag = TRUE;
  1226.          END_CASE  
  1227.  
  1228.          CASE (USE_INDEX_TOKEN)
  1229.             Texture ->Image->Use_Colour_Flag = FALSE;
  1230.          END_CASE  
  1231.  
  1232.          CASE (ALPHA_TOKEN)
  1233.             EXPECT
  1234.             CASE (FLOAT_TOKEN)
  1235.                reg = (int)(Token.Token_Float + 0.01);
  1236.          if (Texture->Image->Colour_Map == NULL)
  1237.             Error ("Can't apply ALPHA to a non colour-mapped image\n");
  1238.  
  1239.          if ((reg < 0) || (reg >= Texture->Image->Colour_Map_Size))
  1240.             Error ("ALPHA colour register value out of range.\n");
  1241.  
  1242.          Texture->Image->Colour_Map[reg].Alpha = (unsigned short) (255.0 * Parse_Float());
  1243.          EXIT
  1244.          END_CASE
  1245.  
  1246.          CASE (ALL_TOKEN)
  1247.          {
  1248.             DBL alpha;
  1249.             alpha = Parse_Float();
  1250.  
  1251.             for (reg = 0 ; reg < Texture->Image->Colour_Map_Size ; reg++)
  1252.                Texture->Image->Colour_Map[reg].Alpha = (unsigned short) (alpha *255.0);
  1253.             EXIT
  1254.          }
  1255.  
  1256.          END_CASE
  1257.          END_EXPECT
  1258.          END_CASE
  1259.  
  1260.          CASE (RIGHT_CURLY_TOKEN)
  1261.             EXIT
  1262.             END_CASE
  1263.  
  1264.             OTHERWISE
  1265.             Parse_Error (RIGHT_CURLY_TOKEN);
  1266.          END_CASE
  1267.          END_EXPECT
  1268.          END_CASE
  1269.  
  1270.          CASE (WAVES_TOKEN)
  1271.             if (Texture->Constant_Flag) {
  1272.                Texture = Copy_Texture (Texture);
  1273.                Texture->Constant_Flag = FALSE;
  1274.             }
  1275.          Texture -> Bump_Number = WAVES;
  1276.          Texture -> Bump_Amount = Parse_Float ();
  1277.          EXPECT
  1278.          CASE (PHASE_TOKEN)
  1279.             Texture -> Phase = Parse_Float();
  1280.          EXIT
  1281.          END_CASE
  1282.  
  1283.          OTHERWISE
  1284.          UNGET
  1285.          EXIT
  1286.          END_CASE
  1287.          END_EXPECT
  1288.          END_CASE
  1289.  
  1290.          CASE (FREQUENCY_TOKEN)
  1291.             if (Texture->Constant_Flag) {
  1292.                Texture = Copy_Texture (Texture);
  1293.                Texture->Constant_Flag = FALSE;
  1294.             }
  1295.          Texture -> Frequency = Parse_Float();
  1296.          END_CASE
  1297.  
  1298.          CASE (PHASE_TOKEN)
  1299.             if (Texture->Constant_Flag) {
  1300.                Texture = Copy_Texture (Texture);
  1301.                Texture->Constant_Flag = FALSE;
  1302.             }
  1303.          Texture -> Phase = Parse_Float();
  1304.          END_CASE
  1305.  
  1306.          CASE (RIPPLES_TOKEN)
  1307.             if (Texture->Constant_Flag) {
  1308.                Texture = Copy_Texture (Texture);
  1309.                Texture->Constant_Flag = FALSE;
  1310.             }
  1311.          Texture -> Bump_Number = RIPPLES;
  1312.          Texture -> Bump_Amount = Parse_Float ();
  1313.          END_CASE
  1314.  
  1315.          CASE (WRINKLES_TOKEN)
  1316.             if (Texture->Constant_Flag) {
  1317.                Texture = Copy_Texture (Texture);
  1318.                Texture->Constant_Flag = FALSE;
  1319.             }
  1320.          Texture -> Bump_Number = WRINKLES;
  1321.          Texture -> Bump_Amount = Parse_Float ();
  1322.          END_CASE
  1323.  
  1324.          CASE (BUMPS_TOKEN)
  1325.             if (Texture->Constant_Flag) {
  1326.                Texture = Copy_Texture (Texture);
  1327.                Texture->Constant_Flag = FALSE;
  1328.             }
  1329.          Texture -> Bump_Number = BUMPS;
  1330.          Texture -> Bump_Amount = Parse_Float ();
  1331.          END_CASE
  1332.  
  1333.          CASE (DENTS_TOKEN)
  1334.             if (Texture->Constant_Flag) {
  1335.                Texture = Copy_Texture (Texture);
  1336.                Texture->Constant_Flag = FALSE;
  1337.             }
  1338.          Texture -> Bump_Number = DENTS;
  1339.          Texture -> Bump_Amount = Parse_Float ();
  1340.          END_CASE
  1341.  
  1342.          CASE (TRANSLATE_TOKEN)
  1343.             if (Texture->Constant_Flag) {
  1344.                Texture = Copy_Texture (Texture);
  1345.                Texture->Constant_Flag = FALSE;
  1346.             }
  1347.          Parse_Vector (&Local_Vector);
  1348.          Translate_Texture (&Texture, &Local_Vector);
  1349.          END_CASE
  1350.  
  1351.          CASE (ROTATE_TOKEN)
  1352.             if (Texture->Constant_Flag) {
  1353.                Texture = Copy_Texture (Texture);
  1354.                Texture->Constant_Flag = FALSE;
  1355.             }
  1356.          Parse_Vector (&Local_Vector);
  1357.          Rotate_Texture (&Texture, &Local_Vector);
  1358.          END_CASE
  1359.  
  1360.          CASE (SCALE_TOKEN)
  1361.             if (Texture->Constant_Flag) {
  1362.                Texture = Copy_Texture (Texture);
  1363.                Texture->Constant_Flag = FALSE;
  1364.             }
  1365.          Parse_Vector (&Local_Vector);
  1366.          Scale_Texture (&Texture, &Local_Vector);
  1367.          END_CASE
  1368.  
  1369.          CASE (COLOUR_TOKEN)
  1370.             if (Texture->Constant_Flag) {
  1371.                Texture = Copy_Texture (Texture);
  1372.                Texture->Constant_Flag = FALSE;
  1373.             }
  1374.          Texture->Colour1 = Get_Colour();
  1375.          Parse_Colour (Texture -> Colour1);
  1376.          Texture -> Texture_Number = COLOUR_TEXTURE;
  1377.          END_CASE
  1378.  
  1379.          CASE (COLOUR_MAP_TOKEN)
  1380.             if (Texture->Constant_Flag) {
  1381.                Texture = Copy_Texture (Texture);
  1382.                Texture->Constant_Flag = FALSE;
  1383.             }
  1384.          Texture -> Colour_Map = Parse_Colour_Map();
  1385.          END_CASE
  1386.  
  1387.          CASE (ONION_TOKEN)
  1388.             if (Texture->Constant_Flag) {
  1389.                Texture = Copy_Texture (Texture);
  1390.                Texture->Constant_Flag = FALSE;
  1391.             }
  1392.          Texture -> Texture_Number = ONION_TEXTURE;
  1393.          END_CASE
  1394.  
  1395.          CASE (LEOPARD_TOKEN)
  1396.             if (Texture->Constant_Flag) {
  1397.                Texture = Copy_Texture (Texture);
  1398.                Texture->Constant_Flag = FALSE;
  1399.             }
  1400.          Texture -> Texture_Number = LEOPARD_TEXTURE;
  1401.          END_CASE
  1402.  
  1403.  
  1404.  
  1405.          /* New Texture Parsing - Cdw */
  1406.          CASE (PAINTED1_TOKEN)
  1407.             if (Texture->Constant_Flag) {
  1408.                Texture = Copy_Texture (Texture);
  1409.                Texture->Constant_Flag = FALSE;
  1410.             }
  1411.          Texture -> Texture_Number = PAINTED1_TEXTURE;
  1412.          END_CASE
  1413.  
  1414.          CASE (PAINTED2_TOKEN)
  1415.             if (Texture->Constant_Flag) {
  1416.                Texture = Copy_Texture (Texture);
  1417.                Texture->Constant_Flag = FALSE;
  1418.             }
  1419.          Texture -> Texture_Number = PAINTED2_TEXTURE;
  1420.          END_CASE
  1421.  
  1422.          CASE (PAINTED3_TOKEN)
  1423.             if (Texture->Constant_Flag) {
  1424.                Texture = Copy_Texture (Texture);
  1425.                Texture->Constant_Flag = FALSE;
  1426.             }
  1427.          Texture -> Texture_Number = PAINTED3_TEXTURE;
  1428.          END_CASE
  1429.  
  1430.          CASE (BUMPY1_TOKEN)
  1431.             if (Texture->Constant_Flag) {
  1432.                Texture = Copy_Texture (Texture);
  1433.                Texture->Constant_Flag = FALSE;
  1434.             }
  1435.          Texture -> Bump_Number = BUMPY1;
  1436.          Texture -> Bump_Amount = Parse_Float ();
  1437.          END_CASE
  1438.  
  1439.          CASE (BUMPY2_TOKEN)
  1440.             if (Texture->Constant_Flag) {
  1441.                Texture = Copy_Texture (Texture);
  1442.                Texture->Constant_Flag = FALSE;
  1443.             }
  1444.          Texture -> Bump_Number = BUMPY2;
  1445.          Texture -> Bump_Amount = Parse_Float ();
  1446.          END_CASE
  1447.  
  1448.          CASE (BUMPY3_TOKEN)
  1449.             if (Texture->Constant_Flag) {
  1450.                Texture = Copy_Texture (Texture);
  1451.                Texture->Constant_Flag = FALSE;
  1452.             }
  1453.          Texture -> Bump_Number = BUMPY3;
  1454.          Texture -> Bump_Amount = Parse_Float ();
  1455.          END_CASE
  1456.  
  1457.  
  1458.          CASE (BUMPMAP_TOKEN)
  1459.             if (Texture->Constant_Flag) {
  1460.                Texture = Copy_Texture (Texture);
  1461.                Texture->Constant_Flag = FALSE;
  1462.             }
  1463.          Texture -> Bump_Number = BUMPMAP;
  1464.          if ((Texture->Bump_Image = (IMAGE *)malloc(sizeof(IMAGE))) == NULL)
  1465.             Error("Out of memory. Cannot allocate bumpmap texture");
  1466.          Make_Vector (&Texture->Bump_Image->Image_Gradient, 1.0, -1.0, 0.0);
  1467.          Texture->Bump_Image->Map_Type = PLANAR_MAP;  
  1468.          Texture->Bump_Image->Interpolation_Type = NO_INTERPOLATION;
  1469.          Texture->Bump_Image->Once_Flag = FALSE;
  1470.          Texture->Bump_Image->Use_Colour_Flag = TRUE;
  1471.  
  1472.          GET(LEFT_CURLY_TOKEN);    
  1473.  
  1474.          EXPECT
  1475.          CASE3 (DASH_TOKEN, PLUS_TOKEN, FLOAT_TOKEN)
  1476.             UNGET
  1477.             (Texture->Bump_Image->Map_Type) = (int) Parse_Float ();
  1478.          END_CASE            
  1479.  
  1480.          CASE (LEFT_ANGLE_TOKEN)
  1481.             UNGET
  1482.             Parse_Vector (&(Texture ->Bump_Image->Image_Gradient));
  1483.          END_CASE
  1484.  
  1485.          CASE (IFF_TOKEN)
  1486.             GET (STRING_TOKEN);
  1487.          Read_Iff_Image(Texture->Bump_Image, Token.Token_String);
  1488.          EXIT
  1489.          END_CASE
  1490.  
  1491.          CASE (GIF_TOKEN)
  1492.             GET (STRING_TOKEN);
  1493.          Read_Gif_Image(Texture->Bump_Image, Token.Token_String);
  1494.          EXIT
  1495.          END_CASE
  1496.  
  1497.          CASE (TGA_TOKEN)
  1498.             GET (STRING_TOKEN);
  1499.          Read_Targa_Image(Texture->Bump_Image, Token.Token_String);
  1500.          EXIT
  1501.          END_CASE
  1502.  
  1503.          CASE (DUMP_TOKEN)
  1504.             GET (STRING_TOKEN);
  1505.          Read_Dump_Image(Texture->Bump_Image, Token.Token_String);
  1506.          EXIT
  1507.          END_CASE
  1508.  
  1509.          OTHERWISE
  1510.          Parse_Error (GIF_TOKEN);
  1511.          END_CASE
  1512.          END_EXPECT
  1513.  
  1514.          EXPECT
  1515.          CASE (ONCE_TOKEN)
  1516.             Texture->Bump_Image->Once_Flag=TRUE;
  1517.          END_CASE          
  1518.  
  1519.          CASE (MAPTYPE_TOKEN)
  1520.             (Texture->Bump_Image->Map_Type) = (int) Parse_Float ();
  1521.          END_CASE
  1522.  
  1523.          CASE (INTERPOLATE_TOKEN)
  1524.             Texture->Bump_Image->Interpolation_Type = (int)Parse_Float();
  1525.          END_CASE
  1526.  
  1527.          CASE (BUMPSIZE_TOKEN)
  1528.             Texture -> Bump_Amount = Parse_Float ();
  1529.          END_CASE  
  1530.  
  1531.          CASE (USE_COLOUR_TOKEN)
  1532.             Texture ->Bump_Image->Use_Colour_Flag = TRUE;
  1533.          END_CASE  
  1534.          CASE (USE_INDEX_TOKEN)
  1535.             Texture ->Bump_Image->Use_Colour_Flag = FALSE;
  1536.          END_CASE  
  1537.  
  1538.          CASE (RIGHT_CURLY_TOKEN)
  1539.             EXIT
  1540.             END_CASE
  1541.  
  1542.             OTHERWISE
  1543.             Parse_Error (RIGHT_CURLY_TOKEN);
  1544.          END_CASE
  1545.          END_EXPECT
  1546.          END_CASE
  1547.  
  1548.  
  1549.          CASE (MATERIAL_MAP_TOKEN)
  1550.  
  1551.             if (Texture->Constant_Flag) {
  1552.                Texture = Copy_Texture (Texture);
  1553.                Texture->Constant_Flag = FALSE;
  1554.             }
  1555.          Texture -> Texture_Number = MATERIAL_MAP_TEXTURE;
  1556.          if ((Texture->Material_Image=(IMAGE *)malloc(sizeof(IMAGE))) == NULL)
  1557.             Error("Out of memory. Cannot allocate material map texture");
  1558.          Make_Vector (&Texture->Texture_Gradient, 1.0, -1.0, 0.0);
  1559.          Texture->Material_Image->Map_Type = PLANAR_MAP;  
  1560.          Texture->Material_Image->Interpolation_Type = NO_INTERPOLATION;
  1561.          Texture->Material_Image->Once_Flag = FALSE;
  1562.          Texture->Material_Image->Use_Colour_Flag = FALSE; 
  1563.  
  1564.          GET(LEFT_CURLY_TOKEN);    
  1565.  
  1566.          EXPECT
  1567.          CASE3 (DASH_TOKEN, PLUS_TOKEN, FLOAT_TOKEN)
  1568.             UNGET
  1569.             (Texture->Image->Map_Type) = (int) Parse_Float ();
  1570.          END_CASE
  1571.  
  1572.          CASE (LEFT_ANGLE_TOKEN)
  1573.             UNGET
  1574.             Parse_Vector (&(Texture ->Material_Image->Image_Gradient));
  1575.          END_CASE
  1576.  
  1577.          CASE (IFF_TOKEN)
  1578.             GET (STRING_TOKEN);
  1579.          Read_Iff_Image(Texture->Material_Image, Token.Token_String);
  1580.          EXIT
  1581.          END_CASE
  1582.  
  1583.          CASE (GIF_TOKEN)
  1584.             GET (STRING_TOKEN);
  1585.          Read_Gif_Image(Texture->Material_Image, Token.Token_String);
  1586.          EXIT
  1587.          END_CASE
  1588.  
  1589.          CASE (TGA_TOKEN)
  1590.             GET (STRING_TOKEN);
  1591.          Read_Targa_Image(Texture->Material_Image, Token.Token_String);
  1592.          EXIT
  1593.          END_CASE
  1594.  
  1595.          CASE (DUMP_TOKEN)
  1596.             GET (STRING_TOKEN);
  1597.          Read_Dump_Image(Texture->Material_Image, Token.Token_String);
  1598.          EXIT
  1599.          END_CASE
  1600.  
  1601.          OTHERWISE
  1602.          Parse_Error (GIF_TOKEN);
  1603.          END_CASE
  1604.          END_EXPECT
  1605.  
  1606.          /* remember where the First_Texture is */
  1607.          First_Texture = Texture; 
  1608.  
  1609.          EXPECT
  1610.  
  1611.          CASE (MAPTYPE_TOKEN)
  1612.             (Texture->Material_Image->Map_Type) = (int) Parse_Float ();
  1613.          END_CASE
  1614.  
  1615.          CASE (INTERPOLATE_TOKEN)
  1616.             Texture->Material_Image->Interpolation_Type=(int)Parse_Float();
  1617.          END_CASE
  1618.  
  1619.          CASE (ONCE_TOKEN)
  1620.             Texture->Material_Image->Once_Flag=TRUE;
  1621.          END_CASE          
  1622.  
  1623.  
  1624.          CASE (TEXTURE_TOKEN) {
  1625.             Texture->Next_Material = Parse_Texture (); 
  1626.             First_Texture->Number_Of_Materials++;
  1627.             Texture = Texture->Next_Material;
  1628.          }
  1629.  
  1630.          END_CASE
  1631.  
  1632.          CASE (RIGHT_CURLY_TOKEN){
  1633.             Texture->Next_Material = NULL; 
  1634.             Texture = First_Texture; 
  1635.             EXIT
  1636.          }
  1637.          END_CASE  
  1638.  
  1639.          OTHERWISE
  1640.          Parse_Error (RIGHT_CURLY_TOKEN);
  1641.          END_CASE
  1642.          END_EXPECT
  1643.          END_CASE
  1644.  
  1645.          CASE (RIGHT_CURLY_TOKEN)
  1646.             EXIT
  1647.             END_CASE
  1648.  
  1649.             OTHERWISE
  1650.             Parse_Error (RIGHT_CURLY_TOKEN);
  1651.          END_CASE
  1652.          END_EXPECT
  1653.          return (Texture);
  1654.       }
  1655.  
  1656.       SHAPE *Parse_Light_Source ()
  1657.       {
  1658.          LIGHT_SHAPE *Local_Shape;
  1659.          VECTOR Local_Vector;
  1660.          CONSTANT Constant_Id;
  1661.  
  1662.  
  1663.          GET (LEFT_CURLY_TOKEN);
  1664.  
  1665.          EXPECT
  1666.          CASE (LEFT_ANGLE_TOKEN)
  1667.             UNGET
  1668.             Local_Shape = Get_Light_Source_Shape();
  1669.          Parse_Vector(&(Local_Shape->Center));
  1670.          Local_Shape->Shape_Colour = Get_Colour();
  1671.          Make_Colour(Local_Shape->Shape_Colour, 1.0, 1.0, 1.0);
  1672.          Local_Shape->Shape_Colour->Alpha = 0.0;
  1673.          GET (COLOUR_TOKEN);
  1674.          Parse_Colour (Local_Shape->Shape_Colour);
  1675.          EXIT
  1676.          END_CASE
  1677.  
  1678.  
  1679.          CASE (IDENTIFIER_TOKEN)
  1680.             if ((Constant_Id = Find_Constant()) != -1)
  1681.                if (Constants[(int)Constant_Id].Constant_Type == LIGHT_SOURCE_CONSTANT)
  1682.                   Local_Shape = (LIGHT_SHAPE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1683.                else 
  1684.                   Type_Error ();
  1685.             else
  1686.                Undeclared ();
  1687.          EXIT
  1688.          END_CASE
  1689.  
  1690.          OTHERWISE
  1691.          Parse_Error (LEFT_ANGLE_TOKEN);
  1692.          END_CASE
  1693.          END_EXPECT
  1694.  
  1695.          EXPECT
  1696.          CASE (RIGHT_CURLY_TOKEN)
  1697.             EXIT
  1698.             END_CASE
  1699.  
  1700.             CASE (TRANSLATE_TOKEN)
  1701.                Parse_Vector (&Local_Vector);
  1702.          Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1703.          END_CASE
  1704.  
  1705.          CASE (ROTATE_TOKEN)
  1706.             Parse_Vector (&Local_Vector);
  1707.          Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1708.          END_CASE
  1709.  
  1710.          CASE (SCALE_TOKEN)
  1711.             Parse_Vector (&Local_Vector);
  1712.          Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1713.          END_CASE
  1714.  
  1715.          /* Point that the spot is pointed at */
  1716.          CASE (POINT_AT_TOKEN)
  1717.             Parse_Vector(&(Local_Shape -> Points_At));
  1718.          END_CASE
  1719.  
  1720.          CASE (TIGHTNESS_TOKEN)
  1721.             Local_Shape -> Coeff = Parse_Float();
  1722.          END_CASE
  1723.  
  1724.          CASE (RADIUS_TOKEN)
  1725.             Local_Shape -> Radius = cos(Parse_Float() * M_PI / 180.0);
  1726.          END_CASE
  1727.  
  1728.          CASE (COLOUR_TOKEN)
  1729.             Parse_Colour (Local_Shape->Shape_Colour);
  1730.          END_CASE
  1731.  
  1732.  
  1733.          CASE (FALLOFF_TOKEN)
  1734.             Local_Shape -> Falloff = cos(Parse_Float() * M_PI / 180.0);
  1735.          END_CASE
  1736.  
  1737.          CASE (SPOTLIGHT_TOKEN)
  1738.             Local_Shape -> Type = SPOT_LIGHT_TYPE;
  1739.          END_CASE
  1740.  
  1741.  
  1742.          OTHERWISE
  1743.          Parse_Error (RIGHT_CURLY_TOKEN);
  1744.          END_CASE
  1745.  
  1746.          END_EXPECT
  1747.          /*  Link_Shapes (Local_Shape, &(Local_Shape -> Next_Light_Source),
  1748.            &(Parsing_Frame_Ptr -> Light_Sources));
  1749. */
  1750.          return ((SHAPE *) Local_Shape);
  1751.       }
  1752.  
  1753.  
  1754.  
  1755.  
  1756.       SHAPE *Parse_Sphere ()
  1757.       {
  1758.          SPHERE *Local_Shape;
  1759.          CONSTANT Constant_Id;
  1760.          VECTOR Local_Vector;
  1761.          TEXTURE *Local_Texture;
  1762.          TEXTURE *temp_texture;
  1763.  
  1764.          Local_Shape = NULL;
  1765.  
  1766.          GET(LEFT_CURLY_TOKEN);
  1767.  
  1768.          EXPECT
  1769.          CASE (LEFT_ANGLE_TOKEN)
  1770.             UNGET
  1771.             Local_Shape = Get_Sphere_Shape();
  1772.          Parse_Vector(&(Local_Shape -> Center));
  1773.          Local_Shape -> Radius = Parse_Float();
  1774.          Local_Shape -> Radius_Squared = Local_Shape -> Radius * Local_Shape -> Radius;
  1775.          Local_Shape -> Inverse_Radius = 1.0 / Local_Shape -> Radius;
  1776.          EXIT
  1777.          END_CASE
  1778.  
  1779.          CASE (IDENTIFIER_TOKEN)
  1780.             if ((Constant_Id = Find_Constant()) != -1)
  1781.                if (Constants[(int)Constant_Id].Constant_Type == SPHERE_CONSTANT)
  1782.                   Local_Shape = (SPHERE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1783.                else
  1784.                   Type_Error ();
  1785.             else
  1786.                Undeclared ();
  1787.          EXIT
  1788.          END_CASE
  1789.  
  1790.          OTHERWISE
  1791.          Parse_Error (LEFT_ANGLE_TOKEN);
  1792.          END_CASE
  1793.          END_EXPECT
  1794.  
  1795.          EXPECT
  1796.          CASE (RIGHT_CURLY_TOKEN)
  1797.             EXIT
  1798.             END_CASE
  1799.  
  1800.             CASE (TRANSLATE_TOKEN)
  1801.                Parse_Vector (&Local_Vector);
  1802.          Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1803.          END_CASE
  1804.  
  1805.          CASE (ROTATE_TOKEN)
  1806.             Parse_Vector (&Local_Vector);
  1807.          Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1808.          END_CASE
  1809.  
  1810.          CASE (SCALE_TOKEN)
  1811.             Parse_Vector (&Local_Vector);
  1812.          Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1813.          END_CASE
  1814.  
  1815.          CASE (INVERSE_TOKEN)
  1816.             Invert ((OBJECT *) Local_Shape);
  1817.          END_CASE
  1818.  
  1819.          CASE (TEXTURE_TOKEN)
  1820.             Local_Texture = Parse_Texture ();
  1821.          if (Local_Texture->Constant_Flag)
  1822.             Local_Texture = Copy_Texture(Local_Texture);
  1823.  
  1824.          {
  1825.             for (temp_texture = Local_Texture ;
  1826.                         temp_texture->Next_Texture != NULL ;
  1827.                         temp_texture = temp_texture->Next_Texture)
  1828.             {}
  1829.  
  1830.             temp_texture->Next_Texture = Local_Shape->Shape_Texture;
  1831.             Local_Shape->Shape_Texture = Local_Texture;
  1832.          }
  1833.          END_CASE
  1834.  
  1835.          CASE (COLOUR_TOKEN)
  1836.             Local_Shape->Shape_Colour = Get_Colour();
  1837.          Parse_Colour (Local_Shape->Shape_Colour);
  1838.          END_CASE
  1839.  
  1840.  
  1841.  
  1842.          OTHERWISE
  1843.          Parse_Error (RIGHT_CURLY_TOKEN);
  1844.          END_CASE
  1845.          END_EXPECT
  1846.  
  1847.          return ((SHAPE *) Local_Shape);
  1848.       }
  1849.  
  1850.       SHAPE *Parse_Plane ()
  1851.       {
  1852.          PLANE *Local_Shape;
  1853.          CONSTANT Constant_Id;
  1854.          VECTOR Local_Vector;
  1855.          TEXTURE *Local_Texture;
  1856.          TEXTURE *temp_texture;
  1857.  
  1858.          Local_Shape = NULL;
  1859.  
  1860.          GET(LEFT_CURLY_TOKEN);
  1861.  
  1862.  
  1863.          EXPECT
  1864.          CASE (LEFT_ANGLE_TOKEN)
  1865.             UNGET
  1866.             Local_Shape = Get_Plane_Shape();
  1867.          Parse_Vector(&(Local_Shape -> Normal_Vector));
  1868.          Local_Shape->Distance = Parse_Float();
  1869.          Local_Shape->Distance *= -1.0;
  1870.          EXIT
  1871.          END_CASE
  1872.  
  1873.          CASE (IDENTIFIER_TOKEN)
  1874.             if ((Constant_Id = Find_Constant()) != -1)
  1875.                if (Constants[(int)Constant_Id].Constant_Type == PLANE_CONSTANT)
  1876.                   Local_Shape = (PLANE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1877.                else
  1878.                   Type_Error ();
  1879.             else
  1880.                Undeclared ();
  1881.          EXIT
  1882.          END_CASE
  1883.  
  1884.          OTHERWISE
  1885.          Parse_Error (LEFT_ANGLE_TOKEN);
  1886.          END_CASE
  1887.          END_EXPECT
  1888.  
  1889.          EXPECT
  1890.          CASE (RIGHT_CURLY_TOKEN)
  1891.             EXIT
  1892.             END_CASE
  1893.  
  1894.             CASE (TRANSLATE_TOKEN)
  1895.                Parse_Vector (&Local_Vector);
  1896.          Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1897.          END_CASE
  1898.  
  1899.          CASE (ROTATE_TOKEN)
  1900.             Parse_Vector (&Local_Vector);
  1901.          Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1902.          END_CASE
  1903.  
  1904.          CASE (SCALE_TOKEN)
  1905.             Parse_Vector (&Local_Vector);
  1906.          Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1907.          END_CASE
  1908.  
  1909.          CASE (INVERSE_TOKEN)
  1910.             Invert ((OBJECT *) Local_Shape);
  1911.          END_CASE
  1912.  
  1913.          CASE (TEXTURE_TOKEN)
  1914.             Local_Texture = Parse_Texture ();
  1915.          if (Local_Texture->Constant_Flag)
  1916.             Local_Texture = Copy_Texture(Local_Texture);
  1917.  
  1918.          {
  1919.             for (temp_texture = Local_Texture ;
  1920.                         temp_texture->Next_Texture != NULL ;
  1921.                         temp_texture = temp_texture->Next_Texture)
  1922.             {}
  1923.  
  1924.             temp_texture->Next_Texture = Local_Shape->Shape_Texture;
  1925.             Local_Shape->Shape_Texture = Local_Texture;
  1926.          }
  1927.          END_CASE
  1928.  
  1929.          CASE (COLOUR_TOKEN)
  1930.             Local_Shape->Shape_Colour = Get_Colour();
  1931.          Parse_Colour (Local_Shape->Shape_Colour);
  1932.          END_CASE
  1933.  
  1934.  
  1935.  
  1936.          OTHERWISE
  1937.          Parse_Error (RIGHT_CURLY_TOKEN);
  1938.          END_CASE
  1939.          END_EXPECT
  1940.  
  1941.          return ((SHAPE *) Local_Shape);
  1942.       }
  1943.  
  1944.       SHAPE *Parse_Height_Field ()
  1945.       {
  1946.          HEIGHT_FIELD *Local_Shape;
  1947.          CONSTANT Constant_Id;
  1948.          VECTOR Local_Vector;
  1949.          TEXTURE *Local_Texture;
  1950.          IMAGE *Image;
  1951.          int Image_Type;
  1952.  
  1953.          Local_Shape = NULL;
  1954.  
  1955.          GET(LEFT_CURLY_TOKEN);
  1956.  
  1957.          EXPECT  /* This should be modified to include other image types - CdW */
  1958.          CASE (GIF_TOKEN)
  1959.             Image_Type = GIF;
  1960.          Local_Shape = Get_Height_Field_Shape();
  1961.          if((Image = (IMAGE *) malloc(sizeof(IMAGE))) == NULL)
  1962.             Error("Out of memory. Cannot allocate space for Height Field (1st message).");
  1963.          GET(STRING_TOKEN); 
  1964.          Read_Gif_Image(Image,Token.Token_String);
  1965.          Local_Shape -> bounding_box -> bounds[0].x = 1.0;
  1966.          Local_Shape -> bounding_box -> bounds[0].y = 0.0;
  1967.          Local_Shape -> bounding_box -> bounds[0].z = 1.0;
  1968.          Local_Shape -> bounding_box -> bounds[1].x = Image -> width - 2.0;
  1969.          Local_Shape -> bounding_box -> bounds[1].y = 256.0;
  1970.          Local_Shape -> bounding_box -> bounds[1].z = Image -> height - 2.0;
  1971.          Make_Vector(&Local_Vector,1.0/(Image->width),1.0/256.0,1.0/(Image->height));
  1972.          Get_Scaling_Transformation(Local_Shape->Transformation,&Local_Vector);
  1973.          EXIT
  1974.          END_CASE
  1975.  
  1976.          CASE (POT_TOKEN)
  1977.             Image_Type = POT;
  1978.          Local_Shape = Get_Height_Field_Shape();
  1979.          if((Image = (IMAGE *) malloc(sizeof(IMAGE))) == NULL)
  1980.             Error("Out of memory. Cannot allocate space for Height Field (1st message).");
  1981.          GET(STRING_TOKEN); 
  1982.          Read_Gif_Image(Image,Token.Token_String);
  1983.          Local_Shape -> bounding_box -> bounds[0].x = 1.0;
  1984.          Local_Shape -> bounding_box -> bounds[0].y = 0.0;
  1985.          Local_Shape -> bounding_box -> bounds[0].z = 1.0;
  1986.          Local_Shape -> bounding_box -> bounds[1].x = Image -> width/2.0 - 2.0;
  1987.          Local_Shape -> bounding_box -> bounds[1].y = 256.0;
  1988.          Local_Shape -> bounding_box -> bounds[1].z = Image -> height - 2.0;
  1989.          Make_Vector(&Local_Vector,2.0/Image->width,1.0/256.0,1.0/Image->height);
  1990.          Get_Scaling_Transformation(Local_Shape->Transformation,&Local_Vector);
  1991.          EXIT
  1992.          END_CASE
  1993.  
  1994.          CASE (TGA_TOKEN)
  1995.             Image_Type = TGA;
  1996.          Local_Shape = Get_Height_Field_Shape();
  1997.          if((Image = (IMAGE *) malloc(sizeof(IMAGE))) == NULL)
  1998.             Error("Cannot allocate space for Height Field (1st message).");
  1999.          GET(STRING_TOKEN); 
  2000.          Read_Targa_Image(Image,Token.Token_String);
  2001.          Local_Shape -> bounding_box -> bounds[0].x = 1.0;
  2002.          Local_Shape -> bounding_box -> bounds[0].y = 0.0;
  2003.          Local_Shape -> bounding_box -> bounds[0].z = 1.0;
  2004.          Local_Shape -> bounding_box -> bounds[1].x = Image -> width - 2.0;
  2005.          Local_Shape -> bounding_box -> bounds[1].y = 256.0;
  2006.          Local_Shape -> bounding_box -> bounds[1].z = Image -> height - 2.0;
  2007.          Make_Vector(&Local_Vector,1.0/Image->width,1.0/256.0,1.0/Image->height);
  2008.          Get_Scaling_Transformation(Local_Shape->Transformation,&Local_Vector);  
  2009.          EXIT
  2010.          END_CASE
  2011.  
  2012.          CASE (IDENTIFIER_TOKEN)
  2013.             if ((Constant_Id = Find_Constant()) != -1)
  2014.                if (Constants[(int)Constant_Id].Constant_Type == HEIGHT_FIELD_CONSTANT)
  2015.                   Local_Shape = (HEIGHT_FIELD *)Copy((OBJECT *)Constants[(int)Constant_Id].Constant_Data);
  2016.                else
  2017.                   Type_Error ();
  2018.             else
  2019.                Undeclared ();
  2020.          EXIT
  2021.          END_CASE
  2022.  
  2023.          OTHERWISE
  2024.          Parse_Error (GIF_TOKEN);
  2025.          END_CASE
  2026.  
  2027.          END_EXPECT
  2028.  
  2029.          EXPECT
  2030.          CASE (RIGHT_CURLY_TOKEN)
  2031.             EXIT
  2032.             END_CASE
  2033.  
  2034.             CASE (WATER_LEVEL_TOKEN)
  2035.                Local_Shape -> bounding_box -> bounds[0].y = Parse_Float(); 
  2036.          END_CASE
  2037.  
  2038.          CASE (TRANSLATE_TOKEN)
  2039.             Parse_Vector (&Local_Vector);
  2040.          Translate ((OBJECT *) Local_Shape, &Local_Vector);
  2041.          END_CASE
  2042.  
  2043.          CASE (ROTATE_TOKEN)
  2044.             Parse_Vector (&Local_Vector);
  2045.          Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  2046.          END_CASE
  2047.  
  2048.          CASE (SCALE_TOKEN)
  2049.             Parse_Vector (&Local_Vector);
  2050.          Scale ((OBJECT *) Local_Shape, &Local_Vector);
  2051.          END_CASE
  2052.  
  2053.          CASE (INVERSE_TOKEN)
  2054.             Invert ((OBJECT *) Local_Shape);
  2055.          END_CASE
  2056.  
  2057.          CASE (TEXTURE_TOKEN)
  2058.             Local_Texture = Parse_Texture ();
  2059.          if (Local_Texture->Constant_Flag)
  2060.             Local_Texture = Copy_Texture(Local_Texture);
  2061.  
  2062.          {
  2063.             TEXTURE *temp_texture;
  2064.  
  2065.             for (temp_texture = Local_Texture ;
  2066.                         temp_texture->Next_Texture != NULL ;
  2067.                         temp_texture = temp_texture->Next_Texture)
  2068.             {}
  2069.  
  2070.             temp_texture->Next_Texture = Local_Shape->Shape_Texture;
  2071.             Local_Shape->Shape_Texture = Local_Texture;
  2072.          }
  2073.          END_CASE
  2074.  
  2075.          CASE (COLOUR_TOKEN)
  2076.             Local_Shape->Shape_Colour = Get_Colour();
  2077.          Parse_Colour (Local_Shape->Shape_Colour);
  2078.          END_CASE
  2079.  
  2080.  
  2081.          OTHERWISE
  2082.          Parse_Error (RIGHT_CURLY_TOKEN);
  2083.          END_CASE
  2084.          END_EXPECT
  2085.  
  2086.          Find_Hf_Min_Max(Local_Shape, Image, Image_Type);
  2087.          return ((SHAPE *) Local_Shape);
  2088.       }        
  2089.  
  2090.  
  2091.       SHAPE *Parse_Triangle ()
  2092.       {
  2093.          TRIANGLE *Local_Shape;
  2094.          CONSTANT Constant_Id;
  2095.          VECTOR Local_Vector;
  2096.          TEXTURE *Local_Texture;
  2097.          TEXTURE *temp_texture;
  2098.  
  2099.          Local_Shape = NULL;
  2100.  
  2101.          GET(LEFT_CURLY_TOKEN);
  2102.  
  2103.          EXPECT
  2104.          CASE (LEFT_ANGLE_TOKEN)
  2105.             UNGET
  2106.             Local_Shape = Get_Triangle_Shape();
  2107.          Parse_Vector (&Local_Shape->P1);
  2108.          Parse_Vector (&Local_Shape->P2);
  2109.          Parse_Vector (&Local_Shape->P3);
  2110.          if (!Compute_Triangle (Local_Shape)) {
  2111.             fprintf (stderr, "Degenerate triangle on line %d.  Please remove.\n",
  2112.                Token.Token_Line_No);
  2113.             Degenerate_Triangles = TRUE;
  2114.          }
  2115.          EXIT
  2116.          END_CASE
  2117.  
  2118.          CASE (IDENTIFIER_TOKEN)
  2119.             if ((Constant_Id = Find_Constant()) != -1)
  2120.                if (Constants[(int)Constant_Id].Constant_Type == TRIANGLE_CONSTANT)
  2121.                   Local_Shape = (TRIANGLE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  2122.                else
  2123.                   Type_Error ();
  2124.             else
  2125.                Undeclared ();
  2126.          EXIT
  2127.          END_CASE
  2128.  
  2129.          OTHERWISE
  2130.          Parse_Error (LEFT_ANGLE_TOKEN);
  2131.          END_CASE
  2132.          END_EXPECT
  2133.  
  2134.          EXPECT
  2135.          CASE (RIGHT_CURLY_TOKEN)
  2136.             EXIT
  2137.             END_CASE
  2138.  
  2139.             CASE (TRANSLATE_TOKEN)
  2140.                Parse_Vector (&Local_Vector);
  2141.          Translate ((OBJECT *) Local_Shape, &Local_Vector);
  2142.          END_CASE
  2143.  
  2144.          CASE (ROTATE_TOKEN)
  2145.             Parse_Vector (&Local_Vector);
  2146.          Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  2147.          END_CASE
  2148.  
  2149.          CASE (SCALE_TOKEN)
  2150.             Parse_Vector (&Local_Vector);
  2151.          Scale ((OBJECT *) Local_Shape, &Local_Vector);
  2152.          END_CASE
  2153.  
  2154.          CASE (INVERSE_TOKEN)
  2155.             Invert ((OBJECT *) Local_Shape);
  2156.          END_CASE
  2157.  
  2158.          CASE (TEXTURE_TOKEN)
  2159.             Local_Texture = Parse_Texture ();
  2160.          if (Local_Texture->Constant_Flag)
  2161.             Local_Texture = Copy_Texture(Local_Texture);
  2162.  
  2163.          {
  2164.             for (temp_texture = Local_Texture ;
  2165.                         temp_texture->Next_Texture != NULL ;
  2166.                         temp_texture = temp_texture->Next_Texture)
  2167.             {}
  2168.  
  2169.             temp_texture->Next_Texture = Local_Shape->Shape_Texture;
  2170.             Local_Shape->Shape_Texture = Local_Texture;
  2171.          }
  2172.          END_CASE
  2173.  
  2174.          CASE (COLOUR_TOKEN)
  2175.             Local_Shape->Shape_Colour = Get_Colour();
  2176.          Parse_Colour (Local_Shape->Shape_Colour);
  2177.          END_CASE
  2178.  
  2179.          OTHERWISE
  2180.          Parse_Error (RIGHT_CURLY_TOKEN);
  2181.          END_CASE
  2182.          END_EXPECT
  2183.  
  2184.          return ((SHAPE *) Local_Shape);
  2185.       }
  2186.  
  2187.       SHAPE *Parse_Smooth_Triangle ()
  2188.       {
  2189.          SMOOTH_TRIANGLE *Local_Shape;
  2190.          CONSTANT Constant_Id;
  2191.          VECTOR Local_Vector;
  2192.          TEXTURE *Local_Texture;
  2193.          TEXTURE *temp_texture;
  2194.  
  2195.          Local_Shape = NULL;
  2196.  
  2197.          GET(LEFT_CURLY_TOKEN);
  2198.  
  2199.          EXPECT
  2200.          CASE (LEFT_ANGLE_TOKEN)
  2201.             UNGET
  2202.             Local_Shape = (SMOOTH_TRIANGLE *) Get_Smooth_Triangle_Shape();
  2203.          Parse_Vector (&Local_Shape->P1);
  2204.          Parse_Vector (&Local_Shape->N1);
  2205.          VNormalize (Local_Shape->N1, Local_Shape->N1)
  2206.             Parse_Vector (&Local_Shape->P2);
  2207.          Parse_Vector (&Local_Shape->N2);
  2208.          VNormalize (Local_Shape->N2, Local_Shape->N2)
  2209.             Parse_Vector (&Local_Shape->P3);
  2210.          Parse_Vector (&Local_Shape->N3);
  2211.          VNormalize (Local_Shape->N3, Local_Shape->N3)
  2212.             if (!Compute_Triangle ((TRIANGLE *) Local_Shape)) {
  2213.                fprintf (stderr, "Degenerate triangle on line %d.  Please remove.\n",
  2214.                   Token.Token_Line_No);
  2215.                Degenerate_Triangles = TRUE;
  2216.             }
  2217.          EXIT
  2218.          END_CASE
  2219.  
  2220.          CASE (IDENTIFIER_TOKEN)
  2221.             if ((Constant_Id = Find_Constant()) != -1)
  2222.                if (Constants[(int)Constant_Id].Constant_Type == SMOOTH_TRIANGLE_CONSTANT)
  2223.                   Local_Shape = (SMOOTH_TRIANGLE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  2224.                else
  2225.                   Type_Error ();
  2226.             else
  2227.                Undeclared ();
  2228.          EXIT
  2229.          END_CASE
  2230.  
  2231.          OTHERWISE
  2232.          Parse_Error (LEFT_ANGLE_TOKEN);
  2233.          END_CASE
  2234.          END_EXPECT
  2235.  
  2236.          EXPECT
  2237.          CASE (RIGHT_CURLY_TOKEN)
  2238.             EXIT
  2239.             END_CASE
  2240.  
  2241.             CASE (TRANSLATE_TOKEN)
  2242.                Parse_Vector (&Local_Vector);
  2243.          Translate ((OBJECT *) Local_Shape, &Local_Vector);
  2244.          END_CASE
  2245.  
  2246.          CASE (ROTATE_TOKEN)
  2247.             Parse_Vector (&Local_Vector);
  2248.          Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  2249.          END_CASE
  2250.  
  2251.          CASE (SCALE_TOKEN)
  2252.             Parse_Vector (&Local_Vector);
  2253.          Scale ((OBJECT *) Local_Shape, &Local_Vector);
  2254.          END_CASE
  2255.  
  2256.          CASE (INVERSE_TOKEN)
  2257.             Invert ((OBJECT *) Local_Shape);
  2258.          END_CASE
  2259.  
  2260.          CASE (TEXTURE_TOKEN)
  2261.             Local_Texture = Parse_Texture ();
  2262.          if (Local_Texture->Constant_Flag)
  2263.             Local_Texture = Copy_Texture(Local_Texture);
  2264.  
  2265.          {
  2266.             for (temp_texture = Local_Texture ;
  2267.                         temp_texture->Next_Texture != NULL ;
  2268.                         temp_texture = temp_texture->Next_Texture)
  2269.             {}
  2270.  
  2271.             temp_texture->Next_Texture = Local_Shape->Shape_Texture;
  2272.             Local_Shape->Shape_Texture = Local_Texture;
  2273.          }
  2274.          END_CASE
  2275.  
  2276.          CASE (COLOUR_TOKEN)
  2277.             Local_Shape->Shape_Colour = Get_Colour();
  2278.          Parse_Colour (Local_Shape->Shape_Colour);
  2279.          END_CASE
  2280.  
  2281.          OTHERWISE
  2282.          Parse_Error (RIGHT_CURLY_TOKEN);
  2283.          END_CASE
  2284.          END_EXPECT
  2285.  
  2286.          return ((SHAPE *) Local_Shape);
  2287.       }
  2288.  
  2289.       SHAPE *Parse_Quadric ()
  2290.       {
  2291.          QUADRIC *Local_Shape;
  2292.          VECTOR Local_Vector;
  2293.          CONSTANT Constant_Id;
  2294.          TEXTURE *Local_Texture;
  2295.          TEXTURE *temp_texture;
  2296.  
  2297.          Local_Shape = NULL;
  2298.  
  2299.          GET(LEFT_CURLY_TOKEN);
  2300.  
  2301.          EXPECT
  2302.          CASE (LEFT_ANGLE_TOKEN)
  2303.             UNGET
  2304.             Local_Shape = Get_Quadric_Shape();
  2305.          Parse_Vector(&(Local_Shape -> Object_2_Terms));
  2306.          Parse_Vector(&(Local_Shape -> Object_Mixed_Terms));
  2307.          Parse_Vector(&(Local_Shape -> Object_Terms));
  2308.          (Local_Shape -> Object_Constant) = Parse_Float();
  2309.          Local_Shape -> Non_Zero_Square_Term = 
  2310.          !((Local_Shape -> Object_2_Terms.x == 0.0)
  2311.             && (Local_Shape -> Object_2_Terms.y == 0.0)
  2312.             && (Local_Shape -> Object_2_Terms.z == 0.0)
  2313.             && (Local_Shape -> Object_Mixed_Terms.x == 0.0)
  2314.             && (Local_Shape -> Object_Mixed_Terms.y == 0.0)
  2315.             && (Local_Shape -> Object_Mixed_Terms.z == 0.0));
  2316.          EXIT
  2317.          END_CASE
  2318.  
  2319.          CASE (IDENTIFIER_TOKEN)
  2320.             if ((Constant_Id = Find_Constant()) != -1)
  2321.                if (Constants[(int)Constant_Id].Constant_Type == QUADRIC_CONSTANT)
  2322.                   Local_Shape = (QUADRIC *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  2323.                else
  2324.                   Type_Error ();
  2325.             else
  2326.                Undeclared ();
  2327.          EXIT
  2328.          END_CASE
  2329.  
  2330.          OTHERWISE
  2331.          Parse_Error (LEFT_ANGLE_TOKEN);
  2332.          END_CASE
  2333.          END_EXPECT
  2334.  
  2335.          EXPECT
  2336.          CASE (RIGHT_CURLY_TOKEN)
  2337.             EXIT
  2338.             END_CASE
  2339.  
  2340.             CASE (TRANSLATE_TOKEN)
  2341.                Parse_Vector (&Local_Vector);
  2342.          Translate ((OBJECT *) Local_Shape, &Local_Vector);
  2343.          END_CASE
  2344.  
  2345.          CASE (ROTATE_TOKEN)
  2346.             Parse_Vector (&Local_Vector);
  2347.          Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  2348.          END_CASE
  2349.  
  2350.          CASE (SCALE_TOKEN)
  2351.             Parse_Vector (&Local_Vector);
  2352.          Scale ((OBJECT *) Local_Shape, &Local_Vector);
  2353.          END_CASE
  2354.  
  2355.          CASE (INVERSE_TOKEN)
  2356.             Invert ((OBJECT *) Local_Shape);
  2357.          END_CASE
  2358.  
  2359.          CASE (TEXTURE_TOKEN)
  2360.             Local_Texture = Parse_Texture ();
  2361.          if (Local_Texture->Constant_Flag)
  2362.             Local_Texture = Copy_Texture(Local_Texture);
  2363.  
  2364.          {
  2365.             for (temp_texture = Local_Texture ;
  2366.                         temp_texture->Next_Texture != NULL ;
  2367.                         temp_texture = temp_texture->Next_Texture)
  2368.             {}
  2369.  
  2370.             temp_texture->Next_Texture = Local_Shape->Shape_Texture;
  2371.             Local_Shape->Shape_Texture = Local_Texture;
  2372.          }
  2373.          END_CASE
  2374.  
  2375.          CASE (COLOUR_TOKEN)
  2376.             Local_Shape->Shape_Colour = Get_Colour();
  2377.          Parse_Colour (Local_Shape->Shape_Colour);
  2378.          END_CASE
  2379.  
  2380.          OTHERWISE
  2381.          Parse_Error (RIGHT_CURLY_TOKEN);
  2382.          END_CASE
  2383.          END_EXPECT
  2384.  
  2385.          return ((SHAPE *) Local_Shape);
  2386.       }
  2387.  
  2388.       SHAPE *Parse_Poly (known_order)
  2389.          int known_order;
  2390.       {
  2391.          POLY *Local_Shape;
  2392.          VECTOR Local_Vector;
  2393.          CONSTANT Constant_Id;
  2394.          int order;
  2395.          TEXTURE *Local_Texture;
  2396.  
  2397.          if (known_order > 0)
  2398.             Local_Shape = Get_Poly_Shape(known_order);
  2399.          else
  2400.             Local_Shape = NULL;
  2401.  
  2402.          GET(LEFT_CURLY_TOKEN);
  2403.  
  2404.          EXPECT
  2405.          CASE3 (DASH_TOKEN, PLUS_TOKEN, FLOAT_TOKEN)
  2406.             UNGET
  2407.             if (Local_Shape != NULL)
  2408.                Error("The order of a polynomial may not be specified twice");
  2409.          order = (int)Parse_Float();
  2410.          if (order < 2 || order > MAX_ORDER)
  2411.             Error("Order of Poly is out of range");
  2412.          Local_Shape = Get_Poly_Shape(order);
  2413.          END_CASE
  2414.  
  2415.          CASE (LEFT_ANGLE_TOKEN)
  2416.             UNGET
  2417.             if (Local_Shape == NULL)
  2418.                printf("Need the order of the Poly");
  2419.          Parse_Coeffs(Local_Shape->Order, &(Local_Shape->Coeffs[0]));
  2420.          EXIT
  2421.          END_CASE
  2422.  
  2423.          CASE (IDENTIFIER_TOKEN)
  2424.             if ((Constant_Id = Find_Constant()) != -1)
  2425.                if (Constants[(int)Constant_Id].Constant_Type == POLY_CONSTANT)
  2426.                   Local_Shape = (POLY *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  2427.                else
  2428.                   Type_Error ();
  2429.             else
  2430.                Undeclared ();
  2431.          EXIT
  2432.          END_CASE
  2433.  
  2434.          OTHERWISE
  2435.          Parse_Error (LEFT_ANGLE_TOKEN);
  2436.          END_CASE
  2437.          END_EXPECT
  2438.  
  2439.          EXPECT
  2440.          CASE (RIGHT_CURLY_TOKEN)
  2441.             EXIT
  2442.             END_CASE
  2443.  
  2444.             CASE (STURM_TOKEN)
  2445.                Local_Shape->Sturm_Flag = 1;
  2446.          END_CASE
  2447.  
  2448.          CASE (TRANSLATE_TOKEN)
  2449.             Parse_Vector (&Local_Vector);
  2450.          Translate ((OBJECT *) Local_Shape, &Local_Vector);
  2451.          END_CASE
  2452.  
  2453.          CASE (ROTATE_TOKEN)
  2454.             Parse_Vector (&Local_Vector);
  2455.          Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  2456.          END_CASE
  2457.  
  2458.          CASE (SCALE_TOKEN)
  2459.             Parse_Vector (&Local_Vector);
  2460.          Scale ((OBJECT *) Local_Shape, &Local_Vector);
  2461.          END_CASE
  2462.  
  2463.          CASE (INVERSE_TOKEN)
  2464.             Invert ((OBJECT *) Local_Shape);
  2465.          END_CASE
  2466.  
  2467.          CASE (TEXTURE_TOKEN)
  2468.             Local_Texture = Parse_Texture ();
  2469.          if (Local_Texture->Constant_Flag)
  2470.             Local_Texture = Copy_Texture(Local_Texture);
  2471.  
  2472.          Link ((OBJECT *) Local_Texture,
  2473.             (OBJECT **) &Local_Texture->Next_Texture,
  2474.             (OBJECT **) &Local_Shape->Shape_Texture);
  2475.          END_CASE
  2476.  
  2477.          CASE (COLOUR_TOKEN)
  2478.             Local_Shape->Shape_Colour = Get_Colour();
  2479.          Parse_Colour (Local_Shape->Shape_Colour);
  2480.          END_CASE
  2481.  
  2482.          OTHERWISE
  2483.          Parse_Error (RIGHT_CURLY_TOKEN);
  2484.          END_CASE
  2485.          END_EXPECT
  2486.  
  2487.          return ((SHAPE *) Local_Shape);
  2488.       }
  2489.  
  2490.       SHAPE *Parse_Bicubic_Patch ()
  2491.       {
  2492.          BICUBIC_PATCH *Local_Shape;
  2493.          VECTOR Local_Vector;
  2494.          CONSTANT Constant_Id;
  2495.          TEXTURE *Local_Texture;
  2496.          int i, j;
  2497.  
  2498.          GET(LEFT_CURLY_TOKEN);
  2499.  
  2500.          EXPECT
  2501.          CASE3 (DASH_TOKEN, PLUS_TOKEN, FLOAT_TOKEN)
  2502.             UNGET
  2503.             Local_Shape = Get_Bicubic_Patch_Shape();
  2504.          Local_Shape->Patch_Type = (int)Parse_Float();
  2505.          if (Local_Shape->Patch_Type == 2 ||
  2506.             Local_Shape->Patch_Type == 3)
  2507.             Local_Shape->Flatness_Value = Parse_Float();
  2508.          else
  2509.             Local_Shape->Flatness_Value = 0.1;
  2510.          Local_Shape->U_Steps = (int)Parse_Float();
  2511.          Local_Shape->V_Steps = (int)Parse_Float();
  2512.          for (i=0;i<4;i++) for (j=0;j<4;j++)
  2513.             Parse_Vector(&(Local_Shape -> Control_Points[i][j]));
  2514.          Precompute_Patch_Values(Local_Shape); /* interpolated mesh coords */
  2515.          EXIT
  2516.          END_CASE
  2517.  
  2518.          CASE (IDENTIFIER_TOKEN)
  2519.             if ((Constant_Id = Find_Constant()) != -1)
  2520.                if (Constants[(int)Constant_Id].Constant_Type==BICUBIC_PATCH_CONSTANT)
  2521.                   Local_Shape = (BICUBIC_PATCH *) Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  2522.                else
  2523.                   Type_Error ();
  2524.             else
  2525.                Undeclared ();
  2526.          EXIT
  2527.          END_CASE
  2528.  
  2529.          OTHERWISE
  2530.          Parse_Error (LEFT_ANGLE_TOKEN);
  2531.          END_CASE
  2532.          END_EXPECT
  2533.  
  2534.          EXPECT
  2535.          CASE (RIGHT_CURLY_TOKEN)
  2536.             EXIT
  2537.             END_CASE
  2538.  
  2539.             CASE (TRANSLATE_TOKEN)
  2540.                Parse_Vector (&Local_Vector);
  2541.          Translate ((OBJECT *) Local_Shape, &Local_Vector);
  2542.          END_CASE
  2543.  
  2544.          CASE (ROTATE_TOKEN)
  2545.             Parse_Vector (&Local_Vector);
  2546.          Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  2547.          END_CASE
  2548.  
  2549.          CASE (SCALE_TOKEN)
  2550.             Parse_Vector (&Local_Vector);
  2551.          Scale ((OBJECT *) Local_Shape, &Local_Vector);
  2552.          END_CASE
  2553.  
  2554.          CASE (INVERSE_TOKEN)
  2555.             Invert ((OBJECT *) Local_Shape);
  2556.          END_CASE
  2557.  
  2558.          CASE (TEXTURE_TOKEN)
  2559.             Local_Texture = Parse_Texture ();
  2560.          if (Local_Texture->Constant_Flag)
  2561.             Local_Texture = Copy_Texture(Local_Texture);
  2562.  
  2563.          Link ((OBJECT *) Local_Texture,
  2564.             (OBJECT **) &Local_Texture->Next_Texture,
  2565.             (OBJECT **) &Local_Shape->Shape_Texture);
  2566.          END_CASE
  2567.  
  2568.          CASE (COLOUR_TOKEN)
  2569.             Local_Shape->Shape_Colour = Get_Colour();
  2570.          Parse_Colour (Local_Shape->Shape_Colour);
  2571.          END_CASE
  2572.  
  2573.  
  2574.  
  2575.          OTHERWISE
  2576.          Parse_Error (RIGHT_CURLY_TOKEN);
  2577.          END_CASE
  2578.          END_EXPECT
  2579.  
  2580.          return ((SHAPE *) Local_Shape);
  2581.       }
  2582.  
  2583.       SHAPE *Parse_Box ()
  2584.       {
  2585.          BOX *Local_Shape;
  2586.          CONSTANT Constant_Id;
  2587.          VECTOR Local_Vector;
  2588.          TEXTURE *Local_Texture;
  2589.          TEXTURE *temp_texture;
  2590.  
  2591.          Local_Shape = NULL;
  2592.          EXPECT
  2593.          CASE (LEFT_CURLY_TOKEN)
  2594.             EXIT
  2595.             END_CASE
  2596.             OTHERWISE
  2597.             Parse_Error (LEFT_CURLY_TOKEN);
  2598.          END_CASE
  2599.          END_EXPECT
  2600.  
  2601.          EXPECT
  2602.          CASE (LEFT_ANGLE_TOKEN)
  2603.             UNGET
  2604.             Local_Shape = Get_Box_Shape();
  2605.          Parse_Vector(&(Local_Shape->bounds[0]));
  2606.          Parse_Vector(&(Local_Shape->bounds[1]));
  2607.          EXIT
  2608.          END_CASE
  2609.  
  2610.          CASE (IDENTIFIER_TOKEN)
  2611.             if ((Constant_Id = Find_Constant()) != -1)
  2612.                if (Constants[(int)Constant_Id].Constant_Type == BOX_CONSTANT)
  2613.                   Local_Shape = (BOX *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  2614.                else
  2615.                   Type_Error ();
  2616.             else
  2617.                Undeclared ();
  2618.          EXIT
  2619.          END_CASE
  2620.  
  2621.          OTHERWISE
  2622.          Parse_Error (LEFT_ANGLE_TOKEN);
  2623.          END_CASE
  2624.          END_EXPECT
  2625.  
  2626.          EXPECT
  2627.          CASE (RIGHT_CURLY_TOKEN)
  2628.             EXIT
  2629.             END_CASE
  2630.  
  2631.             CASE (TRANSLATE_TOKEN)
  2632.                Parse_Vector (&Local_Vector);
  2633.          Translate ((OBJECT *) Local_Shape, &Local_Vector);
  2634.          END_CASE
  2635.  
  2636.          CASE (ROTATE_TOKEN)
  2637.             Parse_Vector (&Local_Vector);
  2638.          Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  2639.          END_CASE
  2640.  
  2641.          CASE (SCALE_TOKEN)
  2642.             Parse_Vector (&Local_Vector);
  2643.          Scale ((OBJECT *) Local_Shape, &Local_Vector);
  2644.          END_CASE
  2645.  
  2646.          CASE (INVERSE_TOKEN)
  2647.             Invert ((OBJECT *) Local_Shape);
  2648.          END_CASE
  2649.  
  2650.          CASE (TEXTURE_TOKEN)
  2651.             Local_Texture = Parse_Texture ();
  2652.          if (Local_Texture->Constant_Flag)
  2653.             Local_Texture = Copy_Texture(Local_Texture);
  2654.  
  2655.          {
  2656.             for (temp_texture = Local_Texture ;
  2657.                         temp_texture->Next_Texture != NULL ;
  2658.                         temp_texture = temp_texture->Next_Texture)
  2659.             {}
  2660.  
  2661.             temp_texture->Next_Texture = Local_Shape->Shape_Texture;
  2662.             Local_Shape->Shape_Texture = Local_Texture;
  2663.          }
  2664.          END_CASE
  2665.  
  2666.          CASE (COLOUR_TOKEN)
  2667.             Local_Shape->Shape_Colour = Get_Colour();
  2668.          Parse_Colour (Local_Shape->Shape_Colour);
  2669.          END_CASE
  2670.  
  2671.          OTHERWISE
  2672.          Parse_Error (RIGHT_CURLY_TOKEN);
  2673.          END_CASE
  2674.          END_EXPECT
  2675.  
  2676.          return ((SHAPE *) Local_Shape);
  2677.       }
  2678.  
  2679.       SHAPE *Parse_Blob ()
  2680.       {
  2681.          BLOB *Local_Shape;
  2682.          CONSTANT Constant_Id;
  2683.          VECTOR Local_Vector;
  2684.          TEXTURE *Local_Texture;
  2685.          TEXTURE *temp_texture;
  2686.          DBL threshold;
  2687.          int npoints;
  2688.          blobstackptr blob_components, blob_component;
  2689.  
  2690.          Local_Shape = NULL;
  2691.          EXPECT
  2692.          CASE (LEFT_CURLY_TOKEN)
  2693.             EXIT
  2694.             END_CASE
  2695.             OTHERWISE
  2696.             Parse_Error (LEFT_CURLY_TOKEN);
  2697.          END_CASE
  2698.          END_EXPECT
  2699.  
  2700.          EXPECT
  2701.          CASE2 (THRESHOLD_TOKEN, COMPONENT_TOKEN)
  2702.             UNGET
  2703.             Local_Shape = Get_Blob_Shape();
  2704.          blob_components = NULL;
  2705.          npoints = 0;
  2706.          threshold = 1.0;
  2707.  
  2708.          /* Here is where we get the blob coefficients */
  2709.          EXPECT
  2710.          CASE (THRESHOLD_TOKEN)
  2711.             threshold = Parse_Float();
  2712.          END_CASE
  2713.  
  2714.          CASE (COMPONENT_TOKEN)
  2715.             blob_component = (blobstackptr) malloc(sizeof(struct
  2716.                blob_list_struct));
  2717.          if (blob_component == NULL)
  2718.             Error("Out of Memory! Cannot allocate blob component");
  2719.          blob_component->elem.coeffs[2] = Parse_Float();
  2720.          blob_component->elem.radius2   = Parse_Float();
  2721.          Parse_Vector(&blob_component->elem.pos);
  2722.          blob_component->next = blob_components;
  2723.          blob_components = blob_component;
  2724.          npoints++;
  2725.          END_CASE
  2726.  
  2727.          OTHERWISE
  2728.          UNGET
  2729.          EXIT
  2730.          END_CASE
  2731.          END_EXPECT
  2732.  
  2733.          /* Finally, process the information */
  2734.          MakeBlob((OBJECT *)Local_Shape, threshold, blob_components, npoints, 0);
  2735.          EXIT
  2736.          END_CASE
  2737.  
  2738.          CASE (IDENTIFIER_TOKEN)
  2739.             if ((Constant_Id = Find_Constant()) != -1)
  2740.                if (Constants[(int)Constant_Id].Constant_Type == BLOB_CONSTANT)
  2741.                   Local_Shape = (BLOB *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  2742.                else
  2743.                   Type_Error ();
  2744.             else
  2745.                Undeclared ();
  2746.          EXIT
  2747.          END_CASE
  2748.  
  2749.          OTHERWISE
  2750.          Parse_Error (FLOAT_TOKEN);
  2751.          END_CASE
  2752.          END_EXPECT
  2753.  
  2754.          EXPECT
  2755.          CASE (RIGHT_CURLY_TOKEN)
  2756.             EXIT
  2757.             END_CASE
  2758.  
  2759.             CASE (STURM_TOKEN)
  2760.                Local_Shape->Sturm_Flag = 1;
  2761.          END_CASE
  2762.  
  2763.          CASE (TRANSLATE_TOKEN)
  2764.             Parse_Vector (&Local_Vector);
  2765.          Translate ((OBJECT *) Local_Shape, &Local_Vector);
  2766.          END_CASE
  2767.  
  2768.          CASE (ROTATE_TOKEN)
  2769.             Parse_Vector (&Local_Vector);
  2770.          Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  2771.          END_CASE
  2772.  
  2773.          CASE (SCALE_TOKEN)
  2774.             Parse_Vector (&Local_Vector);
  2775.          Scale ((OBJECT *) Local_Shape, &Local_Vector);
  2776.          END_CASE
  2777.  
  2778.          CASE (INVERSE_TOKEN)
  2779.             Invert ((OBJECT *) Local_Shape);
  2780.          END_CASE
  2781.  
  2782.          CASE (TEXTURE_TOKEN)
  2783.             Local_Texture = Parse_Texture ();
  2784.          if (Local_Texture->Constant_Flag)
  2785.             Local_Texture = Copy_Texture(Local_Texture);
  2786.  
  2787.          {
  2788.             for (temp_texture = Local_Texture ;
  2789.                         temp_texture->Next_Texture != NULL ;
  2790.                         temp_texture = temp_texture->Next_Texture)
  2791.             {}
  2792.  
  2793.             temp_texture->Next_Texture = Local_Shape->Shape_Texture;
  2794.             Local_Shape->Shape_Texture = Local_Texture;
  2795.          }
  2796.          END_CASE
  2797.  
  2798.          CASE (COLOUR_TOKEN)
  2799.             Local_Shape->Shape_Colour = Get_Colour();
  2800.          Parse_Colour (Local_Shape->Shape_Colour);
  2801.          END_CASE
  2802.  
  2803.          OTHERWISE
  2804.          Parse_Error (RIGHT_CURLY_TOKEN);
  2805.          END_CASE
  2806.          END_EXPECT
  2807.  
  2808.          return ((SHAPE *) Local_Shape);
  2809.       }
  2810.  
  2811.  
  2812.       CSG_SHAPE *Parse_CSG (type, Parent_Object)
  2813.          int type;
  2814.       OBJECT *Parent_Object;
  2815.       {
  2816.          CSG_SHAPE *Container = NULL;
  2817.          SHAPE *Local_Shape;
  2818.          VECTOR Local_Vector;
  2819.          CONSTANT Constant_Id;
  2820.          int First_Shape_Parsed = FALSE;
  2821.  
  2822.          if (type == CSG_UNION_TYPE)
  2823.             Container = Get_CSG_Union ();
  2824.  
  2825.          else if ((type == CSG_INTERSECTION_TYPE) || (type == CSG_DIFFERENCE_TYPE))
  2826.             Container = Get_CSG_Intersection ();
  2827.  
  2828.          Container -> Parent_Object = Parent_Object;
  2829.  
  2830.          GET(LEFT_CURLY_TOKEN);
  2831.  
  2832.          EXPECT
  2833.          CASE (IDENTIFIER_TOKEN)
  2834.             if ((Constant_Id = Find_Constant()) != -1)
  2835.                if ((Constants[(int)Constant_Id].Constant_Type == CSG_INTERSECTION_CONSTANT)
  2836.                   || (Constants[(int)Constant_Id].Constant_Type == CSG_UNION_CONSTANT)
  2837.                   || (Constants[(int)Constant_Id].Constant_Type == CSG_DIFFERENCE_CONSTANT)) {
  2838.                   free (Container);
  2839.                   Container = (CSG_SHAPE *) Copy ((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  2840.                   Set_CSG_Parents(Container, Parent_Object);
  2841.                }
  2842.                else
  2843.                   Type_Error ();
  2844.             else
  2845.                Undeclared ();
  2846.          END_CASE          
  2847.  
  2848.          CASE (LIGHT_SOURCE_TOKEN)
  2849.             Local_Shape = Parse_Light_Source ();
  2850.          Local_Shape -> Parent_Object = Parent_Object;
  2851.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2852.             Invert ((OBJECT *) Local_Shape);
  2853.          First_Shape_Parsed = TRUE;
  2854.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2855.             (OBJECT **) &(Container -> Shapes));
  2856.          END_CASE
  2857.  
  2858.          CASE (SPHERE_TOKEN)
  2859.             Local_Shape = Parse_Sphere ();
  2860.          Local_Shape -> Parent_Object = Parent_Object;
  2861.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2862.             Invert ((OBJECT *) Local_Shape);
  2863.          First_Shape_Parsed = TRUE;
  2864.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2865.             (OBJECT **) &(Container -> Shapes));
  2866.          END_CASE
  2867.  
  2868.          CASE (PLANE_TOKEN)
  2869.             Local_Shape = Parse_Plane ();
  2870.          Local_Shape -> Parent_Object = Parent_Object;
  2871.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2872.             Invert ((OBJECT *) Local_Shape);
  2873.          First_Shape_Parsed = TRUE;
  2874.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2875.             (OBJECT **) &(Container -> Shapes));
  2876.          END_CASE
  2877.  
  2878.          CASE (TRIANGLE_TOKEN)
  2879.             Local_Shape = Parse_Triangle ();
  2880.          Local_Shape -> Parent_Object = Parent_Object;
  2881.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2882.             Invert ((OBJECT *) Local_Shape);
  2883.          First_Shape_Parsed = TRUE;
  2884.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2885.             (OBJECT **) &(Container -> Shapes));
  2886.          END_CASE
  2887.  
  2888.          CASE (SMOOTH_TRIANGLE_TOKEN)
  2889.             Local_Shape = Parse_Smooth_Triangle ();
  2890.          Local_Shape -> Parent_Object = Parent_Object;
  2891.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2892.             Invert ((OBJECT *) Local_Shape);
  2893.          First_Shape_Parsed = TRUE;
  2894.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2895.             (OBJECT **) &(Container -> Shapes));
  2896.          END_CASE
  2897.  
  2898.          CASE (QUADRIC_TOKEN)
  2899.             Local_Shape = Parse_Quadric ();
  2900.          Local_Shape -> Parent_Object = Parent_Object;
  2901.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2902.             Invert ((OBJECT *) Local_Shape);
  2903.          First_Shape_Parsed = TRUE;
  2904.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2905.             (OBJECT **) &(Container -> Shapes));
  2906.          END_CASE
  2907.  
  2908.          CASE (HEIGHT_FIELD_TOKEN)
  2909.             Local_Shape = Parse_Height_Field ();
  2910.          Local_Shape -> Parent_Object = Parent_Object;
  2911.          if((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2912.             Invert((OBJECT *) Local_Shape);
  2913.          First_Shape_Parsed = TRUE;
  2914.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape-> Next_Object),
  2915.             (OBJECT **) &(Container -> Shapes));
  2916.          END_CASE
  2917.  
  2918.  
  2919.          CASE (CUBIC_TOKEN)
  2920.             Local_Shape = Parse_Poly (3);
  2921.          Local_Shape -> Parent_Object = Parent_Object;
  2922.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2923.             Invert ((OBJECT *) Local_Shape);
  2924.          First_Shape_Parsed = TRUE;
  2925.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2926.             (OBJECT **) &(Container -> Shapes));
  2927.          END_CASE
  2928.  
  2929.          CASE (QUARTIC_TOKEN)
  2930.             Local_Shape = Parse_Poly (4);
  2931.          Local_Shape -> Parent_Object = Parent_Object;
  2932.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2933.             Invert ((OBJECT *) Local_Shape);
  2934.          First_Shape_Parsed = TRUE;
  2935.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2936.             (OBJECT **) &(Container -> Shapes));
  2937.          END_CASE
  2938.  
  2939.          CASE (POLY_TOKEN)
  2940.             Local_Shape = Parse_Poly (0);
  2941.          Local_Shape -> Parent_Object = Parent_Object;
  2942.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2943.             Invert ((OBJECT *) Local_Shape);
  2944.          First_Shape_Parsed = TRUE;
  2945.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2946.             (OBJECT **) &(Container -> Shapes));
  2947.          END_CASE
  2948.  
  2949.          CASE (BOX_TOKEN)
  2950.             Local_Shape = Parse_Box ();
  2951.          Local_Shape -> Parent_Object = Parent_Object;
  2952.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2953.             Invert ((OBJECT *) Local_Shape);
  2954.          First_Shape_Parsed = TRUE;
  2955.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2956.             (OBJECT **) &(Container -> Shapes));
  2957.          END_CASE
  2958.  
  2959.          CASE (BLOB_TOKEN)
  2960.             Local_Shape = Parse_Blob ();
  2961.          Local_Shape -> Parent_Object = Parent_Object;
  2962.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2963.             Invert ((OBJECT *) Local_Shape);
  2964.          First_Shape_Parsed = TRUE;
  2965.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2966.             (OBJECT **) &(Container -> Shapes));
  2967.          END_CASE
  2968.  
  2969.          CASE (BICUBIC_PATCH_TOKEN)
  2970.             Local_Shape = Parse_Bicubic_Patch ();
  2971.          Local_Shape -> Parent_Object = Parent_Object;
  2972.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2973.             Invert ((OBJECT *) Local_Shape);
  2974.          First_Shape_Parsed = TRUE;
  2975.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2976.             (OBJECT **) &(Container -> Shapes));
  2977.          END_CASE
  2978.  
  2979.          CASE (UNION_TOKEN)
  2980.             Local_Shape = (SHAPE *) Parse_CSG (CSG_UNION_TYPE, Parent_Object);
  2981.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2982.             Invert ((OBJECT *) Local_Shape);
  2983.          First_Shape_Parsed = TRUE;
  2984.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2985.             (OBJECT **) &(Container -> Shapes));
  2986.          END_CASE
  2987.  
  2988.          CASE (INTERSECTION_TOKEN)
  2989.             Local_Shape = (SHAPE *) Parse_CSG (CSG_INTERSECTION_TYPE, Parent_Object);
  2990.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  2991.             Invert ((OBJECT *) Local_Shape);
  2992.          First_Shape_Parsed = TRUE;
  2993.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  2994.             (OBJECT **) &(Container -> Shapes));
  2995.          END_CASE
  2996.  
  2997.          CASE (DIFFERENCE_TOKEN)
  2998.             Local_Shape = (SHAPE *) Parse_CSG (CSG_DIFFERENCE_TYPE, Parent_Object);
  2999.          if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  3000.             Invert ((OBJECT *) Local_Shape);
  3001.          First_Shape_Parsed = TRUE;
  3002.          Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  3003.             (OBJECT **) &(Container -> Shapes));
  3004.          END_CASE
  3005.  
  3006.          OTHERWISE
  3007.          UNGET
  3008.          EXIT
  3009.          END_CASE
  3010.          END_EXPECT
  3011.  
  3012.          EXPECT
  3013.          CASE (RIGHT_CURLY_TOKEN)
  3014.             EXIT
  3015.             END_CASE
  3016.  
  3017.             CASE (TRANSLATE_TOKEN)
  3018.                Parse_Vector (&Local_Vector);
  3019.          Translate((OBJECT *) Container, &Local_Vector);
  3020.          END_CASE
  3021.  
  3022.          CASE (ROTATE_TOKEN)
  3023.             Parse_Vector (&Local_Vector);
  3024.          Rotate ((OBJECT *) Container, &Local_Vector);
  3025.          END_CASE
  3026.  
  3027.          CASE (SCALE_TOKEN)
  3028.             Parse_Vector (&Local_Vector);
  3029.          Scale ((OBJECT *) Container, &Local_Vector);
  3030.          END_CASE
  3031.  
  3032.          CASE (INVERSE_TOKEN)
  3033.             Invert ((OBJECT *) Container);
  3034.          END_CASE
  3035.  
  3036.          OTHERWISE
  3037.          if (type == CSG_UNION_TYPE)
  3038.             Parse_Error (RIGHT_CURLY_TOKEN);
  3039.          else if (type == CSG_INTERSECTION_TYPE)
  3040.             Parse_Error (RIGHT_CURLY_TOKEN);
  3041.          else
  3042.             Parse_Error (RIGHT_CURLY_TOKEN);
  3043.          END_CASE
  3044.          END_EXPECT
  3045.  
  3046.          return ((CSG_SHAPE *) Container);
  3047.       }
  3048.  
  3049.       SHAPE *Parse_Shape (Object)
  3050.          OBJECT *Object;
  3051.       {
  3052.          SHAPE *Local_Shape = NULL;
  3053.  
  3054.          EXPECT
  3055.          CASE (LIGHT_SOURCE_TOKEN)
  3056.             Local_Shape = Parse_Light_Source ();
  3057.          Local_Shape -> Parent_Object = Object;
  3058.          EXIT
  3059.          END_CASE
  3060.  
  3061.  
  3062.          CASE (SPHERE_TOKEN)
  3063.             Local_Shape = Parse_Sphere ();
  3064.          Local_Shape -> Parent_Object = Object;
  3065.          EXIT
  3066.          END_CASE
  3067.  
  3068.          CASE (PLANE_TOKEN)
  3069.             Local_Shape = Parse_Plane ();
  3070.          Local_Shape -> Parent_Object = Object;
  3071.          EXIT
  3072.          END_CASE
  3073.  
  3074.          CASE (TRIANGLE_TOKEN)
  3075.             Local_Shape = Parse_Triangle ();
  3076.          Local_Shape -> Parent_Object = Object;
  3077.          EXIT
  3078.          END_CASE
  3079.  
  3080.          CASE (SMOOTH_TRIANGLE_TOKEN)
  3081.             Local_Shape = Parse_Smooth_Triangle ();
  3082.          Local_Shape -> Parent_Object = Object;
  3083.          EXIT
  3084.          END_CASE
  3085.  
  3086.          CASE (QUADRIC_TOKEN)
  3087.             Local_Shape = Parse_Quadric ();
  3088.          Local_Shape -> Parent_Object = Object;
  3089.          EXIT
  3090.          END_CASE
  3091.  
  3092.          CASE (HEIGHT_FIELD_TOKEN)
  3093.             Local_Shape = Parse_Height_Field ();
  3094.          Local_Shape -> Parent_Object = Object;
  3095.          EXIT
  3096.          END_CASE
  3097.  
  3098.          CASE (CUBIC_TOKEN)
  3099.             Local_Shape = Parse_Poly (3);
  3100.          Local_Shape -> Parent_Object = Object;
  3101.          EXIT
  3102.          END_CASE
  3103.  
  3104.          CASE (QUARTIC_TOKEN)
  3105.             Local_Shape = Parse_Poly (4);
  3106.          Local_Shape -> Parent_Object = Object;
  3107.          EXIT
  3108.          END_CASE
  3109.  
  3110.          CASE (POLY_TOKEN)
  3111.             Local_Shape = Parse_Poly (0);
  3112.          Local_Shape -> Parent_Object = Object;
  3113.          EXIT
  3114.          END_CASE
  3115.  
  3116.          CASE (BOX_TOKEN)
  3117.             Local_Shape = Parse_Box ();
  3118.          Local_Shape -> Parent_Object = Object;
  3119.          EXIT
  3120.          END_CASE
  3121.  
  3122.          CASE (BLOB_TOKEN)
  3123.             Local_Shape = Parse_Blob ();
  3124.          Local_Shape -> Parent_Object = Object;
  3125.          EXIT
  3126.          END_CASE
  3127.  
  3128.          CASE (BICUBIC_PATCH_TOKEN)
  3129.             Local_Shape = Parse_Bicubic_Patch ();
  3130.          Local_Shape -> Parent_Object = Object;
  3131.          EXIT
  3132.          END_CASE
  3133.  
  3134.          CASE (UNION_TOKEN)
  3135.             Local_Shape = (SHAPE *) Parse_CSG (CSG_UNION_TYPE, Object);
  3136.          EXIT
  3137.          END_CASE
  3138.  
  3139.          CASE (INTERSECTION_TOKEN)
  3140.             Local_Shape = (SHAPE *) Parse_CSG (CSG_INTERSECTION_TYPE, Object);
  3141.          EXIT
  3142.          END_CASE
  3143.  
  3144.          CASE (DIFFERENCE_TOKEN)
  3145.             Local_Shape = (SHAPE *) Parse_CSG (CSG_DIFFERENCE_TYPE, Object);
  3146.          EXIT
  3147.          END_CASE
  3148.  
  3149.          OTHERWISE
  3150.          Parse_Error (QUADRIC_TOKEN);
  3151.          END_CASE
  3152.          END_EXPECT
  3153.          return (Local_Shape);
  3154.       }
  3155.  
  3156.       OBJECT *Parse_Object ()
  3157.       {
  3158.          OBJECT *Object;
  3159.          SHAPE *Local_Shape;
  3160.          VECTOR Local_Vector;
  3161.          CONSTANT Constant_Id;
  3162.          TEXTURE *Local_Texture;
  3163.          TEXTURE *temp_texture;
  3164.  
  3165.          Object = NULL;
  3166.  
  3167.          GET(LEFT_CURLY_TOKEN);
  3168.  
  3169.          EXPECT
  3170.          CASE (IDENTIFIER_TOKEN)
  3171.             if ((Constant_Id = Find_Constant()) != -1)
  3172.                if (Constants[(int)Constant_Id].Constant_Type == OBJECT_CONSTANT)
  3173.                   Object = (OBJECT *) Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  3174.                else
  3175.                   Type_Error ();
  3176.             else
  3177.                Undeclared ();
  3178.          EXIT
  3179.          END_CASE
  3180.  
  3181.          CASE6 (SPHERE_TOKEN, QUADRIC_TOKEN, QUARTIC_TOKEN, UNION_TOKEN,
  3182.             INTERSECTION_TOKEN, DIFFERENCE_TOKEN)
  3183.             CASE6 (TRIANGLE_TOKEN, SMOOTH_TRIANGLE_TOKEN, PLANE_TOKEN, CUBIC_TOKEN,
  3184.                POLY_TOKEN, BICUBIC_PATCH_TOKEN)
  3185.                CASE4  (HEIGHT_FIELD_TOKEN, LIGHT_SOURCE_TOKEN, BOX_TOKEN, BLOB_TOKEN)
  3186.                   UNGET
  3187.                   if (Object == NULL)
  3188.                      Object = Get_Object();
  3189.  
  3190.          Local_Shape = Parse_Shape(Object);
  3191.          Link((OBJECT *)Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  3192.             (OBJECT **) &(Object -> Shape));
  3193.          EXIT
  3194.          END_CASE
  3195.  
  3196.          OTHERWISE
  3197.          Parse_Error (SHAPE_TOKEN);
  3198.          EXIT
  3199.          END_CASE
  3200.          END_EXPECT
  3201.  
  3202.          EXPECT
  3203.          CASE (BOUNDED_TOKEN)
  3204.  
  3205.             GET(LEFT_CURLY_TOKEN);
  3206.  
  3207.          EXPECT
  3208.          CASE (RIGHT_CURLY_TOKEN)
  3209.             EXIT
  3210.             END_CASE
  3211.  
  3212.             OTHERWISE
  3213.             UNGET
  3214.             Local_Shape = Parse_Shape(Object);
  3215.          Link((OBJECT *) Local_Shape,
  3216.             (OBJECT **) &(Local_Shape -> Next_Object),
  3217.             (OBJECT **) &(Object -> Bounding_Shapes));
  3218.          END_CASE
  3219.          END_EXPECT       
  3220.          END_CASE
  3221.  
  3222.          CASE (CLIPPED_TOKEN)
  3223.  
  3224.             GET(LEFT_CURLY_TOKEN);
  3225.  
  3226.          EXPECT
  3227.          CASE (RIGHT_CURLY_TOKEN)
  3228.             EXIT
  3229.             END_CASE
  3230.  
  3231.             OTHERWISE
  3232.             UNGET
  3233.             Local_Shape = Parse_Shape(Object);
  3234.          Link((OBJECT *) Local_Shape,
  3235.             (OBJECT **) &(Local_Shape -> Next_Object),
  3236.             (OBJECT **) &(Object -> Clipping_Shapes));
  3237.          END_CASE
  3238.          END_EXPECT       
  3239.          END_CASE
  3240.  
  3241.          CASE (COLOUR_TOKEN)
  3242.             Object->Object_Colour = Get_Colour();
  3243.          Parse_Colour (Object -> Object_Colour);
  3244.          END_CASE
  3245.  
  3246.          CASE (TEXTURE_TOKEN)
  3247.             Local_Texture = Parse_Texture ();
  3248.          if (Local_Texture->Constant_Flag)
  3249.             Local_Texture = Copy_Texture(Local_Texture);
  3250.  
  3251.          if (Object->Object_Texture == Default_Texture)
  3252.             Object->Object_Texture = Local_Texture;
  3253.          else
  3254.          {
  3255.             for (temp_texture = Local_Texture ;
  3256.                         temp_texture->Next_Texture != NULL ;
  3257.                         temp_texture = temp_texture->Next_Texture)
  3258.             {}
  3259.  
  3260.             temp_texture->Next_Texture = Object->Object_Texture;
  3261.             Object->Object_Texture = Local_Texture;
  3262.          }
  3263.          END_CASE
  3264.  
  3265.          CASE (NO_SHADOW_TOKEN)
  3266.             Object -> No_Shadow_Flag = TRUE;
  3267.          END_CASE
  3268.  
  3269.          CASE (LIGHT_SOURCE_TOKEN)
  3270.             Error("Light source must be defined using new syntax");
  3271.          END_CASE
  3272.  
  3273.          CASE (TRANSLATE_TOKEN)
  3274.             Parse_Vector (&Local_Vector);
  3275.          Translate (Object, &Local_Vector);
  3276.          END_CASE
  3277.  
  3278.          CASE (ROTATE_TOKEN)
  3279.             Parse_Vector (&Local_Vector);
  3280.          Rotate (Object, &Local_Vector);
  3281.          END_CASE
  3282.  
  3283.          CASE (SCALE_TOKEN)
  3284.             Parse_Vector (&Local_Vector);
  3285.          Scale (Object, &Local_Vector);
  3286.          END_CASE
  3287.  
  3288.          CASE (INVERSE_TOKEN)
  3289.             Invert (Object);
  3290.          END_CASE
  3291.  
  3292.          CASE (RIGHT_CURLY_TOKEN)
  3293.             EXIT
  3294.             END_CASE
  3295.  
  3296.             OTHERWISE
  3297.             Parse_Error (RIGHT_CURLY_TOKEN);
  3298.          END_CASE
  3299.  
  3300.          END_EXPECT
  3301.  
  3302.          return (Object);
  3303.       }
  3304.  
  3305.       OBJECT *Parse_Composite ()
  3306.       {
  3307.          COMPOSITE *Local_Composite;
  3308.          OBJECT *Local_Object;
  3309.          SHAPE *Local_Shape;
  3310.          CONSTANT Constant_Id;
  3311.          VECTOR Local_Vector;
  3312.  
  3313.          Local_Composite = NULL;
  3314.  
  3315.          GET(LEFT_CURLY_TOKEN);
  3316.  
  3317.          EXPECT
  3318.          CASE (IDENTIFIER_TOKEN)
  3319.             if ((Constant_Id = Find_Constant()) != -1)
  3320.                if (Constants[(int)Constant_Id].Constant_Type == COMPOSITE_CONSTANT)
  3321.                   Local_Composite = (COMPOSITE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  3322.                else          
  3323.                   Type_Error ();
  3324.             else
  3325.                Undeclared ();
  3326.          END_CASE
  3327.  
  3328.          CASE (COMPOSITE_TOKEN)
  3329.             if (Local_Composite == NULL)       
  3330.                Local_Composite = Get_Composite_Object();
  3331.  
  3332.          Local_Object = Parse_Composite();
  3333.          Link((OBJECT *) Local_Object,(OBJECT **) &(Local_Object -> Next_Object),
  3334.             (OBJECT **) &(Local_Composite -> Objects));
  3335.          END_CASE
  3336.  
  3337.          CASE (OBJECT_TOKEN)
  3338.             if (Local_Composite == NULL)       
  3339.                Local_Composite = Get_Composite_Object();
  3340.  
  3341.          Local_Object = Parse_Object();
  3342.          Link(Local_Object, &(Local_Object -> Next_Object),
  3343.             &(Local_Composite -> Objects));
  3344.          END_CASE
  3345.  
  3346.          CASE (RIGHT_CURLY_TOKEN)
  3347.             UNGET
  3348.             if (Local_Composite == NULL)       
  3349.                Local_Composite = Get_Composite_Object();
  3350.  
  3351.          EXIT
  3352.          END_CASE
  3353.  
  3354.          OTHERWISE
  3355.          UNGET
  3356.          EXIT
  3357.          END_CASE
  3358.          END_EXPECT
  3359.  
  3360.          EXPECT
  3361.          CASE (RIGHT_CURLY_TOKEN)
  3362.             EXIT
  3363.             END_CASE
  3364.  
  3365.             CASE (BOUNDED_TOKEN)
  3366.  
  3367.                GET(LEFT_CURLY_TOKEN);
  3368.  
  3369.          EXPECT
  3370.          CASE (RIGHT_CURLY_TOKEN)
  3371.             EXIT
  3372.             END_CASE
  3373.  
  3374.             OTHERWISE
  3375.             UNGET
  3376.             Local_Shape = Parse_Shape((OBJECT *) Local_Composite);
  3377.          Link((OBJECT *) Local_Shape,
  3378.             (OBJECT **) &(Local_Shape -> Next_Object),
  3379.             (OBJECT **) &(Local_Composite -> Bounding_Shapes));
  3380.          END_CASE
  3381.          END_EXPECT       
  3382.          END_CASE
  3383.  
  3384.          CASE (CLIPPED_TOKEN)
  3385.  
  3386.             GET(LEFT_CURLY_TOKEN);
  3387.  
  3388.          EXPECT
  3389.          CASE (RIGHT_CURLY_TOKEN)
  3390.             EXIT
  3391.             END_CASE
  3392.  
  3393.             OTHERWISE
  3394.             UNGET
  3395.             Local_Shape = Parse_Shape((OBJECT *) Local_Composite);
  3396.          Link((OBJECT *) Local_Shape,
  3397.             (OBJECT **) &(Local_Shape -> Next_Object),
  3398.             (OBJECT **) &(Local_Composite -> Clipping_Shapes));
  3399.          END_CASE
  3400.          END_EXPECT       
  3401.          END_CASE
  3402.  
  3403.          CASE (TRANSLATE_TOKEN)
  3404.             Parse_Vector (&Local_Vector);
  3405.          Translate ((OBJECT *) Local_Composite, &Local_Vector);
  3406.          END_CASE
  3407.  
  3408.          CASE (ROTATE_TOKEN)
  3409.             Parse_Vector (&Local_Vector);
  3410.          Rotate ((OBJECT *) Local_Composite, &Local_Vector);
  3411.          END_CASE
  3412.  
  3413.          CASE (SCALE_TOKEN)
  3414.             Parse_Vector (&Local_Vector);
  3415.          Scale ((OBJECT *) Local_Composite, &Local_Vector);
  3416.          END_CASE
  3417.  
  3418.          CASE (INVERSE_TOKEN)
  3419.             Invert ((OBJECT *) Local_Composite);
  3420.          END_CASE
  3421.  
  3422.          OTHERWISE
  3423.          Parse_Error (RIGHT_CURLY_TOKEN);
  3424.          END_CASE
  3425.          END_EXPECT
  3426.  
  3427.          return ((OBJECT *) Local_Composite);
  3428.       }
  3429.  
  3430.       void Parse_Fog ()
  3431.       {   
  3432.  
  3433.          GET(LEFT_CURLY_TOKEN);
  3434.  
  3435.          EXPECT
  3436.          CASE (COLOUR_TOKEN)
  3437.             Parse_Colour (&Parsing_Frame_Ptr->Fog_Colour);
  3438.          END_CASE
  3439.  
  3440.          CASE (FLOAT_TOKEN)
  3441.             Parsing_Frame_Ptr->Fog_Distance = Token.Token_Float;
  3442.          END_CASE
  3443.  
  3444.          CASE (RIGHT_CURLY_TOKEN)
  3445.             EXIT
  3446.             END_CASE
  3447.  
  3448.             OTHERWISE
  3449.             Parse_Error (RIGHT_CURLY_TOKEN);
  3450.          END_CASE
  3451.          END_EXPECT
  3452.       }
  3453.  
  3454.       /*
  3455.    }
  3456. */
  3457.  
  3458.       void Parse_Frame ()
  3459.       {
  3460.          OBJECT *Local_Object;
  3461.  
  3462.          EXPECT
  3463.          CASE (FOG_TOKEN)
  3464.             Parse_Fog();
  3465.          END_CASE
  3466.  
  3467.  
  3468.          CASE (DEFAULT_TOKEN)
  3469.             GET(LEFT_CURLY_TOKEN);
  3470.          EXPECT    
  3471.          CASE (TEXTURE_TOKEN)
  3472.             Default_Texture->Constant_Flag = FALSE;
  3473.          Default_Texture = Parse_Texture ();
  3474.          Default_Texture->Constant_Flag = TRUE;
  3475.          END_CASE        
  3476.          CASE (RIGHT_CURLY_TOKEN)
  3477.             EXIT
  3478.             END_CASE
  3479.  
  3480.             OTHERWISE
  3481.             Parse_Error (RIGHT_CURLY_TOKEN);
  3482.          END_CASE
  3483.          END_EXPECT      
  3484.          END_CASE
  3485.  
  3486.  
  3487.          CASE (MAX_TRACE_LEVEL_TOKEN)
  3488.             Max_Trace_Level = Parse_Float ();
  3489.          END_CASE        
  3490.  
  3491.          CASE (OBJECT_TOKEN)
  3492.             Local_Object = Parse_Object();
  3493.          Link(Local_Object, &(Local_Object -> Next_Object),
  3494.             &(Parsing_Frame_Ptr -> Objects));
  3495.  
  3496.          /* light sources are now linked in object parsing */
  3497.          /* if (Local_Object -> Light_Source_Flag)
  3498.      Link(Local_Object, &(Local_Object -> Next_Light_Source),
  3499.            &(Parsing_Frame_Ptr -> Light_Sources)); */
  3500.          END_CASE
  3501.  
  3502.          CASE (COMPOSITE_TOKEN)
  3503.             Local_Object = Parse_Composite();
  3504.          Link(Local_Object, &(Local_Object -> Next_Object),
  3505.             &(Parsing_Frame_Ptr -> Objects));
  3506.  
  3507.          /*      Add_Composite_Light_Source ((COMPOSITE *)Local_Object);*/
  3508.          END_CASE
  3509.  
  3510.          CASE (VIEW_POINT_TOKEN)
  3511.             Parse_Viewpoint(&(Parsing_Frame_Ptr -> View_Point));
  3512.          END_CASE
  3513.  
  3514.          CASE (DECLARE_TOKEN)
  3515.             Parse_Declare ();
  3516.          END_CASE
  3517.  
  3518.          CASE (END_OF_FILE_TOKEN)
  3519.             EXIT
  3520.             END_CASE
  3521.  
  3522.             OTHERWISE 
  3523.             Parse_Error (OBJECT_TOKEN);
  3524.          END_CASE
  3525.          END_EXPECT
  3526.       }
  3527.  
  3528.       void Parse_Viewpoint (Given_Vp)
  3529.          VIEWPOINT *Given_Vp;
  3530.       {
  3531.          CONSTANT Constant_Id;
  3532.          VECTOR Local_Vector, Temp_Vector;
  3533.          DBL Direction_Length, Up_Length, Right_Length, Handedness;
  3534.  
  3535.          Init_Viewpoint (Given_Vp);
  3536.  
  3537.          GET(LEFT_CURLY_TOKEN);
  3538.  
  3539.          EXPECT
  3540.          CASE (IDENTIFIER_TOKEN)
  3541.             if ((Constant_Id = Find_Constant()) != -1)
  3542.                if (Constants[(int)Constant_Id].Constant_Type == VIEW_POINT_CONSTANT)
  3543.                   *Given_Vp = 
  3544.                   *((VIEWPOINT*) Constants[(int)Constant_Id].Constant_Data);
  3545.                else
  3546.                   Type_Error ();
  3547.             else
  3548.                Undeclared ();
  3549.          END_CASE
  3550.  
  3551.          CASE (LOCATION_TOKEN)
  3552.             Parse_Vector(&(Given_Vp -> Location));
  3553.          END_CASE
  3554.  
  3555.          CASE (DIRECTION_TOKEN)
  3556.             Parse_Vector(&(Given_Vp -> Direction));
  3557.          END_CASE
  3558.  
  3559.          CASE (UP_TOKEN)
  3560.             Parse_Vector(&(Given_Vp -> Up));
  3561.          END_CASE
  3562.  
  3563.          CASE (RIGHT_TOKEN)
  3564.             Parse_Vector(&(Given_Vp -> Right));
  3565.          END_CASE
  3566.  
  3567.          CASE (SKY_TOKEN)
  3568.             Parse_Vector(&(Given_Vp -> Sky));
  3569.          END_CASE
  3570.  
  3571.          CASE (LOOK_AT_TOKEN)
  3572.             VLength (Direction_Length, Given_Vp->Direction);
  3573.          VLength (Up_Length, Given_Vp->Up);
  3574.          VLength (Right_Length, Given_Vp->Right);
  3575.          VCross (Temp_Vector, Given_Vp->Direction, Given_Vp->Up);
  3576.          VDot (Handedness, Temp_Vector, Given_Vp->Right);
  3577.          Parse_Vector(&Given_Vp->Direction);
  3578.  
  3579.          VSub (Given_Vp->Direction, Given_Vp->Direction, Given_Vp->Location);
  3580.          VNormalize (Given_Vp->Direction, Given_Vp->Direction);
  3581.          VCross(Given_Vp->Right, Given_Vp->Direction, Given_Vp->Sky);
  3582.          VNormalize (Given_Vp->Right, Given_Vp->Right);
  3583.          VCross (Given_Vp->Up, Given_Vp->Right, Given_Vp->Direction);
  3584.          VScale (Given_Vp->Direction, Given_Vp->Direction, Direction_Length);
  3585.          if (Handedness >= 0.0) {
  3586.             VScale (Given_Vp->Right, Given_Vp->Right, Right_Length);
  3587.          }
  3588.          else {
  3589.             VScale (Given_Vp->Right, Given_Vp->Right, -Right_Length);
  3590.          }
  3591.  
  3592.             VScale (Given_Vp->Up, Given_Vp->Up, Up_Length);       
  3593.          END_CASE
  3594.  
  3595.          CASE (TRANSLATE_TOKEN)
  3596.             Parse_Vector (&Local_Vector);
  3597.          Translate ((OBJECT *) Given_Vp, &Local_Vector);
  3598.          END_CASE
  3599.  
  3600.          CASE (ROTATE_TOKEN)
  3601.             Parse_Vector (&Local_Vector);
  3602.          Rotate ((OBJECT *) Given_Vp, &Local_Vector);
  3603.          END_CASE
  3604.  
  3605.          CASE (SCALE_TOKEN)
  3606.             Parse_Vector (&Local_Vector);
  3607.          Scale ((OBJECT *) Given_Vp, &Local_Vector);
  3608.          END_CASE
  3609.  
  3610.          CASE (RIGHT_CURLY_TOKEN)
  3611.             EXIT
  3612.             END_CASE
  3613.  
  3614.             OTHERWISE
  3615.             Parse_Error (RIGHT_CURLY_TOKEN);
  3616.          END_CASE
  3617.          END_EXPECT
  3618.       }
  3619.  
  3620.       void Parse_Declare ()
  3621.       {
  3622.          CONSTANT Constant_Id;
  3623.          TEXTURE *Local_Texture;
  3624.          TEXTURE *temp_texture;
  3625.          struct Constant_Struct *Constant_Ptr;
  3626.  
  3627.          GET (IDENTIFIER_TOKEN);
  3628.          if ((Constant_Id = Find_Constant()) == -1)
  3629.             if (++Number_Of_Constants >= MAX_CONSTANTS)
  3630.                Error ("Too many constants \"declared\"");
  3631.             else
  3632.                Constant_Id = Number_Of_Constants;
  3633.  
  3634.          Constant_Ptr = &(Constants[(int)Constant_Id]);
  3635.          GET (EQUALS_TOKEN);
  3636.  
  3637.          EXPECT
  3638.          CASE (OBJECT_TOKEN)
  3639.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3640.          Constant_Ptr -> Constant_Data = (char *) Parse_Object();
  3641.          Constant_Ptr -> Constant_Type = OBJECT_CONSTANT;
  3642.          EXIT
  3643.          END_CASE
  3644.  
  3645.          CASE (SPHERE_TOKEN)
  3646.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3647.          Constant_Ptr -> Constant_Data = (char *) Parse_Sphere ();
  3648.          Constant_Ptr -> Constant_Type = SPHERE_CONSTANT;
  3649.          EXIT
  3650.          END_CASE
  3651.  
  3652.          CASE (PLANE_TOKEN)
  3653.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3654.          Constant_Ptr -> Constant_Data = (char *) Parse_Plane ();
  3655.          Constant_Ptr -> Constant_Type = PLANE_CONSTANT;
  3656.          EXIT
  3657.          END_CASE
  3658.  
  3659.          CASE (TRIANGLE_TOKEN)
  3660.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3661.          Constant_Ptr -> Constant_Data = (char *) Parse_Triangle ();
  3662.          Constant_Ptr -> Constant_Type = TRIANGLE_CONSTANT;
  3663.          EXIT
  3664.          END_CASE
  3665.  
  3666.          CASE (SMOOTH_TRIANGLE_TOKEN)
  3667.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3668.          Constant_Ptr -> Constant_Data = (char *) Parse_Smooth_Triangle ();
  3669.          Constant_Ptr -> Constant_Type = SMOOTH_TRIANGLE_CONSTANT;
  3670.          EXIT
  3671.          END_CASE
  3672.  
  3673.          CASE (QUADRIC_TOKEN)
  3674.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3675.          Constant_Ptr -> Constant_Data = (char *) Parse_Quadric ();
  3676.          Constant_Ptr -> Constant_Type = QUADRIC_CONSTANT;
  3677.          EXIT
  3678.          END_CASE
  3679.  
  3680.          CASE (CUBIC_TOKEN)
  3681.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3682.          Constant_Ptr -> Constant_Data = (char *) Parse_Poly (3);
  3683.          Constant_Ptr -> Constant_Type = POLY_CONSTANT;
  3684.          EXIT
  3685.          END_CASE
  3686.  
  3687.          CASE (QUARTIC_TOKEN)
  3688.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3689.          Constant_Ptr -> Constant_Data = (char *) Parse_Poly (4);
  3690.          Constant_Ptr -> Constant_Type = POLY_CONSTANT;
  3691.          EXIT
  3692.          END_CASE
  3693.  
  3694.          CASE (HEIGHT_FIELD_TOKEN)
  3695.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3696.          Constant_Ptr -> Constant_Data = (char *) Parse_Height_Field ();
  3697.          Constant_Ptr -> Constant_Type = HEIGHT_FIELD_CONSTANT;
  3698.          EXIT
  3699.          END_CASE
  3700.  
  3701.          CASE (POLY_TOKEN)
  3702.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3703.          Constant_Ptr -> Constant_Data = (char *) Parse_Poly (0);
  3704.          Constant_Ptr -> Constant_Type = POLY_CONSTANT;
  3705.          EXIT
  3706.          END_CASE
  3707.  
  3708.          CASE (BOX_TOKEN)
  3709.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3710.          Constant_Ptr -> Constant_Data = (char *) Parse_Box ();
  3711.          Constant_Ptr -> Constant_Type = BOX_CONSTANT;
  3712.          EXIT
  3713.          END_CASE
  3714.  
  3715.          CASE (BLOB_TOKEN)
  3716.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3717.          Constant_Ptr -> Constant_Data = (char *) Parse_Blob ();
  3718.          Constant_Ptr -> Constant_Type = BLOB_CONSTANT;
  3719.          EXIT
  3720.          END_CASE
  3721.  
  3722.          CASE (BICUBIC_PATCH_TOKEN)
  3723.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3724.          Constant_Ptr -> Constant_Data = (char *) Parse_Bicubic_Patch ();
  3725.          Constant_Ptr -> Constant_Type = BICUBIC_PATCH_CONSTANT;
  3726.          EXIT
  3727.          END_CASE
  3728.  
  3729.          CASE (INTERSECTION_TOKEN)
  3730.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3731.          Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_INTERSECTION_TYPE, NULL);
  3732.          Constant_Ptr -> Constant_Type = CSG_INTERSECTION_CONSTANT;
  3733.          EXIT
  3734.          END_CASE
  3735.  
  3736.          CASE (UNION_TOKEN)
  3737.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3738.          Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_UNION_TYPE, NULL);
  3739.          Constant_Ptr -> Constant_Type = CSG_UNION_CONSTANT;
  3740.          EXIT
  3741.          END_CASE
  3742.  
  3743.          CASE (DIFFERENCE_TOKEN)
  3744.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3745.          Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_DIFFERENCE_TYPE, NULL);
  3746.          Constant_Ptr -> Constant_Type = CSG_DIFFERENCE_CONSTANT;
  3747.          EXIT
  3748.          END_CASE
  3749.  
  3750.          CASE (COMPOSITE_TOKEN)
  3751.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3752.          Constant_Ptr -> Constant_Data = (char *) Parse_Composite();
  3753.          Constant_Ptr -> Constant_Type = COMPOSITE_CONSTANT;
  3754.          EXIT
  3755.          END_CASE
  3756.  
  3757.          CASE (TEXTURE_TOKEN)
  3758.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3759.          Local_Texture = NULL;
  3760.          Constant_Ptr -> Constant_Data = (char *) Local_Texture;
  3761.          Constant_Ptr -> Constant_Type = TEXTURE_CONSTANT;
  3762.          UNGET
  3763.          EXPECT
  3764.          CASE (TEXTURE_TOKEN)
  3765.             Local_Texture = Default_Texture;
  3766.          Local_Texture = Parse_Texture ();
  3767.          if (Local_Texture->Constant_Flag)
  3768.             Local_Texture = Copy_Texture(Local_Texture);
  3769.  
  3770.          Local_Texture -> Constant_Flag = TRUE;
  3771.  
  3772.          {
  3773.             for (temp_texture = Local_Texture ;
  3774.                         temp_texture->Next_Texture != NULL ;
  3775.                         temp_texture = temp_texture->Next_Texture)
  3776.             {}
  3777.  
  3778.             temp_texture->Next_Texture = (TEXTURE *) Constant_Ptr->Constant_Data;
  3779.             Constant_Ptr->Constant_Data = (char *) Local_Texture;
  3780.          }
  3781.          END_CASE
  3782.  
  3783.          OTHERWISE
  3784.          UNGET
  3785.          EXIT
  3786.          END_CASE
  3787.          END_EXPECT
  3788.          EXIT
  3789.          END_CASE
  3790.  
  3791.          CASE (VIEW_POINT_TOKEN)
  3792.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3793.          Constant_Ptr -> Constant_Data = (char *) Get_Viewpoint();
  3794.          Constant_Ptr -> Constant_Type = VIEW_POINT_CONSTANT;
  3795.          Parse_Viewpoint((VIEWPOINT *) Constant_Ptr -> Constant_Data);
  3796.          EXIT
  3797.          END_CASE
  3798.  
  3799.          CASE (COLOUR_TOKEN)
  3800.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3801.          Constant_Ptr -> Constant_Data = (char *) Get_Colour();
  3802.          Constant_Ptr -> Constant_Type = COLOUR_CONSTANT;
  3803.          Parse_Colour ((COLOUR *) Constant_Ptr -> Constant_Data);
  3804.          EXIT
  3805.          END_CASE
  3806.  
  3807.          CASE (LIGHT_SOURCE_TOKEN)
  3808.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3809.          Constant_Ptr -> Constant_Data = (char *) Parse_Light_Source ();
  3810.          Constant_Ptr -> Constant_Type = LIGHT_SOURCE_CONSTANT;
  3811.          EXIT
  3812.          END_CASE
  3813.  
  3814.  
  3815.          CASE (LEFT_ANGLE_TOKEN)
  3816.             UNGET
  3817.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3818.          Constant_Ptr -> Constant_Data = (char *) Get_Vector();
  3819.          Constant_Ptr -> Constant_Type = VECTOR_CONSTANT;
  3820.          Parse_Vector((VECTOR *) Constant_Ptr -> Constant_Data);
  3821.          EXIT
  3822.          END_CASE
  3823.  
  3824.          CASE3 (DASH_TOKEN, PLUS_TOKEN, FLOAT_TOKEN)
  3825.             UNGET
  3826.             Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  3827.          Constant_Ptr -> Constant_Data = (char *) Get_Float();
  3828.          Constant_Ptr -> Constant_Type = FLOAT_CONSTANT;
  3829.          *((DBL *) Constant_Ptr -> Constant_Data) = Parse_Float();
  3830.          EXIT
  3831.          END_CASE
  3832.  
  3833.          OTHERWISE
  3834.          Parse_Error (OBJECT_TOKEN);
  3835.          END_CASE
  3836.          END_EXPECT
  3837.       }
  3838.  
  3839.       void Init_Viewpoint (vp)
  3840.          VIEWPOINT *vp;
  3841.       {
  3842.          vp -> Methods = (void *) &Viewpoint_Methods;
  3843.          vp -> Type = VIEWPOINT_TYPE;
  3844.          Make_Vector (&vp->Location, 0.0, 0.0, 0.0);
  3845.          Make_Vector (&vp->Direction, 0.0, 0.0, 1.0);
  3846.          Make_Vector (&vp->Up, 0.0, 1.0, 0.0);
  3847.          Make_Vector (&vp->Right, 1.33, 0.0, 0.0);
  3848.          Make_Vector (&vp->Sky, 0.0, 1.0, 0.0);
  3849.       }
  3850.  
  3851.       void Link (New_Object, Field, Old_Object_List)
  3852.          OBJECT *New_Object, **Field, **Old_Object_List;
  3853.       {
  3854.          *Field = *Old_Object_List;
  3855.          *Old_Object_List = New_Object;
  3856.       }
  3857.       static void Link_Shapes (New_Object, Field, Old_Object_List)
  3858.          LIGHT_SHAPE *New_Object, **Field, **Old_Object_List;
  3859.       {
  3860.          *Field = *Old_Object_List;
  3861.          *Old_Object_List = New_Object;
  3862.       }
  3863.  
  3864.  
  3865.       CONSTANT Find_Constant()
  3866.       {
  3867.          register int i;
  3868.  
  3869.          for (i = 1 ; i <= Number_Of_Constants ; i++)
  3870.             if (Constants [i].Identifier_Number == Token.Identifier_Number)
  3871.                return (i);
  3872.  
  3873.          return (-1);
  3874.       }
  3875.  
  3876.  
  3877.       char *Get_Token_String (Token_Id)
  3878.          TOKEN Token_Id;
  3879.       {
  3880.          register int i;
  3881.  
  3882.          for (i = 0 ; i < LAST_TOKEN ; i++)
  3883.             if (Reserved_Words[i].Token_Number == Token_Id)
  3884.                return (Reserved_Words[i].Token_Name);
  3885.          return ("");
  3886.       }
  3887.  
  3888.       void Parse_Error (Token_Id)
  3889.          TOKEN Token_Id;
  3890.       {
  3891.          char *expected, *found;
  3892.          FILE *stat_file;
  3893.          fprintf (stderr, "Error in file %s line %d\n", Token.Filename,
  3894.             Token.Token_Line_No+1);
  3895.          expected = Get_Token_String (Token_Id);
  3896.          found = Get_Token_String (Token.Token_Id);
  3897.          fprintf (stderr, "%s expected but %s found instead\n", expected, found);
  3898.          if (Options & VERBOSE_FILE){
  3899.             stat_file = fopen(Stat_File_Name,"w+t");
  3900.             fprintf (stat_file, "%s expected but %s found instead\n", expected, found);
  3901.             fclose(stat_file);
  3902.          }
  3903.  
  3904.          exit(1);
  3905.       }
  3906.  
  3907.       void Type_Error ()
  3908.       {
  3909.          FILE *stat_file;
  3910.          fprintf (stderr, "Error in file %s line %d\n", Token.Filename,
  3911.             Token.Token_Line_No+1);
  3912.          fprintf (stderr, "Identifier %s is the wrong type\n", Token.Token_String);
  3913.          if (Options & VERBOSE_FILE){
  3914.             stat_file = fopen(Stat_File_Name,"w+t");
  3915.             fprintf (stat_file, "Error in file %s line %d\n", Token.Filename,
  3916.                Token.Token_Line_No+1);
  3917.             fprintf (stat_file, "Identifier %s is the wrong type\n", Token.Token_String);
  3918.  
  3919.             fclose(stat_file);
  3920.          }
  3921.  
  3922.          exit (1);
  3923.       }
  3924.  
  3925.       void Undeclared ()
  3926.       {
  3927.          FILE *stat_file;
  3928.          fprintf (stderr, "Error in file %s line %d\n", Token.Filename,
  3929.             Token.Token_Line_No+1);
  3930.          fprintf (stderr, "Undeclared identifier %s\n", Token.Token_String);
  3931.          if (Options & VERBOSE_FILE){
  3932.             stat_file = fopen(Stat_File_Name,"w+t");
  3933.             fprintf (stat_file, "Error in file %s line %d\n", Token.Filename,
  3934.                Token.Token_Line_No+1);
  3935.             fprintf (stat_file, "Undeclared identifier %s\n", Token.Token_String);
  3936.             fclose(stat_file);
  3937.          }
  3938.  
  3939.          exit (1);
  3940.       }
  3941.  
  3942.       void Error (str)
  3943.          char *str;
  3944.       {
  3945.          FILE *stat_file;
  3946.          fprintf (stderr, "Error in file %s line %d\n", Token.Filename,
  3947.             Token.Token_Line_No+1);
  3948.          fprintf (stderr,"%s\n",str);
  3949.  
  3950.          if (Options & VERBOSE_FILE){
  3951.             stat_file = fopen(Stat_File_Name,"w+t");
  3952.             fprintf (stat_file, "Error in file %s line %d\n", Token.Filename,
  3953.                Token.Token_Line_No+1);
  3954.             fprintf (stat_file,"%s\n",str);
  3955.             fclose(stat_file);
  3956.          }
  3957.          exit (1);
  3958.       }
  3959.  
  3960.       static void Post_Process_Object (Object)
  3961.          OBJECT *Object;
  3962.       {
  3963.          OBJECT *Temp;
  3964.  
  3965.          if (Object->Type == COMPOSITE_TYPE)
  3966.             for (Temp = ((COMPOSITE *)Object) -> Objects;
  3967.                      Temp != NULL ; 
  3968.                      Temp = Temp->Next_Object) 
  3969.                Post_Process_Object (Temp);
  3970.          else
  3971.             Post_Process_Shape (Object->Shape);
  3972.       }
  3973.  
  3974.       static void Post_Process_Shape (Shape)
  3975.          SHAPE *Shape;
  3976.       {
  3977.          SHAPE *Temp_Shape;
  3978.  
  3979.          if ((Shape->Type == CSG_UNION_TYPE) 
  3980.             || (Shape->Type == CSG_INTERSECTION_TYPE)
  3981.             || (Shape->Type == CSG_DIFFERENCE_TYPE))
  3982.             for (Temp_Shape = ((CSG_SHAPE *)Shape)->Shapes;
  3983.                      Temp_Shape != NULL ; 
  3984.                      Temp_Shape = Temp_Shape->Next_Object)
  3985.                Post_Process_Shape(Temp_Shape);
  3986.          else
  3987.             if ((Shape->Type == POINT_LIGHT_TYPE)
  3988.                ||(Shape->Type == SPOT_LIGHT_TYPE))
  3989.                Link_Shapes ((LIGHT_SHAPE *)Shape, 
  3990.                   &(((LIGHT_SHAPE *)Shape)->Next_Light_Source),
  3991.                   &(Parsing_Frame_Ptr -> Light_Sources));
  3992.       }
  3993.