home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / source / devel5 / plg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-18  |  7.1 KB  |  330 lines

  1. /* PLG file i/o */
  2.  
  3. /* Written by Bernie Roehl, March 1992 */
  4. /* updated by Dave Stampe */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>  /* atoi(), atol() */
  8. #include <string.h>
  9. #include <alloc.h>
  10. #include <ctype.h>   /* isalnum() */
  11. #include "rend386.h"
  12. #include "plg.h"
  13. #ifdef ENCRYPT
  14. #include "encrypt.h"
  15. #endif
  16.  
  17. /* Copyright 1992 by Dave Stampe and Bernie Roehl.
  18.    May be freely used to write software for release into the public domain;
  19.    all commercial endeavours MUST contact Bernie Roehl and Dave Stampe
  20.    for permission to incorporate any part of this software into their
  21.      products!
  22.  
  23.      ATTRIBUTION:  If you use any part of this source code or the libraries
  24.      in your projects, you must give attribution to REND386, Dave Stampe,
  25.      and Bernie Roehl in your documentation, source code, and at startup
  26.      of your program.  Let's keep the freeware ball rolling!
  27. */
  28.  
  29. int load_err = 0; /* set if an error was encountered during loading */
  30. int err_line = 1; /* line on which error occurred */
  31.  
  32. char *plg_errmsgs[] = {
  33.     "No error",
  34.     "Bad syntax in header line",
  35.     "Couldn't create new object",
  36.     "Couldn't add representation",
  37.     "Early EOF while reading vertices",
  38.     "Bad syntax in vertex line",
  39.     "Early EOF while reading polygons",
  40.     "Missing vertex count in polygon line",
  41.     "Missing vertex index in polygon line",
  42.     "Couldn't add polygon",
  43.     "Vertex number out of range",
  44.     NULL };
  45.  
  46. static long xshift = 0, yshift = 0, zshift = 0;
  47. static float xrescale = 1, yrescale = 1, zrescale = 1;
  48. static int depthsort = 0;
  49.  
  50. static unsigned *cmap;
  51. static int mapsize = 0;
  52.  
  53. long lx, ly, lz; /* DEBUG */
  54.  
  55. static unsigned mapcolor(unsigned orig)
  56. {
  57.     if ((orig & 0x8000) == 0) return orig; /* only map if top bit set */
  58.     orig &= 0x7FFF; /* turn the top bit off */
  59.     if (cmap == NULL) return orig; /* no map */
  60.     if (orig > mapsize) return orig; /* color not in map */
  61.     return cmap[orig]; /* map it */
  62. }
  63.  
  64. void set_loadplg_colormap(unsigned *map, int msize)
  65. {
  66.     cmap = map;
  67.     mapsize = msize;
  68. }
  69.  
  70. void set_loadplg_offset(long x, long y, long z)
  71. {
  72.     xshift = x; 
  73.     yshift = y; 
  74.     zshift = z;
  75. }
  76.  
  77. void set_loadplg_scale(float x, float y, float z)
  78. {
  79.     xrescale = x;
  80.     yrescale = y; 
  81.     zrescale = z;
  82. }
  83.  
  84. void set_loadplg_depthsort(int type)
  85. {
  86.     depthsort = type;
  87. }
  88.  
  89. void strip_comment(char *buff) /* also trim newline character(s) */
  90. {
  91.     char *p;
  92.     if ((p = strchr(buff, '\n')) != NULL) *p = '\0'; /* trim newline */
  93.     if ((p = strchr(buff, '#')) != NULL) *p = '\0'; /* trim comment */
  94.     if ((p = strchr(buff, '*')) != NULL) *p = '\0'; /* future expansion */
  95.     if(sscanf(buff,"%*s")==EOF) buff[0] = 0; /* dump tabs, etc */
  96. }
  97.  
  98. static long default_size;
  99. static int maxpolys;
  100. static int maxverts;
  101. static int multirep = 0;
  102.  
  103. static int load_in_plg_file(FILE *in, OBJECT **obj)
  104. {
  105.     char tbuff[1000], objname[100];
  106.     int nv, np, i;
  107.     char *p;
  108.     long size = 0;
  109.     int multi = (*obj) ? 1 : 0; /* multi-reps if not null object */
  110.  
  111.     multirep = 0;
  112.  
  113.     /* skip blank lines */
  114.     do {
  115.         if (fgets(tbuff, sizeof(tbuff), in) == NULL) return -1;
  116. #ifdef ENCRYPT
  117.         if (tbuff[0] == 26) decrypt_buffer(tbuff);
  118. #endif
  119.         ++err_line;
  120.         if (strstr(tbuff,"#MULTI")) multi++;
  121.         if (multi) multirep++;
  122.         strip_comment(tbuff);
  123.     }
  124.     while (tbuff[0] == '\0');
  125.  
  126.     if (sscanf(tbuff, "%s %d %d", objname, &nv, &np) != 3)
  127.     {
  128.         load_err = -1;
  129.         return -1;
  130.     }
  131.  
  132.     if (multi && (p = strchr(objname, '_')) != NULL)
  133.     {
  134.         *p++ = 0;
  135.         size = atol(p);
  136.     }
  137.     else size = default_size; /* default: use largest detail always */
  138.  
  139.     if (*obj == NULL)
  140.     {
  141.         if ((*obj = new_obj(0, nv, np)) == NULL)
  142.         {
  143.             load_err = -2;
  144.             return -1;
  145.         }
  146.         set_rep_size(*obj, size);
  147.     }
  148.     else
  149.         {
  150.         if (add_representation(*obj, size, nv, np) == NULL)
  151.         {
  152.             load_err = -3;
  153.             return -1;
  154.         }
  155.     }
  156.  
  157.     maxpolys = np;
  158.     maxverts = nv;
  159.  
  160.     for (i = 0; i < nv; ++i) /* load in vertices */
  161.     {
  162.         float x, y, z;
  163.         /* skip blank lines */
  164.         do
  165.             {
  166.             if (fgets(tbuff, sizeof(tbuff), in) == NULL)
  167.             {
  168.                 load_err = -4;
  169.                 return -1;
  170.             }
  171. #ifdef ENCRYPT
  172.             if (tbuff[0] == 26) decrypt_buffer(tbuff);
  173. #endif
  174.             ++err_line;
  175.             strip_comment(tbuff);
  176.         }
  177.         while (tbuff[0] == '\0');
  178.  
  179.         if (sscanf(tbuff, "%f %f %f", &x, &y, &z) != 3)
  180.         {
  181.             load_err = -5;
  182.             return -1;
  183.         }
  184.  
  185.         add_vertex(*obj, (lx = (long) (x*xrescale))+xshift,
  186.         (ly = (long) (y*yrescale))+yshift,
  187.         (lz = (long) (z*zrescale))+zshift);
  188.         lx++;
  189.     }
  190.  
  191.     for (i = 0; i < np; ++i) /* load polygons */
  192.     {
  193.         int j, npoints;
  194.         unsigned color;
  195.         POLY *poly;
  196.         char *p;
  197.         /* skip blank lines */
  198.         do
  199.             {
  200.             if (fgets(tbuff, sizeof(tbuff), in) == NULL)
  201.             {
  202.                 load_err = -6;
  203.                 return -1;
  204.             }
  205. #ifdef ENCRYPT
  206.             if (tbuff[0] == 26) decrypt_buffer(tbuff);
  207. #endif
  208.             ++err_line;
  209.             strip_comment(tbuff);
  210.         }
  211.         while (tbuff[0] == '\0');
  212.  
  213.         color = convert_color(tbuff,&p);
  214.         color = mapcolor(color);
  215.         if ((p = strtok(p, " \t")) == NULL)
  216.         {
  217.             load_err = -7;
  218.             return -1;
  219.         }
  220.         npoints = atoi(p);
  221.         if ((poly = add_poly(*obj, color, npoints)) == NULL)
  222.         {
  223.             load_err = -9;
  224.             return -1;
  225.         }
  226.         for (j = 0; j < npoints; ++j)
  227.         {
  228.             int vertnum;
  229.             if ((p = strtok(NULL, " \t")) == NULL)
  230.             {
  231.                 load_err = -8;
  232.                 return -1;
  233.             }
  234. #ifdef OLD
  235.             if (atoi(p) < maxverts && atoi(p) >= 0)
  236.                 add_point(*obj, poly, atoi(p));
  237.             else add_point(*obj, poly, maxverts-1);
  238. #else
  239.             vertnum = atoi(p);
  240.             if (vertnum < 0 || vertnum >= maxverts) {
  241.                 load_err = -10;
  242.                 return -1;
  243.             }
  244.             add_point(*obj, poly, vertnum);
  245. #endif
  246.         }
  247.     }
  248.     compute_obj(*obj); /* will do current rep only */
  249.     load_err = 0;
  250.     return 0;
  251. }
  252.  
  253. OBJECT *load_plg(FILE *in)
  254. {
  255.     OBJECT *obj = NULL;
  256.     default_size = 0;
  257.     load_err = 0;
  258.     err_line = 1;
  259.     if (load_in_plg_file(in, &obj)) return NULL;
  260.     set_object_sorting(obj, depthsort);
  261.     return obj;
  262. }
  263.  
  264. OBJECT *load_multi_plg(FILE *in)
  265. {
  266.     OBJECT *obj = NULL;
  267.     int ocount = 0;
  268.     default_size = 0;
  269.     load_err = 0;
  270.     err_line = 1;
  271.     while (load_in_plg_file(in, &obj) == 0)
  272.     {
  273.         ocount++;
  274.         if (!multirep) break;
  275.     }
  276.     if (ocount == 0) return NULL;
  277.     set_object_sorting(obj, depthsort);
  278.     return obj;
  279. }
  280.  
  281. OBJECT *load_extra_rep(FILE *in, OBJECT *obj, long size)
  282. {
  283.     int ocount = 0;
  284.     default_size = size;
  285.     load_err = 0;
  286.     err_line = 1;
  287.  
  288.     while (load_in_plg_file(in, &obj) == 0)
  289.     {
  290.         ocount++;
  291.         if (!multirep) break;
  292.     }
  293.     if (ocount == 0) return NULL;
  294.     set_object_sorting(obj, depthsort);
  295.     return obj;
  296. }
  297.  
  298.  
  299. save_plg(OBJECT *obj, FILE *out, int world)
  300. {
  301.     int nv, np, i; /* now saves all representations */
  302.     char buff[100];
  303.  
  304.     first_rep(obj);
  305.     do
  306.         {
  307.         get_obj_info(obj, &nv, &np);
  308.         fprintf(out, "SAVED %d %d\n", nv, np);
  309.         for (i = 0; i < nv; ++i)
  310.         {
  311.             long x, y, z;
  312.             if (world) get_vertex_world_info(obj, i, &x, &y, &z);
  313.             else get_vertex_info(obj, i, &x, &y, &z);
  314.             fprintf(out, "%ld %ld %ld\n", x, y, z);
  315.         }
  316.         for (i = 0; i < np; ++i)
  317.         {
  318.             int j, n, verts[1000];
  319.             unsigned c;
  320.             get_poly_info(obj, i, &c, &n, verts, sizeof(verts)/sizeof(int));
  321.             fprintf(out, "0x%04.4X %d", c & 0x7FFF, n);
  322.             for (j = 0; j < n; ++j) fprintf(out, " %d", verts[j]);
  323.             fprintf(out, "\n");
  324.         }
  325.     }
  326.     while (!next_rep(obj));
  327.  
  328.     return 0;
  329. }
  330.