#include "stdio.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "dos.h"
#include "fcntl.h"

#define precision 256

char fichent[256]="objeto.cob";
char fichsal[256]="objeto.obj";
char buscanobj[]="PolH";
char buscanpun[]="World Vertices";
char buscatext[]="Texture Vertices";
char buscacent[]="center";
char buscanpol[]="Faces";
char buscanver[]="verts";
char buscavert[]="<";
char buscatran[]="Transform";
char buscaeje[]="x axis";
char buscamat[]="Mat1";
char buscanmat[]="mat#";
char buscaparent[]="Parent";
char buscaior[]="ior";
char buscapmat[]="mat";
char buscaid[]="Id";
char buscatextu[]="texture:";
char buscaluz[]="LocLight";
char buscalaser[]="InfLight";

char * buffer;
char * punt,* punt2;
FILE * fich;
int fichs;
unsigned cuenta;
int nobj,npun,npol,npols,npunac,nver,color,nluces,nlasers;
long flong,flonge;
double x,y,z;
unsigned char letra;

int ntext,nmat;
char *nomtex[1024];		     /* 1024 texturas como mucho */
long materiales[1024][2];	     /* 1024 texturas como mucho */
long largo,largo2,largo3;

void main (int argc, char * argv[])
{
double doble,cenx,ceny,cenz,centx,centy,centz;
double m11,m12,m13,m21,m22,m23,m31,m32,m33;
double xt,yt,zt,cxmax,cxmin,cymax,cymin,czmax,czmin;
int cont2,entero,nptext;
int ntext,ntexac,mat;
long cont;

printf ("C2O V 1.5 -- Convertidor de Caligari ASCII a Asm-Flat (.Cob->.Obj)\n");

if (argc>=2)
{
strcpy (fichent,argv[1]);
strcpy (fichsal,argv[1]);
strupr (fichent);
if (strstr(fichent,".")==NULL)
	strcat (fichent,".COB");
}
fich=fopen (fichent,"r");
if (fich==NULL)
{
	printf ("\nNo es posible abrir %s\nConversi˘n interrumpida\n",fichent);
	return;
}
flonge =0;
while (!feof(fich))
	{
	fgetc(fich);
	flonge++;
	}
fclose (fich);
buffer =(char *) malloc (flonge-1);
if (buffer ==NULL)
{
	printf ("\nNo hay suficiente memoria\nConversi˘n interrumpida\n");
	return;
}
fopen (fichent,"r");
flonge=0;
while (!feof (fich))
	{
	buffer[flonge]=fgetc(fich);
	flonge++;
	}
fclose (fich);

/* el fichero nuevo lo abro con funciones del dos */
if (argc>=3)
{
strcpy (fichsal,argv [2]);
}
if (argc>=2)
{
strupr (fichsal);
punt=strstr (fichsal,".");
if (punt!=NULL)
	{
	punt [0]='.';
	punt [1]='O';
	punt [2]='B';
	punt [3]='J';
	punt [4]='\0';
	}
else
	strcat (fichsal,".OBJ");
}
if ((_dos_creat (fichsal,_A_NORMAL,&fichs)) != 0)
{
	free (buffer);
	printf ("\nNo es posible abrir %s\nConversi˘n interrumpida\n",fichsal);
	return;
}
/* proceso las texturas */
punt=buffer;
ntext=0;
punt=strstr (punt,buscatextu);

while (punt!=NULL)
{
		/* apunta solo al ultimo directorio */
		while (punt[0]!='\n')
				punt++;
		while (punt[0]!='\\')
				punt--;
                punt--;
		while (punt[0]!='\\')
				punt--;
		punt++;
		ntexac=0;
		/* busco si hay alguno igual */
		for (cont=0;cont<ntext;cont++)
		{
			punt2=nomtex[cont];
			cont2=0;
			while (punt[cont2]==punt2[cont2]&&punt[cont2]!='\n'&&punt2[cont2]!='\n')
				cont2++;
			if (punt[cont2]=='\n'&&punt2[cont2]=='\n')
			ntexac=1;	/* no hay mat nuevo */
		}
		if (ntexac==0)
		{
		nomtex[ntext]=punt;
		ntext++;
		}
	punt=strstr(punt,buscatextu);

}
_dos_write (fichs,&ntext,2,&cuenta);
flong=2;
for (cont=0;cont <ntext;cont++)
{
	punt=nomtex[cont];
	cont2=0;
	letra=punt[cont2];
	while (letra!='\n')
	{
	  _dos_write (fichs,&letra,1,&cuenta);
	  flong++;
	  cont2++;
	  letra=punt[cont2];
	}
	letra=0;
	_dos_write (fichs,&letra,1,&cuenta);
	flong++;
}
/* hallo el numero de subobjetos,el numero de puntos y el numero de puntos
   de textura */
nobj=0;
npun=0;
npols=0;
nptext=0;
nluces=0;
punt=buffer;
punt=strstr (punt,buscanobj);
while (punt!=NULL)
	{
	nobj++;
	punt=strstr (punt,buscanpun);
	npun+=strtod (punt+14,NULL);
	punt=strstr (punt,buscatext);
	nptext+=strtod (punt+16,NULL);
	punt=strstr (punt,buscanpol);
	npols+=strtod (punt+5,NULL);
	punt=strstr (punt,buscanobj);
	}
/* busco las luces de posicion */
punt=buffer;
punt=strstr(punt,buscaluz);
while (punt!=NULL)
	{
	nluces++;
	punt++;
	punt=strstr (punt,buscaluz);
	}

/* busco los lasers */
nlasers=0;
punt=buffer;
punt=strstr(punt,buscalaser);
while (punt!=NULL)
	{
        nlasers++;
	punt++;
        punt=strstr (punt,buscalaser);
	}
if (nluces>0) nobj++;
printf ("\nNombre Caligari: %s\n",fichent);
printf ("Longitud: %u bytes\n",flonge-1);
printf ("Subobjetos: %d\n",nobj);
printf ("Puntos 3D: %d puntos+%d centros+%d luces=%d\n",npun,nobj,nluces,npun+nobj+nluces);
printf ("Puntos de textura: %d\n",nptext);
printf ("Caras: %d\n",npols);
printf ("Luces de posicion: %d\n",nluces);
printf ("Numero de lasers: %d\n",nlasers);
npun=npun+nobj+nluces;
_dos_write (fichs,&npun,2,&cuenta);
_dos_write (fichs,&nobj,2,&cuenta);
_dos_write (fichs,&nptext,2,&cuenta);
_dos_write (fichs,&nlasers,2,&cuenta);
_dos_write (fichs,&largo,(4*nobj),&cuenta);
flong+=8+(nobj*4)+(nobj*2)+(npun*6)+(nptext*8)+(nlasers*6);
nmat=0;
punt=buffer;
punt=strstr(punt,buscamat);
while (punt!=NULL)
{
	punt=strstr (punt,buscaparent);
	punt+=6;
	largo=strtod (punt,NULL);
	punt=strstr (punt,buscanmat);
	punt+=4;
	largo+=strtod (punt,NULL);
	materiales[nmat][0]=largo;
	punt=strstr (punt,buscaior);
	punt+=3;
	strtod (punt,&punt);
	punt+=1;
	if (punt[7]==':')
	{
	while (punt[0]!='\n')
			punt++;
	while (punt[0]!='\\')
			punt--;
	punt--;
	while (punt[0]!='\\')
			punt--;
	punt++;
	ntexac=0;
	cont2=0;
		while (ntexac==0)
		{
		punt2=nomtex[cont2];
		cont=0;
		while (punt[cont]==punt2[cont]&&punt[cont]!='\n'&&punt2[cont]!='\n')
			cont++;
		if (punt[cont]=='\n'&&punt2[cont]=='\n')
			ntexac=1;	/* es esa la textura */
		else
			cont2++;
		}
	materiales[nmat][1]=cont2+256;
	}
	else
	{
	/*calcula el color*/
	}
	nmat++;
	punt=strstr(punt,buscamat);
	}
printf ("Materiales: %d\n",nmat);
printf ("Texturas: ");
if (ntext==0)
	{
	printf (" No hay");
	}
else
	{
	printf ("%d",ntext);
	for (cont=0;cont<ntext;cont++)
	{
	punt=nomtex[cont];
		printf ("\n| %d: ",cont);
		cont2=0;
		while (punt[cont2]!='\n')
			{
			putchar (punt[cont2]);
			cont2++;
			}
	}
	}
printf ("\n\nProcesando...");
/* hallo los puntos de las texturas */
punt=buffer;
punt=strstr (punt,buscanobj);
while (punt!=NULL)
	{
	punt=strstr (punt,buscatext);
	punt+=16;
	ntext=strtod (punt,&punt);
	for (cont =0;cont<(ntext*2);cont++)
	{
	doble=strtod (punt,&punt);
	doble=doble*1048576;
	largo=doble;
	if (largo==1*1048576) largo--;
	_dos_write (fichs,&largo,4,&cuenta);
	}
	punt=strstr (punt,buscanobj);
	}
/* hallo el centro total*/
punt=buffer;
punt=strstr (punt,buscanobj);
punt=strstr (punt,buscacent);
punt+=6;
cxmax=strtod (punt,&punt);
cxmin=cxmax;
cymax=strtod (punt,&punt);
cymin=cymax;
czmax=strtod (punt,&punt);
czmin=czmax;
punt=strstr (punt,buscanobj);
while (punt!=NULL)
	{
	punt=strstr (punt,buscacent);
	punt+=6;
	centx=strtod (punt,&punt);
	if (centx>cxmax) cxmax=centx;
	if (centx<cxmin) cxmin=centx;
	centy=strtod (punt,&punt);
	if (centy>cymax) cymax=centy;
	if (centy<cymin) cymin=centy;
	centz=strtod (punt,&punt);
	if (centz>czmax) czmax=centz;
	if (centz<czmin) czmin=centz;
	punt=strstr (punt,buscanobj);
	}
centx=(cxmax+cxmin)/2;
centy=(cymax+cymin)/2;
centz=(czmax+czmin)/2;
/* hallo los puntos de los lasers */
punt=buffer;
punt=strstr(punt,buscalaser);
while (punt!=NULL)
	{
	/* busco la matriz de transf. */
	punt=strstr (punt,buscatran);
	punt+=9;
	m11=strtod (punt,&punt);
	m12=strtod (punt,&punt);
	m13=strtod (punt,&punt);
	cenx=strtod (punt,&punt);
	m21=strtod (punt,&punt);
	m22=strtod (punt,&punt);
	m23=strtod (punt,&punt);
	ceny=strtod (punt,&punt);
	m31=strtod (punt,&punt);
	m32=strtod (punt,&punt);
	m33=strtod (punt,&punt);
	cenz=strtod (punt,&punt);

	cenx-=centx;
	ceny-=centy;
	cenz-=centz;

	x=0;y=0;z=0;
		/* paso por la matriz de transformacion  */
		xt=(x*m11)+(y*m12)+(z*m13);
		yt=(x*m21)+(y*m22)+(z*m23);
		zt=(x*m31)+(y*m32)+(z*m33);

		xt=(xt+cenx)*precision;
		yt=(yt+ceny)*precision;
		zt=(zt+cenz)*precision;

		entero=yt;
		_dos_write (fichs,&entero,2,&cuenta);
		entero=zt;
		_dos_write (fichs,&entero,2,&cuenta);
		entero=xt;
		_dos_write (fichs,&entero,2,&cuenta);
        punt=strstr (punt,buscalaser);
	}
/* hallo los centros de cada objeto */
punt=buffer;
punt=strstr (punt,buscanobj);
while (punt!=NULL)
	{
	punt=strstr (punt,buscacent);
	punt+=6;
	x=strtod (punt,&punt);
	x=(x-centx)*precision;
	y=strtod (punt,&punt);
	y=(y-centy)*precision;
	z=strtod (punt,&punt);
	z=(z-centz)*precision;
	entero=y;
	_dos_write (fichs,&entero,2,&cuenta);
	entero=z;
	_dos_write (fichs,&entero,2,&cuenta);
	entero=x;
	_dos_write (fichs,&entero,2,&cuenta);
	punt=strstr (punt,buscanobj);
	}
/* hallo el centro del objeto de las luces */
if (nluces>0)
{
/* pongo el centro que me salga del pandero (puro tramite)*/
	entero=0;
	_dos_write (fichs,&entero,2,&cuenta);
	_dos_write (fichs,&entero,2,&cuenta);
	_dos_write (fichs,&entero,2,&cuenta);
}
/* hallo los puntos*/
punt=buffer;
punt=strstr (punt,buscanobj);
while (punt!=NULL)
	{
	/* coge las matrices y los centros */

	punt=strstr (punt,buscatran);
	punt+=9;
	m11=strtod (punt,&punt);
	m12=strtod (punt,&punt);
	m13=strtod (punt,&punt);
	cenx=strtod (punt,&punt);
	m21=strtod (punt,&punt);
	m22=strtod (punt,&punt);
	m23=strtod (punt,&punt);
	ceny=strtod (punt,&punt);
	m31=strtod (punt,&punt);
	m32=strtod (punt,&punt);
	m33=strtod (punt,&punt);
	cenz=strtod (punt,&punt);

	cenx-=centx;
	ceny-=centy;
	cenz-=centz;

	punt=strstr (punt,buscanpun);
	punt+=14;
	npun=strtod (punt,&punt);
	for (cont=0;cont<npun;cont++)
	{
		x=strtod (punt,&punt);
		y=strtod (punt,&punt);
		z=strtod (punt,&punt);

		/* paso por la matriz de transformacion  */
		xt=(x*m11)+(y*m12)+(z*m13);
		yt=(x*m21)+(y*m22)+(z*m23);
		zt=(x*m31)+(y*m32)+(z*m33);

		xt=(xt+cenx)*precision;
		yt=(yt+ceny)*precision;
		zt=(zt+cenz)*precision;

		entero=yt;
		_dos_write (fichs,&entero,2,&cuenta);
		entero=zt;
		_dos_write (fichs,&entero,2,&cuenta);
		entero=xt;
		_dos_write (fichs,&entero,2,&cuenta);
		}
	punt=strstr (punt,buscanobj);
	}
/* inserto los puntos de las luces */
punt=buffer;
punt=strstr(punt,buscaluz);
while (punt!=NULL)
	{
	/* busco la matriz de transf. */
	punt=strstr (punt,buscatran);
	punt+=9;
	m11=strtod (punt,&punt);
	m12=strtod (punt,&punt);
	m13=strtod (punt,&punt);
	cenx=strtod (punt,&punt);
	m21=strtod (punt,&punt);
	m22=strtod (punt,&punt);
	m23=strtod (punt,&punt);
	ceny=strtod (punt,&punt);
	m31=strtod (punt,&punt);
	m32=strtod (punt,&punt);
	m33=strtod (punt,&punt);
	cenz=strtod (punt,&punt);

	cenx-=centx;
	ceny-=centy;
	cenz-=centz;

	x=0;y=0;z=0;
		/* paso por la matriz de transformacion  */
		xt=(x*m11)+(y*m12)+(z*m13);
		yt=(x*m21)+(y*m22)+(z*m23);
		zt=(x*m31)+(y*m32)+(z*m33);

		xt=(xt+cenx)*precision;
		yt=(yt+ceny)*precision;
		zt=(zt+cenz)*precision;

		entero=yt;
		_dos_write (fichs,&entero,2,&cuenta);
		entero=zt;
		_dos_write (fichs,&entero,2,&cuenta);
		entero=xt;
		_dos_write (fichs,&entero,2,&cuenta);
	punt=strstr (punt,buscaluz);
	}
/* hallo los poligonos*/
punt=buffer;
punt=strstr (punt,buscanobj);
npunac=0;
ntexac=0;
	while (punt!=NULL)
	{
	punt=strstr (punt,buscaid);
	punt+=2;
	largo3=strtod (punt,NULL);

	punt=strstr (punt,buscanpun);
	punt+=14;
	npun=strtod (punt,&punt);

	punt=strstr (punt,buscatext);
	punt+=16;
	ntext=strtod (punt,&punt);

	punt=strstr (punt,buscanpol);
	punt+=5;
	npol=strtod (punt,&punt);
	_dos_write (fichs,&npol,2,&cuenta);
	color=100;
	for (cont=0;cont<npol;cont++)
	{
		/* decide si es liso o tiene textura */
		punt=strstr (punt,buscanver);
		punt+=5;
		nver=strtod (punt,NULL);

		punt=strstr(punt,buscapmat);
		punt+=3;
		largo=largo3;
		largo+=strtod (punt,NULL);
		/* busca el material */
		cont2=0;
		mat=0;
		while (cont2==0)
		{
			if (materiales[mat][0]==largo)
				cont2=1;
			else
				mat++;
		}

		if (materiales[mat][1]>=256)
		{
		/* vector con textura */
		entero=256;
		_dos_write (fichs,&entero,2,&cuenta);
		_dos_write (fichs,&nver,2,&cuenta);
		largo2=(materiales[mat][1])-256;
		_dos_write (fichs,&largo2,4,&cuenta);
		punt2=punt;	/* para el primer punto */
		flong=flong+8+((nver+1)*8);
		for (cont2=0;cont2<nver;cont2++)
		{
			punt=strstr (punt,buscavert);
			punt++;
			doble=strtod(punt,&punt);
			largo2=doble;
			largo2+=npunac;
			_dos_write (fichs,&largo2,4,&cuenta);
			punt+=1;
			largo2=strtod (punt,NULL);
			largo2+=ntexac;
			_dos_write (fichs,&largo2,4,&cuenta);
		}
		/* pongo el ultimo punto */
		punt2=strstr (punt2,buscavert);
		punt2++;
		doble=strtod(punt2,&punt2);
		largo2=doble;
		largo2+=npunac;
		_dos_write (fichs,&largo2,4,&cuenta);
		punt2+=1;
		largo2=strtod (punt2,NULL);
		largo2+=ntexac;
		_dos_write (fichs,&largo2,4,&cuenta);
		}
		else
		{
		/* vector liso sin textura */
		color=(color+10)%256;
		_dos_write (fichs,&color,2,&cuenta);
		_dos_write (fichs,&nver,2,&cuenta);
		punt2=punt;	/* para el primer punto */
		flong=flong+4+((nver+1)*4);
		for (cont2=0;cont2<nver;cont2++)
		{
			punt=strstr (punt,buscavert);
			punt++;
			doble=strtod(punt,NULL);
			largo2=doble;
			largo2+=npunac;
			_dos_write (fichs,&largo2,4,&cuenta);
		}
		/* pongo el ultimo punto */
		punt2=strstr (punt2,buscavert);
		punt2++;
		doble=strtod(punt2,NULL);
		largo2=doble;
		largo2+=npunac;
		_dos_write (fichs,&largo2,4,&cuenta);
		}
	}
	npunac+=npun;
	ntexac+=ntext;
	punt=strstr (punt,buscanobj);
	}

/* construyo el subobjeto con las luces */
if (nluces!=0)
{
entero=nluces;
_dos_write (fichs,&entero,2,&cuenta);
punt=buffer;
cont=0;
punt=strstr(punt,buscaluz);
while (punt!=NULL)
	{
	entero=258;
	_dos_write (fichs,&entero,2,&cuenta);
	largo2=cont+npunac;
	_dos_write (fichs,&largo2,4,&cuenta);
	cont++;
	punt++;
	punt=strstr (punt,buscaluz);
	}
}
flong=flong+(nluces*6);
printf ("OK\n");
printf ("\nNombre Asm: %s\n",fichsal);
printf ("Longitud: %u bytes\n",flong);
_dos_close (fichs);
free (buffer);
return;
}
