/***********************************************************
*
*	This file is Copyright © 1990-1994 Dan Wesnor
*
*	This file and any executables resulting from compilation
*	of this file are freely distributable so long as the
*	above copyright statement is included intact.  This
*	statement of distributability is limited to this file
*	only, and does not include any other file in this
*	archive.
*
*	No gaurantees of usability are made for this file or
*	any executables generated from it.  Use at your own risk.
*
************************************************************
*
*	This program generates an MC script from a 3DDD object
*	file as generated by Impulse's renderers (Turbo Silver
*	and Imagine).  This version show how to generate objects
*	not using vertex based definitions of triangles.
*
*	The 3DDD parser is not all that great, and could be
*	improved upon.  Someone could also use this code as
*	a basis for a program which generates scripts from other 
*	object formats as well.
*
*	NOTE: be careful using this code on machines with
*	int lengths other than 32 bits!
*
***********************************************************/

#include "turbo.h"
#include <fcntl.h>
#include <stdio.h>
#include <math.h>

#define max(a,b)	(((a)>(b))?(a):(b))
#define min(a,b)	(((a)<(b))?(a):(b))

typedef struct {
	unsigned int	form,
					size,
					type;
} Form, *FormPtr;

#define MakeName(s)	(((s)[0]<<24)+((s)[1]<<16)+((s)[2]<<8)+(s)[3])

typedef struct {
	unsigned int	name,
					len;
} Chunk, *ChunkPtr;


typedef struct str_surface {
	struct str_surface	*next;
	int					num;
	COLOR				colr,
						refl,
						tran;
	UBYTE				hard,
						spec,
						index;
	char				name[32];
} Surface, *SurfacePtr;
	



#define FND_PNTS	0x1
#define FND_POSI	0x2
#define FND_NAME	0x4
#define FND_SHAP	0x8
#define FND_AXIS	0x10
#define FND_SIZE	0x20
#define FND_EDGE	0x40
#define FND_FACE	0x80
#define FND_COLR	0x100
#define FND_REFL	0x200
#define FND_TRAN	0x400
#define FND_CLST	0x800
#define FND_SPEC	0x1000
#define FND_TLST	0x2000
#define FND_RLST	0x4000
#define FND_MTTR	0x8000
#define FND_INTS	0x10000
#define FND_PRP0	0x20000


FILE *ofh=0;
char *filename;

SurfacePtr surfList=NULL;

SurfacePtr MakeSurface(cr, cg, cb, rr, rg, rb, tr, tg, tb, h, s, i)
	UBYTE	cr, cg, cb,
			rr, rg, rb,
			tr, tg, tb,
			h, s,
			i;
{
	SurfacePtr	surf;
	
	surf = surfList;
	
	while (surf) {
		if ((surf->colr[0] == cr) && (surf->colr[1] == cg) && (surf->colr[2] == cb)
				&& (surf->refl[0] == rr) && (surf->refl[1] == rg) 
				&& (surf->refl[2] == rb)
				&& (surf->tran[0] == tr) && (surf->tran[1] == tg) 
				&& (surf->tran[2] == tb)
				&& (surf->hard == h) && (surf->spec == s) 
				&& (surf->index == i))
			return surf;
		surf = surf->next;
	}

	if (!(surf = (SurfacePtr)calloc(1, sizeof(Surface)))) {
		fprintf(stdout, "Cannot allocate new surface\n");
		return surfList;
	}
	
	surf->num = surfList ? surfList->num+1 : 0;
	surf->next = surfList;
	surfList = surf;
	surf->colr[0] = cr;
	surf->colr[1] = cg;
	surf->colr[2] = cb;
	surf->refl[0] = rr;
	surf->refl[1] = rg;
	surf->refl[2] = rb;
	surf->tran[0] = tr;
	surf->tran[1] = tg;
	surf->tran[2] = tb;
	surf->hard = h;
	surf->spec = s;
	surf->index = i;
	sprintf(surf->name, "t2a_surf_%s_%d", filename, surf->num);
	
	fprintf(ofh, "surface %s {\n", surf->name);
	fprintf(ofh, "\tdiff\t<%f, %f, %f>\n", cr/255.0, cg/255.0, cb/255.0);
	if (tr && tg && tb)
		fprintf(ofh, "\ttrans\t<%f, %f, %f>\n", tr/255.0, tg/255.0, tb/255.0);
	if (rr && rg && rb)
		fprintf(ofh, "\trefl\t<%f, %f, %f>\n", rr/255.0, rg/255.0, rb/255.0);
	if (s) {
		fprintf(ofh, "\tpcoef\t%f\n", h/5.0);
		fprintf(ofh, "\tprefl\t%f\n", s/255.0);
	}
	if (i)
		fprintf(ofh, "\tindex\t%f\n", i/100.0+1.0);
	fprintf(ofh, "}\n\n");

	return surf;
}



