
#ifdef WIBBLEWOBBLEWIBBLEWOBBLEJELLYONAPLATE

#include "glover.h"
#include "bff_load.h"
//#define CALCGOURAUD

//OBJECTCTRL		objectctrl;
UBYTE OBEflag=NO;
NEWTMD* newtmd=0;
USHORT			numberofsegments;
UBYTE *modeltextures;
ULONG	packetbuildsize;
UBYTE	PSXTransparencies[4]={ 0,96,32,64 };	// PSX solid,semi,add,sub
PSAMODEL 	*mymodel;
NEWOBJECT	*currentobject,*parentobject,*lastobject,*tmpnewobject;
int			foundHeart;
UBYTE waterAnim[]={0,1,2,3,4,5,6,7,6,5,4,3,2,1};

void averageNormals(NEWTMD *pTMD);

void
CreateSegments(PSAMODEL *tmppsamodel ,NEWOBJECT *holdobject){ // Sets up all of Newobject from PSA

//	debugPrintf("CreateSegments()\n");

	parentobject=holdobject;
	if(tmppsamodel->child!=NULL) 
	{
		(LONG)tmppsamodel->child+=(LONG)tmppsamodel;
		CreateChildSegment((PSAMODEL*)tmppsamodel->child);
		CreateSegments((PSAMODEL*)tmppsamodel->child,tmpnewobject);		
	}		
	parentobject=holdobject;
	if (tmppsamodel->next!=NULL)
	{
		(LONG)tmppsamodel->next+=(LONG)tmppsamodel;

   		CreateNextSegment((PSAMODEL*)tmppsamodel->next);
		CreateSegments((PSAMODEL*)tmppsamodel->next,tmpnewobject);		

	}
}
/**************************************************************************************************/

void
CreateNextSegment(PSAMODEL *tmppsamodel ){

NEWOBJECT	*parenttest;

	numberofsegments++;
	tmpnewobject=(NEWOBJECT*)MALLOC(sizeof(NEWOBJECT),tmppsamodel->name);
	ASSERT(tmpnewobject);
//	debugPrintf("next object name %s \n",tmppsamodel->name);

	CreateSegment((PSAMODEL*)tmppsamodel,(NEWOBJECT*)tmpnewobject );	

//	ZeroQuaternion(&tmpnewobject->qRot);

/*	debugPrintf("keyframe move x %d \n",tmpnewobject->movekeys->vect.x);
	debugPrintf("keyframe move y %d \n",tmpnewobject->movekeys->vect.y);
	debugPrintf("keyframe move z %d \n",tmpnewobject->movekeys->vect.z);

	debugPrintf("keyframe scale x %d \n",tmpnewobject->scalekeys->vect.x);
	debugPrintf("keyframe scale y %d \n",tmpnewobject->scalekeys->vect.y);
	debugPrintf("keyframe scale z %d \n",tmpnewobject->scalekeys->vect.z);

*/
	parentobject->next=tmpnewobject;
	tmpnewobject->parent=parentobject->parent;

	lastobject=tmpnewobject;
	currentobject=tmpnewobject;

//	debugPrintf("parent object name %s \n",tmpnewobject->parent->meshdata->name);

	tmpnewobject->scale.vx=4096;
	tmpnewobject->scale.vy=4096;
	tmpnewobject->scale.vz=4096;
  	tmpnewobject->rotate.vx=0;
  	tmpnewobject->rotate.vy=0;
  	tmpnewobject->rotate.vz=0;
	tmpnewobject->flags=0;

	parenttest=tmpnewobject;

	tmpnewobject->meshdata->boundminx+=(tmpnewobject->movekeys->vect.x)/MODELSCALE;
	tmpnewobject->meshdata->boundminy-=(tmpnewobject->movekeys->vect.y)/MODELSCALE;
	tmpnewobject->meshdata->boundminz+=(tmpnewobject->movekeys->vect.z)/MODELSCALE;

	tmpnewobject->meshdata->boundmaxx+=(tmpnewobject->movekeys->vect.x)/MODELSCALE;
	tmpnewobject->meshdata->boundmaxy-=(tmpnewobject->movekeys->vect.y)/MODELSCALE;
	tmpnewobject->meshdata->boundmaxz+=(tmpnewobject->movekeys->vect.z)/MODELSCALE;

  //	if(strcmp(tmppsamodel,"Heart")==0)
  //	{
  //		FREE(tmpnewobject->meshdata);
  //		tmpnewobject->meshdata = NULL;
  //	}
	

//	tmpnewobject->matrix.t[0]+=(tmpnewobject->movekeys->vect.x)/MODELSCALE;
//	tmpnewobject->matrix.t[1]-=(tmpnewobject->movekeys->vect.y)/MODELSCALE;
//	tmpnewobject->matrix.t[2]+=(tmpnewobject->movekeys->vect.z)/MODELSCALE;


}
/**************************************************************************************************/
void
CreateChildSegment(PSAMODEL *tmppsamodel ){

NEWOBJECT	*parenttest;

	numberofsegments++;
	tmpnewobject=(NEWOBJECT*)MALLOC(sizeof(NEWOBJECT),tmppsamodel->name);
	ASSERT(tmpnewobject);

	lastobject->child=tmpnewobject;
//	debugPrintf("child object name %s \n",tmppsamodel->name);
	CreateSegment((PSAMODEL*)tmppsamodel,(NEWOBJECT*)tmpnewobject );	

//	ZeroQuaternion(&tmpnewobject->qRot);

/*	debugPrintf("keyframe move x %d \n",tmpnewobject->movekeys->vect.x);
	debugPrintf("keyframe move y %d \n",tmpnewobject->movekeys->vect.y);
	debugPrintf("keyframe move z %d \n",tmpnewobject->movekeys->vect.z);

	debugPrintf("keyframe scale x %d \n",tmpnewobject->scalekeys->vect.x);
	debugPrintf("keyframe scale y %d \n",tmpnewobject->scalekeys->vect.y);
	debugPrintf("keyframe scale z %d \n",tmpnewobject->scalekeys->vect.z);

*/
	tmpnewobject->parent=parentobject;
	lastobject->child=tmpnewobject;
//	parentobject=tmpnewobject;
	lastobject=tmpnewobject;
	currentobject=tmpnewobject;

//	debugPrintf("parent object name %s \n",tmpnewobject->parent->meshdata->name);
	tmpnewobject->scale.vx=4096;
	tmpnewobject->scale.vy=4096;
	tmpnewobject->scale.vz=4096;
  	tmpnewobject->rotate.vx=0;
  	tmpnewobject->rotate.vy=0;
  	tmpnewobject->rotate.vz=0;

	tmpnewobject->flags=0;


//	tmpnewobject->matrix.t[0]+=(tmpnewobject->movekeys->vect.x)/MODELSCALE;//*4096;
//	tmpnewobject->matrix.t[1]-=(tmpnewobject->movekeys->vect.y)/MODELSCALE;//*4096;
//	tmpnewobject->matrix.t[2]+=(tmpnewobject->movekeys->vect.z)/MODELSCALE;//*4096;

	tmpnewobject->meshdata->boundminx+=(tmpnewobject->movekeys->vect.x)/MODELSCALE;
	tmpnewobject->meshdata->boundminy-=(tmpnewobject->movekeys->vect.y)/MODELSCALE;
	tmpnewobject->meshdata->boundminz+=(tmpnewobject->movekeys->vect.z)/MODELSCALE;

	tmpnewobject->meshdata->boundmaxx+=(tmpnewobject->movekeys->vect.x)/MODELSCALE;
	tmpnewobject->meshdata->boundmaxy-=(tmpnewobject->movekeys->vect.y)/MODELSCALE;
	tmpnewobject->meshdata->boundmaxz+=(tmpnewobject->movekeys->vect.z)/MODELSCALE;

	parenttest=tmpnewobject;

}

LONG eachpoly;

