#include "glover.h"
// include other header files as you need them in between these two 


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

//#define	PRINTMESS	FALSE


COLLBOX		*collBox;
long		numCollBoxes;
COLLDATA	ballColl,gloveColl,cameraColl;

HITDATA 	pHitData[16]; // max number of hits


VECTOR ballVel, ballPos, ballRot;
VECTOR cameraVel, cameraPos, cameraRot;	// added for camera collision
VECTOR gloveVel,glovePos;
NEWMODEL	*pBallPSA;
NEWMODEL	*pGlovePSA;
NEWMODEL	*pPlasterPSA;

//BallPhysics	BallCtrl[NUM_BALL_MODES];

long    ballRadius=77824;
long    ballGravity=4096;


//SETUP BALL DATA //
BALLCTRL	BallCtrl;

BEHAVIOUR_PHYSICS	GloveBehaviour=
{
	10*4096,			// mass;
	GRAVITY,			// gravity;
	0*4096,				// bounce (glove dont bounce)
	(4096-(4096*0.1)),	// drag
	4096*10,			// maxspeed
	19*4096,			// radius
	4096,				// accel
};


BEHAVIOUR_PHYSICS	BallBehaviour[NUM_BALL_MODES]=
{
	//NORMAL_BALL
	{
		10*4096,			// mass;
		GRAVITY,			// gravity;
		.8*4096,			// bounce
		(4096-(4096*0.1)),	// drag
		4096*10,			// maxspeed
		19*4096,			// radius
		4096,				// accel
	},
	//BOWLING_BALL
	{
		18*4096,			// mass;
		GRAVITY,			// gravity;
		.6*4096,			// bounce
		(4096-(4096*0.1)),	// drag
		4096*10,			// maxspeed
		(19*4096)*1.4, 		// radius 	(may need to come back and remove floats)
		4096/1.98,			// accel
	},
	//POWER_BALL
	{
		7*4096,				// mass;
		GRAVITY,			// gravity;
		.99*4096,			// bounce
		(4096-(4096*0.1)),	// drag
		4096*10,			// maxspeed
		(19*4096)*0.6, 		// radius 	(may need to come back and remove floats)
		4096*1.5, 			// accel
	},
	//BALL_BEARING
	{
		10*4096,			// mass;
		GRAVITY,			// gravity;
		.6*4096,			// bounce
		(4096-(4096*0.1)),	// drag
		4096*10,			// maxspeed
		(19*4096)*0.6, 		// radius 	(may need to come back and remove floats)
		4096, 				// accel
	},
	//BEACH_BALL
	{
		3*4096,				// mass;
		GRAVITY,			// gravity;
		.9*4096,			// bounce
		(4096-(4096*0.1)),	// drag
		4096*10,			// maxspeed
		(19*4096)*2.5, 		// radius 	(may need to come back and remove floats)
		4096,	 			// accel
	},
	//CRYSTAL_BALL
	{
		12*4096,			// mass;
		GRAVITY,			// gravity;
		.6*4096,			// bounce
		(4096-(4096*0.1)),	// drag
		4096*10,			// maxspeed
		(19*4096)*0.9, 		// radius 	(may need to come back and remove floats)
		4096,	 			// accel
	},
	//SNOW_BALL
	{
		10*4096,			// mass;
		GRAVITY,			// gravity;
		.6*4096,			// bounce
		(4096-(4096*0.1)),	// drag
		4096*10,			// maxspeed
		(19*4096)*1, 		// radius 	(may need to come back and remove floats)
		4096,	 			// accel
	},
};



/***********************************************************************/
//SPRITE	*testTex1,*testTex2;

SPRITE	*ballTex[7];

char *ballNames[]=
{
	"Normal",
	"Bowling",
	"Power",
	"Bearing",
	"Beach",
	"Snow",
	"Crystal"
};


