#include "glover.h"
//#include "bff_load.h"
//#include "water.h"
//#include "libapi.h"	// criticalsection

PSAWORLD *pWld;

//NEWMODEL *plionfishPSA;
//NEWMODEL *pmalletPSA;
//NEWMODEL *psharkyPSA;

//gameCtrl.dropOutFlag==FALSE
NEWMODEL *pSky;

VECTOR	BallStartPos;	// These are tempory for demo
VECTOR	GloveStartPos;

int		gameScore;
char	maxHealth;
GAMESTATE GameState;

SPRITEX	*cardTex[8];	// Used for Carnival bonus only

// overlays are now in generic. nmes are now in the level
//TextureBankType *pOvlBank,*pWldBank,*pNMEBank;
TextureBankType *pWldBank;
BFF_Header *Level_BFF = NULL;

UBYTE showGameOver=0;
long	gameoverY1,gameoverY2;
extern objectSegDataType  	*GloveSeg;

void pauseBegin();
void renderWorld(void);

#ifdef TWOLEVEL_DEMO
	#define NUM_DEMOVERLAYS 3
	OVERLAY demOvl[NUM_DEMOVERLAYS];
	OVERLAY prog, hasfrnt;
#endif

ULONG frmCols[]={0x007f00, 0x007f00, 0x00007f00, 0x00007f00, 0x00004f7f, 0x0000007f};


// =========================================================================



// Data for time trial stuff (move to menu when possable)
TIMETRIALDATA	timeTrialData[] =
{
	{NULL,NULL,"",NULL},		// testmesh no time trials for hubs
	{NULL,NULL,"",NULL},		// hub1
	{NULL,NULL,"",NULL},		// hub2
	{NULL,NULL,"",NULL},		// hub3
	{NULL,NULL,"",NULL},		// hub4
	{NULL,NULL,"",NULL},		// hub5
	{NULL,NULL,"",NULL},		// hub6
	{NULL,NULL,"",NULL},		// hub7
	{NULL,NULL,"",NULL},		// cave
	{NULL,NULL,"",NULL},		// assult course
	{(3*60),(3*60),"CW",YES},		// at1
	{(3*60),(3*60),"CW",NO},		// at2
	{(3*60),(3*60),"CW",NO},		// at3
	{NULL,NULL,"",NULL},		// atboss
	{(191),(191),"CW",YES},		// atbonus
	{(3*60),(3*60),"FW",NO},		// carn1
	{(3*60),(3*60),"FW",NO},		// carn2
	{(3*60),(3*60),"FW",NO},		// carn3
	{NULL,NULL,"",NULL},		// carnboss
	{(3*60),(3*60),"FW",YES},		// carnbonus
	{(3*60),(3*60),"MBC",YES},		// pir1
	{(3*60),(3*60),"MBC",YES},		// pir2
	{(3*60),(3*60),"MBC",YES},		// pir3
	{NULL,NULL,"",NULL},		// pirboss
	{(3*60),(3*60),"MBC",YES},		// pirbonus
	{(3*60),(3*60),"TIM",YES},		// pre1
	{(3*60),(3*60),"TIM",NO},		// pre2
	{(3*60),(3*60),"TIM",NO},		// pre3
	{NULL,NULL,"",NULL},		// preboss
	{(3*60),(3*60),"TIM",YES},		// prebonus
	{(3*60),(3*60),"MB",YES},		// ff1
	{(3*60),(3*60),"MB",YES},		// ff2
	{(3*60),(3*60),"MB",NO},		// ff3
	{NULL,NULL,"",NULL},		// ffboss
	{(3*60),(3*60),"MB",YES},		// ffbonus
	{(3*60),(3*60),"TOM",NO},		// space2a
	{(3*60),(3*60),"TOM",NO},		// space2b
	{(3*60),(3*60),"TOM",NO},		// space3
	{NULL,NULL,"",NULL},		// spaceboss1
	{NULL,NULL,"",NULL},		// spaceboss2
	{(3*60),(3*60),"TOM",NO},		// spacebonus
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
	{NULL,NULL,"",NULL},		//	test levels
};

// Note - "nextlevel" is defined as "HUB8" or "WAYROOM" where it should be a lookup-hub
// and many levels need to be special-cased


LEVELINFO LevelInfo[] =
{
//	Note - Needs to match the level numbers in MENU.H
//   Music track,	Next Level,			world			    level id

	{TRACK_HUB7,	TITLE,				HUB				},	// TESTMESH,
	{TRACK_HUB7,	HUB1,				HUB				},	// HUB1,		//0	
	{TRACK_HUB7,	HUB1,				HUB				},	// HUB2,		//1 
	{TRACK_HUB7,	HUB1,				HUB				},	// HUB3,		//2 
	{TRACK_HUB7,	HUB1,				HUB				},	// HUB4,		//3 
	{TRACK_HUB7,	HUB1,				HUB				},	// HUB5,		//4 
	{TRACK_HUB7,	HUB1,				HUB				},	// HUB6,		//5 
	{TRACK_HUB7,	HUB1,				HUB				},	// HUB7,		//6 
	{TRACK_HUB8,	HUB1,				HUB				},	// HUB8,		//7  

	{TRACK_XTRA1,	HUB1,				HUB				},	// CAVE,		//8
	{TRACK_HUB7,	TITLE,				HUB				},	// ACOURSE,	//9

	{TRACK_AT1,		ATLANTIS2,			ATLANTIS		},	// ATLANTIS1,//10 
	{TRACK_AT2,		ATLANTIS3,			ATLANTIS		},	// ATLANTIS2,//11
	{TRACK_AT3,		ATLANTISBOSS,		ATLANTIS		},	// ATLANTIS3,//12
	{TRACK_ATBOSS,	HUB8,				ATLANTIS		},	// ATLANTISBOSS,	//13
	{TRACK_ATBOSS,	WAYROOM,			ATLANTIS		},	// ATLANTISBONUS,//14

	{TRACK_CA1,		CARNIVAL2,			CARNIVAL		},	// CARNIVAL1, 	//15
	{TRACK_CA2,		CARNIVAL3,			CARNIVAL		},	// CARNIVAL2,	//16
	{TRACK_CA3,		CARNIVALBOSS,		CARNIVAL		},	// CARNIVAL3,	//17
	{TRACK_CABOSS,	HUB8,				CARNIVAL		},	// CARNIVALBOSS,	//18
	{TRACK_CABONUS,	WAYROOM,			CARNIVAL		},	// CARNIVALBONUS,//19

	{TRACK_PI1,		PIRATES2,			PIRATES			},	// PIRATES1,	  	//20
	{TRACK_PI2,		PIRATES3,			PIRATES			},	// PIRATES2,  	//21
	{TRACK_PI3,		PIRATESBOSS,		PIRATES			},	// PIRATES3,  	//22
	{TRACK_PIBOSS,	HUB8,				PIRATES			},	// PIRATESBOSS,	//23
	{TRACK_PIBOSS,	WAYROOM,			PIRATES			},	// PIRATESBONUS,	//24

	{TRACK_PR1,		PREHISTORIC2,		PREHISTORIC		},	// PREHISTORIC1, //25
	{TRACK_PR2,		PREHISTORIC3,		PREHISTORIC		},	// PREHISTORIC2, //26
	{TRACK_PR3,		PREHISTORICBOSS,	PREHISTORIC		},	// PREHISTORIC3, //27
	{TRACK_PRBOSS,	HUB8,				PREHISTORIC		},	// PREHISTORICBOSS,	//28
	{TRACK_PRBOSS,	WAYROOM,			PREHISTORIC		},	// PREHISTORICBONUS,	//29

	{TRACK_FF1,		FEAR2,				FORTRESS		},	// FEAR1,  		//30
	{TRACK_FF2,		FEAR3,				FORTRESS		},	// FEAR2,  		//31
	{TRACK_FF3,		FEARBOSS,			FORTRESS		},	// FEAR3, 		//32
	{TRACK_FFBOSS,	HUB8,				FORTRESS		},	// FEARBOSS, 	//33
	{TRACK_FFBOSS,	WAYROOM,			FORTRESS		},	// FEARBONUS,	//34

	{TRACK_SP1,		SPACE2B,			SPACE			},	// SPACE2A,		//35
	{TRACK_SP2,		SPACE3,				SPACE			},	// SPACE2B,		//36
	{TRACK_SP3,		SPACEBOSS2,			SPACE			},	// SPACE3,		//37
	{TRACK_SPBOSS,	TITLE,				SPACE			},	// SPACEBOSS1, 	//38
	{TRACK_SPBOSS,	HUB8,				SPACE			},	// SPACEBOSS2, 	//39
	{TRACK_SPBOSS,	WAYROOM,			SPACE			},	// SPACEBONUS, 	//40

	{TRACK_XTRA2,	HUB1,				HUB				},	// WAYROOM,	  	//41
	{TRACK_XTRA3,	HUB1,				HUB				},	// WAYROOM2,  	//41
	{TRACK_XTRA4,	HUB1,				HUB				},	// WAYROOM3,  	//41
	{TRACK_XTRA5,	HUB1,				HUB				},	// WAYROOM4,  	//41
	{TRACK_XTRA1,	HUB1,				HUB				},	// WAYROOM5,  	//41

	{TRACK_HUB7,	TITLE,				ATLANTIS		},	// ATTEST,
	{TRACK_HUB7,	TITLE,				CARNIVAL		},	// CATEST,
	{TRACK_HUB7,	TITLE,				PIRATES			},	// PITEST,
	{TRACK_HUB7,	TITLE,				PREHISTORIC		},	// PREHISTORICTEST,
	{TRACK_HUB7,	TITLE,				FORTRESS		},	// FEARTEST,
	{TRACK_HUB7,	TITLE,				SPACE			},	// SPACETEST,
	{TRACK_HUB7,	TITLE,				HUB				},	// INTRO,	  	//42
};

// =========================================================================












void showFrameRate(int frm) // frame rate and other dev stuff
{
	int col=frm;
	static SPRITEX *pCamCase=NULL;

	if(col>5)
		col=5;

	*(ULONG *)&(sprctrl.r)=frmCols[col];
	sprctrl.scalex=4096;
	sprctrl.scaley=4096;
	if(frm<10)
		spritePrint(fontList[0]+(0x10+frm), -140,100,0);
	else
		spritePrint(fontList[0]+('!'-0x20), -140,100,0);

	if(CamVars.flags)
	{
		if(!pCamCase)
		{
//			DB("Finding tex ...\n");
			pCamCase=textureFindInAllBanks("CAMCASE");
		}
//		DB("Printing %p\n", pCamCase);

		SETRGBC(sprctrl.r,128,128,128,0);
		sprctrl.scalex=5192;
		sprctrl.scaley=4096;
		spritePrint(pCamCase, -96,100,0);
	}
}


GAME_CTRL	gameCtrl;

void gameInitGameStuff(void)
{
	GsF_LIGHT light;

	frame = 0;
	activeframe = 0;

// Fred being paranoid about recordkey demos
	FMEMZERO(&GloveCtrl,sizeof(GloveCtrl));
	FMEMZERO(&BallCtrl,sizeof(BallCtrl));
	FMEMZERO(&gloveColl,sizeof(gloveColl));
	FMEMZERO(&ballColl,sizeof(ballColl));
	FMEMZERO(&CamVars,sizeof(CamVars));
	FMEMZERO(&InputState,sizeof(InputState));
	FMEMZERO(&BallChange,sizeof(BallChange));
	FMEMZERO(&ballOldPos,sizeof(ballOldPos));
	FMEMZERO(&pHitData[0],16*sizeof(HITDATA));
	FMEMZERO(&GloveVel,sizeof(GloveVel));
	FMEMZERO(&JoinGlovePos,sizeof(JoinGlovePos));
	FMEMZERO(&JoinBallPos,sizeof(JoinBallPos));
	ballRadius=(19*4096*NORMAL_SCALE)*1;
	ballStartRadius=ballEndRadius=spinSpeed = 0;
	enemy_has_ball = 0;
	handpower_duration = 0;
	handpower_timer = 0;
	handpower_type = 0;
	FMEMZERO(&handFrontProbe,sizeof(handFrontProbe));
	FMEMZERO(&handFrontProbePos,sizeof(handFrontProbePos));

	FMEMZERO(&BodgeCtrl,sizeof(BodgeCtrl));
// Same lines as at the end of a spell cast
	BallBehaviour[0].radius=(19*4096*NORMAL_SCALE)*1;
	BallBehaviour[1].radius=1*(19*4096*NORMAL_SCALE)*1.4;
	BallBehaviour[2].radius=(19*4096*NORMAL_SCALE)*0.6;
	BallBehaviour[3].radius=(19*4096*NORMAL_SCALE)*0.6;
	BallBehaviour[4].radius=(19*4096*NORMAL_SCALE)*2.5;
	BallBehaviour[5].radius=(19*4096*NORMAL_SCALE)*0.9;
	BallBehaviour[6].radius=(19*4096*NORMAL_SCALE)*1;

// Bingo bongo! This is the baby that wes screwing the recordkey demos once you'd skidded
	GloveBehaviour.accel=4096*8;


// TBD - this should be in menu, and should init the gamestate either this way, or from a memory card load
/*
	if(gameCtrl.previousLevel == TITLE)
	{
		FMEMZERO(&GameState,sizeof(GAMESTATE));
		GameState.version = 0;
		GameState.lives = 3;
		GameState.health = 3;
		GameState.maxhealth = 3;
		GameState.version = GAMESTATE_VERSION;
		gameCtrl.hub_to_use = 1;
	}
*/
	Effects_LevelStart();
/*
	pRipplePSA=LoadPSA("WORLDS\\GENERIC\\NME\\RIPPLE.PSA");
	objectSetupSegmentSort(pRipplePSA);
	pRipplePSA->globalscale.vx=512;
	pRipplePSA->globalscale.vy=512;
	pRipplePSA->globalscale.vz=512;

	pWakePSA=LoadPSA("WORLDS\\GENERIC\\NME\\WAKE.PSA");
	objectSetupSegmentSort(pWakePSA);
	pWakePSA->globalscale.vx=512;
	pWakePSA->globalscale.vy=512;
	pWakePSA->globalscale.vz=512;
*/
	Load_And_Init_Ball();
	Load_And_Init_Glove();	

	//SinCosTable=(SINCOSTABLE*)fileLoad("SINCOS.DAT",32768);
	//SinCosTable=(SINCOSTABLE*)LoadFileRaw("SINCOS.DAT");
	// Init memory card file system
//	InitCards(); //test stuff for cards

	//plionfishPSA=LoadPSA("WORLDS\\ATLANTIS\\NME\\LIONFISH.PSA");
	//pmalletPSA=LoadPSA("WORLDS\\ATLANTIS\\NME\\MALLET.PSA");
	//psharkyPSA=LoadPSA("WORLDS\\ATLANTIS\\NME\\GENERALW.PSA");


	gameCtrl.fadeIn=0;
	gameCtrl.fadeOut=0;
	gameCtrl.gameActive=TRUE;
	gameCtrl.state=TRUE;
	gameCtrl.select=0;
	gameCtrl.dropOutFlag=GAME_INLEVEL;
	gameCtrl.nextLevel = TITLE;
	gameCtrl.MrTipActive=FALSE;
	gameCtrl.PauseActive=FALSE;
 	light.vx = -2896;
	light.vy = 2896;
	light.vz = 0;
	light.r  = 255>>1;
	light.g  = 255>>1;
	light.b  = 255>>1;

	GsSetFlatLight(0, &light);
 	GsSetAmbient(127*16, 127*16, 127*16); //ONE/2,ONE/2,ONE/2);


#ifdef TWOLEVEL_DEMO
	#if PALMODE==YES
		overlaySetupAndAdd(demOvl+0,	textureFindInAllBanks("ISLLOGO"),	256,32,0, 0);
		overlaySetupAndAdd(&hasfrnt,	textureFindInAllBanks("HASFRNT"),	256,20,0, 0);
		overlaySetupAndAdd(demOvl+1,	textureFindInAllBanks("HASBACK"),	256,32,0, 0);
		overlaySetupAndAdd(demOvl+2,	textureFindInAllBanks("E3"),		256,32,0, 0);
	#else
		overlaySetupAndAdd(demOvl+0,	textureFindInAllBanks("ISLLOGO"),	256,32+2,0, 0);
		overlaySetupAndAdd(&hasfrnt,	textureFindInAllBanks("HASFRNT"),	256,20+24,0, 0);
		overlaySetupAndAdd(demOvl+1,	textureFindInAllBanks("HASBACK"),	256,32+24,0, 0);
		overlaySetupAndAdd(demOvl+2,	textureFindInAllBanks("E3"),		256,32+18,0, 0);
	// ick. No. Redraw.
	//	demOvl[1].scaleY = 3000;
	//	hasfrnt.scaleY = 3000;
	#endif

		demOvl[0].a=0;
		demOvl[1].a=0;
		hasfrnt.a=0;
		demOvl[2].a=0;
		overlaySetupAndAdd(&prog,	textureFindInAllBanks("PROG"),		240,230,0, 0);
#endif
//	overlayssprpointer=textureLoadSPT("GFX\\OVERLAYS.SPT");

		//GloveCtrl.allLevelGaribs = FALSE;

}


void gameReleaseGameStuff()
{
	DB("Releasing game stuff\n");
	overlayClearAll();

	ClearAllText();

	ReleaseLandscapeFile();


//	objectFree(pRipplePSA,NULL);
//	objectFree(pWakePSA,NULL);

// tbd
// These belong in hand.c/ball.c, along with the loads, really
	objectFree(pGlovePSA,NULL);
	objectFree(pRotorPSA,NULL);
	objectFree(pBallPSA,NULL);
	objectFree(pCballPSA,NULL);
	objectFree(pPlasterPSA,NULL);
	objectFree(pPhongPSA,NULL);
	if (level==PREHISTORIC1 || level==PREHISTORIC2)
	{
		objectFree(pBoulderPSA,NULL);
	}



	FREE(GloveSeg);



// sky is now BFF'd
//	if(pSky)
//		objectFree(pSky, NULL);

//	FreeWorld(pWld);	// world is now BFF'd
//	FREE(pWld->pZones);	// I think this one's a bug in FreeWorld?
//	FREE(pWld);	// the menu doesn't do this either... oops?

// Yes, this should be done earlier/differently, but for now, it's necessary
	textureDestroyBank(pWldBank);
	textureUnloadBank(pWldBank);

// Still to do - two files loaded by collide.c
// (level.RAW, level.DAT)
//	releaseCollision();	// coldata is now part of the BFF and doesn't need freeing

// undo stuff for the ADD_TEXT macro

	Free_Tips();

	if(Level_BFF)
	{
		BFF_ReleaseFile(Level_BFF);
		Level_BFF = NULL;
	}

//	SFXShutDown();
	sfxDestroy(1);	// get rid of the level's samples


}



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

#define SP_FADE 15

