home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / PASM.LZH / SUFLIB.CPP < prev    next >
C/C++ Source or Header  |  1995-12-06  |  10KB  |  452 lines

  1. #include    <stdio.h>
  2. #include    <string.h>
  3. #include    <stdlib.h>
  4. #include <dos.h>
  5. #include    "suflib.h"
  6. #include "token.h"
  7. #if 0
  8. #ifdef DEBUG
  9. #define STATIC
  10. #else
  11. #define STATIC static
  12. #include    "token.c"
  13. #endif
  14. #endif
  15.  
  16. static const int MAX = 32767;
  17.  
  18. static const int AllocUnit = 32;
  19.  
  20. static SufFile *top = NULL;
  21. static int usepoly = FALSE;
  22.  
  23. Object *SufFile::OpenObject(char *fname, char *oname)
  24. {
  25.     SufFile *s = OpenSuf(fname);
  26.     if (s == NULL) {
  27.         return NULL;
  28.     }
  29.     if (oname == NULL) {
  30.         return s->object[0];
  31.     }
  32.     for (int i = 0; i < MaxObject; ++i) {
  33.         if (s->object[i] == NULL) {
  34.             break;
  35.         }
  36.         if (strcmpi(s->object[i]->name, oname) == 0) {
  37.             return s->object[i];
  38.         }
  39.     }
  40.     return NULL;
  41. }
  42.  
  43. SufFile *SufFile::OpenSuf( char *fname )
  44. {
  45.     SufFile *s;
  46.     for (s = top; s != NULL; s = s -> next) {
  47.         if (strcmpi(s->filename, fname) == 0) {
  48.             return s;
  49.         }
  50.     }
  51.     s = new SufFile(fname);
  52.     if (s->object[0] == NULL) {
  53.         delete s;
  54.         return NULL;
  55.     }
  56.     s->next = top;
  57.     top = s;
  58.     return s;
  59. }
  60.  
  61. SufFile::SufFile( char *fname )
  62. {
  63.     int i;
  64.     char    token[32];
  65.  
  66.     strcpy(filename, fname);
  67.     next = NULL;
  68.  
  69.     TokenReader tokenread(fname);
  70.  
  71.     if (!tokenread.Suceed()) {
  72. #ifdef DEBUG
  73.     printf("cannot open file %s\n", fname);
  74. #endif
  75.         object[0] = NULL;
  76.         return;
  77.     }
  78.     for (i = 0; i < MaxObject-1; ++i) {
  79.         if (tokenread.GetToken( token ), strcmpi( token, "obj" ) == 0) {
  80. #ifdef DEBUG
  81. printf("read object start\n");
  82. #endif
  83.             object[i] = new Object(&tokenread);
  84. #ifdef DEBUG
  85. printf("read object end\n");
  86. #endif
  87.             if (object[i]->Succeed() == FALSE) {
  88.                 delete object[i];
  89.                 --i;
  90.             }
  91.             object[i]->filename = filename;
  92.         } else {
  93.             break;
  94.         }
  95.     }
  96.     object[i] = NULL;
  97. #ifdef DEBUG
  98.     for (i = 0; i < MaxObject-1; ++i) {
  99.         printf("object[%d] = %04x:%04x\n", i, FP_SEG(object[i]), FP_OFF(object[i]));
  100.     }
  101. #endif
  102. }
  103.  
  104. SufFile::~SufFile()
  105. {
  106.     for (int i = 0; object[i] != NULL && i < MaxObject-1; ++i) {
  107.         object[i]->Delete();
  108.     }
  109. }
  110.  
  111. int Object::Succeed(void)
  112. {
  113.     if (point_x == NULL || point_y == NULL || point_z == NULL
  114.      || line_1 == NULL || line_2 == NULL) {
  115.         return FALSE;
  116.     }
  117.     return TRUE;
  118. }
  119.  
  120. void Object::UsePoly(void)
  121. {
  122.     usepoly = TRUE;
  123. }
  124.  
  125. int Object::IsPoly(void)
  126. {
  127.     return usepoly;
  128. }
  129.  
  130. Object::Object()
  131. {
  132.     point_x = point_y = point_z = line_1 = line_2 = poly = polypoint = NULL;
  133. }
  134.  
  135. Object::Object(TokenReader *tokenread)
  136. {
  137.     char    token[32] ;
  138.  
  139.     points = 0 ;
  140.     lines = 0 ;
  141.     polys = 0;
  142.     polypoints = 0;
  143.     maxx = -MAX ;
  144.     maxy = -MAX ;
  145.     maxz = -MAX ;
  146.     minx = MAX ;
  147.     miny = MAX ;
  148.     minz = MAX ;
  149.  
  150.     copy = 1;
  151.  
  152.     point_x = point_y = point_z = line_1 = line_2 = poly = polypoint = NULL;
  153.     allocpoints = alloclines = allocpolys = allocpolypoints = 0;
  154.  
  155.     polygons = 0;
  156.  
  157.     if ( tokenread->GetToken( token ) ,strcmpi( token, "suf" ) ) {
  158. #ifdef DEBUG
  159.     printf("%s %d: not exist suf!\n",
  160.         tokenread->GetFileName(), tokenread->GetFileLine());
  161. #endif
  162.         return;
  163.     }
  164.  
  165.     tokenread->GetToken( token ) ;
  166.     strcpy( name, token );
  167. #ifdef DEBUG
  168.     printf("read:%s\n", name);
  169. #endif
  170.     if ( tokenread->GetToken( token ), token[0] == '{' ) {
  171.         allocpoints = alloclines = AllocUnit;
  172.         point_x = new int[allocpoints];
  173.         point_y = new int[allocpoints];
  174.         point_z = new int[allocpoints];
  175.         line_1 = new int[alloclines];
  176.         line_2 = new int[alloclines];
  177.         if (usepoly) {
  178.             allocpolys = allocpolypoints = AllocUnit;
  179.             poly = new int[allocpolys] ;
  180.             polypoint = new int[allocpolypoints];
  181.         }
  182.         while ( tokenread->GetToken( token ), token[0] != '}' )
  183.         {
  184.             if ( !strcmpi( token, "atr" ) ) {
  185.                 tokenread->GetToken( token ) ;
  186.             } else if ( !strcmpi( token, "prim" ) ) {
  187.                 readpoly(tokenread) ;
  188. //                polygons++;
  189.             }
  190.         }
  191.     }
  192.     for (int i = 0; i < points; ++i) {
  193.         if (minx > point_x[i]) minx = point_x[i];
  194.         if (maxx < point_x[i]) maxx = point_x[i];
  195.         if (miny > point_y[i]) miny = point_y[i];
  196.         if (maxy < point_y[i]) maxy = point_y[i];
  197.         if (minz > point_z[i]) minz = point_z[i];
  198.         if (maxz < point_z[i]) maxz = point_z[i];
  199.     }
  200.  
  201. #if 0
  202.     for (i = 0; i < polys; ++i) {
  203.         for (int j = poly[i]; polypoint[j] != POLY_SEPARATER; ++j) {
  204.             logprintf("%d..", polypoint[j]);
  205.         }
  206.         logprintf("\n");
  207.     }
  208. #endif
  209. //    for (i = 0; i < polys; ++i) {
  210. //        int *p = polypoint + poly[i];
  211.  
  212. #ifdef DEBUG
  213.     for (int i = 0; i < lines; ++i) {
  214.         printf("\t(%d,%d,%d)-(%d,%d,%d)\n",
  215.         point_x[line_1[i]],
  216.         point_y[line_1[i]],
  217.         point_z[line_1[i]],
  218.         point_x[line_2[i]],
  219.         point_y[line_2[i]],
  220.         point_z[line_2[i]]    );
  221.     }
  222. #endif
  223.     return;
  224. }
  225.  
  226. Object::~Object()
  227. {
  228.     if (point_x != NULL) delete[] point_x;
  229.     if (point_y != NULL) delete[] point_y;
  230.     if (point_z != NULL) delete[] point_z;
  231.     if (line_1 != NULL) delete[] line_1;
  232.     if (line_2 != NULL) delete[] line_2;
  233.     if (poly != NULL) delete[] poly;
  234.     if (polypoint != NULL) delete[] polypoint;
  235. }
  236.  
  237. void Object::Delete(void)
  238. {
  239.     if (--copy <= 0) {
  240.         delete this;
  241.     }
  242. }
  243.  
  244. Object *Object::Copy(void)
  245. {
  246.     copy++;
  247.     return this;
  248. }
  249.  
  250. void Object::readpoly( TokenReader *tokenread)
  251. {
  252.     char    token[32] ;
  253.     int        skip = 0, i ;
  254.     int        x, y, z, line1=0, line2=0, lines=0 ;
  255.  
  256.     int polylines = 1;
  257.  
  258.     tokenread->GetToken( token ) ;
  259.     if ( !strcmpi( token, "poly" ) ) {
  260.         skip = 0 ;
  261.     } else if ( !strcmpi( token, "shade" ) ) {
  262.         skip = 3 ;
  263.     } else if ( !strcmpi( token, "uvpoly" ) ) {
  264.         skip = 2 ;
  265.     } else if ( !strcmpi( token, "uvshade" ) ) {
  266.         skip = 5 ;
  267.     } else {
  268. #ifdef DEBUG
  269.     printf("%s %d: poly | uvpoly |uvpoly | uvshade is expected!\n",
  270.         tokenread->GetFileName(), tokenread->GetFileLine());
  271. #endif
  272.         return ;
  273.     }
  274.  
  275.     if ( tokenread->GetToken( token ), token[0] == '(' ) {
  276.         tokenread->GetToken( token ) ;
  277.         if ( token[0] == ')' )
  278.             return ;
  279.         x= atoi( token ) ;
  280.  
  281.         tokenread->GetToken( token ) ;
  282.         if ( token[0] == ')' )
  283.             return ;
  284.         y = atoi( token ) ;
  285.  
  286.         tokenread->GetToken( token ) ;
  287.         if ( token[0] == ')' )
  288.             return ;
  289.         z = atoi( token ) ;
  290.  
  291.         lines = line1 = point(x, y, z ) ;
  292.  
  293.         if (usepoly) {
  294.             polyset(polypoints);
  295.             polypointset(line1);
  296.         }
  297.  
  298.         for( i = skip; i > 0; --i )
  299.         {
  300.             if ( tokenread->GetToken( token ), token[0] == ')' ) {
  301. #ifdef DEBUG
  302.     printf("cannot skip data!\n");
  303. #endif
  304.                 return ;
  305.             }
  306.         }
  307.  
  308.         while ( tokenread->GetToken( token ), token[0] != ')' )
  309.         {
  310.             polylines++;
  311.             x = atoi( token ) ;
  312.  
  313.             tokenread->GetToken( token ) ;
  314.             if ( token[0] == ')' )
  315.                 return ;
  316.             y = atoi( token ) ;
  317.  
  318.             tokenread->GetToken( token ) ;
  319.             if ( token[0] == ')' )
  320.                 return ;
  321.             z = atoi( token ) ;
  322.  
  323.             line2 = point( x, y, z ) ;
  324.             lineset( line1, line2 ) ;
  325.             if (usepoly) polypointset(line2);
  326.  
  327.             for( i = skip; i > 0; --i )
  328.             {
  329.                 if ( tokenread->GetToken( token ), token[0] == ')' )
  330.                     break ;
  331.             }
  332.             line1 = line2 ;
  333.         }
  334.         lineset( line2, lines ) ;
  335.         if (usepoly) polypointset(POLY_SEPARATER);
  336.     }
  337.     polygons += polylines - 2;
  338.     return ;
  339. }
  340.  
  341. void Object::polypointset(int point)
  342. {
  343.     if (polypoints >= allocpolypoints) {
  344.         int *p;
  345.         p = new int[allocpolypoints + AllocUnit];
  346.         memcpy(p, polypoint, sizeof(int) * allocpolypoints);
  347.         allocpolypoints += AllocUnit;
  348.         delete polypoint;
  349.         polypoint = p;
  350.     }
  351.     polypoint[polypoints++] = point;
  352. }
  353.  
  354. void Object::polyset(int polybegin)
  355. {
  356.     if (polys >= allocpolys) {
  357.         int *p;
  358.         p = new int[allocpolys + AllocUnit];
  359.         memcpy(p, poly, sizeof(int) * allocpolys);
  360.         allocpolys += AllocUnit;
  361.         delete poly;
  362.         poly = p;
  363.     }
  364.     poly[polys++] = polybegin;
  365. }
  366.  
  367.  
  368. void Object::lineset(int line1, int line2 )
  369. {
  370.     int i ;
  371.     if ( line1 == line2 ) {
  372.         return;
  373.     }
  374.     if ( line1 > line2 ) {
  375.         i = line2 ;
  376.         line2 = line1 ;
  377.         line1 = i ;
  378.     }
  379.     for( i = 0; i < lines; ++i ) {
  380.         if ( line1 == line_1[i] && line2 == line_2[i] ) {
  381.             return ;
  382.         }
  383.     }
  384.     if (lines >= alloclines) {
  385.         int *l1, *l2;
  386.         l1 = new int[alloclines + AllocUnit];
  387.         l2 = new int[alloclines + AllocUnit];
  388.         memcpy(l1, line_1, sizeof(int) * alloclines);
  389.         memcpy(l2, line_2, sizeof(int) * alloclines);
  390.         alloclines += AllocUnit;
  391. #ifdef DEBUG
  392. printf("%04x:%04x->", FP_SEG(line_1), FP_OFF(line_1));
  393. printf("%04x:%04x, ", FP_SEG(l1), FP_OFF(l1));
  394. printf("%04x:%04x->", FP_SEG(line_2), FP_OFF(line_2));
  395. printf("%04x:%04x\n", FP_SEG(l2), FP_OFF(l2));
  396. #endif
  397.         delete[] line_1;
  398.         delete[] line_2;
  399.         line_1 = l1;
  400.         line_2 = l2;
  401.     }
  402.     line_1[lines] = line1 ;
  403.     line_2[lines] = line2 ;
  404.     lines++ ;
  405. #ifdef DEBUG
  406.     printf("(%d->%d)\n", line1, line2);
  407. #endif
  408. }
  409.  
  410. int    Object::point(int x, int y, int z)
  411. {
  412.     int    i ;
  413.     for(i = 0; i < points; ++i) {
  414.         if (x == point_x[i] && y == point_y[i] && z == point_z[i]) {
  415.             return i ;
  416.         }
  417.     }
  418.     if (points >= allocpoints) {
  419.         int *px, *py, *pz;
  420.         px = new int[allocpoints + AllocUnit];
  421.         py = new int[allocpoints + AllocUnit];
  422.         pz = new int[allocpoints + AllocUnit];
  423.         memcpy(px, point_x, sizeof(int) * allocpoints);
  424.         memcpy(py, point_y, sizeof(int) * allocpoints);
  425.         memcpy(pz, point_z, sizeof(int) * allocpoints);
  426.         allocpoints += AllocUnit;
  427. #ifdef DEBUG
  428. printf("%04x:%04x->", FP_SEG(point_x), FP_OFF(point_x));
  429. printf("%04x:%04x, ", FP_SEG(px), FP_OFF(px));
  430. printf("%04x:%04x->", FP_SEG(point_y), FP_OFF(point_y));
  431. printf("%04x:%04x, ", FP_SEG(py), FP_OFF(py));
  432. printf("%04x:%04x->", FP_SEG(point_z), FP_OFF(point_z));
  433. printf("%04x:%04x\n", FP_SEG(pz), FP_OFF(pz));
  434. #endif
  435.         delete[] point_x;
  436.         delete[] point_y;
  437.         delete[] point_z;
  438.         point_x = px;
  439.         point_y = py;
  440.         point_z = pz;
  441.     }
  442. #ifdef DEBUG
  443.     printf("%d:(%d,%d,%d)\n", points, x, y, z);
  444. #endif
  445.  
  446.     point_x[points] = x ;
  447.     point_y[points] = y ;
  448.     point_z[points] = z ;
  449.     points++ ;
  450.     return points-1 ;
  451. }
  452.