void
CreateSegment(PSAMODEL *psamodel,NEWOBJECT *newobject )
{ // Sets up TMD and sorttables for segment of PSA

ULONG 		loop;
KEYFRAME	*keys,*tmpkeyptr;
USHORT		TotalNumOfKeys;
PSAFACE	*poly;
NEWTMD	temptmd;
LONG		mallsize;
PACKET*		packet;
LONG		primn;
ULONG		*primptr;
UBYTE		debugflag,*offsetaddr;
LONG 		j,k,calc,num;
int			sortSize, ss;
PSAMODEL	*tmp;
char		str[100];
int sizePrim, sizeVert, sizeNorm, sizeSort; 
int offTMD, offPrim, offVert, offNorm, offSort; 

	(LONG)offsetaddr = (LONG)psamodel;
	TotalNumOfKeys=psamodel->numScaleKeys;
	TotalNumOfKeys+=psamodel->numMoveKeys;
	TotalNumOfKeys+=psamodel->numRotateKeys;

	newobject->pad = 0;
	strcpy(str, psamodel->name);
	//debugPrintf("\n%s",str);
	upperStr(str);
//	if(strstr(str, "HEART"))
//	{
//		newobject->pad = 0x1234;
//		foundHeart = 1;
//	}
	/*if( (strcmp(str,"HEAD") == 0) || (strcmp(str,"NECK") == 0) )
		newobject->pad = 0x4ead;
	if( (strcmp(str,"GUN") == 0) || (strcmp(str,"SHOTGUN") == 0) )
		newobject->pad = 0xff00;
	if(strcmp(str,"SHOTGUNBACK") == 0)
		newobject->pad = 0xbac1;
	*/
	sprintf(str, "%s/KF", psamodel->name);
//	keys=(KEYFRAME*)MALLOC(sizeof(KEYFRAME)*TotalNumOfKeys,str);
	keys=(KEYFRAME*)MALLOC(
		  (psamodel->numScaleKeys * sizeof(SVKEYFRAME)
		+ psamodel->numMoveKeys * sizeof(SVKEYFRAME)
		+ psamodel->numRotateKeys * sizeof(SQKEYFRAME)
		+ 3) & (~3)
		,str);

	ASSERT(keys);

	newobject->Animstart=psamodel->Animstart;
	newobject->Animend=psamodel->Animend;
	newobject->numScaleKeys=psamodel->numScaleKeys;
	newobject->numMoveKeys=psamodel->numMoveKeys;
	newobject->numRotateKeys=psamodel->numRotateKeys;

	// Point offset to correct addr.
	(LONG)psamodel->scalekeys+=(LONG)offsetaddr;
	(LONG)psamodel->movekeys+=(LONG)offsetaddr;
	(LONG)psamodel->rotatekeys+=(LONG)offsetaddr;
	(LONG)psamodel->polys+=(LONG)offsetaddr;
	(LONG)psamodel->verts+=(LONG)offsetaddr;

	for (loop=0;loop<8;loop++)
	{
		(LONG)psamodel->sortlistptr[loop]+=(LONG)offsetaddr;
	}

	// Setup keyframe info

/*
	newobject->scalekeys=keys;
	tmpkeyptr=psamodel->scalekeys;
	for (loop=0;loop<psamodel->numScaleKeys;loop++)
	{
		keys->time=tmpkeyptr->time;
		keys->vect.x=tmpkeyptr->vect.x;
		keys->vect.y=tmpkeyptr->vect.y;
		keys->vect.z=tmpkeyptr->vect.z;
		keys->vect.w=tmpkeyptr->vect.w;
		keys++;
		tmpkeyptr++;
	}		

	newobject->movekeys=keys;	
	tmpkeyptr=psamodel->movekeys;
	for (loop=0;loop<psamodel->numMoveKeys;loop++)
	{
		keys->time=tmpkeyptr->time;
		keys->vect.x=tmpkeyptr->vect.x;
		keys->vect.y=tmpkeyptr->vect.y;
		keys->vect.z=tmpkeyptr->vect.z;
		keys->vect.w=tmpkeyptr->vect.w;
		keys++;
		tmpkeyptr++;
	}		
	
	newobject->rotatekeys=keys;	
	tmpkeyptr=psamodel->rotatekeys;
	for (loop=0;loop<psamodel->numRotateKeys;loop++)
	{
		keys->time=tmpkeyptr->time;
		keys->vect.x=-tmpkeyptr->vect.x;
		keys->vect.y=tmpkeyptr->vect.y;
		keys->vect.z=-tmpkeyptr->vect.z;
		keys->vect.w=tmpkeyptr->vect.w;
		keys++;
		tmpkeyptr++;
	}
*/
	newobject->scalekeys=(SVKEYFRAME *)keys;
	tmpkeyptr=psamodel->scalekeys;
	for (loop=0;loop<psamodel->numScaleKeys;loop++)
	{
		((SVKEYFRAME *)keys)->time=tmpkeyptr->time;
		((SVKEYFRAME *)keys)->vect.x=tmpkeyptr->vect.x >> 2;
		((SVKEYFRAME *)keys)->vect.y=tmpkeyptr->vect.y >> 2;
		((SVKEYFRAME *)keys)->vect.z=tmpkeyptr->vect.z >> 2;

		if(tmpkeyptr->time >= 32878*4 || tmpkeyptr->time <-32878*4) printf(" Time OV %d\n",tmpkeyptr->time);
		if(tmpkeyptr->vect.x >= 32878*4 || tmpkeyptr->vect.x<-32878*4) printf(" sxyz ov %d\n",tmpkeyptr->vect.x);
		if(tmpkeyptr->vect.y >= 32878*4 || tmpkeyptr->vect.y<-32878*4) printf(" sxyz ov %d\n",tmpkeyptr->vect.y);
		if(tmpkeyptr->vect.z >= 32878*4 || tmpkeyptr->vect.z<-32878*4) printf(" sxyz ov %d\n",tmpkeyptr->vect.z);

//		((SVKEYFRAME *)keys)->vect.w=tmpkeyptr->vect.w;
//		keys++;
		keys = ADD2POINTER(keys,sizeof(SVKEYFRAME));
		tmpkeyptr++;
	}		


	newobject->movekeys=(SVKEYFRAME *)keys;	
	tmpkeyptr=psamodel->movekeys;
	for (loop=0;loop<psamodel->numMoveKeys;loop++)
	{
		((SVKEYFRAME *)keys)->time=tmpkeyptr->time;
		((SVKEYFRAME *)keys)->vect.x=tmpkeyptr->vect.x;
		((SVKEYFRAME *)keys)->vect.y=tmpkeyptr->vect.y;
		((SVKEYFRAME *)keys)->vect.z=tmpkeyptr->vect.z;

		if(tmpkeyptr->time >= 32878 || tmpkeyptr->time <-32878) printf(" Time OV %d\n",tmpkeyptr->time);
		if(tmpkeyptr->vect.x >= 32878 || tmpkeyptr->vect.x<-32878) printf(" mxyz ov %d\n",tmpkeyptr->vect.x);
		if(tmpkeyptr->vect.y >= 32878 || tmpkeyptr->vect.y<-32878) printf(" mxyz ov %d\n",tmpkeyptr->vect.y);
		if(tmpkeyptr->vect.z >= 32878 || tmpkeyptr->vect.z<-32878) printf(" mxyz ov %d\n",tmpkeyptr->vect.z);

		keys = ADD2POINTER(keys,sizeof(SVKEYFRAME));
//		((SVKEYFRAME *)keys)->vect.w=tmpkeyptr->vect.w;
//		keys++;
		tmpkeyptr++;
	}		
	
	newobject->rotatekeys=(SQKEYFRAME *)keys;	
	tmpkeyptr=psamodel->rotatekeys;
	for (loop=0;loop<psamodel->numRotateKeys;loop++)
	{

		((SQKEYFRAME *)keys)->time=tmpkeyptr->time;
		((SQKEYFRAME *)keys)->vect.x=-tmpkeyptr->vect.x;
		((SQKEYFRAME *)keys)->vect.y=tmpkeyptr->vect.y;
		((SQKEYFRAME *)keys)->vect.z=-tmpkeyptr->vect.z;
		((SQKEYFRAME *)keys)->vect.w=tmpkeyptr->vect.w;

		if(tmpkeyptr->time >= 32878 || tmpkeyptr->time <-32878) printf(" Time OV %d\n",tmpkeyptr->time);
		if(tmpkeyptr->vect.x >= 32878 || tmpkeyptr->vect.x<-32878) printf(" rxyz ov %d\n",tmpkeyptr->vect.x);
		if(tmpkeyptr->vect.y >= 32878 || tmpkeyptr->vect.y<-32878) printf(" rxyz ov %d\n",tmpkeyptr->vect.y);
		if(tmpkeyptr->vect.z >= 32878 || tmpkeyptr->vect.z<-32878) printf(" rxyz ov %d\n",tmpkeyptr->vect.z);
		if(tmpkeyptr->vect.w >= 32878 || tmpkeyptr->vect.w<-32878) printf(" rxyzwov %d\n",tmpkeyptr->vect.w);

		keys = ADD2POINTER(keys,sizeof(SQKEYFRAME));
//		keys++;
		tmpkeyptr++;
	}		


	poly=psamodel->polys;
//SET UP TEMP TMD STRUCTURE

 	temptmd.vertop=MALLOC(sizeof(VERT)*(psamodel->numofverts),"TEMP VERTS");
	ASSERT(temptmd.vertop);
	temptmd.vern=0;

	temptmd.nortop=MALLOC(sizeof(NORM)*(psamodel->numofpolys)*4,"TEMP NORMS");
	ASSERT(temptmd.nortop);
	temptmd.norn=0;

	temptmd.primtop=MALLOC(sizeof(TMD_P_TG4A)*psamodel->numofpolys,"TEMP PRIMS");	 //size of biggest
	ASSERT(temptmd.primtop);
	temptmd.primn=0;

//PROCESS ALL POLYGONS->PRIMATIVES
	eachpoly=0;
	packet=(PACKET*)temptmd.primtop;
	while(eachpoly<psamodel->numofpolys)
	{
   		packet+=Add_Prim2NewTmd(&temptmd,psamodel->verts,&psamodel->polys[eachpoly],packet);
	
		debugflag=0;
		eachpoly++;
	} 

	sortSize=0;

	for(ss=0; ss<8; ss++)
		sortSize+=psamodel->sortlistsize[ss];

/*	newtmd=(NEWTMD *)MALLOC(sizeof(NEWTMD), "NEWTMD");

	FMEMCPY(newtmd,&temptmd,sizeof(NEWTMD)); //copy tmd structure
	newtmd->primn=psamodel->numofpolys;		  //correct
	newtmd->vern=psamodel->numofverts;
	newtmd->norn=psamodel->numofverts;

	newtmd->primtop=(ULONG *)MALLOC(((ULONG)packet)-((ULONG)temptmd.primtop), "PRIMTOP");
	newtmd->vertop=(VERT *)MALLOC(sizeof(VERT)*(psamodel->numofverts), "VERTOP");
	newtmd->nortop=(NORM *)MALLOC(sizeof(NORM)*(psamodel->numofverts), "NORTOP");
	newtmd->sorttable[0]=(int *)MALLOC(sizeof(int)*sortSize, "SORTLISTS");	

	FMEMCPY((UBYTE*)newtmd->primtop,(UBYTE*)temptmd.primtop,(LONG)(packet-(LONG)temptmd.primtop)); //copy primitive packets

 	if ((psamodel->polys->flags&NUMOFSIDES)==0){ // If sprite frig verts
		CopyVertsSpr(psamodel->verts,(VERT*)newtmd->vertop,newtmd->vern);
 	}
	else CopyVertsNew(psamodel->verts,(VERT*)newtmd->vertop,newtmd->vern);

	FMEMCPY((UBYTE*)newtmd->nortop,(UBYTE*)temptmd.nortop,temptmd.norn*sizeof(NORM));

*/
//MALLOC AREA OF PERMANANT TMD

	
	sizePrim=((LONG)packet-(LONG)temptmd.primtop);
	sizeVert=sizeof(VERT)*(psamodel->numofverts);
	sizeNorm=sizeof(NORM)*(temptmd.norn);
	sizeSort=sortSize*sizeof(int);

	offTMD=0;
	offPrim=offTMD+sizeof(NEWTMD);
	offVert=offPrim+sizePrim;
	offNorm=offVert+sizeVert;
	offSort=offNorm+sizeNorm;

	// malloc whole block
	mallsize=sizeof(NEWTMD)+sizePrim+sizeVert+sizeNorm+sizeSort;
	sprintf(str, "%s/TMD", psamodel->name);
	newtmd=(NEWTMD *)MALLOC(mallsize, str);
	ASSERT(newtmd);

	//copy tmd structure
	FMEMCPY(newtmd,&temptmd,sizeof(NEWTMD)); 

	newtmd->primtop=(ULONG *)(((long)newtmd)+offPrim);
	newtmd->primn=psamodel->numofpolys;

	newtmd->vertop=(VERT *)(((long)newtmd)+offVert);
	newtmd->vern=psamodel->numofverts;

	newtmd->nortop=(NORM *)(((long)newtmd)+offNorm); 
	newtmd->norn=temptmd.norn;

//copy the packets to new area

	FMEMCPY((UBYTE*)newtmd->primtop,(UBYTE*)temptmd.primtop,sizePrim); //copy primitive packets

 	if ((psamodel->polys->flags&NUMOFSIDES)==0){ // If sprite frig verts
		CopyVertsSpr(psamodel->verts,(VERT*)newtmd->vertop,newtmd->vern);
 	}
	else CopyVertsNew(psamodel->verts,(VERT*)newtmd->vertop,newtmd->vern);

	FMEMCPY((UBYTE*)newtmd->nortop,(UBYTE*)temptmd.nortop, sizeNorm);

//make sorttables addresses

	calc=0;	
	j=0;

	newtmd->sorttable[0]=(int *)(((long)newtmd)+offSort);

	for(j=0;j<4;j++)
	{
		newtmd->sorttablesize[j]=psamodel->sortlistsize[j];

		if (j!=0) newtmd->sorttable[j]=&(newtmd->sorttable[j-1][psamodel->sortlistsize[j-1]]);  
		for (k=0;k<psamodel->sortlistsize[j];k++)
		{
			num=psamodel->sortlistptr[7-j][k];
			if (num>newtmd->primn)num=0; //corrects bug of having sorttables smaller than polylists
			primn=num;	//calc ptr for poly, from its number
			primptr=newtmd->primtop;
			while (primn)
			{
				primptr+=((((TMD_P_F3*)primptr)->in)+1);
				primn--;
			}
			newtmd->sorttable[j][k]=(primptr-newtmd->primtop)&0xffffff;

		}
	}	


    strcpy(newtmd->name,psamodel->name);
	*(newtmd->name+7)=0;  //tom. is this still correct????

	FREENULL(temptmd.vertop);
	FREENULL(temptmd.nortop);
	FREENULL(temptmd.primtop);

//#ifdef AVGNORMALS
	averageNormals(newtmd);
//#endif

	Do_BoundBox(newtmd);
  	newtmd->scale=Model_Size(newtmd);
	
	OBEflag=NO;

	if(sortSize)
		Reverse_SortTables(newtmd);

	newobject->meshdata=(NEWTMD*)newtmd;
	newobject->child=NULL;

//	if(psamodel->next==NULL || psamodel->child==NULL)
	if(strcmp(psamodel->name,"ACTMAN")!=0 || psamodel->next==NULL)
		newobject->next=NULL;
	else
	{
		newobject->next=(NEWOBJECT*)MALLOC(sizeof(NEWOBJECT),"dummy");
		ASSERT(newobject);

		tmp = (PSAMODEL*)psamodel->next;

		newobject->next->numScaleKeys 	= tmp->numScaleKeys;
		newobject->next->numMoveKeys 	= tmp->numMoveKeys;
		newobject->next->numRotateKeys =  tmp->numRotateKeys;
		newobject->next->meshdata 		= NULL;//tmp->meshdata;
		newobject->next->next 			= NULL;
		newobject->next->child 			= NULL;
		newobject->next->parent 		= WORLD;
/*
	 
		newobject->next->scalekeys 		= tmp->scalekeys;
		newobject->next->movekeys 		= tmp->movekeys;
		newobject->next->rotatekeys 	= tmp->rotatekeys;
*/
		newobject->next->scalekeys 		= MALLOC(tmp->numScaleKeys  * sizeof(SVKEYFRAME),"temp keys");
		newobject->next->movekeys 		= MALLOC(tmp->numMoveKeys   * sizeof(SVKEYFRAME),"temp keys");
		newobject->next->rotatekeys 	= MALLOC(tmp->numRotateKeys * sizeof(SQKEYFRAME),"temp keys");
		{
			int i;
			for(i = 0; i <tmp->numScaleKeys;i++)
			{
				newobject->next->scalekeys[i].vect.x = tmp->scalekeys[i].vect.x >>2;
				newobject->next->scalekeys[i].vect.y = tmp->scalekeys[i].vect.y >>2;
				newobject->next->scalekeys[i].vect.z = tmp->scalekeys[i].vect.z >>2;
				newobject->next->scalekeys[i].time   = tmp->scalekeys[i].time;

		if(tmp->scalekeys[i].time >= 32878*4   || tmp->scalekeys[i].time <-32878*4) printf(" Time OV %d\n",tmpkeyptr->time);
		if(tmp->scalekeys[i].vect.x >= 32878*4 || tmp->scalekeys[i].vect.x<-32878*4) printf(" sxyz ov %d\n",tmpkeyptr->vect.x);
		if(tmp->scalekeys[i].vect.y >= 32878*4 || tmp->scalekeys[i].vect.y<-32878*4) printf(" sxyz ov %d\n",tmpkeyptr->vect.y);
		if(tmp->scalekeys[i].vect.z >= 32878*4 || tmp->scalekeys[i].vect.z<-32878*4) printf(" sxyz ov %d\n",tmpkeyptr->vect.z);



			}
			for(i = 0; i <tmp->numMoveKeys;i++)
			{
				newobject->next->movekeys[i].vect.x = tmp->movekeys[i].vect.x;
				newobject->next->movekeys[i].vect.y = tmp->movekeys[i].vect.y;
				newobject->next->movekeys[i].vect.z = tmp->movekeys[i].vect.z;
				newobject->next->movekeys[i].time   = tmp->movekeys[i].time;

		if(tmp->movekeys[i].time >= 32878   || tmp->movekeys[i].time <-32878) printf(" Time OV %d\n",tmpkeyptr->time);
		if(tmp->movekeys[i].vect.x >= 32878 || tmp->movekeys[i].vect.x<-32878) printf(" mxyz ov %d\n",tmpkeyptr->vect.x);
		if(tmp->movekeys[i].vect.y >= 32878 || tmp->movekeys[i].vect.y<-32878) printf(" mxyz ov %d\n",tmpkeyptr->vect.y);
		if(tmp->movekeys[i].vect.z >= 32878 || tmp->movekeys[i].vect.z<-32878) printf(" mxyz ov %d\n",tmpkeyptr->vect.z);


			}
			for(i = 0; i <tmp->numRotateKeys;i++)
			{
				newobject->next->rotatekeys[i].vect.x = tmp->rotatekeys[i].vect.x;
				newobject->next->rotatekeys[i].vect.y = tmp->rotatekeys[i].vect.y;
				newobject->next->rotatekeys[i].vect.z = tmp->rotatekeys[i].vect.z;
				newobject->next->rotatekeys[i].vect.w = tmp->rotatekeys[i].vect.w;
				newobject->next->rotatekeys[i].time   = tmp->rotatekeys[i].time;

		if(tmp->rotatekeys[i].time >= 32878   || tmp->rotatekeys[i].time <-32878) printf(" Time OV %d\n",tmpkeyptr->time);
		if(tmp->rotatekeys[i].vect.x >= 32878 || tmp->rotatekeys[i].vect.x<-32878) printf(" rxyz ov %d\n",tmpkeyptr->vect.x);
		if(tmp->rotatekeys[i].vect.y >= 32878 || tmp->rotatekeys[i].vect.y<-32878) printf(" rxyz ov %d\n",tmpkeyptr->vect.y);
		if(tmp->rotatekeys[i].vect.z >= 32878 || tmp->rotatekeys[i].vect.z<-32878) printf(" rxyz ov %d\n",tmpkeyptr->vect.z);
		if(tmp->rotatekeys[i].vect.w >= 32878 || tmp->rotatekeys[i].vect.w<-32878) printf(" rxyzwov %d\n",tmpkeyptr->vect.z);
			}
		}

	}
}


