home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / fermiVogle.tar.Z / fermiVogle.tar / devel / src / objects.c < prev    next >
C/C++ Source or Header  |  1996-02-07  |  10KB  |  539 lines

  1. #include <stdio.h>
  2.  
  3. #ifdef PC
  4. #include <fcntl.h>
  5. #endif
  6.  
  7. #ifndef PC
  8. #ifdef SYS5
  9. #include <fcntl.h>
  10. #else
  11. #include <sys/file.h>
  12. #endif
  13. #endif
  14. #include "vogle.h"
  15.  
  16. extern void        polyobj();
  17.  
  18. typedef struct o {
  19.     int        obno;
  20.     TokList        *tlist;
  21.     struct o    *next;
  22. } Object;
  23.  
  24. static Object        *object_table[MAXENTS];
  25.  
  26. static int        obno = -1, omax = 0;
  27.  
  28. static void doarc( float, float, float, float, float, float, int );
  29.  
  30. /*
  31.  * makeobj
  32.  *
  33.  *    start a new object.
  34.  *
  35.  */
  36. void
  37. makeobj(int n)
  38. {
  39.     Object    *o;
  40.  
  41.     if (!vdevice.initialised)
  42.         verror("makeobj: vogle not initialised");
  43.  
  44.     for (o = object_table[n % MAXENTS]; o != (Object *)NULL; o = o->next)
  45.         if (o->obno == n) {
  46.             delobj(n);
  47.             break;
  48.         }
  49.  
  50.     obno = n;
  51.     vdevice.tokens = (TokList *)NULL;
  52.  
  53.     vdevice.inobject = 1;
  54.  
  55.     if (omax <= n)
  56.         omax = n + 1;
  57. }
  58.  
  59. /*
  60.  * closeobj
  61.  *
  62.  *    close an object
  63.  */
  64. void
  65. closeobj(void)
  66. {
  67.     Object    *o;
  68.  
  69.     if (!vdevice.inobject)
  70.         verror("closeobj: not in an object");
  71.  
  72.     vdevice.inobject = 0;
  73.  
  74.     o = (Object *)vallocate(sizeof(Object));
  75.     o->obno = obno;
  76.     o->tlist = vdevice.tokens;
  77.     o->next = object_table[obno % MAXENTS];
  78.  
  79.     object_table[obno % MAXENTS] = o;
  80.  
  81.     obno = -1;
  82. }
  83.  
  84. /*
  85.  * delobj
  86.  *
  87.  *    deletes an object, freeing its memory
  88.  */
  89. void
  90. delobj(int n)
  91. {
  92.     Object    *o, *lo;
  93.     TokList    *tl, *ntl;
  94.  
  95.     for (lo = o = object_table[n % MAXENTS]; o != (Object *)NULL; lo = o, o = o->next)
  96.         if (o->obno == n)
  97.             break;
  98.  
  99.     if (o != (Object *)NULL) {
  100.         for (tl = o->tlist; tl != (TokList *)NULL; tl = ntl) {
  101.             ntl = tl->next;
  102.             if (tl->toks)
  103.                 free(tl->toks);
  104.             free(tl);
  105.         }
  106.         if (lo == object_table[n % MAXENTS])
  107.             object_table[n % MAXENTS] = (Object *)NULL;
  108.         else
  109.             lo->next = o->next;
  110.         free(o);
  111.     }
  112. }
  113.  
  114. /*
  115.  * genobj
  116.  *
  117.  *    generates a unique object identifier
  118.  */
  119. int
  120. genobj(void)
  121. {
  122.     return(omax++);
  123. }
  124.  
  125. /*
  126.  * getopenobj
  127.  *
  128.  *    returns the object currently being edited, -1 if none.
  129.  */
  130. int
  131. getopenobj(void)
  132. {
  133.     return(obno);
  134. }
  135.  
  136. /*
  137.  * loadobj
  138.  *
  139.  *    reads in object file file and makes it the object refered to by n.
  140.  */
  141. void
  142. loadobj(int n, char *file)
  143. {
  144.     int    objfd;
  145.     TokList    *tl;
  146.     Object    *o;
  147.     char    buf[100];
  148.  
  149.     if ((objfd = open(file, O_RDONLY)) == EOF) {
  150.         sprintf(buf, "loadobject: unable to open object file %s", file);
  151.         verror(buf);
  152.     }
  153.  
  154.     o = (Object *)vallocate(sizeof(Object));
  155.     o->obno = n;
  156.     o->next = object_table[n % MAXENTS];
  157.  
  158.     object_table[n % MAXENTS] = o;
  159.  
  160.     o->tlist = tl = (TokList *)vallocate(sizeof(TokList));
  161.     read(objfd, &tl->count, sizeof(tl->count));
  162.  
  163.     tl->toks = (Token *)vallocate(tl->count * sizeof(Token));
  164.     tl->next = (TokList *)NULL;
  165.  
  166.     read(objfd, tl->toks, tl->count * sizeof(Token));
  167.  
  168.     close(objfd);
  169. }
  170.  
  171. /*
  172.  * saveobj
  173.  *
  174.  *    saves the object n into file file.
  175.  */
  176. void
  177. saveobj(int n, char *file)
  178. {
  179.     int    objfd, count;
  180.     Object    *o;
  181.     TokList    *tl;
  182.     char    buf[100];
  183.  
  184.  
  185.     if ((objfd = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0664)) == EOF) {
  186.         sprintf(buf, "saveobject: unable to open object file %s", file);
  187.         verror(buf);
  188.     }
  189.  
  190.     for (o = object_table[n % MAXENTS]; o != (Object *)NULL; o = o->next)
  191.         if (o->obno == n)
  192.             break;
  193.  
  194.     if (o == (Object *)NULL)
  195.         return;
  196.  
  197.     count = 0;
  198.     for (tl = o->tlist; tl != (TokList *)NULL; tl = tl->next)
  199.         count += tl->count;
  200.  
  201.     write(objfd, &count, sizeof(count));
  202.  
  203.     for (tl = o->tlist; tl != (TokList *)NULL; tl = tl->next)
  204.         write(objfd, tl->toks, tl->count * sizeof(Token));
  205.  
  206.     close(objfd);
  207. }
  208.  
  209. /*
  210.  * doarc
  211.  *
  212.  *    draw an arc or circle.
  213.  */
  214. static void
  215. doarc(float x, float y, float xoff, float yoff, float cosine, float sine,
  216.       int nsegs)
  217. {
  218.     float    cx, cy, dx, dy;
  219.     int    i;
  220.  
  221.     cx = x + xoff;
  222.     cy = y + yoff;
  223.     move2(cx, cy);
  224.  
  225.     for (i = 0; i < nsegs; i++)  {
  226.         dx = cx - x;
  227.         dy = cy - y;
  228.         cx = x + dx * cosine - dy * sine;
  229.         cy = y + dx * sine + dy * cosine;
  230.         draw2(cx, cy);
  231.     }
  232. }
  233.  
  234. /*
  235.  * callobj
  236.  *
  237.  *    draws an object
  238.  */
  239. void
  240. callobj(int n)
  241. {
  242.     Object        *o;
  243.     TokList        *tl;
  244.     Matrix        prod, tmpmat;
  245.     Tensor        S;
  246.     int        sync, i, j, inpoly;
  247.     float        cx, cy, cz, *m;
  248.     register Token    *t, *et, *pt;
  249.  
  250.     if (!vdevice.initialised)
  251.         verror("callobj: vogle not initialised");
  252.  
  253.     if (vdevice.inobject) {
  254.         t = newtokens(2);
  255.  
  256.         t[0].i = CALLOBJ;
  257.         t[1].i = n;
  258.  
  259.         return;
  260.     }
  261.  
  262.     for (o = object_table[n % MAXENTS]; o != (Object *)NULL; o = o->next)
  263.         if (o->obno == n)
  264.             break;
  265.  
  266.     if (o == (Object *)NULL)
  267.         return;
  268.  
  269.     if ((sync = vdevice.sync))
  270.         vdevice.sync = 0;
  271.  
  272.     for (tl = o->tlist; tl != (TokList *)NULL; tl = tl->next) {
  273.         t = tl->toks;
  274.         et = &tl->toks[tl->count];
  275.         while (t != et) {
  276.             switch (t->i) {
  277.             case ARC:
  278.                 doarc(t[1].f, t[2].f, t[3].f, t[4].f, t[5].f, t[6].f, t[7].i);
  279.                 t += 8;
  280.                 break;
  281.             case BACKBUFFER:
  282.                 backbuffer();
  283.                 t++;
  284.                 break;
  285.             case BACKFACING:
  286.                 backface(t[1].i);
  287.                 t += 2;
  288.                 break;
  289.             case BOXTEXT:
  290.                 boxtext(t[1].f, t[2].f, t[3].f, t[4].f,
  291.                     (char *)&t[5]);
  292.                 t += 6 + strlen((char *)&t[5]) / sizeof(Token);
  293.                 break;
  294.             case CALLOBJ:
  295.                 callobj(t[1].i);
  296.                 t += 2;
  297.                 break;
  298.             case CENTERTEXT:
  299.                 centertext(t[1].i);
  300.                 t += 2;
  301.                 break;
  302.             case CIRCLE:
  303.                 inpoly = vdevice.inpolygon; 
  304.  
  305.                 if ((vdevice.attr->a.fill || vdevice.attr->a.hatch) && !inpoly)
  306.                     makepoly();
  307.  
  308.                 doarc(t[1].f, t[2].f, t[3].f, 0.0, t[4].f, t[5].f, t[6].i);
  309.  
  310.                 if ((vdevice.attr->a.fill || vdevice.attr->a.hatch) && !inpoly)
  311.                     closepoly();
  312.                 else
  313.                     draw2(t[1].f + t[3].f, t[2].f);
  314.                 t += 7;
  315.                 break;
  316.             case CLEAR:
  317.                 (*vdevice.dev.Vclear)();
  318.                 t++;
  319.                 break;
  320.             case COLOR:
  321.                 color(t[1].i);
  322.                 t += 2;
  323.                 break;
  324.             case DRAW:
  325.                 draw(t[1].f, t[2].f, t[3].f);
  326.                 t += 4;
  327.                 break;
  328.             case DRAWCHAR:
  329.                 drawchar(t[1].i);
  330.                 t += 2;
  331.                 break;
  332.             case DRAWSTR:
  333.                 drawstr((char *)&t[1]);
  334.                 t += 2 + strlen((char *)&t[1]) / sizeof(Token);
  335.                 break;
  336.             case FIXEDWIDTH:
  337.                 fixedwidth(t[1].i);
  338.                 t += 2;
  339.                 break;
  340.             case VFONT:
  341.                 font((char *)&t[1]);
  342.                 t += 2 + strlen((char *)&t[1]) / sizeof(Token);
  343.                 break;
  344.             case HATCHANG:
  345.                 vdevice.attr->a.hatchcos = t[1].f;
  346.                 vdevice.attr->a.hatchsin = t[2].f;
  347.                 t += 3;
  348.                 break;
  349.             case HATCHPITCH:
  350.                 vdevice.attr->a.hatchpitch = t[1].f;
  351.                 t += 2;
  352.                 break;
  353.             case LOADMATRIX:
  354.                 m = (float *)vdevice.transmat->m;
  355.                 for (i = 0; i < 16; i++)
  356.                     *m++ = (++t)->f;
  357.  
  358.                 vdevice.cpVvalid = 0;           /* may have changed mapping from world to device coords */
  359.                 t++;
  360.  
  361.                 break;
  362.             case MAPCOLOR:
  363.                 mapcolor(t[1].i, t[2].i, t[3].i, t[4].i);
  364.                 t += 5;
  365.                 break;
  366.             case MOVE:
  367.                 move(t[1].f, t[2].f, t[3].f);
  368.                 t += 4;
  369.                 break;
  370.             case MULTMATRIX:
  371.                 m = (float *)tmpmat;
  372.                 for (i = 0; i < 16; i++)
  373.                     *m++ = (++t)->f;
  374.  
  375.                 mult4x4(prod, tmpmat, vdevice.transmat->m);
  376.                 loadmatrix(prod);
  377.                 t++;
  378.                 break;
  379.             case POLY:
  380.                 polyobj(t[1].i, &t[2]);
  381.                 t += 2 + 3 * t[1].i;
  382.                 break;
  383.             case POLYFILL:
  384.                 polyfill(t[1].i);
  385.                 t += 2;
  386.                 break;
  387.             case POLYHATCH:
  388.                 polyhatch(t[1].i);
  389.                 t += 2;
  390.                 break;
  391.             case POPATTRIBUTES:
  392.                 popattributes();
  393.                 t++;
  394.                 break;
  395.             case POPMATRIX:
  396.                 popmatrix();
  397.                 t++;
  398.                 break;
  399.             case POPVIEWPORT:
  400.                 popviewport();
  401.                 t++;
  402.                 break;
  403.             case PUSHATTRIBUTES:
  404.                 pushattributes();
  405.                 t++;
  406.                 break;
  407.             case PUSHMATRIX:
  408.                 pushmatrix();
  409.                 t++;
  410.                 break;
  411.             case PUSHVIEWPORT:
  412.                 pushviewport();
  413.                 t++;
  414.                 break;
  415.             case RCURVE:
  416.                 i = (++t)->i;
  417.                 cx = (++t)->f;
  418.                 cy = (++t)->f;
  419.                 cz = (++t)->f;
  420.                 m = (float *)tmpmat;
  421.                 for (j = 0; j < 16; j++)
  422.                     *m++ = (++t)->f;
  423.                 mult4x4(prod, tmpmat, vdevice.transmat->m);
  424.                 drcurve(i, prod);
  425.                 vdevice.cpW[V_X] = cx;
  426.                 vdevice.cpW[V_Y] = cy;
  427.                 vdevice.cpW[V_Z] = cz;
  428.                 t++;
  429.                 break;
  430.             case RPATCH:
  431.                 pt = t + 10;
  432.                 cx = (++t)->f;
  433.                 cy = (++t)->f;
  434.                 cz = (++t)->f;
  435.                 for (i = 0; i < 4; i++)
  436.                     for (j = 0; j < 4; j++) {
  437.                         S[0][i][j] = (pt++)->f;
  438.                         S[1][i][j] = (pt++)->f;
  439.                         S[2][i][j] = (pt++)->f;
  440.                         S[3][i][j] = (pt++)->f;
  441.                     }
  442.  
  443.                 transformtensor(S, vdevice.transmat->m);
  444.                 drpatch(S, t[1].i, t[2].i, t[3].i, t[4].i, t[5].i, t[6].i);
  445.  
  446.                 vdevice.cpW[V_X] = cx;
  447.                 vdevice.cpW[V_Y] = cy;
  448.                 vdevice.cpW[V_Z] = cz;
  449.                 t = pt;
  450.                 break;
  451.             case SECTOR:
  452.                 inpoly = vdevice.inpolygon;
  453.  
  454.                 if ((vdevice.attr->a.fill || vdevice.attr->a.hatch) && !inpoly)
  455.                     makepoly();
  456.  
  457.                     doarc(t[1].f, t[2].f, t[3].f, t[4].f, t[5].f, t[6].f, t[7].i);
  458.                     draw(t[1].f, t[2].f, 0.0);
  459.  
  460.                 if ((vdevice.attr->a.fill || vdevice.attr->a.hatch) && !inpoly)
  461.                     closepoly();
  462.                 else
  463.                     draw2(t[1].f + t[3].f, t[2].f + t[4].f);
  464.                 t += 8;
  465.                 break;
  466.             case TEXTANG:
  467.                 vdevice.attr->a.textcos = t[1].f;
  468.                 vdevice.attr->a.textsin = t[2].f;
  469.                 t += 3;
  470.                 break;
  471.             case TEXTSIZE:
  472.                 textsize(t[1].f, t[2].f);
  473.                 t += 3;
  474.                 break;
  475.             case VIEWPORT:
  476.                 viewport(t[1].f, t[2].f, t[3].f, t[4].f);
  477.                 t += 5;
  478.                 break;
  479.             case TRANSLATE:
  480.                 translate(t[1].f, t[2].f, t[3].f);
  481.                 t += 4;
  482.                 break;
  483.             case SCALE:
  484.                 /*
  485.                  * Do the operations directly on the top matrix of
  486.                  * the stack to speed things up.
  487.                  */
  488.  
  489.                 vdevice.transmat->m[0][0] *= t[1].f;
  490.                 vdevice.transmat->m[0][1] *= t[1].f;
  491.                 vdevice.transmat->m[0][2] *= t[1].f;
  492.                 vdevice.transmat->m[0][3] *= t[1].f;
  493.  
  494.                 vdevice.transmat->m[1][0] *= t[2].f;
  495.                 vdevice.transmat->m[1][1] *= t[2].f;
  496.                 vdevice.transmat->m[1][2] *= t[2].f;
  497.                 vdevice.transmat->m[1][3] *= t[2].f;
  498.  
  499.                 vdevice.transmat->m[2][0] *= t[3].f;
  500.                 vdevice.transmat->m[2][1] *= t[3].f;
  501.                 vdevice.transmat->m[2][2] *= t[3].f;
  502.                 vdevice.transmat->m[2][3] *= t[3].f;
  503.  
  504.                 t += 4;
  505.                 break;
  506.             case ROTATE:
  507.                 rotate(t[1].f, (char)t[2].i);
  508.                 t += 3;
  509.                 break;
  510.             default:
  511.                 verror("vogle: internal error in callobj");
  512.                 exit(1);
  513.             }
  514.         }
  515.     }
  516.  
  517.     if (sync) {
  518.         vdevice.sync = 1;
  519.         (*vdevice.dev.Vsync)();
  520.     }
  521. }
  522.  
  523. /*
  524.  * isobj
  525.  *
  526.  *    returns 1 if there is an object n, 0 otherwise.
  527.  */
  528. int
  529. isobj(int n)
  530. {
  531.     Object    *o;
  532.  
  533.     for (o = object_table[n % MAXENTS]; o != (Object *)NULL; o = o->next)
  534.         if (o->obno == n)
  535.             break;
  536.  
  537.     return(o != (Object *)NULL);
  538. }
  539.