float imn[3]={1e6, 1e6, 1e6}, imx[3]={-1e6, -1e6, -1e6};

void GetDescChunk(int ifd, int len)
{
	Chunk		chunk;
	int			whatami=0;
	int			found=0;
	int			i, p1, p2, p3;
	int			degen;
	SurfacePtr	surf;
	PNTS	 	*pnts;
	POSI 		posi;
	NAME 		name;
	SHAP 		shap;
	AXIS 		axis;
	SIZE 		size;
	EDGE 		*edge;
	FACE 		*face;
	COLR 		colr;
	REFL 		refl;
	TRAN 		tran;
	CLST 		*clst;
	SPEC 		spec;
	TLST 		*tlst;
	RLST 		*rlst;
	MTTR 		mttr;
	INTS 		ints;
	PRP0 		prp;
	
	colr.col[0] = colr.col[1] = colr.col[2] = 255;
	refl.col[0] = refl.col[1] = refl.col[2] = 0;
	tran.col[0] = tran.col[1] = tran.col[2] = 0;

	while (len) {
		len -= read(ifd, &chunk, sizeof(Chunk));
		chunk.len += chunk.len % 2;

		if (chunk.name == MakeName("NAME")) {
			len -= read(ifd, &name, sizeof(NAME));
			fprintf(stdout, "\t\tNAME:  %s\n", name.Name);
		}

		else if (chunk.name == MakeName("SHAP")) {
			len -= read(ifd, &shap, sizeof(SHAP));
			fprintf(stdout, "\t\tSHAP:  ");
			switch (shap.Lamp) {
				case LMP_NOTALAMP:
					whatami = shap.Shape;
					switch (shap.Shape) {
						case SHP_SPHERE:
							fprintf(stdout, "sphere\n");
							break;
				
						case SHP_STENCIL:
							fprintf(stdout, "stencil\n");
							break;

						case SHP_AXIS:
							fprintf(stdout, "axis\n");
							break;
					
						case SHP_FACETS:
							fprintf(stdout, "facets\n");
							break;
				
						case SHP_SURFACE:
							fprintf(stdout, "Surface\n");
							break;
				
						case SHP_GROUND:
							fprintf(stdout, "Ground\n");
							break;
				
						default:
							fprintf(stdout, "Unknown:  %d\n", 
									shap.Shape);
							break;
					}
					break;

				case LMP_SUN:
					fprintf(stdout, "Lamp (Sun)\n");
					break;
				
				case LMP_LAMP:
					fprintf(stdout, "Lamp (Lamp)\n");
					break;
					
				default:
					break;
			}		
		}

		else if (chunk.name == MakeName("POSI")) {
			found |= FND_POSI;
			len -= read(ifd, &posi, sizeof(POSI));
			fprintf(stdout, "\t\tPOSI:  <%f, %f, %f>\n", 
					posi.Position.X/65536.0, 
					posi.Position.Y/65536.0, posi.Position.Z/65536.0);
		}

		else if (chunk.name == MakeName("AXIS")) {
			found |= FND_AXIS;
			len -= read(ifd, &axis, sizeof(AXIS));
			fprintf(stdout, "\t\tAXIS:  X = <%f, %f, %f>\n", 
					axis.XAxis.X/65536.0, axis.XAxis.Z/65536.0, 
					axis.XAxis.Y/65536.0);
			fprintf(stdout, "\t\t       Y = <%f, %f, %f>\n", 
					axis.YAxis.X/65536.0, axis.YAxis.Z/65536.0, 
					axis.YAxis.Y/65536.0);
			fprintf(stdout, "\t\t       Z = <%f, %f, %f>\n", 
					axis.ZAxis.X/65536.0, axis.ZAxis.Z/65536.0, 
					axis.ZAxis.Y/65536.0);
		}

		else if (chunk.name == MakeName("SIZE")) {
			found |= FND_SIZE;
			len -= read(ifd, &size, sizeof(SIZE));
			fprintf(stdout, "\t\tSIZE:  <%f, %f, %f>\n", 
					size.Size.X/65536.0, size.Size.Y/65536.0, 
					size.Size.Z/65536.0);
		}

		else if (chunk.name == MakeName("PNTS")) {
			if (pnts = (PNTS *)calloc(1, chunk.len)) {
				found |= FND_PNTS;
				len -= read(ifd, &(pnts->PCount), 2);
				len -= read(ifd, pnts->Points, chunk.len-2);
				fprintf(stdout, "\t\tPNTS:  %d\n", pnts->PCount);
#ifdef COUNT_UNIQUE_POINTS
				{
					int i, j, u, uc=0;
					for (i=0; i<pnts->PCount; i++)
					{
						u = 1;
						for (j=0; j<pnts->PCount; j++)
							if ((pnts->Points[i].X == pnts->Points[j].X)
									&& (pnts->Points[i].Y == pnts->Points[j].Y)
									&& (pnts->Points[i].Z == pnts->Points[j].Z))
							if (i != j)
							{
								u = 0;
								break;
							}
						if (u)
							uc++;
					}
					printf("%d unique points found.\n", uc);
#endif
				}
			}
			else
				fprintf(stdout, "PNTS found, no memory to load\n");
		}

		else if (chunk.name == MakeName("EDGE")) 
		{
			if (edge = (EDGE *)calloc(1, chunk.len)) 
			{
				found |= FND_EDGE;
				len -= read(ifd, edge, chunk.len);
				fprintf(stdout, "\t\tEDGE:  %d\n", edge->ECount);
			}
			else
				fprintf(stdout, "EDGE found, no memory to load\n");
		}

		else if (chunk.name == MakeName("FACE")) 
		{
			if (face = (FACE *)calloc(1, chunk.len)) 
			{
				found |= FND_FACE;
				len -= read(ifd, face, chunk.len);
				fprintf(stdout, "\t\tFACE:  %d\n", face->TCount);
			}
			else
				fprintf(stdout, "FACE found, no memory to load\n");
		}

		else if (chunk.name == MakeName("COLR")) 
		{
			found |= FND_COLR;
			len -= read(ifd, &colr, sizeof(COLR));
			fprintf(stdout, "\t\tCOLR:  %d %d %d\n", 
					colr.col[0], colr.col[1], colr.col[2]);
		}

		else if (chunk.name == MakeName("REFL")) 
		{
			found |= FND_REFL;
			len -= read(ifd, &refl, sizeof(REFL));
			fprintf(stdout, "\t\tREFL:  %d %d %d\n", 
					refl.col[0], refl.col[1], refl.col[2]);
		}

		else if (chunk.name == MakeName("TRAN")) 
		{
			found |= FND_TRAN;
			len -= read(ifd, &tran, sizeof(TRAN));
			fprintf(stdout, "\t\tTRAN:  %d %d %d\n", 
					tran.col[0], tran.col[1], tran.col[2]);
		}

		else if (chunk.name == MakeName("CLST")) 
		{
			if (clst = (CLST *)calloc(1, chunk.len)) 
			{
				found |= FND_CLST;
				len -= read(ifd, clst, chunk.len);
				fprintf(stdout, "\t\tCLST:  %d\n", clst->count);
			}
			else
				fprintf(stdout, "CLST found, no memory to load\n");
		}

		else if (chunk.name == MakeName("RLST")) 
		{
			if (rlst = (RLST *)calloc(1, chunk.len)) 
			{
				found |= FND_RLST;
				len -= read(ifd, rlst, chunk.len);
				fprintf(stdout, "\t\tRLST:  %d\n", rlst->count);
			}
			else
				fprintf(stdout, "RLST found, no memory to load\n");
		}

		else if (chunk.name == MakeName("TLST")) 
		{
			if (tlst = (TLST *)calloc(1, chunk.len)) 
			{
				found |= FND_TLST;
				len -= read(ifd, tlst, chunk.len);
				fprintf(stdout, "\t\tTLST:  %d\n", tlst->count);
			}
			else
				fprintf(stdout, "TLST found, no memory to load\n");
		}

		else if (chunk.name == MakeName("TPAR")) 
		{
			fprintf(stdout, "\t\tTPAR:  found\n");
			lseek(ifd, chunk.len, 1);
			len -= chunk.len;
		}

		else if (chunk.name == MakeName("SURF")) 
		{
			fprintf(stdout, "\t\tSURF:  found\n");
			lseek(ifd, chunk.len, 1);
			len -= chunk.len;
		}

		else if (chunk.name == MakeName("MTTR")) 
		{
			found |= FND_MTTR;
			len -= read(ifd, &mttr, sizeof(MTTR));
			switch (mttr.Type) 
			{
				case RFR_AIR:
					fprintf(stdout, "\t\tMTTR:  %f (Air)\n", VAL_AIR);
					break;

				case RFR_WATER:
					fprintf(stdout, "\t\tMTTR:  %f (Water)\n", 
							VAL_WATER);
					break;

				case RFR_GLASS:
					fprintf(stdout, "\t\tMTTR:  %f (Glass)\n", 
							VAL_GLASS);
					break;

				case RFR_CRYSTAL:
					fprintf(stdout, "\t\tMTTR:  %f (Crystal)\n", 
							VAL_CRYSTAL);
					break;

				case RFR_CUSTOM:
					fprintf(stdout, "\t\tMTTR:  %f (Custom)\n", 
							VAL_CUSTOM(mttr.Index));
					break;

				default:
					fprintf(stdout, "\t\tMTTR:  unknown type %d\n", 
							mttr.Type);
					break;
			}
		}

		else if (chunk.name == MakeName("SPEC")) 
		{
			found |= FND_SPEC;
			len -= read(ifd, &spec, sizeof(SPEC));
			fprintf(stdout, "\t\tSPEC:  Spec=%d, Hard=%d\n", 
					spec.Specularity, spec.Hardness);
		}

		else if (chunk.name == MakeName("PRP0")) 
		{
			found |= FND_PRP0;
			len -= read(ifd, &prp, sizeof(PRP0));
			fprintf(stdout, "\t\tPRP0:  Blend = %d\n", prp.Props[PRP_BLEND]);
			fprintf(stdout, "\t\t       Rough = %d\n", prp.Props[PRP_SMOOTH]);
			fprintf(stdout, "\t\t       Shade = %s\n", 
					prp.Props[PRP_SHADE] ? "ON" : "OFF");
			fprintf(stdout, "\t\t       Phong = %s\n", 
					prp.Props[PRP_PHONG] ? "OFF" : "ON");
			fprintf(stdout, "\t\t       Glossy = %s\n", 
					prp.Props[PRP_GLOSSY] ? "ON" : "OFF");
			fprintf(stdout, "\t\t       Quick = %s\n", 
					prp.Props[PRP_QUICK] ? "ON" : "OFF");
		}

		else if (chunk.name == MakeName("INTS")) 
		{
			found |= FND_INTS;
			len -= read(ifd, &ints, sizeof(INTS));
			fprintf(stdout, "\t\tINTS:  %f\n", ints.Intensity/65536.0);
		}

		else if (chunk.name == MakeName("STRY")) 
		{
			fprintf(stdout, "\t\tSTRY:  found\n");
			lseek(ifd, chunk.len, 1);
			len -= chunk.len;
		}

		else 
		{
			fprintf(stdout, "\t\t%.4s:  Found unknown chunk, skipping\n", &chunk.name);
			lseek(ifd, chunk.len, 1);
			len -= chunk.len;
		}
	}

	if (whatami == SHP_AXIS) 
	{
		float mx[3]={-1e6, -1e6, -1e6}, mn[3]={1e6, 1e6, 1e6};

		degen = 0;
		
		fprintf(stdout, "***\tDumping axis type object\n");

		fprintf(ofh, "/* --------- %s --------- */\n", name.Name);

		if ((found & FND_PRP0) && (!(prp.Props[PRP_SMOOTH])))
			fprintf(ofh, "");

		if ((found & (FND_PNTS | FND_EDGE | FND_FACE)) 
				!= (FND_PNTS | FND_EDGE | FND_FACE))
			fprintf(stdout, "***\tError:  One of PNTS, EDGE, or FACE not found or allocated\n");
		else 
		{
			for (i=0; i<pnts->PCount; i++) 
			{
				pnts->Points[i].X *= -1.0;
				mx[0] = max(mx[0], pnts->Points[i].X/65536.0);
				mn[0] = min(mn[0], pnts->Points[i].X/65536.0);
				imx[0] = max(imx[0], pnts->Points[i].X/65536.0);
				imn[0] = min(imn[0], pnts->Points[i].X/65536.0);
				mx[1] = max(mx[1], pnts->Points[i].Y/65536.0);
				mn[1] = min(mn[1], pnts->Points[i].Y/65536.0);
				imx[1] = max(imx[1], pnts->Points[i].Y/65536.0);
				imn[1] = min(imn[1], pnts->Points[i].Y/65536.0);
				mx[2] = max(mx[2], pnts->Points[i].Z/65536.0);
				mn[2] = min(mn[2], pnts->Points[i].Z/65536.0);
				imx[2] = max(imx[2], pnts->Points[i].Z/65536.0);
				imn[2] = min(imn[2], pnts->Points[i].Z/65536.0);
			}

			for (i=0; i<face->TCount; i++) 
			{
				surf = MakeSurface(
					(found & FND_CLST)? clst->colors[i][0]: colr.col[0],
					(found & FND_CLST)? clst->colors[i][1]: colr.col[1],
					(found & FND_CLST)? clst->colors[i][2]: colr.col[2],
					(found & FND_RLST)? rlst->colors[i][0]: refl.col[0],
					(found & FND_RLST)? rlst->colors[i][1]: refl.col[1],
					(found & FND_RLST)? rlst->colors[i][2]: refl.col[2],
					(found & FND_TLST)? tlst->colors[i][0]: tran.col[0],
					(found & FND_TLST)? tlst->colors[i][1]: tran.col[1],
					(found & FND_TLST)? tlst->colors[i][2]: tran.col[2],
					(found & FND_SPEC) ? spec.Hardness : 0,
					(found & FND_SPEC) ? spec.Specularity : 0,
					(found & FND_MTTR) ? mttr.Index : 0);
					
				p1 = edge->Edges[face->Connects[i][0]][0];
				p2 = edge->Edges[face->Connects[i][0]][1];
				p3 = edge->Edges[face->Connects[i][1]][0];
				p3 = ((p1 == p3) || (p2 == p3)) ? 
						edge->Edges[face->Connects[i][1]][1] : p3;

				if ((pnts->Points[p1].X == pnts->Points[p2].X) 
						&& (pnts->Points[p1].Y == pnts->Points[p2].Y) 
						&& (pnts->Points[p1].Z == pnts->Points[p2].Z))
					degen++;
				else if ((pnts->Points[p1].X == pnts->Points[p3].X) 
						&& (pnts->Points[p1].Y == pnts->Points[p3].Y) 
						&& (pnts->Points[p1].Z == pnts->Points[p3].Z))
					degen++;
				else if ((pnts->Points[p2].X == pnts->Points[p3].X) 
						&& (pnts->Points[p2].Y == pnts->Points[p3].Y) 
						&& (pnts->Points[p2].Z == pnts->Points[p3].Z))
					degen++;
				else 
				{
					fprintf(ofh, "triangle {\n");
					fprintf(ofh, "\tloc\t\t<%f, %f, %f>\n", 
						pnts->Points[p1].X/65536.0,
						pnts->Points[p1].Z/65536.0, 
						pnts->Points[p1].Y/65536.0);
					fprintf(ofh, "\tv1\t\t<%f, %f, %f>\n",
						(pnts->Points[p2].X-pnts->Points[p1].X)/65536.0,
						(pnts->Points[p2].Z-pnts->Points[p1].Z)/65536.0,
						(pnts->Points[p2].Y-pnts->Points[p1].Y)/65536.0);
					fprintf(ofh, "\tv2\t\t<%f, %f, %f>\n",
						(pnts->Points[p3].X-pnts->Points[p1].X)/65536.0,
						(pnts->Points[p3].Z-pnts->Points[p1].Z)/65536.0,
						(pnts->Points[p3].Y-pnts->Points[p1].Y)/65536.0);
					fprintf(ofh, "\tsurface\t%s\n", surf->name);
					fprintf(ofh, "}\n\n");
				}
			}
			fprintf(stdout, "%d of %d triangle degenerative\n", degen, face->TCount);
			fprintf(stdout, "***\tAxis bounds: <%f, %f, %f> - <%f, %f, %f>\n",
					 mn[0], mn[2], mn[1], mx[0], mx[2], mx[1]);
		}
		if (!(prp.Props[PRP_SMOOTH]))
			fprintf(ofh, "");

	}

	if (found & FND_PNTS)
		free(pnts);
	if (found & FND_EDGE)
		free(edge);
	if (found & FND_FACE)
		free(face);
	if (found & FND_TLST)
		free(tlst);
	if (found & FND_RLST)
		free(rlst);
	if (found & FND_CLST)
		free(clst);
}