NEWMODEL *ProcessPSA(PSAHEADER *pPSAHeader)
{
	NEWMODEL	*modelname;
	UBYTE 		*fileaddr;//,*offsetaddr;
	NEWOBJECT	*tempobject;
	long psaVer;

	if(!pPSAHeader)
	{
		debugPrintf("You called ProcessPSA() with a NULL pointer!\n");
		CRASH;
	}
	foundHeart = 0;

//	debugPrintf("ProcessPSA().2\n");
	if((pPSAHeader->u.lid & 0xffffff)==CHUNK_PSA)
	{// it is a NEW PSA
		psaVer=(ULONG)pPSAHeader->u.id[3];

		pPSAHeader->pRootModel=(PSAMODEL *)((ULONG)pPSAHeader->pRootModel+(ULONG)pPSAHeader);
		pPSAHeader->pAnimRanges=(ANIMRANGE *)((ULONG)pPSAHeader->pAnimRanges+(ULONG)pPSAHeader);

		fileaddr=(UBYTE *)pPSAHeader->pRootModel;
//		debugPrintf("Processing NEW PSA (V.%d) loaded. Has %d anim ranges\n",
//				psaVer, pPSAHeader->nRanges);
	}
	else
	{
		psaVer=-1;
//		debugPrintf("Processing old PSA (or is NEW PSA corrupted?)\n");
		fileaddr=(UBYTE *)pPSAHeader;
	}

	(LONG)mymodel=fileaddr;

//	jallocctrl.usetempmalloc=NO;
	tempobject=(NEWOBJECT*)MALLOC(sizeof(NEWOBJECT),mymodel->name);// top of hyaracy
	ASSERT(tempobject);

//	debugPrintf ("First object name %s\n",mymodel->name);
	CreateSegment(mymodel,tempobject); // create topmost segment
	
	modelname=(NEWMODEL*)MALLOC(sizeof(NEWMODEL), mymodel->name);
	ASSERT(modelname);

	FMEMCPY(&modelname->world,(UBYTE*)tempobject,sizeof(NEWOBJECT)); //copy primitive packets

	modelname->world.meshdata=tempobject->meshdata;
//	debugPrintf("mesh addr $%x\n",tempobject->meshdata);
//	debugPrintf("test addr $%x\n",&modelname->world);
	//debugPrintf("test1 addr $%x\n",&modelname);

  	modelname->world.scale.vx=4096;//4096;
  	modelname->world.scale.vy=4096;//4096;
  	modelname->world.scale.vz=4096;//4096;
  	modelname->world.rotate.vx=0;
  	modelname->world.rotate.vy=0;
  	modelname->world.rotate.vz=0;
  	modelname->globalscale.vx=4096;
  	modelname->globalscale.vy=4096;
  	modelname->globalscale.vz=4096;

	modelname->position.vx=0;
	modelname->position.vy=0;
	modelname->position.vz=0;

	Set_Model_CoordsNew(modelname,0,0,0,0,0,0);

	tempobject->matrix.t[0]+=(tempobject->movekeys->vect.x)/MODELSCALE;
	tempobject->matrix.t[2]+=(tempobject->movekeys->vect.y)/MODELSCALE;
	tempobject->matrix.t[1]+=(tempobject->movekeys->vect.z)/MODELSCALE;

	modelname->world.parent=NULL;
//	modelname->radius=1000;   //size of actor

	parentobject=tempobject;
	lastobject=tempobject;
	currentobject=tempobject;

//	debugPrintf("test addr1$%x\n",parentobject);

	parentobject=&modelname->world;
	lastobject=&modelname->world;
	currentobject=&modelname->world;

	//ZeroQuaternion(&currentobject->qRot);

//	debugPrintf("test addr2$%x\n",parentobject);
	CreateSegments(mymodel,currentobject);
	if (mymodel->child==NULL)
		foundHeart = 1;
//	debugPrintf("number of segments %d\n",numberofsegments);

//	SegmentSort(numberofsegments,modelname,chucktmpsortlistptr);

//	modelname->world.child=chucktmpobject->child;
//	modelname->world.next=chucktmpobject->next;
//	FREE(pPSAHeader);	
	FREE(tempobject);

	if (!foundHeart)
		debugPrintf("******* WARNING: NO HEART FOUND ************\n");

	return modelname;

}
/**************************************************************************************************/

// tbd - Get rid of entirely in favour of the BFF routine
NEWMODEL *LoadPSA(char* filename)
{// Loads PSA into mem for processing
	PSAHEADER *pPSAHeader;
	NEWMODEL *mdl;

	{
		char temp[9];
		int i,d;
		for(i = strlen(filename); i>= 0; i--)
		{
			if(filename[i] == '\\')
			{
				i++;
				break;
			}
		}
		if(i<0) i = 0;

		for(d = 0; filename[i] != '.'; d++,i++)
		{
			temp[d] = filename[i];
		}
		temp[d] = 0;
		mdl = BFF_IsModelLoaded(temp,NULL);
		if(mdl)
		{
//			printf("Model %s found in BFF\n",temp);
			return mdl;
		}
		else
		{
			printf("Model %s not found in BFF\n",temp);

		}
	}



	numberofsegments=1; 
	pPSAHeader=(PSAHEADER *)LoadFile(filename);
	if (pPSAHeader == NULL )
	{
		debugPrintf("PSA not loaded!!\n");
		return NO;
	}
	mdl = ProcessPSA(pPSAHeader);
	FREE(pPSAHeader);
	return mdl;
}


// tbd - Get rid of entirely in favour of the BFF routine
// (this one's only still used for the front end)
/*
PSAWORLD *LoadWorld(char *sFile)
{
	PSAWORLD *pWorld;
	NEWMODEL **pZones;
	ULONG id,nZones,i;
	PSAHEADER *pPSA;
	ULONG *p;
	ULONG base;
	int nx,ny,nz;

	DB("Loading World '%s' ...\n", sFile);

	p =(ULONG *)LoadFile(sFile);
	base =(ULONG)p;

	modelctrl.halfgouraud=TRUE;

	//for(i=0; i<100; i++)
	//	VSync(0);

	pWorld=(PSAWORLD *)MALLOC(sizeof(PSAWORLD), "PSAWORLD");
	ASSERT(pWorld);

	id=*(p++);

	nx=*(p++);
	ny=*(p++);
	nz=*(p++);

	pWorld->nZones=nZones=nx*ny*nz;

	pWorld->pZones=pZones=(NEWMODEL **)MALLOC(sizeof(NEWMODEL **)*nZones, "ZONES");
	ASSERT(pZones);

	for(i=0; i<nZones; i++)
	{
		if(p[i])
		{
			pPSA=(PSAHEADER *)(p[i]+base);
			//DB("pPSA[%ld]=%p\n", i, pPSA);
			if(((ULONG)pPSA)&3)
			{
				printf("Pointer is bolloxed!\n");
				pZones[i]=NULL;
			}
			else
				pZones[i]=ProcessPSA(pPSA);
		}
		else
			pZones[i]=NULL;

		//DB("pZones[%ld]=%p, addr=%p\n", i, pZones[i], pZones+i);
	}
	FREE((void *)base);

	modelctrl.halfgouraud=0;

	return(pWorld);

}
*/
/*
void FreeWorld(PSAWORLD *pWorld)
{
	int i;

	for(i=0; i<pWorld->nZones; i++)
	{
		if(pWorld->pZones[i])
			objectFree(pWorld->pZones[i], NULL);
	}
}
*/
/*************************************************************************/
UBYTE		//returns number of quadrant, normal is telling it, it is
CheckQuad(NORM* norm,UBYTE isitthis){
UBYTE mask=0;
	
	if ((norm->nx>0)&&(norm->nx<4))norm->nx=0;
	if ((norm->nx<0)&&(norm->nx>-4))norm->nx=0;
	if ((norm->ny>0)&&(norm->ny<4))norm->ny=0;
	if ((norm->ny<0)&&(norm->ny>-4))norm->ny=0;
	if ((norm->nz>0)&&(norm->nz<4))norm->nz=0;
	if ((norm->nz<0)&&(norm->nz>-4))norm->nz=0;

	
	if (norm->nx>0)mask|=4;
	if (norm->nx<0)mask|=1;
   	if (norm->ny>0)mask|=16;
   //	if (norm->ny<0)mask|=32;
	if (norm->nz>0)mask|=2;
	if (norm->nz<0)mask|=8;
														 
//	sprintf(message,"(%d,%d,%d)%d",norm->nx,norm->ny,norm->nz,mask);

	switch(isitthis){
		case 0:
				if ((mask==1)||(mask==2)||(mask==(3)))return YES;
				return NO;
		break;
		case 1:
				if ((mask==2)||(mask==4)||(mask==6))return YES;
				return NO;
		break;
		case 2:
				if ((mask==4)||(mask==8)||(mask==12))return YES;
				return NO;
		break;
		case 3:
				if ((mask==1)||(mask==8)||(mask==9))return YES;
				return NO;
		break;
	
	}

	if (isitthis==0)if ((norm->ny>=0)&&(norm->nx<=0)&&(norm->nz>=0))return 0;
	if (isitthis==1)if ((norm->ny>=0)&&(norm->nx<=0)&&(norm->nz<=0))return 1;
	if (isitthis==2)if ((norm->ny>=0)&&(norm->nx>=0)&&(norm->nz<=0))return 2;
	if (isitthis==3)if ((norm->ny>=0)&&(norm->nx>=0)&&(norm->nz>=0))return 3;
	if (isitthis==4)if ((norm->ny<=0)&&(norm->nx<=0)&&(norm->nz>=0))return 4;
	if (isitthis==5)if ((norm->ny<=0)&&(norm->nx<=0)&&(norm->nz<=0))return 5;
	if (isitthis==6)if ((norm->ny<=0)&&(norm->nx>=0)&&(norm->nz<=0))return 6;
	if (isitthis==7)if ((norm->ny<=0)&&(norm->nx>=0)&&(norm->nz>=0))return 7;

 //	debugPrintf(":");
	if (norm->ny>0){
		if (norm->nx<0){
			if (norm->nz>0){	return 0;} //x- y+ z+
			else{
			if (norm->nz!=0)	return 1;} //x- y+ z-
		}
		else
		if (norm->nx!=0){
			if (norm->nz<0){	return 2;} //x+ y+ z-
			else{
			if (norm->nz!=0)	return 3;} //x+ y+ z+
		}
	}
	else{
	if (norm->ny!=0)
		if (norm->nx<0){
			if (norm->nz>0){		return 4;} //x- y- z+
			else{
			if (norm->nz!=0) 		return 5;} //x- y- z-
		}
		else
		if (norm->nx!=0){
		 	if (norm->nz<0){		return 6;} //x+ y- z-
			else{
			if (norm->nz!=0)		return 7;} //x+ y- z+
		}
	}
  // debugPrintf("!error!\n");VSync(0);
   return 255;
}

