home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / graphics / utility / qrt.lzh / QRT / INOUT.C (.txt) < prev    next >
C/C++ Source or Header  |  1989-02-16  |  24KB  |  1,119 lines

  1.  
  2. /**********************************************************
  3.  
  4.                     object loader language
  5.  
  6.  **********************************************************/
  7.  
  8. #define IODEBUG 1
  9.  
  10. #include "qrt.h"
  11. #include "pattern.h"
  12.  
  13. OBJ_PTR      new_obj(), Get_Object(), Get_Primitive(),
  14.              Get_Instance_Of();
  15. PATTERN_PTR  Attach_Pattern(), Get_Pattern();
  16. char         *malloc();
  17.  
  18. # ifdef AMIGA
  19.     float      atof();
  20. # endif
  21.  
  22. /**********************************************************
  23.  
  24.              External declarations from lexer
  25.  
  26.  **********************************************************/
  27.  
  28. float IsPos();
  29. float Get_Next_Num();
  30. short Get_Color_Val();
  31. char *Get_Next_Name();
  32.  
  33.  
  34.  
  35. /**********************************************************
  36.  
  37.    Global input line number.  If negative, error rountines
  38.    will not report line number (already reached EOF).
  39.  
  40.  **********************************************************/
  41.  
  42. extern int linenumber;
  43.  
  44. /**********************************************************
  45.  
  46.           Load the entire world from standard input
  47.  
  48.  **********************************************************/
  49.  
  50. int LoadWorld()                      /* load world from stdio */
  51. {
  52.   linenumber = 1;
  53.   if((THEWORLD.stack=Get_Object())==NULL)
  54.     Error(ILLEGAL_OBJECT,201);
  55.  
  56.   linenumber = -1;
  57.   return(TRUE);
  58. }
  59.  
  60. /**********************************************************
  61.  
  62.      Get an object and return a pointer to it. If it is
  63.      not an object, but some other world attribute
  64.      specification, note it, but keep trying until an
  65.      object is found or end of input is encountered.
  66.      This is slighly hacked out, but it works for now.
  67.      It calls itself recursively sometimes.
  68.  
  69.  **********************************************************/
  70.  
  71. OBJ_PTR Get_Object() {
  72.   char str[SLEN], *name;
  73.   OBJ_PTR newobj, queue, temp;
  74.   VECTOR loc,rad,d,v3, upper, lower;
  75.   CINFO cinfo;
  76.   int found;
  77.  
  78.   name=NULL; queue=NULL;
  79.   VectEqZero(&loc);
  80.   VectEqZero(&rad);
  81.   VectEqZero(&d);
  82.   VectEqZero(&v3);
  83.   VectEqZero(&upper);
  84.   VectEqZero(&lower);
  85.  
  86.   if (feof(stdin)) return(NULL);
  87.   while (!feof(stdin)) {
  88.     GetToken(str); found = FALSE;
  89.  
  90. #   ifdef IODEBUG
  91.       printf("GETOBJECT: token=%s\n",str);
  92. #   endif
  93.  
  94.     if (GetAttrib(str))
  95.       found = TRUE;
  96.  
  97.     if (strcmp(str,"BEGIN_INSTANCES")==0) {
  98.       found = TRUE;
  99.       THEWORLD.instances = Get_Object();
  100.     }
  101.  
  102.     if (strcmp(str,"END_INSTANCES")==0) {
  103. #     ifdef ROBUST
  104.         if (queue==NULL) Error(SYNTAX_ERROR,205);
  105. #     endif
  106.       found = TRUE;
  107.       return(queue);
  108.     }
  109.  
  110.     if (strcmp(str,"END_BBOX")==0) {
  111. #     ifdef ROBUST
  112.         if (queue==NULL) Error(SYNTAX_ERROR,206);
  113. #     endif
  114.       found = TRUE;
  115.       return(queue);
  116.     }
  117.  
  118.     if (strcmp(str,"BEGIN_BBOX")==0) {
  119.  
  120.        newobj=new_obj(BBOX,&loc,&rad,&d,&v3,&cinfo,NULL,NULL,name,
  121.                       &upper, &lower,
  122.                       (float)0.0, (float)0.0, (float)0.0);
  123.  
  124.        newobj->child = Get_Object();
  125.        newobj->nextobj = queue;
  126.        queue = newobj;
  127.        found = TRUE;
  128.  
  129.     }
  130.  
  131.     if (strcmp(str,"NAME")==0) {
  132.        name=Get_Next_Name();
  133.        found = TRUE;
  134.     }
  135.  
  136.     if ((temp=Get_Primitive(str))!=NULL) {
  137.       found = TRUE;
  138.       temp->nextobj=queue;
  139.       queue = temp;
  140.     }
  141.  
  142.     if (!found && !feof(stdin)) Error(SYNTAX_ERROR,207);
  143.  
  144.   }
  145.  
  146.   return(queue);
  147. }
  148.  
  149.  
  150. /**********************************************************
  151.  
  152.                  Load default color info
  153.  
  154.  **********************************************************/
  155.  
  156. def_colorinfo(cinfo)
  157.   CINFO_PTR cinfo;
  158. {
  159.   copy_colorinfo(cinfo,&(def.cinfo));
  160. }
  161.  
  162.  
  163. /**********************************************************
  164.  
  165.                     Copy color info
  166.  
  167.  **********************************************************/
  168.  
  169. copy_colorinfo(c1,c2)
  170.   CINFO_PTR c1,c2;
  171. {
  172.   if (c1 == NULL) return;
  173.  
  174.   SVectEQ(&(c1->amb),&(c2->amb));
  175.   SVectEQ(&(c1->diff),&(c2->diff));
  176.   SVectEQ(&(c1->mirror),&(c2->mirror));
  177.   SVectEQ(&(c1->trans),&(c2->trans));
  178.   VectEQ(&(c1->density),&(c2->density));
  179.  
  180.   c1->fuzz     = c2->fuzz;
  181.   c1->index    = c2->index;
  182.   c1->dither   = c2->dither;
  183.   c1->sreflect = c2->sreflect;
  184.   c1->reflect  = c2->reflect;
  185. }
  186.  
  187.  
  188. /**********************************************************
  189.  
  190.             Get defaults from input file
  191.  
  192.  **********************************************************/
  193.  
  194. int Get_Default()
  195. {
  196.   char        str[SLEN];
  197.   int         end, found;
  198.  
  199.   end=0;
  200.  
  201.   GetLeftParen();
  202.  
  203.   while (!end && !feof(stdin)) {
  204.     GetToken(str);
  205.  
  206. #   ifdef IODEBUG
  207.       printf("GETDEFAULT : token=%s\n",str);
  208. #   endif
  209.  
  210.     found = GetOpt(str,&(def.cinfo));
  211.  
  212.     if (strcmp(str,"NO_SHADOW")==0) {
  213.       def.shadow = FALSE;
  214.       found = TRUE;
  215.     }
  216.  
  217.     if (strcmp(str,"NO_LAMP")==0) {
  218.       def.vlamp = FALSE;
  219.       found = TRUE;
  220.     }
  221.  
  222.     if (strcmp(str,"THRESHOLD")==0) {
  223.       def.threshold = IsPos(Get_Next_Num());
  224.       found = TRUE;
  225.     }
  226.  
  227.     if (strcmp(str,")")==0) { end = 1; found = TRUE;}
  228.  
  229.     if (!found) Error(UNDEFINED_PARAM,209);
  230.   }
  231.   return(TRUE);
  232. }
  233.  
  234.  
  235. /**********************************************************
  236.  
  237.                     Get object options
  238.  
  239.  **********************************************************/
  240.  
  241. int GetOpt(str,cinfo)
  242.   char str[];
  243.   CINFO_PTR cinfo;
  244. {
  245.   int found;
  246.  
  247.   found = FALSE;
  248.  
  249.   if (strcmp(str,"AMB")==0) {
  250.     GetSVector(&(cinfo->amb));
  251.     found = TRUE;
  252.   }
  253.  
  254.   if (strcmp(str,"DIFF")==0) {
  255.     GetSVector(&(cinfo->diff));
  256.     found = TRUE;
  257.   }
  258.  
  259.   if (strcmp(str,"MIRROR")==0) {
  260.     GetSVector(&(cinfo->mirror));
  261.     found = TRUE;
  262.   }
  263.  
  264.   if (strcmp(str,"TRANS")==0) {
  265.     GetSVector(&(cinfo->trans));
  266.     found = TRUE;
  267.   }
  268.  
  269.   if (strcmp(str,"DENSITY")==0) {
  270.     GetVector(&(cinfo->density));
  271.     found = TRUE;
  272.   }
  273.  
  274.   if (strcmp(str,"FUZZ")==0) {
  275.     cinfo->fuzz     = Get_Color_Val();
  276.     found = TRUE;
  277.   }
  278.  
  279.   if (strcmp(str,"INDEX")==0) {
  280.     cinfo->index    = IsPos(Get_Next_Num());
  281.     found = TRUE;
  282.   }
  283.   if (strcmp(str,"DITHER")==0) {
  284.     cinfo->dither   = (short)IsPos(Get_Next_Num());
  285.     found = TRUE;
  286.   }
  287.   if (strcmp(str,"SREFLECT")==0) {
  288.     cinfo->sreflect = IsPos(Get_Next_Num());
  289.     found = TRUE;
  290.   }
  291.   if (strcmp(str,"REFLECT")==0) {
  292.     cinfo->reflect = Get_Color_Val();
  293.     found = TRUE;
  294.   }
  295.  
  296.   return(found);
  297. }
  298.  
  299.  
  300. /**********************************************************
  301.  
  302.           Load a sphere and return pointer to it
  303.  
  304.  **********************************************************/
  305.  
  306. OBJ_PTR GetSphere()
  307. {
  308.   char        str[SLEN], *name;
  309.   VECTOR      loc, rad, d, v3, upper, lower;
  310.   float       xmult, ymult;
  311.   CINFO       cinfo;
  312.   OBJ_PTR     newobj;
  313.   PATTERN_PTR pattern, remove;
  314.   int         end, f, found;
  315.  
  316.   end=f=0;
  317.   def_colorinfo(&cinfo);
  318.   xmult=ymult=1;
  319.   pattern = remove = NULL;
  320.   name    = NULL;
  321.  
  322.   GetLeftParen();
  323.  
  324.   while (!end && !feof(stdin)) {
  325.     GetToken(str);
  326.  
  327. #   ifdef IODEBUG
  328.       printf("GETSPHERE : token=%s\n",str);
  329. #   endif
  330.  
  331.     found = GetOpt(str,&cinfo);
  332.  
  333.     if ((strcmp(str,"POS")==0)      ||
  334.         (strcmp(str,"LOC")==0)      ||
  335.         (strcmp(str,"POSITION")==0) ||
  336.         (strcmp(str,"LOCATION")==0)) {
  337.  
  338.       GetVector(&loc);
  339.       f|=1; found = TRUE;
  340.     }
  341.  
  342.     if (strcmp(str,"RADIUS")==0) {
  343.       rad.x = IsPos(Get_Next_Num());
  344.       f|=2; found = TRUE;
  345.     }
  346.     if (strcmp(str,"PATTERN")==0) {
  347.       pattern = Attach_Pattern();
  348.       found = TRUE;
  349.     }
  350.     if (strcmp(str,"REMOVE")==0) {
  351.       remove = Attach_Pattern();
  352.       found = TRUE;
  353.     }
  354.     if (strcmp(str,"XMULT")==0) {
  355.       xmult = IsPos(Get_Next_Num());
  356.       found=TRUE;
  357.     }
  358.     if (strcmp(str,"YMULT")==0) {
  359.       ymult = IsPos(Get_Next_Num());
  360.       found=TRUE;
  361.     }
  362.     if (strcmp(str,"NAME")==0) {
  363.        name=Get_Next_Name();
  364.        found = TRUE;
  365.     }
  366.  
  367.     if (strcmp(str,")")==0) { end = 1; found = TRUE; }
  368.  
  369.     if (!found) Error(UNDEFINED_PARAM,211);
  370.   }
  371.  
  372.   if (f!=3) Error(TOO_FEW_PARMS,212);
  373.   rad.y=rad.z=0;
  374.  
  375.   VectEqZero(&d);
  376.   VectEqZero(&upper);
  377.   VectEqZero(&lower);
  378.  
  379.   newobj=new_obj(SPHERE,&loc,&rad,&d,&v3,&cinfo,pattern,
  380.                  remove,name,
  381.                  &upper, &lower, 0.0, xmult, ymult);
  382.  
  383.   THEWORLD.objcount++;
  384.   return(newobj);
  385. }
  386.  
  387.  
  388. /**********************************************************
  389.  
  390.              Load lamp and attach to world
  391.  
  392.  **********************************************************/
  393.  
  394. int GetLamp()
  395. {
  396.   char str[SLEN];
  397.   VECTOR loc, rad, d, v3, upper, lower;
  398.   CINFO cinfo;
  399.   int   end, f, found;
  400.  
  401.   end=f=0;
  402.  
  403.   cinfo.amb.r=cinfo.amb.g=cinfo.amb.b=CNUM;
  404.   rad.y=150;
  405.  
  406.   GetLeftParen();
  407.  
  408.   while (!end && !feof(stdin)) {
  409.     GetToken(str); found = TRUE;
  410.  
  411. #   ifdef IODEBUG
  412.       printf("GETLAMP : token=%s\n",str);
  413. #   endif
  414.  
  415.     found = GetOpt(str,&cinfo);
  416.  
  417.     if ((strcmp(str,"POS")==0)      ||
  418.         (strcmp(str,"LOC")==0)      ||
  419.         (strcmp(str,"POSITION")==0) ||
  420.         (strcmp(str,"LOCATION")==0)) {
  421.  
  422.       GetVector(&loc);
  423.       f|=1; found = TRUE;
  424.     }
  425.  
  426.     if (strcmp(str,"RADIUS")==0) {
  427.       rad.x = IsPos(Get_Next_Num());
  428.       f|=2; found = TRUE;
  429.     }
  430.     if (strcmp(str,"DIST")==0) {
  431.       rad.y = IsPos(Get_Next_Num());
  432.       f|=4; found = TRUE;
  433.     }
  434.     if (strcmp(str,")")==0) { end = 1; found = TRUE;}
  435.  
  436.     if (!found) Error(UNDEFINED_PARAM,214);
  437.   }
  438.  
  439.   if (f!=7) return(FALSE);
  440.  
  441.   rad.z=0;
  442.  
  443.   VectEqZero(&d);
  444.   VectEqZero(&v3);
  445.   VectEqZero(&upper);
  446.   VectEqZero(&lower);
  447.  
  448.   cinfo.diff.r=cinfo.diff.g=cinfo.diff.b=CNUM;
  449.  
  450.   add_lamp(new_obj(LAMP,&loc,&rad,&d,&v3,&cinfo,NULL,NULL,
  451.                    NULL, &upper, &lower,
  452.                    (float)0.0, (float)0.0, (float)0.0));
  453.  
  454.   THEWORLD.lampcount++;
  455.   return(TRUE);
  456. }
  457.  
  458.  
  459. /**********************************************************
  460.  
  461.          Load observer and attach him to the world
  462.  
  463.  **********************************************************/
  464.  
  465. int GetObserver()
  466. {
  467.   char   str[SLEN];
  468.   VECTOR loc, lk, up, dir, v3, upper, lower;
  469.   CINFO  cinfo;
  470.   int    end, f, found;
  471.  
  472.   end=f=0;
  473.   up.x = up.z = 0; up.y = 1;
  474.  
  475.   GetLeftParen();
  476.  
  477.   while (!end && !feof(stdin)) {
  478.     GetToken(str); found = FALSE;
  479.  
  480. #   ifdef IODEBUG
  481.       printf("GETOBSERVER : token=%s\n",str);
  482. #   endif
  483.  
  484.     if ((strcmp(str,"POS")==0)      ||
  485.         (strcmp(str,"LOC")==0)      ||
  486.         (strcmp(str,"POSITION")==0) ||
  487.         (strcmp(str,"LOCATION")==0)) {
  488.  
  489.       GetVector(&loc);
  490.       f|=1; found = TRUE;
  491.     }
  492.  
  493.     if (strcmp(str,"LOOKAT")==0) {
  494.       GetVector(&lk);
  495.       f|=2; found = TRUE;
  496.     }
  497.  
  498.     if (strcmp(str,"UP")==0) {
  499.       GetVector(&up);
  500.       found = TRUE;
  501.     }
  502.  
  503.     if (strcmp(str,")")==0) { end = 1; found = TRUE; }
  504.  
  505.     if (!found) Error(UNDEFINED_PARAM,216);
  506.   }
  507.  
  508.   VecSubtract(&dir,&lk,&loc);    /* find view direction */
  509.  
  510.   VectEqZero(&v3);
  511.   VectEqZero(&upper);
  512.   VectEqZero(&lower);
  513.  
  514.   if (f!=3) Error(TOO_FEW_PARMS,217);
  515.  
  516.   THEWORLD.observer=
  517.      new_obj(OBSERVER,&loc,&dir,&up,&v3,&cinfo,NULL,NULL,
  518.              NULL, &upper, &lower,
  519.              (float)0.0, (float)0.0, (float)0.0);
  520.  
  521.   return(TRUE);
  522. }
  523.  
  524.  
  525. /**********************************************************
  526.  
  527.           Load triangle  - not yet implimented
  528.  
  529.  **********************************************************/
  530.  
  531. OBJ_PTR GetTriangle()
  532. {
  533.   char        str[SLEN], *name;
  534.   CINFO       cinfo;
  535.   VECTOR      loc, v1, v2, v3, upper, lower;
  536.   OBJ_PTR     newobj;
  537.   PATTERN_PTR pattern, remove;
  538.   int         end, f, found;
  539.   float       xmult, ymult;
  540.  
  541.   end=f=0;
  542.   xmult=ymult=1;
  543.   def_colorinfo(&cinfo);
  544.   pattern = remove = NULL;
  545.   name    = NULL;
  546.  
  547.   GetLeftParen();
  548.  
  549.   while (!end && !feof(stdin)) {
  550.     GetToken(str);
  551.  
  552. #   ifdef IODEBUG
  553.       printf("GETTRIANGLE : token=%s\n",str);
  554. #   endif
  555.  
  556.     found = GetOpt(str,&cinfo);
  557.  
  558.     if ((strcmp(str,"POS")==0)      ||
  559.         (strcmp(str,"LOC")==0)      ||
  560.         (strcmp(str,"POSITION")==0) ||
  561.         (strcmp(str,"LOCATION")==0)) {
  562.  
  563.       GetVector(&loc);
  564.       f|=1; found = TRUE;
  565.     }
  566.  
  567.     if ((strcmp(str,"V1")==0)     ||
  568.         (strcmp(str,"VECT1")==0)) {
  569.  
  570.       GetVector(&v1);
  571.       f|=2; found = TRUE;
  572.     }
  573.  
  574.     if ((strcmp(str,"V2")==0)     ||
  575.         (strcmp(str,"VECT2")==0)) {
  576.  
  577.       GetVector(&v2);
  578.       f|=4; found = TRUE;
  579.     }
  580.  
  581.     if (strcmp(str,"PATTERN")==0) {
  582.       pattern=Attach_Pattern();
  583.       found = TRUE;
  584.     }
  585.     if (strcmp(str,"REMOVE")==0) {
  586.       remove=Attach_Pattern();
  587.       found = TRUE;
  588.     }
  589.  
  590.     if (strcmp(str,"XMULT")==0) {
  591.       xmult = IsPos(Get_Next_Num());
  592.       found=TRUE;
  593.     }
  594.     if (strcmp(str,"YMULT")==0) {
  595.       ymult = IsPos(Get_Next_Num());
  596.       found=TRUE;
  597.     }
  598.     if (strcmp(str,"NAME")==0) {
  599.        name=Get_Next_Name();
  600.        found = TRUE;
  601.     }
  602.  
  603.     if (strcmp(str,")")==0) { end = 1; found = TRUE;}
  604.  
  605.     if (!found) Error(UNDEFINED_PARAM,219);
  606.   }
  607.  
  608.   if (f!=7) Error(TOO_FEW_PARMS,220);
  609.  
  610.   VectEqZero(&v3);
  611.   VectEqZero(&upper);
  612.   VectEqZero(&lower);
  613.  
  614.   newobj=new_obj(TRIANGLE,&loc,&v1,&v2,&v3,&cinfo,pattern,
  615.                  remove, name,
  616.                  &upper, &lower, 0.0, xmult, ymult);
  617.  
  618.   THEWORLD.objcount++;
  619.   return(newobj);
  620. }
  621.  
  622.  
  623. /**********************************************************
  624.  
  625.          Load sky data and attach it to the world
  626.  
  627.  **********************************************************/
  628.  
  629. int GetSky()
  630. {
  631.   VECTOR loc, v1, v2, v3, upper, lower;
  632.   CINFO  cinfo;
  633.   char   str[SLEN];
  634.   int    end, found;
  635.  
  636.   end=0;
  637.   GetLeftParen();
  638.  
  639.   def_colorinfo(&cinfo);
  640.  
  641.   while (!end && !feof(stdin)) {
  642.     GetToken(str);
  643.  
  644.     found = GetOpt(str,&cinfo);                    /*** DITHER ONLY ***/
  645.  
  646.     if (strcmp(str,"ZENITH")==0) {
  647.        GetSVector(&(THEWORLD.skycolor_zenith));
  648.        found = TRUE;
  649.     }
  650.  
  651.     if ((strcmp(str,"HORIZ")==0) ||
  652.         (strcmp(str,"HORIZON")==0)) {
  653.  
  654.        GetSVector(&(THEWORLD.skycolor_horiz));
  655.        found = TRUE;
  656.     }
  657.     if (strcmp(str,")")==0) { end=1; found=TRUE; }
  658.  
  659.     if (!found) Error(UNDEFINED_PARAM,222);
  660.   }
  661.  
  662.   VectEqZero(&v3);
  663.   VectEqZero(&upper);
  664.   VectEqZero(&lower);
  665.  
  666.   THEWORLD.sky=new_obj(SKY,&loc,&v1,&v2,&v3,&cinfo,NULL,NULL,
  667.                        NULL, &upper, &lower,
  668.                        (float)0.0, (float)0.0, (float)0.0);
  669.   return(TRUE);
  670. }
  671.  
  672. /**********************************************************
  673.  
  674.             Load ring and return pointer to it
  675.  
  676.  **********************************************************/
  677.  
  678. OBJ_PTR GetRing()
  679. {
  680.   char        str[SLEN], *name;
  681.   CINFO       cinfo;
  682.   VECTOR      loc, v1, v2, v3, upper, lower;
  683.   OBJ_PTR     newobj;
  684.   PATTERN_PTR pattern, remove;
  685.   int         end, f, found;
  686.   float       xmult, ymult;
  687.  
  688.   end=f=0;
  689.   xmult=ymult=1;
  690.   def_colorinfo(&cinfo);
  691.   pattern = remove = NULL;
  692.   name    = NULL;
  693.  
  694.   GetLeftParen();
  695.  
  696.   while (!end && !feof(stdin)) {
  697.     GetToken(str);
  698.  
  699. #   ifdef IODEBUG
  700.       printf("GETRING : token=%s\n",str);
  701. #   endif
  702.  
  703.     found = GetOpt(str,&cinfo);
  704.  
  705.     if ((strcmp(str,"POS")==0)      ||
  706.         (strcmp(str,"LOC")==0)      ||
  707.         (strcmp(str,"POSITION")==0) ||
  708.         (strcmp(str,"LOCATION")==0)) {
  709.  
  710.       GetVector(&loc);
  711.       f|=1; found = TRUE;
  712.     }
  713.  
  714.     if ((strcmp(str,"V1")==0)     ||
  715.         (strcmp(str,"VECT1")==0)) {
  716.  
  717.       GetVector(&v1);
  718.       f|=2; found = TRUE;
  719.     }
  720.  
  721.     if ((strcmp(str,"V2")==0)     ||
  722.         (strcmp(str,"VECT2")==0)) {
  723.  
  724.       GetVector(&v2);
  725.       f|=4; found = TRUE;
  726.     }
  727.  
  728.     if (strcmp(str,"RAD_1")==0) {
  729.        v3.x = IsPos(Get_Next_Num());
  730.        f|=8; found = TRUE;
  731.     }
  732.     if (strcmp(str,"RAD_2")==0) {
  733.        v3.y = IsPos(Get_Next_Num());
  734.        f|=16; found = TRUE;
  735.     }
  736.     if (strcmp(str,"PATTERN")==0) {
  737.        pattern=Attach_Pattern();
  738.        found = TRUE;
  739.     }
  740.     if (strcmp(str,"REMOVE")==0) {
  741.       remove=Attach_Pattern();
  742.       found = TRUE;
  743.     }
  744.     if (strcmp(str,"XMULT")==0) {
  745.       xmult = IsPos(Get_Next_Num());
  746.       found=TRUE;
  747.     }
  748.     if (strcmp(str,"YMULT")==0) {
  749.       ymult = IsPos(Get_Next_Num());
  750.       found=TRUE;
  751.     }
  752.     if (strcmp(str,"NAME")==0) {
  753.        name=Get_Next_Name();
  754.        found = TRUE;
  755.     }
  756.  
  757.     if (strcmp(str,")")==0) { end = 1; found = TRUE; }
  758.  
  759.     if (!found) Error(UNDEFINED_PARAM,224);
  760.   }
  761.  
  762.   if (f!=31) Error(TOO_FEW_PARMS,225);
  763.   v3.z = 0;
  764.   Normalize(&v1);
  765.   Normalize(&v2);
  766.  
  767.   newobj=new_obj(RING,&loc,&v1,&v2,&v3,&cinfo,pattern,
  768.                  remove, name,
  769.                  &upper, &lower, 0.0, xmult, ymult);
  770.  
  771.   THEWORLD.objcount++;
  772.   return(newobj);
  773. }
  774.  
  775.  
  776. /**********************************************************
  777.  
  778.        Load parallelogram and return pointer to it
  779.  
  780.  **********************************************************/
  781.  
  782. OBJ_PTR GetParallelogram()
  783. {
  784.   char        str[SLEN], *name;
  785.   CINFO       cinfo;
  786.   VECTOR      loc, v1, v2, v3, upper, lower;
  787.   OBJ_PTR     newobj;
  788.   PATTERN_PTR pattern, remove;
  789.   int         end, f, found;
  790.   float       xmult, ymult;
  791.  
  792.   end=f=0;
  793.   xmult=ymult=1;
  794.   def_colorinfo(&cinfo);
  795.   pattern = remove = NULL;
  796.   name    = NULL;
  797.  
  798.   GetLeftParen();
  799.  
  800.   while (!end && !feof(stdin)) {
  801.     GetToken(str);
  802.  
  803. #   ifdef IODEBUG
  804.       printf("GETPARREL : token=%s\n",str);
  805. #   endif
  806.  
  807.     found = GetOpt(str,&cinfo);
  808.  
  809.     if ((strcmp(str,"POS")==0)      ||
  810.         (strcmp(str,"LOC")==0)      ||
  811.         (strcmp(str,"POSITION")==0) ||
  812.         (strcmp(str,"LOCATION")==0)) {
  813.  
  814.       GetVector(&loc);
  815.       f|=1; found = TRUE;
  816.     }
  817.  
  818.     if ((strcmp(str,"V1")==0)     ||
  819.         (strcmp(str,"VECT1")==0)) {
  820.  
  821.       GetVector(&v1);
  822.       f|=2; found = TRUE;
  823.     }
  824.  
  825.     if ((strcmp(str,"V2")==0)     ||
  826.         (strcmp(str,"VECT2")==0)) {
  827.  
  828.       GetVector(&v2);
  829.       f|=4; found = TRUE;
  830.     }
  831.  
  832.     if (strcmp(str,"PATTERN")==0) {
  833.       pattern=Attach_Pattern();
  834.       found = TRUE;
  835.     }
  836.     if (strcmp(str,"REMOVE")==0) {
  837.       remove=Attach_Pattern();
  838.       found = TRUE;
  839.     }
  840.  
  841.     if (strcmp(str,"XMULT")==0) {
  842.       xmult = IsPos(Get_Next_Num());
  843.       found=TRUE;
  844.     }
  845.     if (strcmp(str,"YMULT")==0) {
  846.       ymult = IsPos(Get_Next_Num());
  847.       found=TRUE;
  848.     }
  849.     if (strcmp(str,"NAME")==0) {
  850.        name=Get_Next_Name();
  851.        found = TRUE;
  852.     }
  853.  
  854.     if (strcmp(str,")")==0) { end = 1; found = TRUE;}
  855.  
  856.     if (!found) Error(UNDEFINED_PARAM,227);
  857.   }
  858.  
  859.   if (f!=7) Error(TOO_FEW_PARMS,228);
  860.  
  861.   VectEqZero(&v3);
  862.   VectEqZero(&upper);
  863.   VectEqZero(&lower);
  864.  
  865.   newobj=new_obj(PARALLELOGRAM,&loc,&v1,&v2,&v3,&cinfo,
  866.                  pattern, remove,name,
  867.                  &upper, &lower, 0.0, xmult, ymult);
  868.  
  869.   THEWORLD.objcount++;
  870.   return(newobj);
  871. }
  872.  
  873. /**********************************************************
  874.  
  875.                   Load quadratic surface
  876.  
  877.  **********************************************************/
  878.  
  879. OBJ_PTR GetQuadratic()
  880. {
  881.   char        str[SLEN], *name;
  882.   CINFO       cinfo;
  883.   VECTOR      loc, v1, v2, v3, upper, lower;
  884.   OBJ_PTR     newobj;
  885.   PATTERN_PTR pattern, remove;
  886.   int         end, f, found;
  887.   float       cterm, xmult, ymult;
  888.  
  889.   end=f=0;
  890.   xmult=ymult=1;
  891.   def_colorinfo(&cinfo);
  892.   pattern = remove = NULL;
  893.   name    = NULL;
  894.  
  895.   GetLeftParen();
  896.  
  897.   upper.x = upper.y = upper.z = 10;
  898.   lower.x = lower.y = lower.z = -10;
  899.  
  900.   v1.x = 0; v1.y = 1; v1.z = 0;
  901.  
  902.   while (!end && !feof(stdin)) {
  903.     GetToken(str);
  904.  
  905. #   ifdef IODEBUG
  906.       printf("GETQUAD : token=%s\n",str);
  907. #   endif
  908.  
  909.     found = GetOpt(str,&cinfo);
  910.  
  911.     if ((strcmp(str,"POS")==0)      ||
  912.         (strcmp(str,"LOC")==0)      ||
  913.         (strcmp(str,"POSITION")==0) ||
  914.         (strcmp(str,"LOCATION")==0)) {
  915.  
  916.       GetVector(&loc);
  917.       f|=1; found = TRUE;
  918.     }
  919.  
  920.     if (strcmp(str,"A")==0) {
  921.       v2.x  = Get_Next_Num();
  922.       f|=2; found = TRUE;
  923.     }
  924.     if (strcmp(str,"B")==0) {
  925.       v2.y  = Get_Next_Num();
  926.       f|=4; found = TRUE;
  927.     }
  928.     if (strcmp(str,"C")==0) {
  929.       v2.z  = Get_Next_Num();
  930.       f|=8; found = TRUE;
  931.     }
  932.     if (strcmp(str,"D")==0) {
  933.       cterm = Get_Next_Num();
  934.       f|=16; found = TRUE;
  935.     }
  936.  
  937.     if (strcmp(str,"XMIN")==0) {
  938.       lower.x  = Get_Next_Num();
  939.       found    = TRUE;
  940.     }
  941.     if (strcmp(str,"XMAX")==0) {
  942.       upper.x  = Get_Next_Num();
  943.       found    = TRUE;
  944.     }
  945.     if (strcmp(str,"YMIN")==0) {
  946.       lower.y  = Get_Next_Num();
  947.       found    = TRUE;
  948.     }
  949.     if (strcmp(str,"YMAX")==0) {
  950.       upper.y  = Get_Next_Num();
  951.       found    = TRUE;
  952.     }
  953.     if (strcmp(str,"ZMIN")==0) {
  954.       lower.z  = Get_Next_Num();
  955.       found    = TRUE;
  956.     }
  957.     if (strcmp(str,"ZMAX")==0) {
  958.       upper.z  = Get_Next_Num();
  959.       found    = TRUE;
  960.     }
  961.  
  962.     if (strcmp(str,"DIR")==0) {
  963.       GetVector(&v1);
  964.       found = TRUE;
  965.     }
  966.  
  967.     if (strcmp(str,"PATTERN")==0) {
  968.       pattern=Attach_Pattern();
  969.       found = TRUE;
  970.     }
  971.     if (strcmp(str,"REMOVE")==0) {
  972.       remove=Attach_Pattern();
  973.       found = TRUE;
  974.     }
  975.     if (strcmp(str,"XMULT")==0) {
  976.       xmult = IsPos(Get_Next_Num());
  977.       found=TRUE;
  978.     }
  979.     if (strcmp(str,"YMULT")==0) {
  980.       ymult = IsPos(Get_Next_Num());
  981.       found=TRUE;
  982.     }
  983.     if (strcmp(str,"NAME")==0) {
  984.        name=Get_Next_Name();
  985.        found = TRUE;
  986.     }
  987.  
  988.     if (strcmp(str,")")==0) { end = 1; found = TRUE;}
  989.  
  990.     if (!found) Error(UNDEFINED_PARAM,230);
  991.   }
  992.  
  993.   if (f!=31) Error(TOO_FEW_PARMS,231);
  994.  
  995.   VectEqZero(&v3);
  996.  
  997.   newobj=new_obj(QUADRATIC,&loc,&v1,&v2,&v3,&cinfo,pattern,
  998.                  remove, name,
  999.                  &upper, &lower, cterm, xmult, ymult);
  1000.  
  1001.   THEWORLD.objcount++;
  1002.   return(newobj);
  1003. }
  1004.  
  1005.  
  1006. /**********************************************************
  1007.  
  1008.        Load the focal length of the observers lens
  1009.  
  1010.  **********************************************************/
  1011.  
  1012. int GetFocLength() {
  1013.   THEWORLD.flength=IsPos(Get_Next_Num());
  1014.   return(TRUE);
  1015. }
  1016.  
  1017.  
  1018. /**********************************************************
  1019.  
  1020.     Load a primitive from input and return pointer to it
  1021.  
  1022.  **********************************************************/
  1023.  
  1024. OBJ_PTR Get_Primitive(str)                /* get an object */
  1025.   char str[];
  1026. {
  1027.   OBJ_PTR newobj;
  1028.  
  1029. # ifdef IODEBUG
  1030.     printf("GETPRIMITIVE : token=%s:\n",str);
  1031. # endif
  1032.  
  1033.   newobj=NULL;
  1034.   if (strcmp(str,"SPHERE")==0) {
  1035.     if ((newobj=GetSphere())==NULL)
  1036.       Error(ILLEGAL_OBJECT,232);
  1037.   }
  1038.   if (strcmp(str,"PARALLELOGRAM")==0) {
  1039.     if ((newobj=GetParallelogram())==NULL)
  1040.       Error(ILLEGAL_OBJECT,233);
  1041.   }
  1042.   if (strcmp(str,"TRIANGLE")==0) {
  1043.     if ((newobj=GetTriangle())==NULL)
  1044.       Error(ILLEGAL_OBJECT,234);
  1045.   }
  1046.   if (strcmp(str,"RING")==0) {
  1047.     if ((newobj=GetRing())==NULL)
  1048.       Error(ILLEGAL_OBJECT,235);
  1049.   }
  1050.   if (strcmp(str,"QUADRATIC")==0) {
  1051.     if ((newobj=GetQuadratic())==NULL)
  1052.       Error(ILLEGAL_OBJECT,236);
  1053.   }
  1054.   if (strcmp(str,"INSTANCE_OF")==0) {
  1055.     if ((newobj=Get_Instance_Of())==NULL)
  1056.       Error(ILLEGAL_OBJECT,237);
  1057.   }
  1058.   return(newobj);
  1059. }
  1060.  
  1061.  
  1062. /**********************************************************
  1063.  
  1064.      Load an attribute from input and do stuff with it
  1065.  
  1066.  **********************************************************/
  1067.  
  1068. int GetAttrib(str)                    /* get an object */
  1069.   char str[];
  1070. {
  1071.   int found;
  1072.  
  1073.   found=FALSE;
  1074.  
  1075. # ifdef IODEBUG
  1076.     printf("GETATTRIB : token=%s:\n",str);
  1077. # endif
  1078.  
  1079.   if (strcmp(str,"SKY")==0) {
  1080.     if (!GetSky())      Error(INTERNAL_ERROR,238);
  1081.     found=TRUE;
  1082.   }
  1083.   if (strcmp(str,"FOC_LENGTH")==0) {
  1084.     if (!GetFocLength()) Error(INTERNAL_ERROR,239);
  1085.     found=TRUE;
  1086.   }
  1087.   if (strcmp(str,"FIRST_SCAN")==0) {
  1088.     THEWORLD.first_scan=(int)IsPos(Get_Next_Num());
  1089.     found=TRUE;
  1090.   }
  1091.   if (strcmp(str,"DEFAULT")==0) {
  1092.     if (!Get_Default()) Error(INTERNAL_ERROR,240);
  1093.     found=TRUE;
  1094.   }
  1095.   if (strcmp(str,"FILE_NAME")==0) {
  1096.     THEWORLD.outfile=Get_Next_Name();
  1097.     found=TRUE;
  1098.   }
  1099.   if (strcmp(str,"LAMP")==0) {
  1100.     if (!GetLamp())     Error(INTERNAL_ERROR,241);
  1101.     found=TRUE;
  1102.   }
  1103.   if (strcmp(str,"OBSERVER")==0) {
  1104.     if (!GetObserver()) Error(INTERNAL_ERROR,242);
  1105.     found=TRUE;
  1106.   }
  1107.   if (strcmp(str,"LAST_SCAN")==0) {
  1108.     THEWORLD.last_scan=(int)IsPos(Get_Next_Num());
  1109.     found=TRUE;
  1110.   }
  1111.   if (strcmp(str,"PATTERN")==0) {
  1112.     if (!GetPattern())  Error(INTERNAL_ERROR,243);
  1113.     found=TRUE;
  1114.   }
  1115.  
  1116.   return(found);
  1117. }
  1118.  
  1119.