#ifdef TWOLEVEL_DEMO
void gameDoDemoOverlayBollox(void)
{
	static int thisOverlay=0;
	static int target=255;
	static int timer=0;

	int value=(int)demOvl[thisOverlay].a;

	if(timer<=0)
	{
		if(target>value)
		{
			value+=SP_FADE;
			if(value>=target)
			{	// we're now at our brightest
				value=target;
				target=0;
				timer=100;
			}
		}
		else
		{
			value-=SP_FADE;
			if(value<=target)
			{
				value=target;
				target=255;
				demOvl[thisOverlay].a=(UBYTE)value;
				thisOverlay++;
				if(thisOverlay==NUM_DEMOVERLAYS)
					thisOverlay=0;
			}
		}
	}

	timer--;

	demOvl[thisOverlay].a=(UBYTE)value;
//	if(thisOverlay==1) // stinky pooey bodge that is all Flynn's fault
//		hasfrnt.a=(UBYTE)value;
	hasfrnt.a = demOvl[1].a;	// lesser-spotted version of the bodge that works better :)
}
#endif
int oldGameOverY;
/******************************************************************************************************/
void gameFrame(void)
{

	if (gameInfo.mode!=GAMEMODE_RESTART) gameInfo.mode=GAMEMODE_DEMO;

	
	if(!showGameOver)	
		MenuDrawFade();
	else
	{
		oldGameOverY=gameoverY1;

		gameoverY1=138+abs((rcos(showGameOver*100)/4)/(256-showGameOver));
		gameoverY2=122-abs((rcos(showGameOver*100)/4)/(256-showGameOver));
		

		//if((gameoverY1==141)&&(gameoverY1<=oldGameOverY))
		if((showGameOver==233)||(showGameOver==213)||(showGameOver==196))
			sfxPlay(globalFX,SFX_BALLBOUNCE_RUBBER);


		   
		if(showGameOver>196)
			showGameOver--;
		else
			{
			MenuFadeOut();
			showGameOver=0;
			}
	}
	
	if(showGameOver || (gameCtrl.dropOutFlag==GAME_EXITED))
	{
		SETRGBC(sprctrl.r,128,128,0,0);
		SETRGBC(sprctrl.r1,200,40,8,0);
		sprctrl.scalex=sprctrl.scaley=4096;
		messctrl.font=fontList[0];
		sprctrl.shaded=1;
		sprctrl.center=1;

		messctrl.justify=CENTRETEXT; //new code

#ifdef MULTI_LANGUAGE
		if(gameCtrl.dropOutFlag==GAME_FAILEDBONUS)
		{
			TEXTPRINTAT(256,gameoverY1,fontFindLangString(STR_OUTOFTIME2));
			TEXTPRINTAT(256,gameoverY2,fontFindLangString(STR_OUTOFTIME1));
		}
		else
		{
			TEXTPRINTAT(256,gameoverY1,fontFindLangString(STR_GAMEOVER2));
			TEXTPRINTAT(256,gameoverY2,fontFindLangString(STR_GAMEOVER1));
		}
#else
		if(gameCtrl.dropOutFlag==GAME_FAILEDBONUS)
		{
			TEXTPRINTAT(256,gameoverY1,"TIME\0");
			TEXTPRINTAT(256,gameoverY2,"OUT OF\0");
		}
		else
		{
			TEXTPRINTAT(256,gameoverY1,"OVER\0");
			TEXTPRINTAT(256,gameoverY2,"GAME\0");
		}
#endif
		GloveCtrl.disableTimer=2;
		SETRGBC(sprctrl.r,128,128,128,0);
		SETRGBC(sprctrl.r1,128,128,128,0);
	}
	switch(gameInfo.mode)
	{
	case GAMEMODE_DEMO:
		//atDemoFrame();

//		SFXUpdate3D();

		Update_All_Effects();
		waterUpdate();
 		//Draw_All_Effects();
#ifdef TWOLEVEL_DEMO
		gameDoDemoOverlayBollox();
#endif
		overlayPrintAll();
		ShowHintText();
		ShowText();
	
		//Kill_All_Effects(); //should put at end of level

		// Temp moving platforms stuff
		//pCollBox->cb.oldpX=pCollBox->cb.pX;
		//pCollBox->cb.oldpY=pCollBox->cb.pY;
		//pCollBox->cb.oldpZ=pCollBox->cb.pZ;

		//collboxMoveDynamicBox(pCollBox, 0, (rsin(gameInfo.frame*16)-4096)*128, rcos(gameInfo.frame*16)*128);

		//pCollBox->pY=(rsin(gameInfo.frame*16)*256);
		// End of moving plat. stuff

		//platformDrawDynamicBoxes();

	
		TIMER_START(TIMER_BALLGLOVE);
		
		Control_Ball_And_Glove();
		TIMER_STOP(TIMER_BALLGLOVE);

		break;
	case GAMEMODE_PREVIEW:
		//viewerFrame();
		break;
	case GAMEMODE_RESTART:
		//printf ("restarting\n");

		levelRestart();
		gameInfo.mode=GAMEMODE_DEMO;
		if (gameInfo.keyRecordFlag==RECORD)
			gameInfo.keyRecordFlag=PLAYBACK;

		keyRecordCount=0;
		break;

	}


	gameInfo.frame++;
}


/****************************************************************************************************/
/****************************************************************************************************/
/****************************************************************************************************/
// This is for when Glove dies and the level has to be restarted
void	levelRestart(void)
{
	resetBall();
	resetGlove();

	Init_Camera();
	Respawn_Enemies();

	Use_Hoop(lasthoopused);	// nb - after the respawn

	UpdateOverlays();
}

/****************************************************************************************************/
/****************************************************************************************************/
/****************************************************************************************************/
char *sBonusTimer;
void gameMainGameLoop(){

	FASTSTACK();
//	DB("fade in\n");
	MenuFadeIn();
	gameInfo.levelStartTime=iframe;

	showGameOver=0;

	while((gameCtrl.dropOutFlag==GAME_INLEVEL)||(fadeout && (fader>1))||(showGameOver))
	{
		//DB("F=%d\n", framerate);

   		Start_Loop();

// Moved here from "interrupt.c", where it was messing up the front end in a big way if you quit mid-cameo
		if((CamVars.flags&(FIXEDLOOKAT|LOOKATPLAT) )&&(gameCtrl.state))
		{	// stop the player playing when camera is looking at stuff
			nleftx[0]=nlefty[0]=nrightx[0]=nrighty[0]=0;
			pad[0]=debounce[0]&=(PAD_START|PAD_SELECT);
		}

		timerDisplay();

		gameFrame();

		//textureDoScrolling();

#if GOLDCD== NO
		//if(debounce[1]&PAD_SELECT)
		//{// save a snapshot of the game
		//	SnapShot();
		//}
		//else
		//{
			showFrameRate(framerate);
		//}
#endif

		if(gameInfo.levelType==BONUS_LEVEL)
		{
			int timeLeft=gameInfo.timeAllowed-(iframe-gameInfo.levelStartTime);
			if((timeLeft<0)&&(showGameOver==0)&&(!fadeout)&&(fader>0))
			{
				timeLeft=0;
				gameCtrl.dropOutFlag=GAME_FAILEDBONUS; // TIMEDOUT is for demo
				gameCtrl.nextLevel = WAYROOM;	
				showGameOver=255;
				GloveCtrl.padDisableTimer=200;								
			}
			else if(timeLeft<=0)
				timeLeft=0;
			menuGetTimerString(timeLeft/30, sBonusTimer);
		}

		End_Loop(framerate);
		TIMER_ENDFRAME;

#if RELEASE==NO
		if(debounce[1] & PAD_R1)
			timerActive = !timerActive;

		if(debounce[1] & PAD_CIRCLE)
			GloveCtrl.lives++;
#endif

#ifdef TWOLEVEL_DEMO
		if (gameInfo.keyRecordFlag!=PLAYBACK)
		{
			if((iframe-padGetWhenLastUsed())>LEVEL_TIMEOUT) // drop out if pad not touched for some time
			{
				DB("Level timeout!\n");
				gameCtrl.dropOutFlag=GAME_TIMEDOUT;
			}
		}

		else
#endif
		if (gameInfo.keyRecordFlag==PLAYBACK)
		{
			if(keyRecordCount > gameInfo.keyTime)
			{
				gameCtrl.dropOutFlag=GAME_TIMEDOUT;
				SHOCK_STOP(0);
				SHOCK_NOBUZZ(0);
			}
			if(gameInfo.timePadLastHit!=padGetWhenLastUsed())
			{
				gameCtrl.dropOutFlag=GAME_TIMEDOUT;
				SHOCK_STOP(0);
				SHOCK_NOBUZZ(0);
			}
		}

#if RELEASE == NO
		if(pad[1]&PAD_TRIANGLE)
			gameCtrl.dropOutFlag=GAME_TIMEDOUT;
#endif

		

	}
SLOWSTACK();
	
// stop rumbling
	SHOCK_STOP(0);
	SHOCK_NOBUZZ(0);
}


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

DYNCOLLBOX *pCollBox;