void
Load_And_Init_Ball(){	
/*
	pBallPSA=LoadPSA("TEST\\GBALL.PSA");
//	pBallPSA=LoadPSA("TEST\\GOODGLOV.PSA");
//	printf("read glove file\n");
	objectSetupSegmentSort(pBallPSA);
	pBallPSA->globalscale.vx=320;
	pBallPSA->globalscale.vy=320;
	pBallPSA->globalscale.vz=320;
	   
	ballColl.nBoxes=numCollBoxes;
	ballColl.bounce=4096;
	ballColl.radius=16*4096;
	ballColl.pCollBox=collBox;
	ballColl.pVel=&ballVel;
	ballColl.pPos=&ballPos;
	ballColl.pRot=&ballRot;	// changed from FVECTOR

	ZeroVector(&ballVel);
	ZeroVector(&ballPos);

	ballPos.vx=50*4096;
	ballPos.vy=-100*4096;
	ballPos.vz=10*4096;
	ZeroVector(&ballRot);
*/

	ballTex[0]=FindTexture("NEWBALL2"); // normal
	ballTex[1]=FindTexture("BOWLING");	// bowling ball
	ballTex[2]=FindTexture("BOTBLUE");	// need power ball texture
	ballTex[3]=FindTexture("BEARING");	// ball bearing
	ballTex[4]=FindTexture("BEACH");	// beachball
	ballTex[5]=FindTexture("WHITE");	// need snow texture
	//ballTex[5]=FindTexture("WFALL3");	// need snow texture
	ballTex[6]=FindTexture("CBALL");	// crystal ball

	pBallPSA=LoadPSA("TEST\\GBALL.PSA");
	pPlasterPSA=LoadPSA("TEST\\PLASTER.PSA");

//	pBallPSA=LoadPSA("test\\goodglov.psa");
//	printf("read glove file\n");
	objectSetupSegmentSort(pBallPSA);
	objectSetupSegmentSort(pPlasterPSA);

	pBallPSA->globalscale.vx=512;
	pBallPSA->globalscale.vy=512;
	pBallPSA->globalscale.vz=512;

	pBallPSA->world.qRot.x=-2896;
	pBallPSA->world.qRot.y=0;
	pBallPSA->world.qRot.z=0;
	pBallPSA->world.qRot.w=2896;


	pBallPSA->world.qRotVel.x=0;
	pBallPSA->world.qRotVel.y=0;
	pBallPSA->world.qRotVel.z=0;
	pBallPSA->world.qRotVel.w=4096;


	pBallPSA->world.qRotLight.x=-2896;
	pBallPSA->world.qRotLight.y=0;
	pBallPSA->world.qRotLight.z=0;
	pBallPSA->world.qRotLight.w=-2896;


	pBallPSA->world.qRotLightVel.x=0;
	pBallPSA->world.qRotLightVel.y=0;
	pBallPSA->world.qRotLightVel.z=0;
	pBallPSA->world.qRotLightVel.w=4096;

	   
	ballColl.nBoxes=numCollBoxes;
//	ballColl.bounce=4096;	// now exzists in physics
	ballColl.radius=19*4096;
	ballColl.pCollBox=collBox;
	ballColl.pVel=&ballVel;
	ballColl.pPos=&ballPos;
	ballColl.pRot=&ballRot;	// changed from FVECTOR


	ballColl.physics=&BallBehaviour[0];
	ballColl.physicsModel=BALL_MODE_NORMAL;

	ZeroVector(&ballVel);
	ZeroVector(&ballPos);

	ballPos.vx=0; //247*4096;
	ballPos.vy=-100*4096; //-280*4096;
	ballPos.vz=1300*4096; //1572*4096;


//	ballPos.vx=50*4096;
//	ballPos.vy=-480*4096;
//	ballPos.vz=394*4096;

//	BallCtrl.gravity=4096;
//	BallCtrl.bounce=4000;
//	BallCtrl.drag=4000;
//	BallCtrl.maxSpeed=4096*7;

//	BallCtrl.gravity=4000;
//	BallCtrl.bounce=4000;
//	BallCtrl.drag=4096;
//	BallCtrl.maxSpeed=4096*10;
	BallCtrl.type=BALL_MODE_NORMAL;
	BallCtrl.hurt=FALSE;	// set ball hurt on

	ZeroVector(&ballRot);

}

/***********************************************************************/
GLOVECTRL	GloveCtrl;
VECTOR		GloveVel;
//objectSegDataType	*gloveSeg;
void
Load_And_Init_Glove(){
	
  	pGlovePSA=LoadPSA("CHARS\\LOGLOVE.PSA");
	//pGlovePSA=LoadPSA("test\\goodglov.psa");
	objectSetupSegmentSort(pGlovePSA);
 	pGlovePSA->globalscale.vx=320;
 	pGlovePSA->globalscale.vy=320;
 	pGlovePSA->globalscale.vz=320;


//	glovePos.vx=ballPos.vx+(50*4096);
//	glovePos.vy=ballPos.vy-(50*4096);
//	glovePos.vz=ballPos.vz;

	glovePos.vx=215363;
	glovePos.vy=-622592;
	glovePos.vz=10403839;


	//gloveSeg=objectLoadSeg("test\\goodglov.seg");

	GloveCtrl.direction=2048;
	GloveCtrl.radius=19*4096;
	GloveCtrl.speed=0;
	GloveCtrl.oldSpeed=0;
	GloveCtrl.animFrame=112;
	GloveCtrl.animState=IDLE;
	GloveCtrl.animSpeed=1;
	GloveCtrl.animCount=0;

	gloveColl.nBoxes=numCollBoxes;
	//gloveColl.bounce=0;//4096;
	gloveColl.radius=20*4096;
//	gloveColl.radius=60*4096;
	gloveColl.pCollBox=collBox;
	gloveColl.pVel=&gloveVel;
	gloveColl.pPos=&glovePos;

	//GloveColl.pRot=&ballRot;	// changed from FVECTOR

	gloveColl.physics=&GloveBehaviour;
	gloveColl.physicsModel=0;	// only one for glove

	cameraColl.nBoxes=numCollBoxes; // collision stuff for camera
	//cameraColl.bounce=4096;
	cameraColl.radius=20*4096;
	cameraColl.pCollBox=collBox;
	cameraColl.pVel=&cameraVel;
	cameraColl.pPos=&cameraPos;
	cameraColl.pRot=&cameraRot;
	cameraColl.physics=NULL;

}