/**************************************************************************************************************/
/*
void
Rework_Sorttables(NEWTMD *tmd){
ULONG *primptr;
LONG primleft;
ULONG j,k;
ULONG table;
VERT *norm=NULL;
LONG calc;
UBYTE    code;		// polygon type 
VERT *v0,*v1,*v2,*v3;
ULONG newsize;
UBYTE face;
	for (table=0;table<4;table++){
		modelctrl.VertTop=(VERT*)(newtmd->vertop);
		modelctrl.PrimTop=newtmd->primtop;
		modelctrl.PrimLeft=newtmd->primn;
		modelctrl.NormTop=(VERT*)newtmd->nortop;
		modelctrl.SortPtr=&newtmd->sorttable[table][0];
		primleft=newtmd->sorttablesize[table];
	
		modelctrl.polysclipped=0;
		modelctrl.polysdrawn=0;
		modelctrl.showquad=((table+3)&3); //+4;
		j=k=0;
		while (primleft>0){
			primptr=modelctrl.PrimTop+((*modelctrl.SortPtr)&0xffffff);
			code =((TMD_P_TF4*)primptr)->cd&(0xff-2);
			v3=0;
			 //	if (andrewvar)debugPrintf("RE poly type %d,",code);
			switch(code){						//THE GOURAUD ONES PROBALY DONT QUITE WORK, THEY NEED TO BE DIFFERENT
				case GPU_COM_F4: norm=&modelctrl.NormTop[((TMD_P_F4 *)primptr)->n0];
								 v0=&modelctrl.VertTop[(((TMD_P_F4*)primptr)->v0)];
								 v1=&modelctrl.VertTop[(((TMD_P_F4*)primptr)->v1)];
								 v2=&modelctrl.VertTop[(((TMD_P_F4*)primptr)->v2)];
								 v3=&modelctrl.VertTop[(((TMD_P_F4*)primptr)->v3)];
				break;
				case GPU_COM_F3: norm=&modelctrl.NormTop[((TMD_P_F3 *)primptr)->n0];
								 v0=&modelctrl.VertTop[(((TMD_P_F3*)primptr)->v0)];
								 v1=&modelctrl.VertTop[(((TMD_P_F3*)primptr)->v1)];
								 v2=&modelctrl.VertTop[(((TMD_P_F3*)primptr)->v2)];
				break;
				case GPU_COM_G3: norm=&modelctrl.NormTop[((TMD_P_F3G *)primptr)->n0];
								 v0=&modelctrl.VertTop[(((TMD_P_F3G*)primptr)->v0)];
								 v1=&modelctrl.VertTop[(((TMD_P_F3G*)primptr)->v1)];
								 v2=&modelctrl.VertTop[(((TMD_P_F3G*)primptr)->v2)];

				break;
				case GPU_COM_G4: norm=&modelctrl.NormTop[((TMD_P_F4G *)primptr)->n0];
								 v0=&modelctrl.VertTop[(((TMD_P_F4G*)primptr)->v0)];
								 v1=&modelctrl.VertTop[(((TMD_P_F4G*)primptr)->v1)];
								 v2=&modelctrl.VertTop[(((TMD_P_F4G*)primptr)->v2)];
								 v3=&modelctrl.VertTop[(((TMD_P_F4G*)primptr)->v3)];
         		break;
	  			case GPU_COM_TG3:
	  							 norm=&modelctrl.NormTop[((TMD_P_TG3A *)primptr)->n0];
								 v0=&modelctrl.VertTop[(((TMD_P_TG3A*)primptr)->v0)];
								 v1=&modelctrl.VertTop[(((TMD_P_TG3A*)primptr)->v1)];
								 v2=&modelctrl.VertTop[(((TMD_P_TG3A*)primptr)->v2)];
				break;
				case GPU_COM_TG4:
								norm=&modelctrl.NormTop[((TMD_P_TG4A*)primptr)->n0];
								 v0=&modelctrl.VertTop[(((TMD_P_TG4A*)primptr)->v0)];
								 v1=&modelctrl.VertTop[(((TMD_P_TG4A*)primptr)->v1)];
								 v2=&modelctrl.VertTop[(((TMD_P_TG4A*)primptr)->v2)];
								 v3=&modelctrl.VertTop[(((TMD_P_TG4A*)primptr)->v3)];
				break;
				case GPU_COM_TF3:
								norm=&modelctrl.NormTop[((TMD_P_TF3A *)primptr)->n0];
								 v0=&modelctrl.VertTop[(((TMD_P_TF3A*)primptr)->v0)];
								 v1=&modelctrl.VertTop[(((TMD_P_TF3A*)primptr)->v1)];
								 v2=&modelctrl.VertTop[(((TMD_P_TF3A*)primptr)->v2)];
				break;
				case GPU_COM_TF4:
		  						 norm=&modelctrl.NormTop[((TMD_P_TF4A*)primptr)->n0];
		  						 v0=&modelctrl.VertTop[(((TMD_P_TF4A*)primptr)->v0)];
		  						 v1=&modelctrl.VertTop[(((TMD_P_TF4A*)primptr)->v1)];
		  						 v2=&modelctrl.VertTop[(((TMD_P_TF4A*)primptr)->v2)];
		  						 v3=&modelctrl.VertTop[(((TMD_P_TF4A*)primptr)->v3)];
		  		break;
				default:	debugPrintf("Error-reducing polys! %x\n",code);
				break;
			}
		
#if POLYSIZECLIP==YES
			if (v3!=0)	size+=Size_Of_Poly(v1,v2,v3);
	   	//   	if (table==((CheckQuad(norm)+2)&3))size+=(size/4);
	   	   //	if (table==((CheckQuad(norm))&3))size+=(size/4);
		//	else size=0;

			newsize=size/25;
			if (newsize>255) newsize=255;
			//newsize=255;
		 //  	if (andrewvar==YES)
		// 	debugPrintf("sizes=(%d,%d)\n",size,newsize);
		//	VSync(0);
#else
			newsize=0;
#endif
			calc=newtmd->sorttable[table][j] &0xffffff;
			newtmd->sorttable[table][k]=calc+(newsize<<24);



		   	face=CheckQuad((NORM*)norm,modelctrl.showquad);	
	   //	   	if (strcmp(newtmd->name,"GUATWR")==0)debugPrintf("norm %d,%d,%d=quad=%d\n",norm->vx,norm->vy,norm->vz,face);
	   	   	//if ((modelctrl.showquad==CheckQuad(norm))&&((((TMD_P_TF4*)primptr)->dummy&2)==0)){
	   	   	//if ((CheckQuad((NORM*)norm,255)>=4)||(modelctrl.showquad==CheckQuad((NORM*)norm,255))){
	   	   	if ((face==YES)&&((((TMD_P_TF4*)primptr)->dummy&2)==0)){
	   	   	//if ((CheckQuad(norm)==0)&&((((TMD_P_TF4*)primptr)->dummy&2)==0)){
   	 	   		modelctrl.polysclipped++;
	   	   		k--;
	   	   		newtmd->sorttablesize[table]--;
	   	   	}
		   	else modelctrl.polysdrawn++;
		   
   			primleft--;
			modelctrl.SortPtr++;
			k++;
			j++;
  						
		}
	 	if (strcmp(newtmd->name,"GUATWR")==0){
	   		debugPrintf("Table=%d\n",table);
	   		debugPrintf("quad=%d\n",modelctrl.showquad);
	   		debugPrintf("Polysdrawn=%d\n",modelctrl.polysdrawn);
	   		debugPrintf("Polysclipped=%d\n",modelctrl.polysclipped);
	 	}
	
	}

}
*/
/**************************************************************************************************************/
USHORT
Model_Size(NEWTMD* newtmd){
ULONG a,b,c;
	a=(fast_sqrt(abs(newtmd->boundmaxx-newtmd->boundminx)))>>16;			// X bounds
	b=(fast_sqrt(abs(newtmd->boundmaxy-newtmd->boundminy)))>>16;			// Y bounds
	c=(fast_sqrt(abs(newtmd->boundmaxz-newtmd->boundminz)))>>16;			// Z bounds
	return fast_sqrt(a*b*c)>>16;
}
/**************************************************************************************************************/
/*********************************************************************************************************************/
void
CopyVerts(NEWVERT *modelverts,VERT*tmdverts,LONG num){
LONG j;
// 	if (andrewvar==YES){debugPrintf("copyverts!\n");VSync(0);}
	//	<se> quick frig by tom
	for (j=0;j<num;j++){
	 //		if (OBEflag==NO){
		  	tmdverts[j].vx=+(modelverts[j].x)/MODELSCALE;
		  	tmdverts[j].vy=-(modelverts[j].z)/MODELSCALE;
		  	tmdverts[j].vz=+(modelverts[j].y)/MODELSCALE;
	 //		}
	 //		else{
	 //	  	tmdverts[j].vx=+(modelverts[j].x)/2;
	 //	  	tmdverts[j].vy=-(modelverts[j].z)/2;
	 //	  	tmdverts[j].vz=+(modelverts[j].y)/2;
	 //
	 //		}
	}
}
/*********************************************************************************************************************/
void Set4VertsFromFace(NEWVERT* verts,VERT *vert0,VERT *vert1,VERT *vert2,VERT *vert3,PSAFACE *face)
{
		vert0->vx=+(verts[face->vert[0]].x); ///size;
		vert0->vy=-(verts[face->vert[0]].z); ///size;
		vert0->vz=(verts[face->vert[0]].y); ///size;

		vert1->vx=+(verts[face->vert[1]].x); ///size;
		vert1->vy=-(verts[face->vert[1]].z); ///size;
		vert1->vz=(verts[face->vert[1]].y); ///size;

		vert2->vx=+(verts[face->vert[2]].x); ///size;
		vert2->vy=-(verts[face->vert[2]].z); ///size;
		vert2->vz=(verts[face->vert[2]].y); ///size;

		vert3->vx=+(verts[face->vert[3]].x); ///size;
		vert3->vy=-(verts[face->vert[3]].z); ///size;
		vert3->vz=(verts[face->vert[3]].y); ///size;
}

void Set3VertsFromFace(NEWVERT* verts,VERT *vert0,VERT *vert1,VERT *vert2,VERT *vert3,PSAFACE *face)
{
		vert0->vx=+(verts[face->vert[0]].x); ///size;
		vert0->vy=-(verts[face->vert[0]].z); ///size;
		vert0->vz=(verts[face->vert[0]].y); ///size;

		vert1->vx=+(verts[face->vert[1]].x); ///size;
		vert1->vy=-(verts[face->vert[1]].z); ///size;
		vert1->vz=(verts[face->vert[1]].y); ///size;

		vert2->vx=+(verts[face->vert[2]].x); ///size;
		vert2->vy=-(verts[face->vert[2]].z); ///size;
		vert2->vz=(verts[face->vert[2]].y); ///size;
}