OVERLAY		ovlHealth[14];
TEXT		*lifePtr;
ULONG		file;
void gameMainGame(int lev)
{
	OVERLAY	ovlLives;
	int i;
	int track;

	OVERLAY ovl;
	TextureBankType *pBank=NULL;
	SPRITEX	*pSpr;


	cardFreeMem();

	fadeStar = BFF_IsModelLoaded("FADESTAR", NULL);	

	ASSERT(fadeStar);
	objectSetupSegmentSort(fadeStar);


	DB("Attempting to load level %d\n", lev);
	pWaterSprites=NULL;
	track = LevelInfo[lev].musictrack;	//track = TRACK_HUB8;
	if(lev == WAYROOM)
	{
		switch(RANDOM256() & 3)
		{
		case 0:
			track = TRACK_XTRA1;
			break;
		case 1:
			track = TRACK_XTRA2;
			break;
		case 2:
			track = TRACK_XTRA3;
			break;
		case 3:
			track = TRACK_XTRA4;
			break;
// track_xtra5 is the outro credits music
		}
	}

	world = LevelInfo[lev].world;
	gameScore=0;

//	printf(">>> Entering gameMainGame\n");
//	memoryShow();

	overlayClearAll();

	interrupt_cyclebar = 1;

	if(gameInfo.keyRecordFlag==PLAYBACK)
	{
		pBank=textureLoadBank("GFX\\MENU.SPT");
		pSpr=textureFindInBank(pBank, "GLOVLOGO");
		textureDownloadBank(pBank);

		ASSERT(pSpr);

//		overlaySetupAndAdd(&ovl, pSpr, 256,48, 0, 0);
//		glovLogo.xPos=256;glovLogo.yPos=64-8*PALMODE;	

		overlaySetupAndAdd(&ovl, pSpr, 256,64-8*PALMODE, 0, 0);

#if PALMODE==YES
		ovl.scaleY=4096;
#else
		ovl.scaleY=3072;
#endif

		textureDestroyBank(pBank);
	}

	gameInitGameStuff();
	Init_Camera();


	//for(i=0; i<GloveCtrl.health; i++)// now possable to put health meter up to 14

	for(i=0; i<GameState.maxhealth; i++)
	//for(i=0; i<14; i++)	// now possable to put health meter up to 14
	{
#if PALMODE==YES
		overlaySetupAndAdd(ovlHealth+i, textureFindInAllBanks("HEALTH01"), 36+(i*24), 232, 0, 0);
#else
		overlaySetupAndAdd(ovlHealth+i, textureFindInAllBanks("HEALTH01"), 36+(i*24), 232-8, 0, 0);
#endif
	}

// Prevent the lives icon from vanishing!
	GloveCtrl.currentDisplayedHealth = GloveCtrl.maxHealth = GameState.maxhealth;

#if PALMODE==YES
	overlaySetupAndAdd(&ovlLives, textureFindInAllBanks("NUMLIVES01"), 453, 228, 0, 0);
#else
	overlaySetupAndAdd(&ovlLives, textureFindInAllBanks("NUMLIVES01"), 453, 228-8, 0, 0);
#endif

	ClearAllText();

	messctrl.font=fontList[0];

	NEW_TEXT(428,232-16+PALMODE*16, 128,128,0,255, 4096,4096, FALSE, "3*", FALSE);

	lifePtr=mtext;

	lifePtr->flags=TEXT_SHADED;

	lifePtr->r1=128;
	lifePtr->g1=40;
	lifePtr->b1=8;

//	textureFogPaletteOn();// enable fogging textures for each texture bank loaded
	pSky=NULL;
	object_atlantis_waterflag = 0;
	platformCreateDynamicBoxList();
	modelctrl.halfgouraud=0;
	modelctrl.subdivflag=TRUE;
	loadlnd_allow_platforms=TRUE;

	gameInfo.levelType=NORMAL_LEVEL;
	

// set the default fog to far off...
	SETRGBC(clscol.r, 0,0,0, GPU_COM_F4);
	lscapeFogStartZ = 5000;
	lscapeFogEndZ	= 5800;
	lscapeFogFlatZ	= 6000;
	SETRGBC(lscapeFogColour.r,255,255,255,255);

	switch(lev)
	{
	case TESTMESH:
		pWldBank=textureLoadBank("WORLDS\\TESTMESH\\TESTMESH\\TESTMESH.SPT");
		world=HUB;
		break;
  	case HUB1:
  	case HUB2:
  	case HUB3:
  	case HUB4:
  	case HUB5:
  	case HUB6:
  	case HUB7:
	case HUB8:
//		textureFogPaletteOff();// enable fogging textures for hub 8 to stop Tim moaning ...
		pWldBank=textureLoadBank("WORLDS\\HUB\\HUB8\\HUB8.SPT");
		SETRGBC(clscol.r, 128,255,255, GPU_COM_F4);
		SETRGBC(lscapeFogColour.r, 0,128,0, GPU_COM_F4);
		lscapeFogStartZ = 10000;
		lscapeFogEndZ	= 10200;
		lscapeFogFlatZ	= 10400;


		BallStartPos.vx=GloveStartPos.vx=0*4096;
		BallStartPos.vy=GloveStartPos.vy=-100*4096;
		BallStartPos.vz=GloveStartPos.vz=-800*4096;
		break;
	case CAVE:
		pWldBank=textureLoadBank("WORLDS\\HUB\\CAVE\\CAVE.SPT");
		break;


	case ATLANTIS1:
		pWldBank=textureLoadBank("WORLDS\\ATLANTIS\\L1\\AT1.SPT");
		SETRGBC(clscol.r, 255,255,162, GPU_COM_F4);
		world=ATLANTIS;
		GloveCtrl.allLevelGaribs = TRUE;	// used for extra heart per world
//		lscapeFogStartZ = 3200;
//		lscapeFogEndZ	= 3800;
//		lscapeFogFlatZ	= 4800;

//		lscapeFogStartZ = 3400;
//		lscapeFogEndZ	= 4000;
//		lscapeFogFlatZ	= 4800;

		break;
	case ATLANTIS2:
		pWldBank=textureLoadBank("WORLDS\\ATLANTIS\\L2\\AT2.SPT");
//		SETRGBC(clscol.r, 0,0,255, GPU_COM_F4);
		SETRGBC(clscol.r, 41,193,175, GPU_COM_F4);
		break;
	case ATLANTIS3:
		pWldBank=textureLoadBank("WORLDS\\ATLANTIS\\L3\\AT3.SPT");
		SETRGBC(clscol.r, 41,193,175, GPU_COM_F4);
		break;
	case ATTEST:
		pWldBank=textureLoadBank("WORLDS\\ATLANTIS\\TEST\\ATTEST.SPT");
		SETRGBC(clscol.r, 255,255,162, GPU_COM_F4);
		break;

	case ATLANTISBOSS:
		pWldBank=textureLoadBank("WORLDS\\ATLANTIS\\BOSS\\ATBOSS.SPT");
		break;
	case ATLANTISBONUS:
		pWldBank=textureLoadBank("WORLDS\\ATLANTIS\\BONUS\\ATBONUS.SPT");
		SETRGBC(clscol.r, 0,255,255, GPU_COM_F4);
		gameInfo.levelType=BONUS_LEVEL;
		break;
	
	case CARNIVAL1:
		GloveCtrl.allLevelGaribs = FALSE;
		pWldBank=textureLoadBank("WORLDS\\CARNIVAL\\L1\\CA1.SPT");
		SETRGBC(clscol.r, 240,112,0, GPU_COM_F4);
		break;
	case CARNIVAL2:
		pWldBank=textureLoadBank("WORLDS\\CARNIVAL\\L2\\CA2.SPT");
		SETRGBC(clscol.r, 240,112,0, GPU_COM_F4);
		break;
	case CARNIVAL3:
		pWldBank=textureLoadBank("WORLDS\\CARNIVAL\\L3\\CA3.SPT");
		SETRGBC(clscol.r, 255,127,0, GPU_COM_F4);
		break;
	case CARNIVALBOSS:
		pWldBank=textureLoadBank("WORLDS\\CARNIVAL\\BOSS\\CABOSS.SPT");
		break;
	case CARNIVALBONUS:
		pWldBank=textureLoadBank("WORLDS\\CARNIVAL\\BONUS\\CABONUS.SPT");
		gameInfo.levelType=BONUS_LEVEL;
		break;
	case CATEST:
		pWldBank=textureLoadBank("WORLDS\\CARNIVAL\\TEST\\CATEST.SPT");
		break;

	case PIRATES1:
		GloveCtrl.allLevelGaribs = FALSE;
		pWldBank=textureLoadBank("WORLDS\\PIRATES\\L1\\PI1.SPT");
		SETRGBC(clscol.r, 255,122,66, GPU_COM_F4);
		break;
	case PIRATES2:
		pWldBank=textureLoadBank("WORLDS\\PIRATES\\L2\\PI2.SPT");
		SETRGBC(clscol.r, 0,0,64, GPU_COM_F4);
		break;
	case PIRATES3:
		pWldBank=textureLoadBank("WORLDS\\PIRATES\\L3\\PI3.SPT");
		break;

	case PIRATESBOSS:
		pWldBank=textureLoadBank("WORLDS\\PIRATES\\BOSS\\PIBOSS.SPT");
		SETRGBC(clscol.r, 0,0,240, GPU_COM_F4);
		break;
	case PIRATESBONUS:
		pWldBank=textureLoadBank("WORLDS\\PIRATES\\BONUS\\PIBONUS.SPT");
		gameInfo.levelType=BONUS_LEVEL;

		break;
	case PITEST:
		pWldBank=textureLoadBank("WORLDS\\PIRATES\\TEST\\PITEST.SPT");
		break;

	case PREHISTORICTEST:
		pWldBank=textureLoadBank("WORLDS\\PREHIST\\TEST\\PRTEST.SPT");
		break;
	case PREHISTORIC1:
		GloveCtrl.allLevelGaribs = FALSE;
		pWldBank=textureLoadBank("WORLDS\\PREHIST\\L1\\PR1.SPT");
		break;
	case PREHISTORIC2:
		pWldBank=textureLoadBank("WORLDS\\PREHIST\\L2\\PR2.SPT");
		break;
	case PREHISTORIC3:
		pWldBank=textureLoadBank("WORLDS\\PREHIST\\L3\\PR3.SPT");
		break;
	case PREHISTORICBOSS:
		pWldBank=textureLoadBank("WORLDS\\PREHIST\\BOSS\\PRBOSS.SPT");
		break;
	case PREHISTORICBONUS:
		pWldBank=textureLoadBank("WORLDS\\PREHIST\\BONUS\\PRBONUS.SPT");
		gameInfo.levelType=BONUS_LEVEL;

		break;

	case FEAR1:
		GloveCtrl.allLevelGaribs = FALSE;
		pWldBank=textureLoadBank("WORLDS\\FEAR\\L1\\FF1.SPT");
		break;
	case FEAR2:
		pWldBank=textureLoadBank("WORLDS\\FEAR\\L2\\FF2.SPT");
		break;
	case FEAR3:
		pWldBank=textureLoadBank("WORLDS\\FEAR\\L3\\FF3.SPT");
		break;
	case FEARBONUS:
		pWldBank=textureLoadBank("WORLDS\\FEAR\\BONUS\\FFBONUS.SPT");
		gameInfo.levelType=BONUS_LEVEL;
		break;
	case FEARBOSS:
		pWldBank=textureLoadBank("WORLDS\\FEAR\\BOSS\\FFBOSS.SPT");
		break;
	case FEARTEST:
		pWldBank=textureLoadBank("WORLDS\\FEAR\\TEST\\FFTEST.SPT");
		break;

	case SPACE2A:
		GloveCtrl.allLevelGaribs = FALSE;
		pWldBank=textureLoadBank("WORLDS\\OOTW\\L1\\SP1.SPT");
		break;
	case SPACE2B:
		pWldBank=textureLoadBank("WORLDS\\OOTW\\L2\\SP2.SPT");
		break;
	case SPACE3:
		pWldBank=textureLoadBank("WORLDS\\OOTW\\L3\\SP3.SPT");
		break;
	case SPACETEST:
		pWldBank=textureLoadBank("WORLDS\\OOTW\\TEST\\SPTEST.SPT");
		break;

	case SPACEBOSS1:
		pWldBank=textureLoadBank("WORLDS\\OOTW\\BOSS\\SPBOSS.SPT");
		break;
	case SPACEBOSS2:
		pWldBank=textureLoadBank("WORLDS\\OOTW\\BOSS2\\SPBOSS2.SPT");
		break;
	case SPACEBONUS:
		pWldBank=textureLoadBank("WORLDS\\OOTW\\BONUS\\SPBONUS.SPT");
		gameInfo.levelType=BONUS_LEVEL;

		break;
	case WAYROOM:
	case WAYROOM2:
	case WAYROOM3:
	case WAYROOM4:
	case WAYROOM5:
		pWldBank=textureLoadBank("WORLDS\\HUB\\WAYROOM\\WAYROOM.SPT");
		break;

	default:
		DB("WARNING: No texture bank has been loaded (other than generic)\n");
	}
	//platformLoadFragmentBodge();

	if(*(u_long *)(&lscapeFogColour.r) == 0xffffffff)
		lscapeFogColour = clscol;

	textureDownloadBank(pWldBank);
	textureDestroyBank(pWldBank);

	LoadMusic();
	weatherInitialise(WEATHER_NULL);

	ballOldPos.vx=ballPos.vx=glovePos.vx=BallStartPos.vx=GloveStartPos.vx=0;
	ballOldPos.vy=ballPos.vy=glovePos.vy=BallStartPos.vy=GloveStartPos.vy=0;
	ballOldPos.vz=ballPos.vz=glovePos.vz=BallStartPos.vz=GloveStartPos.vz=0;

	switch(lev)
	{
	case TESTMESH:
		//setupCollision("WORLDS\\TESTMESH\\TESTMESH\\TESTMESH");
		Level_BFF = BFF_LoadFile("WORLDS\\TESTMESH\\TESTMESH.BFF");
		setupCollision("TESTMESH");

		//ballPos.vy=glovePos.vy=BallStartPos.vy=GloveStartPos.vy=-10000*4096;

		BallStartPos.vx=GloveStartPos.vx=300*4096;
		BallStartPos.vy=GloveStartPos.vy=-200*4096;
		BallStartPos.vz=GloveStartPos.vz=-600*4096;

		ParseLandscapeFile("WORLDS\\TESTMESH\\TESTMESH\\TESTMESH.LEV");
		break;

	case HUB1:
		Level_BFF = BFF_LoadFile("WORLDS\\HUB\\HUB1.BFF");
		setupCollision("HUB1");
		ParseLandscapeFile("WORLDS\\HUB\\HUB1\\HUB1.LEV");
		break;
//		goto GENERICHUB;
	case HUB2:
		Level_BFF = BFF_LoadFile("WORLDS\\HUB\\HUB2.BFF");
		setupCollision("HUB2");
		ParseLandscapeFile("WORLDS\\HUB\\HUB2\\HUB2.LEV");
		break;
//		goto GENERICHUB;
 	case HUB3:
		Level_BFF = BFF_LoadFile("WORLDS\\HUB\\HUB3.BFF");
		setupCollision("HUB3");
		ParseLandscapeFile("WORLDS\\HUB\\HUB3\\HUB3.LEV");
		break;
//		goto GENERICHUB;
	case HUB4:
		Level_BFF = BFF_LoadFile("WORLDS\\HUB\\HUB4.BFF");
		setupCollision("HUB4");
		ParseLandscapeFile("WORLDS\\HUB\\HUB4\\HUB4.LEV");
		break;
//		goto GENERICHUB;
	case HUB5:
		Level_BFF = BFF_LoadFile("WORLDS\\HUB\\HUB5.BFF");
		setupCollision("HUB5");
		ParseLandscapeFile("WORLDS\\HUB\\HUB5\\HUB5.LEV");
		break;
//		goto GENERICHUB;
	case HUB6:
		Level_BFF = BFF_LoadFile("WORLDS\\HUB\\HUB6.BFF");
		setupCollision("HUB6");
		ParseLandscapeFile("WORLDS\\HUB\\HUB6\\HUB6.LEV");
		break;
//		goto GENERICHUB;
 	case HUB7:
		Level_BFF = BFF_LoadFile("WORLDS\\HUB\\HUB7.BFF");
		setupCollision("HUB7");
		ParseLandscapeFile("WORLDS\\HUB\\HUB7\\HUB7.LEV");
		break;
//		goto GENERICHUB;
	case HUB8:
		Level_BFF = BFF_LoadFile("WORLDS\\HUB\\HUB8.BFF");
		setupCollision("HUB8");
		ParseLandscapeFile("WORLDS\\HUB\\HUB8\\HUB8.LEV");
		break;
//		goto GENERICHUB;

//	GENERICHUB:

//		BallStartPos.vx=GloveStartPos.vx=0*4096;
//		BallStartPos.vy=GloveStartPos.vy=-100*4096;
//		BallStartPos.vz=GloveStartPos.vz=-800*4096;
	
		//weatherInitialise(WEATHER_BIRDY);
		//weatherInitialise(WEATHER_RAIN);
//		weatherInitialise(WEATHER_THUNDER|WEATHER_RAIN);
//		ParseLandscapeFile("WORLDS\\HUB\\HUB8\\HUB8.LEV");
//		break;

	case CAVE:
		Level_BFF = BFF_LoadFile("WORLDS\\HUB\\CAVE.BFF");
		setupCollision("CAVE");
		ParseLandscapeFile("WORLDS\\HUB\\CAVE\\CAVE.LEV");
		break;

	case ATLANTIS1:
		Level_BFF = BFF_LoadFile("WORLDS\\ATLANTIS\\AT1.BFF");
		setupCollision("AT1");

		object_atlantis_waterflag = 1;

  //		textureFogPaletteOff();

// As soon as we've got a proper lnd, it'll be time to move the lscape parse to after the start position define
		ParseLandscapeFile("WORLDS\\ATLANTIS\\L1\\AT1.LEV");

		break;

	case ATLANTIS2:
		Level_BFF = BFF_LoadFile("WORLDS\\ATLANTIS\\AT2.BFF");
		setupCollision("AT2");
		BallStartPos.vx=GloveStartPos.vx=0.08*4096;
		BallStartPos.vy=GloveStartPos.vy=-133.12*4096; // ?
		BallStartPos.vz=GloveStartPos.vz=79*4096;
		ParseLandscapeFile("WORLDS\\ATLANTIS\\L2\\AT2.LEV");
		break;

	case ATLANTIS3:
		Level_BFF = BFF_LoadFile("WORLDS\\ATLANTIS\\AT3.BFF");
		setupCollision("AT3");

		BallStartPos.vx=GloveStartPos.vx=0.08*4096;
		BallStartPos.vy=GloveStartPos.vy=-133.12*4096; // ?
		BallStartPos.vz=GloveStartPos.vz=79*4096;
		ParseLandscapeFile("WORLDS\\ATLANTIS\\L3\\AT3.LEV");
		break;

	case ATLANTISBOSS:
		Level_BFF = BFF_LoadFile("WORLDS\\ATLANTIS\\ATBOSS.BFF");
		setupCollision("ATBOSS");
		ParseLandscapeFile("WORLDS\\ATLANTIS\\BOSS\\ATBOSS.LEV");
		break;
	case ATLANTISBONUS:

		Level_BFF = BFF_LoadFile("WORLDS\\ATLANTIS\\ATBONUS.BFF");
		setupCollision("ATBONUS");
		BallStartPos.vy=GloveStartPos.vy=-80*4096;
		ParseLandscapeFile("WORLDS\\ATLANTIS\\BONUS\\ATBONUS.LEV");
		break;

	case ATTEST:
// note that the BFF load has to come after the music & sprite files have been loaded in
		Level_BFF = BFF_LoadFile("WORLDS\\ATLANTIS\\ATTEST.BFF");

		setupCollision("ATTEST");
		BallStartPos.vx=GloveStartPos.vx=0.08*4096;
		BallStartPos.vy=GloveStartPos.vy=-133.12*4096; // ?
		BallStartPos.vz=GloveStartPos.vz=79*4096;
//		loadlnd_load_scape = 1;
		ParseLandscapeFile("WORLDS\\ATLANTIS\\TEST\\ATTEST.LEV");
//		loadlnd_load_scape = 0;
		break;

	case CARNIVAL1:
		Level_BFF = BFF_LoadFile("WORLDS\\CARNIVAL\\CA1.BFF");
		setupCollision("CA1");
		BallStartPos.vy=GloveStartPos.vy=-50*4096; // ?

		ParseLandscapeFile("WORLDS\\CARNIVAL\\L1\\CA1.LEV");

		carnival1Init();
		break;

	case CARNIVAL2:
		Level_BFF = BFF_LoadFile("WORLDS\\CARNIVAL\\CA2.BFF");
		setupCollision("CA2");

		BallStartPos.vx=GloveStartPos.vx=-1992*4096;
		BallStartPos.vy=GloveStartPos.vy=-50*4096; // ?
		BallStartPos.vz=GloveStartPos.vz=-397*4096;

		ParseLandscapeFile("WORLDS\\CARNIVAL\\L2\\CA2.LEV");
		break;

	case CARNIVAL3:
		Level_BFF = BFF_LoadFile("WORLDS\\CARNIVAL\\CA3.BFF");
		setupCollision("CA3");

		BallStartPos.vx=GloveStartPos.vx=345*4096;
		BallStartPos.vy=GloveStartPos.vy=-70*4096; // ?
		BallStartPos.vz=GloveStartPos.vz=1444*4096;

		ParseLandscapeFile("WORLDS\\CARNIVAL\\L3\\CA3.LEV");
		break;

	case CARNIVALBOSS:
		Level_BFF = BFF_LoadFile("WORLDS\\CARNIVAL\\CABOSS.BFF");
		setupCollision("CABOSS");
		ParseLandscapeFile("WORLDS\\CARNIVAL\\BOSS\\CABOSS.LEV");
		break;

	case CARNIVALBONUS:
		Level_BFF = BFF_LoadFile("WORLDS\\CARNIVAL\\CABONUS.BFF");
		setupCollision("CABONUS");
		ParseLandscapeFile("WORLDS\\CARNIVAL\\BONUS\\CABONUS.LEV");
		
		loadCarnivalBonusModels();

		break;

	case CATEST:
		Level_BFF = BFF_LoadFile("WORLDS\\CARNIVAL\\CATEST.BFF");
		setupCollision("CATEST");
		BallStartPos.vx=GloveStartPos.vx=-700*4096;
		BallStartPos.vy=GloveStartPos.vy= -20*4096;
		BallStartPos.vz=GloveStartPos.vz=   0*4096;
		ParseLandscapeFile("WORLDS\\CARNIVAL\\TEST\\CATEST.LEV");
		break;


	case PIRATES1:
		Level_BFF = BFF_LoadFile("WORLDS\\PIRATES\\PI1.BFF");
		setupCollision("PI1");

		BallStartPos.vx=GloveStartPos.vx=2589*4096;
		BallStartPos.vy=GloveStartPos.vy=500*4096;//-622*4096;
		BallStartPos.vz=GloveStartPos.vz=115*4096;
		ParseLandscapeFile("WORLDS\\PIRATES\\L1\\PI1.LEV");

		loadPiratesModels();

		break;
	case PIRATES2:
		Level_BFF = BFF_LoadFile("WORLDS\\PIRATES\\PI2.BFF");
		setupCollision("PI2");

		BallStartPos.vx=GloveStartPos.vx=5*4096;
		BallStartPos.vy=GloveStartPos.vy=-20*4096;//-622*4096;
		BallStartPos.vz=GloveStartPos.vz=0*4096;

		ParseLandscapeFile("WORLDS\\PIRATES\\L2\\PI2.LEV");
		break;
	case PIRATES3:
		Level_BFF = BFF_LoadFile("WORLDS\\PIRATES\\PI3.BFF");
		setupCollision("PI3");

		BallStartPos.vx=GloveStartPos.vx=50*4096;
		BallStartPos.vy=GloveStartPos.vy=0;
		BallStartPos.vz=GloveStartPos.vz=100*4096;

		ParseLandscapeFile("WORLDS\\PIRATES\\L3\\PI3.LEV");
		break;

	case PIRATESBOSS:
		Level_BFF = BFF_LoadFile("WORLDS\\PIRATES\\PIBOSS.BFF");
		setupCollision("PIBOSS");
		ParseLandscapeFile("WORLDS\\PIRATES\\BOSS\\PIBOSS.LEV");
		break;
	case PIRATESBONUS:
		Level_BFF = BFF_LoadFile("WORLDS\\PIRATES\\PIBONUS.BFF");
		setupCollision("PIBONUS");
		ParseLandscapeFile("WORLDS\\PIRATES\\BONUS\\PIBONUS.LEV");
		break;
	case PITEST:
		Level_BFF = BFF_LoadFile("WORLDS\\PIRATES\\PITEST.BFF");
		setupCollision("PITEST");
//		BallStartPos.vy=GloveStartPos.vy=-200*4096;
		BallStartPos.vx=GloveStartPos.vx=-700*4096;
		BallStartPos.vy=GloveStartPos.vy= -20*4096;//-622*4096;
		BallStartPos.vz=GloveStartPos.vz=   0*4096;
		ParseLandscapeFile("WORLDS\\PIRATES\\TEST\\PITEST.LEV");
		break;



	case PREHISTORICTEST:
		Level_BFF = BFF_LoadFile("WORLDS\\PREHIST\\PRTEST.BFF");
		setupCollision("PRTEST");
		BallStartPos.vy=GloveStartPos.vy=-200*4096;

		ParseLandscapeFile("WORLDS\\PREHIST\\TEST\\PRTEST.LEV");
		break;

	case PREHISTORIC1:
		Level_BFF = BFF_LoadFile("WORLDS\\PREHIST\\PR1.BFF");
		setupCollision("PR1");

		BallStartPos.vy=GloveStartPos.vy=-200*4096;
		ParseLandscapeFile("WORLDS\\PREHIST\\L1\\PR1.LEV");
		weatherInitialise(WEATHER_SNOW);

		pBoulderPSA=BFF_IsModelLoaded("SNOWBALL",NULL);
		objectSetupSegmentSort(pBoulderPSA);

		pGloveBoulderPSA=BFF_IsModelLoaded("SNOWGLOV",NULL);
		objectSetupSegmentSort(pGloveBoulderPSA);

		pBoulderPSA->globalscale.vx=1360;
		pBoulderPSA->globalscale.vy=1360;
		pBoulderPSA->globalscale.vz=1360;

		pGloveBoulderPSA->globalscale.vx=1360;
		pGloveBoulderPSA->globalscale.vy=1360;
		pGloveBoulderPSA->globalscale.vz=1360;

		break;

	case PREHISTORIC2:
		Level_BFF = BFF_LoadFile("WORLDS\\PREHIST\\PR2.BFF");
		setupCollision("PR2");

		BallStartPos.vy=GloveStartPos.vy=-200*4096;
		ParseLandscapeFile("WORLDS\\PREHIST\\L2\\PR2.LEV");
		pBoulderPSA=BFF_IsModelLoaded("BOULDER",NULL);
		objectSetupSegmentSort(pBoulderPSA);
		pBoulderPSA->globalscale.vx=1360;
		pBoulderPSA->globalscale.vy=1360;
		pBoulderPSA->globalscale.vz=1360;


		break;

	case PREHISTORIC3:
		Level_BFF = BFF_LoadFile("WORLDS\\PREHIST\\PR3.BFF");
		setupCollision("PR3");

		BallStartPos.vx=GloveStartPos.vx=-2320*4096;
		BallStartPos.vy=GloveStartPos.vy=    0*4096;
		BallStartPos.vz=GloveStartPos.vz= 1080 * 4096;

		ParseLandscapeFile("WORLDS\\PREHIST\\L3\\PR3.LEV");
		break;

	case PREHISTORICBOSS:
		Level_BFF = BFF_LoadFile("WORLDS\\PREHIST\\PRBOSS.BFF");
		setupCollision("PRBOSS");

		ParseLandscapeFile("WORLDS\\PREHIST\\BOSS\\PRBOSS.LEV");
		weatherInitialise(WEATHER_SNOW);

		break;

	case PREHISTORICBONUS:
		Level_BFF = BFF_LoadFile("WORLDS\\PREHIST\\PRBONUS.BFF");
		setupCollision("PRBONUS");

		ParseLandscapeFile("WORLDS\\PREHIST\\BONUS\\PRBONUS.LEV");
		break;



	case FEAR1:
		Level_BFF = BFF_LoadFile("WORLDS\\FEAR\\FF1.BFF");
		setupCollision("FF1");

		ParseLandscapeFile("WORLDS\\FEAR\\L1\\FF1.LEV");
		weatherInitialise(WEATHER_THUNDER|WEATHER_RAIN);
		break;
	case FEAR2:
		Level_BFF = BFF_LoadFile("WORLDS\\FEAR\\FF2.BFF");
		setupCollision("FF2");

		ParseLandscapeFile("WORLDS\\FEAR\\L2\\FF2.LEV");
		weatherInitialise(WEATHER_THUNDER|WEATHER_RAIN);
		break;

	case FEAR3:
		Level_BFF = BFF_LoadFile("WORLDS\\FEAR\\FF3.BFF");
		setupCollision("FF3");

		BallStartPos.vx=GloveStartPos.vx=-1880*4096;
		BallStartPos.vy=GloveStartPos.vy=-225*4096;
		BallStartPos.vz=GloveStartPos.vz=4596*4096;

		ParseLandscapeFile("WORLDS\\FEAR\\L3\\FF3.LEV");
		weatherInitialise(WEATHER_THUNDER|WEATHER_RAIN);

		break;

	case FEARTEST:
		Level_BFF = BFF_LoadFile("WORLDS\\FEAR\\FFTEST.BFF");
		setupCollision("FFTEST");
		BallStartPos.vy=GloveStartPos.vy=-200*4096;

		ParseLandscapeFile("WORLDS\\FEAR\\TEST\\FFTEST.LEV");
		break;
	case FEARBOSS:
		Level_BFF = BFF_LoadFile("WORLDS\\FEAR\\FFBOSS.BFF");
		setupCollision("FFBOSS");
		ParseLandscapeFile("WORLDS\\FEAR\\BOSS\\FFBOSS.LEV");
		break;
	case FEARBONUS:
		Level_BFF = BFF_LoadFile("WORLDS\\FEAR\\FFBONUS.BFF");
		setupCollision("FFBONUS");
		BallStartPos.vy=GloveStartPos.vy=-200*4096;

		ParseLandscapeFile("WORLDS\\FEAR\\BONUS\\FFBONUS.LEV");
		break;



	case SPACE2A:
		Level_BFF = BFF_LoadFile("WORLDS\\OOTW\\SP1.BFF");
		setupCollision("SP1");
		BallStartPos.vy=GloveStartPos.vy=-200*4096;

		ParseLandscapeFile("WORLDS\\OOTW\\L1\\SP1.LEV");
		break;
	case SPACE2B:
		Level_BFF = BFF_LoadFile("WORLDS\\OOTW\\SP2.BFF");
		setupCollision("SP2");
		BallStartPos.vy=GloveStartPos.vy=-200*4096;

		ParseLandscapeFile("WORLDS\\OOTW\\L2\\SP2.LEV");
		break;

	case SPACE3:
		Level_BFF = BFF_LoadFile("WORLDS\\OOTW\\SP3.BFF");
		setupCollision("SP3");
		BallStartPos.vy=GloveStartPos.vy=-200*4096;

		ParseLandscapeFile("WORLDS\\OOTW\\L3\\SP3.LEV");
		break;

	case SPACETEST:
		Level_BFF = BFF_LoadFile("WORLDS\\OOTW\\SPTEST.BFF");
		setupCollision("SPTEST");
		BallStartPos.vy=GloveStartPos.vy=-200*4096;

		ParseLandscapeFile("WORLDS\\OOTW\\TEST\\SPTEST.LEV");
		break;

	case SPACEBOSS1:
		Level_BFF = BFF_LoadFile("WORLDS\\OOTW\\SPBOSS.BFF");
		setupCollision("SPBOSS");
		ParseLandscapeFile("WORLDS\\OOTW\\BOSS\\SPBOSS.LEV");
		break;
	case SPACEBOSS2:
		Level_BFF = BFF_LoadFile("WORLDS\\OOTW\\SPBOSS2.BFF");
		setupCollision("SPBOSS2");
		ParseLandscapeFile("WORLDS\\OOTW\\BOSS2\\SPBOSS2.LEV");
		break;

	case SPACEBONUS:
		Level_BFF = BFF_LoadFile("WORLDS\\OOTW\\SPBONUS.BFF");
		setupCollision("SPBONUS");
		ParseLandscapeFile("WORLDS\\OOTW\\BONUS\\SPBONUS.LEV");
		break;


	case WAYROOM5:
		GameState.levels_open[i]|=LEVOPEN_BONUS_OPEN;
	case WAYROOM4:
		GameState.levels_open[i]|=LEVOPEN_BOSS_OPEN;
	case WAYROOM3:
		GameState.levels_open[i]|=LEVOPEN_L3_OPEN;
	case WAYROOM2:
		GameState.levels_open[i]|=LEVOPEN_L2_OPEN;
	case WAYROOM:
	{
		int i;
		i = gameCtrl.wayroom_world-1;
		if(i < 0 || i >= 6) i = 0;

		i = GameState.levels_open[i];

		if(i & LEVOPEN_BONUS_OPEN)
		{
			Level_BFF = BFF_LoadFile("WORLDS\\HUB\\WAYROOM5.BFF");
			setupCollision("WAYROOM5");
			ParseLandscapeFile("WORLDS\\HUB\\WAYROOM5\\WAYROOM5.LEV");
		}
		else if(i & LEVOPEN_BOSS_OPEN)
		{
			Level_BFF = BFF_LoadFile("WORLDS\\HUB\\WAYROOM4.BFF");
			setupCollision("WAYROOM4");
			ParseLandscapeFile("WORLDS\\HUB\\WAYROOM4\\WAYROOM4.LEV");
		}
		else if(i & LEVOPEN_L3_OPEN)
		{
			Level_BFF = BFF_LoadFile("WORLDS\\HUB\\WAYROOM3.BFF");
			setupCollision("WAYROOM3");
			ParseLandscapeFile("WORLDS\\HUB\\WAYROOM3\\WAYROOM3.LEV");
		}
		else if(i & LEVOPEN_L2_OPEN)
		{
			Level_BFF = BFF_LoadFile("WORLDS\\HUB\\WAYROOM2.BFF");
			setupCollision("WAYROOM2");
			ParseLandscapeFile("WORLDS\\HUB\\WAYROOM2\\WAYROOM2.LEV");
		}
		else
		{
			Level_BFF = BFF_LoadFile("WORLDS\\HUB\\WAYROOM.BFF");
			setupCollision("WAYROOM");
			ParseLandscapeFile("WORLDS\\HUB\\WAYROOM\\WAYROOM.LEV");
		}

		break;
	}

	default:
		// have a fit!
		DB("LEVEL UNPLAYABLE\n");
		CRASH;
	}

//	textureMakeScrolling(textureFindInAllBanks("CONV3"));


	{
		BFF_WorldHeader *head;
		head = (void *)BFF_FindNamedObject(BFF_WLD_ID, "WORLD");
		if(head)
		{
			pWld = &head->world;
		}
	}

/*	if((lev>=HUB1)&&(lev<=HUB8))
		noHintText=0;
	else 
		noHintText=1;*/

	Load_And_Init_Tips();
	pSky = BFF_IsModelLoaded("SKY",NULL);	// bff-only version of LoadPSA

	gameInfo.level=lev;

//Startpos will/should have been defined in the parselandscape
	ballPos = BallStartPos;
	glovePos = GloveStartPos;

	{
		pGlovePSA->position.vx = glovePos.vx >>12;	// the camera init runs off the glovePSA
		pGlovePSA->position.vy = glovePos.vy >>12;
		pGlovePSA->position.vz = glovePos.vz >>12;
		pBallPSA->position.vx = ballPos.vx >>12;
		pBallPSA->position.vy = ballPos.vy >>12;
		pBallPSA->position.vz = ballPos.vz >>12;
		ballOldPos.vx=ballPos.vx;
		ballOldPos.vy=ballPos.vy;
		ballOldPos.vz=ballPos.vz;
		Init_Camera();
	}

	interrupt_cyclebar = 0;


 //	textureFogPaletteOff();

	// Main loop

// got rid of, coz we're using the XA tracks now...
/*
	if (cdmusic==YES)
	{
		CDInitialise();	// Dunno, but let's give this a whirl. I was having to open the door for a mo to wake the music up

		CDPlayTrack(1);
	}
*/
//	debugPrintf("main loop\n");

	padResetWhenLastUsed();
	gameInfo.timePadLastHit=padGetWhenLastUsed();

	XA_SetMusicGoing(track, 1);	// **** ALL FILE LOADING NEEDS TO HAVE BEEN DONE BY NOW! ****


// repeated here coz setmusicgoing can be a time consuming one in worst case
	padResetWhenLastUsed();
	gameInfo.timePadLastHit=padGetWhenLastUsed();

	if(gameInfo.levelType==BONUS_LEVEL)
	{
#if PALMODE == YES
#ifdef MULTI_LANGUAGE
		NEW_TEXT(256, 16, 128,128,0,255, 3072,3072, FALSE, fontFindLangString(STR_TIME), TRUE);
#else
		NEW_TEXT(256, 16, 128,128,0,255, 3072,3072, FALSE, "TIME", TRUE);
#endif
		mtext->flags=TEXT_SHADED;
		mtext->r1=128;
		mtext->g1=40;
		mtext->b1=8;

		NEW_TEXT(256, 32, 128,128,0,255, 4096,4096, FALSE, "", TRUE);
		mtext->flags=TEXT_SHADED;
		mtext->font=fontList[2];
		mtext->r1=128;
		mtext->g1=40;
		mtext->b1=8;
#else
#ifdef MULTI_LANGUAGE
		NEW_TEXT(256, 16+12, 128,128,0,255, 3072,3072, FALSE, fontFindLangString(STR_TIME), TRUE);
#else
		NEW_TEXT(256, 16+12, 128,128,0,255, 3072,3072, FALSE, "TIME", TRUE);
#endif
		mtext->flags=TEXT_SHADED;
		mtext->r1=128;
		mtext->g1=40;
		mtext->b1=8;

//		NEW_TEXT(256, 32+12, 128,128,0,255, 2400,2400, FALSE, "", TRUE);
		NEW_TEXT(256, 32+12, 128,128,0,255, 4096,4096, FALSE, "", TRUE);
		mtext->flags=TEXT_SHADED;
		mtext->font=fontList[2];
		mtext->r1=128;
		mtext->g1=40;
		mtext->b1=8;
#endif

		sBonusTimer=mtext->message;
		if(level == PIRATESBONUS)
			gameInfo.timeAllowed=((180+100)*100)*30;
		else
			gameInfo.timeAllowed=(180*100)*30; // = 3 mins in iframes
	}


	if ( ((numGaribs-garibscollected)==0) )
		GloveCtrl.garibCollectState=255;





	DB(">>> Memory state at level-playing time <<<\n");
	memoryShowStats();
	texturePrintStatus();

//	printf(">>> Details...\n");
//	memoryShow();

	GloveCtrl.healthChange = TRUE;
	UpdateOverlays();

	gameMainGameLoop();			//EVERYTHING THAT RUNS THE GAME!!!


	gameInfo.levelEndTime=iframe;

	if(gameInfo.keyRecordFlag==PLAYBACK)
	{
		textureUnloadBank(pBank);
	}

	if(gameCtrl.dropOutFlag==GAME_BACKTOCASTLE)	// requested by hasbro's testers.
	{
		UpdateGamestate();
	}
	else if(gameCtrl.dropOutFlag==GAME_COMPLETED || gameCtrl.dropOutFlag==GAME_FAILEDBONUS)
	{
		gameCtrl.previousLevel = level;

// Note - the game-state update needs to be done before freeing the level
		UpdateGamestate();

		if(world == HUB)
			gameCtrl.port_with_ball = (GloveCtrl.handOnBall || GloveCtrl.ballWithHand);
		else
			gameCtrl.port_with_ball = TRUE;	// deal with cheating. If you complete a level "successfully", you've left with the ball
	}


	//SFXStopSounds();
	

//	printf(">>> Leaving gameMainGame\n");
//	memoryShow();


	if(world != HUB)
	{
		DB("overriding wayroom world with %d\n",world);
		gameCtrl.wayroom_world = world;
	}

	if(gameCtrl.dropOutFlag==GAME_BACKTOCASTLE)
	{
		gameCtrl.nextLevel = gameCtrl.hub_to_use;
		gameCtrl.previousLevel = level;
// DONT update the gamestate with the things we failed to do on that level
		gameCtrl.port_with_ball = FALSE;
	}



//	if(gameCtrl.dropOutFlag==GAME_COMPLETED && level != HUB8)
	if(gameCtrl.dropOutFlag==GAME_COMPLETED && world != HUB)
	{
		HiScoreType theseScores;
		int timeTook=(gameInfo.levelEndTime-gameInfo.levelStartTime)/30;


		DB("------ world = %d -------\n",world);

		theseScores.betterTime=FALSE;

		if(timeTook<hiScores[gameInfo.level].timeTook)
		{
			theseScores.betterTime=TRUE;
			hiScores[gameInfo.level].timeTook=timeTook;
		}

		theseScores.betterGaribs=FALSE;

		if(garibscollected>hiScores[gameInfo.level].nGaribs)
		{
			theseScores.betterGaribs=TRUE;
			hiScores[gameInfo.level].nGaribs=garibscollected;
		}

		hiScores[gameInfo.level].nTotalGaribs=numGaribs; // store it here for convenience

		if(gameScore>hiScores[gameInfo.level].score)
			hiScores[gameInfo.level].score=gameScore;

		theseScores.timeTook=timeTook;
		theseScores.nGaribs=garibscollected;
		theseScores.nTotalGaribs=numGaribs;
		theseScores.score=gameScore;


		{
			int result;
			result = menuShowStats(&gameInfo, hiScores, &theseScores);


			if(result == 0)
			{
				MenuFadeIn();
				enemiesFreeTempEnemies();
				MemCardControl(MEMCARD_SAVE);
			}
			gameReleaseGameStuff();	// MemCardControl needs some free memory to work with. Try saving on Space3
		}

	}
	else
	{
		gameReleaseGameStuff();
	}
	weatherCleanUp();

#if RECORDKEYS == YES
	if (gameInfo.keyRecordFlag==RECORD)
	{
		unsigned long   file;

		if((file=PCcreat("C:\\PSX\\WHACK\\CD\\DEMOS\\RECORD.DEM",1)) == -1)
		{
			DB("Error creating file record.dem\n");
			return;
		}
		else
		{
			PCwrite(file,(UBYTE*)keyRecord,32768);// 64k for main ptr array
			PCclose(file);
			//FREE( (UBYTE*)keyRecord );// Very bad way of doing this
			DB("Record Key Demo Length = %d\n",keyRecordCount);

		}
	}
#endif

}