/***********************************************************************/
void Control_Ball_And_Glove(void)
{
	int	loop; 
	VECTOR	tempVect;
	IQUATERNION	tempQ;
	//	,mapx,mapy,mapz;
	textSetPos(32,8);

	sprctrl.r=0;
	sprctrl.g=128;
	sprctrl.b=0;

	sprctrl.scalex=4096;
	sprctrl.scaley=4096;
	sprctrl.stretch=0;

//	if (CamVars.mode==CAM_BALL){
	if (CamVars.targetmodel==pBallPSA)
	{
		if(pad[0]&PAD_LEFT)			ballVel.vx-=4096;
		else if(pad[0]&PAD_RIGHT) 	ballVel.vx+=4096;
		if(pad[0]&PAD_DOWN)			ballVel.vz-=4096;
		else if(pad[0]&PAD_UP)		ballVel.vz+=4096;

		if(pad[0]&PAD_CROSS)
			if ( (getHeightAt(ballPos.vx, ballPos.vy, ballPos.vz) < (ballColl.radius+ballColl.radius/10)) && (getHeightAt(ballPos.vx, ballPos.vy, ballPos.vz)!=-1) )
			{
				ballVel.vy+=ballColl.physics[ballColl.physicsModel].gravity*30;
			}

		if( (debounce[1]&PAD_CIRCLE) ) 
		{
			BallCtrl.type++;
			if (BallCtrl.type==NUM_BALL_MODES) BallCtrl.type=BALL_MODE_NORMAL;

			ballRadius=BallBehaviour[BallCtrl.type].radius;
			ballGravity=BallBehaviour[BallCtrl.type].gravity;
			ballColl.physicsModel=BallCtrl.type;
			ChangeBall(&pBallPSA->world,ballTex[BallCtrl.type]);
		}
		if( (debounce[1]&PAD_SQUARE) )
		{
			BallCtrl.type--;
			if (BallCtrl.type<BALL_MODE_NORMAL) BallCtrl.type=BALL_MODE_CRYSTAL;

			ballRadius=BallBehaviour[BallCtrl.type].radius;
			ballGravity=BallBehaviour[BallCtrl.type].gravity;
			ballColl.physicsModel=BallCtrl.type;
			ChangeBall(&pBallPSA->world,ballTex[BallCtrl.type]);
		}
	}
	if (PRINTMESS) textPrintf("Ball Type= %s\n",ballNames[BallCtrl.type] );

	pBallPSA->globalscale.vx=512*ballRadius/(4096*19);
	pBallPSA->globalscale.vy=512*ballRadius/(4096*19);
	pBallPSA->globalscale.vz=512*ballRadius/(4096*19);

	ballColl.radius=ballRadius;
	//ballColl.radius*=4096;


	ballVel.vy-=BallBehaviour[BallCtrl.type].gravity;

	AddVector(&ballPos, &ballPos, &ballVel);
	ballPos.vy-=(ballVel.vy*2);

	TIMER_START(TIMER_COLLISION);
	//collboxCheckSphere(&ballColl);

	ballColl.dbug=0;
	if ( collboxCheckSphere(&ballColl) ) 
	{
		ActorStartRoll(pBallPSA,ballVel.vx,ballVel.vz);
	}
	TIMER_STOP(TIMER_COLLISION);


	GetQuaternionFromRotation(&tempQ,&pBallPSA->world.qRotVel);
	QuaternionMultiply(&pBallPSA->world.qRot,&pBallPSA->world.qRot,&tempQ);


	GetQuaternionFromRotation(&tempQ,&pBallPSA->world.qRotLightVel);
	QuaternionMultiply(&pBallPSA->world.qRotLight,&pBallPSA->world.qRotLight,&tempQ);
	//QuaternionMultiply(&pBallPSA->world.qRotLight,&tempQ,&pBallPSA->world.qRotLight);

	pBallPSA->world.rotatekeys->vect.x=pBallPSA->world.qRot.x;
	pBallPSA->world.rotatekeys->vect.y=pBallPSA->world.qRot.y;
	pBallPSA->world.rotatekeys->vect.z=pBallPSA->world.qRot.z;
	pBallPSA->world.rotatekeys->vect.w=pBallPSA->world.qRot.w;
	
	// keep ball speeds below certain amount
	if (ballVel.vx>BallBehaviour[BallCtrl.type].maxSpeed) ballVel.vx=BallBehaviour[BallCtrl.type].maxSpeed;
	if (ballVel.vy>BallBehaviour[BallCtrl.type].maxSpeed) ballVel.vy=BallBehaviour[BallCtrl.type].maxSpeed;
	if (ballVel.vz>BallBehaviour[BallCtrl.type].maxSpeed) ballVel.vz=BallBehaviour[BallCtrl.type].maxSpeed;

	if (ballVel.vx<-BallBehaviour[BallCtrl.type].maxSpeed) ballVel.vx=-BallBehaviour[BallCtrl.type].maxSpeed;
	if (ballVel.vy<-BallBehaviour[BallCtrl.type].maxSpeed) ballVel.vy=-BallBehaviour[BallCtrl.type].maxSpeed;	
	if (ballVel.vz<-BallBehaviour[BallCtrl.type].maxSpeed) ballVel.vz=-BallBehaviour[BallCtrl.type].maxSpeed;
	// do drag factor
	ballVel.vx=(BallBehaviour[BallCtrl.type].drag*ballVel.vx)/4096;
	//ballVel.vy=(BallBehaviour[BallCtrl.type].drag*ballVel.vy)/4096; // not sure if drag applyed on y
	ballVel.vz=(BallBehaviour[BallCtrl.type].drag*ballVel.vz)/4096;


	if (PRINTMESS) textPrintf("BallPos=%d,%d,%d\n", ballPos.vx, ballPos.vy, ballPos.vz);
	//textPrintf("BallVel=%d,%d,%d\n", ballVel.vx, ballVel.vy, ballVel.vz);
	if (PRINTMESS) textPrintf("BallVel=X %d\n", ballVel.vx);
	if (PRINTMESS) textPrintf("BallVel=Y %d\n", ballVel.vy);
	if (PRINTMESS) textPrintf("BallVel=Z %d\n", ballVel.vz);

	if (PRINTMESS) textPrintf("Ball  Height= %d\n",getHeightAt(ballPos.vx, ballPos.vy, ballPos.vz) );
	if (PRINTMESS) textPrintf("Glove Height= %d\n",getHeightAt(glovePos.vx, glovePos.vy, glovePos.vz) );
	if (PRINTMESS) textPrintf("Camera angle= %d\n",CamVars.angle);
	if (PRINTMESS) textPrintf("Glove angle = %d\n",GloveCtrl.direction);

	pBallPSA->position.vx=ballPos.vx/4096;
	pBallPSA->position.vy=ballPos.vy/4096;
	pBallPSA->position.vz=ballPos.vz/4096;

	if (BallCtrl.hurt)
	{
		pPlasterPSA->world.rotatekeys->vect.x=pBallPSA->world.qRot.x;
		pPlasterPSA->world.rotatekeys->vect.y=pBallPSA->world.qRot.y;
		pPlasterPSA->world.rotatekeys->vect.z=pBallPSA->world.qRot.z;
		pPlasterPSA->world.rotatekeys->vect.w=pBallPSA->world.qRot.w;

		pPlasterPSA->globalscale.vx=pBallPSA->globalscale.vx;
		pPlasterPSA->globalscale.vy=pBallPSA->globalscale.vy;
		pPlasterPSA->globalscale.vz=pBallPSA->globalscale.vz;

		pPlasterPSA->position.vx=pBallPSA->position.vx;
		pPlasterPSA->position.vy=pBallPSA->position.vy;
		pPlasterPSA->position.vz=pBallPSA->position.vz;

		pPlasterPSA->world.qRotLight.x=pBallPSA->world.qRotLight.x;
		pPlasterPSA->world.qRotLight.y=pBallPSA->world.qRotLight.y;
		pPlasterPSA->world.qRotLight.z=pBallPSA->world.qRotLight.z;
		pPlasterPSA->world.qRotLight.w=pBallPSA->world.qRotLight.w;
	}


	UpdateCamera();

	if (pad[0]&PAD_START) 
	{
//		textPrintf("box0 =X %d\n", (collBox+0)->pX);
//		textPrintf("box0 =Y %d\n", (collBox+0)->pY);
//		textPrintf("box0 =Z %d\n", (collBox+0)->pZ);

		for (loop=0;loop<numCollBoxes;loop++)
		{
			collboxShowWire( (collBox+loop) );
		}
	}
/*	mapx=0;
	mapy=0;
	mapz=0;
	if(pad[1]&PAD_LEFT)			mapx=4096;
	else if(pad[1]&PAD_RIGHT) 	mapx=-4096;
	if(pad[1]&PAD_DOWN)			mapz=4096;
	else if(pad[1]&PAD_UP)		mapz=-4096;
	if(pad[1]&PAD_CROSS)		mapy=4096;
	else if(pad[1]&PAD_TRIANGLE)mapy=-4096;
	if ( mapx!=0 || mapy!=0 || mapz!=0)
	{
		for (loop=0;loop<numCollBoxes;loop++)
		{
			(collBox+loop)->pX+=mapx;
			(collBox+loop)->pY+=mapy;
			(collBox+loop)->pZ+=mapz;
		}
	}
*/

	
	TIMER_START(TIMER_LSCAPE);
	lscapeDrawAll(pWld);
	TIMER_STOP(TIMER_LSCAPE);

	if (BallCtrl.hurt)
	{
		objectSetAnimation(pPlasterPSA, 0);
		objectDraw/*CheckWater*/(pPlasterPSA);
	}

	TIMER_START(TIMER_BALLGLOVE);
	objectSetAnimation(pBallPSA, 0);
	objectDraw/*CheckWater*/(pBallPSA);
	TIMER_STOP(TIMER_BALLGLOVE);




	Control_Glove();


}
GLOVERSEG	gloveData[5]=
{
	112,200,
	66,81,
	85,94,
	95,112,
	201,208
};
//#define TOPSPEED 256