/*********************************************************************************************************************/
ULONG
NPercentAcrossX(ULONG x,ULONG w,ULONG per,UBYTE tiled){
ULONG calc;
ULONG result;

	calc=(w*per)>>8; 
 	result=calc+x;
 	if (result>255)
		result=8;
 	return result;
}
/*********************************************************************************************************************/
UBYTE
GetTypeOfFace(USHORT flags){
UBYTE type=0;
   	if ((flags & NUMOFSIDES)==2){
		if (flags & TEXTURED){
				if (flags & GOURAUD) 	type=GPU_COM_TG3;
				else 			 		type=GPU_COM_TG3; //TF
		}else{
				if (flags & GOURAUD)	type=GPU_COM_G3;
				else   					type=GPU_COM_F3;
		}
	}
	if ((flags & NUMOFSIDES)==3){
		if (flags & TEXTURED){
				if (flags & GOURAUD)  	type=GPU_COM_TG4;
				else				  	type=GPU_COM_TG4; //TF
		}else{ 
				if (flags & GOURAUD)	type=GPU_COM_G4;
				else 					type=GPU_COM_F4;
		}
	}

	if ((flags & NUMOFSIDES)==0){// Sprite 
		if (flags & TEXTURED){
				if (flags & GOURAUD)	
							type=GPU_COM_TG4;
				else  		
					type=GPU_COM_TF4SPR;

					//debugPrintf ("GPU_COM_TF4 \n");
		}else{ // This must be an error
				if (flags & GOURAUD)type=GPU_COM_G4;
				else 			  type=GPU_COM_F4;
		}
	}

  	if (type==0){
  		debugPrintf("UNSUPPORTED! %d sides,textured %d,doub %d,lit %d,tileh %d,tilev %d,Trans %d\n",
 		1+(flags & NUMOFSIDES),flags & TEXTURED,flags & DOUBLESIDED,flags & LIT,flags & TILEDH,flags & TILEDV,flags & TRANSPAR);	
  		VSync(0);
		type=GPU_COM_F3;
  	}
	return type; 
}																	  