void GetObjChunk(int ifd, int len)
{
	Chunk	chunk;
	
	while (len) 
	{
		len -= read(ifd, &chunk, sizeof(Chunk));

		if (chunk.name == MakeName("EXTR")) 
		{
			fprintf(stdout, "\tEXTR:  found\n");
			lseek(ifd, chunk.len, 1);
			len -= chunk.len;
		}
		
		else if (chunk.name == MakeName("TOBJ")) 
		{
			fprintf(stdout, "\tTOBJ:\n\n");
			lseek(ifd, chunk.len, 1);
			len -= chunk.len;
		}
		
		else if (chunk.name == MakeName("DESC")) 
		{
			fprintf(stdout, "\tDESC:\n");
			GetDescChunk(ifd, chunk.len);
			len -= chunk.len;
		}
		
		else 
		{
			fprintf(stdout, "\t%.4s:  Found unknown chunk\n", &chunk.name);
			lseek(ifd, chunk.len, 1);
			len -= chunk.len;
		}
	}
}






void GetInfoChunk(int ifd, int len)
{
	Chunk	chunk;
	
	while (len) 
	{
		len -= read(ifd, &chunk, sizeof(Chunk));

		if (chunk.name == MakeName("BRSH")) 
		{
			BRSH brsh;
			len -= read(ifd, &brsh, sizeof(BRSH));
			fprintf(stdout, "\tBRSH:  #%d = %s\n", brsh.Number, brsh.Filename);
		}
		
		else if (chunk.name == MakeName("STNC")) 
		{
			STNC stnc;
			len -= read(ifd, &stnc, sizeof(STNC));
			fprintf(stdout, "\tSTNC:  #%d = %s\n", stnc.Number, stnc.Filename);
		}
		
		else if (chunk.name == MakeName("TXTR")) 
		{
			TXTR txtr;
			len -= read(ifd, &txtr, sizeof(TXTR));
			fprintf(stdout, "\tTXTR:  #%d = %s\n", txtr.Number, txtr.Filename);
		}
		
		else if (chunk.name == MakeName("OBSV")) 
		{
			OBSV obsv;
			len -= read(ifd, &obsv, sizeof(OBSV));
			fprintf(stdout, "\tOBSV:  Location = <%f, %f, %f>n", obsv.Camera.X/65536.0, obsv.Camera.Y/65536, obsv.Camera.Z/65536.0);
			fprintf(stdout, "\t       Rotate = <%f, %f, %f>\n", obsv.Rotate.X/65536.0, obsv.Rotate.Y/65536, obsv.Rotate.Z/65536.0);
			fprintf(stdout, "\t       Focal Len. = %f\n", obsv.Focal/65536.0);
		}
		
		else if (chunk.name == MakeName("OTRK")) 
		{
			OTRK otrk;
			len -= read(ifd, &otrk, sizeof(OTRK));
			fprintf(stdout, "\tOTRK:  %s\n", otrk.Trackname);
		}
		
		else if (chunk.name == MakeName("OSTR")) 
		{
			fprintf(stdout, "\tOSTR:  found\n");
			lseek(ifd, chunk.len, 1);
			len -= chunk.len;
		}
		
		else if (chunk.name == MakeName("FADE")) 
		{
			fprintf(stdout, "\tFADE:  found\n");
			lseek(ifd, chunk.len, 1);
			len -= chunk.len;
		}
		
		else if (chunk.name == MakeName("SKYC")) 
		{
			fprintf(stdout, "\tSKYC:  found\n");
			lseek(ifd, chunk.len, 1);
			len -= chunk.len;
		}
		
		else if (chunk.name == MakeName("AMBI")) 
		{
			fprintf(stdout, "\tAMBI:  found\n");
			lseek(ifd, chunk.len, 1);
			len -= chunk.len;
		}
		
		else if (chunk.name == MakeName("GLB0")) 
		{
			fprintf(stdout, "\tGLB0:  found\n");
			lseek(ifd, chunk.len, 1);
			len -= chunk.len;
		}
		
		else 
		{
			fprintf(stdout, "\t%.4s:  Found unknown chunk\n", &chunk.name);
			lseek(ifd, chunk.len, 1);
			len -= chunk.len;
		}
	}
}