/****************************************************************************************************/
/****************************************************************************************************/
/****************************************************************************************************/
//int	pauseFlag=FALSE;
//int	initcard=FALSE;

VECTOR soundPos;

void renderWorld(void)
{
	weatherDo();

	ballRender();
	handRender();

	if(cheatNeedsDraw)
		cheatDisplay();


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

	if(pSky)
	{
		ZEROVECTOR(&pSky->position);
		lscapeDraw(pSky,0);
	}

	Draw_All_Effects();

	TIMER_START(TIMER_LSCAPE);
	platformDrawDynamicBoxes();

	if(level==CARNIVAL1)
		carnival1Handler();

	TIMER_STOP(TIMER_LSCAPE);

	TIMER_START(TIMER_BALLGLOVE);

}
/***********************************************************************************/
void Control_Ball_And_Glove(void)
{
	IQUATERNION	tempQ;
	

#if RELEASE==NO
	if( (debounce[1]&PAD_SQUARE) )
	{
		if(GETSUBDIVDEPTH==SUBDIVISIONDEPTH)
		{
			DB("Subdiv off\n");
			SETSUBDIVDEPTH(-16000);	// disable subdiv, in effect
		}
		else
		{
			DB("Subdiv on\n");
			SETSUBDIVDEPTH(SUBDIVISIONDEPTH);
		}
	}
#endif

	if (GloveCtrl.action==HAND_CASTSPELL)
	{
		pBallPSA->globalscale.vx=ballRadius/152;
		pBallPSA->globalscale.vy=ballRadius/152;
		pBallPSA->globalscale.vz=ballRadius/152;
	}
	ballColl.radius=ballRadius;

	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);

	// Fix quat problem
	if (!(frame%100))
	{
		UnifyQuat(&pBallPSA->world.qRot);
		UnifyQuat(&pBallPSA->world.qRotLight);
		//printf ("fixing quats\n");
	}

	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;
	

#if PRINTMESS==YES
	TEXTSETPOS(32,8);
	SETRGBC(sprctrl.r,0,128,0,0);

	sprctrl.scalex=4096;
	sprctrl.scaley=4096;
	sprctrl.stretch=0;
	textPrintf("BallPos=%d,%d,%d\n", ballPos.vx, ballPos.vy, ballPos.vz);
	textPrintf("Ball  Height= %d\n",getHeightAt(ballPos.vx, ballPos.vy, ballPos.vz) );
	textPrintf("Glove Height= %d\n",getHeightAt(glovePos.vx, glovePos.vy, glovePos.vz) );
	textPrintf("Camera angle= %d\n",CamVars.angle);
	textPrintf("Glove angle = %d\n",GloveCtrl.direction);
#endif

	if (
		((debounce[0]&PAD_START) || (padData.present[0] == PADTYPE_NONE))
		&& gameCtrl.state!=FALSE
		&& gameCtrl.gameActive == TRUE
		&& GloveCtrl.health && BallCtrl.health && !BallCtrl.ballSmashed)
	{
		pauseBegin();	// sets gameActive = false, so won't get repeatedly called
	}

//	if (gameCtrl.MrTipActive && gameCtrl.gameActive!=FALSE)
	if (gameCtrl.MrTipActive)
	{
		tipDisplay();
		renderWorld();
	}
	else if (gameCtrl.PauseActive)
	{
		pauseDisplay();
		renderWorld();	// having this inside the pausedisplay caused stack shortage
		if (level==CARNIVALBONUS) caBonusDisplay();
	}
//	else if (gameCtrl.gameActive==TRUE && gameCtrl.MrTipActive==FALSE)
	else if (gameCtrl.gameActive==TRUE)
	{
		//UpdateCamera(TRUE);
		//UpdateCamera(FALSE);

		TIMER_STOP(TIMER_BALLGLOVE);
		TIMER_START(TIMER_CAMERA);

		
		if ( level==CARNIVALBONUS )
		{
			HandOnCannon();
			if (gameCtrl.dropOutFlag==GAME_COMPLETED)
			{
				DB("fin ca bonus\n");
				pBallPSA->world.rotate.vx=0;
				pBallPSA->world.rotate.vy=0;
				pBallPSA->world.rotate.vz=0;
			}
		}
		else if ( level!=FEARBONUS && level != PREHISTORICBONUS)
		{
			
			if(GloveCtrl.enabled)
						Control_Glove();
			UpdateOverlays();
		
			if(lightningIsModelInRange(&ballPos, BallBehaviour[BallCtrl.type].radius) && !GloveCtrl.deathType)
			{
				//DB("Hurt Ball!\n");
				GloveCtrl.hurtFlagBall=TRUE;
				GloveCtrl.deathTypeBall=DEADFROMBALLBURST;
			}

			if(lightningIsModelInRange(&glovePos, GloveBehaviour.radius) && !GloveCtrl.deathType)
			{
				//DB("Hurt Glove!\n");
				GloveCtrl.hurtFlag=TRUE;
				GloveCtrl.deathType=HURTFALL;
			}

			UpdateBallAndGlove();
			//UpdateBallAndGlove();
			TIMER_STOP(TIMER_CAMERA);
			TIMER_START(TIMER_BALLGLOVE);
		}
		else
		{
			standAloneBall();
			UpdateOverlays();
			//UpdateBallPos();
		}


		if ( level==CARNIVALBONUS )
		{
			carnivalBonusCamera();
		}
		else if (level == CARNIVALBOSS && !cameo_running)
		{
			CarnivalBossCamera();
		}
		else if (level == SPACEBOSS2 && !cameo_running)
		{
			SpaceBossCamera();
		}
  		else if (level == FEARBOSS && !cameo_running)
		{
			FearBossCamera();
		}
  		else if (level == WAYROOM)
		{
			WayroomCamera();
		}
		else
		{
			UpdateCamera(TRUE);
			UpdateCamera(FALSE);
		}



		//if(BallCtrl.hurt)
		//	doBallHurt();
		renderWorld();
	}
}




/****************************************************************************************************/
/****************************************************************************************************/
/****************************************************************************************************/
void	UpdateOverlays(void)
{
	ULONG	loop;
	int l;

	if(GloveCtrl.lives>=128)	// must have wrapped round to -1 (255)
	{
		l=sprintf(lifePtr->message, "%d", 0);
	}
	else
	{
		if(GloveCtrl.lives>=100)
			GloveCtrl.lives=100;

		l=sprintf(lifePtr->message, "%d", GloveCtrl.lives);
	}

	// Why not just plot the lives with right justification on ???

	//if (GloveCtrl.lives<128)
	//else
	//	l=sprintf(lifePtr->message, "%d",0);

	//l=sprintf(lifePtr->message, "%d", GloveCtrl.lives);

	lifePtr->x = 410 - l * 16;
	//lifePtr->message[0]=48+GloveCtrl.lives;

	if (GloveCtrl.currentDisplayedHealth!=GloveCtrl.maxHealth)
	{
		GloveCtrl.currentDisplayedHealth=GloveCtrl.maxHealth;
#if PALMODE==YES
		overlaySetupAndAdd(ovlHealth+GloveCtrl.maxHealth-1, textureFindInAllBanks("HEALTH01"), 32+((GloveCtrl.maxHealth-1)*24), 232, 0, 0);
#else
		overlaySetupAndAdd(ovlHealth+GloveCtrl.maxHealth-1, textureFindInAllBanks("HEALTH01"), 32+((GloveCtrl.maxHealth-1)*24), 232-8, 0, 0);
#endif
		GloveCtrl.health = GloveCtrl.maxHealth;
		GloveCtrl.healthChange = TRUE;
	}


/*
	for(i=0; i<GloveCtrl.health; i++)
	//for(i=0; i<14; i++)	// now possable to put health meter up to 14
	{
#if PALMODE==YES
		overlaySetupAndAdd(ovlHealth+i, textureFindInAllBanks("HEALTH01"), 32+(i*24), 232, 0, 0);
#else
		overlaySetupAndAdd(ovlHealth+i, textureFindInAllBanks("HEALTH01"), 32+(i*24), 232-8, 0, 0);
#endif
	}
*/

	
	if (GloveCtrl.healthChange)
	{
		l=GloveCtrl.health;
		for (loop=0;loop<GloveCtrl.maxHealth;loop++)
		{
			if (l>loop)
				ovlHealth[loop].texture=textureFindInAllBanks("HEALTH01");
			else
				ovlHealth[loop].texture=textureFindInAllBanks("HEALTH02");
		}
		GloveCtrl.healthChange = FALSE;
	}



}

/****************************************************************************************************/
/****************************************************************************************************/
/****************************************************************************************************/
//long	tiptoe=4096/7;
//long	walk=4048/(RUNSPEED);
//long	run=4048/(RUNSPEED);

int		offsetangle=1536;


