home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / vr386 / loadfig.c < prev    next >
C/C++ Source or Header  |  1996-03-19  |  6KB  |  212 lines

  1. /* Segment file i/o  <actually FIG files> */
  2. /* segments are usually created and linked in the .WLD files */
  3.  
  4. /* Original code written by Bernie Roehl, March 1992 */
  5. /* Completely redone for VR-386 by Dave Stampe, 1/1/94
  6.  
  7. /*
  8.  This code is part of the VR-386 project, created by Dave Stampe.
  9.  VR-386 is a desendent of REND386, created by Dave Stampe and
  10.  Bernie Roehl.  Almost all the code has been rewritten by Dave
  11.  Stampre for VR-386.
  12.  
  13.  Copyright (c) 1994 by Dave Stampe:
  14.  May be freely used to write software for release into the public domain
  15.  or for educational use; all commercial endeavours MUST contact Dave Stampe
  16.  (dstampe@psych.toronto.edu) for permission to incorporate any part of
  17.  this software or source code into their products!  Usually there is no
  18.  charge for under 50-100 items for low-cost or shareware products, and terms
  19.  are reasonable.  Any royalties are used for development, so equipment is
  20.  often acceptable payment.
  21.  
  22.  ATTRIBUTION:  If you use any part of this source code or the libraries
  23.  in your projects, you must give attribution to VR-386 and Dave Stampe,
  24.  and any other authors in your documentation, source code, and at startup
  25.  of your program.  Let's keep the freeware ball rolling!
  26.  
  27.  DEVELOPMENT: VR-386 is a effort to develop the process started by
  28.  REND386, improving programmer access by rewriting the code and supplying
  29.  a standard API.  If you write improvements, add new functions rather
  30.  than rewriting current functions.  This will make it possible to
  31.  include you improved code in the next API release.  YOU can help advance
  32.  VR-386.  Comments on the API are welcome.
  33.  
  34.  CONTACT: dstampe@psych.toronto.edu
  35. */
  36.  
  37.  
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <ctype.h>
  41. #include <string.h>
  42.  
  43. #include "vr_api.h"
  44. #include "intmath.h"  /* for RYZ definition */
  45. #include "segment.h"
  46.  
  47. extern char *fix_fname(char *fname);
  48.  
  49. static int readseg_err = 0;
  50.  
  51. static char *seg_errmsgs[] = {
  52.     "No error",
  53.     "Couldn't open plg file",
  54.     "Error reading plg file",
  55.     "Bad syntax",
  56.     "Couldn't open map file",
  57.     NULL };
  58.  
  59.  
  60. static char errm[50];
  61.  
  62. char *seg_error(int *errnum)
  63. {
  64.   if(errnum) *errnum = readseg_err;
  65.   if(!readseg_err) return NULL;
  66.   sprintf(errm, "FIG load error: %s", seg_errmsgs[-readseg_err]);
  67.   return errm;
  68. }
  69.  
  70.  
  71. #define match(a, b) (!strnicmp((a), (b), strlen(b)))
  72.  
  73. extern OBJLIST *default_objlist;
  74.  
  75. static OBJLIST *seg_olist;
  76.  
  77. static SEGMENT **seg_array = NULL;
  78. static int seg_array_size = 0;
  79.  
  80. static float seg_sx = 1; /* for pos'n and rotate, just */
  81. static float seg_sy = 1; /* attach a parent, update,   */
  82. static float seg_sz = 1; /* then detach it again       */
  83.  
  84. static int process_attribute(char *buff, OBJECT *seg)
  85. {
  86.   char filename[100];
  87.   int depth = 0;
  88.   FILE *in;
  89.  
  90.   while (isspace(*buff)) ++buff;
  91.   if (match(buff, "plgfile"))
  92.     {
  93.       float sx = 1, sy = 1, sz = 1;
  94.       OBJECT *obj;
  95.       POSE p = ZERO_POSE;
  96.  
  97.       sscanf(buff, "plgfile = %s scale %f,%f,%f shift %ld,%ld,%ld sort %d", filename, &sx, &sy, &sz, &p.x, &p.y, &p.z, &depth);
  98.       if ((in = fopen(fix_fname(filename), "r")) == NULL)
  99.     {
  100.       readseg_err = -1;
  101.       return -1;
  102.     }
  103.       p.x *= seg_sx;
  104.       p.y *= seg_sy;
  105.       p.z *= seg_sz;
  106.       obj = load_plg_object(in, &p, sx*seg_sx, sy*seg_sy, sz*seg_sz, depth);
  107.       if (!obj)
  108.     {
  109.       readseg_err = -2;
  110.       fclose(in);
  111.       return -2;
  112.     }
  113.       add_to_objlist(seg_olist, obj);
  114.       seg = make_fixed_object_moveable(obj, seg);
  115.       fclose(in);
  116.       return 0;
  117.     }
  118.   else if (match(buff, "pos"))
  119.     {
  120.       POSE p = DONTCARE_POSE;
  121.  
  122.       sscanf(buff, "pos = %ld,%ld,%ld", &p.x, &p.y, &p.z);
  123.       p.x *= seg_sx;
  124.       p.y *= seg_sy;
  125.       p.z *= seg_sz;
  126.       set_object_pose(seg, &p);
  127.     }
  128.   else if (match(buff, "rot"))
  129.     {
  130.       POSE p = DONTCARE_POSE;
  131.       float rx, ry, rz;
  132.  
  133.       sscanf(buff, "rot = %f,%f,%f", &rx, &ry, &rz);
  134.       p.rx = float2angle(rx);
  135.       p.ry = float2angle(ry);
  136.       p.rz = float2angle(rz);
  137.       set_object_pose(seg, &p);
  138.     }
  139.   else if (match(buff, "name"))
  140.     {
  141.       char *p;
  142.       if ((p = strchr(buff, '=')) == NULL)
  143.     {
  144.       readseg_err = -3;
  145.       return -3;
  146.     }
  147.       do ++p; while (isspace(*p));
  148.       seg_setname(seg, p);
  149.     }
  150.   else if (match(buff, "segnum"))
  151.     {
  152.       int j;
  153.       sscanf(buff, "segnum = %d", &j);
  154.       if (seg_array && j < seg_array_size) seg_array[j] = seg;
  155.     }
  156.     /* ignore anything we don't understand */
  157.  return 0;
  158. }
  159.  
  160.  
  161. static SEGMENT *readseg(FILE *in, SEGMENT *parent)
  162. {
  163.   SEGMENT *seg;
  164.   char buff[256];
  165.   int c, i = 0;
  166.  
  167.   seg = create_invisible_object();     // create, link new object
  168.   if(!seg) return NULL;
  169.   if(parent) naked_attach_object(seg, parent);
  170.  
  171.   while ((c = getc(in)) != EOF)
  172.     {
  173.       switch (c)
  174.     {
  175.       case '#':
  176.         while ((c = getc(in)) != EOF)    // comment: skip
  177.             if (c == '\n')
  178.                 break;
  179.         break;
  180.       case '{':                              // new layer
  181.         readseg(in, seg);
  182.         break;
  183.       case '}':                              // end of layer
  184.         return seg;
  185.       case ';':
  186.         buff[i] = '\0';                  // move or load appearance
  187.         process_attribute(buff, seg);
  188.         i = 0;
  189.         break;
  190.       default:                               // debug
  191.         if (i < sizeof(buff)-1) buff[i++] = c;
  192.         break;
  193.     }
  194.     }
  195.   return seg;
  196. }
  197.  
  198.  
  199. OBJECT *load_figure_as_object(FILE *in, OBJLIST *olist, OBJECT **segtable,
  200.                   WORD stmax, float sx, float sy, float sz)
  201. {
  202.   seg_olist = olist;
  203.   if(!olist) seg_olist = default_objlist;
  204.   seg_array = segtable;
  205.   seg_array_size = stmax;
  206.   seg_sx = sx;
  207.   seg_sy = sy;
  208.   seg_sz = sz;
  209.   readseg_err = 0;
  210.   return readseg(in, create_invisible_object());
  211. }
  212.