home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / source / devel5 / segio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-25  |  5.8 KB  |  224 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.      ATTRIBUTION:  If you use any part of this source code or the libraries
  12.      in your projects, you must give attribution to REND386, Dave Stampe,
  13.      and Bernie Roehl in your documentation, source code, and at startup
  14.      of your program.  Let's keep the freeware ball rolling!
  15.  */
  16.  
  17. /* The format of a segment file is simple, and very C-like.  Each segment
  18.    is bounded by { and }, and contains any combination of attributes and
  19.    additional segments (which are children of the segment they appear in).
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <ctype.h>
  25. #include <string.h>
  26. #include "rend386.h"
  27. #include "intmath.h"  /* for RYZ definition */
  28. #include "plg.h"
  29. #include "segio.h"
  30.  
  31. extern char *fix_fname(char *fname);
  32.  
  33. int readseg_err = 0;
  34.  
  35. char *readseg_errmsgs[] = {
  36.     "No error",
  37.     "Couldn't open plg file",
  38.     "Error reading plg file",
  39.     "Bad syntax",
  40.     "Couldn't open map file",
  41.     NULL };
  42.  
  43. #define match(a, b) (!strnicmp((a), (b), strlen(b)))
  44.  
  45. static OBJLIST *curr_objlist = NULL;
  46.  
  47. static char *boundstypes[] = { 
  48.     "NONE", "SPHERE", "BOX", "CSG", NULL };
  49.  
  50. void set_readseg_objlist(OBJLIST *olist)
  51. {
  52.     curr_objlist = olist;
  53. }
  54.  
  55. static SEGMENT **seg_array = NULL;
  56. static int seg_array_size = 0;
  57.  
  58. void set_readseg_seglist(SEGMENT **ptr, int maxsegs)
  59. {
  60.     seg_array = ptr;
  61.     seg_array_size = maxsegs;
  62. }
  63.  
  64. static float seg_scalex = 1; /* for pos'n and rotate, just */
  65. static float seg_scaley = 1; /* attach a parent, update,   */
  66. static float seg_scalez = 1; /* then detach it again       */
  67.  
  68. void set_readseg_scale(float x, float y, float z)
  69. {
  70.     seg_scalex = x;
  71.     seg_scaley = y;
  72.     seg_scalez = z;
  73. }
  74.  
  75. static unsigned cmap[1000];
  76. static int cmapsize = 0;
  77.  
  78. static int process_attribute(char *buff, SEGMENT *seg)
  79. {
  80.     char filename[100];
  81.     float sx = 1, sy = 1, sz = 1;
  82.     long tx = 0, ty = 0, tz = 0;
  83.     int depth = 0;
  84.     FILE *in;
  85.     cmapsize = 0;
  86.     while (isspace(*buff)) ++buff;
  87.     if (match(buff, "plgfile")) {
  88.         OBJECT *obj;
  89.         char mapfile[100];
  90.         mapfile[0] = '\0';
  91.         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);
  92.         if (mapfile[0]) {
  93.             if ((in = fopen(fix_fname(mapfile), "r")) == NULL) {
  94.                 readseg_err = -4;
  95.                 return -1;
  96.             }
  97.             for (cmapsize = 0; cmapsize < sizeof(cmap)/sizeof(unsigned) && !feof(in); ++cmapsize) {
  98.                 char buff[100], *p;
  99.                 fgets(buff, sizeof(buff), in);
  100.                 strip_comment(buff);
  101.                 cmap[cmapsize] = (unsigned) strtoul(buff,&p,0); /* req so hex colors usable */
  102.             }
  103.             fclose(in);
  104.         }
  105.         set_loadplg_scale(sx*seg_scalex, sy*seg_scaley, sz*seg_scalez);
  106.         set_loadplg_offset(tx*seg_scalex, ty*seg_scaley, tz*seg_scalez);
  107.         set_loadplg_depthsort(depth);
  108.         set_loadplg_colormap(cmap, cmapsize);
  109.         if ((in = fopen(fix_fname(filename), "r")) == NULL) {
  110.             readseg_err = -1;
  111.             return -1;
  112.         }
  113.         if ((obj = load_multi_plg(in)) == NULL) {
  114.             readseg_err = -2;
  115.             fclose(in);
  116.             return -2;
  117.         }
  118.         seg_set_object(seg, obj);
  119.         set_object_owner(obj, seg);
  120.         if (curr_objlist) add_to_objlist(curr_objlist, obj);
  121.         fclose(in);
  122.         return 0;
  123.     }
  124.     else if (match(buff, "pos")) {
  125.         long tx, ty, tz;
  126.         sscanf(buff, "pos = %ld,%ld,%ld", &tx, &ty, &tz);
  127.         abs_move_segment(seg, tx*seg_scalex, ty*seg_scaley, tz*seg_scalez);
  128.     }
  129.     else if (match(buff, "rot")) {
  130.         float rx, ry, rz;
  131.         sscanf(buff, "rot = %f,%f,%f", &rx, &ry, &rz);
  132.         abs_rot_segment(seg, (long) (rx * 65536L), (long) (ry * 65536L), (long) (rz * 65536L), RYXZ);
  133.     }
  134.     else if (match(buff, "name")) {
  135.         char *p;
  136.         if ((p = strchr(buff, '=')) == NULL) {
  137.             readseg_err = -3;
  138.             return -3;
  139.         }
  140.         do ++p;
  141.         while (isspace(*p));
  142.         seg_setname(seg, p);
  143.     }
  144.     else if (match(buff, "segnum")) {
  145.         int j;
  146.         sscanf(buff, "segnum = %d", &j);
  147.         if (seg_array && j < seg_array_size) seg_array[j] = seg;
  148.     }
  149.     /* ignore anything we don't understand */
  150.     return 0;
  151. }
  152.  
  153. SEGMENT *readseg(FILE *in, SEGMENT *parent)
  154. {
  155.     SEGMENT *seg;
  156.     char buff[256];
  157.     int c, i = 0;
  158.     if ((seg = new_seg(parent)) == NULL) return NULL;
  159.     while ((c = getc(in)) != EOF) {
  160.         switch (c) {
  161.         case '#':
  162.             while ((c = getc(in)) != EOF)
  163.                 if (c == '\n')
  164.                     break;
  165.             break;
  166.         case '{':
  167.             readseg(in, seg);
  168.             break;
  169.         case '}':
  170.             return seg;
  171.         case ';':
  172.             buff[i] = '\0';
  173.             process_attribute(buff, seg);
  174.             i = 0;
  175.             break;
  176.         default:
  177.             if (i < sizeof(buff)-1) buff[i++] = c;
  178.             break;
  179.         }
  180.     }
  181.     return seg;
  182. }
  183.  
  184. static void indent(FILE *out, int level)
  185. {
  186.     while (level--) fprintf(out, "\t");
  187. }
  188.  
  189. writeseg(FILE *out, SEGMENT *s, int level)
  190. {
  191.     SEGMENT *p;
  192.     void *q;
  193.     long tx, ty, tz, rx, ry, rz;
  194.     float frx, fry, frz;
  195.     char *name;
  196.     unsigned char btype;
  197.     unsigned w;
  198.     long lims[12];
  199.     int depth;
  200.     int i;
  201.     indent(out, level);
  202.     fprintf(out, "{\n");
  203.     if ((name = seg_getname(s)) != NULL) {
  204.         indent(out, level);
  205.         fprintf(out, "name = %s;\n", name);
  206.     }
  207.     seg_getposxyz(s, &tx, &ty, &tz);
  208.     seg_getposang(s, &rx, &ry, &rz);
  209.     indent(out, level);
  210.     fprintf(out, "pos = %ld,%ld,%ld;\n", tx, ty, tz);
  211.     indent(out, level);
  212.     fprintf(out, "rot = %f,%f,%f;\n", ((float) rx) /65536L, ((float) ry) /65536L, ((float) rz) /65536L);
  213.  
  214.     indent(out, level);
  215.     if ((q = seg_get_object(s)) != NULL) depth = get_object_sorting(q);
  216.     else depth = 0;
  217.     fprintf(out, "plgfile = %s scale %f,%f,%f shift %ld,%ld,%ld sort %d;\n", name, frx, fry, frz, tx, ty, tz, depth);
  218.     for (p = child_segment(s); p; p = sibling_segment(p))
  219.         writeseg(out, p, level+1);
  220.     indent(out, level);
  221.     fprintf(out, "}\n");
  222.     return 0;
  223. }
  224.