#define	NONE	0
#define	LEFT	1
#define	RIGHT	2
#define	UP		4
#define	DOWN	8

/********************************************************************************/
void	Control_Glove(){

	ULONG	ConState;
	ULONG	flag=FALSE;
	LONG	targetAngle,temp;

	if (CamVars.targetmodel==pGlovePSA)
	{
		if (GloveCtrl.animState==JUMP) flag=TRUE;
		ConState=NONE;
		
		if(pad[0]&PAD_LEFT)			ConState=LEFT;
		else if(pad[0]&PAD_RIGHT)	ConState=RIGHT;
		if(pad[0]&PAD_UP)			ConState|=UP;
		else if(pad[0]&PAD_DOWN )	ConState|=DOWN;


		if(pad[0]&PAD_CROSS)
			if (getHeightAt(glovePos.vx,glovePos.vy,glovePos.vz) < (gloveColl.radius+(gloveColl.radius/4)) && getHeightAt(glovePos.vx,glovePos.vy,glovePos.vz)!=-1)
			{
				gloveVel.vy+=GRAVITY*12;
				SFXPlay3D(globalFX, SFX_GLOVEJUMP,64, &glovePos, DEFAULTPITCH, 200);
			}
	}
	if (ConState!=NONE && GloveCtrl.speed<TOPSPEED) GloveCtrl.speed+=16;
	else if (ConState==NONE && GloveCtrl.speed>0)		GloveCtrl.speed-=16;
	
	// now need to get correct angle for glover based on direction and camera angle
	if (ConState&UP) targetAngle=CamVars.angle;
	if (ConState&DOWN) targetAngle=(CamVars.angle+2048)&4095;
	if (ConState&LEFT) targetAngle=(CamVars.angle-1024)&4095;
	if (ConState&RIGHT) targetAngle=(CamVars.angle+1024)&4095;


	GloveCtrl.direction&=4095;

	if (ConState!=NONE) 
	{
		temp = findShortestAngle(GloveCtrl.direction,targetAngle);
		GloveCtrl.direction = GloveCtrl.direction-(temp/8);
	}


	gloveVel.vz=/*glovePos.vz*/-(rcos(GloveCtrl.direction)*GloveCtrl.speed)/16;
	gloveVel.vx=/*glovePos.vx*/-(rsin(GloveCtrl.direction)*GloveCtrl.speed)/16;

	pGlovePSA->world.rotate.vy=GloveCtrl.direction;

	GloveCtrl.animCount++;

	if (GloveCtrl.animCount>=GloveCtrl.animSpeed)
	{
		GloveCtrl.animFrame++;
		GloveCtrl.animCount=0;
	}

	if (GloveCtrl.speed==0) 
	{
		GloveCtrl.animState=IDLE;
		GloveCtrl.animSpeed=1;
	}
	else if (GloveCtrl.speed>0 && GloveCtrl.speed<TOPSPEED/2) 
	{
		GloveCtrl.animState=WALK;
		GloveCtrl.animSpeed=((TOPSPEED/GloveCtrl.speed)/4);
	}
	else 
	{
		GloveCtrl.animState=RUN;
		GloveCtrl.animSpeed=((TOPSPEED/GloveCtrl.speed)/4);
	}

	if (GloveCtrl.oldSpeed>GloveCtrl.speed) GloveCtrl.animState=SLIDE;

	if (getHeightAt(glovePos.vx,glovePos.vy,glovePos.vz) > (gloveColl.radius+(gloveColl.radius/4)) || getHeightAt(glovePos.vx,glovePos.vy,glovePos.vz)==-1)
	{
		GloveCtrl.animState=JUMP;
		
		//PlaySFX(glovesfxvab,SFX_GLOVEJUMP,64,DEFAULTPITCH);
		
		GloveCtrl.animSpeed=0;//((TOPSPEED/GloveCtrl.speed)/4);
	}

	if (flag==TRUE && GloveCtrl.animState!=JUMP) PlaySFX(glovesfxvab,SFX_GLOVELAND,64,DEFAULTPITCH);

	if (GloveCtrl.animFrame<gloveData[GloveCtrl.animState].start)
		GloveCtrl.animFrame=gloveData[GloveCtrl.animState].start;


	GloveCtrl.oldSpeed=GloveCtrl.speed;

	if (GloveCtrl.animFrame>=gloveData[GloveCtrl.animState].end && GloveCtrl.animState!=JUMP) GloveCtrl.animFrame=gloveData[GloveCtrl.animState].start;
	else if (GloveCtrl.animFrame>=gloveData[GloveCtrl.animState].end) GloveCtrl.animFrame=gloveData[GloveCtrl.animState].end-2;
	//now do collision
	// must sort this out

	gloveVel.vy-=GRAVITY;
	AddVector(&glovePos, &glovePos, &gloveVel);
	glovePos.vy-=(gloveVel.vy*2);

	//BallCtrl.bounce=000;

	TIMER_START(TIMER_COLLISION);
	gloveColl.dbug=1;
	collboxCheckSphere(&gloveColl);
	TIMER_STOP(TIMER_COLLISION);

	//BallCtrl.bounce=4000;
	//print glove
	pGlovePSA->position.vx=glovePos.vx/4096;
	pGlovePSA->position.vy=glovePos.vy/4096;
	pGlovePSA->position.vz=glovePos.vz/4096;

	
	objectSetAnimation(pGlovePSA, GloveCtrl.animFrame);

	if (CamVars.mode==ZOOM) modelctrl.semitrans=2;
	objectSegmentSort(pGlovePSA);
 	//objectDrawCheckWater(pGlovePSA);
	objectDraw(pGlovePSA);
	if (CamVars.mode==ZOOM) modelctrl.semitrans=0;

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

// This is the N64 routine to roll the ball
// Note any commented out stuff was by me
// Converting to fixed format going to be a laught!

//void ActorStartRoll(ACTOR *actor,float x,float z)

void ActorStartRoll(NEWMODEL *actor,LONG x,LONG z) // will have to put quat stuff back in for models
{
	LONG	speed,factor,dp;
	VECTOR	tempVect,tempVect2;
	int		j;
	IQUATERNION tempQ,tempQ2,tempQ3;




	tempVect.vx=x;
	tempVect.vy=0;
	tempVect.vz=z;
	speed = Magnitude(&tempVect);



	//actor->world.qRotVel.w = speed/actor->maxRadius;

	actor->world.qRotVel.w = (speed*700)/ballColl.radius;
	if(speed)
	{
		actor->world.qRotVel.x = (z*4096)/speed;
		actor->world.qRotVel.z = -(x*4096)/speed;
		actor->world.qRotVel.y = 0;

	}
	else
	{
		actor->world.qRotVel.x = 0;
		actor->world.qRotVel.z = 0;
		actor->world.qRotVel.y = 0;
		actor->world.qRotVel.w = 4096;
	}

	speed=-speed;
	actor->world.qRotLightVel.w = ((speed*700)/ballColl.radius);
	if(speed)
	{
		actor->world.qRotLightVel.x = -(z*4096)/speed;	//-
		actor->world.qRotLightVel.z = 0;//(x*4096)/speed;	//+
		actor->world.qRotLightVel.y = -(x*4096)/speed;
	}
	else
	{
		actor->world.qRotLightVel.x = 0;
		actor->world.qRotLightVel.z = 0;
		actor->world.qRotLightVel.y = 0;
		actor->world.qRotLightVel.w = 4096;
	}
}







void ChangeBall(NEWOBJECT *world ,SPRITE *spr)
{
	long		loop;
	long		numVerts;
	long		primLeft;
	VERT		*vertTop;
	NORM		*normTop;
	TMD_P_TG4A	*op;
	TMD_P_TG4A	*opTG4;
	TMD_P_TG3A	*opTG3;
	TMD_P_F4G	*opG4;
	TMD_P_F3G	*opG3;


	unsigned char	*primPtr;
	int			*sortPtr;
//	VECTOR		vec1,vec2,vec3;
	long		xdiff,ydiff;
	
		
	sortPtr = world->meshdata->sorttable[0];
	primLeft = world->meshdata->sorttablesize[0];
	vertTop = world->meshdata->vertop;
	primPtr = (unsigned char*)world->meshdata->primtop;
	numVerts = world->meshdata->vern;
	normTop = world->meshdata->nortop;

	//printf("\nsegment %s",world->meshdata->name);
	//printf("\n%d verts",numVerts);
	//printf("\n%d polys",primLeft);


	op = (TMD_P_TG4A*)(primPtr);
	switch(op->cd & (0xff-2))
	{
		case GPU_COM_TG4:

			//op->spr=testTex1;

			xdiff=op->spr->x;
			ydiff=op->spr->y;

			xdiff-=spr->x;
			ydiff-=spr->y;

			break;

		case GPU_COM_TG3:
			//printf("\nfound a TG3");
			opTG3 = (TMD_P_TG3A*)op;

			xdiff=opTG3->spr->x;
			ydiff=opTG3->spr->y;

			xdiff-=spr->x;
			ydiff-=spr->y;

			opTG3->clut=spr->clut;
			opTG3->tpage=spr->tpage;
			opTG3->spr=spr;

			break;
	}

	
	while(primLeft)
	{
		op = (TMD_P_TG4A*)(primPtr);
		switch(op->cd & (0xff-2))
		{
			case GPU_COM_TG4:

				op->clut=spr->clut;
				op->tpage=spr->tpage;
				op->spr=spr;

				op->tu0-=xdiff;
				op->tv0-=ydiff;

				op->tu1-=xdiff;
				op->tv1-=ydiff;

				op->tu2-=xdiff;
				op->tv2-=ydiff;

				op->tu3-=xdiff;
				op->tv3-=ydiff;

				primPtr += sizeof(TMD_P_TG4A);
				break;

			case GPU_COM_TF4:
				printf("\nunsupported poly type TF4");
				primPtr += sizeof(TMD_P_TF4A);
				break;

			case GPU_COM_G4:
				opG4 = (TMD_P_F4G *)op;
				//printf("\nfound a G4");
				primPtr += sizeof(TMD_P_F4G);
				break;
			case GPU_COM_F4:
				printf("\nunsupported poly type F4");
				break;

			case GPU_COM_TG3:
				//printf("\nfound a TG3");
				opTG3 = (TMD_P_TG3A*)op;

				opTG3->clut=spr->clut;
				opTG3->tpage=spr->tpage;
				opTG3->spr=spr;

				opTG3->tu0-=xdiff;
				opTG3->tv0-=ydiff;

				opTG3->tu1-=xdiff;
				opTG3->tv1-=ydiff;

				opTG3->tu2-=xdiff;
				opTG3->tv2-=ydiff;

				primPtr += sizeof(TMD_P_TG3A);
				break;

			case GPU_COM_TF3:
				printf("\nunsupported poly type TF3");
				primPtr += sizeof(TMD_P_TF3A);
				break;

			case GPU_COM_G3:
				//printf("\nfound a G3");
				
				primPtr += sizeof(TMD_P_F3G);
				break;

			case GPU_COM_F3:
				printf("\nunsupported poly type F3");
				break;

			default:

				printf("\nfound something nasty!");
				break;
		}
		primLeft--;
	}
}









/////////////////////////////////////////////////////////////////////////////////////////////
void	Control_Gloveold(){

	ULONG	ConState;
	ULONG	flag=FALSE;
	LONG	targetAngle,temp;
//bodged coords for glove next to ball
   //	glovePos.vx=ballPos.vx+(50*4096);
  //	glovePos.vy=ballPos.vy;
  //	glovePos.vz=ballPos.vz;


//		camangle=camvars->angle; 						// map 'drawing' angle
//		turn=(camangle+2048) &4095;				// +180 degrees


	//if (CamVars.mode==CAM_GLOVE)
	//{
	if (CamVars.targetmodel==pGlovePSA)
	{
		if (GloveCtrl.animState==JUMP) flag=TRUE;
//		if(pad[0]&PAD_LEFT)			GloveCtrl.direction-=64;
//		else if(pad[0]&PAD_RIGHT) 	GloveCtrl.direction+=64;

//		if(pad[0]&PAD_UP && GloveCtrl.speed<TOPSPEED)		GloveCtrl.speed+=16;
//		else if(pad[0]&PAD_DOWN && GloveCtrl.speed>0)		GloveCtrl.speed-=16;
		ConState=NONE;
		
		if(pad[0]&PAD_LEFT)			ConState=LEFT;
		else if(pad[0]&PAD_RIGHT)	ConState=RIGHT;
		if(pad[0]&PAD_UP)			ConState|=UP;
		else if(pad[0]&PAD_DOWN )	ConState|=DOWN;


		if(pad[0]&PAD_CROSS)
			if (getHeightAt(glovePos.vx,glovePos.vy,glovePos.vz) < (gloveColl.radius+(gloveColl.radius/4)) && getHeightAt(glovePos.vx,glovePos.vy,glovePos.vz)!=-1)
			{
				gloveVel.vy+=GRAVITY*12;
				SFXPlay3D(globalFX,SFX_GLOVEJUMP,64,&glovePos,DEFAULTPITCH,200);
			}
	}
	if (ConState!=NONE && GloveCtrl.speed<TOPSPEED) GloveCtrl.speed+=16;
	else if (ConState==NONE && GloveCtrl.speed>0)		GloveCtrl.speed-=16;
	
	// now need to get correct angle for glover based on direction and camera angle
	if (ConState&UP) targetAngle=CamVars.angle;
	if (ConState&DOWN) targetAngle=(CamVars.angle+2048)&4095;
	if (ConState&LEFT) targetAngle=(CamVars.angle-1024)&4095;
	if (ConState&RIGHT) targetAngle=(CamVars.angle+1024)&4095;


	GloveCtrl.direction&=4095;

	if (ConState!=NONE) 
	{
		temp = findShortestAngle(GloveCtrl.direction,targetAngle);
		GloveCtrl.direction = GloveCtrl.direction-(temp/8);
	}
	

	gloveVel.vz=/*glovePos.vz*/-(rcos(GloveCtrl.direction)*GloveCtrl.speed)/16;
	gloveVel.vx=/*glovePos.vx*/-(rsin(GloveCtrl.direction)*GloveCtrl.speed)/16;

	pGlovePSA->world.rotate.vy=GloveCtrl.direction;

	GloveCtrl.animCount++;

	if (GloveCtrl.animCount>=GloveCtrl.animSpeed)
	{
		GloveCtrl.animFrame++;
		GloveCtrl.animCount=0;
	}

	if (GloveCtrl.speed==0) 
	{
		GloveCtrl.animState=IDLE;
		GloveCtrl.animSpeed=1;
	}
	else if (GloveCtrl.speed>0 && GloveCtrl.speed<TOPSPEED/2) 
	{
		GloveCtrl.animState=WALK;
		GloveCtrl.animSpeed=((TOPSPEED/GloveCtrl.speed)/4);
	}
	else 
	{
		GloveCtrl.animState=RUN;
		GloveCtrl.animSpeed=((TOPSPEED/GloveCtrl.speed)/4);
	}

	if (GloveCtrl.oldSpeed>GloveCtrl.speed) GloveCtrl.animState=SLIDE;

	if (getHeightAt(glovePos.vx,glovePos.vy,glovePos.vz) > (gloveColl.radius+(gloveColl.radius/4)) || getHeightAt(glovePos.vx,glovePos.vy,glovePos.vz)==-1)
	{
		GloveCtrl.animState=JUMP;
		
		//PlaySFX(glovesfxvab,SFX_GLOVEJUMP,64,DEFAULTPITCH);
		
		GloveCtrl.animSpeed=0;//((TOPSPEED/GloveCtrl.speed)/4);
	}

	if (flag==TRUE && GloveCtrl.animState!=JUMP) SFXPlay(glovesfxvab,SFX_GLOVELAND,64,DEFAULTPITCH);

	if (GloveCtrl.animFrame<gloveData[GloveCtrl.animState].start)
		GloveCtrl.animFrame=gloveData[GloveCtrl.animState].start;


	GloveCtrl.oldSpeed=GloveCtrl.speed;

	if (GloveCtrl.animFrame>=gloveData[GloveCtrl.animState].end && GloveCtrl.animState!=JUMP) GloveCtrl.animFrame=gloveData[GloveCtrl.animState].start;
	else if (GloveCtrl.animFrame>=gloveData[GloveCtrl.animState].end) GloveCtrl.animFrame=gloveData[GloveCtrl.animState].end-2;
	//now do collision
	// must sort this out

	gloveVel.vy-=GRAVITY;
	AddVector(&glovePos, &glovePos, &gloveVel);
	glovePos.vy-=(gloveVel.vy*2);

	//BallCtrl.bounce=000;

	TIMER_START(TIMER_COLLISION);
	gloveColl.dbug=1;
	collboxCheckSphere(&gloveColl);
	TIMER_STOP(TIMER_COLLISION);

	//BallCtrl.bounce=4000;
	//print glove
	pGlovePSA->position.vx=glovePos.vx/4096;
	pGlovePSA->position.vy=glovePos.vy/4096;
	pGlovePSA->position.vz=glovePos.vz/4096;

	
	objectSetAnimation(pGlovePSA, GloveCtrl.animFrame);

	if (CamVars.mode==ZOOM) modelctrl.semitrans=2;
	objectSegmentSort(pGlovePSA);
 	//objectDrawCheckWater(pGlovePSA);
	objectDraw(pGlovePSA);
	if (CamVars.mode==ZOOM) modelctrl.semitrans=0;

}