/*********************************************************************************************************************/
//UBYTE psxteam[4][9]={"PSXTEAM1",
//					"PSXTEAM2",
//					"PSXTEAM3",
//					"PSXTEAM4"
//					};
LONG
Add_Prim2NewTmd(NEWTMD *tmd,NEWVERT *verts,PSAFACE *face,PACKET *p)
{
					  ///NOTE   Y & Z's have been swapped & Z -ve'd because PC format has different axis!
	NORM *norm;
	VERT vert0;
	VERT vert1;
	VERT vert2;
	VERT vert3;													  
 	SPRITEX *spr;
	ULONG trans=0;
	UBYTE semiflag=0;
	UBYTE type=GetTypeOfFace(face->flags);
	ULONG j;
	UBYTE tiled;
	UV uv[4];
	ULONG col;
	int r,g,b;

	tiled=((PSAFACE*)face)->tiled;

	for (j=0;j<4;j++){
		uv[j].u=((PSAFACE*)face)->uv[j].u;
		uv[j].v=((PSAFACE*)face)->uv[j].v;
	}

	if (tiled)packetbuildsize+=sizeof(DR_MODEA)*2;

	upperStr(face->texture); 			// force to upper case

  	((TMD_P_TF3A*)p)->dummy=0; //flag

	// THIS IS TEST MUST BE REMOVED ! (leave until sortting works)
	//face->flags=face->flags|DOUBLESIDED;
	// !!!!	
   	if (face->flags &DOUBLESIDED) ((TMD_P_TF3*)p)->dummy+=2;

//  	if (strcmp(face->texture,"PSXTEAM1")==0) strcpy(face->texture,psxteam[0]); //put in team number later!!!




	trans = (face->flags&TRANSPAR)>>7;
	trans = PSXTransparencies[trans];
	if (trans) semiflag=2;
	else semiflag=0;


	if(modelctrl.halfgouraud)
	{
		for(j=0; j<4; j++)
		{
			face->rgb[j].r/=2;
			face->rgb[j].g/=2;
			face->rgb[j].b/=2;
		}
	}

	switch (type){
 	
 		case GPU_COM_TG4: //WORKS! //0x3c
		 		packetbuildsize+=sizeof(POLY_GT4);	
				
		 		((TMD_P_TG4A*)p)->cd=GPU_COM_TG4|semiflag; //mode
		 		((TMD_P_TG4A*)p)->in=(sizeof(TMD_P_TG4A)/4)-1; //0xA+2; //ilen
		 		((TMD_P_TG4A*)p)->out=0xc; //olen   
		 		((TMD_P_TG4A*)p)->code=GPU_COM_TG4|semiflag; //mode YES needs BOTH
		 		((TMD_P_TG4A*)p)->code2=GPU_COM_TG4|semiflag; //mode YES needs BOTH
		 		((TMD_P_TG4A*)p)->code3=0;//GPU_COM_TG4|semiflag; //mode YES needs BOTH

		 		spr=textureFindInAllBanks(face->texture); 

				//if (strcmp(face->texture,"WATERS") == 0)((TMD_P_TG4A*)p)->code3=1; //water static 
				//if (strcmp(face->texture,"WATERF") == 0)((TMD_P_TG4A*)p)->code3=2; //water static 

			   //	(semiflag==2)
			   //	strcmp(face->texture,"ATWAT1");
		 		   
		 		((TMD_P_TG4A*)p)->tile=tiled;
		 
		 		((TMD_P_TG4A*)p)->clut=spr->clut;

#ifdef CLUT_FOGGING_CODE
				if((!fogpalette) && (spr->clut & 0x8000))	// The model printer doesn't know about fogging
			 		((TMD_P_TG4A*)p)->clut=VRAMfogPalette[spr->clut & 0x7fff];
#endif


		 		((TMD_P_TG4A*)p)->tpage=spr->tpage|trans;
		 		((TMD_P_TG4A*)p)->spr=(SPRITE *)spr;

		 		((TMD_P_TG4A*)p)->r0=face->rgb[0].r;//>>1;
		 		((TMD_P_TG4A*)p)->g0=face->rgb[0].g;//>>1;
		 		((TMD_P_TG4A*)p)->b0=face->rgb[0].b;//>>1;
		 		((TMD_P_TG4A*)p)->r1=face->rgb[1].r;//>>1;
		 		((TMD_P_TG4A*)p)->g1=face->rgb[1].g;//>>1;
		 		((TMD_P_TG4A*)p)->b1=face->rgb[1].b;//>>1;
		 		((TMD_P_TG4A*)p)->r2=face->rgb[3].r;//>>1;
		 		((TMD_P_TG4A*)p)->g2=face->rgb[3].g;//>>1;
		 		((TMD_P_TG4A*)p)->b2=face->rgb[3].b;//>>1;
		 		((TMD_P_TG4A*)p)->r3=face->rgb[2].r;//>>1;
		 		((TMD_P_TG4A*)p)->g3=face->rgb[2].g;//>>1;
		 		((TMD_P_TG4A*)p)->b3=face->rgb[2].b;//>>1;

#ifdef CLUT_FOGGING_CODE
				if(fogpalette)
				{
					col=(ULONG)spr->image;//AverageOfClutAccurate(spr);
					
					r=(col&0x1f)<<3;
					g=((col>>5)&0x1f)<<3;
					b=((col>>10)&0x1f)<<3;

//#ifdef CALCGOURAUD
					r|=(r>>5);
					g|=(g>>5);
					b|=(b>>5);

					r*=(face->rgb[0].r+face->rgb[1].r+face->rgb[2].r+face->rgb[3].r)/4;
					g*=(face->rgb[0].g+face->rgb[1].g+face->rgb[2].g+face->rgb[3].g)/4;
					b*=(face->rgb[0].b+face->rgb[1].b+face->rgb[2].b+face->rgb[3].b)/4;

					r=r>>7;
					g=g>>7;
					b=b>>7;

					if(r>255) r=255;
					if(g>255) g=255;
					if(b>255) b=255;
//#endif
					((TMD_P_TG4A*)p)->avgTexCol.r=r;	
					((TMD_P_TG4A*)p)->avgTexCol.g=g;
					((TMD_P_TG4A*)p)->avgTexCol.b=b;	

					((TMD_P_TG4A*)p)->avgTexCol.code=GPU_COM_F4|semiflag; 
				}
#endif
				 			 
	 	 	   	((TMD_P_TG4A*)p)->tu0=NPercentAcrossX(spr->x,spr->w,uv[0].u,(tiled&15));
	 	 		((TMD_P_TG4A*)p)->tv0=NPercentAcrossX(spr->y,spr->h,uv[0].v,(tiled>>4));		
	 					
	 	 		((TMD_P_TG4A*)p)->tu1=NPercentAcrossX(spr->x,spr->w,uv[1].u,(tiled&15));
	 	 		((TMD_P_TG4A*)p)->tv1=NPercentAcrossX(spr->y,spr->h,uv[1].v,(tiled>>4));		
	 			   							  
	 	 	   	((TMD_P_TG4A*)p)->tu2=NPercentAcrossX(spr->x,spr->w,uv[3].u,(tiled&15));	
	 	 	   	((TMD_P_TG4A*)p)->tv2=NPercentAcrossX(spr->y,spr->h,uv[3].v,(tiled>>4));	
	 			   				
	 	 	   	((TMD_P_TG4A*)p)->tu3=NPercentAcrossX(spr->x,spr->w,uv[2].u,(tiled&15));	
	 	 	   	((TMD_P_TG4A*)p)->tv3=NPercentAcrossX(spr->y,spr->h,uv[2].v,(tiled>>4));

				if(strncmp(face->texture, "ATWAT", 5)==0)
				{
					if(!pWaterSprites)
						pWaterSprites=textureFindFrames("WATER");
					((TMD_P_TG4A*)p)->code2=128;// 128 = anim, 8 = no. of frames

	 				(((TMD_P_TG4A*)p)->tu0)-=spr->u0;
	 				(((TMD_P_TG4A*)p)->tv0)-=spr->v0;

	 				(((TMD_P_TG4A*)p)->tu1)-=spr->u0;
	 				(((TMD_P_TG4A*)p)->tv1)-=spr->v0;

	 				(((TMD_P_TG4A*)p)->tu2)-=spr->u0;
	 				(((TMD_P_TG4A*)p)->tv2)-=spr->v0;

	 				(((TMD_P_TG4A*)p)->tu3)-=spr->u0;
	 				(((TMD_P_TG4A*)p)->tv3)-=spr->v0;

				}

		 		((TMD_P_TG4A*)p)->tileduvs=(0xe2<<24)|((spr->x>>3)<<10)|((spr->y>>3)<<15)|((0x20-(spr->w>>3)))|((0x20-(spr->h>>3))<<5);
		 		Set4VertsFromFace(verts,&vert0,&vert1,&vert2,&vert3,face);

		 		((TMD_P_TG4A*)p)->v0=face->vert[0];
		 		((TMD_P_TG4A*)p)->v1=face->vert[1];
		 		((TMD_P_TG4A*)p)->v3=face->vert[2];
		 		((TMD_P_TG4A*)p)->v2=face->vert[3];
  
		 		norm=(NORM*)tmd->nortop;
		 		norm+=tmd->norn;
		 		((TMD_P_TG4A*)p)->n0=tmd->norn;
		 		((TMD_P_TG4A*)p)->n1=tmd->norn+1;		//all normals point the same way at the moment
		 		((TMD_P_TG4A*)p)->n2=tmd->norn+2;		//all normals point the same way at the moment
		 		((TMD_P_TG4A*)p)->n3=tmd->norn+3;		//all normals point the same way at the moment

		 		tmd->norn+=4;
		 		Normal2Plane(&vert0,&vert1,&vert2,norm);
				for(j=1; j<4; j++)
				{
					norm[j].nx=norm->nx;
					norm[j].ny=norm->ny;
					norm[j].nz=norm->nz;
					norm[j].tu=norm->tu;
					norm[j].tv=norm->tv;
				}

				tmd->primn++;

		 		return sizeof(TMD_P_TG4A);
  			break;

		case GPU_COM_TG3: //WORKS! //&34
		 		packetbuildsize+=sizeof(POLY_GT3);	
							
		 		((TMD_P_TG3A*)p)->cd=GPU_COM_TG3|semiflag; //mode
		 		((TMD_P_TG3A*)p)->in=(sizeof(TMD_P_TG3A)/4)-1; //0x9+1; //0x8;  //ilen
		 		((TMD_P_TG3A*)p)->out=0x9; //olen
		 		((TMD_P_TG3A*)p)->code=GPU_COM_TG3|semiflag; //mode YES needs BOTH
		  		((TMD_P_TG3A*)p)->code2=GPU_COM_TG3|semiflag; //mode YES needs BOTH
					
		  		((TMD_P_TG3A*)p)->tile=tiled;

				spr=textureFindInAllBanks(face->texture); 
				((TMD_P_TG3A*)p)->clut=spr->clut;
#ifdef CLUT_FOGGING_CODE
				if(!fogpalette && (spr->clut & 0x8000))	// The model printer doesn't know about fogging
			 		((TMD_P_TG3A*)p)->clut=VRAMfogPalette[spr->clut & 0x7fff];
#endif

				((TMD_P_TG3A*)p)->tpage=spr->tpage|trans;
				((TMD_P_TG3A*)p)->spr=(SPRITE *)spr;

				((TMD_P_TG3A*)p)->r0=face->rgb[0].r;//>>1;
				((TMD_P_TG3A*)p)->g0=face->rgb[0].g;//>>1;
				((TMD_P_TG3A*)p)->b0=face->rgb[0].b;//>>1;
				((TMD_P_TG3A*)p)->r1=face->rgb[1].r;//>>1;
				((TMD_P_TG3A*)p)->g1=face->rgb[1].g;//>>1;
				((TMD_P_TG3A*)p)->b1=face->rgb[1].b;//>>1;
				((TMD_P_TG3A*)p)->r2=face->rgb[2].r;//>>1;
				((TMD_P_TG3A*)p)->g2=face->rgb[2].g;//>>1;
				((TMD_P_TG3A*)p)->b2=face->rgb[2].b;//>>1;


#ifdef CLUT_FOGGING_CODE
				if(fogpalette)
				{
					col=(ULONG)spr->image;//AverageOfClutAccurate(spr);
					
					r=(col&0x1f)<<3;
					g=((col>>5)&0x1f)<<3;
					b=((col>>10)&0x1f)<<3;

					r|=(r>>5);
					g|=(g>>5);
					b|=(b>>5);

					r*=(face->rgb[0].r+face->rgb[1].r+face->rgb[2].r)/3;
					g*=(face->rgb[0].g+face->rgb[1].g+face->rgb[2].g)/3;
					b*=(face->rgb[0].b+face->rgb[1].b+face->rgb[2].b)/3;

					r=r>>7;
					g=g>>7;
					b=b>>7;

					if(r>255) r=255;
					if(g>255) g=255;
					if(b>255) b=255;

					((TMD_P_TG3A*)p)->avgTexCol.r=r;	
					((TMD_P_TG3A*)p)->avgTexCol.g=g;
					((TMD_P_TG3A*)p)->avgTexCol.b=b;	

					((TMD_P_TG3A*)p)->avgTexCol.code=GPU_COM_F4|semiflag; 
				}
#endif
			
				//((TMD_P_TG3A*)p)->avgTexCol.r=face->rgb[0].code;
				//((TMD_P_TG3A*)p)->avgTexCol.g=face->rgb[1].code;
				//((TMD_P_TG3A*)p)->avgTexCol.b=face->rgb[2].code;
	 			 
	 			((TMD_P_TG3A*)p)->tu0=NPercentAcrossX(spr->x,spr->w,uv[0].u,tiled&15);
	 			((TMD_P_TG3A*)p)->tv0=NPercentAcrossX(spr->y,spr->h,uv[0].v,tiled>>4);	
	 					
	 			((TMD_P_TG3A*)p)->tu1=NPercentAcrossX(spr->x,spr->w,uv[1].u,tiled&15);
	 			((TMD_P_TG3A*)p)->tv1=NPercentAcrossX(spr->y,spr->h,uv[1].v,tiled>>4);			
	 			   		
	 			((TMD_P_TG3A*)p)->tu2=NPercentAcrossX(spr->x,spr->w,uv[2].u,tiled&15);	
	 			((TMD_P_TG3A*)p)->tv2=NPercentAcrossX(spr->y,spr->h,uv[2].v,tiled>>4);	

				if(strncmp(face->texture, "ATWAT", 5)==0)
				{
					if(!pWaterSprites)
						pWaterSprites=textureFindFrames("WATER");
					((TMD_P_TG3A*)p)->code2=128;// 128 = anim, 8 = no. of frames

	 				(((TMD_P_TG3A*)p)->tu0)-=spr->u0;
	 				(((TMD_P_TG3A*)p)->tv0)-=spr->v0;

	 				(((TMD_P_TG3A*)p)->tu1)-=spr->u0;
	 				(((TMD_P_TG3A*)p)->tv1)-=spr->v0;

	 				(((TMD_P_TG3A*)p)->tu2)-=spr->u0;
	 				(((TMD_P_TG3A*)p)->tv2)-=spr->v0;
				}

				((TMD_P_TG3A*)p)->tileduvs=(0xe2<<24)|((spr->x>>3)<<10)|((spr->y>>3)<<15)|((0x20-(spr->w>>3)))|((0x20-(spr->h>>3))<<5);

				Set3VertsFromFace(verts,&vert0,&vert1,&vert2,&vert3,face);

				((TMD_P_TG3A*)p)->v0=face->vert[0];
				((TMD_P_TG3A*)p)->v1=face->vert[1];
				((TMD_P_TG3A*)p)->v2=face->vert[2];
					
				norm=(NORM*)tmd->nortop;
				norm+=tmd->norn;
				((TMD_P_TG3A*)p)->n0=tmd->norn;
				((TMD_P_TG3A*)p)->n1=tmd->norn+1;		//all normals point the same way at the moment 
				((TMD_P_TG3A*)p)->n2=tmd->norn+2;		//all normals point the same way at the moment

				tmd->norn+=3;
				Normal2Plane(&vert0,&vert1,&vert2,norm);
				for(j=1; j<3; j++)
				{
					norm[j].nx=norm->nx;
					norm[j].ny=norm->ny;
					norm[j].nz=norm->nz;
					norm[j].tu=norm->tu;
					norm[j].tv=norm->tv;
				}

				tmd->primn++;
		
				return sizeof(TMD_P_TG3A);
			   
 			break;

 	
 	
 			case GPU_COM_TF4: //WORKS! //0x2c

		 		packetbuildsize+=sizeof(POLY_FT4);	

				((TMD_P_TF4A*)p)->cd=GPU_COM_TF4|semiflag; //mode
				((TMD_P_TF4A*)p)->in=(sizeof(TMD_P_TF4A)/4)-1; //0x7+2;  //ilen
				((TMD_P_TF4A*)p)->out=0x9; //olen
				((TMD_P_TF4A*)p)->code=GPU_COM_TF4|semiflag; //mode
					
				spr=textureFindInAllBanks(face->texture); 
				((TMD_P_TF4A*)p)->clut=spr->clut;

#ifdef CLUT_FOGGING_CODE
				if((!fogpalette) && (spr->clut & 0x8000))	// The model printer doesn't know about fogging
			 		((TMD_P_TF4A*)p)->clut=VRAMfogPalette[spr->clut & 0x7fff];
#endif

				((TMD_P_TF4A*)p)->tpage=spr->tpage|trans;
				((TMD_P_TF4A*)p)->spr=(SPRITE *)spr;
						
				((TMD_P_TF4A*)p)->tile=tiled;

			  //	#ifdef WARGAMES
			  //	((TMD_P_TF4A*)p)->r0=face->rgb[0].r;
			  //	((TMD_P_TF4A*)p)->g0=face->rgb[0].g;
			  //	((TMD_P_TF4A*)p)->b0=face->rgb[0].b;
			  //	#else
				((TMD_P_TF4A*)p)->r0=face->rgb[0].r;//>>1;
				((TMD_P_TF4A*)p)->g0=face->rgb[0].g;//>>1;
				((TMD_P_TF4A*)p)->b0=face->rgb[0].b;//>>1;
			  //	#endif
				((TMD_P_TF3A*)p)->avgTexCol.r=face->rgb[0].code;
				((TMD_P_TF3A*)p)->avgTexCol.g=face->rgb[1].code;
				((TMD_P_TF3A*)p)->avgTexCol.b=face->rgb[2].code;
	 			   		

				((TMD_P_TF4A*)p)->tu0=NPercentAcrossX(spr->x,spr->w,uv[0].u,tiled&15);
	 			((TMD_P_TF4A*)p)->tv0=NPercentAcrossX(spr->y,spr->h,uv[0].v,tiled>>4);		
	 				
	 			((TMD_P_TF4A*)p)->tu1=NPercentAcrossX(spr->x,spr->w,uv[1].u,tiled&15);
	 			((TMD_P_TF4A*)p)->tv1=NPercentAcrossX(spr->y,spr->h,uv[1].v,tiled>>4);		
	 		   	
	 		   	((TMD_P_TF4A*)p)->tu2=NPercentAcrossX(spr->x,spr->w,uv[3].u,tiled&15);	
	 		   	((TMD_P_TF4A*)p)->tv2=NPercentAcrossX(spr->y,spr->h,uv[3].v,tiled>>4);	
	 		   				
	 		   	((TMD_P_TF4A*)p)->tu3=NPercentAcrossX(spr->x,spr->w,uv[2].u,tiled&15);	
	 		   	((TMD_P_TF4A*)p)->tv3=NPercentAcrossX(spr->y,spr->h,uv[2].v,tiled>>4);			
				((TMD_P_TF4A*)p)->tileduvs=(0xe2<<24)|((spr->x>>3)<<10)|((spr->y>>3)<<15)|((0x20-(spr->w>>3)))|((0x20-(spr->h>>3))<<5);
			
				Set4VertsFromFace(verts,&vert0,&vert1,&vert2,&vert3,face);
				((TMD_P_TF4A*)p)->v0=face->vert[0];
				((TMD_P_TF4A*)p)->v1=face->vert[1];
				((TMD_P_TF4A*)p)->v2=face->vert[3];
				((TMD_P_TF4A*)p)->v3=face->vert[2];
  				
  				norm=(NORM*)tmd->nortop;
				norm+=tmd->norn;
				((TMD_P_TF4A*)p)->n0=tmd->norn;
				tmd->norn++;
				Normal2Plane(&vert0,&vert1,&vert2,norm);
				
				tmd->primn++;
				return sizeof(TMD_P_TF4A);
  			break;


			case GPU_COM_TF4SPR: //WORKS! //0x2c

			  	debugPrintf ("sprite \n");
		 		packetbuildsize+=sizeof(POLY_FT4);	
			 	((TMD_P_TF4A*)p)->cd=GPU_COM_TF4SPR; //22|semiflag; //mode
			   	((TMD_P_TF4A*)p)->in=(sizeof(TMD_P_TF4A)/4)-1; //0x7+2;  //ilen
			   	((TMD_P_TF4A*)p)->out=0x9; //olen
			 	((TMD_P_TF4A*)p)->code=GPU_COM_TF4SPR; //|semiflag; //mode
						
				spr=textureFindInAllBanks(face->texture); 
				((TMD_P_TF4A*)p)->clut=spr->clut;
#ifdef CLUT_FOGGING_CODE
				if(!fogpalette && (spr->clut & 0x8000))	// The model printer doesn't know about fogging
			 		((TMD_P_TF4A*)p)->clut=VRAMfogPalette[spr->clut & 0x7fff];
#endif

				((TMD_P_TF4A*)p)->tpage=spr->tpage|trans;
				((TMD_P_TF4A*)p)->spr=(SPRITE *)spr;
				
				((TMD_P_TF4A*)p)->tile=tiled;

			  //	#ifdef WARGAMES
			  //	((TMD_P_TF4A*)p)->r0=face->rgb[0].r;
			  //	((TMD_P_TF4A*)p)->g0=face->rgb[0].g;
			  //	((TMD_P_TF4A*)p)->b0=face->rgb[0].b;
			  //	#else
				((TMD_P_TF4A*)p)->r0=face->rgb[0].r;//>>1;
				((TMD_P_TF4A*)p)->g0=face->rgb[0].g;//>>1;
				((TMD_P_TF4A*)p)->b0=face->rgb[0].b;//>>1;
			  //	#endif
				((TMD_P_TF4A*)p)->avgTexCol.r=face->rgb[0].code;
				((TMD_P_TF4A*)p)->avgTexCol.g=face->rgb[1].code;
				((TMD_P_TF4A*)p)->avgTexCol.b=face->rgb[2].code;

				// frig u&v's
				uv[0].u=0;
				uv[0].v=0;
				uv[1].u=255;
				uv[1].v=0;
				uv[2].u=255;
				uv[2].v=255;
				uv[3].u=0;
				uv[3].v=255;
							
				((TMD_P_TF4A*)p)->tu0=NPercentAcrossX(spr->x,spr->w,uv[0].u,tiled&15);
		 		((TMD_P_TF4A*)p)->tv0=NPercentAcrossX(spr->y,spr->h,uv[0].v,tiled>>4);		
	 					
		 		((TMD_P_TF4A*)p)->tu1=NPercentAcrossX(spr->x,spr->w,uv[1].u,tiled&15);
		 		((TMD_P_TF4A*)p)->tv1=NPercentAcrossX(spr->y,spr->h,uv[1].v,tiled>>4);		
	 			   	
		 		((TMD_P_TF4A*)p)->tu2=NPercentAcrossX(spr->x,spr->w,uv[3].u,tiled&15);	
		 		((TMD_P_TF4A*)p)->tv2=NPercentAcrossX(spr->y,spr->h,uv[3].v,tiled>>4);	
	 			  				
		 		((TMD_P_TF4A*)p)->tu3=NPercentAcrossX(spr->x,spr->w,uv[2].u,tiled&15);	
		 		((TMD_P_TF4A*)p)->tv3=NPercentAcrossX(spr->y,spr->h,uv[2].v,tiled>>4);			
		
				((TMD_P_TF4A*)p)->tileduvs=(0xe2<<24)|((spr->x>>3)<<10)|((spr->y>>3)<<15)|((0x20-(spr->w>>3)))|((0x20-(spr->h>>3))<<5);
				
			   //	SetVertsFromFace(model->verts,&vert0,&vert1,&vert2,&vert3,face);




				verts[face->vert[0]].x=verts[face->vert[0]].x/MODELSCALE;
				verts[face->vert[0]].y=-verts[face->vert[0]].y/MODELSCALE;		
				verts[face->vert[0]].z=verts[face->vert[0]].z/MODELSCALE;

				verts[face->vert[1]].x=verts[face->vert[1]].x/MODELSCALE;
				verts[face->vert[1]].y=-verts[face->vert[1]].y/MODELSCALE;		


				Set4VertsFromFace(verts,&vert0,&vert1,&vert2,&vert3,face);

				((TMD_P_TF4A*)p)->v0=face->vert[0]; // centre position
				((TMD_P_TF4A*)p)->v1=face->vert[1]; // size of sprite (x,y)
 
				//if(verts[face->vert[1]].x<0)
				//	verts[face->vert[1]].x=-verts[face->vert[1]].x;

				//if(verts[face->vert[1]].y<0)
				//	verts[face->vert[1]].y=-verts[face->vert[1]].y;

				printf("sprite height = %d, width = %d\n", verts[face->vert[1]].x, verts[face->vert[1]].y);

			  	norm=(NORM*)tmd->nortop;
			  	norm+=tmd->norn;
			  	((TMD_P_TF4A*)p)->n0=tmd->norn;
			  	tmd->norn++;
			  	Normal2Plane(&vert0,&vert1,&vert2,norm);
				//debugPrintf ("x %d y %d z %d\n",vert0.vx,vert0.vy,vert0.vz);
				tmd->primn++;

			   	return sizeof(TMD_P_TF4A);
			break;

 		case GPU_COM_TF3:  //WORKS!	 ////0x24
 		
		 		packetbuildsize+=sizeof(POLY_FT3);	

		  	  	((TMD_P_TF3A*)p)->cd=GPU_COM_TF3|semiflag; //mode
		  	  	((TMD_P_TF3A*)p)->in=(sizeof(TMD_P_TF3A)/4)-1; //0x5+2;  //ilen
		  	  	((TMD_P_TF3A*)p)->out=0x7; //olen
		  	  	((TMD_P_TF3A*)p)->code=GPU_COM_TF3|semiflag; //mode
				
			   	//if ((face->flags &(TILEDV+TILEDH))) alignTextures=YES;
			   	spr=textureFindInAllBanks(face->texture); 
				
			   	((TMD_P_TF3A*)p)->clut=spr->clut;
#ifdef CLUT_FOGGING_CODE
				if(!fogpalette && (spr->clut & 0x8000))	// The model printer doesn't know about fogging
			 		((TMD_P_TF3A*)p)->clut=VRAMfogPalette[spr->clut & 0x7fff];
#endif

			   	((TMD_P_TF3A*)p)->tpage=spr->tpage|trans;
			   	((TMD_P_TF3A*)p)->spr=(SPRITE *)spr;
			   	((TMD_P_TF3A*)p)->tile=tiled;

				((TMD_P_TF3A*)p)->r0=face->rgb[0].r;//>>1;
			    ((TMD_P_TF3A*)p)->g0=face->rgb[0].g;//>>1;
				((TMD_P_TF3A*)p)->b0=face->rgb[0].b;//>>1;

				((TMD_P_TF3A*)p)->avgTexCol.r=face->rgb[0].code;
				((TMD_P_TF3A*)p)->avgTexCol.g=face->rgb[1].code;
				((TMD_P_TF3A*)p)->avgTexCol.b=face->rgb[2].code;
			  //	#endif




//		   		((TMD_P_TF3A*)p)->tu0=NPercentAcrossX(spr->x,spr->w,face->uv[0].u,face->tiled&15);
  //				((TMD_P_TF3A*)p)->tv0=NPercentAcrossX(spr->y,spr->h,face->uv[0].v,face->tiled>>4);	
	 				


  	 			((TMD_P_TF3A*)p)->tu0=NPercentAcrossX(spr->x,spr->w,uv[0].u,tiled&15);
	 			((TMD_P_TF3A*)p)->tv0=NPercentAcrossX(spr->y,spr->h,uv[0].v,tiled>>4);	
	 			
	 			((TMD_P_TF3A*)p)->tu1=NPercentAcrossX(spr->x,spr->w,uv[1].u,tiled&15);
	 			((TMD_P_TF3A*)p)->tv1=NPercentAcrossX(spr->y,spr->h,uv[1].v,tiled>>4);			
				
				((TMD_P_TF3A*)p)->tu2=NPercentAcrossX(spr->x,spr->w,uv[2].u,tiled&15);	
	 			((TMD_P_TF3A*)p)->tv2=NPercentAcrossX(spr->y,spr->h,uv[2].v,tiled>>4);	
				((TMD_P_TF3A*)p)->tileduvs=(0xe2<<24)|((spr->x>>3)<<10)|((spr->y>>3)<<15)|((0x20-(spr->w>>3)))|((0x20-(spr->h>>3))<<5);

				Set3VertsFromFace(verts,&vert0,&vert1,&vert2,&vert3,face);

				((TMD_P_TF3A*)p)->v0=face->vert[0];
				((TMD_P_TF3A*)p)->v1=face->vert[1];
				((TMD_P_TF3A*)p)->v2=face->vert[2];
						
				norm=(NORM*)tmd->nortop;
				norm+=tmd->norn;
				((TMD_P_TF3A*)p)->n0=tmd->norn;
				tmd->norn++;
				Normal2Plane(&vert0,&vert1,&vert2,norm);

				tmd->primn++;
				return sizeof(TMD_P_TF3A);
			break;
   

			 case GPU_COM_G4:			 
		 		packetbuildsize+=sizeof(POLY_G4);	
		
			   	((TMD_P_F4G*)p)->cd=GPU_COM_G4|semiflag; //mode
			   	((TMD_P_F4G*)p)->in=(sizeof(TMD_P_F4G)/4)-1; //0x7;  //ilen
			  	((TMD_P_F4G*)p)->out=0x8; //olen

			  	((TMD_P_F4G*)p)->r0=face->rgb[0].r;//>>1;
			  	((TMD_P_F4G*)p)->g0=face->rgb[0].g;//>>1;
			  	((TMD_P_F4G*)p)->b0=face->rgb[0].b;//>>1;
			 	((TMD_P_F4G*)p)->r1=face->rgb[1].r;//>>1;
			  	((TMD_P_F4G*)p)->g1=face->rgb[1].g;//>>1;
			  	((TMD_P_F4G*)p)->b1=face->rgb[1].b;//>>1;
			  	((TMD_P_F4G*)p)->r2=face->rgb[3].r;//>>1;
			 	((TMD_P_F4G*)p)->g2=face->rgb[3].g;//>>1;
			  	((TMD_P_F4G*)p)->b2=face->rgb[3].b;//>>1;
			  	((TMD_P_F4G*)p)->r3=face->rgb[2].r;//>>1;
			  	((TMD_P_F4G*)p)->g3=face->rgb[2].g;//>>1;
			  	((TMD_P_F4G*)p)->b3=face->rgb[2].b;//>>1;
					  
			  	((TMD_P_F4G*)p)->code=GPU_COM_G4|semiflag;
					  	
			  //	SetVertsFromFace(model->verts,&vert0,&vert1,&vert2,&vert3,face);
				Set4VertsFromFace(verts,&vert0,&vert1,&vert2,&vert3,face);

			   	((TMD_P_F4G*)p)->v0=face->vert[0];
				((TMD_P_F4G*)p)->v1=face->vert[1];
				((TMD_P_F4G*)p)->v2=face->vert[3];
				((TMD_P_F4G*)p)->v3=face->vert[2];

			   	norm=(NORM*)tmd->nortop;
			  	norm+=tmd->norn;
			  	((TMD_P_F4G*)p)->n0=tmd->norn;
			   	tmd->norn++;
				Normal2Plane(&vert0,&vert1,&vert2,norm);
				tmd->primn++;

				return sizeof(TMD_P_F4G);
			break;

					 
	
			case GPU_COM_G3:
		 		packetbuildsize+=sizeof(POLY_G3);	

				((TMD_P_F3G*)p)->cd=GPU_COM_G3|semiflag; //mode
				((TMD_P_F3G*)p)->in=(sizeof(TMD_P_F3G)/4)-1; //0x5;  //ilen
				((TMD_P_F3G*)p)->out=0x6; //olen
				((TMD_P_F3G*)p)->code=GPU_COM_G3|semiflag;
 
				((TMD_P_F3G*)p)->r0=face->rgb[0].r;//>>1;
				((TMD_P_F3G*)p)->g0=face->rgb[0].g;//>>1;
				((TMD_P_F3G*)p)->b0=face->rgb[0].b;//>>1;

				((TMD_P_F3G*)p)->r1=face->rgb[1].r;//>>1;
				((TMD_P_F3G*)p)->g1=face->rgb[1].g;//>>1;
				((TMD_P_F3G*)p)->b1=face->rgb[1].b;//>>1;

				((TMD_P_F3G*)p)->r2=face->rgb[2].r;//>>1;
				((TMD_P_F3G*)p)->g2=face->rgb[2].g;//>>1;
				((TMD_P_F3G*)p)->b2=face->rgb[2].b;//>>1;

			 //	SetVertsFromFace(model->verts,&vert0,&vert1,&vert2,&vert3,face);
				Set3VertsFromFace(verts,&vert0,&vert1,&vert2,&vert3,face);
				((TMD_P_F3G*)p)->v0=face->vert[0];
				((TMD_P_F3G*)p)->v1=face->vert[1];
				((TMD_P_F3G*)p)->v2=face->vert[2];

				norm=(NORM*)tmd->nortop;
				norm+=tmd->norn;
				((TMD_P_F3G*)p)->n0=tmd->norn;
				tmd->norn++;
				Normal2Plane(&vert0,&vert1,&vert2,norm);
				tmd->primn++;
						
				return sizeof(TMD_P_F3G);

	
			case GPU_COM_F4:   //0x28
		 		packetbuildsize+=sizeof(POLY_F4);	
			   	((TMD_P_F4*)p)->cd=GPU_COM_F4|semiflag; //mode
			   	((TMD_P_F4*)p)->in=(sizeof(TMD_P_F4)/4)-1; //0x4;  //ilen
			  	((TMD_P_F4*)p)->out=0x5; //olen

			  	((TMD_P_F4*)p)->r0=face->rgb[0].r;//>>1;
			 	((TMD_P_F4*)p)->g0=face->rgb[0].g;//>>1;
			  	((TMD_P_F4*)p)->b0=face->rgb[0].b;//>>1;
			  	((TMD_P_F4*)p)->code=GPU_COM_F4|semiflag;
					  	
			 //	SetVertsFromFace(model->verts,&vert0,&vert1,&vert2,&vert3,face);
				Set4VertsFromFace(verts,&vert0,&vert1,&vert2,&vert3,face);

			   	((TMD_P_F4*)p)->v0=face->vert[0];
				((TMD_P_F4*)p)->v1=face->vert[1];
				((TMD_P_F4*)p)->v2=face->vert[3];
				((TMD_P_F4*)p)->v3=face->vert[2];

			   	norm=(NORM*)tmd->nortop;
			   	norm+=tmd->norn;
			   	((TMD_P_F4*)p)->n0=tmd->norn;
			   	tmd->norn++;
				Normal2Plane(&vert0,&vert1,&vert2,norm);
				tmd->primn++;

				return sizeof(TMD_P_F4);
			break;

	
			case GPU_COM_F3:   //WORKS!

		 		packetbuildsize+=sizeof(POLY_F3);	

				((TMD_P_F3*)p)->cd=GPU_COM_F3|semiflag; //mode
				((TMD_P_F3*)p)->in=(sizeof(TMD_P_F3)/4)-1; //0x3;  //ilen
				((TMD_P_F3*)p)->out=0x4; //olen
 				((TMD_P_F3*)p)->code=GPU_COM_F3|semiflag; //mode
				
				((TMD_P_F3*)p)->r0=face->rgb[0].r;//>>1;
				((TMD_P_F3*)p)->g0=face->rgb[0].g;//>>1;
				((TMD_P_F3*)p)->b0=face->rgb[0].b;//>>1;
					  	
				Set3VertsFromFace(verts,&vert0,&vert1,&vert2,&vert3,face);

				((TMD_P_F3*)p)->v0=face->vert[0];
				((TMD_P_F3*)p)->v1=face->vert[1];
				((TMD_P_F3*)p)->v2=face->vert[2];

				norm=(NORM*)tmd->nortop;
				norm+=tmd->norn;
				((TMD_P_F3*)p)->n0=tmd->norn;
				tmd->norn++;
				Normal2Plane(&vert0,&vert1,&vert2,norm);
				tmd->primn++;

				return sizeof(TMD_P_F3);
		
			break;		 

  
   			default:
					debugPrintf("W-%x,",type);
			break;
   			
   			}

	return 0;
}

