home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / PCGLOVE / GLOVE / OBJGLV.ZIP / SRC / DEMO4B / SUPP / SEGIO.CPP < prev    next >
C/C++ Source or Header  |  1993-04-07  |  5KB  |  205 lines

  1. /* Segment file i/o */
  2.  
  3. /* Written by Bernie Roehl, March 1992 */
  4.  
  5. /* Copyright 1992 by Bernie Roehl.
  6.    May be freely used to write software for release into the public domain;
  7.    all commercial endeavours MUST contact Bernie Roehl
  8.    for permission to incorporate any part of this software into their
  9.    products!
  10.  */
  11.  
  12. /* The format of a segment file is simple, and very C-like.  Each segment
  13.    is bounded by { and }, and contains any combination of attributes and
  14.    additional segments (which are children of the segment they appear in).
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <ctype.h>
  20. #include <string.h>
  21. #include "rend386.hpp"
  22. #include "intmath.h"  /* for RYZ definition */
  23. #include "plg.h"
  24. #include "segio.hpp"
  25.  
  26. extern char *fix_fname(char *fname);
  27.  
  28. int readseg_err = 0;
  29.  
  30. #define match(a, b) (!strnicmp((a), (b), strlen(b)))
  31.  
  32. static OBJLIST *curr_objlist = NULL;
  33.  
  34. static char *boundstypes[] = { "NONE", "SPHERE", "BOX", "CSG", NULL };
  35.  
  36. void set_readseg_objlist(OBJLIST *olist)
  37. {
  38.     curr_objlist = olist;
  39. }
  40.  
  41. static SEGMENT **seg_array = NULL;
  42. static int seg_array_size = 0;
  43.  
  44. void set_readseg_seglist(SEGMENT **ptr, int maxsegs)
  45. {
  46.     seg_array = ptr;
  47.     seg_array_size = maxsegs;
  48. }
  49.  
  50. static float seg_scalex = 1; /* for pos'n and rotate, just */
  51. static float seg_scaley = 1; /* attach a parent, update,   */
  52. static float seg_scalez = 1; /* then detach it again       */
  53.  
  54. void set_readseg_scale(float x, float y, float z)
  55. {
  56.     seg_scalex = x;
  57.     seg_scaley = y;
  58.     seg_scalez = z;
  59. }
  60.  
  61. static unsigned cmap[1000];
  62. static int cmapsize = 0;
  63.  
  64. static process_attribute(char *buff, SEGMENT *seg)
  65. {
  66.     char filename[100];
  67.     float sx = 1, sy = 1, sz = 1;
  68.     long tx = 0, ty = 0, tz = 0;
  69.     int depth = 0;
  70.     FILE *in;
  71.     cmapsize = 0;
  72.     while (isspace(*buff)) ++buff;
  73.     if (match(buff, "plgfile")) {
  74.         OBJECT *obj;
  75.         char mapfile[100];
  76.         mapfile[0] = '\0';
  77.         sscanf(buff, "plgfile = %s scale %f,%f,%f shift %ld,%ld,%ld sort %d map %s", filename, &sx, &sy, &sz, &tx, &ty, &tz, &depth, mapfile);
  78.         if (mapfile[0]) {
  79.             if ((in = fopen(fix_fname(mapfile), "r")) == NULL) {
  80.                 readseg_err = -1;
  81.                 return -1;
  82.             }
  83.             for (cmapsize = 0; cmapsize < sizeof(cmap)/sizeof(unsigned) && !feof(in); ++cmapsize) {
  84.                 char buff[100], *p;
  85.                 fgets(buff, sizeof(buff), in);
  86.                 strip_comment(buff);
  87.                 cmap[cmapsize] = (unsigned) strtoul(buff,&p,0); /* req so hex colors usable */
  88.             }
  89.             fclose(in);
  90.         }
  91.         set_loadplg_scale(sx*seg_scalex, sy*seg_scaley, sz*seg_scalez);
  92.         set_loadplg_offset(tx*seg_scalex, ty*seg_scaley, tz*seg_scalez);
  93.         set_loadplg_depthsort(depth);
  94.         set_loadplg_colormap(cmap, cmapsize);
  95.         if ((in = fopen(fix_fname(filename), "r")) == NULL) {
  96.             readseg_err = -1;
  97.             return -1;
  98.         }
  99.         if ((obj = load_plg(in)) == NULL) {
  100.             readseg_err = -2;
  101.             fclose(in);
  102.             return -2;
  103.         }
  104.         seg_set_object(seg, obj);
  105.         set_object_owner(obj, seg);
  106.         if (curr_objlist) add_to_objlist(curr_objlist, obj);
  107.         fclose(in);
  108.         return 0;
  109.     }
  110.     else if (match(buff, "pos")) {
  111.         long tx, ty, tz;
  112.         sscanf(buff, "pos = %ld,%ld,%ld", &tx, &ty, &tz);
  113.         abs_move_segment(seg, tx*seg_scalex, ty*seg_scaley, tz*seg_scalez);
  114.     }
  115.     else if (match(buff, "rot")) {
  116.         float rx, ry, rz;
  117.         sscanf(buff, "rot = %f,%f,%f", &rx, &ry, &rz);
  118.         abs_rot_segment(seg, (long) (rx * 65536L), (long) (ry * 65536L), (long) (rz * 65536L), RYXZ);
  119.     }
  120.     else if (match(buff, "name")) {
  121.         char *p;
  122.         if ((p = strchr(buff, '=')) == NULL) {
  123.             readseg_err = -3;
  124.             return -3;
  125.         }
  126.         do ++p;
  127.         while (isspace(*p));
  128.         seg_setname(seg, p);
  129.     }
  130.     else if (match(buff, "segnum")) {
  131.         int j;
  132.         sscanf(buff, "segnum = %d", &j);
  133.         if (seg_array && j < seg_array_size) seg_array[j] = seg;
  134.     }
  135.     /* ignore anything we don't understand */
  136.     return 0;
  137. }
  138.  
  139. SEGMENT *readseg(FILE *in, SEGMENT *parent)
  140. {
  141.     SEGMENT *seg;
  142.     char buff[256];
  143.     int c, i = 0;
  144.     if ((seg = new_seg(parent)) == NULL) return NULL;
  145.     while ((c = getc(in)) != EOF) {
  146.         switch (c) {
  147.             case '{':
  148.                 readseg(in, seg);
  149.                 break;
  150.             case '}':
  151.                 return seg;
  152.             case ';':
  153.                 buff[i] = '\0';
  154.                 process_attribute(buff, seg);
  155.                 i = 0;
  156.                 break;
  157.             default:
  158.                 if (i < sizeof(buff)-1) buff[i++] = c;
  159.                 break;
  160.         }
  161.     }
  162.     return seg;
  163. }
  164.  
  165. static void indent(FILE *out, int level)
  166. {
  167.     while (level--) fprintf(out, "\t");
  168. }
  169.  
  170. writeseg(FILE *out, SEGMENT *s, int level)
  171. {
  172.     SEGMENT *p;
  173.     void *q;
  174.     long tx, ty, tz, rx, ry, rz;
  175.     float frx, fry, frz;
  176.     char *name;
  177.     unsigned char btype;
  178.     unsigned w;
  179.     long lims[12];
  180.     int depth;
  181.     int i;
  182.     indent(out, level);
  183.     fprintf(out, "{\n");
  184.     if ((name = seg_getname(s)) != NULL) {
  185.         indent(out, level);
  186.         fprintf(out, "name = %s;\n", name);
  187.     }
  188.     seg_getposxyz(s, &tx, &ty, &tz);
  189.     seg_getposang(s, &rx, &ry, &rz);
  190.     indent(out, level);
  191.     fprintf(out, "pos = %ld,%ld,%ld;\n", tx, ty, tz);
  192.     indent(out, level);
  193.     fprintf(out, "rot = %f,%f,%f;\n", ((float) rx) /65536L, ((float) ry) /65536L, ((float) rz) /65536L);
  194.  
  195.     indent(out, level);
  196.     if ((q = seg_get_object(s)) != NULL) depth = get_object_sorting((OBJECT *)q);
  197.     else depth = 0;
  198.     fprintf(out, "plgfile = %s scale %f,%f,%f shift %ld,%ld,%ld sort %d;\n", name, frx, fry, frz, tx, ty, tz, depth);
  199.     for (p = child_segment(s); p; p = sibling_segment(p))
  200.         writeseg(out, p, level+1);
  201.     indent(out, level);
  202.     fprintf(out, "}\n");
  203.     return 0;
  204. }
  205.