void	UpdateBallAndGlove()
{

	VECTOR	tempVect;
	SHORT	leftRight,upDown;
	LONG	targetAngle,temp;
	VECTOR	tempV;
	USHORT	padIn;

	if(!GloveCtrl.enabled)
		return;


	if ( GloveCtrl.forceSlide && (GloveCtrl.action!=HAND_IDLE && GloveCtrl.action!=HAND_WALK && GloveCtrl.action!=HAND_SKIDDING 
	&& GloveCtrl.action!=HAND_JUMP && GloveCtrl.action!=HAND_PUSH) /*&& !GloveCtrl.onIce*/)
	{
		GloveCtrl.forceSlide=0;
		GloveCtrl.active=TRUE;
		GloveCtrl.forceSlideDelay=0;
	}


	if (GloveCtrl.active && GloveCtrl.disableTimer==0 && !GloveCtrl.padDisableTimer && CamVars.mode!=ZOOM)
	{
		leftRight=(nleftx[0]);
		upDown=-(nlefty[0]);
		padIn=pad[0];

		tempV.vx=leftRight;
		tempV.vz=upDown;
		tempV.vy=0;

		temp=Magnitude(&tempV);

		if (temp>4096) temp=4096;

		//DB ("input states before leftRight %d upDown %d\n",leftRight,upDown);

		if (temp<3072)
		{
			SCALEVECTOR(&tempV,(temp-(temp/2)) );
		}
		else
		{
			SCALEVECTOR(&tempV,( temp-((4096-temp)/2) ) );
		}
		leftRight=tempV.vx;
		upDown=tempV.vz;

		//DB ("input states after leftRight %d upDown %d\n",leftRight,upDown);

		// need to mask off camera buttons
		padIn=padIn&(~PAD_L1);
		padIn=padIn&(~PAD_R1);

		if (gameInfo.keyRecordFlag==RECORD)
		{
			padIn=keyRecord[keyRecordCount];
			padIn=padIn&(~PAD_L1);
			padIn=padIn&(~PAD_R1);
			leftRight=0;
			upDown=0;

			if (padIn&PAD_LEFT) leftRight=-4096;
			if (padIn&PAD_RIGHT) leftRight=4096;
			if (padIn&PAD_UP) upDown=4096;
			if (padIn&PAD_DOWN) upDown=-4096;
		}

		if (gameInfo.keyRecordFlag==PLAYBACK)
		{
			if (gameInfo.keyRecordFlag==PLAYBACK)
			{
				padIn=keyRecord[keyRecordCount];
				padIn=padIn&(~PAD_L1);
				padIn=padIn&(~PAD_R1);
				leftRight=0;
				upDown=0;
				if (padIn&PAD_LEFT) leftRight=-4096;
				if (padIn&PAD_RIGHT) leftRight=4096;
				if (padIn&PAD_UP) upDown=4096;
				if (padIn&PAD_DOWN) upDown=-4096;
			}
			//keyRecordCount++;
		}
	}
	else
	{	
		GloveCtrl.idleTimer=0;
		leftRight=0;
		upDown=0;
		padIn=0;
	}

	if (gameInfo.keyRecordFlag==PLAYBACK || gameInfo.keyRecordFlag==RECORD) keyRecordCount++;

	if (GloveCtrl.preDelay)
	{
		GloveCtrl.preDelay--;
		pGlovePSA->world.rotate.vy=GloveCtrl.direction;

		//ballVel.vy-=BallBehaviour[BallCtrl.type].gravity;
		//ADDVECTOR(&ballPos, &ballPos, &ballVel);
		//ballPos.vy-=(ballVel.vy*2);

		UpdateBallPos();
		TIMER_STOP(TIMER_COLLISION);

		//printf ("pre delay\n");
		UpdateGlovePos();
		pBallPSA->position.vx=ballPos.vx/4096;
		pBallPSA->position.vy=ballPos.vy/4096;
		pBallPSA->position.vz=ballPos.vz/4096;

		HandCollision();

		pGlovePSA->position.vx=glovePos.vx/4096;
		pGlovePSA->position.vy=glovePos.vy/4096;
		pGlovePSA->position.vz=glovePos.vz/4096;

		return;
	}

	switch (GloveCtrl.action)
	{

		case HAND_LEVELCOMPLETE:

			if (Glover.currentAnimation==HANDANIM_IDLE)
			{
				DB("finished level\n");
				gameCtrl.dropOutFlag=GAME_COMPLETED;
			}

			pGlovePSA->world.rotate.vy=GloveCtrl.direction;
			//if (GloveCtrl.lastAction!=HAND_JOINED)
			//	moveBall(0,0);

			//COPYVECTOR(&GloveCtrl.move,&glovePos);
			HandCollision();

			break;

		case HAND_ALLGARIBS:
			//printf ("HAND_ALLGRARIBS:\n");
			moveBall(0,0);
			gloveVel.vx=0;
			gloveVel.vz=0;
			pGlovePSA->world.rotate.vx=0;
			//pGlovePSA->world.rotate.vy=0;
			pGlovePSA->world.rotate.vz=0;
			gloveVel.vy-=gravity;
			ADDVECTOR(&glovePos, &glovePos, &gloveVel);
			glovePos.vy-=(gloveVel.vy*2);

			if (Glover.currentAnimation!=HANDANIM_OKAY) GloveCtrl.action=HAND_IDLE;

			HandCollision();

			break;



		case HAND_HURT:
			moveBall(0,0);

			//gloveVel.vy-=GRAVITY;
			//ADDVECTOR(&glovePos, &glovePos, &gloveVel);
			//glovePos.vy-=(gloveVel.vy*2);
			//printf ("hand hurt\n");
			UpdateGlovePos();
			HandCollision();

			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;
			break;

		case HAND_SLAM:
			moveBall(0,0);
			//printf ("hand slam \n");
			//if (GloveCtrl.actionTime==0) gloveVel.vy=SLAMSPEED/10;
			//if (GloveCtrl.actionTime>=5 && GloveCtrl.actionTime<=15) gloveVel.vy-=SLAMSPEED/5;
			if (GloveCtrl.actionTime<3)
			{
				gloveVel.vy=0;
			}
			else if (GloveCtrl.actionTime<7)
			{
				gloveVel.vy=-(SLAMSPEED/(7-GloveCtrl.actionTime));
			}
			else gloveVel.vy=-SLAMSPEED;

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

			HandCollision();
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;


			break;

/*
		case HAND_SWISH:
			moveBall(0,0);
			
			//tempV.vx=abs(leftRight);
			//tempV.vy=abs(upDown);
			//tempV.vz=0;
			//temp=Magnitude(&tempV);
			temp=Magnitude2D_S(leftRight,upDown);
			
			
			if (temp>4096) temp=4096;

			if (temp>4000) tempVect.vz=SWISHRUNSPEED;
			else tempVect.vz=SWISHWALKSPEED;

			if (GloveCtrl.mount->animinfo.num == NMEANIM_ACTION1) tempVect.vz=0;

			if (temp)
			{
				temp=calc_angle( leftRight,upDown );
				targetAngle=(temp+CamVars.angle)&4095;
				temp = findShortestAngle(GloveCtrl.direction,targetAngle);

				if (temp>0)
				{
					if ( temp>(ROTATESPEED/2) ) GloveCtrl.direction-=(ROTATESPEED/2);
					else GloveCtrl.direction=targetAngle;
				}
				else if (temp<0)
				{
					if ( temp<-(ROTATESPEED/2) ) GloveCtrl.direction+=(ROTATESPEED/2);
					else GloveCtrl.direction=targetAngle;
				}
				GloveCtrl.direction&=4095;

				//gloveVel.vz=-(rcos(GloveCtrl.direction)*CRAWLSPEED);
				//gloveVel.vx=-(rsin(GloveCtrl.direction)*CRAWLSPEED);
			}

			GloveCtrl.mount->psa->world.rotate.vy=GloveCtrl.direction;
			GloveCtrl.mount->ya=GloveCtrl.direction;

			SwishVel.vx-=SwishVel.vx/2;
			SwishVel.vz-=SwishVel.vz/2;

			if ( GloveCtrl.dennisJumpHit )
			{
				printf ("starting attack \n");
				AddToQueue(&GloveCtrl.mount->anim,NMEANIM_ACTION1,NO,NO,4096);
				AddToQueue(&GloveCtrl.mount->anim,NMEANIM_WALK,YES,YES,4096);
			}
			//SwishVel.vy=0;

			SwishVel.vx=0;
			SwishVel.vy=0;
			SwishVel.vz=0;

			tempVect.vy=0;
			tempVect.vx=0;
			RotateVector2D(&tempVect,&tempVect,GloveCtrl.direction );
			SwishVel.vx+=tempVect.vx;
			SwishVel.vz+=tempVect.vz;

			//GloveCtrl.mount->psa->world.rotate.vy=(GloveCtrl.mount->psa->world.rotate.vy+2048)&4095;
			GloveCtrl.mount->psa->world.rotate.vx=0;
			GloveCtrl.mount->psa->world.rotate.vy=0;			
			GloveCtrl.mount->psa->world.rotate.vz=0;

			objectSetAnimation(GloveCtrl.mount->psa, animate(&GloveCtrl.mount->anim));
			objectCalcWorldMatrix(GloveCtrl.mount->psa, &GloveCtrl.mount->psa->world);
			MatrixNormal(&GloveCtrl.mount->psa->world.child->matrix,&GloveCtrl.matrix);

			//RotMatrixY( -(GloveCtrl.direction )&4095 ,&GloveCtrl.matrix);
			TransposeMatrix(&GloveCtrl.matrix,&GloveCtrl.matrix);
			RotMatrixY( (GloveCtrl.direction )&4095 ,&GloveCtrl.matrix);

			glovePos.vx=GloveCtrl.mount->pos.vx;//+GloveCtrl.mount->psa->world.child->matrix.t[0]*409;
			glovePos.vy=GloveCtrl.mount->pos.vy;//+GloveCtrl.mount->psa->world.child->matrix.t[1]*409;
			glovePos.vz=GloveCtrl.mount->pos.vz;//+GloveCtrl.mount->psa->world.child->matrix.t[2]*409;

			SwishPos.vx+=SwishVel.vx;
			SwishPos.vz+=SwishVel.vz;

			GloveCtrl.mount->pos.vx=SwishPos.vx;
			GloveCtrl.mount->pos.vy=SwishPos.vy;
			GloveCtrl.mount->pos.vz=SwishPos.vz;
			
			//pGlovePSA->world.rotate.vy=GloveCtrl.direction;
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			break;
*/

		case HAND_HOPPING:
			//printf ("doing dennis\n");
			moveBall(0,0);

			//tempV.vx=abs(leftRight);
			//tempV.vy=abs(upDown);
			//tempV.vz=0;
			//temp=Magnitude(&tempV);
			temp=Magnitude2D_S(leftRight,upDown);

			if (temp>4096) temp=4096;
			//GloveCtrl.targetSpeed=(TOPSPEED*temp)/4096;
			pGlovePSA->world.rotate.vz=0;

			if (GloveCtrl.onGround)
			{
				GloveCtrl.speed=FALSE;
				if (GloveCtrl.dennisJumpHit || GloveCtrl.dennisJump) // jump pressed
				{
					if (!GloveCtrl.dennisJump)
					{
						AddToQueue(&GloveCtrl.mount->anim,NMEANIM_SPECIAL1,NO,NO,2048);
						AddToQueue(&GloveCtrl.mount->anim,NMEANIM_JUMP,NO,YES,2048);
						GloveCtrl.dennisJump=TRUE;
					}
					else
					{
						temp=GloveCtrl.mount->anim.animInfo->frame;
						temp+=GloveCtrl.mount->anim.animInfo->segInfo[GloveCtrl.mount->anim.currentAnimation].segStart;
//						printf ("frame %d\n",temp);
						if (temp>=61)
						{
							if (temp)
							{
								GloveCtrl.speed=TRUE;
								tempVect.vz = -temp*DENNISMOVESPEED;
								tempVect.vy=0;
								tempVect.vx=0;
								RotateVector2D(&tempVect, &tempVect,GloveCtrl.direction );
								DennisVel.vx = tempVect.vx;
								DennisVel.vz = tempVect.vz;
							}
							else GloveCtrl.speed=FALSE;

// Fred note - dennis's yvel's +ve downwards
							DennisVel.vy = -(20*4096+(GloveCtrl.dennisBounceCount*4096*3));
							if ( GloveCtrl.dennisBounceCount<6 ) GloveCtrl.dennisBounceCount++;
							GloveCtrl.dennisJumpHit=FALSE;
							GloveCtrl.dennisJump=FALSE;
						}
					}
				}
				else
				{
					GloveCtrl.dennisBounceCount=0;
				}
				/*if (GloveCtrl.ballHit) // jump pressed
				{
					DennisVel.vy=(20*4096+(GloveCtrl.dennisBounceCount*4096*3));
					GloveCtrl.dennisBounceCount++;
					GloveCtrl.ballHit=0;
				}
				else GloveCtrl.dennisBounceCount=0;
				*/
			}
			else
			{
				if (temp)
				{
					GloveCtrl.speed=TRUE;
					tempVect.vz = -(temp*DENNISMOVESPEED)/10;
					tempVect.vy=0;
					tempVect.vx=0;
					RotateVector2D(&tempVect, &tempVect,GloveCtrl.direction );
					DennisVel.vx += tempVect.vx;
					DennisVel.vz += tempVect.vz;
				}

				tempVect.vy=DennisVel.vy;
				DennisVel.vy=0;
//				if ( Magnitude(&DennisVel)>(4096*DENNISMOVESPEED) )
				if ( Magnitude2D(DennisVel.vx,DennisVel.vz)>(4096*DENNISMOVESPEED) )
				{
					SCALEVECTOR( &DennisVel,(DENNISMOVESPEED) );
				}
				DennisVel.vy=tempVect.vy;
				//if (GloveCtrl.ballHit) // jump pressed
				//{
				//	DennisVel.vy=(20*4096+(GloveCtrl.dennisBounceCount*4096*3));
				//	GloveCtrl.dennisBounceCount++;
				//	GloveCtrl.ballHit=0;
				//}
				//else GloveCtrl.dennisBounceCount=0;
			}



			//HandCollision();
			//temp=Magnitude(&tempV);
			if (temp>4096) temp=4096;
			if (temp)
			{
				temp=calc_angle( leftRight,upDown );
				targetAngle=(temp+CamVars.angle)&4095;
				temp = findShortestAngle(GloveCtrl.direction,targetAngle);

				if (temp>0)
				{
					if ( temp>ROTATESPEED ) GloveCtrl.direction-=ROTATESPEED;
					else GloveCtrl.direction=targetAngle;
				}
				else if (temp<0)
				{
					if ( temp<-ROTATESPEED ) GloveCtrl.direction+=ROTATESPEED;
					else GloveCtrl.direction=targetAngle;
				}
				GloveCtrl.direction&=4095;
				//gloveVel.vz=-(rcos(GloveCtrl.direction)*CRAWLSPEED);
				//gloveVel.vx=-(rsin(GloveCtrl.direction)*CRAWLSPEED);
			}

			GloveCtrl.mount->psa->world.rotate.vy=GloveCtrl.direction;
			GloveCtrl.mount->ya=GloveCtrl.direction;
			
			pGlovePSA->world.rotate.vy=GloveCtrl.direction;
			pGlovePSA->world.rotate.vy=GloveCtrl.direction;
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			break;



		case HAND_FALLING:
			moveBall(0,0);
			//gloveVel.vy-=GRAVITY;
			//ADDVECTOR(&glovePos, &glovePos, &gloveVel);
			//glovePos.vy-=(gloveVel.vy*2);
			//printf ("hand falling\n");
			UpdateGlovePos();
			HandCollision();

			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;
			break;

		case HAND_CLING:
			gloveVel.vx=gloveVel.vy=gloveVel.vz=0;
			if (GloveCtrl.disableTimer) break;


			break;
		case HAND_CATCH:

			//tempV.vx=abs(leftRight);
			//tempV.vy=abs(upDown);
			//tempV.vz=0;
			//temp=Magnitude(&tempV);
			temp=Magnitude2D_S(leftRight,upDown);
			
			if (temp>4096) temp=4096;
			GloveCtrl.targetSpeed=(TOPSPEED*temp)/4096;
			pGlovePSA->world.rotate.vz=0;

			if (temp)
			{
				temp=calc_angle( leftRight,upDown );
				targetAngle=(temp+CamVars.angle)&4095;
				temp = findShortestAngle(GloveCtrl.direction,targetAngle);

				if (temp>0)
				{
					if ( temp>ROTATESPEED )
					{
						GloveCtrl.direction-=ROTATESPEED;
						if (GloveCtrl.action==HAND_WALK) pGlovePSA->world.rotate.vz = (LEANANGLE*GloveCtrl.speed)/TOPSPEED;
					}
					else 
					{
						GloveCtrl.direction=targetAngle;
						if (GloveCtrl.action==HAND_WALK) pGlovePSA->world.rotate.vz =  (((temp*LEANANGLE)/ROTATESPEED)*GloveCtrl.speed)/TOPSPEED;
						//(( (temp*4096)/ROTATESPEED )*LEANANGLE)/4096;
					}
				}
				else if (temp<0)
				{
					if ( temp<-ROTATESPEED )
					{
						GloveCtrl.direction+=ROTATESPEED;
						if (GloveCtrl.action==HAND_WALK) pGlovePSA->world.rotate.vz = -(LEANANGLE*GloveCtrl.speed)/TOPSPEED;
					}
					else 
					{
						GloveCtrl.direction=targetAngle;
						if (GloveCtrl.action==HAND_WALK) pGlovePSA->world.rotate.vz = - (((temp*LEANANGLE)/ROTATESPEED)*GloveCtrl.speed)/TOPSPEED;
					}
				}
			
			}

			GloveCtrl.oldSpeed=GloveCtrl.speed;
			if (GloveCtrl.speed<GloveCtrl.targetSpeed)
			{
				if ( GloveCtrl.speed<(GloveCtrl.targetSpeed+(GloveBehaviour.accel/4096)) ) 
					GloveCtrl.speed+=GloveBehaviour.accel/4096;
				else 
					GloveCtrl.speed=GloveCtrl.targetSpeed;
			}
			else if (GloveCtrl.speed>GloveCtrl.targetSpeed)
			{
				if ( GloveCtrl.speed>(GloveCtrl.targetSpeed+(GloveBehaviour.accel/4096)) )
					GloveCtrl.speed-=GloveBehaviour.accel/4096;
				else 
					GloveCtrl.speed=GloveCtrl.targetSpeed;
			}
			GloveCtrl.direction&=4095;
			pGlovePSA->world.rotate.vy=GloveCtrl.direction;

			gloveVel.vz=-(rcos(GloveCtrl.direction)*GloveCtrl.speed)/16;
			gloveVel.vx=-(rsin(GloveCtrl.direction)*GloveCtrl.speed)/16;
			// now need to set anim speed
			if (GloveCtrl.flags&GLOVEMOVE)
			{
				gloveVel.vy-=gravity;
				ADDVECTOR(&glovePos, &glovePos, &gloveVel);
				glovePos.vy-=(gloveVel.vy*2);
			}
			moveBall(0,0);

			HandCollision();

			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			break;

		case HAND_BALLWALK:
//			moveBall(upDown,leftRight);

			//printf ("hand ballwalk\n");

			gloveVel.vx=ballVel.vx;
			gloveVel.vz=ballVel.vz;

			glovePos.vx=ballPos.vx;
			glovePos.vz=ballPos.vz;			

			//if ( (ballVel.vy>gloveVel.vy) /*&& ballVel.vy>(-3*4096)*/) gloveVel.vy=ballVel.vy;
			//else gloveVel.vy=0;
			gloveVel.vy=ballVel.vy;

			glovePos.vy=ballPos.vy-(( (GloveBehaviour.radius+BallBehaviour[BallCtrl.type].radius)*4000)/4296);

			gloveVel.vy-=GloveBehaviour.gravity;
			ADDVECTOR(&glovePos, &glovePos, &gloveVel);
			glovePos.vy-=(gloveVel.vy*2);

			//glovePos.vy=ballPos.vy-(GloveBehaviour.radius+BallBehaviour[BallCtrl.type].radius);

			//gloveVel.vy=ballVel.vy;
			
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			HandCollision();

			//pGlovePSA->position.vx=glovePos.vx/4096;
			//pGlovePSA->position.vy=glovePos.vy/4096;
			//pGlovePSA->position.vz=glovePos.vz/4096;

			moveBall(upDown,leftRight);

			//tempV.vx=ballVel.vx;
			//tempV.vy=0;
			//tempV.vz=ballVel.vz;
			//temp=Magnitude(&tempV);
			temp=Magnitude2D(ballVel.vx,ballVel.vz);
			
			if (temp<512) temp=0;
			if (temp==0 && GloveCtrl.currentAnim!=HANDANIM_IDLE)
			{
				AddToQueue(&Glover,HANDANIM_BALLWALK2IDLE,NO,NO,2048);
				AddToQueue(&Glover,HANDANIM_IDLE,YES,YES,2048);
				GloveCtrl.currentAnim=HANDANIM_IDLE;
			}
			else if ( temp<(42959/2) && temp!=0 ) // ball physics need looking at
			{
				if (GloveCtrl.currentAnim!=HANDANIM_BALLWALK)
					AddToQueue(&Glover,HANDANIM_BALLWALK,YES,NO,2048);
				GloveCtrl.currentAnim=HANDANIM_BALLWALK;

			}
			else if ( temp>=(42959/2) )
			{
				if (GloveCtrl.currentAnim!=HANDANIM_BALLWALK2)
					AddToQueue(&Glover,HANDANIM_BALLWALK2,YES,NO,2048);
				GloveCtrl.currentAnim=HANDANIM_BALLWALK2;
			}
			break;


		case HAND_CLIMBDOWN:
			
			moveBall(0,0);
			//ballVel.vy-=BallBehaviour[BallCtrl.type].gravity;
			//ADDVECTOR(&ballPos, &ballPos, &ballVel);
			//ballPos.vy-=(ballVel.vy*2);

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

			gloveVel.vx=0;
			gloveVel.vy=0;
			gloveVel.vz=0;

			if (padIn&PAD_L2) 
			{	// Make hand move forewards
				AddToQueue(&Glover,HANDANIM_SITUP,NO,NO,4096);
				AddToQueue(&Glover,HANDANIM_IDLE,YES,YES,2048);
				GloveCtrl.action=HAND_CLIMBUP;
				GloveCtrl.disableTimer=22;
				GloveCtrl.speed=16;

			}

			//if ( collboxCheckSphere(&ballColl) )
			//{
			//	BallCtrl.ballOnGround=TRUE;
			//	ActorStartRoll(pBallPSA,ballVel.vx,ballVel.vz);
			//}
			//else BallCtrl.ballOnGround=FALSE;

			if (leftRight || upDown || padIn)
			{
				AddToQueue(&Glover,HANDANIM_SITUP,NO,NO,4096);
				AddToQueue(&Glover,HANDANIM_IDLE,YES,YES,2048);
				GloveCtrl.action=HAND_CLIMBUP;
				GloveCtrl.disableTimer=22;
			}
			break;

		case HAND_CLIMBUP:
			// make glove turn
			if (GloveCtrl.disableTimer<10 && GloveCtrl.speed==0)
			{
				GloveCtrl.direction+=204;
				pGlovePSA->world.rotate.vy=GloveCtrl.direction;
				HandCollision();
				GloveCtrl.speed=0;
			}
			else
			{
				gloveVel.vz=-(rcos(GloveCtrl.direction)*GloveCtrl.speed)/16;
				gloveVel.vx=-(rsin(GloveCtrl.direction)*GloveCtrl.speed)/16;
				pGlovePSA->world.rotate.vy=GloveCtrl.direction;

				gloveVel.vy-=gravity;
				ADDVECTOR(&glovePos, &glovePos, &gloveVel);
				glovePos.vy-=(gloveVel.vy*2);

				pGlovePSA->position.vx=glovePos.vx/4096;
				pGlovePSA->position.vy=glovePos.vy/4096;
				pGlovePSA->position.vz=glovePos.vz/4096;

				HandCollision();
			}
			moveBall(0,0);
			//ballVel.vy-=BallBehaviour[BallCtrl.type].gravity;
			//ADDVECTOR(&ballPos, &ballPos, &ballVel);
			//ballPos.vy-=(ballVel.vy*2);

			//TIMER_START(TIMER_COLLISION);

			//if ( collboxCheckSphere(&ballColl) ) 
			//{
			//	BallCtrl.ballOnGround=TRUE;
			//	ActorStartRoll(pBallPSA,ballVel.vx,ballVel.vz);
			//}
			//else BallCtrl.ballOnGround=FALSE;
			//TIMER_STOP(TIMER_COLLISION);

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

			
			if (!GloveCtrl.disableTimer) GloveCtrl.action=HAND_IDLE;
			break;

		case HAND_CASTSPELL:
			pGlovePSA->world.rotate.vy=GloveCtrl.direction;
			if (GloveCtrl.lastAction!=HAND_JOINED)
				moveBall(0,0);

			//printf ("last action = %d \n",GloveCtrl.lastAction);
			//printf ("spell from ball = %d \n",GloveCtrl.spellCastOnBall);
			//COPYVECTOR(&GloveCtrl.move,&glovePos);
			if (GloveCtrl.spellCastOnBall)
			{
				//printf ("casting spell from on ball\n");
				glovePos.vy=ballPos.vy-(( (GloveBehaviour.radius+BallBehaviour[BallCtrl.type].radius)*4000)/4296);

				//gloveVel.vy-=GloveBehaviour.gravity;
				//ADDVECTOR(&glovePos, &glovePos, &gloveVel);
				//glovePos.vy-=(gloveVel.vy*2);

				pGlovePSA->position.vx=glovePos.vx/4096;
				pGlovePSA->position.vy=glovePos.vy/4096;
				pGlovePSA->position.vz=glovePos.vz/4096;
			}
			//else
			//	HandCollision();
			HandCollision();
			//ballVel.vy-=BallBehaviour[BallCtrl.type].gravity;
			//ADDVECTOR(&ballPos, &ballPos, &ballVel);
			//ballPos.vy-=(ballVel.vy*2);

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

			//if ( collboxCheckSphere(&ballColl) )
			//{
			//	BallCtrl.ballOnGround=TRUE;
			//	ActorStartRoll(pBallPSA,ballVel.vx,ballVel.vz);
			//}
			//else BallCtrl.ballOnGround=FALSE;
			break;

/*		case HAND_DUCK:

			gloveVel.vx=0;
			gloveVel.vz=0;

			//gloveVel.vy-=GRAVITY;
			//ADDVECTOR(&glovePos, &glovePos, &gloveVel);
			//glovePos.vy-=(gloveVel.vy*2);
			UpdateGlovePos();
			//pGlovePSA->position.vx=glovePos.vx/4096;
			//pGlovePSA->position.vy=glovePos.vy/4096;
			//pGlovePSA->position.vz=glovePos.vz/4096;

			moveBall(0,0);

			HandCollision();
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			break;
*/
/*
		case HAND_CRAWL:
			moveBall(0,0);
			gloveVel.vx=0;
			gloveVel.vz=0;

			if (GloveCtrl.onConveyer==XPOS) glovePos.vx+=(GloveCtrl.conveyerTimer*4096);
			if (GloveCtrl.onConveyer==XNEG) glovePos.vx-=(GloveCtrl.conveyerTimer*4096);
			if (GloveCtrl.onConveyer==ZPOS) glovePos.vz+=(GloveCtrl.conveyerTimer*4096);
			if (GloveCtrl.onConveyer==ZNEG) glovePos.vz-=(GloveCtrl.conveyerTimer*4096);

			if (leftRight || upDown)
			{
				ANIM_SPEED( Glover,2048 );
				if (Glover.animInfo->frame>=7) 
				{
					gloveVel.vy-=gravity;
					ADDVECTOR(&glovePos, &glovePos, &gloveVel);
					glovePos.vy-=(gloveVel.vy*2);

					HandCollision();
					pGlovePSA->position.vx=glovePos.vx/4096;
					pGlovePSA->position.vy=glovePos.vy/4096;
					pGlovePSA->position.vz=glovePos.vz/4096;
					break;
				}
				
				//tempV.vx=abs(leftRight);
				//tempV.vy=abs(upDown);
				//tempV.vz=0;
				//temp=Magnitude(&tempV);
				temp=Magnitude2D_S(leftRight,upDown);
				if (temp>4096) temp=4096;
				GloveCtrl.targetSpeed=(TOPSPEED*temp)/4096;
				pGlovePSA->world.rotate.vz=0;

				temp=calc_angle( leftRight,upDown );
				targetAngle=(temp+CamVars.angle)&4095;
				temp = findShortestAngle(GloveCtrl.direction,targetAngle);

				if (temp>0)
				{
					if ( temp>ROTATESPEED ) GloveCtrl.direction-=ROTATESPEED;
					else GloveCtrl.direction=targetAngle;
				}
				else if (temp<0)
				{
					if ( temp<-ROTATESPEED ) GloveCtrl.direction+=ROTATESPEED;
					else GloveCtrl.direction=targetAngle;
				}

				GloveCtrl.direction&=4095;
				gloveVel.vz=-(rcos(GloveCtrl.direction)*CRAWLSPEED);
				gloveVel.vx=-(rsin(GloveCtrl.direction)*CRAWLSPEED);

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

				//ballVel.vy-=BallBehaviour[BallCtrl.type].gravity;
				//ADDVECTOR(&ballPos, &ballPos, &ballVel);
				//ballPos.vy-=(ballVel.vy*2);

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

				//pGlovePSA->position.vx=glovePos.vx/4096;
				//pGlovePSA->position.vy=glovePos.vy/4096;
				//pGlovePSA->position.vz=glovePos.vz/4096;

				//if ( collboxCheckSphere(&ballColl) )
				//{
				//	BallCtrl.ballOnGround=TRUE;
				//	ActorStartRoll(pBallPSA,ballVel.vx,ballVel.vz);
				//}
				//else BallCtrl.ballOnGround=FALSE;

				//TIMER_START(TIMER_COLLISION);
				//collboxCheckSphere(&gloveColl);
				//collboxCheckSphere(&gloveColl);
				//TIMER_STOP(TIMER_COLLISION);
				//HandCollision();
			}
			else if (Glover.animInfo->frame>=11) AddToQueue(&Glover,HANDANIM_CRAWL,YES,NO,0);



			gloveVel.vy-=gravity;
			ADDVECTOR(&glovePos, &glovePos, &gloveVel);
			glovePos.vy-=(gloveVel.vy*2);

			//pGlovePSA->position.vx=glovePos.vx/4096;
			//pGlovePSA->position.vy=glovePos.vy/4096;
			//pGlovePSA->position.vz=glovePos.vz/4096;
			HandCollision();
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			break;
*/
/*		case HAND_CARTWHEEL:
			moveBall(0,0);
			if (GloveCtrl.actionTime>=5 && GloveCtrl.actionTime<=20) // move glove
			{
				//moveBall(0,0);
				tempVect.vz = -CARTWHEELSPEED*4096;
				tempVect.vy = 0;
				tempVect.vx = 0;
				RotateVector2D(&tempVect, &tempVect, GloveCtrl.direction );
				gloveVel.vx = tempVect.vx;
				gloveVel.vz = tempVect.vz;

				gloveVel.vy-=gravity;
				ADDVECTOR(&glovePos, &glovePos, &gloveVel);
				glovePos.vy-=(gloveVel.vy*2);

				//ballVel.vy-=BallBehaviour[BallCtrl.type].gravity;
				//ADDVECTOR(&ballPos, &ballPos, &ballVel);
				//ballPos.vy-=(ballVel.vy*2);

				//TIMER_START(TIMER_COLLISION);
				//if ( collboxCheckSphere(&ballColl) ) 
				//{
				//	BallCtrl.ballOnGround=TRUE;
				//	ActorStartRoll(pBallPSA,ballVel.vx,ballVel.vz);
				//}
				//else BallCtrl.ballOnGround=FALSE;
				//TIMER_STOP(TIMER_COLLISION);

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

				GloveCtrl.iceData.vx=gloveVel.vx;
				GloveCtrl.iceData.vz=gloveVel.vz;

				HandCollision();
				pGlovePSA->position.vx=glovePos.vx/4096;
				pGlovePSA->position.vy=glovePos.vy/4096;
				pGlovePSA->position.vz=glovePos.vz/4096;

			}
			break;
*/
		case HAND_WHACK:
			if (GloveCtrl.actionTime==0)
			{
				tempVect.vz = -BALLTHROWSPEED*2;
				tempVect.vx = 0;
				RotateVector2D(&tempVect, &tempVect,GloveCtrl.direction );	
				ballVel.vx = tempVect.vx;
				ballVel.vy = 9*4096;
				ballVel.vz = tempVect.vz;
				BallCtrl.anywhack = POWERWHACK_START;
				if(BallCtrl.type == BALL_MODE_BOWLING || cheat_any_ball_powerwhacks || 
				(BallCtrl.preSnowType == BALL_MODE_BOWLING && BallCtrl.snowAddition ) )
					BallCtrl.powerwhack = POWERWHACK_START;

				sfxPlay3D(globalFX,SFX_HAND_WHACKBALL,&glovePos);
			}

			moveBall(0,0);

			if (GloveCtrl.flags&GLOVEMOVE)
			{
				gloveVel.vy-=gravity;
				ADDVECTOR(&glovePos, &glovePos, &gloveVel);
				glovePos.vy-=(gloveVel.vy*2);
			}

			//ballVel.vy-=BallBehaviour[BallCtrl.type].gravity;
			//ADDVECTOR(&ballPos, &ballPos, &ballVel);
			//ballPos.vy-=(ballVel.vy*2);
/*
			TIMER_START(TIMER_COLLISION);

			if ( collboxCheckSphere(&ballColl) ) 
			{
				BallCtrl.ballOnGround=TRUE;
				ActorStartRoll(pBallPSA,ballVel.vx,ballVel.vz);
				BallApplySquash();
			}
			else BallCtrl.ballOnGround=FALSE;
			TIMER_STOP(TIMER_COLLISION);
			BallUpdateSquash();
*/
//			UpdateBallPos();
			//pBallPSA->position.vx=ballPos.vx/4096;
			//pBallPSA->position.vy=ballPos.vy/4096;
			//pBallPSA->position.vz=ballPos.vz/4096;

			//TIMER_START(TIMER_COLLISION);
			//collboxCheckSphere(&gloveColl);
			//collboxCheckSphere(&gloveColl);
			//TIMER_STOP(TIMER_COLLISION);
			HandCollision();
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			break;

		case HAND_PREWHACK:

			moveBall(0,0);

			temp=Magnitude2D_S(leftRight,upDown);

			if (temp)
			{
				temp=calc_angle( leftRight,upDown );
				targetAngle=(temp+CamVars.angle)&4095;
				temp = findShortestAngle(GloveCtrl.direction,targetAngle);
				if (temp>0)
				{
					if ( temp>ROTATESPEED ) GloveCtrl.direction-=ROTATESPEED;
					else GloveCtrl.direction=targetAngle;
				}
				else if (temp<0)
				{
					if ( temp<-ROTATESPEED ) GloveCtrl.direction+=ROTATESPEED;
					else GloveCtrl.direction=targetAngle;
				}
			}


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

			tempVect.vz = (BallBehaviour[BallCtrl.type].radius/2)+BallCtrl.ballSpeed;
			tempVect.vy=0;
			tempVect.vx=0;
			RotateVector2D(&tempVect, &tempVect,GloveCtrl.direction );

			glovePos.vx=ballPos.vx+tempVect.vx;
			glovePos.vz=ballPos.vz+tempVect.vz;			

			if (BallCtrl.onConveyer==XPOS) glovePos.vx+=(BallCtrl.conveyerTimer*4096);
			if (BallCtrl.onConveyer==XNEG) glovePos.vx-=(BallCtrl.conveyerTimer*4096);
			if (BallCtrl.onConveyer==ZPOS) glovePos.vz+=(BallCtrl.conveyerTimer*4096);
			if (BallCtrl.onConveyer==ZNEG) glovePos.vz-=(BallCtrl.conveyerTimer*4096);

			if (GloveCtrl.flags&GLOVEMOVE)
			{
				gloveVel.vy-=gravity;
				ADDVECTOR(&glovePos, &glovePos, &gloveVel);
				glovePos.vy-=(gloveVel.vy*2);
			}

			

			//if (BallCtrl.ballStopMove!=TRUE)
			//{
			//	ballVel.vy-=BallBehaviour[BallCtrl.type].gravity;
			//	ADDVECTOR(&ballPos, &ballPos, &ballVel);
			//	ballPos.vy-=(ballVel.vy*2);
			//}

			//TIMER_START(TIMER_COLLISION);

			//if ( collboxCheckSphere(&ballColl) ) 
			//{
			//	BallCtrl.ballOnGround=TRUE;
			//	ActorStartRoll(pBallPSA,ballVel.vx,ballVel.vz);
			//}
			//else BallCtrl.ballOnGround=FALSE;
			//TIMER_STOP(TIMER_COLLISION);

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

			//TIMER_START(TIMER_COLLISION);
			//collboxCheckSphere(&gloveColl);
			//collboxCheckSphere(&gloveColl);
			//TIMER_STOP(TIMER_COLLISION);
			HandCollision();
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			break;

		case HAND_THROW:
			if (GloveCtrl.throwDelay) // first time
			{
				GloveCtrl.throwDelay=FALSE;
				tempVect.vz = -BALLTHROWSPEED;
				ballVel.vy = GRAVITY*14;

				//tempVect.vz=0;
				//ballVel.vy=BallBehaviour[BallCtrl.type].gravity*30;	// These two line for testting only
				tempVect.vx = 0;
				RotateVector2D(&tempVect, &tempVect,GloveCtrl.direction );
				ballVel.vx = tempVect.vx;
				ballVel.vz = tempVect.vz;

				sfxPlay3D(globalFX,SFX_HAND_THROW_1 + (RANDOM256() & 1),&glovePos);

			}

			if (GloveCtrl.flags&GLOVEMOVE)
			{
				gloveVel.vy-=gravity;
				ADDVECTOR(&glovePos, &glovePos, &gloveVel);
				glovePos.vy-=(gloveVel.vy*2);
			}

			moveBall(0,0);
			//ballVel.vy-=BallBehaviour[BallCtrl.type].gravity;
			//ADDVECTOR(&ballPos, &ballPos, &ballVel);
			//ballPos.vy-=(ballVel.vy*2);

			//TIMER_START(TIMER_COLLISION);

			//if ( collboxCheckSphere(&ballColl) ) 
			//{
			//	BallCtrl.ballOnGround=TRUE;
			//	ActorStartRoll(pBallPSA,ballVel.vx,ballVel.vz);
			//}
			//else BallCtrl.ballOnGround=FALSE;
			//TIMER_STOP(TIMER_COLLISION);

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

			//TIMER_START(TIMER_COLLISION);
			//collboxCheckSphere(&gloveColl);
			//collboxCheckSphere(&gloveColl);
			//TIMER_STOP(TIMER_COLLISION);
			HandCollision();
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;
			break;

		case HAND_LOB:
			if (GloveCtrl.throwDelay) // first time
			{
				GloveCtrl.throwDelay=FALSE;
				tempVect.vz = LOBDISTANCE;
				ballVel.vy = LOBHEIGHT;
				tempVect.vx = 0;
				RotateVector2D(&tempVect, &tempVect,(GloveCtrl.direction+2048)&4095 );
				ballVel.vx = tempVect.vx;
				ballVel.vz = tempVect.vz;
			}

			if (GloveCtrl.flags&GLOVEMOVE)
			{
				gloveVel.vy-=gravity;
				ADDVECTOR(&glovePos, &glovePos, &gloveVel);
				glovePos.vy-=(gloveVel.vy*2);
			}

			moveBall(0,0);
			HandCollision();
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			break;

/*		case HAND_PUSH:
			//tempV.vx=abs(leftRight);
			//tempV.vy=abs(upDown);
			//tempV.vz=0;
			//temp=Magnitude(&tempV);
			tem=Magnitude2D_S(leftRight,UpDown);
			if (temp>4096) temp=4096;
			GloveCtrl.targetSpeed=(TOPSPEED*temp)/4096;
			pGlovePSA->world.rotate.vz=0;

			GloveCtrl.oldSpeed=GloveCtrl.speed;

			if (GloveCtrl.speed<GloveCtrl.targetSpeed)
			{
				if ( GloveCtrl.speed<(GloveCtrl.targetSpeed+( (4096*10)/4096)) ) 
					GloveCtrl.speed+=(4096*10)/4096;
				else 
					GloveCtrl.speed=GloveCtrl.targetSpeed;
			}
			else if (GloveCtrl.speed>GloveCtrl.targetSpeed)
			{
				if ( GloveCtrl.speed>(GloveCtrl.targetSpeed+((4096*10)/4096)) )
					GloveCtrl.speed-=(4096*10)/4096;
				else 
					GloveCtrl.speed=GloveCtrl.targetSpeed;
			}

			moveBall(0,0);
			UpdateGlovePos();
			HandCollision();
			break;
*/
		case HAND_PUSH:
		case HAND_IDLE:
		case HAND_WALK:
		case HAND_SKIDDING:
		case HAND_JUMP:

			if (GloveCtrl.forceSlide )
			{
				//if (GloveCtrl.action!=HAND_SKIDDING)
				//{
					GloveCtrl.action=HAND_SKIDDING;
					GloveCtrl.direction=calc_angle( GloveCtrl.slideData.vx,GloveCtrl.slideData.vz );
					//GloveCtrl.active=FALSE;
					//GloveBehaviour.accel=4096*8;
					GloveBehaviour.accel=0;
					//if (GloveCtrl.forceSlide) GloveCtrl.forceSlideDelay=1;
					//GloveCtrl.forceSlideDelay++;
					GloveCtrl.speed=72;
				//}
				if (GloveCtrl.forceSlide) GloveCtrl.forceSlideDelay=1;
			}
			if (GloveCtrl.forceSlideDelay) GloveCtrl.forceSlideDelay++;
			if (GloveCtrl.forceSlideDelay>5)
			{
				GloveCtrl.action=HAND_SKIDDING;
				GloveBehaviour.accel=4096*14;
				GloveCtrl.forceSlideDelay=0;
				GloveCtrl.active=TRUE;
			}
			if (GloveCtrl.action==HAND_SKIDDING)
			{
				leftRight=0;
				upDown=0;
			}

			
			tempV.vx=abs(leftRight);
			tempV.vy=abs(upDown);
			tempV.vz=0;
			temp=Magnitude(&tempV);
			if (temp>4096) temp=4096;
			GloveCtrl.targetSpeed=(TOPSPEED*temp)/4096;
			pGlovePSA->world.rotate.vz=0;

			if (temp)
			{
				temp=calc_angle( leftRight,upDown );
				targetAngle=(temp+CamVars.angle)&4095;
				temp = findShortestAngle(GloveCtrl.direction,targetAngle);
			}
			else
			{
				temp=0;
				targetAngle = GloveCtrl.direction;
			}

			if ( (abs(temp)>1536 && abs(temp)<2560) && GloveCtrl.speed>SKIDSPEED && GloveCtrl.action==HAND_WALK)
			{
				if (ActionAllowed(GloveCtrl.action,HAND_SKIDDING))
				{
					GloveCtrl.targetSpeed=0;	// stop glove if direction reversed
					GloveCtrl.action=HAND_SKIDDING;
					//GloveCtrl.active=FALSE;
					GloveBehaviour.accel=4096*8;
				}
			}
			else
			{
				if (temp>0)
				{
					if ( temp>ROTATESPEED )
					{
						GloveCtrl.direction-=ROTATESPEED;
						if (GloveCtrl.action==HAND_WALK) pGlovePSA->world.rotate.vz = (LEANANGLE*GloveCtrl.speed)/TOPSPEED;
					}
					else 
					{
						GloveCtrl.direction=targetAngle;
						if (GloveCtrl.action==HAND_WALK) pGlovePSA->world.rotate.vz =  (((temp*LEANANGLE)/ROTATESPEED)*GloveCtrl.speed)/TOPSPEED;
						//(( (temp*4096)/ROTATESPEED )*LEANANGLE)/4096;
					}
				}
				else if (temp<0)
				{
					if ( temp<-ROTATESPEED )
					{
						GloveCtrl.direction+=ROTATESPEED;
						if (GloveCtrl.action==HAND_WALK) pGlovePSA->world.rotate.vz = -(LEANANGLE*GloveCtrl.speed)/TOPSPEED;
					}
					else 
					{
						GloveCtrl.direction=targetAngle;
						if (GloveCtrl.action==HAND_WALK) pGlovePSA->world.rotate.vz = - (((temp*LEANANGLE)/ROTATESPEED)*GloveCtrl.speed)/TOPSPEED;
					}
				}
			}

			GloveCtrl.oldSpeed=GloveCtrl.speed;
			if (GloveCtrl.speed<GloveCtrl.targetSpeed)
			{
				if ( GloveCtrl.speed<(GloveCtrl.targetSpeed+(GloveBehaviour.accel/4096)) ) 
					GloveCtrl.speed+=GloveBehaviour.accel/4096;
				else 
					GloveCtrl.speed=GloveCtrl.targetSpeed;
			}
			else if (GloveCtrl.speed>GloveCtrl.targetSpeed)
			{
				if ( GloveCtrl.speed>(GloveCtrl.targetSpeed+(GloveBehaviour.accel/2048)) )
					GloveCtrl.speed-=GloveBehaviour.accel/2048;
				else 
					GloveCtrl.speed=GloveCtrl.targetSpeed;
			}
			GloveCtrl.direction&=4095;

			if (GloveCtrl.action!=HAND_PUSH) pGlovePSA->world.rotate.vy=GloveCtrl.direction;
			else pGlovePSA->world.rotate.vy=GloveCtrl.pushDirection;

			if(    GloveCtrl.action == HAND_PUSH
				&& GloveCtrl.pushingPlatform
				&& (((GloveCtrl.pushDirection - GloveCtrl.direction + 800) & 4095) < 1600)
				)
			{
// In the "nearby angle" check above, +512, cf 1024 was a bit small.
// (Having no check at all results in your being able to pull platforms as well as push them!)
				gloveVel.vz=-(rcos(GloveCtrl.pushDirection)*GloveCtrl.speed)/16;
				gloveVel.vx=-(rsin(GloveCtrl.pushDirection)*GloveCtrl.speed)/16;
			}
			else
			{
				GloveCtrl.pushingPlatform--;
// This is the code that was already here
				gloveVel.vz=-(rcos(GloveCtrl.direction)*GloveCtrl.speed)/16;
				gloveVel.vx=-(rsin(GloveCtrl.direction)*GloveCtrl.speed)/16;
			}
			// now need to set anim speed
			if (GloveCtrl.speed && GloveCtrl.action!=HAND_JUMP && GloveCtrl.action!=HAND_PUSH && !GloveCtrl.stopXZ)
			{
				if ( GloveCtrl.walkType==HANDWALK_TIPTOE )
				{
					ANIM_SPEED(Glover,(GloveCtrl.speed*650) );
				}
				else if ( GloveCtrl.walkType==HANDWALK_WALK )
				{
					ANIM_SPEED(Glover,(GloveCtrl.speed*136) );
				}
				else if ( GloveCtrl.walkType==HANDWALK_RUN )
				{
					ANIM_SPEED(Glover,(GloveCtrl.speed*58) );
				}

				

				/*
				if (GloveCtrl.speed<(TOPSPEED/2))
				{
					ANIM_SPEED(Glover,(GloveCtrl.speed*4048/(TOPSPEED/2)) );
				}
				
				else 
					ANIM_SPEED(Glover,(GloveCtrl.speed*1500/(TOPSPEED/2)) );

				ANIM_SPEED(Glover,2048 );
				*/
			}

			//if (GloveCtrl.stopXZ)
			//{
			//	GloveCtrl.speed=0;
			//	GloveCtrl.targetSpeed=0;
			//}

			if (GloveCtrl.flags&GLOVEMOVE)
			{
				//gloveVel.vy-=GRAVITY;
				//ADDVECTOR(&glovePos, &glovePos, &gloveVel);
				//glovePos.vy-=(gloveVel.vy*2);
				//printf ("run walk jump ect\n");
				UpdateGlovePos();
			}
			moveBall(0,0);

			//ballVel.vy-=BallBehaviour[BallCtrl.type].gravity;
			//ADDVECTOR(&ballPos, &ballPos, &ballVel);
			//ballPos.vy-=(ballVel.vy*2);

			//TIMER_START(TIMER_COLLISION);

			//if ( collboxCheckSphere(&ballColl) ) 
			//{
			//	BallCtrl.ballOnGround=TRUE;
			//	ActorStartRoll(pBallPSA,ballVel.vx,ballVel.vz);
			//}
			//else BallCtrl.ballOnGround=FALSE;
			//TIMER_STOP(TIMER_COLLISION);

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

			//pGlovePSA->position.vx=glovePos.vx/4096;
			//pGlovePSA->position.vy=glovePos.vy/4096;
			//pGlovePSA->position.vz=glovePos.vz/4096;

			//TIMER_START(TIMER_COLLISION);
			//collboxCheckSphere(&gloveColl);
			//collboxCheckSphere(&gloveColl);
			//TIMER_STOP(TIMER_COLLISION);
			HandCollision();
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			break;

		case HAND_LOCATE:

			moveBall(0,0);
			//ballVel.vy-=BallBehaviour[BallCtrl.type].gravity;
			//ADDVECTOR(&ballPos, &ballPos, &ballVel);
			//ballPos.vy-=(ballVel.vy*2);

			//if ( collboxCheckSphere(&ballColl) ) 
			//{
			//	BallCtrl.ballOnGround=TRUE;
			//	ActorStartRoll(pBallPSA,ballVel.vx,ballVel.vz);
			//}
			//else BallCtrl.ballOnGround=FALSE;

			//pBallPSA->position.vx=ballPos.vx/4096;
			//pBallPSA->position.vy=ballPos.vy/4096;
			//pBallPSA->position.vz=ballPos.vz/4096;
			if (GloveCtrl.onIce)
			{
				ADDVECTOR(&glovePos, &glovePos, &gloveVel);
				//gloveVel.vx=0;
				//gloveVel.vz=0;
				HandCollision();
				DB("vel x %d z %d pos %x z %d\n",(int)gloveVel.vx,(int)gloveVel.vz,(int)glovePos.vx,(int)glovePos.vz);
			}

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

			gloveVel.vx=0;
			gloveVel.vy=0;
			gloveVel.vz=0;

			HandCollision();
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			break;

		case HAND_THROWAIM:
		//case HAND_THROW2CUP:
			//if (GloveCtrl.flags==STOPGLOVEMOVE)
			//{	// put aim here
				tempV.vx=abs(leftRight);
				tempV.vy=abs(upDown);
				tempV.vz=0;
				temp=Magnitude(&tempV);

				if (temp)
				{
					temp=calc_angle( leftRight,upDown );
					targetAngle=(temp+CamVars.angle)&4095;
					temp = findShortestAngle(GloveCtrl.direction,targetAngle);
					if (temp>0)
					{
						if ( temp>ROTATESPEED ) GloveCtrl.direction-=ROTATESPEED;
						else GloveCtrl.direction=targetAngle;
					}
					else if (temp<0)
					{
						if ( temp<-ROTATESPEED ) GloveCtrl.direction+=ROTATESPEED;
						else GloveCtrl.direction=targetAngle;
					}
				}
			//}

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

			//glovePos.vx=ballPos.vx;
			//glovePos.vz=ballPos.vz;			

			tempVect.vz = BallBehaviour[BallCtrl.type].radius/2;
			tempVect.vy=0;
			tempVect.vx=0;
			RotateVector2D(&tempVect, &tempVect,GloveCtrl.direction );

			glovePos.vx = oldGlovePos.vx+tempVect.vx;//+gloveVel.vx;
			glovePos.vz = oldGlovePos.vz+tempVect.vz;//+gloveVel.vz;

			ballPos.vx=oldGlovePos.vx;
			ballPos.vz=oldGlovePos.vz;

			//if (GloveCtrl.flags&GLOVEMOVE)
			//{
			//	gloveVel.vy-=gravity;
			//	ADDVECTOR(&glovePos, &glovePos, &gloveVel);
			//	glovePos.vy-=(gloveVel.vy*2);
			//}

			//if (BallCtrl.ballStopMove!=TRUE)
			//{
			//	ballVel.vy-=BallBehaviour[BallCtrl.type].gravity;
			//	ADDVECTOR(&ballPos, &ballPos, &ballVel);
			//	ballPos.vy-=(ballVel.vy*2);
			//}
/*
			TIMER_START(TIMER_COLLISION);

			if ( collboxCheckSphere(&ballColl) ) 
			{
				BallCtrl.ballOnGround=TRUE;
				ActorStartRoll(pBallPSA,ballVel.vx,ballVel.vz);
				BallApplySquash();
			}
			else BallCtrl.ballOnGround=FALSE;
			TIMER_STOP(TIMER_COLLISION);
			BallUpdateSquash();
*/
			UpdateBallPos();
			pBallPSA->position.vx=ballPos.vx/4096;
			pBallPSA->position.vy=ballPos.vy/4096;
			pBallPSA->position.vz=ballPos.vz/4096;

			//TIMER_START(TIMER_COLLISION);
			//collboxCheckSphere(&gloveColl);
			//collboxCheckSphere(&gloveColl);
			//TIMER_STOP(TIMER_COLLISION);
			HandCollision();
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			break;


		case HAND_ROTOR:

			moveBall(0,0);
			tempV.vx=abs(leftRight);
			tempV.vy=abs(upDown);
			tempV.vz=0;

			temp=Magnitude(&tempV);


			if (temp>4096) temp=4096;

			if (temp)
			{
				temp=(calc_angle( leftRight,upDown ) &4095);
				targetAngle=(temp+CamVars.angle)&4095;
				temp = (findShortestAngle(GloveCtrl.direction,targetAngle) );
				//pGlovePSA->world.rotate.vz=512+1024;
				if (temp>0)
				{
					if ( temp>ROTATESPEED )	GloveCtrl.direction-=ROTATESPEED;
					else GloveCtrl.direction=targetAngle;
				}
				else if (temp<0)
				{
					if ( temp<-ROTATESPEED ) GloveCtrl.direction+=ROTATESPEED;
					else GloveCtrl.direction=targetAngle;
				}
			}

			temp=Magnitude(&tempV);
			if (temp>4096) temp=4096;

			GloveCtrl.targetSpeed=(TOPSPEED*temp)/4096;

			GloveCtrl.oldSpeed=GloveCtrl.speed;
			if (GloveCtrl.speed<GloveCtrl.targetSpeed)
			{
				if ( GloveCtrl.speed<(GloveCtrl.targetSpeed+(GloveBehaviour.accel/4096)) ) 
					GloveCtrl.speed+=GloveBehaviour.accel/4096;
				else
					GloveCtrl.speed=GloveCtrl.targetSpeed;
			}
			else if (GloveCtrl.speed>GloveCtrl.targetSpeed)
			{
				if ( GloveCtrl.speed>(GloveCtrl.targetSpeed+(GloveBehaviour.accel/4096)) )
					GloveCtrl.speed-=GloveBehaviour.accel/4096;
				else
					GloveCtrl.speed=GloveCtrl.targetSpeed;
			}
			GloveCtrl.direction&=4095;
			pGlovePSA->world.rotate.vy=GloveCtrl.direction;

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

			if (GloveCtrl.lastAction==HAND_JOINED)
			{
				gloveVel.vy-=GloveBehaviour.gravity;
				ADDVECTOR(&glovePos, &glovePos, &gloveVel);
				glovePos.vy-=(gloveVel.vy*2);

				if (BallCtrl.ballOnGround /*&& BallCtrl.inWaterFlag!=NOWHERENEARWATER*/)
				{
					//if ( (ballPos.vy-((BallBehaviour[BallCtrl.type].radius+GloveBehaviour.radius/2))) < glovePos.vy)
					//{
						glovePos.vy=ballPos.vy-((BallBehaviour[BallCtrl.type].radius+GloveBehaviour.radius/2));
						if (gloveVel.vy<0) gloveVel.vy=0;
					//}
					//else
					//{
					//	ballPos.vy=glovePos.vy+((BallBehaviour[BallCtrl.type].radius+GloveBehaviour.radius/2));
					//	BallCtrl.ballOnGround=FALSE;
					//}
				}
				else
				{
					ballPos.vy=glovePos.vy+((BallBehaviour[BallCtrl.type].radius+GloveBehaviour.radius/2));
				}
				//ballPos.vy=glovePos.vy+(BallBehaviour[BALL_MODE_NORMAL].radius);
				ballPos.vx=glovePos.vx;
				ballPos.vz=glovePos.vz;

				ballVel.vx=gloveVel.vx;
				ballVel.vy=gloveVel.vy;
				ballVel.vz=gloveVel.vz;
			}
			else if (BallCtrl.ballOnGround || BallCtrl.inWaterFlag!=NOWHERENEARWATER)
			{
				gloveVel.vy-=GloveBehaviour.gravity;
				ADDVECTOR(&glovePos, &glovePos, &gloveVel);
				glovePos.vy-=(gloveVel.vy*2);

				tempV.vx=glovePos.vx-ballPos.vx;
				tempV.vy=glovePos.vy-ballPos.vy;
				tempV.vz=glovePos.vz-ballPos.vz;
				temp=Magnitude(&tempV);
				if ( temp < (BallBehaviour[BallCtrl.type].radius+GloveBehaviour.radius) )
				{
					//printf ("%d \n",temp);
					if (glovePos.vx>ballPos.vx) glovePos.vx-=4096;
					else if (glovePos.vx<ballPos.vx) glovePos.vx+=4096;
					if (glovePos.vz>ballPos.vz) glovePos.vz-=4096;
					else if (glovePos.vz<ballPos.vz) glovePos.vz+=4096;

					if (glovePos.vy>ballPos.vy-(BallBehaviour[BallCtrl.type].radius+GloveBehaviour.radius/2))
					{
						glovePos.vy-=4096;
						if (gloveVel.vy<0) gloveVel.vy=0;
					}
					else if (glovePos.vy<ballPos.vy-(BallBehaviour[BallCtrl.type].radius+GloveBehaviour.radius/2))
						glovePos.vy+=4096;

					if ( (abs (glovePos.vx-ballPos.vx) < 3*4096) && (abs (glovePos.vz-ballPos.vz) < 3*4096) &&
					(abs (glovePos.vy-(ballPos.vy-(BallBehaviour[BallCtrl.type].radius+GloveBehaviour.radius/2))) < 3*4096) )
						GloveCtrl.lastAction=HAND_JOINED;

					//printf ( "%d \n",glovePos.vx-ballPos.vx);
					//printf ( "%d \n",glovePos.vz-ballPos.vz);
					//printf ( "%d \n",glovePos.vy-(ballPos.vy-(BallBehaviour[BallCtrl.type].radius+GloveBehaviour.radius/2)));

				}
			}
			else
			{
				gloveVel.vy-=GloveBehaviour.gravity;
				ADDVECTOR(&glovePos, &glovePos, &gloveVel);
				glovePos.vy-=(gloveVel.vy*2);
			}

			GloveCtrl.direction=GloveCtrl.direction&4095;

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

			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			HandCollision();
			//moveBall(0,0);
			break;

	
		case HAND_JOINED:	// need to focus control on ball


			moveBall(upDown,leftRight);
			gloveVel.vy=ballVel.vy; // new

			// could this be the problem ?
			if (GloveCtrl.lastAction!=HAND_BALLWALK || GloveCtrl.actionTime>5)
			{
				glovePos.vy=ballPos.vy; // new
			}
			else
			{
				glovePos.vy=(( ballPos.vy*GloveCtrl.actionTime ) + ( GloveCtrl.move.vy* (5-GloveCtrl.actionTime) ) )/5;
			}
			glovePos.vx=ballPos.vx;
			glovePos.vz=ballPos.vz;

			//tempV.vx=abs(leftRight);
			//tempV.vy=abs(upDown);
			//tempV.vz=0;
			//temp=Magnitude(&tempV);
			temp=Magnitude2D_S(leftRight,upDown);
			
			if (temp>4096) temp=4096;

			if (temp)
			{
				temp=(calc_angle( leftRight,upDown ) &4095);
				targetAngle=(temp+CamVars.angle)&4095;
				GloveCtrl.targetDirection=targetAngle;
			}
			else
			{
				targetAngle=GloveCtrl.targetDirection;
			}

			temp = (findShortestAngle(GloveCtrl.direction,targetAngle) );
			if (temp>0) GloveCtrl.direction-=temp/6;
			else if (temp<0) GloveCtrl.direction-=temp/6;

/*				if (temp>0)
				{
					if ( temp>ROTATESPEED/2 )	GloveCtrl.direction-=ROTATESPEED/2;
					else GloveCtrl.direction=targetAngle;
				}
				else if (temp<0)
				{
					if ( temp<-ROTATESPEED/2 ) GloveCtrl.direction+=ROTATESPEED/2;
					else GloveCtrl.direction=targetAngle;
				}
*/
//			}

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

			//printf ("rsin direction	%d direction %d \n",(rsin(GloveCtrl.direction)),GloveCtrl.direction);
			//printf ("rcos direction	%d direction %d \n",(rcos(GloveCtrl.direction)),GloveCtrl.direction);

			//tempVect.vz = BallBehaviour[BallCtrl.type].radius/2;
			if (GloveCtrl.lastAction!=HAND_BOUNCE)
			{
				tempVect.vz = BallBehaviour[BallCtrl.type].radius-GloveBehaviour.radius/3;
				//tempVect.vz = 8192*2;
				tempVect.vy=0;
				tempVect.vx=0;

				RotateVector2D(&tempVect, &tempVect,GloveCtrl.direction );
				glovePos.vx += tempVect.vx;
				glovePos.vz += tempVect.vz;

				//tempVect.vx=SinCosTable[GloveCtrl.direction].sin;
				//tempVect.vz=SinCosTable[GloveCtrl.direction].cos;

				//SCALEVECTOR(&tempVect,(BallBehaviour[BallCtrl.type].radius-GloveBehaviour.radius/3)/16);

				//glovePos.vx += tempVect.vx/8;
				//glovePos.vz += tempVect.vz/8;
			}
			else
			{
				if (GloveCtrl.actionTime<10)
				{
					tempVect.vx=(GloveCtrl.move.vx)/(GloveCtrl.actionTime+1);
					tempVect.vy=(GloveCtrl.move.vy)/(GloveCtrl.actionTime+1);
					tempVect.vz=(GloveCtrl.move.vz)/(GloveCtrl.actionTime+1);

					glovePos.vx += tempVect.vx;
					glovePos.vy += tempVect.vy;
					glovePos.vz += tempVect.vz;

					tempVect.vz = BallBehaviour[BallCtrl.type].radius-GloveBehaviour.radius/3;
					tempVect.vy=0;
					tempVect.vx=0;
					RotateVector2D(&tempVect, &tempVect,GloveCtrl.direction );

					glovePos.vx += (tempVect.vx*(GloveCtrl.actionTime))/10;
					glovePos.vz += (tempVect.vz*(GloveCtrl.actionTime))/10;
				}
				else	//	else GloveCtrl.lastAction=NULL;
				{
					GloveCtrl.lastAction=NULL;
					tempVect.vz = BallBehaviour[BallCtrl.type].radius-GloveBehaviour.radius/3;
					tempVect.vy=0;
					tempVect.vx=0;
					RotateVector2D(&tempVect, &tempVect,GloveCtrl.direction );
					glovePos.vx += tempVect.vx;
					glovePos.vz += tempVect.vz;
				}

			}

			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			HandCollision();

			//if (GloveCtrl.ballIdleAction==BALLPEDDLE)
			//{
			//	ballPos.vy=glovePos.vy-10*4096;
			//	ballVel.vy=0;
			//}

			break;

		case HAND_BOUNCE:

			gloveVel.vx=ballVel.vx;
			gloveVel.vz=ballVel.vz;

			glovePos.vx=ballPos.vx;
			glovePos.vz=ballPos.vz;			

			gloveVel.vy-=GloveBehaviour.gravity;
			ADDVECTOR(&glovePos, &glovePos, &gloveVel);
			glovePos.vy-=(gloveVel.vy*2);

			moveBall(upDown,leftRight);

			//tempV.vx=abs(leftRight);
			//tempV.vy=abs(upDown);
			//tempV.vz=0;

			//temp=Magnitude(&tempV);
			//temp=Magnitude2D_S(leftRight,upDown);
			//if (temp>4096) temp=4096;

			temp=Magnitude2D_S(leftRight,upDown);
			if (temp>4096) temp=4096;

			if (temp)
			{
				temp=(calc_angle( leftRight,upDown ) &4095);
				targetAngle=(temp+CamVars.angle)&4095;
				GloveCtrl.targetDirection=targetAngle;
			}
			else
			{
				targetAngle=GloveCtrl.targetDirection;
			}

			temp = (findShortestAngle(GloveCtrl.direction,targetAngle) );
			if (temp>0) GloveCtrl.direction-=temp/6;
			else if (temp<0) GloveCtrl.direction-=temp/6;

/*			if (temp)
			{
				temp=(calc_angle( leftRight,upDown ) &4095);
				targetAngle=(temp+CamVars.angle)&4095;
				temp = (findShortestAngle(GloveCtrl.direction,targetAngle) );
				if (temp>0)
				{
					if ( temp>ROTATESPEED )	GloveCtrl.direction-=ROTATESPEED;
					else GloveCtrl.direction=targetAngle;
				}
				else if (temp<0)
				{
					if ( temp<-ROTATESPEED ) GloveCtrl.direction+=ROTATESPEED;
					else GloveCtrl.direction=targetAngle;
				}
			}
*/
			GloveCtrl.direction=GloveCtrl.direction&4095;

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

			tempVect.vz = 4096*2;
			tempVect.vy=0;
			tempVect.vx=0;
			RotateVector2D(&tempVect, &tempVect,GloveCtrl.direction );
			glovePos.vx += tempVect.vx;
			glovePos.vz += tempVect.vz;
			
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			HandCollision();
			break;

//		case HAND_PUSH:
//			pGlovePSA->world.rotate.vy=GloveCtrl.direction;
//			moveBall(0,0);
//			HandCollision();
//			break;

//		case HAND_RELEASE:
//
//			break;

		default:
//			printf ("No update for this action using default\n");	// printf removed for running speed
			pGlovePSA->world.rotate.vy=GloveCtrl.direction;
			
			moveBall(0,0);

			gloveVel.vy-=gravity;
			ADDVECTOR(&glovePos, &glovePos, &gloveVel);
			glovePos.vy-=(gloveVel.vy*2);

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


			//TIMER_START(TIMER_COLLISION);
			//collboxCheckSphere(&gloveColl);
			//collboxCheckSphere(&gloveColl);
			//TIMER_STOP(TIMER_COLLISION);
			HandCollision();
			pGlovePSA->position.vx=glovePos.vx/4096;
			pGlovePSA->position.vy=glovePos.vy/4096;
			pGlovePSA->position.vz=glovePos.vz/4096;

			break;
	}
//	printf (",");
//	objectSetAnimation(pBallPSA, 0);
//	objectDrawWithShadow(pBallPSA,ballColl.radius >> 12,ballColl.radius >> 12,0);

/*	if (GloveCtrl.action==HAND_CASTSPELL)
	{
		if (!gloveColl.nHitPlats && !ballColl.nHitPlats)
		{
			BodgeCtrl.carnivalPlat=NULL;
			BodgeCtrl.hitPlat=FALSE;
		}
		else if ( (gloveColl.nHitPlats && BodgeCtrl.carnivalPlat!=gloveColl.hitPlats[0].pPlatform) ||
				  (ballColl.nHitPlats && BodgeCtrl.carnivalPlat!=ballColl.hitPlats[0].pPlatform) )
		{
			BodgeCtrl.carnivalPlat=NULL;
			BodgeCtrl.hitPlat=FALSE;
		}
	}
	else
	{
		BodgeCtrl.carnivalPlat=NULL;
		BodgeCtrl.hitPlat=FALSE;
	}
*/
		BodgeCtrl.carnivalPlat=NULL;
		BodgeCtrl.hitPlat=FALSE;


}