void main(int argc, char *argv[])
{
	int		ifd=-1;
	Form	form;
	Chunk	chunk;
	int		len;
	
	if (argc < 3) 
	{
		fprintf(stdout, "usage: turbo2arrt turbofile.in arrtscript.out\n");
		goto cleanup;
	}
	
	if ((ifd = open(argv[1], O_RDONLY)) == -1) 
	{
		fprintf(stdout, "turbo2arrt:  could not open input file %s\n", argv[1]);
		goto cleanup;
	}
	
	if (!(ofh = fopen(argv[2], "w"))) 
	{
		fprintf(stdout, "turbo2arrt:  could not open output file %s\n", argv[2]);
		goto cleanup;
	}

	filename = argv[1];

	read(ifd, &form, sizeof(Form));
	if ((form.form != MakeName("FORM")) || (form.type != MakeName("TDDD"))) 
	{
		fprintf(stdout, "turbo2arrt:  %s is not proper file type\n", argv[1]);
		goto cleanup;
	}
	
	len = read(ifd, &chunk, sizeof(Chunk));
	while (len) 
	{
		if (chunk.name == MakeName("INFO")) 
		{
			fprintf(stdout, "INFO:\n");
			GetInfoChunk(ifd, chunk.len);
			fprintf(stdout, "\n\n");
		}
		
		else if (chunk.name == MakeName("OBJ ")) 
		{
			fprintf(stdout, "OBJ :\n");
			GetObjChunk(ifd, chunk.len);
			fprintf(stdout, "\n");
		}

		else 
		{
			fprintf(stdout, "%.4s:  Found unknown chunk\n\n\n", &chunk.name);
			lseek(ifd, chunk.len, 1);
		}

		len = read(ifd, &chunk, sizeof(Chunk));
	}

	fprintf(stdout, "***\n\tBounds: <%f, %f, %f> - <%f, %f, %f>\n", imn[0], imn[2], imn[1], imx[0], imx[2], imx[1]);

cleanup:

	if (ifd != -1)
		close(ifd);
	if (ofh)
		fclose(ofh);
}
