home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Graphics / Graphics.zip / pov22f.zip / source / povray.c < prev    next >
C/C++ Source or Header  |  1994-02-03  |  33KB  |  1,055 lines

  1. /****************************************************************************
  2. *                povray.c
  3. *
  4. *  This module contains the entry routine for the raytracer and the code to
  5. *  parse the parameters on the command line.
  6. *
  7. *  from Persistence of Vision Raytracer
  8. *  Copyright 1993 Persistence of Vision Team
  9. *---------------------------------------------------------------------------
  10. *  NOTICE: This source code file is provided so that users may experiment
  11. *  with enhancements to POV-Ray and to port the software to platforms other 
  12. *  than those supported by the POV-Ray Team.  There are strict rules under
  13. *  which you are permitted to use this file.  The rules are in the file
  14. *  named POVLEGAL.DOC which should be distributed with this file. If 
  15. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  16. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  17. *  Forum.  The latest version of POV-Ray may be found there as well.
  18. *
  19. * This program is based on the popular DKB raytracer version 2.12.
  20. * DKBTrace was originally written by David K. Buck.
  21. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  22. *
  23. *****************************************************************************/
  24.  
  25. #include <ctype.h>
  26. #include <time.h>          /* BP */
  27. #include "frame.h"        /* common to ALL modules in this program */
  28. #include "povproto.h"
  29.  
  30. #define MAX_FILE_NAMES 1
  31. unsigned int Options;
  32. unsigned long Quality_Flags;
  33. int Quality,Use_Slabs;
  34. int Case_Sensitive_Flag = CASE_SENSITIVE_DEFAULT;
  35.  
  36. extern FRAME Frame;
  37. OBJECT *Root_Object;
  38.  
  39. char Input_File_Name[FILE_NAME_LENGTH], Output_File_Name[FILE_NAME_LENGTH], Stat_File_Name[FILE_NAME_LENGTH];
  40.  
  41. #define MAX_LIBRARIES 10
  42. char *Library_Paths[MAX_LIBRARIES];
  43. int Library_Path_Index;
  44. int Max_Symbols = 1000;
  45.  
  46. FILE_HANDLE *Output_File_Handle;
  47. int File_Buffer_Size;
  48. static int Number_Of_Files;
  49. static int inflag, outflag; 
  50. DBL VTemp;
  51. DBL Antialias_Threshold;
  52. int First_Line, Last_Line;
  53. int First_Column, Last_Column;
  54. DBL First_Column_Temp, Last_Column_Temp;
  55. DBL First_Line_Temp, Last_Line_Temp;
  56. int Display_Started = FALSE;
  57. int Shadow_Test_Flag = FALSE;
  58. DBL Clock_Value = 0.0;
  59. DBL Language_Version = 2.0;
  60. long Bounds_Threshold = 25;
  61. long AntialiasDepth = 3;
  62. DBL JitterScale = 1.0;
  63.  
  64. /* Quality constants */
  65.   long Quality_Values[10]=
  66.     {
  67.     QUALITY_0, QUALITY_1, QUALITY_2, QUALITY_3, QUALITY_4,
  68.     QUALITY_5, QUALITY_6, QUALITY_7, QUALITY_8, QUALITY_9
  69.     };
  70. /* Stats kept by the ray tracer: */
  71. long Number_Of_Pixels, Number_Of_Rays, Number_Of_Pixels_Supersampled;
  72. long Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded;
  73. long Ray_Box_Tests, Ray_Box_Tests_Succeeded;    
  74. long Ray_Blob_Tests, Ray_Blob_Tests_Succeeded;  
  75. long Ray_Cone_Tests, Ray_Cone_Tests_Succeeded;
  76. long Ray_Disc_Tests, Ray_Disc_Tests_Succeeded;
  77. long Ray_Plane_Tests, Ray_Plane_Tests_Succeeded;
  78. long Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded;
  79. long Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded;
  80. long Ray_Poly_Tests, Ray_Poly_Tests_Succeeded;
  81. long Ray_Bicubic_Tests, Ray_Bicubic_Tests_Succeeded;
  82. long Ray_Ht_Field_Tests, Ray_Ht_Field_Tests_Succeeded;
  83. long Ray_Ht_Field_Box_Tests, Ray_HField_Box_Tests_Succeeded;
  84. long Bounding_Region_Tests, Bounding_Region_Tests_Succeeded;
  85. long Clipping_Region_Tests, Clipping_Region_Tests_Succeeded;
  86. long Calls_To_Noise, Calls_To_DNoise;
  87. /* SJA */
  88. long Shadow_Ray_Tests, Shadow_Rays_Succeeded, Shadow_Cache_Hits;
  89. /* SJA */
  90. long Reflected_Rays_Traced, Refracted_Rays_Traced;
  91. long Transmitted_Rays_Traced;
  92. long Istack_overflows;
  93. int Number_of_istacks;
  94. int Max_Intersections;
  95. ISTACK *free_istack;
  96.  
  97. DBL    tused;             /* Trace timer variables. - BP */ 
  98. time_t tstart, tstop;
  99.  
  100. char DisplayFormat, OutputFormat, VerboseFormat, PaletteOption, Color_Bits;
  101.  
  102. struct Constant_Struct Constants[MAX_CONSTANTS];
  103.  
  104. #ifdef NOCMDLINE    /* a main() by any other name... */
  105. #ifdef ALTMAIN
  106.   MAIN_RETURN_TYPE alt_main()
  107. #else
  108.   MAIN_RETURN_TYPE main()
  109. #endif
  110. #else
  111. #ifdef ALTMAIN
  112.   MAIN_RETURN_TYPE alt_main(argc, argv)
  113. #else
  114.   MAIN_RETURN_TYPE main(argc, argv)
  115. #endif
  116.     int argc;
  117. char **argv;
  118. #endif            /* ...would be a lot less hassle!! :-) AAC */
  119.   {
  120.   register int i;
  121.   FILE *stat_file;
  122.  
  123.   STARTUP_POVRAY
  124.  
  125.   PRINT_CREDITS
  126.  
  127.   PRINT_OTHER_CREDITS
  128.  
  129.   /* Parse the command line parameters */
  130. #ifndef NOCMDLINE
  131.   if (argc == 1)
  132.     usage();
  133. #endif
  134.  
  135.   init_vars();
  136.  
  137.   Output_File_Name[0]='\0';
  138.  
  139.   Library_Paths[0] = NULL;
  140.   Library_Path_Index = 0;
  141.  
  142.   /* Read the default parameters from povray.def */
  143.   get_defaults();
  144.  
  145. #ifndef NOCMDLINE
  146.   for (i = 1 ; i < argc ; i++ )
  147.     if ((*argv[i] == '+') || (*argv[i] == '-'))
  148.       parse_option(argv[i]);
  149.     else
  150.       parse_file_name(argv[i]);
  151.  
  152. #endif
  153.  
  154.   if (Last_Line == -1)
  155.     Last_Line = Frame.Screen_Height;
  156.  
  157.   if (Last_Column == -1)
  158.     Last_Column = Frame.Screen_Width;
  159.  
  160.   if (Options & DISKWRITE) 
  161.     {
  162.     switch (OutputFormat) 
  163.     {
  164.     case '\0':
  165.     case 'd':
  166.     case 'D':
  167.       if ((Output_File_Handle = Get_Dump_File_Handle()) == NULL) 
  168.         {
  169.         close_all();
  170.         exit(1);
  171.         }
  172.       break;
  173.       /*
  174.          case 'i':
  175.          case 'I':
  176.                    if ((Output_File_Handle = Get_Iff_File_Handle()) == NULL) {
  177.                       close_all();
  178.                       exit(1);
  179.                       }
  180.                    break;
  181.  
  182. */
  183.     case 'r':
  184.     case 'R':
  185.       if ((Output_File_Handle = Get_Raw_File_Handle()) == NULL) 
  186.         {
  187.         close_all();
  188.         exit(1);
  189.         }
  190.       break;
  191.  
  192.     case 't':
  193.     case 'T':
  194.       if ((Output_File_Handle = Get_Targa_File_Handle()) == NULL) 
  195.         {
  196.         close_all();
  197.         exit(1);
  198.         }
  199.       break;
  200.  
  201.     default:
  202.       fprintf (stderr, "Unrecognized output file format %c\n", OutputFormat);
  203.       close_all(); 
  204.       exit(1);
  205.     }
  206.     if (Output_File_Name[0] == '\0')
  207.       strcpy (Output_File_Name, Default_File_Name (Output_File_Handle));
  208.     }
  209.  
  210.   Print_Options();
  211.  
  212.   Initialize_Tokenizer(Input_File_Name);
  213.   fprintf (stderr,"Parsing...");
  214.  
  215.  
  216.   if (Options & VERBOSE_FILE)
  217.     {
  218.     stat_file = fopen(Stat_File_Name,"w+t");
  219.     fprintf (stat_file, "Parsing...\n");
  220.     fclose(stat_file);
  221.     }
  222.  
  223.   Parse ();
  224.   Terminate_Tokenizer();
  225.  
  226.   if (Use_Slabs) 
  227.     {
  228.     fprintf (stderr, "Preprocessing...\n");  /* Added */
  229.     BuildBoundingSlabs(&Root_Object);        /* Added */
  230.     }
  231.  
  232.   if (Options & DISPLAY)
  233.     {
  234.     printf ("Displaying...\n");
  235.     display_init(Frame.Screen_Width, Frame.Screen_Height);
  236.     Display_Started = TRUE;
  237.     }
  238.  
  239.   /* Get things ready for ray tracing */
  240.   if (Options & DISKWRITE)
  241.     if (Options & CONTINUE_TRACE) 
  242.     {
  243.     if (Open_File (Output_File_Handle, Output_File_Name,
  244.       &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  245.       READ_MODE) != 1) 
  246.       {
  247.       fprintf (stderr, "Error opening continue trace output file\n");
  248.       fprintf (stderr, "Opening new output file %s.\n",Output_File_Name);
  249.       Options &= ~CONTINUE_TRACE; /* Turn off continue trace */
  250.  
  251.       if (Open_File (Output_File_Handle, Output_File_Name,
  252.         &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  253.         WRITE_MODE) != 1) 
  254.         {
  255.         fprintf (stderr, "Error opening output file\n");
  256.         close_all();
  257.         exit(1);
  258.         }
  259.       }
  260.  
  261.     Initialize_Renderer();
  262.     if (Options & CONTINUE_TRACE) 
  263.       Read_Rendered_Part();
  264.     }
  265.     else 
  266.     {
  267.     if (Open_File (Output_File_Handle, Output_File_Name,
  268.       &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  269.       WRITE_MODE) != 1) 
  270.       {
  271.       fprintf (stderr, "Error opening output file\n");
  272.       close_all();
  273.       exit(1);
  274.       }
  275.  
  276.     Initialize_Renderer();
  277.     }
  278.   else
  279.     Initialize_Renderer();
  280.  
  281.   Initialize_Noise();
  282.  
  283.   START_TIME  /* Store start time for trace. Timer macro in CONFIG.H */
  284.  
  285.  
  286.   /* Ok, go for it - trace the picture */
  287.   if ((Options & VERBOSE) && (VerboseFormat !='1'))
  288.     printf ("Rendering...\n");
  289.   else if ((Options & VERBOSE) && (VerboseFormat=='1'))
  290.     fprintf (stderr,"POV-Ray rendering %s to %s :\n",Input_File_Name,Output_File_Name);
  291.   if (Options & VERBOSE_FILE)
  292.     {
  293.     stat_file = fopen(Stat_File_Name,"w+t");
  294.     fprintf (stat_file,"Parsed ok. Now rendering %s to %s :\n",Input_File_Name,Output_File_Name);
  295.     fclose(stat_file);
  296.     }
  297.   CONFIG_MATH               /* Macro for setting up any special FP options */
  298.   Start_Tracing ();
  299.  
  300.   if (Options & VERBOSE && VerboseFormat=='1')
  301.     fprintf (stderr,"\n");
  302.  
  303.   /* Record the time so well spent... */
  304.   STOP_TIME                  /* Get trace done time. */
  305.   tused = TIME_ELAPSED       /* Calc. elapsed time. Define TIME_ELAPSED as */
  306.   /* 0 in your specific CONFIG.H if unsupported */
  307.  
  308.   /* Clean up and leave */
  309.   display_finished();
  310.  
  311.   close_all ();
  312.  
  313.   PRINT_STATS
  314.  
  315.   if (Options & VERBOSE_FILE)
  316.     {
  317.     stat_file = fopen(Stat_File_Name,"a+t");
  318.     fprintf (stat_file,"Done Tracing\n");
  319.     fclose(stat_file);
  320.     }
  321.  
  322.   FINISH_POVRAY
  323.   }
  324.  
  325. /* Print out usage error message */
  326.  
  327. void usage ()
  328.   {
  329.   fprintf (stdout,"\nUsage: POVRAY  [+/-] Option1 [+/-] Option2 ...");
  330.   fprintf (stdout,"\n  Example: +L\\povray\\include +Iscene.pov +Oscene.tga +W320 +H200");
  331.   fprintf (stdout,"\n  Example: +Iscene.pov +Oscene.tga +W160 +H200 +V -D +X ");
  332.   fprintf (stdout,"\n");
  333.   fprintf (stdout,"\n[ Paused for keypress... ]\n");
  334.   WAIT_FOR_KEYPRESS;
  335.   fprintf (stdout,"\n\n\n\n\n Options:");
  336.   fprintf (stdout,"\n    Dxy = display in format x, using palette option y");
  337.   fprintf (stdout,"\n    V   = verbose messages on");
  338.   fprintf (stdout,"\n    P  = pause before exit");
  339.   fprintf (stdout,"\n    X  = enable early exit by key hit");
  340.   fprintf (stdout,"\n    Fx = write output file in format x");
  341.   fprintf (stdout,"\n         FT - Uncompressed Targa-24  |  FD - DKB/QRT Dump  | FR - RGB Raw Files");
  342.   fprintf (stdout,"\n    C  = continue aborted trace");
  343.   fprintf (stdout,"\n    Qx = image quality 0=rough, 9=full");
  344.   fprintf (stdout,"\n    A0.x = perform antialiasing");
  345.   fprintf (stdout,"\n    Bxxx = Use xxx KB for output file buffer");
  346.   fprintf (stdout,"\n    Jx.x = set aa-jitter amount");
  347.   fprintf (stdout,"\n    Kx.x = set frame clocK to x.x");
  348.   fprintf (stdout,"\n    MBxxx = use slabs if more than xxx objects");
  349.   fprintf (stdout,"\n    MSxxx = set max symbol table size to xxx");
  350.   fprintf (stdout,"\n    MVx.x = set compability to version x.x");
  351.   fprintf (stdout,"\n    Rn   = set aa-depth (use n X n rays/pixel)");
  352.   fprintf (stdout,"\n    SRxx = start at row xxx         |  SR0.xx start row at x%% of screen");
  353.   fprintf (stdout,"\n    ERxx = end   at row xxx         |  ER0.xx end   row at x%% of screen");
  354.   fprintf (stdout,"\n    SCxx = start at col xxx         |  SC0.xx start col at x%% of screen");
  355.   fprintf (stdout,"\n    ECxx = end   at col xxx         |  EC0.xx end   col at x%% of screen");
  356.   fprintf (stdout,"\n    I<filename> = input file name   |  O<filename> = output file name");
  357.   fprintf (stdout,"\n    L<pathname> = library path prefix");
  358.   fprintf (stdout,"\n");
  359.   exit(1);
  360.   }
  361. void init_vars()
  362.   {
  363.   Output_File_Handle = NULL;
  364.   File_Buffer_Size = 0;
  365.   Options = JITTER;
  366.   Quality_Flags = QUALITY_9;
  367.   Quality = 9;
  368.   Use_Slabs=TRUE;
  369.   Number_Of_Files = 0;
  370.   Frame.Screen_Height = 100;
  371.   Frame.Screen_Width = 100;
  372.   First_Line = 0;
  373.   Last_Line = -1;
  374.   First_Column = 0;
  375.   Last_Column = -1;
  376.  
  377.   First_Line_Temp = (DBL) First_Line+1;
  378.   Last_Line_Temp = (DBL) Last_Line;
  379.   First_Column_Temp = (DBL) First_Column+1;
  380.   Last_Column_Temp = (DBL) Last_Column;
  381.  
  382.   Color_Bits = 8;
  383.  
  384.   Number_Of_Pixels = 0L;
  385.   Number_Of_Rays = 0L;
  386.   Number_Of_Pixels_Supersampled = 0L;
  387.   Ray_Ht_Field_Tests = 0L;
  388.   Ray_Ht_Field_Tests_Succeeded = 0L;
  389.   Ray_Ht_Field_Box_Tests = 0L;
  390.   Ray_HField_Box_Tests_Succeeded = 0L;
  391.   Ray_Bicubic_Tests = 0L;
  392.   Ray_Bicubic_Tests_Succeeded = 0L;
  393.   Ray_Blob_Tests = 0L;
  394.   Ray_Blob_Tests_Succeeded = 0L;
  395.   Ray_Box_Tests = 0L;
  396.   Ray_Box_Tests_Succeeded = 0L;
  397.   Ray_Disc_Tests = 0L;
  398.   Ray_Disc_Tests_Succeeded = 0L;
  399.   Ray_Cone_Tests = 0L;
  400.   Ray_Cone_Tests_Succeeded = 0L;
  401.   Ray_Sphere_Tests = 0L;
  402.   Ray_Sphere_Tests_Succeeded = 0L;
  403.   Ray_Plane_Tests = 0L;
  404.   Ray_Plane_Tests_Succeeded = 0L;
  405.   Ray_Triangle_Tests = 0L;
  406.   Ray_Triangle_Tests_Succeeded = 0L;
  407.   Ray_Quadric_Tests = 0L;
  408.   Ray_Quadric_Tests_Succeeded = 0L;
  409.   Ray_Poly_Tests = 0L;
  410.   Ray_Poly_Tests_Succeeded = 0L;
  411.   Bounding_Region_Tests = 0L;
  412.   Bounding_Region_Tests_Succeeded = 0L;
  413.   Clipping_Region_Tests = 0L;
  414.   Clipping_Region_Tests_Succeeded = 0L;
  415.   Calls_To_Noise = 0L;
  416.   Calls_To_DNoise = 0L;
  417.   Shadow_Ray_Tests = 0L;
  418.   /* SJA */
  419.   Shadow_Cache_Hits = 0L;
  420.   /* SJA */
  421.   Shadow_Rays_Succeeded = 0L;
  422.   Reflected_Rays_Traced = 0L;
  423.   Refracted_Rays_Traced = 0L;
  424.   Transmitted_Rays_Traced = 0L;
  425.   Istack_overflows = 0L;
  426.   Number_of_istacks = 0;
  427.   free_istack = NULL;
  428.   Max_Intersections = 64; /*128*/
  429.   Antialias_Threshold = 0.3;
  430.   strcpy (Input_File_Name, "object.pov");
  431.   return;
  432.   }
  433.  
  434. /* Close all the stuff that has been opened. */
  435. void close_all ()
  436.   {
  437.   if ((Options & DISPLAY) && Display_Started)
  438.     display_close();
  439.  
  440.   if (Output_File_Handle)
  441.     Close_File (Output_File_Handle);
  442.   }
  443.  
  444. /* Read the default parameters from povray.def */
  445. void get_defaults()
  446.   {
  447.   FILE *defaults_file;
  448.   char Option_String[256], *Option_String_Ptr;
  449.   /* READ_ENV_VAR_? should be defined in config.h */
  450.   /* Only one READ_ENV_VAR_? should ever be defined. */
  451.   /* This allows some machines to read environment variable before */
  452.   /* reading povray.def and others to do it after depending on the */
  453.   /* operating system. IBM-PC is before. Default is after if not */
  454.   /* defined in config.h. CDW 2/92 */
  455.   /* Set Diskwrite as default */
  456.   Options |= DISKWRITE;
  457.   OutputFormat = DEFAULT_OUTPUT_FORMAT;
  458.  
  459.   READ_ENV_VAR_BEFORE
  460.   if ((defaults_file = Locate_File("povray.def", "r")) != NULL) 
  461.     {
  462.     while (fgets(Option_String, 256, defaults_file) != NULL)
  463.       read_options(Option_String);
  464.     fclose (defaults_file);
  465.     }
  466.   READ_ENV_VAR_AFTER
  467.   }
  468.  
  469. void read_options (Option_Line)
  470. char *Option_Line;
  471.   {
  472.   register int c, String_Index, Option_Started;
  473.   short Option_Line_Index = 0;
  474.   char Option_String[80];
  475.  
  476.   String_Index = 0;
  477.   Option_Started = FALSE;
  478.   while ((c = Option_Line[Option_Line_Index++]) != '\0')
  479.     {
  480.     if (Option_Started)
  481.       if (isspace(c))
  482.         {
  483.         Option_String[String_Index] = '\0';
  484.         parse_option (Option_String);
  485.         Option_Started = FALSE;
  486.         String_Index = 0;
  487.         }
  488.       else
  489.         Option_String[String_Index++] = (char) c;
  490.  
  491.     else /* Option_Started */
  492.       if ((c == (int) '-') || (c == (int) '+'))
  493.         {
  494.         String_Index = 0;
  495.         Option_String[String_Index++] = (char) c;
  496.         Option_Started = TRUE;
  497.         }
  498.       else
  499.         if (!isspace(c))
  500.           {
  501.           fprintf (stderr, 
  502.             "\nCommand line or .DEF error. Bad character (%c), val: %d.\n", 
  503.             (char) c, c);
  504.           exit (1);
  505.           }
  506.     }
  507.  
  508.   if (Option_Started)
  509.     {
  510.     Option_String[String_Index] = '\0';
  511.     parse_option (Option_String);
  512.     }
  513.   }
  514.  
  515. /* parse the command line parameters */
  516. void parse_option (Option_String)
  517. char *Option_String;
  518.   {
  519.   register int Add_Option;
  520.   unsigned int Option_Number;
  521.   long bounds_thresh;
  522.   DBL threshold;
  523.  
  524.   inflag = outflag = FALSE;   /* if these flags aren't immediately used, reset them on next -/+ option! */
  525.   if (*(Option_String++) == '-')
  526.     Add_Option = FALSE;
  527.   else
  528.     Add_Option = TRUE;
  529.  
  530.   Option_Number = 0;
  531.  
  532.   switch (*Option_String)
  533.   {
  534.   case 'B':
  535.   case 'b':  
  536.     sscanf (&Option_String[1], "%d", &File_Buffer_Size);
  537.     File_Buffer_Size *= 1024;
  538.     if (File_Buffer_Size < BUFSIZ)   /* system default MIN */
  539.       File_Buffer_Size = BUFSIZ;
  540.     if (File_Buffer_Size > MAX_BUFSIZE)    /* unsigned short MAX */
  541.       File_Buffer_Size = MAX_BUFSIZE;
  542.     break;
  543.  
  544.   case 'C':
  545.   case 'c':  
  546.     Option_Number = CONTINUE_TRACE;
  547.     break;
  548.  
  549.   case 'D':
  550.   case 'd':  
  551.     Option_Number = DISPLAY;
  552.     DisplayFormat = '0';
  553.     PaletteOption = '3';
  554.     if (Option_String[1] != '\0')
  555.       DisplayFormat = (char)toupper(Option_String[1]);
  556.  
  557.     if (Option_String[1] != '\0' && Option_String[2] != '\0')
  558.       PaletteOption = (char)toupper(Option_String[2]);
  559.     break;
  560.  
  561.   case '@':  
  562.     Option_Number = VERBOSE_FILE;
  563.     if(Option_String[1] == '\0')
  564.       strcpy(Stat_File_Name, "POVSTAT.OUT");
  565.     else
  566.       strncpy (Stat_File_Name, &Option_String[1], FILE_NAME_LENGTH);
  567.     break;
  568.  
  569.   case 'V':
  570.   case 'v':  
  571.     Option_Number = VERBOSE;
  572.     VerboseFormat = (char)toupper(Option_String[1]);
  573.     if (VerboseFormat == '\0')
  574.       VerboseFormat = '1';
  575.     break;
  576.  
  577.   case 'W':
  578.   case 'w':  
  579.     sscanf (&Option_String[1], "%d", &Frame.Screen_Width);
  580.     break;
  581.  
  582.   case 'H':
  583.   case 'h':  
  584.     sscanf (&Option_String[1], "%d", &Frame.Screen_Height);
  585.     break;
  586.  
  587.   case 'F':
  588.   case 'f':  
  589.     Option_Number = DISKWRITE;
  590.     if (isupper(Option_String[1]))
  591.       OutputFormat = (char)tolower(Option_String[1]);
  592.     else
  593.       OutputFormat = Option_String[1];
  594.  
  595.     /* Default the output format to the default in the config file */
  596.     if (OutputFormat == '\0')
  597.       OutputFormat = DEFAULT_OUTPUT_FORMAT;
  598.     break;
  599.  
  600.   case 'P':
  601.   case 'p':  
  602.     Option_Number = PROMPTEXIT;
  603.     break;
  604.  
  605.   case 'I':
  606.   case 'i':  
  607.     if (Option_String[1] == '\0')
  608.       inflag = TRUE;
  609.     else 
  610.       strncpy (Input_File_Name, &Option_String[1], FILE_NAME_LENGTH);
  611.     break;
  612.  
  613.   case 'O':
  614.   case 'o':  
  615.     if (Option_String[1] == '\0')
  616.       outflag = TRUE;
  617.     else
  618.       strncpy (Output_File_Name, &Option_String[1], FILE_NAME_LENGTH);
  619.     break;
  620.  
  621.   case 'A':
  622.   case 'a':  
  623.     Option_Number = ANTIALIAS;
  624.     if (sscanf (&Option_String[1], DBL_FORMAT_STRING, &threshold) != EOF)
  625.       Antialias_Threshold = threshold;
  626.     break;
  627.  
  628.   case 'J':
  629.   case 'j':
  630.     Option_Number = JITTER;
  631.     if (sscanf (&Option_String[1], DBL_FORMAT_STRING, &threshold) != EOF)
  632.        JitterScale = threshold;
  633.     if (JitterScale<=0.0)
  634.        Add_Option = FALSE;
  635.     break; 
  636.  
  637.   case 'R':
  638.   case 'r':  
  639.     sscanf (&Option_String[1], "%ld", &AntialiasDepth);
  640.     if (AntialiasDepth < 1)
  641.       AntialiasDepth = 1;
  642.     if (AntialiasDepth > 9)
  643.       AntialiasDepth = 9;
  644.     break;
  645.  
  646.   case 'X':
  647.   case 'x':  
  648.     Option_Number = EXITENABLE;
  649.     break;
  650.  
  651.   case 'L':
  652.   case 'l':  
  653.     if (Library_Path_Index >= MAX_LIBRARIES) 
  654.       {
  655.       fprintf (stderr, "Too many library directories specified\n");
  656.       exit(1);
  657.       }
  658.     Library_Paths [Library_Path_Index] = malloc (strlen(Option_String));
  659.     if (Library_Paths [Library_Path_Index] == NULL) 
  660.       {
  661.       fprintf (stderr, "Out of memory. Cannot allocate memory for library pathname\n");
  662.       exit(1);
  663.       }
  664.     strcpy (Library_Paths [Library_Path_Index], &Option_String[1]);
  665.     Library_Path_Index++;
  666.     break;
  667.  
  668.   case 'T':
  669.   case 't':  
  670.     switch (toupper(Option_String[1]))
  671.     {
  672.     case 'Y':
  673.       Case_Sensitive_Flag = 0;
  674.       break;
  675.     case 'N':
  676.       Case_Sensitive_Flag = 1;
  677.       break;
  678.     case 'O':
  679.       Case_Sensitive_Flag = 2;
  680.       break;
  681.     default:
  682.       Case_Sensitive_Flag = 2;
  683.       break;
  684.     }  
  685.     break;
  686.  
  687.   case 'S':
  688.   case 's':  
  689.     switch (Option_String[1])
  690.     {
  691.     case 'c': 
  692.     case 'C':
  693.       sscanf (&Option_String[2], DBL_FORMAT_STRING, &First_Column_Temp);
  694.       break;
  695.  
  696.     case 'r': 
  697.     case 'R':
  698.       sscanf (&Option_String[2], DBL_FORMAT_STRING, &First_Line_Temp);
  699.       break;
  700.  
  701.     default:
  702.       sscanf (&Option_String[1], DBL_FORMAT_STRING, &First_Line_Temp);
  703.       break;
  704.     }
  705.  
  706.     if(First_Column_Temp > 0.0 && First_Column_Temp < 1.0)
  707.       First_Column = (int) (Frame.Screen_Width * First_Column_Temp);
  708.     else
  709.       First_Column = (int) First_Column_Temp-1;
  710.  
  711.     if(First_Line_Temp > 0.0 && First_Line_Temp < 1.0)
  712.       First_Line = (int) (Frame.Screen_Height * First_Line_Temp);
  713.     else
  714.       First_Line = (int) First_Line_Temp-1;
  715.  
  716.     if (First_Column < 0)
  717.       First_Column = 0;
  718.  
  719.     if (First_Line < 0)
  720.       First_Line = 0;
  721.  
  722.     break;
  723.  
  724.   case 'E':
  725.   case 'e': 
  726.     switch (Option_String[1])
  727.     {
  728.     case 'c': 
  729.     case 'C':
  730.       sscanf (&Option_String[2], DBL_FORMAT_STRING, &Last_Column_Temp);
  731.       break;
  732.  
  733.     case 'r': 
  734.     case 'R':
  735.       sscanf (&Option_String[2], DBL_FORMAT_STRING, &Last_Line_Temp);
  736.       break;
  737.  
  738.     default:
  739.       sscanf (&Option_String[1], DBL_FORMAT_STRING, &Last_Line_Temp);
  740.       break;
  741.     }
  742.  
  743.     if(Last_Column_Temp > 0.0 && Last_Column_Temp < 1.0)
  744.       Last_Column = (int) (Frame.Screen_Width * Last_Column_Temp);
  745.     else
  746.       Last_Column = (int) Last_Column_Temp;
  747.  
  748.     if(Last_Line_Temp > 0.0 && Last_Line_Temp < 1.0)
  749.       Last_Line = (int) (Frame.Screen_Height * Last_Line_Temp);
  750.     else
  751.       Last_Line = (int) Last_Line_Temp;
  752.  
  753.     if (Last_Column < 0 || Last_Column > Frame.Screen_Width)
  754.       Last_Column = Frame.Screen_Width;
  755.  
  756.     if (Last_Line > Frame.Screen_Height)
  757.       Last_Line = Frame.Screen_Height;
  758.  
  759.     break;
  760.  
  761.   case 'M': /* Switch used so other max values can be inserted easily */
  762.   case 'm':  
  763.     switch (Option_String[1])
  764.     {
  765.     case 's': /* Max Symbols */
  766.     case 'S':
  767.       sscanf (&Option_String[2], "%d", &Max_Symbols);
  768.       break;
  769.     case 'v': /* Max Version */
  770.     case 'V':
  771.       sscanf (&Option_String[2], DBL_FORMAT_STRING, &Language_Version);
  772.       break;
  773.     case 'b': /* Min Bounded */
  774.     case 'B':
  775.       if (sscanf (&Option_String[2], "%ld", &bounds_thresh) != EOF)
  776.         Bounds_Threshold=bounds_thresh;
  777.       Use_Slabs = Add_Option;
  778.       break;
  779.     default:
  780.       break;
  781.     }
  782.     break;
  783.  
  784.   case 'Q':
  785.   case 'q':
  786.     sscanf (&Option_String[1], "%d", &Quality);
  787.     if ((Quality < 0) || (Quality > 9))
  788.       Error("Illegal +Q switch setting");
  789.     Quality_Flags = Quality_Values[Quality];
  790.     break;
  791.  
  792.     /* Turn on debugging print statements. */
  793.   case 'Z':
  794.   case 'z':  
  795.     Option_Number = DEBUGGING;
  796.     break;
  797.  
  798.     /* +Y switch to remain undocumented.  Add to +Q later */
  799.   case 'Y':
  800.   case 'y':  
  801.     Use_Slabs = Add_Option;
  802.     break;
  803.  
  804.   case 'K':
  805.   case 'k': 
  806.     sscanf (&Option_String[1], DBL_FORMAT_STRING, &Clock_Value);
  807.     break;
  808.  
  809.   default:   
  810.     fprintf (stderr, "\nInvalid option: %s\n\n", --Option_String);
  811.   }
  812.  
  813.   if (Option_Number != 0)
  814.     if (Add_Option)
  815.       Options |= Option_Number;
  816.     else Options &= ~Option_Number;
  817.   }
  818.  
  819.   void Print_Options()
  820.     {
  821.     int i;
  822.  
  823.     fprintf (stdout,"\nPOV-Ray Options in effect: ");
  824.  
  825.     if (Options & CONTINUE_TRACE)
  826.       fprintf (stdout,"+c ");
  827.  
  828.     if (Options & DISPLAY)
  829.       fprintf (stdout,"+d%c%c ", DisplayFormat, PaletteOption);
  830.  
  831.     if (Options & VERBOSE)
  832.       fprintf (stdout,"+v%c ", VerboseFormat);
  833.  
  834.     if (Options & VERBOSE_FILE)
  835.       fprintf (stdout,"+@%s ", Stat_File_Name);
  836.  
  837.     if (Options & DISKWRITE)
  838.       fprintf (stdout,"+f%c ", OutputFormat);
  839.  
  840.     if (Options & PROMPTEXIT)
  841.       fprintf (stdout,"+p ");
  842.  
  843.     if (Options & EXITENABLE)
  844.       fprintf (stdout,"+x ");
  845.  
  846.     if (Use_Slabs)
  847.       fprintf (stdout,"+mb%d ", Bounds_Threshold);
  848.     else
  849.       fprintf (stdout,"-mb ");
  850.  
  851.     if (Options & DEBUGGING)
  852.       fprintf (stdout,"+z ");
  853.  
  854.     if (File_Buffer_Size != 0)
  855.       fprintf (stdout,"-b%d ", File_Buffer_Size/1024);
  856.  
  857.     if (Options & ANTIALIAS)
  858.       {
  859.       fprintf (stdout,"+a%.3f ", Antialias_Threshold);
  860.       if (Options & JITTER)
  861.         fprintf (stdout,"+j%.3f ", JitterScale);
  862.       fprintf (stdout,"+r%ld ",AntialiasDepth);
  863.       }
  864.  
  865.     /* quality flags rewrite in progress by CEY */
  866.  
  867.     fprintf (stdout,"-q%d -w%d -h%d -s%d -e%d\n",Quality,
  868.       Frame.Screen_Width, Frame.Screen_Height, First_Line+1, Last_Line);
  869.  
  870.     fprintf (stdout, "-k%.3f -mv%.1f -i%s ", Clock_Value, Language_Version, 
  871.       Input_File_Name);
  872.  
  873.     if (Options & DISKWRITE)
  874.       fprintf (stdout,"-o%s ", Output_File_Name);
  875.  
  876.     for (i = 0 ; i < Library_Path_Index ; i++)
  877.       fprintf (stdout,"-l%s ", Library_Paths[i]);
  878.  
  879.     fprintf (stdout,"\n");
  880.     }
  881.  
  882. void parse_file_name (File_Name)
  883. char *File_Name;
  884.   {
  885.   FILE *defaults_file;
  886.   char Option_String[256];
  887.  
  888.   if (inflag)   /* file names may now be separated by spaces from cmdline option */
  889.     {
  890.     strncpy (Input_File_Name, File_Name, FILE_NAME_LENGTH);
  891.     inflag = FALSE;
  892.     return;
  893.     }
  894.  
  895.   if (outflag)  /* file names may now be separated by spaces from cmdline option */
  896.     {
  897.     strncpy (Output_File_Name, File_Name, FILE_NAME_LENGTH);
  898.     outflag = FALSE;
  899.     return;
  900.     }
  901.  
  902.  
  903.   if (++Number_Of_Files > MAX_FILE_NAMES)
  904.     {
  905.     fprintf (stderr, "\nOnly %d option file names are allowed in a command line.", 
  906.       MAX_FILE_NAMES);
  907.     exit(1);
  908.     }
  909.  
  910.   if ((defaults_file = Locate_File(File_Name, "r")) != NULL) 
  911.     {
  912.     while (fgets(Option_String, 256, defaults_file) != NULL)
  913.       read_options(Option_String);
  914.     fclose (defaults_file);
  915.     }
  916.   else
  917.     printf("\nError opening option file %s.",File_Name);  
  918.   }
  919.  
  920. void print_stats()
  921.   {
  922.   long hours,min;
  923.   DBL sec;
  924.   FILE *stat_out;
  925.   long Pixels_In_Image;
  926.  
  927.   if (Options & VERBOSE_FILE)
  928.     stat_out = fopen(Stat_File_Name,"w+t");
  929.   else
  930.     stat_out = stdout;  
  931.  
  932.   Pixels_In_Image = (long)Frame.Screen_Width * (long)Frame.Screen_Height;
  933.  
  934.  
  935.   fprintf (stat_out,"\n%s statistics\n",Input_File_Name);
  936.   if(Pixels_In_Image > Number_Of_Pixels)
  937.     fprintf (stat_out,"  Partial Image Rendered");
  938.  
  939.   fprintf (stat_out,"--------------------------------------\n");
  940.   fprintf (stat_out,"Resolution %d x %d\n",Frame.Screen_Width, Frame.Screen_Height);
  941.   fprintf (stat_out,"# Rays:  %10ld    # Pixels:  %10ld  # Pixels supersampled: %10ld\n",
  942.     Number_Of_Rays, Number_Of_Pixels, Number_Of_Pixels_Supersampled);
  943.  
  944.   fprintf (stat_out,"  Ray->Shape Intersection Tests:\n");
  945.   fprintf (stat_out,"   Type             Tests    Succeeded   Percentage\n");
  946.   fprintf (stat_out,"  -----------------------------------------------------------\n");
  947.   if(Ray_Sphere_Tests)
  948.     fprintf (stat_out,"  Sphere       %10ld  %10ld  %10.2f\n", Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded, ( ((DBL)Ray_Sphere_Tests_Succeeded/(DBL)Ray_Sphere_Tests) *100.0 ) );
  949.   if(Ray_Plane_Tests)
  950.     fprintf (stat_out,"  Plane        %10ld  %10ld  %10.2f\n", Ray_Plane_Tests, Ray_Plane_Tests_Succeeded, ( ((DBL)Ray_Plane_Tests_Succeeded/(DBL)Ray_Plane_Tests) *100.0 ));
  951.   if(Ray_Triangle_Tests)
  952.     fprintf (stat_out,"  Triangle     %10ld  %10ld  %10.2f\n", Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded, ( ((DBL)Ray_Triangle_Tests_Succeeded/(DBL)Ray_Triangle_Tests) *100.0 ));
  953.   if(Ray_Quadric_Tests)
  954.     fprintf (stat_out,"  Quadric      %10ld  %10ld  %10.2f\n", Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded, ( ((DBL)Ray_Quadric_Tests_Succeeded/(DBL)Ray_Quadric_Tests) *100.0 ));
  955.   if(Ray_Blob_Tests)
  956.     fprintf (stat_out,"  Blob         %10ld  %10ld  %10.2f\n", Ray_Blob_Tests, Ray_Blob_Tests_Succeeded, ( ((DBL)Ray_Blob_Tests_Succeeded/(DBL)Ray_Blob_Tests) *100.0 ));
  957.   if(Ray_Box_Tests)
  958.     fprintf (stat_out,"  Box          %10ld  %10ld  %10.2f\n", Ray_Box_Tests, Ray_Box_Tests_Succeeded, ( ((DBL)Ray_Box_Tests_Succeeded/(DBL)Ray_Box_Tests) *100.0 ));
  959.   if(Ray_Cone_Tests)
  960.     fprintf (stat_out,"  Cone         %10ld  %10ld  %10.2f\n", Ray_Cone_Tests, Ray_Cone_Tests_Succeeded, ( ((DBL)Ray_Cone_Tests_Succeeded/(DBL)Ray_Cone_Tests) *100.0 ) );
  961.   if(Ray_Disc_Tests)
  962.     fprintf (stat_out,"  Disc         %10ld  %10ld  %10.2f\n", Ray_Disc_Tests, Ray_Disc_Tests_Succeeded, ( ((DBL)Ray_Disc_Tests_Succeeded/(DBL)Ray_Disc_Tests) *100.0 ) );
  963.   if(Ray_Poly_Tests)
  964.     fprintf (stat_out,"  Quartic\\Poly %10ld  %10ld  %10.2f\n", Ray_Poly_Tests, Ray_Poly_Tests_Succeeded, ( ((DBL)Ray_Poly_Tests_Succeeded/(DBL)Ray_Poly_Tests) *100.0 ));
  965.   if(Ray_Bicubic_Tests)
  966.     fprintf (stat_out,"  Bezier Patch %10ld  %10ld  %10.2f\n", Ray_Bicubic_Tests, Ray_Bicubic_Tests_Succeeded, ( ((DBL)Ray_Bicubic_Tests_Succeeded/(DBL)Ray_Bicubic_Tests) *100.0 ));
  967.   if(Ray_Ht_Field_Tests)
  968.     fprintf (stat_out,"  Height Fld   %10ld  %10ld  %10.2f\n", Ray_Ht_Field_Tests, Ray_Ht_Field_Tests_Succeeded, ( ((DBL)Ray_Ht_Field_Tests_Succeeded/(DBL)Ray_Ht_Field_Tests) *100.0 ));
  969.   if(Ray_Ht_Field_Box_Tests)
  970.     fprintf (stat_out,"  Hght Fld Box %10ld  %10ld  %10.2f\n", Ray_Ht_Field_Box_Tests, Ray_HField_Box_Tests_Succeeded, ( ((DBL)Ray_HField_Box_Tests_Succeeded/(DBL)Ray_Ht_Field_Box_Tests) *100.0 ));
  971.   if(Bounding_Region_Tests)
  972.     fprintf (stat_out,"  Bounds       %10ld  %10ld  %10.2f\n", Bounding_Region_Tests, Bounding_Region_Tests_Succeeded, ( ((DBL)Bounding_Region_Tests_Succeeded/(DBL)Bounding_Region_Tests) *100.0 ));
  973.   if(Clipping_Region_Tests)
  974.     fprintf (stat_out,"  Clips        %10ld  %10ld  %10.2f\n", Clipping_Region_Tests, Clipping_Region_Tests_Succeeded, ( ((DBL)Clipping_Region_Tests_Succeeded/(DBL)Clipping_Region_Tests) *100.0 ));
  975.  
  976.   if(Calls_To_Noise) 
  977.  
  978.     fprintf (stat_out,"  Calls to Noise:   %10ld\n", Calls_To_Noise);
  979.   if(Calls_To_DNoise)
  980.     fprintf (stat_out,"  Calls to DNoise:  %10ld\n", Calls_To_DNoise);
  981.   if(Shadow_Ray_Tests)
  982.     fprintf (stat_out,"  Shadow Ray Tests: %10ld     Blocking Objects Found:  %10ld\n",
  983.       Shadow_Ray_Tests, Shadow_Rays_Succeeded);
  984.   if(Reflected_Rays_Traced)
  985.     fprintf (stat_out,"  Reflected Rays:   %10ld\n", Reflected_Rays_Traced);
  986.   if(Refracted_Rays_Traced)
  987.     fprintf (stat_out,"  Refracted Rays:   %10ld\n", Refracted_Rays_Traced);
  988.   if(Transmitted_Rays_Traced)
  989.     fprintf (stat_out,"  Transmitted Rays: %10ld\n", Transmitted_Rays_Traced);
  990.   if(Istack_overflows)
  991.     fprintf (stat_out,"  I-Stack overflows:%10ld\n", Istack_overflows);
  992.  
  993.   if(tused==0) 
  994.     {
  995.     STOP_TIME                  /* Get trace done time. */
  996.     tused = TIME_ELAPSED       /* Calc. elapsed time. Define TIME_ELAPSED as */
  997.     /* 0 in your specific CONFIG.H if unsupported */
  998.     }
  999.   if (tused != 0)
  1000.     {
  1001.     /* Convert seconds to hours, min & sec. CdW */
  1002.     hours = (long) tused/3600;
  1003.     min = (long) (tused - hours*3600)/60;
  1004.     sec = tused - (DBL) (hours*3600 + min*60);
  1005.     fprintf (stat_out,"  Time For Trace:   %2ld hours %2ld minutes %4.2f seconds\n", hours,min,sec); 
  1006.     }
  1007.   if (Options & VERBOSE_FILE)
  1008.     fclose(stat_out);
  1009.  
  1010.   }
  1011.  
  1012. /* Find a file in the search path. */
  1013.  
  1014. FILE *Locate_File (filename, mode)
  1015. char *filename, *mode;
  1016.   {
  1017.   FILE *f;
  1018.   int i;
  1019.   char pathname[FILE_NAME_LENGTH];
  1020.  
  1021.   /* Check the current directory first. */
  1022.   if ((f = fopen (filename, mode)) != NULL)
  1023.     return (f);
  1024.  
  1025.   for (i = 0 ; i < Library_Path_Index ; i++) 
  1026.     {
  1027.     strcpy (pathname, Library_Paths[i]);
  1028.     if (FILENAME_SEPARATOR != NULL)
  1029.       strcat (pathname, FILENAME_SEPARATOR);
  1030.     strcat (pathname, filename);
  1031.     if ((f = fopen (pathname, mode)) != NULL)
  1032.       return (f);
  1033.     }
  1034.  
  1035.   return (NULL);
  1036.   }
  1037. void print_credits()
  1038.   {
  1039.   fprintf (stderr,"\n");
  1040.   fprintf (stderr,"  Persistence of Vision Raytracer Ver %s%s\n",POV_RAY_VERSION,COMPILER_VER);
  1041.   fprintf (stderr,"    %s\n",DISTRIBUTION_MESSAGE_1);
  1042.   fprintf (stderr,"     %s\n",DISTRIBUTION_MESSAGE_2);
  1043.   fprintf (stderr,"     %s\n",DISTRIBUTION_MESSAGE_3);
  1044.   fprintf (stderr,"  Copyright 1993 POV-Team\n");
  1045.   fprintf (stderr,"  ----------------------------------------------------------------------\n");
  1046.   fprintf (stderr,"  POV-Ray is based on DKBTrace 2.12 by David K. Buck & Aaron A. Collins.\n");
  1047.   fprintf (stderr,"    Contributing Authors: (Alphabetically)\n");
  1048.   fprintf (stderr,"       Steve Anger        Steve A. Bennett   David K. Buck\n");
  1049.   fprintf (stderr,"       Aaron A. Collins   Alexander Enzmann  Dan Farmer\n");
  1050.   fprintf (stderr,"       Douglas Muir       Bill Pulver        Robert Skinner\n");
  1051.   fprintf (stderr,"       Scott Taylor       Drew Wells         Chris Young\n");
  1052.   fprintf (stderr,"    Other contributors listed in the documentation.\n");
  1053.   fprintf (stderr,"  ----------------------------------------------------------------------\n");
  1054.   }
  1055.