void	UpdateGlovePos(void)
{
VECTOR	tempVect;
LONG	mag,temp,temp1,temp2;

	if(!GloveCtrl.enabled)
		return;

/*	if (GloveCtrl.onIce && GloveCtrl.forceSlide)
	{
		DB ("ice and slide \n");
		GloveCtrl.forceSlide=FALSE;
		GloveCtrl.slideData.vx=0;
		GloveCtrl.slideData.vy=0;
		GloveCtrl.slideData.vz=0;
	}

	if (GloveCtrl.onIce)
	{
		DB ("slide normal X %d Y %d Z %d\n",GloveCtrl.slideData.vx,GloveCtrl.slideData.vy,GloveCtrl.slideData.vz);
	}
*/
//	GloveCtrl.slideData.vx=0;
//	GloveCtrl.slideData.vy=0;
//	GloveCtrl.slideData.vz=0;
//	GloveCtrl.forceSlide=FALSE;

	if (GloveCtrl.onIce)
	{
		//printf("%d\n",TRUE);
		if (GloveCtrl.onIceFlag==FALSE)	// first time?
		{
			GloveCtrl.iceData.vx=gloveVel.vx;
			GloveCtrl.iceData.vz=gloveVel.vz;
			//GloveCtrl.onIceFlag=TRUE;
			//GloveCtrl.slideData.vy=0;
		}
		mag=Magnitude(&gloveVel);


		if (GloveCtrl.slideData.vx || GloveCtrl.slideData.vz)
		{
			temp2=(abs(GloveCtrl.iceData.vx)+abs(GloveCtrl.iceData.vz));

			temp=(abs(GloveCtrl.slideData.vx)+abs(GloveCtrl.slideData.vz));
			temp1=abs(GloveCtrl.slideData.vy);
			//if (!temp) temp=1;
			//if (!temp1) temp1=1;
			//GloveCtrl.slideData.vy=-(temp2*temp1)/temp;
			GloveCtrl.slideData.vy=-(temp2*temp1)/4096;

			GloveCtrl.iceData.vx-=(GloveCtrl.slideData.vx/2);
			GloveCtrl.iceData.vz-=(GloveCtrl.slideData.vz/2);
		}

		if (GloveCtrl.onIceFlag==FALSE)	// first time?
		{
			GloveCtrl.onIceFlag=TRUE;
			GloveCtrl.slideData.vy=0;
			//printf ("blanking y part\n");
		}


		//GloveCtrl.slideData.vy=(GloveCtrl.slideData.vy*temp)/temp1;
		//glovePos.vy-=(GloveCtrl.slideData.vy*5);

		if ( mag>ICESLIDESPEED)
		{
			GloveCtrl.iceData.vx+=(gloveVel.vx-GloveCtrl.iceData.vx)/30;
			GloveCtrl.iceData.vz+=(gloveVel.vz-GloveCtrl.iceData.vz)/30;
		}
		else
		{
			GloveCtrl.iceData.vx+=(gloveVel.vx-GloveCtrl.iceData.vx)/60;
			GloveCtrl.iceData.vz+=(gloveVel.vz-GloveCtrl.iceData.vz)/60;
		}
		//mag = Magnitude(&GloveCtrl.iceData);

		//printf ("glove y vel before slide stuff %d \n",gloveVel.vy);
		
		gloveVel.vx=GloveCtrl.iceData.vx;
		gloveVel.vz=GloveCtrl.iceData.vz;
		//gloveVel.vy+=(GloveCtrl.slideData.vy/2);

		//GloveCtrl.forceSlide=TRUE;
		//printf ("glove y vel after slide stuff %d \n",gloveVel.vy);

		if (GloveCtrl.action==HAND_CRAWL || GloveCtrl.action==HAND_THROWAIM)
		{
			GloveCtrl.iceData.vx=0;
			GloveCtrl.iceData.vz=0;	
		}
		GloveCtrl.onIce++;
	}
	else if (GloveCtrl.onIceFlag) GloveCtrl.onIceFlag=FALSE;

	if (GloveCtrl.onIce==7) GloveCtrl.onIce=FALSE;

	if (GloveCtrl.inWaterFlag==NOWHERENEARWATER || GloveCtrl.inWaterFlag==ABOVEWATER)
	{
		//HAND_THROWAIM
		COPYVECTOR(&oldGlovePos, &glovePos);
		gloveVel.vy-=gravity;
		ADDVECTOR(&glovePos, &glovePos, &gloveVel);
		glovePos.vy-=(gloveVel.vy*2);

		if (GloveCtrl.onConveyer==XPOS)
		{
		 	if (GloveCtrl.conveyerNormal.vx)
			{
				glovePos.vx+=GloveCtrl.conveyerTimer*GloveCtrl.conveyerNormal.vy;
				glovePos.vy-=GloveCtrl.conveyerTimer*GloveCtrl.conveyerNormal.vx;
			}
			else glovePos.vx+=(GloveCtrl.conveyerTimer*4096);
		}

		if (GloveCtrl.onConveyer==XNEG)
		{
		 	if (GloveCtrl.conveyerNormal.vx)
			{
				glovePos.vx-=GloveCtrl.conveyerTimer*GloveCtrl.conveyerNormal.vy;
				glovePos.vy-=GloveCtrl.conveyerTimer*GloveCtrl.conveyerNormal.vx;
			}
			else glovePos.vx-=(GloveCtrl.conveyerTimer*4096);
		}
		

		if (GloveCtrl.onConveyer==ZPOS)
		{
		 	if (GloveCtrl.conveyerNormal.vz)
			{
				glovePos.vz+=GloveCtrl.conveyerTimer*GloveCtrl.conveyerNormal.vy;
				glovePos.vy-=GloveCtrl.conveyerTimer*GloveCtrl.conveyerNormal.vz;
			}
			else glovePos.vz+=(GloveCtrl.conveyerTimer*4096);
		}

		if (GloveCtrl.onConveyer==ZNEG)
		{
		 	if (GloveCtrl.conveyerNormal.vz)
			{
				glovePos.vz-=GloveCtrl.conveyerTimer*GloveCtrl.conveyerNormal.vy;
				glovePos.vy-=GloveCtrl.conveyerTimer*GloveCtrl.conveyerNormal.vz;
			}
			else glovePos.vz-=(GloveCtrl.conveyerTimer*4096);
		}
		
		if (GloveCtrl.conveyerTimer) GloveCtrl.conveyerTimer--;
		if (!GloveCtrl.conveyerTimer) GloveCtrl.onConveyer=FALSE;
	}
	else
	{
		COPYVECTOR(&oldGlovePos, &glovePos);

		//gloveVel.vy/=2;
		tempVect.vx=gloveVel.vx-(gloveVel.vx/4);
		tempVect.vz=gloveVel.vz-(gloveVel.vz/4);
		tempVect.vy=gloveVel.vy/2;

		if (frame%2) gloveVel.vy-=gravity;
		//ADDVECTOR(&glovePos, &glovePos, &gloveVel);
		ADDVECTOR(&glovePos, &glovePos, &tempVect);
		glovePos.vy-=(gloveVel.vy);


//		COPYVECTOR(&oldGlovePos, &glovePos);
//		gloveVel.vy-=gravity;
//		tempVect.vx=gloveVel.vx-(gloveVel.vx/4);
//		//tempVect.vy=gloveVel.vy-(gloveVel.vy/4);
//		tempVect.vy=gloveVel.vy/2;
//		tempVect.vz=gloveVel.vz-(gloveVel.vz/4);

//		ADDVECTOR(&glovePos, &glovePos, &tempVect);
//		glovePos.vy-=(gloveVel.vy*2);
	}

	//printf ("lava %d \n",GloveCtrl.onLava);

	if (GloveCtrl.action==HAND_IDLE && GloveCtrl.onGround && !GloveCtrl.onLava && !GloveCtrl.onIce && !gloveColl.nHitPlats && !GloveCtrl.onConveyer && !GloveCtrl.onTrampoline)
	{
		//printf ("holding glove pos\n");
		COPYVECTOR(&glovePos, &oldGlovePos);
		gloveVel.vy=0;
		GloveCtrl.positionHold=TRUE;
	}
	else GloveCtrl.positionHold=FALSE;
	GloveCtrl.onLava=FALSE;
	//printf ("rou end\n");
}