/*********************************************************************************************************************/
void Do_BoundBox(NEWTMD* tmd){
VERT *vert;
LONG j;

	vert=(VERT*)tmd->vertop;
	tmd->boundminx=tmd->boundmaxx=vert->vx;		// X bounds
	tmd->boundminy=tmd->boundmaxy=vert->vy;		// Y bounds
	tmd->boundminz=tmd->boundmaxz=vert->vz;		// Z bounds
	
	for (j=tmd->vern;j!=0;j--)
	{
		if (vert->vx<tmd->boundminx) tmd->boundminx=vert->vx;
		if (vert->vx>tmd->boundmaxx) tmd->boundmaxx=vert->vx;
		if (vert->vy<tmd->boundminy) tmd->boundminy=vert->vy;
		if (vert->vy>tmd->boundmaxy) tmd->boundmaxy=vert->vy;
		if (vert->vz<tmd->boundminz) tmd->boundminz=vert->vz;
		if (vert->vz>tmd->boundmaxz) tmd->boundmaxz=vert->vz;
		vert++;
	}
	tmd->center.vx=(tmd->boundminx+tmd->boundmaxx)/2;
	tmd->center.vy=(tmd->boundminy+tmd->boundmaxy)/2;
	tmd->center.vz=(tmd->boundminz+tmd->boundmaxz)/2;
}

