home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / graphics / ftpovstc / parse.c < prev    next >
C/C++ Source or Header  |  1994-05-25  |  87KB  |  3,348 lines

  1. /****************************************************************************
  2. *
  3. *  ATTENTION!!!
  4. *
  5. *  THIS FILE HAS BEEN MODIFIED!!! IT IS NOT PART OF THE OFFICAL
  6. *  POV-RAY 2.2 DISTRIBUTION!!!
  7. *
  8. *  THIS FILE IS PART OF "FASTER THAN POV-RAY" (VERSION 1.1),
  9. *  A SPED-UP VERSION OF POV-RAY 2.2. USE AT YOUR OWN RISK!!!!!!
  10. *
  11. *  New files: addon0.c, addon1.c, addon2.c, addon3.c, addon.h
  12. *
  13. *  The additional modules were written by Dieter Bayer.
  14. *
  15. *  Send comments, suggestions, bugs, ideas ... to:
  16. *
  17. *  dieter@cip.e-technik.uni-erlangen.de
  18. *
  19. *  All changed/added lines are enclosed in #ifdef DB_CODE ... #endif
  20. *
  21. *  The vista projection was taken from:
  22. *
  23. *    A. Hashimoto, T. Akimoto, K. Mase, and Y. Suenaga, 
  24. *    "Vista Ray-Tracing: High Speed Ray Tracing Using Perspective
  25. *    Projection Image", New Advances in Computer Graphics, Proceedings
  26. *    of CG International '89, R. A. Earnshaw, B. Wyvill (Eds.), 
  27. *    Springer, ..., pp. 549-560
  28. *
  29. *  The idea for the light buffer was taken from:
  30. *
  31. *    E. Haines and D. Greenberg, "The Light Buffer: A Shadow-Testing 
  32. *    Accelerator", IEEE CG&A, Vol. 6, No. 9, Sept. 1986, pp. 6-16
  33. *
  34. *****************************************************************************/
  35.  
  36. /****************************************************************************
  37. *                parse.c
  38. *
  39. *  This module implements a parser for the scene description files.
  40. *
  41. *  from Persistence of Vision Raytracer
  42. *  Copyright 1993 Persistence of Vision Team
  43. *---------------------------------------------------------------------------
  44. *  NOTICE: This source code file is provided so that users may experiment
  45. *  with enhancements to POV-Ray and to port the software to platforms other 
  46. *  than those supported by the POV-Ray Team.  There are strict rules under
  47. *  which you are permitted to use this file.  The rules are in the file
  48. *  named POVLEGAL.DOC which should be distributed with this file. If 
  49. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  50. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  51. *  Forum.  The latest version of POV-Ray may be found there as well.
  52. *
  53. * This program is based on the popular DKB raytracer version 2.12.
  54. * DKBTrace was originally written by David K. Buck.
  55. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  56. *
  57. *****************************************************************************/
  58.  
  59. #include "frame.h"
  60. #include "vector.h"
  61. #include "povproto.h"
  62. #include "parse.h"
  63.  
  64. /* This file implements a simple recursive-descent parser for reading the
  65. input file.  */
  66.  
  67. extern DBL Max_Trace_Level;
  68. extern char VerboseFormat;
  69. extern unsigned int Options;
  70. extern int Use_Slabs;
  71. extern char Stat_File_Name[FILE_NAME_LENGTH];
  72.  
  73. extern struct Reserved_Word_Struct Reserved_Words [];
  74. extern DBL Antialias_Threshold;
  75.  
  76. extern struct Token_Struct Token;
  77. extern char String[MAX_STRING_INDEX];
  78.  
  79. extern COLOUR_MAP_ENTRY *Build_Entries;
  80. extern FRAME Frame;
  81. extern DBL Clock_Value;
  82. extern char **Symbol_Table;
  83. extern int Max_Intersections;
  84. extern DBL Language_Version;
  85. extern METHODS Csg_Height_Field_Methods;
  86. extern METHODS CSG_Union_Methods;
  87. #ifdef DB_CODE
  88. /* necessary for bounding of quadrics. */
  89. extern METHODS Quadric_Methods;
  90. #endif
  91.  
  92. static void Parse_Image_Map PARAMS((PIGMENT *Pigment));
  93. static void Parse_Bump_Map PARAMS((TNORMAL *Tnormal));
  94. static void Parse_Pigment PARAMS((PIGMENT **Pigment_Ptr));
  95. static void Parse_Tnormal PARAMS((TNORMAL **Tnormal_Ptr));
  96. static void Parse_Finish PARAMS((FINISH **Finish_Ptr));
  97. static TEXTURE *Parse_Texture PARAMS((void));
  98. static void Token_Init PARAMS((void));
  99. static void Frame_Init PARAMS((void));
  100. static void Parse_Coeffs PARAMS((int order, DBL *Coeffs));
  101. static IMAGE *Parse_Image PARAMS((int Legal));
  102. static TRANSFORM *Parse_Transform PARAMS((void));
  103. static void Parse_Object_Mods PARAMS((OBJECT *Object));
  104. static OBJECT *Parse_Bicubic_Patch PARAMS((void));
  105. static OBJECT *Parse_Blob PARAMS((void));
  106. static OBJECT *Parse_Box PARAMS((void));
  107. static OBJECT *Parse_Cone PARAMS((void));
  108. static OBJECT *Parse_Cylinder PARAMS((void));
  109. static OBJECT *Parse_Disc PARAMS((void));
  110. static OBJECT *Parse_Height_Field PARAMS((void));
  111. static OBJECT *Parse_Plane PARAMS((void));
  112. static OBJECT *Parse_Poly PARAMS((int order));
  113. static OBJECT *Parse_Quadric PARAMS((void));
  114. static OBJECT *Parse_Smooth_Triangle PARAMS((void));
  115. static OBJECT *Parse_Sphere PARAMS((void));
  116. static OBJECT *Parse_Torus PARAMS((void));
  117. static OBJECT *Parse_Triangle PARAMS((void));
  118. static OBJECT *Parse_CSG PARAMS((int CSG_Type));
  119. static OBJECT *Parse_Light_Source PARAMS((void));
  120. static OBJECT *Parse_Object PARAMS((void));
  121. static void Parse_Fog PARAMS((void));
  122. static void Parse_Frame PARAMS((void));
  123. static void Parse_Camera PARAMS((CAMERA **Camera_Ptr));
  124. static void Parse_Declare PARAMS((void));
  125. static void Link PARAMS((OBJECT *New_Object,OBJECT **Field,OBJECT **Old_Object_List));
  126. static void Link_Textures PARAMS((TEXTURE **Old_Texture, TEXTURE *New_Texture));
  127. static char *Get_Token_String PARAMS((TOKEN Token_Id));
  128. static void Where_Error PARAMS((void));
  129. static int Test_Redefine PARAMS((int a));
  130. static OBJECT *Parse_Bound_Clip PARAMS((void));
  131. static void Found_Instead PARAMS((void));
  132. /*static void Parse_Warn PARAMS((TOKEN Token_Id));*/
  133. static void Warn_State PARAMS((TOKEN Token_Id, TOKEN Type));
  134. static void Post_Process PARAMS((OBJECT *Object, OBJECT *Parent));
  135. static void Destroy_Constants PARAMS((void));
  136. static OBJECT *Parse_Object_Id PARAMS((void));
  137. static void Link_To_Frame PARAMS((OBJECT *Object));
  138.  
  139. extern struct Constant_Struct Constants[MAX_CONSTANTS];
  140.  
  141. int Number_Of_Constants;
  142. int Previous;
  143. short Have_Vector;
  144. short Not_In_Default;
  145.  
  146. TOKEN *Brace_Stack;
  147. int Brace_Index;
  148.  
  149. TEXTURE *Default_Texture;
  150. CAMERA *Default_Camera;
  151.  
  152. /* Parse the file. */
  153. void Parse ()
  154.   {
  155.    Build_Entries  = NULL;
  156.    if ((Brace_Stack = (TOKEN *) malloc(MAX_BRACES*sizeof (TOKEN))) == NULL)
  157.      MAError ("brace stack");
  158.    Brace_Index = 0;
  159.    Token_Init ();
  160.    Default_Camera = Create_Camera();
  161.    Default_Texture = Create_PNF_Texture();
  162.    Default_Texture->Pigment = Create_Pigment();
  163.    Default_Texture->Tnormal = NULL;
  164.    Default_Texture->Finish  = Create_Finish();
  165.    Not_In_Default = TRUE;
  166.    Frame_Init ();
  167.    Parse_Frame ();
  168.    if (Frame.Objects==NULL)
  169.      Error("No objects in scene");
  170.    Destroy_Constants ();
  171.    Destroy_Textures(Default_Texture);
  172.    Destroy_Camera(Default_Camera);
  173.    if (Build_Entries != NULL)
  174.      free (Build_Entries);
  175.    free (Brace_Stack);
  176.   }
  177.  
  178. static void Token_Init ()
  179.   {
  180.    Number_Of_Constants = 0;
  181.   }
  182.  
  183. /* Set up the fields in the frame to default values. */
  184. static
  185. void Frame_Init ()
  186.   {
  187.    Frame.Camera = Copy_Camera(Default_Camera);
  188.    Frame.Light_Sources = NULL;
  189.    Frame.Objects = NULL;
  190.    Frame.Atmosphere_IOR = 1.0;
  191.    Frame.Antialias_Threshold = Antialias_Threshold;
  192.    Frame.Fog_Distance = 0.0;
  193.    Make_Colour (&(Frame.Fog_Colour), 0.0, 0.0, 0.0);
  194.   }
  195.  
  196. void Parse_Begin ()
  197.   {
  198.    char *front;
  199.  
  200.    Brace_Stack[++Brace_Index]=Token.Token_Id;
  201.    Get_Token ();
  202.  
  203.    if (Token.Token_Id == LEFT_CURLY_TOKEN)
  204.      return;
  205.  
  206.    Where_Error ();
  207.  
  208.    front = Get_Token_String (Brace_Stack[Brace_Index]);
  209.    fprintf (stderr, "Missing { after %s, ", front);
  210.    Found_Instead ();
  211.    exit (1);
  212.   }
  213.  
  214. void Parse_End ()
  215.   {
  216.    char *front;
  217.  
  218.    Get_Token ();
  219.  
  220.    if (Token.Token_Id == RIGHT_CURLY_TOKEN)
  221.      {
  222.       Brace_Index--;
  223.       return;
  224.      }
  225.  
  226.    Where_Error ();
  227.  
  228.    front = Get_Token_String (Brace_Stack[Brace_Index]);
  229.    fprintf (stderr, "No matching } in %s,", front);
  230.    Found_Instead ();
  231.    exit (1);
  232.   }
  233.  
  234. static OBJECT *Parse_Object_Id ()
  235.   {
  236.    OBJECT *Object;
  237.    
  238.    EXPECT
  239.      CASE (OBJECT_ID_TOKEN)
  240.        Warn_State(OBJECT_ID_TOKEN, OBJECT_TOKEN);
  241.        Object = Copy_Object((OBJECT *) Token.Constant_Data);
  242.        Parse_Object_Mods (Object);
  243.        EXIT
  244.      END_CASE
  245.  
  246.      OTHERWISE
  247.        Object = NULL;
  248.        UNGET
  249.        EXIT
  250.      END_CASE
  251.    END_EXPECT
  252.  
  253.    return (Object);
  254.   }
  255.  
  256. void Parse_Comma ()
  257.   {
  258.    Get_Token();
  259.    if (Token.Token_Id != COMMA_TOKEN)
  260.      {
  261.       UNGET;
  262.      }
  263.   }
  264.  
  265. static void Parse_Coeffs(order, Coeffs)
  266.   int order;
  267.   DBL *Coeffs;
  268.   {
  269.    int i;
  270.  
  271.    EXPECT
  272.      CASE (LEFT_ANGLE_TOKEN)
  273.        Coeffs[0] = Parse_Float();
  274.        for (i = 1; i < term_counts(order); i++)
  275.          {
  276.           Parse_Comma();
  277.           Coeffs[i] = Parse_Float();
  278.          }
  279.        GET (RIGHT_ANGLE_TOKEN);
  280.        EXIT
  281.      END_CASE
  282.  
  283.      OTHERWISE
  284.        Parse_Error (LEFT_ANGLE_TOKEN);
  285.      END_CASE
  286.    END_EXPECT
  287.   }
  288.  
  289. static
  290. IMAGE *Parse_Image (Legal)
  291.   int Legal;
  292.   {
  293.    IMAGE *Image;
  294.    VECTOR Local_Vector;
  295.  
  296.    Image = Create_Image ();
  297.  
  298.    if (Legal & GRAD_FILE)
  299.      {
  300.       EXPECT
  301.         CASE_VECTOR
  302.           Warn("Should use map_type keyword and/or eliminate orientation.",1.5);
  303.           Have_Vector = FALSE;
  304.           Parse_Vector_Float (&Local_Vector);
  305.           if (Have_Vector)
  306.             Image->Gradient = Local_Vector;
  307.           else
  308.             Image->Map_Type = (int)Local_Vector.x;
  309.         END_CASE
  310.  
  311.         OTHERWISE
  312.           UNGET
  313.           EXIT
  314.         END_CASE
  315.       END_EXPECT
  316.      }
  317.  
  318.    EXPECT
  319.      CASE (IFF_TOKEN)
  320.        Image->File_Type = IFF_FILE;
  321.        GET (STRING_TOKEN);
  322.        Read_Iff_Image (Image, Token.Token_String);
  323.        EXIT
  324.      END_CASE
  325.  
  326.      CASE (GIF_TOKEN)
  327.        Image->File_Type = GIF_FILE;
  328.        GET (STRING_TOKEN);
  329.        Read_Gif_Image(Image, Token.Token_String);
  330.        EXIT
  331.      END_CASE
  332.  
  333.      CASE (POT_TOKEN)
  334.        Image->File_Type = POT_FILE;
  335.        GET (STRING_TOKEN);
  336.        Read_Gif_Image(Image, Token.Token_String);
  337.        EXIT
  338.      END_CASE
  339.  
  340.      CASE (DUMP_TOKEN)
  341.        Image->File_Type = DUMP_FILE;
  342.        GET (STRING_TOKEN);
  343.        Read_Dump_Image(Image, Token.Token_String);
  344.        EXIT
  345.      END_CASE
  346.  
  347.      CASE (TGA_TOKEN)
  348.        Image->File_Type = TGA_FILE;
  349.        GET (STRING_TOKEN);
  350.        Read_Targa_Image(Image, Token.Token_String);
  351.        EXIT
  352.      END_CASE
  353.  
  354.      OTHERWISE
  355.        Parse_Error_Str ("map file spec");
  356.      END_CASE
  357.    END_EXPECT
  358.  
  359.    if (!(Image->File_Type & Legal))
  360.      Error ("File type not supported here");
  361.    return (Image);
  362.   }
  363.  
  364. static void Parse_Image_Map (Pigment)
  365.   PIGMENT *Pigment;
  366.   {
  367.    int reg;
  368.  
  369.    Pigment->Type = IMAGE_MAP_PIGMENT;
  370.  
  371.    Parse_Begin ();
  372.  
  373.    Pigment->Image = Parse_Image (IMAGE_FILE);
  374.    Pigment->Image->Use_Colour_Flag = TRUE;
  375.  
  376.    EXPECT                   /* Look for image_attribs */
  377.      CASE (ONCE_TOKEN)
  378.        Pigment->Image->Once_Flag=TRUE;
  379.      END_CASE
  380.  
  381.      CASE (INTERPOLATE_TOKEN)
  382.        Pigment->Image->Interpolation_Type = (int)Parse_Float();
  383.      END_CASE
  384.  
  385.      CASE (MAP_TYPE_TOKEN)
  386.        Pigment->Image->Map_Type = (int) Parse_Float ();
  387.      END_CASE
  388.  
  389.      CASE (USE_COLOUR_TOKEN)
  390.        Pigment->Image->Use_Colour_Flag = TRUE;
  391.      END_CASE
  392.  
  393.      CASE (USE_INDEX_TOKEN)
  394.        Pigment->Image->Use_Colour_Flag = FALSE;
  395.      END_CASE
  396.  
  397.      CASE (ALPHA_TOKEN)
  398.        Warn("Keyword ALPHA discontinued.  Use FILTER instead.",1.55);
  399.          
  400.      CASE (FILTER_TOKEN)
  401.        EXPECT
  402.          CASE (ALL_TOKEN)
  403.            {
  404.             DBL filter;
  405.             filter = Parse_Float();
  406.             for (reg = 0 ; reg < Pigment->Image->Colour_Map_Size ; reg++)
  407.               Pigment->Image->Colour_Map[reg].Filter
  408.                   = (unsigned short) (filter *255.0);
  409.            }
  410.            EXIT
  411.          END_CASE
  412.  
  413.          OTHERWISE
  414.            UNGET
  415.            reg = (int)(Parse_Float() + 0.01);
  416.            if (Pigment->Image->Colour_Map == NULL)
  417.              Error ("Can't apply FILTER to a non colour-mapped image\n");
  418.            if ((reg < 0) || (reg >= Pigment->Image->Colour_Map_Size))
  419.              Error ("FILTER colour register value out of range.\n");
  420.  
  421.            Parse_Comma();
  422.            Pigment->Image->Colour_Map[reg].Filter
  423.                   = (unsigned short) (255.0 * Parse_Float());
  424.            EXIT
  425.          END_CASE
  426.  
  427.        END_EXPECT
  428.      END_CASE
  429.  
  430.      OTHERWISE
  431.        UNGET
  432.        EXIT
  433.      END_CASE
  434.    END_EXPECT
  435.  
  436.    Parse_End ();
  437. }
  438.  
  439. static void Parse_Bump_Map (Tnormal)
  440.   TNORMAL *Tnormal;
  441.   {
  442.    Tnormal->Type = BUMP_MAP;
  443.  
  444.    Parse_Begin ();
  445.  
  446.    Tnormal->Image = Parse_Image (NORMAL_FILE);
  447.  
  448.    Tnormal->Image->Use_Colour_Flag = TRUE;
  449.  
  450.    EXPECT
  451.      CASE (ONCE_TOKEN)
  452.        Tnormal->Image->Once_Flag=TRUE;
  453.      END_CASE
  454.  
  455.      CASE (MAP_TYPE_TOKEN)
  456.        Tnormal->Image->Map_Type = (int) Parse_Float ();
  457.      END_CASE
  458.  
  459.      CASE (INTERPOLATE_TOKEN)
  460.        Tnormal->Image->Interpolation_Type = (int)Parse_Float();
  461.      END_CASE
  462.  
  463.      CASE (BUMP_SIZE_TOKEN)
  464.        Tnormal->Amount = Parse_Float ();
  465.      END_CASE
  466.  
  467.      CASE (USE_COLOUR_TOKEN)
  468.        Tnormal->Image->Use_Colour_Flag = TRUE;
  469.      END_CASE
  470.  
  471.      CASE (USE_INDEX_TOKEN)
  472.        Tnormal->Image->Use_Colour_Flag = FALSE;
  473.      END_CASE
  474.  
  475.      OTHERWISE
  476.        UNGET
  477.        EXIT
  478.      END_CASE
  479.    END_EXPECT
  480.    Parse_End ();
  481. }
  482.  
  483. static void Parse_Pigment (Pigment_Ptr)
  484.   PIGMENT **Pigment_Ptr;
  485.   {
  486.    PIGMENT *New;
  487.    VECTOR Local_Vector;
  488.  
  489.    Parse_Begin ();
  490.  
  491.    EXPECT            /* Look for [pigment_id] */
  492.      CASE (PIGMENT_ID_TOKEN)
  493.        Destroy_Pigment(*Pigment_Ptr);
  494.        *Pigment_Ptr = Copy_Pigment ((PIGMENT *) Token.Constant_Data);
  495.        EXIT
  496.      END_CASE
  497.  
  498.      OTHERWISE
  499.        UNGET
  500.        EXIT
  501.      END_CASE
  502.    END_EXPECT    /* End pigment_id */
  503.  
  504.    New = *Pigment_Ptr;
  505.  
  506.    EXPECT
  507.      CASE (AGATE_TOKEN)
  508.        New->Type = AGATE_PIGMENT;
  509.        EXIT
  510.      END_CASE
  511.  
  512.      CASE (BOZO_TOKEN)
  513.        New->Type = BOZO_PIGMENT;
  514.        EXIT
  515.      END_CASE
  516.  
  517.      CASE (GRANITE_TOKEN)
  518.        New->Type = GRANITE_PIGMENT;
  519.        EXIT
  520.      END_CASE
  521.  
  522.      CASE (LEOPARD_TOKEN)
  523.        New->Type = LEOPARD_PIGMENT;
  524.        EXIT
  525.      END_CASE
  526.  
  527.      CASE (MARBLE_TOKEN)
  528.        New->Type = MARBLE_PIGMENT;
  529.        EXIT
  530.      END_CASE
  531.  
  532.      CASE (MANDEL_TOKEN)
  533.        New->Type = MANDEL_PIGMENT;
  534.        New->Iterations = (int)Parse_Float();
  535.        EXIT
  536.      END_CASE
  537.  
  538.      CASE (ONION_TOKEN)
  539.        New->Type = ONION_PIGMENT;
  540.        EXIT
  541.      END_CASE
  542.  
  543.      CASE (PAINTED1_TOKEN)
  544.        New->Type = PAINTED1_PIGMENT;
  545.        EXIT
  546.      END_CASE
  547.  
  548.      CASE (PAINTED2_TOKEN)
  549.        New->Type = PAINTED2_PIGMENT;
  550.        EXIT
  551.      END_CASE
  552.  
  553.      CASE (PAINTED3_TOKEN)
  554.        New->Type = PAINTED2_PIGMENT;
  555.        EXIT
  556.      END_CASE
  557.  
  558.      CASE (SPOTTED_TOKEN)
  559.        New->Type = SPOTTED_PIGMENT;
  560.        EXIT
  561.      END_CASE
  562.  
  563.      CASE (WOOD_TOKEN)
  564.        New->Type = WOOD_PIGMENT;
  565.        EXIT
  566.      END_CASE
  567.  
  568.      CASE (GRADIENT_TOKEN)
  569.        New->Type = GRADIENT_PIGMENT;
  570.        Parse_Vector (&(New->Colour_Gradient));
  571.        EXIT
  572.      END_CASE
  573.  
  574.      CASE (RADIAL_TOKEN)
  575.        New->Type = RADIAL_PIGMENT;
  576.      END_CASE
  577.  
  578.      CASE (COLOUR_TOKEN)
  579.        New->Type = COLOUR_PIGMENT;
  580.        New->Colour1 = Create_Colour ();
  581.        Parse_Colour (New->Colour1);
  582.        New->Quick_Colour = *New->Colour1;
  583.        EXIT
  584.      END_CASE
  585.  
  586.      CASE5 (COLOUR_ID_TOKEN, RGB_TOKEN, RGBF_TOKEN, RED_TOKEN, BLUE_TOKEN)
  587.      CASE3 (GREEN_TOKEN, ALPHA_TOKEN, FILTER_TOKEN)
  588.        UNGET
  589.        New->Type = COLOUR_PIGMENT;
  590.        New->Colour1 = Create_Colour ();
  591.        Parse_Colour (New->Colour1);
  592.        New->Quick_Colour = *New->Colour1;
  593.        EXIT
  594.      END_CASE
  595.  
  596.      CASE (CHECKER_TOKEN)
  597.        New->Type = CHECKER_PIGMENT;
  598.        New->Colour_Map = Parse_Colour_List(2);
  599.        EXIT
  600.      END_CASE
  601.  
  602.      CASE (HEXAGON_TOKEN)
  603.        New->Type = HEXAGON_PIGMENT;
  604.        New->Colour_Map = Parse_Colour_List(3);
  605.        EXIT
  606.      END_CASE
  607.  
  608.      CASE (IMAGE_MAP_TOKEN)
  609.        Parse_Image_Map (New);
  610.        EXIT
  611.      END_CASE
  612.  
  613.      OTHERWISE
  614.        UNGET
  615.        EXIT
  616.      END_CASE
  617.    END_EXPECT     /* Concludes pigment_body */
  618.  
  619.    EXPECT         /* Look for pigment_modifier */
  620.      CASE (TURBULENCE_TOKEN)
  621.        Parse_Vector_Float(&(New->Turbulence));
  622.        if ((New->Turbulence.x !=0.0) || (New->Turbulence.y !=0.0) ||
  623.            (New->Turbulence.z !=0.0))
  624.           New->Flags |= HAS_TURB;
  625.      END_CASE
  626.  
  627.      CASE (COLOUR_MAP_TOKEN)
  628.        if (New->Type == CHECKER_PIGMENT ||
  629.            New->Type == HEXAGON_PIGMENT ||
  630.            New->Type == COLOUR_PIGMENT ||
  631.            New->Type == IMAGE_MAP_PIGMENT)
  632.          Warn ("Cannot use color map with this pigment type",1.5);
  633.        New->Colour_Map = Parse_Colour_Map ();
  634.      END_CASE
  635.  
  636.      CASE (QUICK_COLOUR_TOKEN)
  637.        Parse_Colour (&New->Quick_Colour);
  638.      END_CASE
  639.  
  640.      CASE (OCTAVES_TOKEN)
  641.        New->Octaves = (int)Parse_Float();
  642.          if(New->Octaves < 1)
  643.             New->Octaves = 1;
  644.          if(New->Octaves > 10)  /* Avoid DOMAIN errors */
  645.             New->Octaves = 10;
  646.      END_CASE
  647.  
  648.      CASE (OMEGA_TOKEN)
  649.        New->omega = Parse_Float();
  650.      END_CASE
  651.  
  652.      CASE (LAMBDA_TOKEN)
  653.        New->lambda = Parse_Float();
  654.      END_CASE
  655.  
  656.      CASE (FREQUENCY_TOKEN)
  657.        New->Frequency = Parse_Float();
  658.      END_CASE
  659.  
  660.      CASE (PHASE_TOKEN)
  661.        New->Phase = Parse_Float();
  662.      END_CASE
  663.  
  664.      CASE (AGATE_TURB_TOKEN)
  665.        if (Not_In_Default && (New->Type != AGATE_PIGMENT))
  666.       Warn("Attempt to use agate_turb on non-agate",1.9);
  667.        New->Agate_Turb_Scale = Parse_Float();
  668.      END_CASE
  669.  
  670.      CASE (TRANSLATE_TOKEN)
  671.        Parse_Vector (&Local_Vector);
  672.        Translate_Pigment (New, &Local_Vector);
  673.      END_CASE
  674.  
  675.      CASE (ROTATE_TOKEN)
  676.        Parse_Vector (&Local_Vector);
  677.        Rotate_Pigment (New, &Local_Vector);
  678.      END_CASE
  679.  
  680.      CASE (SCALE_TOKEN)
  681.        Parse_Scale_Vector (&Local_Vector);
  682.        Scale_Pigment (New, &Local_Vector);
  683.      END_CASE
  684.  
  685.      CASE (TRANSFORM_TOKEN)
  686.        GET(TRANSFORM_ID_TOKEN)
  687.        Transform_Pigment (New, (TRANSFORM *)Token.Constant_Data);
  688.      END_CASE
  689.  
  690.      OTHERWISE
  691.        UNGET
  692.        EXIT
  693.      END_CASE
  694.    END_EXPECT
  695.  
  696.    if (Not_In_Default && (New->Type == NO_PIGMENT))
  697.      Warn("Pigment type unspecified or not 1st item",1.7);
  698.  
  699.    Parse_End ();
  700.   }
  701.  
  702. static void Parse_Tnormal (Tnormal_Ptr)
  703.   TNORMAL **Tnormal_Ptr;
  704.   {
  705.    TNORMAL *New;
  706.    VECTOR Local_Vector;
  707.  
  708.    Parse_Begin ();
  709.  
  710.    EXPECT            /* Look for [tnormal_id] */
  711.      CASE (TNORMAL_ID_TOKEN)
  712.        Destroy_Tnormal(*Tnormal_Ptr);
  713.        *Tnormal_Ptr = Copy_Tnormal ((TNORMAL *) Token.Constant_Data);
  714.        EXIT
  715.      END_CASE
  716.  
  717.      OTHERWISE
  718.        UNGET
  719.        EXIT
  720.      END_CASE
  721.    END_EXPECT    /* End [tnormal_id] */
  722.  
  723.    if (*Tnormal_Ptr == NULL)
  724.      if ((Default_Texture->Tnormal) != NULL)
  725.        *Tnormal_Ptr = Copy_Tnormal ((Default_Texture->Tnormal));
  726.      else
  727.        *Tnormal_Ptr = Create_Tnormal ();
  728.  
  729.    New = *Tnormal_Ptr;
  730.  
  731.    EXPECT  /* [tnormal_body] */
  732.      CASE (BUMPS_TOKEN)
  733.        New->Type = BUMPS;
  734.        New->Amount = Parse_Float ();
  735.        EXIT
  736.      END_CASE
  737.  
  738.      CASE (BUMPY1_TOKEN)
  739.        New->Type = BUMPY1;
  740.        New->Amount = Parse_Float ();
  741.        EXIT
  742.      END_CASE
  743.  
  744.      CASE (BUMPY2_TOKEN)
  745.        New->Type = BUMPY2;
  746.        New->Amount = Parse_Float ();
  747.        EXIT
  748.      END_CASE
  749.  
  750.      CASE (BUMPY3_TOKEN)
  751.        New->Type = BUMPY3;
  752.        New->Amount = Parse_Float ();
  753.        EXIT
  754.      END_CASE
  755.  
  756.      CASE (DENTS_TOKEN)
  757.        New->Type = DENTS;
  758.        New->Amount = Parse_Float ();
  759.        EXIT
  760.      END_CASE
  761.  
  762.      CASE (RIPPLES_TOKEN)
  763.        New->Type = RIPPLES;
  764.        New->Amount = Parse_Float ();
  765.        EXIT
  766.      END_CASE
  767.  
  768.      CASE (WAVES_TOKEN)
  769.        New->Type = WAVES;
  770.        New->Amount = Parse_Float ();
  771.        EXIT
  772.      END_CASE
  773.  
  774.      CASE (WRINKLES_TOKEN)
  775.        New->Type = WRINKLES;
  776.        New->Amount = Parse_Float ();
  777.        EXIT
  778.      END_CASE
  779.  
  780.      CASE (BUMP_MAP_TOKEN)
  781.        Parse_Bump_Map (New);
  782.        EXIT
  783.      END_CASE
  784.  
  785.      OTHERWISE
  786.        if (Not_In_Default && (New->Type == NO_NORMAL))
  787.          Parse_Error_Str("normal body");
  788.        UNGET
  789.        EXIT
  790.      END_CASE
  791.    END_EXPECT    /* End of tnormal_body */
  792.  
  793.    EXPECT        /* Look for tnormal_mods */
  794.  
  795.      CASE (TURBULENCE_TOKEN)
  796.        Parse_Vector_Float(&(New->Turbulence));
  797.        if ((New->Turbulence.x !=0.0) || (New->Turbulence.y !=0.0) ||
  798.            (New->Turbulence.z !=0.0))
  799.           New->Flags |= HAS_TURB;
  800.      END_CASE
  801.  
  802.      CASE (OCTAVES_TOKEN)
  803.        New->Octaves = (int)Parse_Float();
  804.      END_CASE
  805.  
  806.      CASE (OMEGA_TOKEN)
  807.        New->omega = Parse_Float();
  808.      END_CASE
  809.  
  810.      CASE (LAMBDA_TOKEN)
  811.        New->lambda = Parse_Float();
  812.      END_CASE
  813.  
  814.      CASE (FREQUENCY_TOKEN)
  815.        if (!(New->Type == RIPPLES || New->Type == WAVES))
  816.          if (Language_Version >= 1.5)
  817.            Warn ("Cannot use frequency with this normal",1.5);
  818.        New->Frequency = Parse_Float();
  819.      END_CASE
  820.  
  821.      CASE (PHASE_TOKEN)
  822.        if (!(New->Type == RIPPLES || New->Type == WAVES))
  823.          if (Language_Version >= 1.5)
  824.             Warn ("Cannot use phase with this normal",1.5);
  825.        New->Phase = Parse_Float();
  826.      END_CASE
  827.  
  828.      CASE (TRANSLATE_TOKEN)
  829.        Parse_Vector (&Local_Vector);
  830.        Translate_Tnormal (New, &Local_Vector);
  831.      END_CASE
  832.  
  833.      CASE (ROTATE_TOKEN)
  834.        Parse_Vector (&Local_Vector);
  835.        Rotate_Tnormal (New, &Local_Vector);
  836.      END_CASE
  837.  
  838.      CASE (SCALE_TOKEN)
  839.        Parse_Scale_Vector (&Local_Vector);
  840.        Scale_Tnormal (New, &Local_Vector);
  841.      END_CASE
  842.  
  843.      CASE (TRANSFORM_TOKEN)
  844.        GET(TRANSFORM_ID_TOKEN)
  845.        Transform_Tnormal (New, (TRANSFORM *)Token.Constant_Data);
  846.      END_CASE
  847.  
  848.      OTHERWISE
  849.        UNGET
  850.        EXIT
  851.      END_CASE
  852.    END_EXPECT    /* End of tnormal_mods */
  853.  
  854.    Parse_End ();
  855.   }
  856.  
  857. static void Parse_Finish (Finish_Ptr)
  858.   FINISH **Finish_Ptr;
  859.   {
  860.    FINISH *New;
  861.  
  862.    Parse_Begin ();
  863.  
  864.    EXPECT        /* Look for zero or one finish_id */
  865.      CASE (FINISH_ID_TOKEN)
  866.        Destroy_Finish(*Finish_Ptr);
  867.        *Finish_Ptr = Copy_Finish ((FINISH *) Token.Constant_Data);
  868.        EXIT
  869.      END_CASE
  870.  
  871.      OTHERWISE
  872.        UNGET
  873.        EXIT
  874.      END_CASE
  875.    END_EXPECT    /* End finish_id */
  876.  
  877.    New = *Finish_Ptr;
  878.  
  879.    EXPECT        /* Look for zero or more finish_body */
  880.      CASE (AMBIENT_TOKEN)
  881.        New->Ambient = Parse_Float ();
  882.      END_CASE
  883.  
  884.      CASE (BRILLIANCE_TOKEN)
  885.        New->Brilliance = Parse_Float ();
  886.      END_CASE
  887.  
  888.      CASE (DIFFUSE_TOKEN)
  889.        New->Diffuse = Parse_Float ();
  890.      END_CASE
  891.  
  892.      CASE (REFLECTION_TOKEN)
  893.        New->Reflection = Parse_Float ();
  894.      END_CASE
  895.  
  896.      CASE (REFRACTION_TOKEN)
  897.        New->Refraction = Parse_Float ();
  898.      END_CASE
  899.  
  900.      CASE (IOR_TOKEN)
  901.        New->Index_Of_Refraction = Parse_Float ();
  902.      END_CASE
  903.  
  904.      CASE (PHONG_TOKEN)
  905.        New->Phong = Parse_Float ();
  906.      END_CASE
  907.  
  908.      CASE (PHONG_SIZE_TOKEN)
  909.        New->Phong_Size = Parse_Float ();
  910. /*     if (New->Phong_Size < 1.0)
  911.            New->Phong_Size = 1.0;
  912.        if (New->Phong_Size > 100)
  913.            New->Phong_Size = 100; */
  914.      END_CASE
  915.  
  916.      CASE (SPECULAR_TOKEN)
  917.        New->Specular = Parse_Float ();
  918.      END_CASE
  919.  
  920.      CASE (ROUGHNESS_TOKEN)
  921.        New->Roughness = Parse_Float ();
  922. /*     if (New->Roughness > 1.0)
  923.            New->Roughness = 1.0;
  924.        if (New->Roughness < 0.001)
  925.            New->Roughness = 0.001;  */
  926.        New->Roughness = 1.0/New->Roughness; /* CEY 12/92 */
  927.      END_CASE
  928.  
  929.      CASE (METALLIC_TOKEN)
  930.        New->Metallic_Flag = TRUE;
  931.      END_CASE
  932.  
  933.      CASE (CRAND_TOKEN)
  934.        New->Crand = Parse_Float();
  935.      END_CASE
  936.  
  937.      OTHERWISE
  938.        UNGET
  939.        EXIT
  940.      END_CASE
  941.    END_EXPECT    /* End of finish_body */
  942.  
  943.    EXPECT        /* Look for finish_mods */
  944.  
  945. /*   CASE none implemented
  946.      END_CASE     */
  947.  
  948.      OTHERWISE
  949.        UNGET
  950.        EXIT
  951.      END_CASE
  952.    END_EXPECT    /* End of finish_mods */
  953.  
  954.    Parse_End ();
  955.   }
  956.  
  957. #define ADD_TNORMAL if (Tnormal == NULL) {if ((Default_Texture->Tnormal) != NULL) \
  958.  Tnormal = Copy_Tnormal ((Default_Texture->Tnormal)); else Tnormal = Create_Tnormal ();\
  959.  Texture->Tnormal=Tnormal;};
  960.  
  961. static
  962. TEXTURE *Parse_Texture ()
  963.   {
  964.    VECTOR Local_Vector;
  965.    TEXTURE *Texture, *Local_Texture;
  966.    PIGMENT *Pigment;
  967.    TNORMAL *Tnormal;
  968.    FINISH *Finish;
  969.  
  970.    Parse_Begin ();
  971.  
  972.    EXPECT                      /* Look for texture_body */
  973.      CASE (TILES_TOKEN)
  974.        Parse_Begin ();
  975.  
  976.        Texture = (TEXTURE *)Create_Tiles_Texture ();
  977.  
  978.        EXPECT
  979.          CASE (TEXTURE_TOKEN)
  980.            Local_Texture = Parse_Texture ();
  981.            Link_Textures(&(((TILES *)Texture)->Tile1),Local_Texture);
  982.          END_CASE
  983.  
  984.          OTHERWISE
  985.            UNGET
  986.            EXIT
  987.          END_CASE
  988.        END_EXPECT
  989.  
  990.        GET (TILE2_TOKEN);
  991.  
  992.        EXPECT
  993.          CASE (TEXTURE_TOKEN)
  994.            Local_Texture = Parse_Texture ();
  995.            Link_Textures(&(((TILES *)Texture)->Tile2),Local_Texture);
  996.          END_CASE
  997.  
  998.          OTHERWISE
  999.            UNGET
  1000.            EXIT
  1001.          END_CASE
  1002.        END_EXPECT
  1003.        Parse_End ();
  1004.        EXIT
  1005.      END_CASE
  1006.  
  1007.      CASE (MATERIAL_MAP_TOKEN)
  1008.        Parse_Begin ();
  1009.  
  1010.        Texture = (TEXTURE *)Create_Material_Texture ();
  1011.  
  1012.        ((MATERIAL *)Texture)->Image = Parse_Image(MATERIAL_FILE);
  1013.        ((MATERIAL *)Texture)->Image->Use_Colour_Flag = FALSE;
  1014.  
  1015.        EXPECT
  1016.          CASE (ONCE_TOKEN)
  1017.            ((MATERIAL *)Texture)->Image->Once_Flag=TRUE;
  1018.          END_CASE
  1019.  
  1020.          CASE (INTERPOLATE_TOKEN)
  1021.            ((MATERIAL *)Texture)->Image->Interpolation_Type=(int)Parse_Float();
  1022.          END_CASE
  1023.  
  1024.          CASE (MAP_TYPE_TOKEN)
  1025.            ((MATERIAL *)Texture)->Image->Map_Type = (int) Parse_Float ();
  1026.          END_CASE
  1027.  
  1028.          OTHERWISE
  1029.            UNGET
  1030.            EXIT
  1031.          END_CASE
  1032.        END_EXPECT
  1033.  
  1034.        GET (TEXTURE_TOKEN)                /* First material */
  1035.        ((MATERIAL *)Texture)->Materials = Local_Texture = Parse_Texture ();
  1036.        ((MATERIAL *)Texture)->Num_Of_Mats++;
  1037.  
  1038.        EXPECT                             /* Subsequent materials */
  1039.          CASE (TEXTURE_TOKEN)
  1040.            Local_Texture->Next_Material = Parse_Texture ();
  1041.            Local_Texture = Local_Texture->Next_Material;
  1042.            ((MATERIAL *)Texture)->Num_Of_Mats++;
  1043.          END_CASE
  1044.  
  1045.          OTHERWISE
  1046.            UNGET
  1047.            EXIT
  1048.          END_CASE
  1049.        END_EXPECT
  1050.        Parse_End ();
  1051.        EXIT
  1052.      END_CASE
  1053.      
  1054.      CASE (TEXTURE_ID_TOKEN)
  1055.        Texture = Copy_Textures((TEXTURE *) Token.Constant_Data);
  1056.        EXIT
  1057.      END_CASE
  1058.  
  1059.      OTHERWISE
  1060.        UNGET
  1061.        Texture = Copy_Textures (Default_Texture);
  1062.        EXIT
  1063.      END_CASE
  1064.    END_EXPECT
  1065.    
  1066.    /* Look for [pnf_texture] */
  1067.    if (Texture->Type == PNF_TEXTURE)
  1068.      {
  1069.        EXPECT   /* Look for [pnf_ids] */
  1070.          CASE (PIGMENT_ID_TOKEN)
  1071.            Destroy_Pigment(Texture->Pigment);
  1072.            Texture->Pigment = Copy_Pigment ((PIGMENT *) Token.Constant_Data);
  1073.          END_CASE
  1074.  
  1075.          CASE (TNORMAL_ID_TOKEN)
  1076.            Destroy_Tnormal(Texture->Tnormal);
  1077.            Texture->Tnormal = Copy_Tnormal ((TNORMAL *) Token.Constant_Data);
  1078.          END_CASE
  1079.  
  1080.          CASE (FINISH_ID_TOKEN)
  1081.            Destroy_Finish(Texture->Finish);
  1082.            Texture->Finish = Copy_Finish ((FINISH *) Token.Constant_Data);
  1083.          END_CASE
  1084.  
  1085.          OTHERWISE
  1086.            UNGET
  1087.            EXIT
  1088.          END_CASE
  1089.        END_EXPECT
  1090.  
  1091.        Pigment = Texture->Pigment;
  1092.        Tnormal = Texture->Tnormal;
  1093.        Finish  = Texture->Finish;
  1094.  
  1095.        EXPECT
  1096.          CASE (PIGMENT_TOKEN)
  1097.            Parse_Pigment ( &(Texture->Pigment) );
  1098.          END_CASE
  1099.  
  1100.          CASE (TNORMAL_TOKEN)
  1101.            Parse_Tnormal ( &(Texture->Tnormal) );
  1102.          END_CASE
  1103.  
  1104.          CASE (FINISH_TOKEN)
  1105.            Parse_Finish ( &(Texture->Finish) );
  1106.          END_CASE
  1107.  
  1108. /***********************************************************************
  1109.  PIGMENT STUFF OUTSIDE PIGMENT{}
  1110. ***********************************************************************/
  1111.          CASE (AGATE_TOKEN)
  1112.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1113.            Pigment->Type = AGATE_PIGMENT;
  1114.          END_CASE
  1115.  
  1116.          CASE (BOZO_TOKEN)
  1117.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1118.            Pigment->Type = BOZO_PIGMENT;
  1119.          END_CASE
  1120.  
  1121.          CASE (GRANITE_TOKEN)
  1122.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1123.            Pigment->Type = GRANITE_PIGMENT;
  1124.          END_CASE
  1125.  
  1126.          CASE (LEOPARD_TOKEN)
  1127.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1128.            Pigment->Type = LEOPARD_PIGMENT;
  1129.          END_CASE
  1130.  
  1131.          CASE (MARBLE_TOKEN)
  1132.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1133.            Pigment->Type = MARBLE_PIGMENT;
  1134.          END_CASE
  1135.  
  1136.          CASE (MANDEL_TOKEN)
  1137.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1138.            Pigment->Type = MANDEL_PIGMENT;
  1139.            Pigment->Iterations = (int)Parse_Float();
  1140.          END_CASE
  1141.  
  1142.          CASE (ONION_TOKEN)
  1143.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1144.            Pigment->Type = ONION_PIGMENT;
  1145.          END_CASE
  1146.  
  1147.          CASE (PAINTED1_TOKEN)
  1148.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1149.            Pigment->Type = PAINTED1_PIGMENT;
  1150.          END_CASE
  1151.  
  1152.          CASE (PAINTED2_TOKEN)
  1153.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1154.            Pigment->Type = PAINTED2_PIGMENT;
  1155.          END_CASE
  1156.  
  1157.          CASE (PAINTED3_TOKEN)
  1158.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1159.            Pigment->Type = PAINTED2_PIGMENT;
  1160.          END_CASE
  1161.  
  1162.          CASE (SPOTTED_TOKEN)
  1163.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1164.            Pigment->Type = SPOTTED_PIGMENT;
  1165.          END_CASE
  1166.  
  1167.          CASE (WOOD_TOKEN)
  1168.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1169.            Pigment->Type = WOOD_PIGMENT;
  1170.          END_CASE
  1171.  
  1172.          CASE (GRADIENT_TOKEN)
  1173.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1174.            Pigment->Type = GRADIENT_PIGMENT;
  1175.            Parse_Vector (&(Pigment->Colour_Gradient));
  1176.          END_CASE
  1177.  
  1178.          CASE (COLOUR_TOKEN)
  1179.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1180.            Pigment->Type = COLOUR_PIGMENT;
  1181.            Pigment->Colour1 = Create_Colour ();
  1182.            Parse_Colour (Pigment->Colour1);
  1183.            Pigment->Quick_Colour = *Pigment->Colour1;
  1184.          END_CASE
  1185.  
  1186.          CASE5 (COLOUR_ID_TOKEN, RGB_TOKEN, RGBF_TOKEN, RED_TOKEN, BLUE_TOKEN)
  1187.          CASE3 (GREEN_TOKEN, ALPHA_TOKEN, FILTER_TOKEN)
  1188.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1189.            UNGET
  1190.            Pigment->Type = COLOUR_PIGMENT;
  1191.            Pigment->Colour1 = Create_Colour ();
  1192.            Parse_Colour (Pigment->Colour1);
  1193.            Pigment->Quick_Colour = *Pigment->Colour1;
  1194.          END_CASE
  1195.  
  1196.          CASE (CHECKER_TOKEN)
  1197.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1198.            Pigment->Type = CHECKER_PIGMENT;
  1199.            Pigment->Colour_Map = Parse_Colour_List(2);
  1200.          END_CASE
  1201.  
  1202.          CASE (HEXAGON_TOKEN)
  1203.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1204.            Pigment->Type = HEXAGON_PIGMENT;
  1205.            Pigment->Colour_Map = Parse_Colour_List(3);
  1206.          END_CASE
  1207.  
  1208.          CASE (IMAGE_MAP_TOKEN)
  1209.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1210.            Parse_Image_Map (Pigment);
  1211.          END_CASE
  1212.  
  1213.          CASE (TURBULENCE_TOKEN)
  1214.            Parse_Vector_Float(&(Pigment->Turbulence));
  1215.            if ((Pigment->Turbulence.x !=0.0) ||
  1216.                (Pigment->Turbulence.y !=0.0) ||
  1217.                (Pigment->Turbulence.z !=0.0))
  1218.              Pigment->Flags |= HAS_TURB;
  1219.          END_CASE
  1220.  
  1221.          CASE (COLOUR_MAP_TOKEN)
  1222.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);
  1223.            if (Pigment->Type == CHECKER_PIGMENT ||
  1224.                Pigment->Type == HEXAGON_PIGMENT ||
  1225.                Pigment->Type == COLOUR_PIGMENT ||
  1226.                Pigment->Type == IMAGE_MAP_PIGMENT)
  1227.              Warn ("Cannot use color map with this pigment type",1.5);
  1228.            Pigment->Colour_Map = Parse_Colour_Map ();
  1229.          END_CASE
  1230.  
  1231.          CASE (QUICK_COLOUR_TOKEN)
  1232.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1233.            Parse_Colour (&Pigment->Quick_Colour);
  1234.          END_CASE
  1235.  
  1236.          CASE (OCTAVES_TOKEN)
  1237.            Pigment->Octaves = (int)Parse_Float();
  1238.              if(Pigment->Octaves < 1)
  1239.                 Pigment->Octaves = 1;
  1240.              if(Pigment->Octaves > 10)  /* Avoid DOMAIN errors */
  1241.                 Pigment->Octaves = 10;
  1242.          END_CASE
  1243.  
  1244.          CASE (OMEGA_TOKEN)
  1245.            Pigment->omega = Parse_Float();
  1246.          END_CASE
  1247.  
  1248.          CASE (LAMBDA_TOKEN)
  1249.            Pigment->lambda = Parse_Float();
  1250.          END_CASE
  1251.  
  1252. /***********************************************************************
  1253. TNORMAL STUFF OUTSIDE NORMAL{}
  1254. ***********************************************************************/
  1255.          CASE (BUMPS_TOKEN)
  1256.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1257.            ADD_TNORMAL
  1258.            Tnormal->Type = BUMPS;
  1259.            Tnormal->Amount = Parse_Float ();
  1260.          END_CASE
  1261.  
  1262.          CASE (BUMPY1_TOKEN)
  1263.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1264.            ADD_TNORMAL
  1265.            Tnormal->Type = BUMPY1;
  1266.            Tnormal->Amount = Parse_Float ();
  1267.          END_CASE
  1268.  
  1269.          CASE (BUMPY2_TOKEN)
  1270.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1271.            ADD_TNORMAL
  1272.            Tnormal->Type = BUMPY2;
  1273.            Tnormal->Amount = Parse_Float ();
  1274.          END_CASE
  1275.  
  1276.          CASE (BUMPY3_TOKEN)
  1277.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1278.            ADD_TNORMAL
  1279.            Tnormal->Type = BUMPY3;
  1280.            Tnormal->Amount = Parse_Float ();
  1281.          END_CASE
  1282.  
  1283.          CASE (DENTS_TOKEN)
  1284.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1285.            ADD_TNORMAL
  1286.            Tnormal->Type = DENTS;
  1287.            Tnormal->Amount = Parse_Float ();
  1288.          END_CASE
  1289.  
  1290.          CASE (RIPPLES_TOKEN)
  1291.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1292.            ADD_TNORMAL
  1293.            Tnormal->Type = RIPPLES;
  1294.            Tnormal->Amount = Parse_Float ();
  1295.          END_CASE
  1296.  
  1297.          CASE (WAVES_TOKEN)
  1298.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1299.            ADD_TNORMAL
  1300.            Tnormal->Type = WAVES;
  1301.            Tnormal->Amount = Parse_Float ();
  1302.          END_CASE
  1303.  
  1304.          CASE (WRINKLES_TOKEN)
  1305.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1306.            ADD_TNORMAL
  1307.            Tnormal->Type = WRINKLES;
  1308.            Tnormal->Amount = Parse_Float ();
  1309.          END_CASE
  1310.  
  1311.          CASE (BUMP_MAP_TOKEN)
  1312.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1313.            ADD_TNORMAL
  1314.            Parse_Bump_Map (Tnormal);
  1315.          END_CASE
  1316.  
  1317.          CASE (FREQUENCY_TOKEN)
  1318.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1319.            ADD_TNORMAL
  1320.            if (!(Tnormal->Type == RIPPLES || Tnormal->Type == WAVES))
  1321.              if (Language_Version >= 1.5)
  1322.                Warn ("Cannot use frequency with this normal",1.5);
  1323.            Tnormal->Frequency = Parse_Float();
  1324.          END_CASE
  1325.  
  1326.          CASE (PHASE_TOKEN)
  1327.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1328.            ADD_TNORMAL
  1329.            if (!(Tnormal->Type == RIPPLES || Tnormal->Type == WAVES))
  1330.              if (Language_Version >= 1.5)
  1331.                Warn ("Cannot use phase with this normal",1.5);
  1332.            Tnormal->Phase = Parse_Float();
  1333.          END_CASE
  1334.  
  1335.  
  1336. /***********************************************************************
  1337. FINISH STUFF OUTSIDE FINISH{}
  1338. ***********************************************************************/
  1339.          CASE (AMBIENT_TOKEN)
  1340.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1341.            Finish->Ambient = Parse_Float ();
  1342.          END_CASE
  1343.  
  1344.          CASE (BRILLIANCE_TOKEN)
  1345.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1346.            Finish->Brilliance = Parse_Float ();
  1347.          END_CASE
  1348.  
  1349.          CASE (DIFFUSE_TOKEN)
  1350.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1351.            Finish->Diffuse = Parse_Float ();
  1352.          END_CASE
  1353.  
  1354.          CASE (REFLECTION_TOKEN)
  1355.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1356.            Finish->Reflection = Parse_Float ();
  1357.          END_CASE
  1358.  
  1359.          CASE (REFRACTION_TOKEN)
  1360.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1361.            Finish->Refraction = Parse_Float ();
  1362.          END_CASE
  1363.  
  1364.          CASE (IOR_TOKEN)
  1365.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1366.        Finish->Index_Of_Refraction = Parse_Float ();
  1367.          END_CASE
  1368.  
  1369.          CASE (PHONG_TOKEN)
  1370.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1371.            Finish->Phong = Parse_Float ();
  1372.          END_CASE
  1373.  
  1374.          CASE (PHONG_SIZE_TOKEN)
  1375.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1376.            Finish->Phong_Size = Parse_Float ();
  1377.     /*     if (Finish->Phong_Size < 1.0)
  1378.                Finish->Phong_Size = 1.0;
  1379.            if (Finish->Phong_Size > 100)
  1380.                Finish->Phong_Size = 100; */
  1381.          END_CASE
  1382.  
  1383.          CASE (SPECULAR_TOKEN)
  1384.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1385.            Finish->Specular = Parse_Float ();
  1386.          END_CASE
  1387.  
  1388.          CASE (ROUGHNESS_TOKEN)
  1389.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1390.            Finish->Roughness = Parse_Float ();
  1391.     /*     if (Finish->Roughness > 1.0)
  1392.                Finish->Roughness = 1.0;
  1393.            if (Finish->Roughness < 0.001)
  1394.                Finish->Roughness = 0.001;  */
  1395.            Finish->Roughness = 1.0/Finish->Roughness; /* CEY 12/92 */
  1396.          END_CASE
  1397.  
  1398.          CASE (METALLIC_TOKEN)
  1399.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1400.            Finish->Metallic_Flag = TRUE;
  1401.      END_CASE
  1402.  
  1403.          CASE (CRAND_TOKEN)
  1404.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1405.            Finish->Crand = Parse_Float();
  1406.          END_CASE
  1407.  
  1408.          CASE_FLOAT
  1409.            Finish->Crand = Parse_Float();
  1410.            Warn("Should use crand keyword in finish statement.",1.5);           
  1411.          END_CASE
  1412.  
  1413.          CASE (TRANSLATE_TOKEN)
  1414.            Parse_Vector (&Local_Vector);
  1415.            Translate_Textures (Texture, &Local_Vector);
  1416.          END_CASE
  1417.  
  1418.          CASE (ROTATE_TOKEN)
  1419.            Parse_Vector (&Local_Vector);
  1420.            Rotate_Textures (Texture, &Local_Vector);
  1421.          END_CASE
  1422.  
  1423.          CASE (SCALE_TOKEN)
  1424.            Parse_Scale_Vector (&Local_Vector);
  1425.            Scale_Textures (Texture, &Local_Vector);
  1426.          END_CASE
  1427.  
  1428.          CASE (TRANSFORM_TOKEN)
  1429.            GET(TRANSFORM_ID_TOKEN)
  1430.            Transform_Textures (Texture, (TRANSFORM *)Token.Constant_Data);
  1431.          END_CASE
  1432.  
  1433.          CASE (TEXTURE_ID_TOKEN)
  1434.            Warn("Texture identifier overwriting previous values.",0);
  1435.            Destroy_Textures(Texture);
  1436.        Texture = Copy_Textures((TEXTURE *) Token.Constant_Data);
  1437.            Pigment = Texture->Pigment;
  1438.            Tnormal = Texture->Tnormal;
  1439.            Finish  = Texture->Finish;
  1440.          END_CASE
  1441.  
  1442.          OTHERWISE
  1443.            UNGET
  1444.            EXIT
  1445.          END_CASE
  1446. /***********************************************************************/
  1447.  
  1448.        END_EXPECT
  1449.  
  1450.        if (Not_In_Default && (Texture->Pigment->Type == NO_PIGMENT) &&
  1451.            !(Language_Version < 1.5))
  1452.          Parse_Error(PIGMENT_ID_TOKEN);
  1453.  
  1454.      }
  1455.  
  1456.    EXPECT            /* Look for texture_mods */
  1457.      CASE (TRANSLATE_TOKEN)
  1458.        Parse_Vector (&Local_Vector);
  1459.        Translate_Textures (Texture, &Local_Vector);
  1460.      END_CASE
  1461.  
  1462.      CASE (ROTATE_TOKEN)
  1463.        Parse_Vector (&Local_Vector);
  1464.        Rotate_Textures (Texture, &Local_Vector);
  1465.      END_CASE
  1466.  
  1467.      CASE (SCALE_TOKEN)
  1468.        Parse_Scale_Vector (&Local_Vector);
  1469.        Scale_Textures (Texture, &Local_Vector);
  1470.      END_CASE
  1471.  
  1472.      CASE (TRANSFORM_TOKEN)
  1473.        GET(TRANSFORM_ID_TOKEN)
  1474.        Transform_Textures (Texture, (TRANSFORM *)Token.Constant_Data);
  1475.      END_CASE
  1476.  
  1477.      OTHERWISE
  1478.        UNGET
  1479.        EXIT
  1480.      END_CASE
  1481.    END_EXPECT        /* End of texture */
  1482.  
  1483.    Parse_End ();
  1484.    return (Texture);
  1485.   }
  1486.  
  1487. static
  1488. OBJECT *Parse_Bound_Clip ()
  1489.   {
  1490.    VECTOR Local_Vector;
  1491.    OBJECT *First, *Current, *Prev;
  1492.  
  1493.    First = Prev = NULL;
  1494.  
  1495.    while ((Current = Parse_Object ()) != NULL)
  1496.      {
  1497.       if (Current->Type & (TEXTURED_OBJECT+PATCH_OBJECT))
  1498.         Error ("Illegal texture or patch in clip or bound");
  1499.       if (First == NULL)
  1500.         First = Current;
  1501.       if (Prev != NULL)
  1502.         Prev->Sibling = Current;
  1503.       Prev = Current;
  1504.      }
  1505.  
  1506.    EXPECT
  1507.      CASE (TRANSLATE_TOKEN)
  1508.        Parse_Vector (&Local_Vector);
  1509.        for (Current = First;
  1510.             Current != NULL;
  1511.             Current = Current->Sibling)
  1512.          Translate_Object (Current, &Local_Vector);
  1513.      END_CASE
  1514.  
  1515.      CASE (ROTATE_TOKEN)
  1516.        Parse_Vector (&Local_Vector);
  1517.        for (Current = First;
  1518.             Current != NULL;
  1519.             Current = Current->Sibling)
  1520.          Rotate_Object (Current, &Local_Vector);
  1521.      END_CASE
  1522.  
  1523.      CASE (SCALE_TOKEN)
  1524.        Parse_Scale_Vector (&Local_Vector);
  1525.        for (Current = First;
  1526.             Current != NULL;
  1527.             Current = Current->Sibling)
  1528.          Scale_Object (Current, &Local_Vector);
  1529.      END_CASE
  1530.  
  1531.      CASE (TRANSFORM_TOKEN)
  1532.        GET(TRANSFORM_ID_TOKEN)
  1533.        for (Current = First;
  1534.             Current != NULL;
  1535.             Current = Current->Sibling)
  1536.        Transform_Object (Current, (TRANSFORM *)Token.Constant_Data);
  1537.      END_CASE
  1538.  
  1539.      OTHERWISE
  1540.        UNGET
  1541.        EXIT
  1542.      END_CASE
  1543.    END_EXPECT
  1544.  
  1545.    return (First);
  1546.   }
  1547.  
  1548. static void Parse_Object_Mods (Object)
  1549.   OBJECT *Object;
  1550.   {
  1551.    VECTOR Local_Vector;
  1552.    TEXTURE *Local_Texture;
  1553.    OBJECT *Temp1_Object;
  1554.    OBJECT *Temp2_Object;
  1555.    COLOUR Local_Colour;
  1556.    DBL Temp_Water_Level;
  1557.  
  1558.    EXPECT
  1559.      CASE (COLOUR_TOKEN)
  1560.        Parse_Colour (&Local_Colour);
  1561.        if (Language_Version < 1.5)
  1562.          if (Object->Texture != NULL) 
  1563.            if (Object->Texture->Type == PNF_TEXTURE)
  1564.              {
  1565.               Object->Texture->Pigment->Quick_Colour = Local_Colour;
  1566.               break;  /* acts like END_CASE */
  1567.              }
  1568.        Warn("Quick color belongs in texture.  Color ignored.",0.0);
  1569.      END_CASE
  1570.  
  1571.      CASE (TRANSLATE_TOKEN)
  1572.        Parse_Vector (&Local_Vector);
  1573.        Translate_Object (Object, &Local_Vector);
  1574.      END_CASE
  1575.  
  1576.      CASE (ROTATE_TOKEN)
  1577.        Parse_Vector (&Local_Vector);
  1578.        Rotate_Object (Object, &Local_Vector);
  1579.      END_CASE
  1580.  
  1581.      CASE (SCALE_TOKEN)
  1582.        Parse_Scale_Vector (&Local_Vector);
  1583.        Scale_Object (Object, &Local_Vector);
  1584.      END_CASE
  1585.  
  1586.      CASE (TRANSFORM_TOKEN)
  1587.        GET(TRANSFORM_ID_TOKEN)
  1588.        Transform_Object (Object, (TRANSFORM *)Token.Constant_Data);
  1589.      END_CASE
  1590.  
  1591.      CASE (BOUNDED_BY_TOKEN)
  1592.        Parse_Begin ();
  1593.        if (Object->Bound != NULL)
  1594.          if (Object->Clip == Object->Bound)
  1595.            Error ("Cannot add bounds after linking bounds and clips");
  1596.  
  1597.        EXPECT
  1598.          CASE (CLIPPED_BY_TOKEN)
  1599.            if (Object->Bound != NULL)
  1600.              Error ("Cannot link clips with previous bounds");
  1601.            Object->Bound = Object->Clip;
  1602.            EXIT
  1603.          END_CASE
  1604.  
  1605.          OTHERWISE
  1606.            UNGET
  1607.            Temp1_Object = Temp2_Object = Parse_Bound_Clip ();
  1608.            while (Temp2_Object->Sibling != NULL)
  1609.              Temp2_Object = Temp2_Object->Sibling;
  1610.            Temp2_Object->Sibling = Object->Bound;
  1611.        Object->Bound = Temp1_Object;
  1612.            EXIT
  1613.          END_CASE
  1614.        END_EXPECT
  1615.        
  1616.        Parse_End ();
  1617.      END_CASE
  1618.  
  1619.      CASE (CLIPPED_BY_TOKEN)
  1620.        Parse_Begin ();
  1621.        if (Object->Clip != NULL)
  1622.          if (Object->Clip == Object->Bound)
  1623.            Error ("Cannot add clips after linking bounds and clips");
  1624.  
  1625.        EXPECT
  1626.          CASE (BOUNDED_BY_TOKEN)
  1627.            if (Object->Clip != NULL)
  1628.              Error ("Cannot link bounds with previous clips");
  1629.            Object->Clip = Object->Bound;
  1630.            EXIT
  1631.          END_CASE
  1632.  
  1633.          OTHERWISE
  1634.            UNGET
  1635.            Temp1_Object = Temp2_Object = Parse_Bound_Clip ();
  1636.            while (Temp2_Object->Sibling != NULL)
  1637.              Temp2_Object = Temp2_Object->Sibling;
  1638.            Temp2_Object->Sibling = Object->Clip;
  1639.            Object->Clip = Temp1_Object;
  1640. #ifdef DB_CODE
  1641.        /* necessary for bounding of quadrics. */
  1642.        if (Object->Methods == &Quadric_Methods)
  1643.          Compute_Quadric_BBox((QUADRIC *)Object);
  1644. #endif
  1645.        EXIT
  1646.          END_CASE
  1647.        END_EXPECT
  1648.  
  1649.        Parse_End ();
  1650.      END_CASE
  1651.  
  1652.      CASE (TEXTURE_TOKEN)
  1653.        Object->Type |= TEXTURED_OBJECT;
  1654.        Local_Texture = Parse_Texture ();
  1655.        Link_Textures(&(Object->Texture), Local_Texture);
  1656.      END_CASE
  1657.  
  1658.      CASE3 (PIGMENT_TOKEN, TNORMAL_TOKEN, FINISH_TOKEN)
  1659.        Object->Type |= TEXTURED_OBJECT;
  1660.        if (Object->Texture == NULL)
  1661.          Object->Texture = Copy_Textures(Default_Texture);
  1662.        else
  1663.          if (Object->Texture->Type != PNF_TEXTURE)
  1664.            Link_Textures(&(Object->Texture), Copy_Textures(Default_Texture));
  1665.        UNGET
  1666.        EXPECT
  1667.          CASE (PIGMENT_TOKEN)
  1668.            Parse_Pigment ( &(Object->Texture->Pigment) );
  1669.          END_CASE
  1670.  
  1671.          CASE (TNORMAL_TOKEN)
  1672.            Parse_Tnormal ( &(Object->Texture->Tnormal) );
  1673.          END_CASE
  1674.  
  1675.          CASE (FINISH_TOKEN)
  1676.            Parse_Finish ( &(Object->Texture->Finish) );
  1677.          END_CASE
  1678.  
  1679.          OTHERWISE
  1680.            UNGET
  1681.            EXIT
  1682.      END_CASE
  1683.        END_EXPECT
  1684.      END_CASE
  1685.  
  1686.      CASE (INVERSE_TOKEN)
  1687.        if (Object->Type & PATCH_OBJECT)
  1688.          Warn ("Cannot invert a patch object",0.0);
  1689.        Invert_Object (Object);
  1690.      END_CASE
  1691.  
  1692.      CASE (STURM_TOKEN)
  1693.        if (!(Object->Type & STURM_OK_OBJECT))
  1694.          Error ("Cannot use STRUM here");
  1695.        ((POLY *) Object)->Sturm_Flag = TRUE;
  1696.      END_CASE
  1697.  
  1698.      CASE (WATER_LEVEL_TOKEN)
  1699.        if (!(Object->Type & WATER_LEVEL_OK_OBJECT))
  1700.          Error ("Cannot use WATER_LEVEL here");
  1701.        Temp_Water_Level = Parse_Float();
  1702.        if (Language_Version < 2.0)
  1703.          Temp_Water_Level /=256.0;
  1704.        ((HEIGHT_FIELD *) Object)->bounding_box->bounds[0].y = 65536.0 * Temp_Water_Level;
  1705.      END_CASE
  1706.  
  1707.      CASE (SMOOTH_TOKEN)
  1708.        if (!(Object->Type & SMOOTH_OK_OBJECT))
  1709.          Error ("Cannot use SMOOTH here");
  1710.        ((HEIGHT_FIELD *) Object)->Smoothed = TRUE;
  1711.        Object->Type |= DOUBLE_ILLUMINATE;
  1712.      END_CASE
  1713.  
  1714.      CASE (NO_SHADOW_TOKEN)
  1715.        Object->No_Shadow_Flag = TRUE;
  1716.      END_CASE
  1717.  
  1718.      CASE (LIGHT_SOURCE_TOKEN)
  1719.        Error("Light source must be defined using new syntax");
  1720.      END_CASE
  1721.  
  1722.      OTHERWISE
  1723.        UNGET
  1724.        EXIT
  1725.      END_CASE
  1726.    END_EXPECT
  1727.  
  1728.    if (Object->Bound != NULL)
  1729.      {
  1730. #ifdef DB_CODE
  1731.       /* I don't like this! What if the bounding object's bounding box
  1732.      is larger than the object's bounding box ??? */
  1733. #else
  1734.       Object->Bounds.Lower_Left = Object->Bound->Bounds.Lower_Left;
  1735.       Object->Bounds.Lengths    = Object->Bound->Bounds.Lengths;
  1736. #endif
  1737.      }
  1738.    Parse_End ();
  1739.   }
  1740.  
  1741. static
  1742. OBJECT *Parse_Sphere ()
  1743.   {
  1744.    SPHERE *Object;
  1745.  
  1746.    Parse_Begin ();
  1747.  
  1748.    if ( (Object = (SPHERE *)Parse_Object_Id()) != NULL)
  1749.       return ((OBJECT *) Object);
  1750.       
  1751.    Object = Create_Sphere();
  1752.  
  1753.    Parse_Vector(&(Object -> Center));   Parse_Comma();
  1754.    Object -> Radius = Parse_Float();
  1755.    Object -> Radius_Squared = Object -> Radius * Object -> Radius;
  1756.    Object -> Inverse_Radius = 1.0 / Object -> Radius;
  1757.  
  1758.    Make_Vector(&Object->Bounds.Lower_Left,
  1759.            Object->Center.x - Object->Radius,
  1760.            Object->Center.y - Object->Radius,
  1761.            Object->Center.z - Object->Radius);
  1762.    Make_Vector(&Object->Bounds.Lengths,
  1763.            2.0 * Object->Radius,
  1764.            2.0 * Object->Radius,
  1765.            2.0 * Object->Radius);
  1766.  
  1767.    Parse_Object_Mods ((OBJECT *) Object);
  1768.  
  1769.    return ((OBJECT *) Object);
  1770.   }
  1771.  
  1772. static
  1773. OBJECT *Parse_Plane ()
  1774.   {
  1775.    PLANE *Object;
  1776.  
  1777.    Parse_Begin ();
  1778.  
  1779.    if ( (Object = (PLANE *)Parse_Object_Id()) != NULL)
  1780.       return ((OBJECT *) Object);
  1781.  
  1782.    Object = Create_Plane();
  1783.  
  1784.    Parse_Vector(&(Object -> Normal_Vector));   Parse_Comma();
  1785.    VNormalize(Object->Normal_Vector, Object->Normal_Vector);
  1786.    Object->Distance = -Parse_Float();
  1787.  
  1788.    Parse_Object_Mods ((OBJECT *)Object);
  1789.  
  1790.    return ((OBJECT *) Object);
  1791.   }
  1792.  
  1793. static
  1794. OBJECT *Parse_Height_Field ()
  1795.   {
  1796.    HEIGHT_FIELD *Object;
  1797.    VECTOR Local_Vector;
  1798.    IMAGE *Image;
  1799.  
  1800.    Parse_Begin ();
  1801.  
  1802.    if ( (Object = (HEIGHT_FIELD *)Parse_Object_Id()) != NULL)
  1803.       return ((OBJECT *) Object);
  1804.  
  1805.    Object = Create_Height_Field();
  1806.  
  1807.    Image = Parse_Image (HF_FILE);
  1808.    Image->Use_Colour_Flag = FALSE;
  1809.  
  1810.    Object->bounding_box->bounds[0].x = 1.0;
  1811.    Object->bounding_box->bounds[0].y = 0.0;
  1812.    Object->bounding_box->bounds[0].z = 1.0;
  1813.    if (Image->File_Type == POT_FILE)
  1814.      {
  1815.       Object->bounding_box->bounds[1].x = Image -> width/2.0 - 2.0;
  1816.       Make_Vector(&Local_Vector,2.0/Image->width,1.0/65536.0,1.0/Image->height);
  1817.      }
  1818.    else
  1819.      {
  1820.       Object->bounding_box->bounds[1].x = Image -> width - 2.0;
  1821.       Make_Vector(&Local_Vector,1.0/(Image->width),1.0/65536.0,1.0/(Image->height));
  1822.      }
  1823.    Object->bounding_box->bounds[1].y = 65536.0;
  1824.    Object->bounding_box->bounds[1].z = Image -> height - 2.0;
  1825.    Compute_Scaling_Transform(Object->Trans,&Local_Vector);
  1826.  
  1827.    Parse_Object_Mods ((OBJECT *)Object);
  1828.  
  1829.    Find_Hf_Min_Max(Object, Image);
  1830.  
  1831.    return ((OBJECT *) Object);
  1832.   }
  1833.  
  1834. static
  1835. OBJECT *Parse_Triangle ()
  1836.   {
  1837.    TRIANGLE *Object;
  1838.  
  1839.    Parse_Begin ();
  1840.  
  1841.    if ( (Object = (TRIANGLE *)Parse_Object_Id()) != NULL)
  1842.       return ((OBJECT *) Object);
  1843.       
  1844.    Object = Create_Triangle();
  1845.  
  1846.    Parse_Vector (&Object->P1);    Parse_Comma();
  1847.    Parse_Vector (&Object->P2);    Parse_Comma();
  1848.    Parse_Vector (&Object->P3);
  1849.    if (!Compute_Triangle (Object,FALSE))
  1850.      fprintf (stdout, "Degenerate triangle on line %d.  Please remove.\n",
  1851.           Token.Token_Line_No+1);
  1852.  
  1853.    Parse_Object_Mods ((OBJECT *)Object);
  1854.  
  1855.    return ((OBJECT *) Object);
  1856.   }
  1857.  
  1858. static
  1859. OBJECT *Parse_Smooth_Triangle ()
  1860.   {
  1861.    SMOOTH_TRIANGLE *Object;
  1862.    short degen;                                                   /* LSK */
  1863.    DBL vlen;                                                      /* LSK */
  1864.  
  1865.    degen=FALSE;
  1866.  
  1867.    Parse_Begin ();
  1868.  
  1869.    if ( (Object = (SMOOTH_TRIANGLE *)Parse_Object_Id()) != NULL)
  1870.       return ((OBJECT *) Object);
  1871.  
  1872.    Object = Create_Smooth_Triangle();
  1873.  
  1874.    Parse_Vector (&Object->P1);    Parse_Comma();
  1875.    Parse_Vector (&Object->N1);    Parse_Comma();
  1876.  
  1877.    VLength(vlen,Object->N1);                                     /* LSK */
  1878.    if (vlen<1E-09)                                               /* LSK */
  1879.      degen=TRUE;                                                 /* LSK */
  1880.    else                                                          /* LSK */
  1881.      VNormalize (Object->N1, Object->N1);
  1882.  
  1883.    Parse_Vector (&Object->P2);    Parse_Comma();
  1884.    Parse_Vector (&Object->N2);    Parse_Comma();
  1885.  
  1886.    VLength(vlen,Object->N2);                                     /* LSK */
  1887.    if (vlen<1E-09)                                               /* LSK */
  1888.      degen=TRUE;                                                 /* LSK */
  1889.    else                                                          /* LSK */
  1890.      VNormalize (Object->N2, Object->N2);
  1891.  
  1892.    Parse_Vector (&Object->P3);    Parse_Comma();
  1893.    Parse_Vector (&Object->N3);
  1894.  
  1895.    VLength(vlen,Object->N3);                                     /* LSK */
  1896.    if (vlen<1E-09)                                               /* LSK */
  1897.      degen=TRUE;                                                 /* LSK */
  1898.    else                                                          /* LSK */
  1899.      VNormalize (Object->N3, Object->N3);
  1900.  
  1901.    if (!degen) {                                                 /* LSK */
  1902.      degen=!Compute_Triangle ((TRIANGLE *) Object,TRUE);         /* LSK */
  1903.    }
  1904.  
  1905.    if (degen)                                                    /* LSK */
  1906.      fprintf (stdout, "Degenerate triangle on line %d.  Please remove.\n",
  1907.               Token.Token_Line_No+1);
  1908.  
  1909.    Parse_Object_Mods ((OBJECT *)Object);
  1910.  
  1911.    return ((OBJECT *) Object);
  1912.  }
  1913.  
  1914. static
  1915. OBJECT *Parse_Quadric ()
  1916.   {
  1917.    QUADRIC *Object;
  1918.  
  1919.    Parse_Begin ();
  1920.  
  1921.    if ( (Object = (QUADRIC *)Parse_Object_Id()) != NULL)
  1922.       return ((OBJECT *) Object);
  1923.       
  1924.    Object = Create_Quadric();
  1925.  
  1926.    Parse_Vector(&(Object -> Square_Terms));     Parse_Comma();
  1927.    Parse_Vector(&(Object -> Mixed_Terms));      Parse_Comma();
  1928.    Parse_Vector(&(Object -> Terms));            Parse_Comma();
  1929.    Object -> Constant = Parse_Float();
  1930.    Object -> Non_Zero_Square_Term =
  1931.      !( (Object -> Square_Terms.x == 0.0)
  1932.      && (Object -> Square_Terms.y == 0.0)
  1933.      && (Object -> Square_Terms.z == 0.0)
  1934.      && (Object -> Mixed_Terms.x == 0.0)
  1935.      && (Object -> Mixed_Terms.y == 0.0)
  1936.      && (Object -> Mixed_Terms.z == 0.0));
  1937.  
  1938. #ifdef DB_CODE
  1939.    /* necessary for bounding of quadrics. */
  1940.    Compute_Quadric_BBox(Object);
  1941. #endif
  1942.  
  1943.    Parse_Object_Mods ((OBJECT *)Object);
  1944.    
  1945.    return ((OBJECT *) Object);
  1946.   }
  1947.  
  1948. static
  1949. OBJECT *Parse_Box ()
  1950.   {
  1951.    BOX *Object;
  1952.    DBL temp;
  1953.  
  1954.    Parse_Begin ();
  1955.  
  1956.    if ( (Object = (BOX *)Parse_Object_Id()) != NULL)
  1957.       return ((OBJECT *) Object);
  1958.       
  1959.    Object = Create_Box();
  1960.  
  1961.    Parse_Vector(&(Object->bounds[0]));     Parse_Comma();
  1962.    Parse_Vector(&(Object->bounds[1]));
  1963.  
  1964.     if (Object->bounds[0].x > Object->bounds[1].x) {
  1965.        temp = Object->bounds[0].x;
  1966.        Object->bounds[0].x = Object->bounds[1].x;
  1967.        Object->bounds[1].x = temp;
  1968.        }
  1969.     if (Object->bounds[0].y > Object->bounds[1].y) {
  1970.        temp = Object->bounds[0].y;
  1971.        Object->bounds[0].y = Object->bounds[1].y;
  1972.        Object->bounds[1].y = temp;
  1973.        }
  1974.     if (Object->bounds[0].z > Object->bounds[1].z) {
  1975.        temp = Object->bounds[0].z;
  1976.        Object->bounds[0].z = Object->bounds[1].z;
  1977.        Object->bounds[1].z = temp;
  1978.        }
  1979.  
  1980.    Object->Bounds.Lower_Left = Object->bounds[0];
  1981.    VSub(Object->Bounds.Lengths, Object->bounds[1],Object->bounds[0]);
  1982.  
  1983.    Parse_Object_Mods ((OBJECT *)Object);
  1984.  
  1985.    return ((OBJECT *) Object);
  1986.   }
  1987.  
  1988.  
  1989.  
  1990. static
  1991. OBJECT *Parse_Disc ()
  1992.   {
  1993.    DISC *Object;
  1994.    DBL tmpf;
  1995.    VECTOR lengths;
  1996.  
  1997.    Parse_Begin ();
  1998.  
  1999.    if ( (Object = (DISC *)Parse_Object_Id()) != NULL)
  2000.       return ((OBJECT *) Object);
  2001.       
  2002.    Object = Create_Disc();
  2003.  
  2004.    Parse_Vector(&(Object->center)); Parse_Comma ();
  2005.    Parse_Vector(&(Object->normal)); Parse_Comma ();
  2006.    VNormalize(Object->normal, Object->normal);
  2007.  
  2008.    tmpf = Parse_Float(); Parse_Comma ();
  2009.    Object->oradius2 = tmpf * tmpf;
  2010.  
  2011.    EXPECT
  2012.      CASE_FLOAT
  2013.        tmpf = Parse_Float();
  2014.        Object->iradius2 = tmpf * tmpf;
  2015.      END_CASE
  2016.  
  2017.      OTHERWISE
  2018.        UNGET
  2019.        EXIT
  2020.      END_CASE
  2021.    END_EXPECT
  2022.  
  2023.    /* Calculate info needed for ray-disc intersections */
  2024.    VDot(tmpf, Object->center, Object->normal);
  2025.    Object->d = -tmpf;
  2026.  
  2027.    /* Calculate the bounds */
  2028.    tmpf = sqrt(Object->oradius2);
  2029.    Make_Vector(&lengths, tmpf, tmpf, tmpf);
  2030.    VSub(Object->Bounds.Lower_Left, Object->center, lengths);
  2031.    VScale(Object->Bounds.Lengths, lengths, 2.0);
  2032.  
  2033.    Parse_Object_Mods ((OBJECT *)Object);
  2034.  
  2035.    return ((OBJECT *) Object);
  2036.   }
  2037.  
  2038. static
  2039. OBJECT *Parse_Cylinder ()
  2040.   {
  2041.    CONE *Object;
  2042.  
  2043.    Parse_Begin ();
  2044.  
  2045.    if ( (Object = (CONE *)Parse_Object_Id()) != NULL)
  2046.       return ((OBJECT *) Object);
  2047.       
  2048.    Object = Create_Cylinder();
  2049.  
  2050.    Parse_Vector(&(Object->apex));  Parse_Comma ();
  2051.    Parse_Vector(&(Object->base));  Parse_Comma ();
  2052.    Object->apex_radius = Parse_Float();
  2053.    Object->base_radius = Object->apex_radius;
  2054.  
  2055.    EXPECT
  2056.      CASE(OPEN_TOKEN)
  2057.        Object->closed = 0;
  2058.        EXIT
  2059.      END_CASE
  2060.      
  2061.      OTHERWISE
  2062.        UNGET
  2063.        EXIT
  2064.      END_CASE
  2065.    END_EXPECT
  2066.  
  2067.    Compute_Cylinder_Data((OBJECT *)Object);
  2068.  
  2069.    Parse_Object_Mods ((OBJECT *)Object);
  2070.  
  2071.    return ((OBJECT *) Object);
  2072.   }
  2073.  
  2074. static
  2075. OBJECT *Parse_Cone ()
  2076.   {
  2077.    CONE *Object;
  2078.  
  2079.    Parse_Begin ();
  2080.  
  2081.    if ( (Object = (CONE *)Parse_Object_Id()) != NULL)
  2082.       return ((OBJECT *) Object);
  2083.       
  2084.    Object = Create_Cone();
  2085.  
  2086.    Parse_Vector(&(Object->apex));  Parse_Comma ();
  2087.    Object->apex_radius = Parse_Float();  Parse_Comma ();
  2088.  
  2089.    Parse_Vector(&(Object->base));  Parse_Comma ();
  2090.    Object->base_radius = Parse_Float();
  2091.    
  2092.    EXPECT
  2093.      CASE(OPEN_TOKEN)
  2094.        Object->closed = 0;
  2095.        EXIT
  2096.      END_CASE
  2097.      
  2098.      OTHERWISE
  2099.        UNGET
  2100.        EXIT
  2101.      END_CASE
  2102.    END_EXPECT
  2103.  
  2104.    /* Compute run-time values for the cone */
  2105.    Compute_Cone_Data((OBJECT *)Object);
  2106.  
  2107.    Parse_Object_Mods ((OBJECT *)Object);
  2108.  
  2109.    return ((OBJECT *) Object);
  2110.   }
  2111.  
  2112. static
  2113. OBJECT *Parse_Blob ()
  2114.   {
  2115.    BLOB *Object;
  2116.    DBL threshold;
  2117.    int npoints;
  2118.    blobstackptr blob_components, blob_component;
  2119.  
  2120.    Parse_Begin ();
  2121.  
  2122.    if ( (Object = (BLOB *)Parse_Object_Id()) != NULL)
  2123.       return ((OBJECT *) Object);
  2124.       
  2125.    Object = Create_Blob();
  2126.  
  2127.    blob_components = NULL;
  2128.    npoints = 0;
  2129.    threshold = 1.0;
  2130.  
  2131.    EXPECT
  2132.      CASE (THRESHOLD_TOKEN)
  2133.        threshold = Parse_Float();
  2134.      END_CASE
  2135.  
  2136.      CASE (COMPONENT_TOKEN)
  2137.        blob_component = (blobstackptr) malloc(sizeof(struct blob_list_struct));
  2138.        if (blob_component == NULL)
  2139.           MAError("blob component");
  2140.        blob_component->elem.coeffs[2] = Parse_Float(); Parse_Comma();
  2141.        blob_component->elem.radius2   = Parse_Float(); Parse_Comma();
  2142.        Parse_Vector(&blob_component->elem.pos);
  2143.        blob_component->next = blob_components;
  2144.        blob_components = blob_component;
  2145.        npoints++;
  2146.      END_CASE
  2147.  
  2148.      OTHERWISE
  2149.        UNGET
  2150.        EXIT
  2151.      END_CASE
  2152.    END_EXPECT
  2153.  
  2154.    /* Finally, process the information */
  2155.    MakeBlob(Object, threshold, blob_components, npoints, 0);
  2156.  
  2157.    Parse_Object_Mods ((OBJECT *)Object);
  2158.  
  2159.    return ((OBJECT *) Object);
  2160.   }
  2161.  
  2162. static
  2163. OBJECT *Parse_Torus ()
  2164.   {
  2165.    POLY *Object;
  2166.    DBL iradius, oradius, *Coeffs;
  2167.  
  2168.    Parse_Begin ();
  2169.  
  2170.    if ( (Object = (POLY *)Parse_Object_Id()) != NULL)
  2171.       return ((OBJECT *) Object);
  2172.       
  2173.    Object = Create_Poly(4);
  2174.  
  2175.    /* Read in the two radii */
  2176.    iradius = Parse_Float(); /* Big radius */
  2177.    Parse_Comma();
  2178.    oradius = Parse_Float(); /* Little radius */
  2179.  
  2180.    /* Build the coefficients of a torus lying in the x-z plane */
  2181.    Coeffs = Object->Coeffs;
  2182.    Coeffs[ 0] =  1.0;
  2183.    Coeffs[ 4] =  2.0;
  2184.    Coeffs[ 7] =  2.0;
  2185.    Coeffs[ 9] = -2.0 * (iradius * iradius + oradius * oradius);
  2186.    Coeffs[20] =  1.0;
  2187.    Coeffs[23] =  2.0;
  2188.    Coeffs[25] =  2.0 * (iradius * iradius - oradius * oradius);
  2189.    Coeffs[30] =  1.0;
  2190.    Coeffs[32] = -2.0 * (iradius * iradius + oradius * oradius);
  2191.    Coeffs[34] = (iradius * iradius - oradius * oradius) *
  2192.             (iradius * iradius - oradius * oradius);
  2193.  
  2194.    Make_Vector(&Object->Bounds.Lower_Left, -(iradius + oradius),
  2195.            -iradius, -(iradius + oradius))
  2196.    Make_Vector(&Object->Bounds.Lengths, 2.0 * (iradius + oradius),
  2197.            2.0 * iradius, 2.0 * (iradius + oradius));
  2198.  
  2199.    Parse_Object_Mods ((OBJECT *)Object);
  2200.  
  2201.    return ((OBJECT *) Object);
  2202.   }
  2203.  
  2204. static
  2205. OBJECT *Parse_Poly (order)
  2206.   int order;
  2207.   {
  2208.    POLY *Object;
  2209.  
  2210.    Parse_Begin ();
  2211.  
  2212.    if ( (Object = (POLY *)Parse_Object_Id()) != NULL)
  2213.       return ((OBJECT *) Object);
  2214.       
  2215.    if (order == 0)
  2216.      {
  2217.       order = (int)Parse_Float();      Parse_Comma();
  2218.       if (order < 2 || order > MAX_ORDER)
  2219.         Error("Order of poly is out of range");
  2220.      }
  2221.  
  2222.    Object = Create_Poly(order);
  2223.  
  2224.    Parse_Coeffs(Object->Order, &(Object->Coeffs[0]));
  2225.  
  2226.    Parse_Object_Mods ((OBJECT *)Object);
  2227.  
  2228.    return ((OBJECT *) Object);
  2229.   }
  2230.  
  2231. static
  2232. OBJECT *Parse_Bicubic_Patch ()
  2233.   {
  2234.    BICUBIC_PATCH *Object;
  2235.    int i, j;
  2236.  
  2237.    Parse_Begin ();
  2238.  
  2239.    if ( (Object = (BICUBIC_PATCH *)Parse_Object_Id()) != NULL)
  2240.       return ((OBJECT *) Object);
  2241.       
  2242.    Object = Create_Bicubic_Patch();
  2243.  
  2244.    EXPECT
  2245.      CASE_FLOAT
  2246.        Warn("Should use keywords for bicubic parameters.",1.5);
  2247.        Object->Patch_Type = (int)Parse_Float();
  2248.        if (Object->Patch_Type == 2 ||
  2249.            Object->Patch_Type == 3)
  2250.            Object->Flatness_Value = Parse_Float();
  2251.          else
  2252.            Object->Flatness_Value = 0.1;
  2253.        Object->U_Steps = (int)Parse_Float();
  2254.        Object->V_Steps = (int)Parse_Float();
  2255.        EXIT
  2256.      END_CASE       
  2257.        
  2258.      CASE (TYPE_TOKEN)
  2259.        Object->Patch_Type = (int)Parse_Float();
  2260.      END_CASE
  2261.  
  2262.      CASE (FLATNESS_TOKEN)
  2263.        Object->Flatness_Value = Parse_Float();
  2264.      END_CASE
  2265.  
  2266.      CASE (V_STEPS_TOKEN)
  2267.        Object->V_Steps = (int)Parse_Float();
  2268.      END_CASE
  2269.  
  2270.      CASE (U_STEPS_TOKEN)
  2271.        Object->U_Steps = (int)Parse_Float();
  2272.      END_CASE
  2273.  
  2274.      OTHERWISE
  2275.        UNGET
  2276.        EXIT
  2277.      END_CASE
  2278.    END_EXPECT
  2279.  
  2280.    if (Object->Patch_Type > 1)
  2281.      {
  2282.       Object->Patch_Type = 1;
  2283.       Warn("Patch type no longer supported. Using type 1.",0.0);
  2284.      }
  2285.  
  2286.    if ((Object->Patch_Type < 0) || (Object->Patch_Type > MAX_PATCH_TYPE))
  2287.      Error("Undefined bicubic patch type");
  2288.  
  2289.    Parse_Comma();
  2290.    for (i=0;i<4;i++)
  2291.      for (j=0;j<4;j++)
  2292.        {
  2293.         Parse_Vector(&(Object -> Control_Points[i][j]));
  2294.         if (!((i==3)&&(j==3)))
  2295.           Parse_Comma();
  2296.        };
  2297.    Precompute_Patch_Values(Object); /* interpolated mesh coords */
  2298.  
  2299.    Parse_Object_Mods ((OBJECT *)Object);
  2300.  
  2301.    return ((OBJECT *) Object);
  2302.   }
  2303.  
  2304. static
  2305. OBJECT *Parse_CSG (CSG_Type)
  2306.   int CSG_Type;
  2307.   {
  2308.    CSG *Object;
  2309.    OBJECT *Local;
  2310.    int Object_Count = 0;
  2311.  
  2312.    Parse_Begin ();
  2313.  
  2314.    if ( (Object = (CSG *)Parse_Object_Id()) != NULL)
  2315.       return ((OBJECT *) Object);
  2316.       
  2317.    if (CSG_Type & CSG_UNION_TYPE)
  2318.      Object = Create_CSG_Union ();
  2319.    else
  2320.      if (CSG_Type & CSG_MERGE_TYPE)
  2321.        Object = Create_CSG_Merge ();
  2322.      else
  2323.        Object = Create_CSG_Intersection ();
  2324.  
  2325.    Object->Children = NULL;
  2326.  
  2327.    while ((Local = Parse_Object ()) != NULL)
  2328.      {
  2329.       if ((CSG_Type & CSG_INTERSECTION_TYPE) && (Local->Type & PATCH_OBJECT))
  2330.         Warn ("Patch objects not allowed in intersection",0.0);
  2331.       Object_Count++;
  2332.       if ((CSG_Type & CSG_DIFFERENCE_TYPE) && (Object_Count > 1))
  2333.         Invert_Object (Local);
  2334.       Object->Type |=  (Local->Type & CHILDREN_FLAGS);
  2335.       Local->Type |= IS_CHILD_OBJECT;
  2336.       Link(Local, &Local->Sibling, &Object->Children);
  2337.      };
  2338.  
  2339.    if ((Object_Count < 2) && (Language_Version >= 1.5))
  2340.      Warn ("Should have at least 2 objects in csg",1.5);
  2341.    Compute_CSG_Bounds((OBJECT *)Object);
  2342.  
  2343.    Parse_Object_Mods ((OBJECT *)Object);
  2344.  
  2345.    return ((OBJECT *) Object);
  2346.   }
  2347.  
  2348. static
  2349. OBJECT *Parse_Light_Source ()
  2350.   {
  2351.    VECTOR Local_Vector;
  2352.    LIGHT_SOURCE *Object;
  2353.  
  2354.    Parse_Begin ();
  2355.  
  2356.    if ( (Object = (LIGHT_SOURCE *)Parse_Object_Id()) != NULL)
  2357.       return ((OBJECT *) Object);
  2358.       
  2359.    Object = Create_Light_Source ();
  2360.  
  2361.    Parse_Vector(&Object->Center);
  2362.  
  2363.    GET (COLOUR_TOKEN)
  2364.  
  2365.    Parse_Colour (&Object->Colour);
  2366.  
  2367.    EXPECT
  2368.      CASE (LOOKS_LIKE_TOKEN)
  2369.        if (Object->Children != NULL)
  2370.          Error("Only one looks_like allowed per light_source");
  2371.        Parse_Begin ();
  2372.        Object->Type &= ~(int)PATCH_OBJECT;
  2373.        if ((Object->Children = Parse_Object ()) == NULL)
  2374.          Parse_Error_Str ("object");
  2375.        Translate_Object (Object->Children, &Object->Center);
  2376.        Parse_Object_Mods (Object->Children);
  2377.        Object->Children->No_Shadow_Flag = TRUE;
  2378.        Object->No_Shadow_Flag = TRUE;
  2379.        Object->Type |= (Object->Children->Type & CHILDREN_FLAGS);
  2380.      END_CASE
  2381.  
  2382.      CASE (SPOTLIGHT_TOKEN)
  2383.        Object->Light_Type = SPOT_SOURCE;
  2384.      END_CASE
  2385.  
  2386.      CASE (POINT_AT_TOKEN)
  2387.        if (Object->Light_Type == SPOT_SOURCE)
  2388.          Parse_Vector(&Object->Points_At);
  2389.        else
  2390.          Error("Spotlight param illegal in standard light source");
  2391.      END_CASE
  2392.  
  2393.      CASE (TIGHTNESS_TOKEN)
  2394.        if (Object->Light_Type == SPOT_SOURCE)
  2395.          Object->Coeff = Parse_Float();
  2396.        else
  2397.          Error("Spotlight param illegal in standard light source");
  2398.      END_CASE
  2399.  
  2400.      CASE (RADIUS_TOKEN)
  2401.        if (Object->Light_Type == SPOT_SOURCE)
  2402.          Object->Radius = cos(Parse_Float() * M_PI / 180.0);
  2403.        else
  2404.          Error("Spotlight param illegal in standard light source");
  2405.      END_CASE
  2406.  
  2407.      CASE (FALLOFF_TOKEN)
  2408.        if (Object->Light_Type == SPOT_SOURCE)
  2409.          Object->Falloff = cos(Parse_Float() * M_PI / 180.0);
  2410.        else
  2411.          Error("Spotlight param illegal in standard light source");
  2412.      END_CASE
  2413.  
  2414.      CASE (AREA_LIGHT_TOKEN)
  2415.        Object -> Area_Light = TRUE;
  2416.        Parse_Vector (&(Object -> Axis1)); Parse_Comma ();
  2417.        Parse_Vector (&(Object -> Axis2)); Parse_Comma ();
  2418.        Object -> Area_Size1 = (int)Parse_Float(); Parse_Comma ();
  2419.        Object -> Area_Size2 = (int)Parse_Float();
  2420.        Object -> Light_Grid = Create_Light_Grid (Object -> Area_Size1,
  2421.             Object -> Area_Size2);
  2422.      END_CASE
  2423.  
  2424.      CASE (JITTER_TOKEN)
  2425.        Object -> Jitter = TRUE;
  2426.      END_CASE
  2427.  
  2428.      CASE (TRACK_TOKEN)
  2429.        Object -> Track = TRUE;
  2430.      END_CASE
  2431.  
  2432.      CASE (ADAPTIVE_TOKEN)
  2433.        Object -> Adaptive_Level = (int)Parse_Float();
  2434.      END_CASE
  2435.  
  2436.      CASE (TRANSLATE_TOKEN)
  2437.        Parse_Vector (&Local_Vector);
  2438.        Translate_Object ((OBJECT *)Object, &Local_Vector);
  2439.      END_CASE
  2440.  
  2441.      CASE (ROTATE_TOKEN)
  2442.        Parse_Vector (&Local_Vector);
  2443.        Rotate_Object ((OBJECT *)Object, &Local_Vector);
  2444.      END_CASE
  2445.  
  2446.      CASE (SCALE_TOKEN)
  2447.        Parse_Scale_Vector (&Local_Vector);
  2448.        Scale_Object ((OBJECT *)Object, &Local_Vector);
  2449.      END_CASE
  2450.  
  2451.      CASE (TRANSFORM_TOKEN)
  2452.        GET(TRANSFORM_ID_TOKEN)
  2453.        Transform_Object ((OBJECT *)Object, (TRANSFORM *)Token.Constant_Data);
  2454.      END_CASE
  2455.  
  2456.      OTHERWISE
  2457.        UNGET
  2458.        EXIT
  2459.      END_CASE
  2460.    END_EXPECT
  2461.  
  2462.    Parse_End ();
  2463.  
  2464.    return ((OBJECT *)Object);
  2465.   }
  2466.  
  2467.  
  2468. static
  2469. OBJECT *Parse_Object ()
  2470.   {
  2471.    OBJECT *Object = NULL;
  2472.  
  2473.    EXPECT
  2474.      CASE (SPHERE_TOKEN)
  2475.        Object = Parse_Sphere ();
  2476.        EXIT
  2477.      END_CASE
  2478.  
  2479.      CASE (PLANE_TOKEN)
  2480.        Object = Parse_Plane ();
  2481.        EXIT
  2482.      END_CASE
  2483.  
  2484.      CASE (CONE_TOKEN)
  2485.        Object = Parse_Cone ();
  2486.        EXIT
  2487.      END_CASE
  2488.  
  2489.      CASE (CYLINDER_TOKEN)
  2490.        Object = Parse_Cylinder ();
  2491.        EXIT
  2492.      END_CASE
  2493.  
  2494.      CASE (DISC_TOKEN)
  2495.        Object = Parse_Disc ();
  2496.        EXIT
  2497.      END_CASE
  2498.  
  2499.      CASE (QUADRIC_TOKEN)
  2500.        Object = Parse_Quadric ();
  2501.        EXIT
  2502.      END_CASE
  2503.  
  2504.      CASE (CUBIC_TOKEN)
  2505.        Object = Parse_Poly (3);
  2506.        EXIT
  2507.      END_CASE
  2508.  
  2509.      CASE (QUARTIC_TOKEN)
  2510.        Object = Parse_Poly (4);
  2511.        EXIT
  2512.      END_CASE
  2513.  
  2514.      CASE (POLY_TOKEN)
  2515.        Object = Parse_Poly (0);
  2516.        EXIT
  2517.      END_CASE
  2518.  
  2519.      CASE (TORUS_TOKEN)
  2520.        Object = Parse_Torus ();
  2521.        EXIT
  2522.      END_CASE
  2523.  
  2524.      CASE (OBJECT_ID_TOKEN)
  2525.        Object = Copy_Object((OBJECT *) Token.Constant_Data);
  2526.        EXIT
  2527.      END_CASE
  2528.  
  2529.      CASE (UNION_TOKEN)
  2530.        Object = Parse_CSG (CSG_UNION_TYPE);
  2531.        EXIT
  2532.      END_CASE
  2533.  
  2534.      CASE (COMPOSITE_TOKEN)
  2535.        Warn("Use union instead of composite",1.5);
  2536.        Object = Parse_CSG (CSG_UNION_TYPE);
  2537.        EXIT
  2538.      END_CASE
  2539.  
  2540.      CASE (MERGE_TOKEN)
  2541.        Object = Parse_CSG (CSG_MERGE_TYPE);
  2542.        EXIT
  2543.      END_CASE
  2544.  
  2545.      CASE (INTERSECTION_TOKEN)
  2546.        Object = Parse_CSG (CSG_INTERSECTION_TYPE);
  2547.        EXIT
  2548.      END_CASE
  2549.  
  2550.      CASE (DIFFERENCE_TOKEN)
  2551.        Object = Parse_CSG (CSG_DIFFERENCE_TYPE+CSG_INTERSECTION_TYPE);
  2552.        EXIT
  2553.      END_CASE
  2554.  
  2555.      CASE (BICUBIC_PATCH_TOKEN)
  2556.        Object = Parse_Bicubic_Patch ();
  2557.        EXIT
  2558.      END_CASE
  2559.  
  2560.      CASE (TRIANGLE_TOKEN)
  2561.        Object = Parse_Triangle ();
  2562.        EXIT
  2563.      END_CASE
  2564.  
  2565.      CASE (SMOOTH_TRIANGLE_TOKEN)
  2566.        Object = Parse_Smooth_Triangle ();
  2567.        EXIT
  2568.      END_CASE
  2569.  
  2570.      CASE (HEIGHT_FIELD_TOKEN)
  2571.        Object = Parse_Height_Field ();
  2572.        EXIT
  2573.      END_CASE
  2574.  
  2575.      CASE (BOX_TOKEN)
  2576.        Object = Parse_Box ();
  2577.        EXIT
  2578.      END_CASE
  2579.  
  2580.      CASE (BLOB_TOKEN)
  2581.        Object = Parse_Blob ();
  2582.        EXIT
  2583.      END_CASE
  2584.  
  2585.      CASE (LIGHT_SOURCE_TOKEN)
  2586.        Object = Parse_Light_Source ();
  2587.        EXIT
  2588.      END_CASE
  2589.  
  2590.      CASE (OBJECT_TOKEN)
  2591.        Parse_Begin ();
  2592.        Object = Parse_Object ();
  2593.        if (!Object)
  2594.          Parse_Error_Str ("object");
  2595.        Parse_Object_Mods ((OBJECT *)Object);
  2596.        EXIT
  2597.      END_CASE
  2598.  
  2599.      OTHERWISE
  2600.        UNGET
  2601.        EXIT
  2602.      END_CASE
  2603.    END_EXPECT
  2604.  
  2605.    return ((OBJECT *) Object);
  2606.   }
  2607.  
  2608. static void Parse_Fog ()
  2609.   {
  2610.    Parse_Begin ();
  2611.  
  2612.    EXPECT
  2613.      CASE (COLOUR_TOKEN)
  2614.        Parse_Colour (&Frame.Fog_Colour);
  2615.      END_CASE
  2616.  
  2617.      CASE (DISTANCE_TOKEN)
  2618.        Frame.Fog_Distance = Parse_Float ();
  2619.      END_CASE
  2620.  
  2621.      CASE_FLOAT
  2622.        Warn("Should use distance keyword.",1.5);
  2623.        Frame.Fog_Distance = Parse_Float ();
  2624.      END_CASE
  2625.  
  2626.      OTHERWISE
  2627.        UNGET
  2628.        EXIT
  2629.      END_CASE
  2630.    END_EXPECT
  2631.    Parse_End ();
  2632.   }
  2633.  
  2634. static void Parse_Frame ()
  2635.   {
  2636.    OBJECT *Object;
  2637.    TEXTURE *Local_Texture;
  2638.    PIGMENT *Local_Pigment;
  2639.    TNORMAL *Local_Tnormal;
  2640.    FINISH  *Local_Finish;
  2641.  
  2642.    EXPECT
  2643.      CASE (FOG_TOKEN)
  2644.        Parse_Fog();
  2645.      END_CASE
  2646.  
  2647.      CASE (BACKGROUND_TOKEN)
  2648.        Parse_Begin();
  2649.        GET (COLOUR_TOKEN)
  2650.        Parse_Colour (&Frame.Background_Colour);
  2651.        Parse_End();
  2652.      END_CASE
  2653.  
  2654.      CASE (CAMERA_TOKEN)
  2655.        Parse_Camera (&Frame.Camera);
  2656.      END_CASE
  2657.  
  2658.      CASE (DECLARE_TOKEN)
  2659.        Parse_Declare ();
  2660.      END_CASE
  2661.  
  2662.      CASE (MAX_TRACE_LEVEL_TOKEN)
  2663.        Max_Trace_Level = Parse_Float ();
  2664.      END_CASE
  2665.  
  2666.      CASE (VERSION_TOKEN)
  2667.        Language_Version = Parse_Float ();
  2668.      END_CASE
  2669.  
  2670.      CASE (MAX_INTERSECTIONS)
  2671.        Max_Intersections = (int)Parse_Float ();
  2672.      END_CASE
  2673.  
  2674.      CASE (DEFAULT_TOKEN)
  2675.        Not_In_Default = FALSE;
  2676.        Parse_Begin();
  2677.        EXPECT
  2678.          CASE (TEXTURE_TOKEN)
  2679.            Local_Texture = Default_Texture;
  2680.            Default_Texture = Parse_Texture();
  2681.            if (Default_Texture->Type != PNF_TEXTURE)
  2682.              Error("Default texture cannot be material map or tiles");
  2683.            if (Default_Texture->Next_Layer != NULL)
  2684.              Error("Default texture cannot be layered");
  2685.            Destroy_Textures(Local_Texture);
  2686.          END_CASE
  2687.  
  2688.          CASE (PIGMENT_TOKEN)
  2689.            Local_Pigment = Copy_Pigment((Default_Texture->Pigment));
  2690.            Parse_Pigment (&Local_Pigment);
  2691.            Destroy_Pigment(Default_Texture->Pigment);
  2692.            Default_Texture->Pigment = Local_Pigment;
  2693.          END_CASE
  2694.  
  2695.          CASE (TNORMAL_TOKEN)
  2696.            Local_Tnormal = Copy_Tnormal((Default_Texture->Tnormal));
  2697.            Parse_Tnormal (&Local_Tnormal);
  2698.            Destroy_Tnormal(Default_Texture->Tnormal);
  2699.            Default_Texture->Tnormal = Local_Tnormal;
  2700.          END_CASE
  2701.  
  2702.          CASE (FINISH_TOKEN)
  2703.            Local_Finish = Copy_Finish((Default_Texture->Finish));
  2704.            Parse_Finish (&Local_Finish);
  2705.            Destroy_Finish(Default_Texture->Finish);
  2706.            Default_Texture->Finish = Local_Finish;
  2707.          END_CASE
  2708.  
  2709.          CASE (CAMERA_TOKEN)
  2710.        Parse_Camera (&Default_Camera);
  2711.          END_CASE
  2712.  
  2713.          OTHERWISE
  2714.            UNGET
  2715.            EXIT
  2716.          END_CASE
  2717.        END_EXPECT
  2718.        Parse_End();
  2719.        Not_In_Default = TRUE;
  2720.      END_CASE
  2721.  
  2722.      CASE (END_OF_FILE_TOKEN)
  2723.        EXIT
  2724.      END_CASE
  2725.  
  2726.      OTHERWISE
  2727.        UNGET
  2728.        Object = Parse_Object();
  2729.        if (Object == NULL)
  2730.          Parse_Error_Str ("object or directive");
  2731.        Post_Process (Object, NULL);
  2732.        Link_To_Frame (Object);
  2733.      END_CASE
  2734.    END_EXPECT
  2735.   }
  2736.  
  2737. static void Parse_Camera (Camera_Ptr)
  2738.   CAMERA **Camera_Ptr;
  2739.   {
  2740.    VECTOR Local_Vector, Temp_Vector;
  2741.    DBL Direction_Length, Up_Length, Right_Length, Handedness;
  2742.    CAMERA *New;
  2743.  
  2744.    Parse_Begin ();
  2745.  
  2746.    EXPECT
  2747.      CASE (CAMERA_ID_TOKEN)
  2748.        Destroy_Camera(*Camera_Ptr);
  2749.        *Camera_Ptr = Copy_Camera ((CAMERA *) Token.Constant_Data);
  2750.        EXIT
  2751.      END_CASE
  2752.  
  2753.      OTHERWISE
  2754.        UNGET
  2755.        EXIT
  2756.      END_CASE
  2757.    END_EXPECT
  2758.  
  2759.    New = *Camera_Ptr;
  2760.  
  2761.    EXPECT
  2762.      CASE (LOCATION_TOKEN)
  2763.        Parse_Vector(&(New->Location));
  2764.      END_CASE
  2765.  
  2766.      CASE (DIRECTION_TOKEN)
  2767.        Parse_Vector(&(New->Direction));
  2768.      END_CASE
  2769.  
  2770.      CASE (UP_TOKEN)
  2771.        Parse_Vector(&(New->Up));
  2772.      END_CASE
  2773.  
  2774.      CASE (RIGHT_TOKEN)
  2775.        Parse_Vector(&(New->Right));
  2776.      END_CASE
  2777.  
  2778.      CASE (SKY_TOKEN)
  2779.        Parse_Vector(&(New->Sky));
  2780.      END_CASE
  2781.  
  2782.      CASE (LOOK_AT_TOKEN)
  2783.        VLength (Direction_Length, New->Direction);
  2784.        VLength (Up_Length,        New->Up);
  2785.        VLength (Right_Length,     New->Right);
  2786.        VCross  (Temp_Vector,      New->Direction, New->Up);
  2787.        VDot    (Handedness,       Temp_Vector,   New->Right);
  2788.  
  2789.        Parse_Vector (&New->Direction);
  2790.  
  2791.        VSub       (New->Direction, New->Direction, New->Location);
  2792.        VNormalize (New->Direction, New->Direction);
  2793.        VCross     (New->Right,     New->Direction, New->Sky);
  2794.        VNormalize (New->Right,     New->Right);
  2795.        VCross     (New->Up,        New->Right,     New->Direction);
  2796.        VScale     (New->Direction, New->Direction, Direction_Length);
  2797.  
  2798.        if (Handedness >= 0.0)
  2799.      VScale (New->Right, New->Right, Right_Length)
  2800.        else
  2801.      VScale (New->Right, New->Right, -Right_Length);
  2802.  
  2803.        VScale (New->Up, New->Up, Up_Length);
  2804.      END_CASE
  2805.  
  2806.      CASE (TRANSLATE_TOKEN)
  2807.        Parse_Vector (&Local_Vector);
  2808.        Translate_Camera (New, &Local_Vector);
  2809.      END_CASE
  2810.  
  2811.      CASE (ROTATE_TOKEN)
  2812.        Parse_Vector (&Local_Vector);
  2813.        Rotate_Camera (New, &Local_Vector);
  2814.      END_CASE
  2815.  
  2816.      CASE (SCALE_TOKEN)
  2817.        Parse_Scale_Vector (&Local_Vector);
  2818.        Scale_Camera (New, &Local_Vector);
  2819.      END_CASE
  2820.  
  2821.      CASE (TRANSFORM_TOKEN)
  2822.        GET(TRANSFORM_ID_TOKEN)
  2823.        Transform_Camera (New, (TRANSFORM *)Token.Constant_Data);
  2824.      END_CASE
  2825.  
  2826.      OTHERWISE
  2827.        UNGET
  2828.        EXIT
  2829.      END_CASE
  2830.    END_EXPECT
  2831.    Parse_End ();
  2832.   }
  2833.  
  2834. static
  2835. TRANSFORM *Parse_Transform ()
  2836.   {
  2837.    TRANSFORM *New, Local_Trans;
  2838.    VECTOR Local_Vector;
  2839.  
  2840.    Parse_Begin ();
  2841.    New = Create_Transform ();
  2842.  
  2843.    EXPECT
  2844.      CASE(TRANSFORM_ID_TOKEN)
  2845.        Compose_Transforms (New, (TRANSFORM *)Token.Constant_Data);
  2846.        EXIT
  2847.      END_CASE
  2848.  
  2849.      CASE (TRANSLATE_TOKEN)
  2850.        Parse_Vector (&Local_Vector);
  2851.        Compute_Translation_Transform(&Local_Trans, &Local_Vector);
  2852.        Compose_Transforms (New, &Local_Trans);
  2853.      END_CASE
  2854.  
  2855.      CASE (ROTATE_TOKEN)
  2856.        Parse_Vector (&Local_Vector);
  2857.        Compute_Rotation_Transform(&Local_Trans, &Local_Vector);
  2858.        Compose_Transforms (New, &Local_Trans);
  2859.      END_CASE
  2860.  
  2861.      CASE (SCALE_TOKEN)
  2862.        Parse_Scale_Vector (&Local_Vector);
  2863.        Compute_Scaling_Transform(&Local_Trans, &Local_Vector);
  2864.        Compose_Transforms (New, &Local_Trans);
  2865.      END_CASE
  2866.  
  2867.      OTHERWISE
  2868.        UNGET
  2869.        EXIT
  2870.      END_CASE
  2871.    END_EXPECT
  2872.  
  2873.    Parse_End ();
  2874.    return (New);
  2875.   }
  2876.  
  2877. static void Parse_Declare ()
  2878.   {
  2879.   VECTOR Local_Vector;
  2880.   COLOUR *Local_Colour;
  2881.   PIGMENT *Local_Pigment;
  2882.   TNORMAL *Local_Tnormal;
  2883.   FINISH *Local_Finish;
  2884.   TEXTURE *Local_Texture;
  2885.   COLOUR_MAP *Local_Colour_Map;
  2886.   TRANSFORM *Local_Trans;
  2887.   OBJECT *Local_Object;
  2888.   CAMERA *Local_Camera;
  2889.  
  2890.   struct Constant_Struct *Constant_Ptr;
  2891.  
  2892.   EXPECT
  2893.     CASE (IDENTIFIER_TOKEN)
  2894.       if (++Number_Of_Constants >= MAX_CONSTANTS)
  2895.         Error ("Too many constants \"DECLARED\"");
  2896.       else
  2897.         Constant_Ptr = &(Constants[Number_Of_Constants]);
  2898.       EXIT
  2899.     END_CASE
  2900.  
  2901.     CASE4 (COLOUR_ID_TOKEN, VECTOR_ID_TOKEN, FLOAT_ID_TOKEN, PIGMENT_ID_TOKEN)
  2902.     CASE4 (TNORMAL_ID_TOKEN, FINISH_ID_TOKEN, TEXTURE_ID_TOKEN, OBJECT_ID_TOKEN)
  2903.     CASE3 (COLOUR_MAP_ID_TOKEN, TRANSFORM_ID_TOKEN, CAMERA_ID_TOKEN)
  2904.       Constant_Ptr = &(Constants[Token.Constant_Index]);
  2905.       EXIT
  2906.     END_CASE
  2907.  
  2908.     OTHERWISE
  2909.       Parse_Error(IDENTIFIER_TOKEN);
  2910.     END_CASE
  2911.   END_EXPECT
  2912.  
  2913.   Previous = Token.Token_Id;
  2914.  
  2915.   GET (EQUALS_TOKEN);
  2916.  
  2917.   EXPECT
  2918.     CASE (COLOUR_TOKEN)
  2919.       if (Test_Redefine(COLOUR_ID_TOKEN))
  2920.         Destroy_Colour((COLOUR *)Constant_Ptr->Constant_Data);
  2921.       Local_Colour = Create_Colour();
  2922.       Parse_Colour (Local_Colour);
  2923.       Constant_Ptr -> Constant_Data = (char *) Local_Colour;
  2924.       Constant_Ptr -> Constant_Type = COLOUR_CONSTANT;
  2925.       EXIT
  2926.     END_CASE
  2927.  
  2928.     CASE_VECTOR
  2929.       Have_Vector = FALSE;
  2930.       Parse_Vector_Float (&Local_Vector);
  2931.       if (Have_Vector)
  2932.         {
  2933.          if (Test_Redefine(VECTOR_ID_TOKEN))
  2934.            Destroy_Vector((VECTOR *)Constant_Ptr->Constant_Data);
  2935.          Constant_Ptr -> Constant_Type = VECTOR_CONSTANT;
  2936.          Constant_Ptr -> Constant_Data = (char *) Create_Vector();
  2937.          *((VECTOR *)Constant_Ptr -> Constant_Data) = Local_Vector;
  2938.         }
  2939.       else
  2940.         {
  2941.          if (Test_Redefine(FLOAT_ID_TOKEN))
  2942.            Destroy_Float((DBL *)Constant_Ptr->Constant_Data);
  2943.          Constant_Ptr -> Constant_Type = FLOAT_CONSTANT;
  2944.          Constant_Ptr -> Constant_Data = (char *) Create_Float();
  2945.          *((DBL *) Constant_Ptr -> Constant_Data) = Local_Vector.x;
  2946.         }
  2947.       EXIT
  2948.     END_CASE
  2949.  
  2950.     CASE (PIGMENT_TOKEN)
  2951.       if (Test_Redefine(PIGMENT_ID_TOKEN))
  2952.         Destroy_Pigment((PIGMENT *)Constant_Ptr->Constant_Data);
  2953.       Local_Pigment = Copy_Pigment((Default_Texture->Pigment));
  2954.       Parse_Pigment (&Local_Pigment);
  2955.       Constant_Ptr -> Constant_Type = PIGMENT_CONSTANT;
  2956.       Constant_Ptr -> Constant_Data = (char *)Local_Pigment;
  2957.       EXIT
  2958.     END_CASE
  2959.  
  2960.     CASE (TNORMAL_TOKEN)
  2961.       if (Test_Redefine(TNORMAL_ID_TOKEN))
  2962.         Destroy_Tnormal((TNORMAL *)Constant_Ptr->Constant_Data);
  2963.       Local_Tnormal = Copy_Tnormal((Default_Texture->Tnormal));
  2964.       Parse_Tnormal (&Local_Tnormal);
  2965.       Constant_Ptr -> Constant_Type = TNORMAL_CONSTANT;
  2966.       Constant_Ptr -> Constant_Data = (char *) Local_Tnormal;
  2967.       EXIT
  2968.     END_CASE
  2969.  
  2970.     CASE (FINISH_TOKEN)
  2971.       if (Test_Redefine(FINISH_ID_TOKEN))
  2972.         Destroy_Finish((FINISH *)Constant_Ptr->Constant_Data);
  2973.       Local_Finish = Copy_Finish((Default_Texture->Finish));
  2974.       Parse_Finish (&Local_Finish);
  2975.       Constant_Ptr -> Constant_Type = FINISH_CONSTANT;
  2976.       Constant_Ptr -> Constant_Data = (char *) Local_Finish;
  2977.       EXIT
  2978.     END_CASE
  2979.  
  2980.     CASE (CAMERA_TOKEN)
  2981.       if (Test_Redefine(CAMERA_ID_TOKEN))
  2982.         Destroy_Camera((CAMERA *)Constant_Ptr->Constant_Data);
  2983.       Local_Camera = Copy_Camera(Default_Camera);
  2984.       Parse_Camera (&Local_Camera);
  2985.       Constant_Ptr -> Constant_Type = CAMERA_CONSTANT;
  2986.       Constant_Ptr -> Constant_Data = (char *) Local_Camera;
  2987.       EXIT
  2988.     END_CASE
  2989.  
  2990.     CASE (TEXTURE_TOKEN)
  2991.       if (Test_Redefine(TEXTURE_ID_TOKEN))
  2992.         Destroy_Textures((TEXTURE *)Constant_Ptr->Constant_Data);
  2993.       Local_Texture = Parse_Texture ();
  2994.       Constant_Ptr -> Constant_Type = TEXTURE_CONSTANT;
  2995.       Constant_Ptr -> Constant_Data = NULL;
  2996.       Link_Textures((TEXTURE **) &Constant_Ptr->Constant_Data, Local_Texture);
  2997.       EXPECT
  2998.         CASE (TEXTURE_TOKEN)
  2999.           Local_Texture = Parse_Texture ();
  3000.           Link_Textures((TEXTURE **) &Constant_Ptr->Constant_Data, Local_Texture);
  3001.         END_CASE
  3002.  
  3003.         OTHERWISE
  3004.           UNGET
  3005.           EXIT
  3006.         END_CASE
  3007.       END_EXPECT
  3008.       EXIT
  3009.     END_CASE
  3010.  
  3011.     CASE (COLOUR_MAP_TOKEN)
  3012.       if (Test_Redefine(COLOUR_MAP_ID_TOKEN))
  3013.         Destroy_Colour_Map((COLOUR_MAP *)Constant_Ptr->Constant_Data);
  3014.       Local_Colour_Map = Parse_Colour_Map ();
  3015.       Constant_Ptr -> Constant_Type = COLOUR_MAP_CONSTANT;
  3016.       Constant_Ptr -> Constant_Data = (char *) Local_Colour_Map;
  3017.       EXIT
  3018.     END_CASE
  3019.  
  3020.     CASE (TRANSFORM_TOKEN)
  3021.       if (Test_Redefine(TRANSFORM_ID_TOKEN))
  3022.         Destroy_Transform((TRANSFORM *)Constant_Ptr->Constant_Data);
  3023.       Local_Trans = Parse_Transform ();
  3024.       Constant_Ptr -> Constant_Type = TRANSFORM_CONSTANT;
  3025.       Constant_Ptr -> Constant_Data = (char *) Local_Trans;
  3026.       EXIT
  3027.     END_CASE
  3028.  
  3029.     OTHERWISE
  3030.       UNGET
  3031.       if (Test_Redefine(OBJECT_ID_TOKEN))
  3032.         Destroy_Object((OBJECT *)Constant_Ptr->Constant_Data);
  3033.       Local_Object = Parse_Object ();
  3034.       Constant_Ptr -> Constant_Type = OBJECT_CONSTANT;
  3035.       Constant_Ptr -> Constant_Data = (char *) Local_Object;
  3036.       EXIT
  3037.     END_CASE
  3038.  
  3039.   END_EXPECT
  3040.   }
  3041.  
  3042. static void Link (New_Object, Field, Old_Object_List)
  3043.   OBJECT *New_Object, **Field, **Old_Object_List;
  3044.   {
  3045.   *Field = *Old_Object_List;
  3046.   *Old_Object_List = New_Object;
  3047.   }
  3048.  
  3049. static void Link_Textures (Old_Textures, New_Textures)
  3050.   TEXTURE **Old_Textures;
  3051.   TEXTURE  *New_Textures;
  3052.   {
  3053.    TEXTURE *Layer;
  3054.  
  3055.    for (Layer = New_Textures ;
  3056.         Layer->Next_Layer != NULL ;
  3057.         Layer = Layer->Next_Layer)
  3058.      {}
  3059.         Layer->Next_Layer = *Old_Textures;
  3060.         *Old_Textures = New_Textures;
  3061.   }
  3062.  
  3063. static
  3064. char *Get_Token_String (Token_Id)
  3065.   TOKEN Token_Id;
  3066.   {
  3067.   register int i;
  3068.  
  3069.   for (i = 0 ; i < LAST_TOKEN ; i++)
  3070.      if (Reserved_Words[i].Token_Number == Token_Id)
  3071.         return (Reserved_Words[i].Token_Name);
  3072.   return ("");
  3073.   }
  3074.  
  3075. static
  3076. void Where_Error ()
  3077.   {
  3078.   fprintf (stderr, "\nError in file %s line %d\n", Token.Filename,
  3079.                                                  Token.Token_Line_No+1);
  3080.   }
  3081.  
  3082. static int Test_Redefine(a)
  3083.   int a;
  3084.   {
  3085.   char *old, *new;
  3086.  
  3087.   if (Previous == IDENTIFIER_TOKEN)
  3088.     return (FALSE);
  3089.   if (Previous != a)
  3090.     {old = Get_Token_String (Previous);
  3091.      new = Get_Token_String (a);
  3092.      Where_Error ();
  3093.      fprintf (stderr, "Attempted to redefine %s as %s", old, new);
  3094.      exit (1);
  3095.     }
  3096.   return (TRUE);
  3097.   }
  3098.  
  3099. void Parse_Error (Token_Id)
  3100.   TOKEN Token_Id;
  3101.   {
  3102.   char *expected;
  3103.  
  3104.   expected = Get_Token_String (Token_Id);
  3105.   Parse_Error_Str(expected);
  3106.   }
  3107.  
  3108. void Parse_Error_Str (str)
  3109.   char *str;
  3110.   {
  3111.    Where_Error ();
  3112.    fprintf (stderr, "%s expected but", str);
  3113.    Found_Instead ();
  3114.    exit (1);
  3115.   }
  3116.  
  3117. static void Found_Instead ()
  3118.   {
  3119.   char *found;
  3120.  
  3121.   if (Token.Token_Id == IDENTIFIER_TOKEN)
  3122.     fprintf (stderr,
  3123.       " undeclared identifier '%s' found instead.\n", Token.Token_String);
  3124.   else
  3125.    {
  3126.     found = Get_Token_String (Token.Token_Id);
  3127.     fprintf (stderr, " %s found instead.\n", found);
  3128.    }
  3129.   }
  3130. /*
  3131. static void Parse_Warn (Token_Id)
  3132.   TOKEN Token_Id;
  3133.   {
  3134.   char *expected;
  3135.  
  3136.   fprintf (stderr, "\nWarning in file %s line %d\n", Token.Filename,
  3137.                                                    Token.Token_Line_No+1);
  3138.   expected = Get_Token_String (Token_Id);
  3139.   fprintf (stderr, "%s expected but", expected);
  3140.   Found_Instead ();
  3141.   }
  3142. */
  3143. static void Warn_State (Token_Id,Type)
  3144.   TOKEN Token_Id, Type;
  3145.   {
  3146.   char *found;
  3147.   char *should;
  3148.  
  3149.   if (Language_Version < 1.5)
  3150.      return;
  3151.  
  3152.   fprintf (stderr, "\nWarning in file %s line %d\n", Token.Filename,
  3153.                                                    Token.Token_Line_No+1);
  3154.   found = Get_Token_String (Token_Id);
  3155.   should = Get_Token_String (Type);
  3156.   fprintf (stderr, "Found %s that should be in %s statement", found, should);
  3157.   }
  3158.  
  3159. void Warn (str,Level)
  3160.   char *str;
  3161.   DBL Level;
  3162.   {
  3163.   if (Language_Version < Level)
  3164.     return;
  3165.     
  3166.   fprintf (stdout, "\nWarning in file %s line %d\n", Token.Filename,
  3167.                                                    Token.Token_Line_No+1);
  3168.   fputs (str, stdout);
  3169.   }
  3170.  
  3171. void Error (str)
  3172.   char *str;
  3173.   {
  3174.   Where_Error ();
  3175.   fputs (str, stderr);
  3176.   exit (1);
  3177.   }
  3178.  
  3179. void MAError (str)
  3180.   char *str;
  3181.   {
  3182.   Where_Error ();
  3183.   fprintf (stderr, "Out of memory.  Cannot allocate %s.\n",str);
  3184.   exit (1);
  3185.   }
  3186.  
  3187. /* Write a token out to the token file */
  3188.  
  3189. void Write_Token (Token_Id, Data_File)
  3190.   TOKEN Token_Id;
  3191.   DATA_FILE *Data_File;
  3192.  
  3193.   {
  3194.    Token.Token_Id = Token_Id;
  3195.    Token.Token_Line_No = Data_File->Line_Number;
  3196.    Token.Filename = Data_File->Filename;
  3197.    Token.Token_String = String;
  3198.    Token.Constant_Data = NULL;
  3199.    Token.Constant_Index = (int) Token.Token_Id - (int) LAST_TOKEN;
  3200.  
  3201.    if (Token.Constant_Index >= 0)
  3202.      {if (Token.Constant_Index <= Number_Of_Constants)
  3203.         {Token.Constant_Data = Constants[Token.Constant_Index].Constant_Data;
  3204.          switch (Constants[Token.Constant_Index].Constant_Type)
  3205.            {CASEID(COLOUR_CONSTANT,     COLOUR_ID_TOKEN)
  3206.             CASEID(VECTOR_CONSTANT,     VECTOR_ID_TOKEN)
  3207.             CASEID(FLOAT_CONSTANT,      FLOAT_ID_TOKEN)
  3208.             CASEID(PIGMENT_CONSTANT,    PIGMENT_ID_TOKEN)
  3209.             CASEID(TNORMAL_CONSTANT,    TNORMAL_ID_TOKEN)
  3210.             CASEID(FINISH_CONSTANT,     FINISH_ID_TOKEN)
  3211.             CASEID(TEXTURE_CONSTANT,    TEXTURE_ID_TOKEN)
  3212.             CASEID(OBJECT_CONSTANT,     OBJECT_ID_TOKEN)
  3213.             CASEID(COLOUR_MAP_CONSTANT, COLOUR_MAP_ID_TOKEN)
  3214.             CASEID(TRANSFORM_CONSTANT,  TRANSFORM_ID_TOKEN)
  3215.             CASEID(CAMERA_CONSTANT,     CAMERA_ID_TOKEN)
  3216.            }
  3217.         }
  3218.       else Token.Token_Id = IDENTIFIER_TOKEN;
  3219.      }
  3220.   }
  3221.  
  3222. static void Post_Process (Object,Parent)
  3223.   OBJECT *Object, *Parent;
  3224.   {
  3225.    OBJECT *Sib;
  3226.  
  3227.    if (Object == NULL)
  3228.      return;
  3229.  
  3230.    if (Parent != NULL)
  3231.      {
  3232.       if (Object->Texture == NULL)
  3233.         Object->Texture = Parent->Texture;
  3234. /*
  3235.       else
  3236.         if (Parent->Texture != NULL)
  3237.           {Local_Texture = Copy_Textures (Parent->Texture);
  3238.            Link_Textures (&(Object->Texture), Local_Texture);
  3239.           }
  3240. */ /* Removed for backward compat with 1.0.  May put back in. CEY 12/92 */
  3241.       Object->No_Shadow_Flag |= Parent->No_Shadow_Flag;
  3242.      }
  3243.      
  3244.    if (     (Object->Texture == NULL) 
  3245.         && !(Object->Type & TEXTURED_OBJECT) 
  3246.         && !(Object->Type & LIGHT_SOURCE_OBJECT))
  3247.      Object->Texture = Copy_Textures(Default_Texture);
  3248.  
  3249.    if (Object->Type & COMPOUND_OBJECT)
  3250.      {
  3251.       if (Object->Type & LIGHT_SOURCE_OBJECT)
  3252.         {
  3253.          ((LIGHT_SOURCE *)Object)->Next_Light_Source = Frame.Light_Sources;
  3254.          Frame.Light_Sources = (LIGHT_SOURCE *)Object;
  3255.         }
  3256.       for (Sib = ((CSG *)Object)->Children;
  3257.            Sib != NULL;
  3258.            Sib = Sib->Sibling)
  3259.         Post_Process(Sib, Object);
  3260.      }
  3261.    else
  3262.      {
  3263.       if (Object->Texture == NULL)
  3264.         Object->Texture = Copy_Textures(Default_Texture);
  3265.       if (Object->Texture->Type == PNF_TEXTURE) 
  3266.         if (Object->Texture->Tnormal != NULL)
  3267.           Object->Type |= DOUBLE_ILLUMINATE;
  3268.      }
  3269.    Post_Textures (Object->Texture);
  3270.    if ((Object->Type & WATER_LEVEL_OK_OBJECT) &&
  3271.        (Object->Type & IS_CHILD_OBJECT))
  3272.      Object->Methods = &Csg_Height_Field_Methods;
  3273.   }
  3274.  
  3275. static void Destroy_Constants ()
  3276.   {
  3277.    int i;
  3278.    char *Ptr;
  3279.  
  3280.    for (i=1; i <= Number_Of_Constants; i++)
  3281.      {
  3282.       Ptr = Constants[i].Constant_Data;
  3283.       switch (Constants[i].Constant_Type)
  3284.         {
  3285.          case COLOUR_CONSTANT:
  3286.            Destroy_Colour((COLOUR *)Ptr);
  3287.            break;
  3288.          case VECTOR_CONSTANT:
  3289.            Destroy_Vector((VECTOR *)Ptr);
  3290.            break;
  3291.          case FLOAT_CONSTANT:
  3292.            Destroy_Float((DBL *)Ptr);
  3293.            break;
  3294.          case PIGMENT_CONSTANT:
  3295.            Destroy_Pigment((PIGMENT *)Ptr);
  3296.            break;
  3297.          case TNORMAL_CONSTANT:
  3298.            Destroy_Tnormal((TNORMAL *)Ptr);
  3299.            break;
  3300.          case FINISH_CONSTANT:
  3301.            Destroy_Finish((FINISH *)Ptr);
  3302.            break;
  3303.          case TEXTURE_CONSTANT:
  3304.            Destroy_Textures((TEXTURE *)Ptr);
  3305.            break;
  3306.          case OBJECT_CONSTANT:
  3307.            Destroy_Object((OBJECT *)Ptr);
  3308.            break;
  3309.          case COLOUR_MAP_CONSTANT:
  3310.            Destroy_Colour_Map((COLOUR_MAP *)Ptr);
  3311.            break;
  3312.          case TRANSFORM_CONSTANT:
  3313.            Destroy_Transform((TRANSFORM *)Ptr);
  3314.            break;
  3315.          case CAMERA_CONSTANT:
  3316.            Destroy_Camera((CAMERA *)Ptr);
  3317.            break;
  3318.         }
  3319.      }
  3320.   }
  3321.  
  3322. static void Link_To_Frame (Object)
  3323.  OBJECT *Object;
  3324.  {
  3325.   OBJECT *This_Sib, *Next_Sib;
  3326.   
  3327.   if ((Object->Methods != &CSG_Union_Methods) ||
  3328.       (Object->Bound != NULL) ||
  3329.       (Object->Clip != NULL) ||
  3330.       (!Use_Slabs))
  3331.     {
  3332.      Link(Object, &(Object -> Sibling), &(Frame.Objects));
  3333.      return;
  3334.     }
  3335.   
  3336.   for (This_Sib = ((CSG *)Object)->Children;
  3337.        This_Sib != NULL;
  3338.        This_Sib = Next_Sib)
  3339.        {
  3340.         Next_Sib = This_Sib->Sibling; /*L2F changes Sibling so save it */
  3341.         Link_To_Frame (This_Sib);
  3342.        }
  3343.   Object->Texture = NULL;
  3344.   Object->Sibling = NULL;
  3345.   ((CSG *)Object)->Children = NULL;
  3346.   Destroy_Object (Object);
  3347.  }
  3348.