/////////////////////////////////////////////////////////////////////////////////////

void	loadCarnivalBonusModels(void)
{
	SHORT	loop;

	pRing03PSA=BFF_IsModelLoaded("RING03",NULL);
	objectSetupSegmentSort(pRing03PSA);

	pRing02PSA=BFF_IsModelLoaded("RING02",NULL);
	objectSetupSegmentSort(pRing02PSA);

	pRing01PSA=BFF_IsModelLoaded("RING01",NULL);
	objectSetupSegmentSort(pRing01PSA);

	pPod01PSA=BFF_IsModelLoaded("POD01",NULL);
	objectSetupSegmentSort(pPod01PSA);

	pCannonPSA=BFF_IsModelLoaded("CANNON01",NULL);
	objectSetupSegmentSort(pCannonPSA);

	pCard01PSA=BFF_IsModelLoaded("CARD04",NULL);
	objectSetupSegmentSort(pCard01PSA);

	pCard02PSA=BFF_IsModelLoaded("CARD05",NULL);
	objectSetupSegmentSort(pCard02PSA);

	pCard03PSA=BFF_IsModelLoaded("CARD06",NULL);
	objectSetupSegmentSort(pCard03PSA);

	chuckBullet=BFF_IsModelLoaded("CHUCKTOTHROW",NULL);
	objectSetupSegmentSort(chuckBullet);

	dennisBullet=BFF_IsModelLoaded("DENNISTOTHROW",NULL);
	objectSetupSegmentSort(dennisBullet);

	bugleBullet=BFF_IsModelLoaded("BUGLETOTHROW",NULL);
	objectSetupSegmentSort(bugleBullet);


	pCard01PSA->world.movekeys->vect.x=0;
	pCard01PSA->world.movekeys->vect.y=0;
	pCard01PSA->world.movekeys->vect.z=0;

	bugleBullet->globalscale.vx=160;
	bugleBullet->globalscale.vy=160;
	bugleBullet->globalscale.vz=160;

	chuckBullet->globalscale.vx=160;
	chuckBullet->globalscale.vy=160;
	chuckBullet->globalscale.vz=160;

	dennisBullet->globalscale.vx=160;
	dennisBullet->globalscale.vy=160;
	dennisBullet->globalscale.vz=160;

	//pCard01PSA->globalscale.vx=2048;
	//pCard01PSA->globalscale.vy=2048;
	//pCard01PSA->globalscale.vz=2048;	// **&! it

	for (loop=0;loop<pCard01PSA->world.meshdata->vern;loop++)
	{
		pCard01PSA->world.meshdata->vertop[loop].vx=pCard01PSA->world.meshdata->vertop[loop].vx/2;
		pCard01PSA->world.meshdata->vertop[loop].vy=pCard01PSA->world.meshdata->vertop[loop].vy/2;
		pCard01PSA->world.meshdata->vertop[loop].vz=pCard01PSA->world.meshdata->vertop[loop].vz/2;
	}


	AddToQueue(&Glover,HANDANIM_RIDEDENNIS,YES,NO,4096);
	AddToQueue(&Glover,HANDANIM_RIDEDENNIS,YES,YES,4096);

	pCannonPSA->position.vx= 0;
	pCannonPSA->position.vy= -28/4;
	pCannonPSA->position.vz= 18/4;

	pPod01PSA->position.vx= 0;
	pPod01PSA->position.vy= 25/4;
	pPod01PSA->position.vz= 0;

	pRing01PSA->position.vx=0;
	pRing01PSA->position.vy=65;	
	pRing01PSA->position.vz=0;

	pRing02PSA->position.vx=0;
	pRing02PSA->position.vy=20;
	pRing02PSA->position.vz=0;

	pRing03PSA->position.vx=0;
	pRing03PSA->position.vy=-25;
	pRing03PSA->position.vz=0;

	CannonCtrl.elevation=-128;
	// now setup cards for display

	BallCtrl.enabled=FALSE;

	cardTex[0]=FindTexture("TGWIZ");
	cardTex[1]=FindTexture("TGCHUCK");
	cardTex[2]=FindTexture("TGCLOSIT");
	cardTex[3]=FindTexture("TGEVILG");
	cardTex[4]=FindTexture("TGHOPPER");
	cardTex[5]=FindTexture("TGBUGLE");

	for (loop=0;loop<20;loop++)
	{
		CannonCtrl.ring1CardTypes[loop]=(RANDOM256()/52)+1;
		CannonCtrl.ring2CardTypes[loop]=(RANDOM256()/52)+1;
		CannonCtrl.ring3CardTypes[loop]=(RANDOM256()/52)+1;

		CannonCtrl.ring1CardStatus[loop]=TRUE;
		CannonCtrl.ring2CardStatus[loop]=TRUE;
		CannonCtrl.ring3CardStatus[loop]=TRUE;
	}

	CannonCtrl.ring1CardTypes[(RANDOM256()/25)]=0;
	CannonCtrl.ring2CardTypes[(RANDOM256()/25)]=0;
	CannonCtrl.ring3CardTypes[(RANDOM256()/25)]=0;

	CannonCtrl.nextFireCount=0;
	CannonCtrl.endOfBonusFlag=FALSE;

	CannonCtrl.shotsFired=0;
	CannonCtrl.cardsHit=0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////

void	loadPiratesModels()
{
LONG	loop;

	pCannonPSA=BFF_IsModelLoaded("CANNON2",NULL);
	objectSetupSegmentSort(pCannonPSA);

	pBoulderPSA=BFF_IsModelLoaded("CANNON",NULL);
	objectSetupSegmentSort(pBoulderPSA);

	pCannonPSA->world.movekeys->vect.x=0;
	pCannonPSA->world.movekeys->vect.y=0;
	pCannonPSA->world.movekeys->vect.z=0;

	for (loop=0;loop<10;loop++)
		CannonCtrl.alive[loop]=FALSE;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////

void	timeTrialSelection(void)
{
long	counter=0;
int		loop,check;
SHORT	openLevels[NUM_LEVELS];
SHORT	mins,tens,secs,g1,g2,g1dir,g2dir;

TEXT	*pTextLevel[9];
TEXT	*pTextTime[9];
TEXT	*pTextName[9];

long	selection=0,lastselection=0,changed=FALSE;
long	upDown,debouncePad=0,debounceCount=0;
char	sTime[9][5];




	End_Loop(0);	// Stops gte timeout errors

	//debouncePad = 0;
	//debounceCount = 0;

	for (loop=0;loop<NUM_LEVELS;loop++) openLevels[loop]=256;

	for (loop=0;loop<NUM_LEVELS;loop++)	// find numbers for open levels
	{
		if (timeTrialData[loop].levelOpen)
		{
			openLevels[counter++]=loop;
		}
	}
	//counter--;
	g1=0;
	g2=128;
	g1dir=6;
	g2dir=6;

	textReset();				// Setup font scale ect
	messctrl.font=fontList[1];
	spriteReset();
	sprctrl.stretch=1;

	sprctrl.scalex=4096;
	sprctrl.scaley=4096;

	NEW_TEXT(240, 40, 128,128,0,255, 4096,4096, TRUE, "TIME TRIAL", TRUE);
	//pText[loop]=mtext;
	//mtext->flags=TEXT_SHADED;
	SETRGBC(mtext->r1,128,40,8,FULLALPHA);

	sprctrl.scalex=3072;
	sprctrl.scaley=3072;

	if (counter<9) check=counter;
	else check=9;

	for (loop=0;loop<check;loop++)
	{
		secs=timeTrialData[openLevels[loop]].bestTime;
		mins=secs/60;
		tens=(secs-(mins*60))/10;
		secs=(secs-(mins*60))-(tens*10);
		sprintf (&(sTime[loop][0]),"%d:%d%d",mins,tens,secs);

		//NEW_TEXT(240, 40+loop*20, 128,128,0,255, 4096,4096, TRUE, &sTime[loop], TRUE);
		NEW_TEXT(20, 80+loop*20, 128,128,0,255, 4096,4096, TRUE, sLevelNames[openLevels[loop]], FALSE);
		pTextLevel[loop]=mtext;
		mtext->flags=TEXT_SHADED;

		SETRGBC(pTextLevel[loop]->r,128,128,0,FULLALPHA);
		SETRGBC(pTextLevel[loop]->r1,128,40,8,FULLALPHA);

		NEW_TEXT(320, 80+loop*20, 128,128,0,255, 4096,4096, TRUE, &(sTime[loop][0]), FALSE);
		pTextTime[loop]=mtext;
		mtext->flags=TEXT_SHADED;
		SETRGBC(pTextTime[loop]->r,128,128,0,FULLALPHA);
		SETRGBC(pTextTime[loop]->r1,128,40,8,FULLALPHA);

		NEW_TEXT(380, 80+loop*20, 128,128,0,255, 4096,4096, TRUE, &timeTrialData[openLevels[loop]].name[0], FALSE);
		pTextName[loop]=mtext;
		mtext->flags=TEXT_SHADED;
		SETRGBC(pTextName[loop]->r,128,128,0,FULLALPHA);
		SETRGBC(pTextName[loop]->r1,128,40,8,FULLALPHA);

	}



	for ( ;; )
	{
		Start_Loop();

		upDown=-(nlefty[0]);
		if (upDown<0)
		{
			if (debouncePad<0)
			{
				if (debounceCount)
				{
					upDown=0;
					debounceCount--;
				}
			}
			else
			{
				debouncePad=0;
				debounceCount=0;
			}
		}
		else if (upDown>0)
		{
			if (debouncePad>0)
			{
				if (debounceCount)
				{
					upDown=0;
					debounceCount--;
				}
			}
			else
			{
				debouncePad=0;
				debounceCount=0;
			}
		}
		else
		{
			debouncePad=0;
			debounceCount=0;
		}

		if (upDown>1024)
		{
			debouncePad=upDown;
			debounceCount=6;
			lastselection=selection;
			changed=TRUE;
			if (selection==0) selection=check-1;
			else selection--;
		}
		if (upDown<-1024)
		{
			debouncePad=upDown;
			debounceCount=6;
			lastselection=selection;
			changed=TRUE;
			selection++;
			if (selection==check) selection=0;
		}


		SETRGBC(pTextTime[selection]->r,128,128,g1,FULLALPHA);
		SETRGBC(pTextTime[selection]->r1,128,40,g2,FULLALPHA);

		SETRGBC(pTextName[selection]->r,128,128,g1,FULLALPHA);
		SETRGBC(pTextName[selection]->r1,128,40,g2,FULLALPHA);

		SETRGBC(pTextLevel[selection]->r,128,128,g1,FULLALPHA);
		SETRGBC(pTextLevel[selection]->r1,128,40,g2,FULLALPHA);

		if (changed)
		{
			SETRGBC(pTextTime[lastselection]->r,128,128,0,FULLALPHA);
			SETRGBC(pTextTime[lastselection]->r1,128,40,8,FULLALPHA);

			SETRGBC(pTextName[lastselection]->r,128,128,0,FULLALPHA);
			SETRGBC(pTextName[lastselection]->r1,128,40,8,FULLALPHA);

			SETRGBC(pTextLevel[lastselection]->r,128,128,0,FULLALPHA);
			SETRGBC(pTextLevel[lastselection]->r1,128,40,8,FULLALPHA);
			changed=FALSE;
		}

		g1+=g1dir;
		g2+=g2dir;
		if (g1>255)
		{
			g1=255;
			g1dir=-6;
		}
		if (g1<0)
		{
			g1=0;
			g1dir=6;
		}
		if (g2>255)
		{
			g2=255;
			g2dir=-6;
		}
		if (g2<0)
		{
			g2=0;
			g2dir=6;
		}
		

		ShowText();
		menuPrintBack(1024);	// zoom = 1024
		End_Loop(0);

	}
}


