home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / povsrc.sit / SOURCE / POVRAY.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-03  |  25.9 KB  |  854 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 1992 Persistence of Vision Team
  9. *---------------------------------------------------------------------------
  10. *  Copying, distribution and legal info is in the file povlegal.doc which
  11. *  should be distributed with this file. If povlegal.doc is not available
  12. *  or for more info please contact:
  13. *
  14. *       Drew Wells [POV-Team Leader] 
  15. *       CIS: 73767,1244  Internet: 73767.1244@compuserve.com
  16. *       Phone: (213) 254-4041
  17. * This program is based on the popular DKB raytracer version 2.12.
  18. * DKBTrace was originally written by David K. Buck.
  19. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  20. *
  21. *****************************************************************************/
  22. #include <ctype.h>
  23. #include <time.h>          /* BP */
  24. #include "frame.h"              /* common to ALL modules in this program */
  25. #include "povproto.h"
  26.  
  27. #define MAX_FILE_NAMES 1
  28. unsigned int Options;
  29. int Quality;
  30. int Case_Sensitive_Flag = CASE_SENSITIVE_DEFAULT;
  31.  
  32. FILE *bfp;
  33.  
  34. extern FRAME Frame;
  35.  
  36. char Input_File_Name[FILE_NAME_LENGTH], Output_File_Name[FILE_NAME_LENGTH], Stat_File_Name[FILE_NAME_LENGTH];
  37.  
  38. #define MAX_LIBRARIES 10
  39. char *Library_Paths[MAX_LIBRARIES];
  40. int Library_Path_Index;
  41.  
  42. int Max_Symbols   = 500;
  43.  
  44. FILE_HANDLE *Output_File_Handle;
  45. int File_Buffer_Size;
  46. static int Number_Of_Files;
  47. static int inflag, outflag; 
  48. DBL VTemp;
  49. DBL Antialias_Threshold;
  50. int First_Line, Last_Line;
  51. int Display_Started = FALSE;
  52. int Shadow_Test_Flag = FALSE;
  53.  
  54. /* Stats kept by the ray tracer: */
  55. long Number_Of_Pixels, Number_Of_Rays, Number_Of_Pixels_Supersampled;
  56. long Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded;
  57. long Ray_Box_Tests, Ray_Box_Tests_Succeeded;
  58. long Ray_Blob_Tests, Ray_Blob_Tests_Succeeded;
  59. long Ray_Plane_Tests, Ray_Plane_Tests_Succeeded;
  60. long Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded;
  61. long Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded;
  62. long Ray_Poly_Tests, Ray_Poly_Tests_Succeeded;
  63. long Ray_Bicubic_Tests, Ray_Bicubic_Tests_Succeeded;
  64. long Ray_Ht_Field_Tests, Ray_Ht_Field_Tests_Succeeded;
  65. long Ray_Ht_Field_Box_Tests, Ray_HField_Box_Tests_Succeeded;
  66. long Bounding_Region_Tests, Bounding_Region_Tests_Succeeded;
  67. long Clipping_Region_Tests, Clipping_Region_Tests_Succeeded;
  68. long Calls_To_Noise, Calls_To_DNoise;
  69. long Shadow_Ray_Tests, Shadow_Rays_Succeeded;
  70. long Reflected_Rays_Traced, Refracted_Rays_Traced;
  71. long Transmitted_Rays_Traced;
  72. time_t tstart, tstop;
  73. DBL    tused;             /* Trace timer variables. - BP */ 
  74.  
  75. char DisplayFormat, OutputFormat, VerboseFormat, PaletteOption, Color_Bits;
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82. #ifdef NOCMDLINE        /* a main() by any other name... */
  83. #ifdef ALTMAIN
  84. void alt_main()
  85. #else
  86. void main()
  87. #endif
  88. #else
  89. #ifdef ALTMAIN
  90. void alt_main(argc, argv)
  91. #else
  92. void main(argc, argv)
  93. #endif
  94. int argc;
  95. char **argv;
  96. #endif                  /* ...would be a lot less hassle!! :-) AAC */
  97. {
  98.    register int i;
  99.    FILE *stat_file;
  100.  
  101.    STARTUP_POVRAY
  102.  
  103.    PRINT_CREDITS
  104.  
  105.    PRINT_OTHER_CREDITS
  106.  
  107.    /* Parse the command line parameters */
  108. #ifndef NOCMDLINE
  109.    if (argc == 1)
  110.       usage();
  111. #endif
  112.  
  113.    init_vars();
  114.  
  115.    Output_File_Name[0]='\0';
  116.  
  117.    Library_Paths[0] = NULL;
  118.    Library_Path_Index = 0;
  119.  
  120.    /* Read the default parameters from povray.def */
  121.    get_defaults();
  122.  
  123. #ifndef NOCMDLINE
  124.    for (i = 1 ; i < argc ; i++ )
  125.       if ((*argv[i] == '+') || (*argv[i] == '-'))
  126.          parse_option(argv[i]);
  127.       else
  128.          parse_file_name(argv[i]);
  129. #endif
  130.  
  131.    if (Last_Line == -1)
  132.       Last_Line = Frame.Screen_Height;
  133.  
  134.    if (Options & DISKWRITE) {
  135.       switch (OutputFormat) {
  136.       case '\0':
  137.       case 'd':
  138.       case 'D':
  139.          if ((Output_File_Handle = Get_Dump_File_Handle()) == NULL) {
  140.             close_all();
  141.             exit(1);
  142.          }
  143.          break;
  144.          /*
  145.          case 'i':
  146.          case 'I':
  147.                    if ((Output_File_Handle = Get_Iff_File_Handle()) == NULL) {
  148.                       close_all();
  149.                       exit(1);
  150.                       }
  151.                    break;
  152.  
  153. */
  154.       case 'r':
  155.       case 'R':
  156.          if ((Output_File_Handle = Get_Raw_File_Handle()) == NULL) {
  157.             close_all();
  158.             exit(1);
  159.          }
  160.          break;
  161.  
  162.       case 't':
  163.       case 'T':
  164.          if ((Output_File_Handle = Get_Targa_File_Handle()) == NULL) {
  165.             close_all();
  166.             exit(1);
  167.          }
  168.          break;
  169.       default:
  170.          fprintf (stderr, "Unrecognized output file format %c\n", OutputFormat);
  171.          exit(1);
  172.       }
  173.       if (Output_File_Name[0] == '\0')
  174.          strcpy (Output_File_Name, Default_File_Name (Output_File_Handle));
  175.    }
  176.  
  177.    Print_Options();
  178.  
  179.    Initialize_Tokenizer(Input_File_Name);
  180.    fprintf (stderr,"Parsing...");
  181.    if (Options & VERBOSE_FILE){
  182.       stat_file = fopen(Stat_File_Name,"w+t");
  183.       fprintf (stat_file, "Parsing...\n");
  184.       fclose(stat_file);
  185.    }
  186.    Parse (&Frame);
  187.    Terminate_Tokenizer();
  188.    /* fprintf (stderr,"\n"); */
  189.  
  190.    if (Options & DISPLAY)
  191.    {
  192.       printf ("Displaying...\n");
  193.       display_init(Frame.Screen_Width, Frame.Screen_Height);
  194.       Display_Started = TRUE;
  195.    }
  196.  
  197.    /* Get things ready for ray tracing */
  198.    if (Options & DISKWRITE)
  199.       if (Options & CONTINUE_TRACE) {
  200.          if (Open_File (Output_File_Handle, Output_File_Name,
  201.             &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  202.             READ_MODE) != 1) {
  203.             fprintf (stderr, "Error opening continue trace output file\n");
  204.             fprintf (stderr, "Opening new output file %s.\n",Output_File_Name);
  205.             Options &= ~CONTINUE_TRACE; /* Turn off continue trace */
  206.  
  207.             if (Open_File (Output_File_Handle, Output_File_Name,
  208.                &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  209.                WRITE_MODE) != 1) {
  210.                fprintf (stderr, "Error opening output file\n");
  211.                close_all();
  212.                exit(1);
  213.             }
  214.          }
  215.  
  216.          Initialize_Renderer();
  217.          if (Options & CONTINUE_TRACE) 
  218.             Read_Rendered_Part();
  219.       }
  220.       else {
  221.          if (Open_File (Output_File_Handle, Output_File_Name,
  222.             &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  223.             WRITE_MODE) != 1) {
  224.             fprintf (stderr, "Error opening output file\n");
  225.             close_all();
  226.             exit(1);
  227.          }
  228.  
  229.          Initialize_Renderer();
  230.       }
  231.    else
  232.       Initialize_Renderer();
  233.  
  234.    pq_init();
  235.    Initialize_Noise();
  236.  
  237.    START_TIME  /* Store start time for trace. Timer macro in CONFIG.H */
  238.  
  239.    /* Ok, go for it - trace the picture */
  240.    if ((Options & VERBOSE) && (VerboseFormat !='1'))
  241.       printf ("Rendering...\n");
  242.    else if ((Options & VERBOSE) && (VerboseFormat=='1'))
  243.       fprintf (stderr,"POV-Ray rendering %s to %s :\n",Input_File_Name,Output_File_Name);
  244.    if (Options & VERBOSE_FILE){
  245.       stat_file = fopen(Stat_File_Name,"w+t");
  246.       fprintf (stat_file,"Parsed ok. Now rendering %s to %s :\n",Input_File_Name,Output_File_Name);
  247.       fclose(stat_file);
  248.    }
  249.  
  250.    CONFIG_MATH               /* Macro for setting up any special FP options */
  251.    Start_Tracing ();
  252.  
  253.    if (Options & VERBOSE && VerboseFormat=='1')
  254.       fprintf (stderr,"\n");
  255.  
  256.    /* Record the time so well spent... */
  257.    STOP_TIME                  /* Get trace done time. */
  258.    tused = TIME_ELAPSED       /* Calc. elapsed time. Define TIME_ELAPSED as */
  259.    /* 0 in your specific CONFIG.H if unsupported */
  260.  
  261.    /* Clean up and leave */
  262.    display_finished();
  263.  
  264.    close_all ();
  265.  
  266.    PRINT_STATS
  267.  
  268.    if (Options & VERBOSE_FILE){
  269.       stat_file = fopen(Stat_File_Name,"a+t");
  270.       fprintf (stat_file,"Done Tracing\n");
  271.       fclose(stat_file);
  272.    }
  273.  
  274.    FINISH_POVRAY
  275. }
  276.  
  277. /* Print out usage error message */
  278.  
  279. void usage ()
  280. {
  281.    WAIT_FOR_KEYPRESS        
  282.    fprintf (stdout,"\nUsage:");
  283.    fprintf (stdout,"\n   povray  [+/-] Option1 [+/-] Option2 ...");
  284.    fprintf (stdout,"\n");
  285.    fprintf (stdout,"\n Options: ");
  286.    fprintf (stdout,"\n    dxy = display in format x, using palette option y");
  287.    fprintf (stdout,"\n    vx  = verbose in format x");
  288.    /*fprintf (stdout,"\n    @filename  = verbose to file name -- see docs");*/
  289.    fprintf (stdout,"\n    p  = pause before exit");
  290.    fprintf (stdout,"\n    x  = enable early exit by key hit");
  291.    fprintf (stdout,"\n    fx = write output file in format x");
  292.    fprintf (stdout,"\n         ft - Uncompressed Targa-24  fd - DKB/QRT Dump  fr - 3 Raw Files");
  293.    fprintf (stdout,"\n    a  = perform antialiasing");
  294.    fprintf (stdout,"\n    c  = continue aborted trace");
  295.    fprintf (stdout,"\n    qx = image quality 0=rough, 9=full");
  296.    fprintf (stdout,"\n    l<pathname> = library path prefix");
  297.    fprintf (stdout,"\n    wxxx = width of the screen");
  298.    fprintf (stdout,"\n    hxxx = height of the screen");
  299.    fprintf (stdout,"\n    sxxx = start at line number xxx");
  300.    fprintf (stdout,"\n    exxx = end at line number xxx");
  301.    fprintf (stdout,"\n    bxxx = Use xxx kilobytes for output file buffer space");
  302.    fprintf (stdout,"\n    i<filename> = input file name");
  303.    fprintf (stdout,"\n    o<filename> = output file name");
  304.    fprintf (stdout,"\n  Ex: +l\\povray\\include +iscene.pov +oscene.tga +w320 +h200 +d -v +x");
  305.    fprintf (stdout,"\n  Ex: +iscene.pov +oscene.tga +w160 +h200 +v -d +x");
  306.    fprintf (stdout,"\n");
  307.    exit(1);
  308. }
  309.  
  310. void init_vars()
  311. {
  312.    Output_File_Handle = NULL;
  313.    File_Buffer_Size = 0;
  314.    Options = 0;
  315.    Quality = 9;
  316.    Number_Of_Files = 0;
  317.    First_Line = 0;
  318.    Last_Line = -1;
  319.    Color_Bits = 8;
  320.  
  321.    Number_Of_Pixels = 0L;
  322.    Number_Of_Rays = 0L;
  323.    Number_Of_Pixels_Supersampled = 0L;
  324.    Ray_Ht_Field_Tests = 0L;
  325.    Ray_Ht_Field_Tests_Succeeded = 0L;
  326.    Ray_Ht_Field_Box_Tests = 0L;
  327.    Ray_HField_Box_Tests_Succeeded = 0L;
  328.    Ray_Bicubic_Tests = 0L;
  329.    Ray_Bicubic_Tests_Succeeded = 0L;
  330.    Ray_Blob_Tests = 0L;
  331.    Ray_Blob_Tests_Succeeded = 0L;
  332.    Ray_Box_Tests = 0L;
  333.    Ray_Box_Tests_Succeeded = 0L;
  334.    Ray_Sphere_Tests = 0L;
  335.    Ray_Sphere_Tests_Succeeded = 0L;
  336.    Ray_Plane_Tests = 0L;
  337.    Ray_Plane_Tests_Succeeded = 0L;
  338.    Ray_Triangle_Tests = 0L;
  339.    Ray_Triangle_Tests_Succeeded = 0L;
  340.    Ray_Quadric_Tests = 0L;
  341.    Ray_Quadric_Tests_Succeeded = 0L;
  342.    Ray_Poly_Tests = 0L;
  343.    Ray_Poly_Tests_Succeeded = 0L;
  344.    Bounding_Region_Tests = 0L;
  345.    Bounding_Region_Tests_Succeeded = 0L;
  346.    Clipping_Region_Tests = 0L;
  347.    Clipping_Region_Tests_Succeeded = 0L;
  348.    Calls_To_Noise = 0L;
  349.    Calls_To_DNoise = 0L;
  350.    Shadow_Ray_Tests = 0L;
  351.    Shadow_Rays_Succeeded = 0L;
  352.    Reflected_Rays_Traced = 0L;
  353.    Refracted_Rays_Traced = 0L;
  354.    Transmitted_Rays_Traced = 0L;
  355.  
  356.    Frame.Screen_Height = 100;
  357.    Frame.Screen_Width = 100;
  358.  
  359.    Antialias_Threshold = 0.3;
  360.    strcpy (Input_File_Name, "object.dat");
  361.    return;
  362. }
  363.  
  364. /* Close all the stuff that has been opened. */
  365. void close_all ()
  366. {
  367.    if ((Options & DISPLAY) && Display_Started)
  368.       display_close();
  369.  
  370.    if (Output_File_Handle)
  371.       Close_File (Output_File_Handle);
  372. }
  373.  
  374. /* Read the default parameters from povray.def */
  375. void get_defaults()
  376. {
  377.    FILE *defaults_file;
  378.    char Option_String[256], *Option_String_Ptr;
  379.    /* READ_ENV_VAR_? should be defined in config.h */
  380.    /* Only one READ_ENV_VAR_? should ever be defined. */
  381.    /* This allows some machines to read environment variable before */
  382.    /* reading povray.def and others to do it after depending on the */
  383.    /* operating system. IBM-PC is before. Default is after if not */
  384.    /* defined in config.h. CDW 2/92 */
  385.    /* Set Diskwrite as default */
  386.    Options |= DISKWRITE;
  387.    OutputFormat = DEFAULT_OUTPUT_FORMAT;
  388.  
  389.    READ_ENV_VAR_BEFORE
  390.    if ((defaults_file = Locate_File("povray.def", "r")) != NULL) {
  391.       while (fgets(Option_String, 256, defaults_file) != NULL)
  392.          read_options(Option_String);
  393.       fclose (defaults_file);
  394.    }
  395.    READ_ENV_VAR_AFTER
  396. }
  397.  
  398. void read_options (Option_Line)
  399. char *Option_Line;
  400. {
  401.    register int c, String_Index, Option_Started;
  402.    short Option_Line_Index = 0;
  403.    char Option_String[80];
  404.  
  405.    String_Index = 0;
  406.    Option_Started = FALSE;
  407.    while ((c = Option_Line[Option_Line_Index++]) != '\0')
  408.    {
  409.       if (Option_Started)
  410.          if (isspace(c))
  411.          {
  412.             Option_String[String_Index] = '\0';
  413.             parse_option (Option_String);
  414.             Option_Started = FALSE;
  415.             String_Index = 0;
  416.          }
  417.          else
  418.             Option_String[String_Index++] = (char) c;
  419.  
  420.       else /* Option_Started */
  421.          if ((c == (int) '-') || (c == (int) '+'))
  422.          {
  423.             String_Index = 0;
  424.             Option_String[String_Index++] = (char) c;
  425.             Option_Started = TRUE;
  426.          }
  427.          else
  428.             if (!isspace(c))
  429.             {
  430.                fprintf (stderr, "\nBad default file format.  Offending char: (%c), val: %d.\n", (char) c, c);
  431.                exit (1);
  432.             }
  433.    }
  434.  
  435.    if (Option_Started)
  436.    {
  437.       Option_String[String_Index] = '\0';
  438.       parse_option (Option_String);
  439.    }
  440. }
  441.  
  442. /* parse the command line parameters */
  443. void parse_option (Option_String)
  444. char *Option_String;
  445. {
  446.    register int Add_Option;
  447.    unsigned int Option_Number;
  448.    DBL threshold;
  449.  
  450.    inflag = outflag = FALSE;   /* if these flags aren't immediately used, reset them on next -/+ option! */
  451.    if (*(Option_String++) == '-')
  452.       Add_Option = FALSE;
  453.    else
  454.       Add_Option = TRUE;
  455.  
  456.    switch (*Option_String)
  457.    {
  458.    case 'B':
  459.    case 'b':  
  460.       sscanf (&Option_String[1], "%d", &File_Buffer_Size);
  461.       File_Buffer_Size *= 1024;
  462.       if (File_Buffer_Size < BUFSIZ)
  463.          File_Buffer_Size = BUFSIZ;
  464.       Option_Number = 0;
  465.       break;
  466.  
  467.    case 'C':
  468.    case 'c':  
  469.       Option_Number = CONTINUE_TRACE;
  470.       break;
  471.  
  472.    case 'D':
  473.    case 'd':  
  474.       Option_Number = DISPLAY;
  475.       DisplayFormat = '0';
  476.       PaletteOption = '3';
  477.       if (Option_String[1] != '\0')
  478.          DisplayFormat = (char)toupper(Option_String[1]);
  479.  
  480.       if (Option_String[1] != '\0' && Option_String[2] != '\0')
  481.          PaletteOption = (char)toupper(Option_String[2]);
  482.       break;
  483.  
  484.    case '@':  
  485.       Option_Number = VERBOSE_FILE;
  486.       if(Option_String[1] == '\0')
  487.          strcpy(Stat_File_Name, "POVSTAT.OUT");
  488.       else
  489.          strncpy (Stat_File_Name, &Option_String[1], FILE_NAME_LENGTH);
  490.       break;
  491.    case 'V':
  492.    case 'v':  
  493.       Option_Number = VERBOSE;
  494.       VerboseFormat = (char)toupper(Option_String[1]);
  495.       if (VerboseFormat == '\0')
  496.          VerboseFormat = '1';
  497.       break;
  498.  
  499.    case 'W':
  500.    case 'w':  
  501.       sscanf (&Option_String[1], "%d", &Frame.Screen_Width);
  502.       Option_Number = 0;
  503.       break;
  504.  
  505.    case 'H':
  506.    case 'h':  
  507.       sscanf (&Option_String[1], "%d", &Frame.Screen_Height);
  508.       Option_Number = 0;
  509.       break;
  510.  
  511.    case 'F':
  512.    case 'f':  
  513.       Option_Number = DISKWRITE;
  514.       if (isupper(Option_String[1]))
  515.          OutputFormat = (char)tolower(Option_String[1]);
  516.       else
  517.          OutputFormat = Option_String[1];
  518.  
  519.       /* Default the output format to the default in the config file */
  520.       if (OutputFormat == '\0')
  521.          OutputFormat = DEFAULT_OUTPUT_FORMAT;
  522.       break;
  523.  
  524.    case 'P':
  525.    case 'p':  
  526.       Option_Number = PROMPTEXIT;
  527.       break;
  528.  
  529.    case 'I':
  530.    case 'i':  
  531.       if (Option_String[1] == '\0')
  532.          inflag = TRUE;
  533.       else 
  534.          strncpy (Input_File_Name, &Option_String[1], FILE_NAME_LENGTH);
  535.       Option_Number = 0;
  536.       break;
  537.  
  538.    case 'O':
  539.    case 'o':  
  540.       if (Option_String[1] == '\0')
  541.          outflag = TRUE;
  542.       else
  543.          strncpy (Output_File_Name, &Option_String[1], FILE_NAME_LENGTH);
  544.       Option_Number = 0;
  545.       break;
  546.  
  547.    case 'A':
  548.    case 'a':  
  549.       Option_Number = ANTIALIAS;
  550.       if (sscanf (&Option_String[1], DBL_FORMAT_STRING, &threshold) != EOF)
  551.          Antialias_Threshold = threshold;
  552.       break;
  553.  
  554.    case 'X':
  555.    case 'x':  
  556.       Option_Number = EXITENABLE;
  557.       break;
  558.  
  559.  
  560.    case 'L':
  561.    case 'l':  
  562.       if (Library_Path_Index >= MAX_LIBRARIES) {
  563.          fprintf (stderr, "Too many library directories specified\n");
  564.          exit(1);
  565.       }
  566.       Library_Paths [Library_Path_Index] = malloc (strlen(Option_String));
  567.       if (Library_Paths [Library_Path_Index] == NULL) {
  568.          fprintf (stderr, "Out of memory. Cannot allocate memory for library pathname\n");
  569.          exit(1);
  570.       }
  571.       strcpy (Library_Paths [Library_Path_Index], &Option_String[1]);
  572.       Library_Path_Index++;
  573.       Option_Number = 0;
  574.       break;
  575.    case 'T':
  576.    case 't':  
  577.       switch (toupper(Option_String[1])){
  578.       case 'Y':
  579.          Case_Sensitive_Flag = 0;
  580.          break;
  581.       case 'N':
  582.          Case_Sensitive_Flag = 1;
  583.          break;
  584.       case 'O':
  585.          Case_Sensitive_Flag = 2;
  586.          break;
  587.       default:
  588.          Case_Sensitive_Flag = 2;
  589.          break;
  590.       }        
  591.       Option_Number = 0;
  592.       break;
  593.  
  594.    case 'S':
  595.    case 's':  
  596.       sscanf (&Option_String[1], "%d", &First_Line);
  597.       Option_Number = 0;
  598.       break;
  599.  
  600.    case 'E':
  601.    case 'e':  
  602.       sscanf (&Option_String[1], "%d", &Last_Line);
  603.       Option_Number = 0;
  604.       break;
  605.  
  606.    case 'M': /* Switch used so other max values can be inserted easily */
  607.    case 'm':  
  608.       switch (Option_String[1]){
  609.       case 's': /* Max Symbols */
  610.       case 'S':
  611.          sscanf (&Option_String[2], "%d", &Max_Symbols);
  612.          Option_Number = 0;
  613.          break;
  614.       default:
  615.          break;
  616.       }
  617.       break;
  618.  
  619.    case 'Q':
  620.    case 'q':  
  621.       sscanf (&Option_String[1], "%d", &Quality);
  622.       Option_Number = 0;
  623.       break;
  624.  
  625.       /* Turn on debugging print statements. */
  626.    case 'Z':
  627.    case 'z':  
  628.       Option_Number = DEBUGGING;
  629.       break;
  630.  
  631.    default:   
  632.       fprintf (stderr, "\nInvalid option: %s\n\n", --Option_String);
  633.       Option_Number = 0;
  634.    }
  635.  
  636.    if (Option_Number != 0)
  637.       if (Add_Option)
  638.          Options |= Option_Number;
  639.       else Options &= ~Option_Number;
  640. }
  641.  
  642.    void Print_Options()
  643.    {
  644.       int i;
  645.  
  646.       fprintf (stdout,"\nPOV-Ray    Options in effect: ");
  647.  
  648.       if (Options & CONTINUE_TRACE)
  649.          fprintf (stdout,"+c ");
  650.  
  651.       if (Options & DISPLAY)
  652.          fprintf (stdout,"+d%c%c ", DisplayFormat, PaletteOption);
  653.  
  654.       if (Options & VERBOSE)
  655.          fprintf (stdout,"+v%c ", VerboseFormat);
  656.  
  657.       if (Options & VERBOSE_FILE)
  658.          fprintf (stdout,"+@%s ", Stat_File_Name);
  659.  
  660.       if (Options & DISKWRITE)
  661.          fprintf (stdout,"+f%c ", OutputFormat);
  662.  
  663.       if (Options & PROMPTEXIT)
  664.          fprintf (stdout,"+p ");
  665.  
  666.       if (Options & EXITENABLE)
  667.          fprintf (stdout,"+x ");
  668.  
  669.       if (Options & ANTIALIAS)
  670.          fprintf (stdout,"+a%f ", Antialias_Threshold);
  671.  
  672.       if (Options & DEBUGGING)
  673.          fprintf (stdout,"+z ");
  674.  
  675.       if (File_Buffer_Size != 0)
  676.          fprintf (stdout,"-b%d ", File_Buffer_Size/1024);
  677.  
  678.       fprintf (stdout,"-q%d -w%d -h%d -s%d -e%d\n-i%s ",
  679.          Quality, Frame.Screen_Width, Frame.Screen_Height,
  680.          First_Line, Last_Line, Input_File_Name);
  681.  
  682.       if (Options & DISKWRITE)
  683.          fprintf (stdout,"-o%s ", Output_File_Name);
  684.  
  685.       for (i = 0 ; i < Library_Path_Index ; i++)
  686.          fprintf (stdout,"-l%s ", Library_Paths[i]);
  687.  
  688.       fprintf (stdout,"\n");
  689.    }
  690.  
  691. void parse_file_name (File_Name)
  692. char *File_Name;
  693. {
  694.    FILE *defaults_file;
  695.    char Option_String[256];
  696.  
  697.    if (inflag)   /* file names may now be separated by spaces from cmdline option */
  698.    {
  699.       strncpy (Input_File_Name, File_Name, FILE_NAME_LENGTH);
  700.       inflag = FALSE;
  701.       return;
  702.    }
  703.  
  704.    if (outflag)  /* file names may now be separated by spaces from cmdline option */
  705.    {
  706.       strncpy (Output_File_Name, File_Name, FILE_NAME_LENGTH);
  707.       outflag = FALSE;
  708.       return;
  709.    }
  710.  
  711.  
  712.    if (++Number_Of_Files > MAX_FILE_NAMES)
  713.    {
  714.       fprintf (stderr, "\nOnly %d option file names are allowed in a command line.", 
  715.          MAX_FILE_NAMES);
  716.       exit(1);
  717.    }
  718.  
  719.    if ((defaults_file = Locate_File(File_Name, "r")) != NULL) {
  720.       while (fgets(Option_String, 256, defaults_file) != NULL)
  721.          read_options(Option_String);
  722.       fclose (defaults_file);
  723.    }
  724.    else
  725.       printf("\nError opening option file %s.",File_Name);  
  726. }
  727.  
  728. void print_stats()
  729. {
  730.    int hours,min;
  731.    DBL sec;
  732.    FILE *stat_out;
  733.    long Pixels_In_Image;
  734.  
  735.    if (Options & VERBOSE_FILE)
  736.       stat_out = fopen(Stat_File_Name,"w+t");
  737.    else
  738.       stat_out = stdout;  
  739.  
  740.    Pixels_In_Image = (long)Frame.Screen_Width * (long)Frame.Screen_Height;
  741.  
  742.  
  743.    fprintf (stat_out,"\n%s statistics\n",Input_File_Name);
  744.    if(Pixels_In_Image > Number_Of_Pixels)
  745.       fprintf (stat_out,"  Partial Image Rendered");
  746.  
  747.    fprintf (stat_out,"--------------------------------------\n");
  748.    fprintf (stat_out,"Resolution %d x %d\n",Frame.Screen_Width, Frame.Screen_Height);
  749.    fprintf (stat_out,"# Rays:  %10ld    # Pixels:  %10ld  # Pixels supersampled: %10ld\n",
  750.       Number_Of_Rays, Number_Of_Pixels, Number_Of_Pixels_Supersampled);
  751.  
  752.    fprintf (stat_out,"  Ray->Shape Intersection Tests:\n");
  753.    fprintf (stat_out,"   Type             Tests    Succeeded   Percentage\n");
  754.    fprintf (stat_out,"  -----------------------------------------------------------\n");
  755.    if(Ray_Sphere_Tests)
  756.       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 ) );
  757.    if(Ray_Plane_Tests)
  758.       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 ));
  759.    if(Ray_Triangle_Tests)
  760.       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 ));
  761.    if(Ray_Quadric_Tests)
  762.       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 ));
  763.    if(Ray_Blob_Tests)
  764.       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 ));
  765.    if(Ray_Box_Tests)
  766.       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 ));
  767.    if(Ray_Poly_Tests)
  768.       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 ));
  769.    if(Ray_Bicubic_Tests)
  770.       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 ));
  771.    if(Ray_Ht_Field_Tests)
  772.       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 ));
  773.    if(Ray_Ht_Field_Box_Tests)
  774.       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 ));
  775.    if(Bounding_Region_Tests)
  776.       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 ));
  777.    if(Clipping_Region_Tests)
  778.       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 ));
  779.  
  780.    if(Calls_To_Noise) 
  781.  
  782.       fprintf (stat_out,"  Calls to Noise:   %10ld\n", Calls_To_Noise);
  783.    if(Calls_To_DNoise)
  784.       fprintf (stat_out,"  Calls to DNoise:  %10ld\n", Calls_To_DNoise);
  785.    if(Shadow_Ray_Tests)
  786.       fprintf (stat_out,"  Shadow Ray Tests: %10ld     Blocking Objects Found:  %10ld\n",
  787.          Shadow_Ray_Tests, Shadow_Rays_Succeeded);
  788.    if(Reflected_Rays_Traced)
  789.       fprintf (stat_out,"  Reflected Rays:   %10ld\n", Reflected_Rays_Traced);
  790.    if(Refracted_Rays_Traced)
  791.       fprintf (stat_out,"  Refracted Rays:   %10ld\n", Refracted_Rays_Traced);
  792.    if(Transmitted_Rays_Traced)
  793.       fprintf (stat_out,"  Transmitted Rays: %10ld\n", Transmitted_Rays_Traced);
  794.  
  795.    if(tused==0) {
  796.       STOP_TIME                  /* Get trace done time. */
  797.       tused = TIME_ELAPSED       /* Calc. elapsed time. Define TIME_ELAPSED as */
  798.       /* 0 in your specific CONFIG.H if unsupported */
  799.    }
  800.    if (tused != 0){
  801.       /* Convert seconds to hours, min & sec. CdW */
  802.       hours = (int) tused/3600;
  803.       min = (int) (tused - hours*3600)/60;
  804.       sec = tused - (DBL) (hours*3600 + min*60);
  805.       fprintf (stat_out,"  Time For Trace:   %2d hours %2d minutes %4.2f seconds\n", hours,min,sec); 
  806.    }
  807.    if (Options & VERBOSE_FILE)
  808.       fclose(stat_out);
  809.  
  810. }
  811.  
  812. /* Find a file in the search path. */
  813.  
  814. FILE *Locate_File (filename, mode)
  815. char *filename, *mode;
  816. {
  817.    FILE *f;
  818.    int i;
  819.    char pathname[FILE_NAME_LENGTH];
  820.  
  821.    /* Check the current directory first. */
  822.    if ((f = fopen (filename, mode)) != NULL)
  823.       return (f);
  824.  
  825.    for (i = 0 ; i < Library_Path_Index ; i++) {
  826.       strcpy (pathname, Library_Paths[i]);
  827.       if (FILENAME_SEPARATOR != NULL)
  828.          strcat (pathname, FILENAME_SEPARATOR);
  829.       strcat (pathname, filename);
  830.       if ((f = fopen (pathname, mode)) != NULL)
  831.          return (f);
  832.    }
  833.  
  834.    return (NULL);
  835. }
  836. void print_credits()
  837. {
  838.    fprintf (stderr,"\n");
  839.    fprintf (stderr,"  Persistence of Vision Raytracer Ver 1.0%s\n",COMPILER_VER);
  840.    fprintf (stderr,"  Copyright 1992 POV-Team\n");
  841.    fprintf (stderr,"  ----------------------------------------------------------------------\n");
  842.    fprintf (stderr,"  POV-Ray is based on DKBTrace 2.12 by David K. Buck & Aaron A. Collins.\n");
  843.    fprintf (stderr,"  \n");
  844.    fprintf (stderr,"  Contributing Authors: (Alphabetically)\n");
  845.    fprintf (stderr,"  \n");
  846.    fprintf (stderr,"  Steve A. Bennett   David K. Buck      Aaron A. Collins\n");
  847.    fprintf (stderr,"  Alexander Enzmann  Dan Farmer         Girish T. Hagan\n");
  848.    fprintf (stderr,"  Douglas Muir       Bill Pulver        Robert Skinner\n");
  849.    fprintf (stderr,"  Scott Taylor       Drew Wells         Chris Young\n");
  850.    fprintf (stderr,"  ----------------------------------------------------------------------\n");
  851.    fprintf (stderr,"  Other contributors listed in the documentation.\n");
  852. }
  853.