/*****************************************************************************************************************/
SPRITE*	FindTexture(UBYTE *name)
{
	return (SPRITE*)textureFindInAllBanks(name);
}


void
StopVectorWrap(VECTOR *v){	//reduce a bit 'cos they're big!
//below is recomended way to check for over-large vectors which could wrap round.
LONG a,b=0;
	a=absmax3(v->vx,v->vy,v->vz);
	a=abs(a);
	if(abs(a)>181){
	b=fast_sqrt(a)>>16;
		v->vx/=b;
		v->vy/=b;
		v->vz/=b;
		}
}

void Normal2Plane(VERT *p0,VERT *p1,VERT *p2,NORM *n)
{
	VECTOR v0,v1,v2,v3;

	v1.vx=p1->vx-p0->vx;
	v1.vy=p1->vy-p0->vy;
	v1.vz=p1->vz-p0->vz;

	v0.vx=p2->vx-p0->vx;
	v0.vy=p2->vy-p0->vy;
	v0.vz=p2->vz-p0->vz;

	OuterProduct0(&v0,&v1,&v2);
	StopVectorWrap(&v2);
	VectorNormal(&v2,&v3);

	n->nx=v3.vx;
	n->ny=v3.vy;
	n->nz=v3.vz;

	if(n->nx>=4095)n->nx=4094;
	if(n->nx<=-4095)n->nx=-4094;
	if(n->ny>=4095)n->ny=4094;
	if(n->ny<=-4095)n->ny=-4094;
	if(n->nz>=4095)n->nz=4094;
	if(n->nz<=-4095)n->nz=-4094;

	n->tu=eachpoly;// I've used a global. Sorry.
	n->tv=0;	
}		

void averageNormals(NEWTMD *pTMD)
{
	int i,j;
	int used;
	int sides;
	int nn,vn;
	int nPolys=pTMD->primn;
	NORM *pNorm=pTMD->nortop;
	register TMD_P_TF4A	*op=(TMD_P_TF4A	*)(pTMD->primtop);
	long n[4],v[4];
	NORM *pTable=(NORM *)MALLOC((pTMD->vern)*sizeof(NORM), "TEMP TABLE");
	ASSERT(pTable);

	for(i=0; i<pTMD->vern; i++)
	{
		pTable[i].nx=pTable[i].ny=pTable[i].nz=0;
		pTable[i].tu=pTable[i].tv=0;
	}

	for(i=0; i<nPolys; i++)
	{
		sides=0;

		switch (op->cd & (0xff-2))
		{
		case GPU_COM_TG4:
			sides=4;
			n[0]=((TMD_P_TG4A *)op)->n0; v[0]=((TMD_P_TG4A *)op)->v0;
			n[1]=((TMD_P_TG4A *)op)->n1; v[1]=((TMD_P_TG4A *)op)->v1;
			n[2]=((TMD_P_TG4A *)op)->n2; v[2]=((TMD_P_TG4A *)op)->v2;
			n[3]=((TMD_P_TG4A *)op)->n3; v[3]=((TMD_P_TG4A *)op)->v3;
			op=(TMD_P_TF4A *)(((long)op)+sizeof(TMD_P_TG4A));
			break;

		case GPU_COM_TG3:
			sides=3;
			n[0]=((TMD_P_TG3A *)op)->n0; v[0]=((TMD_P_TG3A *)op)->v0;
			n[1]=((TMD_P_TG3A *)op)->n1; v[1]=((TMD_P_TG3A *)op)->v1;
			n[2]=((TMD_P_TG3A *)op)->n2; v[2]=((TMD_P_TG3A *)op)->v2;
			op=(TMD_P_TF4A *)(((long)op)+sizeof(TMD_P_TG3A));
		}

		if(!sides)
			continue;

		for(j=0; j<sides; j++)
		{
			nn=n[j];
			vn=v[j];
			(pTable[vn].nx)+=pNorm[nn].nx;
			(pTable[vn].ny)+=pNorm[nn].ny;
			(pTable[vn].nz)+=pNorm[nn].nz;

			(pTable[vn].tu)++;
		}
	}

	op=(TMD_P_TF4A	*)(pTMD->primtop); // reset op

	// go round again ...
	for(i=0; i<nPolys; i++)
	{
		sides=0;

		switch (op->cd & (0xff-2))
		{
		case GPU_COM_TG4:
			sides=4;
			n[0]=((TMD_P_TG4A *)op)->n0; v[0]=((TMD_P_TG4A *)op)->v0;
			n[1]=((TMD_P_TG4A *)op)->n1; v[1]=((TMD_P_TG4A *)op)->v1;
			n[2]=((TMD_P_TG4A *)op)->n2; v[2]=((TMD_P_TG4A *)op)->v2;
			n[3]=((TMD_P_TG4A *)op)->n3; v[3]=((TMD_P_TG4A *)op)->v3;
			op=(TMD_P_TF4A *)(((long)op)+sizeof(TMD_P_TG4A));
			break;

		case GPU_COM_TG3:
			sides=3;
			n[0]=((TMD_P_TG3A *)op)->n0; v[0]=((TMD_P_TG3A *)op)->v0;
			n[1]=((TMD_P_TG3A *)op)->n1; v[1]=((TMD_P_TG3A *)op)->v1;
			n[2]=((TMD_P_TG3A *)op)->n2; v[2]=((TMD_P_TG3A *)op)->v2;
			op=(TMD_P_TF4A *)(((long)op)+sizeof(TMD_P_TG3A));
		}

		if(!sides)
			continue;

		for(j=0; j<sides; j++)
		{
			nn=n[j];
			vn=v[j];
			used=pTable[vn].tu;

			pNorm[nn].nx=pTable[vn].nx/used;
			pNorm[nn].ny=pTable[vn].ny/used;
			pNorm[nn].nz=pTable[vn].nz/used;
		}
	}

	FREE(pTable);
}

/**************************************************************************************************************/
void
Reverse_SortTables(NEWTMD* tmptmd)
{
int	*temptable;
ULONG	loop,loop1,size;

//	store=jallocctrl.usetempmalloc;

//	jallocctrl.usetempmalloc=YES;
 	

	for (loop1=0;loop1<4;loop1++)
	{
		size=tmptmd->sorttablesize[loop1];
	   	temptable=MALLOC(sizeof(int)*(size),"TEMP SORT TABLE");
		ASSERT(temptable);

		for (loop=0;loop<size;loop++)
		{
			*(temptable+((size-loop)-1))=tmptmd->sorttable[loop1][loop];
		}
		for (loop=0;loop<size;loop++)
		{
			tmptmd->sorttable[loop1][loop]=*(temptable+loop);
		}
	   	FREE(temptable);
	}

//	jallocctrl.usetempmalloc=store;
}



/**************************************************************************************************************/
void
CopyVertsNew(NEWVERT *modelverts,VERT*tmdverts,LONG num){
LONG j;

	for (j=0;j<num;j++){
			if (OBEflag==NO){
		  	tmdverts[j].vx=+(modelverts[j].x)/MODELSCALE;
		  	tmdverts[j].vy=-(modelverts[j].y)/MODELSCALE;
		  	tmdverts[j].vz=+(modelverts[j].z)/MODELSCALE;
			}
			else{
		  	tmdverts[j].vx=+(modelverts[j].x)/2;
		  	tmdverts[j].vy=-(modelverts[j].y)/2;
		  	tmdverts[j].vz=+(modelverts[j].z)/2;

			}
	}
}
/*********************************************************************************************************************/
void
CopyVertsSpr(NEWVERT *modelverts,VERT*tmdverts,LONG num){
LONG j;

	for (j=0;j<num;j++){
			if (OBEflag==NO){
		  	tmdverts[j].vx=+(modelverts[j].x);
		  	tmdverts[j].vy=+(modelverts[j].y);
		  	tmdverts[j].vz=+(modelverts[j].z);
			}
			else{
		  	tmdverts[j].vx=+(modelverts[j].x)/2;
		  	tmdverts[j].vy=+(modelverts[j].y)/2;
		  	tmdverts[j].vz=+(modelverts[j].z)/2;

			}
	}
}


/*********************************************************************************************************************/

void SetVertsFromFaceSpr(NEWVERT* verts,VERT *vert0,VERT *vert1,VERT *vert2,VERT *vert3,PSAFACE *face)
{

		vert0->vx=(verts[face->vert[0]].x); ///size;
		vert2->vy=-(verts[face->vert[0]].y); ///size;
		vert0->vz=(verts[face->vert[0]].z); ///size;

		vert1->vx=(verts[face->vert[1]].x); ///size;
		vert3->vy=-(verts[face->vert[0]].y); ///size;
		vert1->vz=(verts[face->vert[0]].z); ///size;

		vert3->vx=(verts[face->vert[0]].x); ///size;
		vert0->vy=-(verts[face->vert[1]].y); ///size;
		vert3->vz=(verts[face->vert[0]].z); ///size;

		vert2->vx=(verts[face->vert[1]].x); ///size;
		vert1->vy=-(verts[face->vert[1]].y); ///size;
		vert2->vz=(verts[face->vert[0]].z); ///size;
}

void uploadTimToVRAM(ULONG *addr)
{
	RECT rect1;
	GsIMAGE tim1;

	/* get TIM data info. */	
	/* skip and pass file header*/
	GsGetTimInfo(addr+1, &tim1);	

	/* transfer pixel data to VRAM*/	
	rect1.x=tim1.px;
	rect1.y=tim1.py;
	rect1.w=tim1.pw;
	rect1.h=tim1.ph;

#if PALMODE == NO
/*
	memset(tim1.pixel + 8 * tim1.pw/2, 255, tim1.pw/2);
	memset(tim1.pixel + 16 * tim1.pw/2, 255, tim1.pw/2);
	memset(tim1.pixel + 24 * tim1.pw/2, 255, tim1.pw/2);

	memset(tim1.pixel + (240-8) * tim1.pw/2, 255, tim1.pw/2);
	memset(tim1.pixel + (240-16) * tim1.pw/2, 255, tim1.pw/2);
	memset(tim1.pixel + (240-24) * tim1.pw/2, 255, tim1.pw/2);
*/

/*
	if(rect1.x == 0 && rect1.y == 0)
	{
		rect1.h -= 16;
		LoadImage(&rect1,tim1.pixel + 8 * tim1.pw);
	}
	else
*/
	{
		LoadImage(&rect1,tim1.pixel);
	}
#endif
#if PALMODE == YES
	LoadImage(&rect1,tim1.pixel);
#endif


	/* if CLUT exists, transfer it to VRAM*/
	if((tim1.pmode>>3)&0x01)
	{
		rect1.x=tim1.cx;
		rect1.y=tim1.cy;
		rect1.w=tim1.cw;
		rect1.h=tim1.ch;
		LoadImage(&rect1,tim1.clut);
	}
}



#endif
