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 >
Wrap
C/C++ Source or Header
|
1995-12-06
|
10KB
|
452 lines
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dos.h>
#include "suflib.h"
#include "token.h"
#if 0
#ifdef DEBUG
#define STATIC
#else
#define STATIC static
#include "token.c"
#endif
#endif
static const int MAX = 32767;
static const int AllocUnit = 32;
static SufFile *top = NULL;
static int usepoly = FALSE;
Object *SufFile::OpenObject(char *fname, char *oname)
{
SufFile *s = OpenSuf(fname);
if (s == NULL) {
return NULL;
}
if (oname == NULL) {
return s->object[0];
}
for (int i = 0; i < MaxObject; ++i) {
if (s->object[i] == NULL) {
break;
}
if (strcmpi(s->object[i]->name, oname) == 0) {
return s->object[i];
}
}
return NULL;
}
SufFile *SufFile::OpenSuf( char *fname )
{
SufFile *s;
for (s = top; s != NULL; s = s -> next) {
if (strcmpi(s->filename, fname) == 0) {
return s;
}
}
s = new SufFile(fname);
if (s->object[0] == NULL) {
delete s;
return NULL;
}
s->next = top;
top = s;
return s;
}
SufFile::SufFile( char *fname )
{
int i;
char token[32];
strcpy(filename, fname);
next = NULL;
TokenReader tokenread(fname);
if (!tokenread.Suceed()) {
#ifdef DEBUG
printf("cannot open file %s\n", fname);
#endif
object[0] = NULL;
return;
}
for (i = 0; i < MaxObject-1; ++i) {
if (tokenread.GetToken( token ), strcmpi( token, "obj" ) == 0) {
#ifdef DEBUG
printf("read object start\n");
#endif
object[i] = new Object(&tokenread);
#ifdef DEBUG
printf("read object end\n");
#endif
if (object[i]->Succeed() == FALSE) {
delete object[i];
--i;
}
object[i]->filename = filename;
} else {
break;
}
}
object[i] = NULL;
#ifdef DEBUG
for (i = 0; i < MaxObject-1; ++i) {
printf("object[%d] = %04x:%04x\n", i, FP_SEG(object[i]), FP_OFF(object[i]));
}
#endif
}
SufFile::~SufFile()
{
for (int i = 0; object[i] != NULL && i < MaxObject-1; ++i) {
object[i]->Delete();
}
}
int Object::Succeed(void)
{
if (point_x == NULL || point_y == NULL || point_z == NULL
|| line_1 == NULL || line_2 == NULL) {
return FALSE;
}
return TRUE;
}
void Object::UsePoly(void)
{
usepoly = TRUE;
}
int Object::IsPoly(void)
{
return usepoly;
}
Object::Object()
{
point_x = point_y = point_z = line_1 = line_2 = poly = polypoint = NULL;
}
Object::Object(TokenReader *tokenread)
{
char token[32] ;
points = 0 ;
lines = 0 ;
polys = 0;
polypoints = 0;
maxx = -MAX ;
maxy = -MAX ;
maxz = -MAX ;
minx = MAX ;
miny = MAX ;
minz = MAX ;
copy = 1;
point_x = point_y = point_z = line_1 = line_2 = poly = polypoint = NULL;
allocpoints = alloclines = allocpolys = allocpolypoints = 0;
polygons = 0;
if ( tokenread->GetToken( token ) ,strcmpi( token, "suf" ) ) {
#ifdef DEBUG
printf("%s %d: not exist suf!\n",
tokenread->GetFileName(), tokenread->GetFileLine());
#endif
return;
}
tokenread->GetToken( token ) ;
strcpy( name, token );
#ifdef DEBUG
printf("read:%s\n", name);
#endif
if ( tokenread->GetToken( token ), token[0] == '{' ) {
allocpoints = alloclines = AllocUnit;
point_x = new int[allocpoints];
point_y = new int[allocpoints];
point_z = new int[allocpoints];
line_1 = new int[alloclines];
line_2 = new int[alloclines];
if (usepoly) {
allocpolys = allocpolypoints = AllocUnit;
poly = new int[allocpolys] ;
polypoint = new int[allocpolypoints];
}
while ( tokenread->GetToken( token ), token[0] != '}' )
{
if ( !strcmpi( token, "atr" ) ) {
tokenread->GetToken( token ) ;
} else if ( !strcmpi( token, "prim" ) ) {
readpoly(tokenread) ;
// polygons++;
}
}
}
for (int i = 0; i < points; ++i) {
if (minx > point_x[i]) minx = point_x[i];
if (maxx < point_x[i]) maxx = point_x[i];
if (miny > point_y[i]) miny = point_y[i];
if (maxy < point_y[i]) maxy = point_y[i];
if (minz > point_z[i]) minz = point_z[i];
if (maxz < point_z[i]) maxz = point_z[i];
}
#if 0
for (i = 0; i < polys; ++i) {
for (int j = poly[i]; polypoint[j] != POLY_SEPARATER; ++j) {
logprintf("%d..", polypoint[j]);
}
logprintf("\n");
}
#endif
// for (i = 0; i < polys; ++i) {
// int *p = polypoint + poly[i];
#ifdef DEBUG
for (int i = 0; i < lines; ++i) {
printf("\t(%d,%d,%d)-(%d,%d,%d)\n",
point_x[line_1[i]],
point_y[line_1[i]],
point_z[line_1[i]],
point_x[line_2[i]],
point_y[line_2[i]],
point_z[line_2[i]] );
}
#endif
return;
}
Object::~Object()
{
if (point_x != NULL) delete[] point_x;
if (point_y != NULL) delete[] point_y;
if (point_z != NULL) delete[] point_z;
if (line_1 != NULL) delete[] line_1;
if (line_2 != NULL) delete[] line_2;
if (poly != NULL) delete[] poly;
if (polypoint != NULL) delete[] polypoint;
}
void Object::Delete(void)
{
if (--copy <= 0) {
delete this;
}
}
Object *Object::Copy(void)
{
copy++;
return this;
}
void Object::readpoly( TokenReader *tokenread)
{
char token[32] ;
int skip = 0, i ;
int x, y, z, line1=0, line2=0, lines=0 ;
int polylines = 1;
tokenread->GetToken( token ) ;
if ( !strcmpi( token, "poly" ) ) {
skip = 0 ;
} else if ( !strcmpi( token, "shade" ) ) {
skip = 3 ;
} else if ( !strcmpi( token, "uvpoly" ) ) {
skip = 2 ;
} else if ( !strcmpi( token, "uvshade" ) ) {
skip = 5 ;
} else {
#ifdef DEBUG
printf("%s %d: poly | uvpoly |uvpoly | uvshade is expected!\n",
tokenread->GetFileName(), tokenread->GetFileLine());
#endif
return ;
}
if ( tokenread->GetToken( token ), token[0] == '(' ) {
tokenread->GetToken( token ) ;
if ( token[0] == ')' )
return ;
x= atoi( token ) ;
tokenread->GetToken( token ) ;
if ( token[0] == ')' )
return ;
y = atoi( token ) ;
tokenread->GetToken( token ) ;
if ( token[0] == ')' )
return ;
z = atoi( token ) ;
lines = line1 = point(x, y, z ) ;
if (usepoly) {
polyset(polypoints);
polypointset(line1);
}
for( i = skip; i > 0; --i )
{
if ( tokenread->GetToken( token ), token[0] == ')' ) {
#ifdef DEBUG
printf("cannot skip data!\n");
#endif
return ;
}
}
while ( tokenread->GetToken( token ), token[0] != ')' )
{
polylines++;
x = atoi( token ) ;
tokenread->GetToken( token ) ;
if ( token[0] == ')' )
return ;
y = atoi( token ) ;
tokenread->GetToken( token ) ;
if ( token[0] == ')' )
return ;
z = atoi( token ) ;
line2 = point( x, y, z ) ;
lineset( line1, line2 ) ;
if (usepoly) polypointset(line2);
for( i = skip; i > 0; --i )
{
if ( tokenread->GetToken( token ), token[0] == ')' )
break ;
}
line1 = line2 ;
}
lineset( line2, lines ) ;
if (usepoly) polypointset(POLY_SEPARATER);
}
polygons += polylines - 2;
return ;
}
void Object::polypointset(int point)
{
if (polypoints >= allocpolypoints) {
int *p;
p = new int[allocpolypoints + AllocUnit];
memcpy(p, polypoint, sizeof(int) * allocpolypoints);
allocpolypoints += AllocUnit;
delete polypoint;
polypoint = p;
}
polypoint[polypoints++] = point;
}
void Object::polyset(int polybegin)
{
if (polys >= allocpolys) {
int *p;
p = new int[allocpolys + AllocUnit];
memcpy(p, poly, sizeof(int) * allocpolys);
allocpolys += AllocUnit;
delete poly;
poly = p;
}
poly[polys++] = polybegin;
}
void Object::lineset(int line1, int line2 )
{
int i ;
if ( line1 == line2 ) {
return;
}
if ( line1 > line2 ) {
i = line2 ;
line2 = line1 ;
line1 = i ;
}
for( i = 0; i < lines; ++i ) {
if ( line1 == line_1[i] && line2 == line_2[i] ) {
return ;
}
}
if (lines >= alloclines) {
int *l1, *l2;
l1 = new int[alloclines + AllocUnit];
l2 = new int[alloclines + AllocUnit];
memcpy(l1, line_1, sizeof(int) * alloclines);
memcpy(l2, line_2, sizeof(int) * alloclines);
alloclines += AllocUnit;
#ifdef DEBUG
printf("%04x:%04x->", FP_SEG(line_1), FP_OFF(line_1));
printf("%04x:%04x, ", FP_SEG(l1), FP_OFF(l1));
printf("%04x:%04x->", FP_SEG(line_2), FP_OFF(line_2));
printf("%04x:%04x\n", FP_SEG(l2), FP_OFF(l2));
#endif
delete[] line_1;
delete[] line_2;
line_1 = l1;
line_2 = l2;
}
line_1[lines] = line1 ;
line_2[lines] = line2 ;
lines++ ;
#ifdef DEBUG
printf("(%d->%d)\n", line1, line2);
#endif
}
int Object::point(int x, int y, int z)
{
int i ;
for(i = 0; i < points; ++i) {
if (x == point_x[i] && y == point_y[i] && z == point_z[i]) {
return i ;
}
}
if (points >= allocpoints) {
int *px, *py, *pz;
px = new int[allocpoints + AllocUnit];
py = new int[allocpoints + AllocUnit];
pz = new int[allocpoints + AllocUnit];
memcpy(px, point_x, sizeof(int) * allocpoints);
memcpy(py, point_y, sizeof(int) * allocpoints);
memcpy(pz, point_z, sizeof(int) * allocpoints);
allocpoints += AllocUnit;
#ifdef DEBUG
printf("%04x:%04x->", FP_SEG(point_x), FP_OFF(point_x));
printf("%04x:%04x, ", FP_SEG(px), FP_OFF(px));
printf("%04x:%04x->", FP_SEG(point_y), FP_OFF(point_y));
printf("%04x:%04x, ", FP_SEG(py), FP_OFF(py));
printf("%04x:%04x->", FP_SEG(point_z), FP_OFF(point_z));
printf("%04x:%04x\n", FP_SEG(pz), FP_OFF(pz));
#endif
delete[] point_x;
delete[] point_y;
delete[] point_z;
point_x = px;
point_y = py;
point_z = pz;
}
#ifdef DEBUG
printf("%d:(%d,%d,%d)\n", points, x, y, z);
#endif
point_x[points] = x ;
point_y[points] = y ;
point_z[points] = z ;
points++ ;
return points-1 ;
}