home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / RT / RMAIN.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  18KB  |  719 lines

  1. /* Copyright (c) 1992 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)rmain.c 2.15 11/8/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  rmain.c - main for ray tracing programs
  9.  *
  10.  *     3/24/87
  11.  */
  12.  
  13.                     /* for flaky pre-processors */
  14. #ifndef     RPICT
  15. #define     RPICT        0
  16. #endif
  17. #ifndef     RTRACE
  18. #define     RTRACE        0
  19. #endif
  20. #ifndef     RVIEW
  21. #define     RVIEW        0
  22. #endif
  23.  
  24. #include  "ray.h"
  25.  
  26. #include  "resolu.h"
  27.  
  28. #include  "octree.h"
  29.  
  30. #include  <signal.h>
  31.  
  32. #include  "view.h"
  33.  
  34. #include  "paths.h"
  35.  
  36. char  *progname;            /* argv[0] */
  37.  
  38. char  *octname;                /* octree name */
  39.  
  40. char  *libpath;                /* library directory list */
  41.  
  42. char  *sigerr[NSIG];            /* signal error messages */
  43.  
  44. extern char  VersionID[];        /* version ID string */
  45.  
  46. extern int  stderr_v();            /* standard error output */
  47. int  (*errvec)() = stderr_v;        /* error output vector */
  48. int  (*wrnvec)() = stderr_v;        /* warning output vector */
  49. int  (*cmdvec)() = NULL;        /* command error vector */
  50.  
  51. int  (*trace)() = NULL;            /* trace call */
  52. int  do_irrad = 0;            /* compute irradiance? */
  53.  
  54. extern long  time();
  55. long  tstart;                /* start time */
  56.  
  57. extern int  ambnotify();        /* new object notify functions */
  58. int  (*addobjnotify[])() = {ambnotify, NULL};
  59.  
  60. CUBE  thescene;                /* our scene */
  61. OBJECT    nsceneobjs;            /* number of objects in our scene */
  62.  
  63. extern int  imm_irrad;            /* calculate immediate irradiance? */
  64.  
  65. extern int  ralrm;            /* seconds between reports */
  66.  
  67. extern int  greyscale;            /* map colors to brightness? */
  68. extern char  *devname;            /* output device name */
  69.  
  70. extern char  *formstr();        /* string from format */
  71. extern int  inform;            /* input format */
  72. extern int  outform;            /* output format */
  73. extern char  *outvals;            /* output values */
  74.  
  75. extern VIEW  ourview;            /* viewing parameters */
  76.  
  77. extern int  hresolu;            /* horizontal resolution */
  78. extern int  vresolu;            /* vertical resolution */
  79. extern double  pixaspect;        /* pixel aspect ratio */
  80.  
  81. extern int  psample;            /* pixel sample size */
  82. extern double  maxdiff;            /* max. sample difference */
  83. extern double  dstrpix;            /* square pixel distribution */
  84.  
  85. extern double  dstrsrc;            /* square source distribution */
  86. extern double  shadthresh;        /* shadow threshold */
  87. extern double  shadcert;        /* shadow testing certainty */
  88. extern int  directrelay;        /* number of source relays */
  89. extern int  vspretest;            /* virtual source pretest density */
  90. extern int  directinvis;        /* light sources invisible to eye? */
  91. extern double  srcsizerat;        /* maximum source size/dist. ratio */
  92.  
  93. extern double  specthresh;        /* specular sampling threshold */
  94. extern double  specjitter;        /* specular sampling jitter */
  95.  
  96. extern int  maxdepth;            /* maximum recursion depth */
  97. extern double  minweight;        /* minimum ray weight */
  98.  
  99. extern COLOR  ambval;            /* ambient value */
  100. extern double  ambacc;            /* ambient accuracy */
  101. extern int  ambres;            /* ambient resolution */
  102. extern int  ambdiv;            /* ambient divisions */
  103. extern int  ambssamp;            /* ambient super-samples */
  104. extern int  ambounce;            /* ambient bounces */
  105. extern char  *amblist[];        /* ambient include/exclude list */
  106. extern int  ambincl;            /* include == 1, exclude == 0 */
  107.  
  108.  
  109. main(argc, argv)
  110. int  argc;
  111. char  *argv[];
  112. {
  113. #define     check(ol,al)        if (argv[i][ol] || \
  114.                 badarg(argc-i-1,argv+i+1,al)) \
  115.                 goto badopt
  116. #define     bool(olen,var)        switch (argv[i][olen]) { \
  117.                 case '\0': var = !var; break; \
  118.                 case 'y': case 'Y': case 't': case 'T': \
  119.                 case '+': case '1': var = 1; break; \
  120.                 case 'n': case 'N': case 'f': case 'F': \
  121.                 case '-': case '0': var = 0; break; \
  122.                 default: goto badopt; }
  123.     char  *err;
  124.     char  *recover = NULL;
  125.     char  *outfile = NULL;
  126.     char  *zfile = NULL;
  127.     char  *errfile = NULL;
  128.     char  *ambfile = NULL;
  129.     char  **amblp = amblist;
  130.     int  loadflags = ~IO_FILES;
  131.     int  seqstart = 0;
  132.     int  rval;
  133.     int  i;
  134.                     /* record start time */
  135.     tstart = time((long *)0);
  136.                     /* global program name */
  137.     progname = argv[0] = fixargv0(argv[0]);
  138.                     /* get library path */
  139.     if ((libpath = getenv(ULIBVAR)) == NULL)
  140.         libpath = DEFPATH;
  141.                     /* initialize object types */
  142.     initotypes();
  143.                     /* initialize urand */
  144.     initurand(2048);
  145.                     /* option city */
  146.     for (i = 1; i < argc; i++) {
  147.                         /* expand arguments */
  148.         while (rval = expandarg(&argc, &argv, i))
  149.             if (rval < 0) {
  150.                 sprintf(errmsg, "cannot expand '%s'", argv[i]);
  151.                 error(SYSTEM, errmsg);
  152.             }
  153.         if (argv[i] == NULL || argv[i][0] != '-')
  154.             break;            /* break from options */
  155.         if (!strcmp(argv[i], "-version")) {
  156.             puts(VersionID);
  157.             quit(0);
  158.         }
  159.         if (!strcmp(argv[i], "-defaults") ||
  160.                 !strcmp(argv[i], "-help")) {
  161.             printdefaults();
  162.             quit(0);
  163.         }
  164. #if  RVIEW
  165.         if (!strcmp(argv[i], "-devices")) {
  166.             printdevices();
  167.             quit(0);
  168.         }
  169. #endif
  170. #if  RPICT|RVIEW
  171.         rval = getviewopt(&ourview, argc-i, argv+i);
  172.         if (rval >= 0) {
  173.             i += rval;
  174.             continue;
  175.         }
  176. #endif
  177.         switch (argv[i][1]) {
  178. #if  RPICT|RVIEW
  179.         case 'v':                /* view file */
  180.             if (argv[i][2] != 'f')
  181.                 goto badopt;
  182.             check(3,"s");
  183.             rval = viewfile(argv[++i], &ourview, NULL);
  184.             if (rval < 0) {
  185.                 sprintf(errmsg,
  186.                 "cannot open view file \"%s\"",
  187.                         argv[i]);
  188.                 error(SYSTEM, errmsg);
  189.             } else if (rval == 0) {
  190.                 sprintf(errmsg,
  191.                     "bad view file \"%s\"",
  192.                         argv[i]);
  193.                 error(USER, errmsg);
  194.             }
  195.             break;
  196. #endif
  197.         case 'd':                /* direct */
  198.             switch (argv[i][2]) {
  199.             case 't':                /* threshold */
  200.                 check(3,"f");
  201.                 shadthresh = atof(argv[++i]);
  202.                 break;
  203.             case 'c':                /* certainty */
  204.                 check(3,"f");
  205.                 shadcert = atof(argv[++i]);
  206.                 break;
  207.             case 'j':                /* jitter */
  208.                 check(3,"f");
  209.                 dstrsrc = atof(argv[++i]);
  210.                 break;
  211.             case 'r':                /* relays */
  212.                 check(3,"i");
  213.                 directrelay = atoi(argv[++i]);
  214.                 break;
  215.             case 'p':                /* pretest */
  216.                 check(3,"i");
  217.                 vspretest = atoi(argv[++i]);
  218.                 break;
  219.             case 'i':                /* invis. */
  220.                 bool(3,directinvis);
  221.                 break;
  222.             case 's':                /* size */
  223.                 check(3,"f");
  224.                 srcsizerat = atof(argv[++i]);
  225.                 break;
  226.             default:
  227.                 goto badopt;
  228.             }
  229.             break;
  230.         case 's':                /* specular */
  231.             switch (argv[i][2]) {
  232.             case 't':                /* threshold */
  233.                 check(3,"f");
  234.                 specthresh = atof(argv[++i]);
  235.                 break;
  236.             case 'j':                /* jitter */
  237.                 check(3,"f");
  238.                 specjitter = atof(argv[++i]);
  239.                 break;
  240.             default:
  241.                 goto badopt;
  242.             }
  243.             break;
  244. #if  RPICT|RVIEW
  245.         case 'p':                /* pixel */
  246.             switch (argv[i][2]) {
  247.             case 's':                /* sample */
  248.                 check(3,"i");
  249.                 psample = atoi(argv[++i]);
  250.                 break;
  251.             case 't':                /* threshold */
  252.                 check(3,"f");
  253.                 maxdiff = atof(argv[++i]);
  254.                 break;
  255. #if  RPICT
  256.             case 'j':                /* jitter */
  257.                 check(3,"f");
  258.                 dstrpix = atof(argv[++i]);
  259.                 break;
  260.             case 'a':                /* aspect */
  261.                 check(3,"f");
  262.                 pixaspect = atof(argv[++i]);
  263.                 break;
  264. #endif
  265.             default:
  266.                 goto badopt;
  267.             }
  268.             break;
  269. #endif
  270. #if  RPICT|RTRACE
  271.         case 'x':                /* x resolution */
  272.             check(2,"i");
  273.             hresolu = atoi(argv[++i]);
  274.             break;
  275.         case 'y':                /* y resolution */
  276.             check(2,"i");
  277.             vresolu = atoi(argv[++i]);
  278.             break;
  279. #endif
  280.         case 'w':                /* warnings */
  281.             rval = wrnvec != NULL;
  282.             bool(2,rval);
  283.             if (rval) wrnvec = stderr_v;
  284.             else wrnvec = NULL;
  285.             break;
  286.         case 'e':                /* error file */
  287.             check(2,"s");
  288.             errfile = argv[++i];
  289.             break;
  290.         case 'l':                /* limit */
  291.             switch (argv[i][2]) {
  292.             case 'r':                /* recursion */
  293.                 check(3,"i");
  294.                 maxdepth = atoi(argv[++i]);
  295.                 break;
  296.             case 'w':                /* weight */
  297.                 check(3,"f");
  298.                 minweight = atof(argv[++i]);
  299.                 break;
  300.             default:
  301.                 goto badopt;
  302.             }
  303.             break;
  304.         case 'i':                /* irradiance */
  305.             bool(2,do_irrad);
  306.             break;
  307. #if  RPICT
  308.         case 'S':                /* slave index */
  309.             check(2,"i");
  310.             seqstart = atoi(argv[++i]);
  311.             break;
  312.         case 'o':                /* output file */
  313.             check(2,"s");
  314.             outfile = argv[++i];
  315.             break;
  316.         case 'z':                /* z file */
  317.             check(2,"s");
  318.             zfile = argv[++i];
  319.             break;
  320.         case 'r':                /* recover file */
  321.             check(2,"s");
  322.             recover = argv[++i];
  323.             break;
  324.         case 't':                /* timer */
  325.             check(2,"i");
  326.             ralrm = atoi(argv[++i]);
  327.             break;
  328. #endif
  329.         case 'a':                /* ambient */
  330.             switch (argv[i][2]) {
  331.             case 'v':                /* value */
  332.                 check(3,"fff");
  333.                 setcolor(ambval, atof(argv[i+1]),
  334.                         atof(argv[i+2]),
  335.                         atof(argv[i+3]));
  336.                 i += 3;
  337.                 break;
  338.             case 'a':                /* accuracy */
  339.                 check(3,"f");
  340.                 ambacc = atof(argv[++i]);
  341.                 break;
  342.             case 'r':                /* resolution */
  343.                 check(3,"i");
  344.                 ambres = atoi(argv[++i]);
  345.                 break;
  346.             case 'd':                /* divisions */
  347.                 check(3,"i");
  348.                 ambdiv = atoi(argv[++i]);
  349.                 break;
  350.             case 's':                /* super-samp */
  351.                 check(3,"i");
  352.                 ambssamp = atoi(argv[++i]);
  353.                 break;
  354.             case 'b':                /* bounces */
  355.                 check(3,"i");
  356.                 ambounce = atoi(argv[++i]);
  357.                 break;
  358.             case 'i':                /* include */
  359.             case 'I':
  360.                 check(3,"s");
  361.                 if (ambincl != 1) {
  362.                     ambincl = 1;
  363.                     amblp = amblist;
  364.                 }
  365.                 if (argv[i][2] == 'I') {    /* file */
  366.                     rval = wordfile(amblp,
  367.                     getpath(argv[++i],libpath,R_OK));
  368.                     if (rval < 0) {
  369.                         sprintf(errmsg,
  370.                 "cannot open ambient include file \"%s\"",
  371.                                 argv[i]);
  372.                         error(SYSTEM, errmsg);
  373.                     }
  374.                     amblp += rval;
  375.                 } else
  376.                     *amblp++ = argv[++i];
  377.                 break;
  378.             case 'e':                /* exclude */
  379.             case 'E':
  380.                 check(3,"s");
  381.                 if (ambincl != 0) {
  382.                     ambincl = 0;
  383.                     amblp = amblist;
  384.                 }
  385.                 if (argv[i][2] == 'E') {    /* file */
  386.                     rval = wordfile(amblp,
  387.                     getpath(argv[++i],libpath,R_OK));
  388.                     if (rval < 0) {
  389.                         sprintf(errmsg,
  390.                 "cannot open ambient exclude file \"%s\"",
  391.                                 argv[i]);
  392.                         error(SYSTEM, errmsg);
  393.                     }
  394.                     amblp += rval;
  395.                 } else
  396.                     *amblp++ = argv[++i];
  397.                 break;
  398.             case 'f':                /* file */
  399.                 check(3,"s");
  400.                 ambfile= argv[++i];
  401.                 break;
  402.             default:
  403.                 goto badopt;
  404.             }
  405.             break;
  406. #if  RTRACE
  407.         case 'I':                /* immed. irradiance */
  408.             bool(2,imm_irrad);
  409.             break;
  410.         case 'f':                /* format i/o */
  411.             switch (argv[i][2]) {
  412.             case 'a':                /* ascii */
  413.             case 'f':                /* float */
  414.             case 'd':                /* double */
  415.                 inform = argv[i][2];
  416.                 break;
  417.             default:
  418.                 goto badopt;
  419.             }
  420.             switch (argv[i][3]) {
  421.             case '\0':
  422.                 outform = inform;
  423.                 break;
  424.             case 'a':                /* ascii */
  425.             case 'f':                /* float */
  426.             case 'd':                /* double */
  427.             case 'c':                /* color */
  428.                 check(4,"");
  429.                 outform = argv[i][3];
  430.                 break;
  431.             default:
  432.                 goto badopt;
  433.             }
  434.             break;
  435.         case 'o':                /* output */
  436.             outvals = argv[i]+2;
  437.             break;
  438.         case 'h':                /* header output */
  439.             rval = loadflags & IO_INFO;
  440.             bool(2,rval);
  441.             loadflags = rval ? loadflags | IO_INFO :
  442.                     loadflags & ~IO_INFO;
  443.             break;
  444. #endif
  445. #if  RVIEW
  446.         case 'b':                /* black and white */
  447.             bool(2,greyscale);
  448.             break;
  449.         case 'o':                /* output device */
  450.             check(2,"s");
  451.             devname = argv[++i];
  452.             break;
  453. #endif
  454.         default:
  455.             goto badopt;
  456.         }
  457.     }
  458.     *amblp = NULL;
  459. #if  RPICT|RVIEW
  460.     err = setview(&ourview);    /* set viewing parameters */
  461.     if (err != NULL)
  462.         error(USER, err);
  463. #endif
  464.                     /* set up signal handling */
  465.     sigdie(SIGINT, "Interrupt");
  466.     sigdie(SIGHUP, "Hangup");
  467.     sigdie(SIGTERM, "Terminate");
  468.     sigdie(SIGPIPE, "Broken pipe");
  469.     sigdie(SIGALRM, "Alarm clock");
  470. #ifdef    SIGXCPU
  471.     sigdie(SIGXCPU, "CPU limit exceeded");
  472.     sigdie(SIGXFSZ, "File size exceeded");
  473. #endif
  474.                     /* open error file */
  475.     if (errfile != NULL) {
  476.         if (freopen(errfile, "a", stderr) == NULL)
  477.             quit(2);
  478.         fprintf(stderr, "**************\n*** PID %5d: ",
  479.                 getpid());
  480.         printargs(argc, argv, stderr);
  481.         putc('\n', stderr);
  482.         fflush(stderr);
  483.     }
  484. #ifdef    NICE
  485.     nice(NICE);            /* lower priority */
  486. #endif
  487.                     /* get octree */
  488. #if  RVIEW
  489.     loadflags &= ~IO_INFO;
  490. #endif
  491.     if (i == argc)
  492.         octname = NULL;
  493.     else if (i == argc-1)
  494.         octname = argv[i];
  495.     else
  496.         goto badopt;
  497.     if (
  498. #if  RPICT
  499.         seqstart > 0 &&
  500. #endif
  501.             octname == NULL)
  502.         error(USER, "missing octree argument");
  503. #if  RPICT
  504.     if (outfile != NULL)
  505.         openheader();
  506. #endif
  507. #ifdef    MSDOS
  508. #if  RTRACE
  509.     if (outform != 'a')
  510. #endif
  511.     setmode(fileno(stdout), O_BINARY);
  512.     if (octname == NULL)
  513.         setmode(fileno(stdin), O_BINARY);
  514. #endif
  515.     readoct(octname, loadflags, &thescene, NULL);
  516.     nsceneobjs = nobjects;
  517.  
  518.     if (loadflags & IO_INFO) {    /* print header */
  519.         printargs(i, argv, stdout);
  520.         printf("SOFTWARE= %s\n", VersionID);
  521. #if  RTRACE
  522.         fputformat(formstr(outform), stdout);
  523.         putchar('\n');
  524. #endif
  525.     }
  526.  
  527.     marksources();            /* find and mark sources */
  528.  
  529.     setambient(ambfile);        /* initialize ambient calculation */
  530.  
  531. #if  RPICT
  532.     rpict(seqstart, outfile, zfile, recover);
  533. #endif
  534. #if  RTRACE
  535.     rtrace(NULL);
  536. #endif
  537. #if  RVIEW
  538.     rview();
  539. #endif
  540.     quit(0);
  541.  
  542. badopt:
  543.     sprintf(errmsg, "command line error at '%s'", argv[i]);
  544.     error(USER, errmsg);
  545.  
  546. #undef    check
  547. #undef    bool
  548. }
  549.  
  550.  
  551. eputs(s)                /* error output */
  552. char  *s;
  553. {
  554.     if (errvec != NULL)
  555.         (*errvec)(s);
  556. }
  557.  
  558.  
  559. wputs(s)                /* warning output */
  560. char  *s;
  561. {
  562.     int  lasterrno = errno;        /* save errno */
  563.  
  564.     if (wrnvec != NULL)
  565.         (*wrnvec)(s);
  566.  
  567.     errno = lasterrno;
  568. }
  569.  
  570.  
  571. cputs(s)                /* command error output */
  572. char  *s;
  573. {
  574.     if (cmdvec != NULL)
  575.         (*cmdvec)(s);
  576. }
  577.  
  578.  
  579. stderr_v(s)                /* put string to stderr */
  580. register char  *s;
  581. {
  582.     static int  midline = 0;
  583.  
  584.     if (!*s)
  585.         return;
  586.     if (!midline++) {
  587.         fputs(progname, stderr);
  588.         fputs(": ", stderr);
  589.     }
  590.     fputs(s, stderr);
  591.     if (s[strlen(s)-1] == '\n') {
  592.         fflush(stderr);
  593.         midline = 0;
  594.     }
  595. }
  596.  
  597.  
  598. onsig(signo)                /* fatal signal */
  599. int  signo;
  600. {
  601.     static int  gotsig = 0;
  602.  
  603.     if (gotsig++)            /* two signals and we're gone! */
  604.         _exit(signo);
  605.  
  606.     alarm(15);            /* allow 15 seconds to clean up */
  607.     signal(SIGALRM, SIG_DFL);    /* make certain we do die */
  608.     eputs("signal - ");
  609.     eputs(sigerr[signo]);
  610.     eputs("\n");
  611.     quit(3);
  612. }
  613.  
  614.  
  615. sigdie(signo, msg)            /* set fatal signal */
  616. int  signo;
  617. char  *msg;
  618. {
  619.     if (signal(signo, onsig) == SIG_IGN)
  620.         signal(signo, SIG_IGN);
  621.     sigerr[signo] = msg;
  622. }
  623.  
  624.  
  625. printdefaults()            /* print default values to stdout */
  626. {
  627.     register char  *cp;
  628.  
  629. #if  RTRACE
  630.     if (imm_irrad)
  631.         printf("-I+\t\t\t\t# immediate irradiance on\n");
  632.     else
  633. #endif
  634.     printf(do_irrad ? "-i+\t\t\t\t# irradiance calculation on\n" :
  635.             "-i-\t\t\t\t# irradiance calculation off\n");
  636. #if  RVIEW
  637.     printf(greyscale ? "-b+\t\t\t\t# greyscale on\n" :
  638.             "-b-\t\t\t\t# greyscale off\n");
  639. #endif
  640. #if  RPICT|RVIEW
  641.     printf("-vt%c\t\t\t\t# view type %s\n", ourview.type,
  642.             ourview.type==VT_PER ? "perspective" :
  643.             ourview.type==VT_PAR ? "parallel" :
  644.             ourview.type==VT_HEM ? "hemispherical" :
  645.             ourview.type==VT_ANG ? "angular" :
  646.             "unknown");
  647.     printf("-vp %f %f %f\t# view point\n",
  648.             ourview.vp[0], ourview.vp[1], ourview.vp[2]);
  649.     printf("-vd %f %f %f\t# view direction\n",
  650.             ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
  651.     printf("-vu %f %f %f\t# view up\n",
  652.             ourview.vup[0], ourview.vup[1], ourview.vup[2]);
  653.     printf("-vh %f\t\t\t# view horizontal size\n", ourview.horiz);
  654.     printf("-vv %f\t\t\t# view vertical size\n", ourview.vert);
  655.     printf("-vs %f\t\t\t# view shift\n", ourview.hoff);
  656.     printf("-vl %f\t\t\t# view lift\n", ourview.voff);
  657. #endif
  658. #if  RPICT|RTRACE
  659.     printf("-x  %-9d\t\t\t# x resolution\n", hresolu);
  660.     printf("-y  %-9d\t\t\t# y resolution\n", vresolu);
  661. #endif
  662. #if  RPICT
  663.     printf("-pa %f\t\t\t# pixel aspect ratio\n", pixaspect);
  664.     printf("-pj %f\t\t\t# pixel jitter\n", dstrpix);
  665. #endif
  666. #if  RPICT|RVIEW
  667.     printf("-ps %-9d\t\t\t# pixel sample\n", psample);
  668.     printf("-pt %f\t\t\t# pixel threshold\n", maxdiff);
  669. #endif
  670.     printf("-dt %f\t\t\t# direct threshold\n", shadthresh);
  671.     printf("-dc %f\t\t\t# direct certainty\n", shadcert);
  672.     printf("-dj %f\t\t\t# direct jitter\n", dstrsrc);
  673.     printf("-ds %f\t\t\t# direct sampling\n", srcsizerat);
  674.     printf("-dr %-9d\t\t\t# direct relays\n", directrelay);
  675.     printf("-dp %-9d\t\t\t# direct pretest density\n", vspretest);
  676.     printf(directinvis ? "-di+\t\t\t\t# direct invisibility on\n" :
  677.             "-di-\t\t\t\t# direct invisibility off\n");
  678.     printf("-sj %f\t\t\t# specular jitter\n", specjitter);
  679.     printf("-st %f\t\t\t# specular threshold\n", specthresh);
  680.     printf("-av %f %f %f\t# ambient value\n", colval(ambval,RED),
  681.             colval(ambval,GRN), colval(ambval, BLU));
  682.     printf("-ab %-9d\t\t\t# ambient bounces\n", ambounce);
  683.     printf("-aa %f\t\t\t# ambient accuracy\n", ambacc);
  684.     printf("-ar %-9d\t\t\t# ambient resolution\n", ambres);
  685.     printf("-ad %-9d\t\t\t# ambient divisions\n", ambdiv);
  686.     printf("-as %-9d\t\t\t# ambient super-samples\n", ambssamp);
  687.     printf("-lr %-9d\t\t\t# limit reflection\n", maxdepth);
  688.     printf("-lw %f\t\t\t# limit weight\n", minweight);
  689. #if  RPICT
  690.     printf("-t  %-9d\t\t\t# time between reports\n", ralrm);
  691. #endif
  692. #if  RVIEW
  693.     printf("-o %s\t\t\t\t# output device\n", devname);
  694. #endif
  695. #if  RTRACE
  696.     printf("-f%c%c\t\t\t\t# format input/output = %s/%s\n",
  697.             inform, outform, formstr(inform), formstr(outform));
  698.     printf("-o%s\t\t\t\t# output", outvals);
  699.     for (cp = outvals; *cp; cp++)
  700.         switch (*cp) {
  701.         case 't': printf(" trace"); break;
  702.         case 'o': printf(" origin"); break;
  703.         case 'd': printf(" direction"); break;
  704.         case 'v': printf(" value"); break;
  705.         case 'l': printf(" length"); break;
  706.         case 'L': printf(" first_length"); break;
  707.         case 'p': printf(" point"); break;
  708.         case 'n': printf(" normal"); break;
  709.         case 'N': printf(" unperturbed_normal"); break;
  710.         case 's': printf(" surface"); break;
  711.         case 'w': printf(" weight"); break;
  712.         case 'm': printf(" modifier"); break;
  713.         }
  714.     putchar('\n');
  715. #endif
  716.     printf(wrnvec != NULL ? "-w+\t\t\t\t# warning messages on\n" :
  717.             "-w-\t\t\t\t# warning messages off\n");
  718. }
  719.