#include "global.h"
//#include "camera.h"

//
#include "main.h" 

#include "map_view.h"
#include "collide.h"
#include "maths.h"
#include "platform.h"
#include "main.h"
#include "inventory.h"
#include "enemies.h"
#include "charactr.h"
#include "map_play.h"
#include "puzzles.h"
#include "camera.h"
#include "deth.h"

COLLBOX	hitBox;
//COLLBOX	*test;
#define	CAMMOD	8

#undef  NULL
#define NULL 0

#define	CHANGETIME	50
CAMVARS	camVars;
#define	ACTIVEZONE	100*4096
//#define MOVEDIST	300
#define	MOVEHEIGHT	50
#define	OFFSETDIST	50

#define	CAMLEFT		1
#define	CAMRIGHT	2
#define	CAMNEAR		4
#define	CAMFAR		8

#define	DEADZONERANGE	200
#define	HEIGHTOFFSET	300
//#define	HEIGHTOFFSET	0

#define	LEFT		1
#define	RIGHT		2
//int	scale1,scale2;

#define	SWINGSPEEDMOD	3000

//RAILDATA1	railData;

/*VECTOR		testRailData[5]=
{
	{-6882,-500,1010},
	{-3512,-1000,-2474},
	{-328,-500,999},
	{5823,-1000,-2659},
	{8471,-500,848},
};
*/

/*VECTOR		testRailData[4]=
{
	{2344,-500,1043,0},
	{-1109,-1000,-2083,4685},
	{-6352,-500,-834,7629},
	{-6818,-1000,5727,2021},
};
*/
COLLDATA	cameraColl;
VECTOR		camVel,cameraPos;	// vel just there to make up struct

VECTOR	testDeadZone;

void	initCamera(void)
{
	int	sin,cos;

	DB("init camera called\n");

	cameraColl.pPos=&cameraPos;
	cameraColl.pVel=&camVel;
	cameraColl.bounce=4096;
	//cameraColl.radius=(9*4096)<<3;
	cameraColl.radius=(40*4096);
	cameraColl.nBoxes = numCollBoxes;

	// Values for interiour camera
	//camVars.camHeight=1000;//2000;
	//camVars.actualHeight=camVars.requiredHeight=camVars.normalHeight=camVars.camHeight;
	//camVars.camDistance=3000;

	// Values for exteriour camera
	camVars.camHeight=2000;
	camVars.actualHeight=camVars.requiredHeight=camVars.normalHeight=camVars.camHeight;
	camVars.camDistance=3000;
	camVars.tweedySpecial=NULL;
	camVars.tweedyHoldTime=0;


	camVars.lookHeight=MOVEHEIGHT;
	//camVars.lookDistance=MOVEDIST*10;
	camVars.lookDistance=camVars.camDistance;
	camVars.requiredDistance=camVars.lookDistance;
	camVars.actualDistance=camVars.lookDistance;
	camVars.offsetDistance=OFFSETDIST*10;
	camVars.objectHeight=0;
	camVars.oldRequiredDistance=camVars.requiredDistance;
	camVars.camType=ROTCAM;
	//camVars.camType=RAILCAM;
	camVars.lastCamType=NULL;	// will only be set when cam type changes
	camVars.camTypeChanged=NO;
	//camVars.camType=RAILCAM;
	camVars.swingDirection=NULL;
	camVars.holdPositionFlag=FALSE;

	//camVars.area=INSIDE;
	camVars.area=OUTSIDE;

	//	Assume targetmodel setup by this point
	if (camVars.targetEnemy!=NULL)
	{
		int	cos,sin;
		mycamera.vrx=camVars.targetEnemy->pos.vx;
		mycamera.vry=camVars.targetEnemy->pos.vy-HEIGHTOFFSET;
		mycamera.vrz=camVars.targetEnemy->pos.vz;

		mycamera.vpx=camVars.targetEnemy->pos.vx+camVars.lookDistance;
		mycamera.vpy=camVars.targetEnemy->pos.vy;
		mycamera.vpz=camVars.targetEnemy->pos.vz;

		sin=rsin(camVars.camAngle);
		cos=rcos(camVars.camAngle);
		mycamera.vpx=mycamera.vrx+sin;
		mycamera.vpz=mycamera.vrz-cos;
		//DB("start cam pos X %d Z %d\n",mycamera.vrx,mycamera.vrz);
	}
	else
	{
		mycamera.vrx=0;
		mycamera.vry=0;
		mycamera.vrz=0;

		mycamera.vpx=0;
		mycamera.vpy=0;
		mycamera.vpz=0;
	}
	camVars.camVel.vx=0;
	camVars.camVel.vy=0;
	camVars.camVel.vz=0;
	camVars.railCamYOffset=0;
	//camVars.flags=NOSWEEPLOOK;

	camVars.flags=NULL;
	camVars.lastFlags=NULL;

	camVars.numActorHits=0;
	camVars.posChange=FALSE;
	camVars.timer=0;
	camVars.targetRadius=(80*4096)/512;
	camVars.quadrant=0;
	camVars.lastQuadrant=0;

	camVars.fixedAngle=2048;	// needs to come from cam case
	camVars.inactiveTime=0;

	camVars.currentRailDist=0;
	camVars.railCamVel=0;
	camVars.railCamDirection=1;
	camVars.sweepFlag=FALSE;	// use puzzel to set
	camVars.firstSweep=FALSE;

/*	railData.numPoints=4;	// will get this data from editor
	railData.currentPoint=0;
	railData.direction=-1;
	railData.pointData=&testRailData[0];
*/
	testDeadZone.vx=mycamera.vrx;
	testDeadZone.vy=mycamera.vry;
	testDeadZone.vz=mycamera.vrz;

	camVars.railCamDirection=1;

	camVars.posCaseOnTime=0;
	camVars.lookCaseOnTime=0;

	camVars.posCaseToHold=0;
	camVars.lookCaseToHold=0;
	camVars.flipFlop=0;
	camVars.timeTillNextChange=0;

	camVars.timerTar=0;
	camVars.tarChange=0;
	camVars.tarChangeOn=0;
	//camVars.camAngle=camVars.camStartAngle;

/*	sin=rsin(camVars.camStartAngle);
	cos=rcos(camVars.camStartAngle);

	mycamera.vpx=sin;
	mycamera.vpy=mycamera.vpy;
	mycamera.vpz=cos;
*/
	camVars.caseSpecials=NULL;
	camVars.specialOveride=FALSE;

	camVars.justStartedTimer=5;	// stop the camera interpol for the first 5 frames
	if (levinfo)
	{
		camVars.camHeight=levinfo->initial_cam_height;
		camVars.actualHeight=camVars.requiredHeight=camVars.normalHeight=camVars.camHeight;
		camVars.camDistance=levinfo->initial_cam_distance;

		camVars.lookDistance=camVars.camDistance;
		camVars.requiredDistance=camVars.lookDistance;
		camVars.actualDistance=camVars.lookDistance;
		camVars.oldRequiredDistance=camVars.requiredDistance;

		camVars.camStartAngle=levinfo->cam_start_angle;
		camVars.camAngle=camVars.camStartAngle;
		{
			int	cos,sin;

			sin=rsin(camVars.camAngle);
			cos=rcos(camVars.camAngle);
			mycamera.vpx=mycamera.vrx+sin;
			mycamera.vpz=mycamera.vrz-cos;
		}
	}

/*	{
		VECTOR	temp;
		int		angle;
		temp.vx=camVars.targetEnemy->pos.vx;
		temp.vz=camVars.targetEnemy->pos.vz;
		angle=utilCalcAngle(temp.vx,temp.vz);

		mycamera.vpx=mycamera.vrx-temp.vx;
		mycamera.vpz=mycamera.vrz-temp.vz;

		camVars.camAngle=angle&4095;
	}
*/

}

//////////////////////////////////////////////////////////////////////
CAMINFOHANDLE caminfo;
void caminfoLinkBFF(CAMINFOHANDLE info)
{
	int i;
	caminfo = info;
	if (info->numCases)
		info->rec = ADD2POINTER(info->rec, (int)info);
	if (info->numRailCases)
		info->data = ADD2POINTER(info->rec, (int)info);


//	for (i=0;i<caminfo->numRails[0];i++)
//	{
//		DB ("rail X %d Y %d Z %d\n",caminfo->data[i].pointX,caminfo->data[i].pointY,caminfo->data[i].pointZ);
//	}

//	DB("debug\n");
//	if(info->posmarks)
//		info->posmarks = ADD2POINTER(info->posmarks, (int)info);
//	if(info->lights)
//		info->lights = ADD2POINTER(info->lights, (int)info);

//	printf("n_lights = %d\n",info->n_lights);
//	for(i = 0; i < info->n_lights; i++)
//		EXLIGHT_MergeLights(&info->lights[i]);

//	EXLIGHT_SetAmbient(info->ambient_colour);

}
//////////////////////////////////////////////////////
// vp is the cam pos vr is what we look at



void	upDateCamera(void)
{
	int	loop;
	COLLBOX	*pBox,*pBox1;
	VECTOR	camPos,temp,viewPos;
	int	position=NULL;
	int	camPosition=NULL;
// CPW: 	int	heightChange=camHeight;
	int heightChange = 0;
	int	height;

	char	message[255];

	int	dz1,dy1,dz2,dy2,dy3;

	camVars.specialDist=0x7fffffff;

/*	if (camVars.camTypeChanged)
	{
		mycamera.vpx=camVars.camRealPos.vx;
		mycamera.vpy=camVars.camRealPos.vy;
		mycamera.vpz=camVars.camRealPos.vz;

		mycamera.vrx=camVars.camRealView.vx;
		mycamera.vry=camVars.camRealView.vy;
		mycamera.vrz=camVars.camRealView.vz;
	}
*/	camVars.camAtStart.vx=mycamera.vpx;
	camVars.camAtStart.vy=mycamera.vpy;
	camVars.camAtStart.vz=mycamera.vpz;

	//DB("area =%d\n",camVars.area);


	switch (camVars.camType)
	{
		case HUTCAM:
			//DB("hut cam\n");
			hutCamera();
			//standardCamera(&camVars);
			break;

		case ROTCAM:
			//DB("normal cam\n");
			//checkObstructionsRotate(&camVars);
			//if (camVars.area==OUTSIDE) swingCameraOutside(&camVars);
			//else swingCameraInside(&camVars);
			swingCameraOutside(&camVars);

			camVars.oldRequiredDistance=camVars.requiredDistance;
			checkObstructionsRotate(&camVars);
			break;

		case RAILCAMAXIS:
			//DB ("rail cam aligned\n");
			mycamera.vry-=camVars.railCamYOffset;
			railCamera();
			mycamera.vry+=camVars.railCamYOffset;
			break;

		case RAILCAM:
			//DB("rail none aligned\n");
			mycamera.vry-=camVars.railCamYOffset;
			railCamNoneAligned();
			mycamera.vry+=camVars.railCamYOffset;
			break;

/*		case LOOKCAM:
			//DB("look cam\n");
			lookCamera();
			break;
*/
	}

	if (camVars.caseSpecials&UPDATEPOSITION)	// cam returning from case update start position
	{
//		if (camVars.camType!=RAILCAM)
//		{
			camVars.startCamPos.vx=mycamera.vpx;
			camVars.startCamPos.vy=mycamera.vpy;
			camVars.startCamPos.vz=mycamera.vpz;
//		}
		camVars.caseSpecials=0;
	}


/*	if (camVars.camTypeChanged)
	{
		camVars.camRealPos.vx=mycamera.vpx;
		camVars.camRealPos.vy=mycamera.vpy;
		camVars.camRealPos.vz=mycamera.vpz;

		camVars.camRealView.vx=mycamera.vrx;
		camVars.camRealView.vy=mycamera.vry;
		camVars.camRealView.vz=mycamera.vrz;
	}
*/	camVars.camAfterStart.vx=mycamera.vpx;
	camVars.camAfterStart.vy=mycamera.vpy;
	camVars.camAfterStart.vz=mycamera.vpz;

	CamModesAllowed();

	caseHandler();

	camVars.camAfterCase.vx=mycamera.vpx;
	camVars.camAfterCase.vy=mycamera.vpy;
	camVars.camAfterCase.vz=mycamera.vpz;

//	height=getCeilingAt(camVars.targetEnemy->pos.vx<<9,camVars.targetEnemy->pos.vy<<9,camVars.targetEnemy->pos.vz<<9);
//	sprintf(message,"distance to ceiling %d",height/512);
//	fontPrint(font, -220,-25, message, 128,128,0);


/*	if (!camVars.posChangeOn) // if moving back from case update position moving to
	{
		camVars.startCamPos.vx=mycamera.vpx;
		camVars.startCamPos.vy=mycamera.vpy;
		camVars.startCamPos.vz=mycamera.vpz;

		sprintf(message,"cam pos X %d  Y %d  Z %d",mycamera.vpx,mycamera.vpy,mycamera.vpz);
		fontPrint(font, -220,-25, message, 128,128,0);
	}
*/
	tweedyCaseHandler();

	updateTimers();

	if (camVars.justStartedTimer)
	{
		camVars.justStartedTimer--;
		if (camVars.posChange)
		{
			camVars.startCamPos.vx=camVars.targetCamPos.vx;
			camVars.startCamPos.vy=camVars.targetCamPos.vy;
			camVars.startCamPos.vz=camVars.targetCamPos.vz;
		}
		if (camVars.tarChange)
		{
			camVars.startViewPos.vx=camVars.targetViewPos.vx=mycamera.vrx;
			camVars.startViewPos.vy=camVars.targetViewPos.vy=mycamera.vry;
			camVars.startViewPos.vz=camVars.targetViewPos.vz=mycamera.vrz;
		}
	}

	if (camVars.posChange )
	{
		camVars.interpCamPos.vx=mycamera.vpx= ((camVars.targetCamPos.vx*camVars.timer) + (camVars.startCamPos.vx*(camVars.camTransitionSpeed-camVars.timer)) )/camVars.camTransitionSpeed;
		camVars.interpCamPos.vy=mycamera.vpy= ((camVars.targetCamPos.vy*camVars.timer) + (camVars.startCamPos.vy*(camVars.camTransitionSpeed-camVars.timer)) )/camVars.camTransitionSpeed;
		camVars.interpCamPos.vz=mycamera.vpz= ((camVars.targetCamPos.vz*camVars.timer) + (camVars.startCamPos.vz*(camVars.camTransitionSpeed-camVars.timer)) )/camVars.camTransitionSpeed;
	}

	//if (camVars.tarChange && (camVars.camType==RAILCAMAXIS) )
	if (camVars.tarChange )
	{
		//DB("rail cam overide\n");
		camVars.startViewPos.vx=camVars.targetEnemy->pos.vx;
		//camVars.startViewPos.vy=camVars.targetEnemy->pos.vy;
		camVars.startViewPos.vz=camVars.targetEnemy->pos.vz;
		camVars.startViewPos.vy=(camVars.targetEnemy->pos.vy-HEIGHTOFFSET)-camVars.targetRadius/8;

		camVars.interpCamView.vx=mycamera.vrx= ((camVars.targetViewPos.vx*camVars.timerTar) + (camVars.startViewPos.vx*(camVars.camTransitionSpeed-camVars.timerTar)) )/camVars.camTransitionSpeed;
		camVars.interpCamView.vy=mycamera.vry= ((camVars.targetViewPos.vy*camVars.timerTar) + (camVars.startViewPos.vy*(camVars.camTransitionSpeed-camVars.timerTar)) )/camVars.camTransitionSpeed;
		camVars.interpCamView.vz=mycamera.vrz= ((camVars.targetViewPos.vz*camVars.timerTar) + (camVars.startViewPos.vz*(camVars.camTransitionSpeed-camVars.timerTar)) )/camVars.camTransitionSpeed;
	}


	if ( !(camVars.lastFlags&FIXEDPOS) )
	{
		if (camVars.actualDistance!=camVars.requiredDistance)
		{
			camVars.actualDistance+=(camVars.requiredDistance-camVars.actualDistance)/6;
		}
	}

	camVars.camAfterInterp.vx=mycamera.vrx;
	camVars.camAfterInterp.vy=mycamera.vry;
	camVars.camAfterInterp.vz=mycamera.vrz;

	if ( !(camVars.lastFlags&FIXEDPOS) && (camVars.area==OUTSIDE) )
	{
		if (camVars.requiredHeight>(camVars.normalHeight+(camVars.normalHeight>>1)))
			camVars.requiredHeight=(camVars.normalHeight+(camVars.normalHeight>>1));

		if (camVars.actualHeight<camVars.requiredHeight)
			camVars.actualHeight+=(camVars.requiredHeight-camVars.actualHeight)/10;
		else
			camVars.actualHeight+=(camVars.requiredHeight-camVars.actualHeight)/16;
	}

	if ( (camVars.holdPosition.vx>mycamera.vpx-10) && (camVars.holdPosition.vx<mycamera.vpx+10)
	&& (camVars.holdPosition.vy>mycamera.vpy-10) && (camVars.holdPosition.vy<mycamera.vpy+10)
	&& (camVars.holdPosition.vz>mycamera.vpz-10) && (camVars.holdPosition.vz<mycamera.vpz+10) && camVars.targetEnemy->moveSpeed==0)
	{
		camVars.holdPositionFlag=TRUE;
	}
	else camVars.holdPositionFlag=FALSE;

	if (camVars.holdPositionFlag)
	{
		mycamera.vpx=camVars.holdPosition.vx;
		mycamera.vpy=camVars.holdPosition.vy;
		mycamera.vpz=camVars.holdPosition.vz;
	}			

	camVars.oldActorPos.vx=camVars.targetEnemy->pos.vx;	// will need changing at later date
	camVars.oldActorPos.vy=camVars.targetEnemy->pos.vy;
	camVars.oldActorPos.vz=camVars.targetEnemy->pos.vz;


	if (camVars.camType==RAILCAM && camVars.railTargetRail)
	{
		temp.vx=mycamera.vrx;
		temp.vy=mycamera.vry;
		temp.vz=mycamera.vrz;

		mycamera.vrx=mycamera.vpx-camVars.railCamPoint.vx;
		mycamera.vrz=mycamera.vpz-camVars.railCamPoint.vz;
	}


	if (camVars.specialOveride)
	{
		mycamera.vpx=camVars.specialPos.vx;
		mycamera.vpy=camVars.specialPos.vy;
		mycamera.vpz=camVars.specialPos.vz;

		mycamera.vrx=camVars.specialView.vx;
		mycamera.vry=camVars.specialView.vy;
		mycamera.vrz=camVars.specialView.vz;
		camVars.specialOveride=FALSE;
	}

/*
	height=getCeilingAt(camVars.targetEnemy->pos.vx<<9,camVars.targetEnemy->pos.vy<<9,camVars.targetEnemy->pos.vz<<9);
	sprintf(message,"distance to ceiling %d",height/512);
	fontPrint(font, -220,-25, message, 128,128,0);
	height=height/512;
	if ( (camVars.targetEnemy->pos.vy-height) > mycamera.vpy ) mycamera.vpy=(camVars.targetEnemy->pos.vy-height);
*/



/*
	{
		//mycamera.vpx=mycamera.vrx;
		mycamera.vpx=mycamera.vrx=0;
		mycamera.vpy=mycamera.vry-3000;
		mycamera.vpz=mycamera.vrz-500;
	}
*/

	// these two overide just about everything and need to be processed last
	if (camVars.posCaseToHold&FIXEDPOSSNAP)
	//if (camVars.flags&FIXEDPOSSNAP)
	{
		mycamera.vpx=camVars.camMovePosSnap.vx;
		mycamera.vpy=camVars.camMovePosSnap.vy;
		mycamera.vpz=camVars.camMovePosSnap.vz;
	}

	if (camVars.lookCaseToHold&FIXEDLOOKSNAP)
	//if (camVars.flags&FIXEDLOOKSNAP)
	{
		mycamera.vrx=camVars.viewMovePosSnap.vx;
		mycamera.vry=camVars.viewMovePosSnap.vy;
		mycamera.vrz=camVars.viewMovePosSnap.vz;

		//camVars.tarChangeOn=TRUE;
		//camVars.tarChange=TRUE;
	}
	camVars.flags=NULL;


	camVars.camAtEnd.vx=mycamera.vpx;
	camVars.camAtEnd.vy=mycamera.vpy;
	camVars.camAtEnd.vz=mycamera.vpz;

#ifdef	CASEDEBUG
	sprintf(message,"Camera when set X %d  Y %d  Z %d",mycamera.vpx,mycamera.vpy,mycamera.vpz);
	fontPrint(font, -220,20, message, 128,128,0);
#endif

	camVars.camAngle=(utilCalcAngle( (mycamera.vpx-mycamera.vrx),(mycamera.vpz-mycamera.vrz) )+2048)&4095;
	mapCamSetRefView2L(&mycamera);






	if (camVars.camType==RAILCAM && camVars.railTargetRail)
	{
		mycamera.vrx=temp.vx;
		mycamera.vry=temp.vy;
		mycamera.vrz=temp.vz;
	}
}
////////////////////////////////////////////////////////////////////////////
//	If cam in collision find direction to swing it in

//	big problem can get stuck between two objects and oscilate
//	Try again on new map with better spacing
void	findSwingDirection(VECTOR camPos,VECTOR actorPos)
{
	switch (camVars.quadrant)
	{
		case 1:
			if (actorPos.vx>camPos.vx) camVars.swingDirection=RIGHT;
			else camVars.swingDirection=LEFT;
			break;

		case 2:
			if (actorPos.vz<camPos.vz) camVars.swingDirection=RIGHT;
			else camVars.swingDirection=LEFT;
			break;

		case 3:
			if (actorPos.vx<camPos.vx) camVars.swingDirection=RIGHT;
			else camVars.swingDirection=LEFT;
			break;

		case 4:
			if (actorPos.vz>camPos.vz) camVars.swingDirection=RIGHT;
			else camVars.swingDirection=LEFT;
			break;
	}
}

////////////////////////////////////////////////////////////////////////////
//	Checks to see if target out of view and changes distance acordingly
void	checkObstructionsFixed(int *dist,CAMVARS *CamVars)
{
	int	dz1,dy1,dz2,dy2,dy3;
	int	height;
	VECTOR	camPos;


	camPos.vx=mycamera.vpx*512;
	camPos.vy=mycamera.vpy*512;
	camPos.vz=mycamera.vpz*512;

	height=getHeightAtCam(camPos.vx,camPos.vy,camPos.vz, &hitBox )/512;

	// need to take radius off positions
	dz1=(mycamera.vrz-mycamera.vpz)-CamVars->targetRadius;
	dy1=mycamera.vry-mycamera.vpy+CamVars->targetRadius;

	dz2=-( ((hitBox.pZ+hitBox.sZ)/512)-testchar_actor->position.vz )-(CamVars->targetRadius);
	if (dz2<1 && dz2>-65) dz2=1;

	dy2=(dy1*dz2)/dz1;
	dy3=(-hitBox.sY/512)+( (mycamera.vry) -hitBox.pY/512);

	if ( (dy2>0) && (dy3>0) )
	{
		if (dy3>dy2)
		{
			//*dist=mycamera.vpz-mycamera.vrz;
			*dist=( (*dist) *dy2)/dy3;
			//mycamera.vpz=mycamera.vrz+(*dist);
		}
		else *dist=0;
	}
	else *dist=0;
}

////////////////////////////////////////////////////////////////////////////
//	Checks to see if target out of view and changes distance acordingly

void	checkObstructionsRotate(CAMVARS *CamVars)
{
	int	dz1,dy1,dz2,dy2,dy3,dx1;
	int	height;
	VECTOR	camPos,actorPos;
	int	position=0;
	int	position1=0;
	int	scale1,scale2;

	camPos.vx=camVars.camPos2.vx;
	camPos.vy=camVars.camPos2.vy;
	camPos.vz=camVars.camPos2.vz;

	actorPos.vx=CamVars->targetEnemy->pos.vx*512;
	actorPos.vy=(CamVars->targetEnemy->pos.vy-HEIGHTOFFSET)*512;
	actorPos.vz=CamVars->targetEnemy->pos.vz*512;

	findClosestBox(actorPos.vx,actorPos.vy,actorPos.vz,camPos.vx,camPos.vy,camPos.vz,&hitBox,TRUE);

	if ( actorPos.vy < (hitBox.pY+hitBox.sY) )
	{
		camVars.quadrant=0;	// cam not above another box
		camVars.requiredDistance=camVars.lookDistance;
	}
	else
		camVars.quadrant=findQuadrant(camPos,actorPos);

	if (camVars.quadrant)
	{
		camVars.lastQuadrant=camVars.quadrant;
		camVars.requiredHeight=camVars.normalHeight-((hitBox.pY+hitBox.sY+actorPos.vy)/512);

//		hitBox.pX+=10*4096;
//		hitBox.pZ+=10*4096;

//		hitBox.sX-=20*4096;
//		hitBox.sZ-=20*4096;
	}
	else camVars.objectHeight=0;

	//DB("quad %d\n",camVars.quadrant);

	switch (camVars.quadrant)
	{
		case	1:
			scale2=(actorPos.vz-camPos.vz)>>9;
			scale1=(actorPos.vz-(hitBox.pZ+hitBox.sZ))>>9;
			if (scale1<0 || scale2<0)
			{
				camVars.requiredDistance=camVars.lookDistance;
				camVars.objectHeight=0;
				camVars.requiredHeight=camVars.normalHeight;
				break;
			}
			if ( scale2>scale1)
			{
				camVars.requiredDistance=(camVars.lookDistance*(scale1))/(scale2);
			}
			else
			{
				camVars.requiredDistance=camVars.lookDistance;
				camVars.objectHeight=0;
				camVars.requiredHeight=camVars.normalHeight;
			}
			break;

		case	2:
			scale2=(actorPos.vx-camPos.vx)>>9;
			scale1=(actorPos.vx-(hitBox.pX+hitBox.sX))>>9;
			//DB("scale1 %d scale2 %d\n",scale1,scale2);
			if (scale1<0 || scale2<0)
			{
				camVars.requiredDistance=camVars.lookDistance;
				camVars.objectHeight=0;
				camVars.requiredHeight=camVars.normalHeight;
				break;
			}
			if ( scale2>scale1)
			{
				camVars.requiredDistance=(camVars.lookDistance*(scale1))/(scale2);
			}
			else
			{
				camVars.requiredDistance=camVars.lookDistance;
				camVars.objectHeight=0;
				camVars.requiredHeight=camVars.normalHeight;
			}
			break;

		case	3:
			scale2=(camPos.vz-actorPos.vz)>>9;
			scale1=(hitBox.pZ-actorPos.vz)>>9;
			if (scale1<0 || scale2<0)
			{
				camVars.requiredDistance=camVars.lookDistance;
				camVars.objectHeight=0;
				camVars.requiredHeight=camVars.normalHeight;
				break;
			}
			if (scale2==0) scale2=scale1;
			if ( scale2>scale1)
			{
				camVars.requiredDistance=(camVars.lookDistance*(scale1))/(scale2);
			}
			else
			{
				camVars.requiredDistance=camVars.lookDistance;
				camVars.objectHeight=0;
				camVars.requiredHeight=camVars.normalHeight;
			}
			break;

		case	4:
			scale2=(camPos.vx-actorPos.vx)>>9;
			scale1=(hitBox.pX-actorPos.vx)>>9;
			if (scale1<0 || scale2<0)
			{
				camVars.requiredDistance=camVars.lookDistance;
				camVars.objectHeight=0;
				camVars.requiredHeight=camVars.normalHeight;
				break;
			}
			if (scale2==0) scale2=scale1;
			if ( (scale2)>(scale1))
			{
				//DB ("scale1 %d scale2 %d \n",scale1,scale2);
				camVars.requiredDistance=(camVars.lookDistance*(scale1))/(scale2);
			}
			else
			{
				camVars.requiredDistance=camVars.lookDistance;
				camVars.objectHeight=0;
				camVars.requiredHeight=camVars.normalHeight;
			}
			break;
	}

	if (camVars.quadrant==0)
	{
		camVars.swingDirection=NULL;
		camVars.requiredHeight=camVars.normalHeight;
	}
}

////////////////////////////////////////////////////////////////////////////
//	Checks to see if target out of view and changes distance acordingly
//	Test verient for inside camera
void	checkObstructionsRotate2(CAMVARS *CamVars)
{
	int	dz1,dy1,dz2,dy2,dy3,dx1;
	int	height;
	VECTOR	camPos,actorPos;
	int	position=0;
	int	position1=0;
	int	scale1,scale2;

	int	dist;

	camPos.vx=camVars.camPos2.vx;
	camPos.vy=camVars.camPos2.vy;
	camPos.vz=camVars.camPos2.vz;

	actorPos.vx=CamVars->targetEnemy->pos.vx*512;
	actorPos.vy=(CamVars->targetEnemy->pos.vy-HEIGHTOFFSET)*512;
	actorPos.vz=CamVars->targetEnemy->pos.vz*512;

	//DB("rot 2 test start\n");
	CamVars->specialDist=findClosestBox(actorPos.vx,actorPos.vy,actorPos.vz,camPos.vx,camPos.vy,camPos.vz,&hitBox,FALSE);
	//DB("dist %d\n",dist);
	

	if ( actorPos.vy < (hitBox.pY+hitBox.sY) )
	{
		camVars.quadrant=0;	// cam not above another box
//		camVars.requiredDistance=camVars.lookDistance;
	}
	else
		camVars.quadrant=findQuadrant(camPos,actorPos);

	if (camVars.quadrant)
	{
		camVars.lastQuadrant=camVars.quadrant;
//		camVars.requiredHeight=camVars.normalHeight-((hitBox.pY+hitBox.sY+actorPos.vy)/512);
	}
	else camVars.objectHeight=0;

	switch (camVars.quadrant)
	{
		case	1:
			scale2=(actorPos.vz-camPos.vz)>>9;
			scale1=(actorPos.vz-(hitBox.pZ+hitBox.sZ))>>9;
			if ( scale2>scale1)
			{
				camVars.requiredDistance=(camVars.lookDistance*(scale1))/(scale2);
			}
			else
			{
				camVars.requiredDistance=camVars.lookDistance;
				//camVars.objectHeight=0;
				//camVars.requiredHeight=camVars.normalHeight;
			}
			break;

		case	2:
			scale2=(actorPos.vx-camPos.vx)>>9;
			scale1=(actorPos.vx-(hitBox.pX+hitBox.sX))>>9;
			if ( scale2>scale1)
			{
				camVars.requiredDistance=(camVars.lookDistance*(scale1))/(scale2);
			}
			else
			{
				camVars.requiredDistance=camVars.lookDistance;
				//camVars.objectHeight=0;
				//camVars.requiredHeight=camVars.normalHeight;
			}
			break;

		case	3:
			scale2=(camPos.vz-actorPos.vz)>>9;
			scale1=(hitBox.pZ-actorPos.vz)>>9;
			if (!scale2) break;	// due to cam starting inside box
			if ( scale2>scale1)
			{
				camVars.requiredDistance=(camVars.lookDistance*(scale1))/(scale2);
			}
			else
			{
				camVars.requiredDistance=camVars.lookDistance;
				//camVars.objectHeight=0;
				//camVars.requiredHeight=camVars.normalHeight;
			}
			break;

		case	4:
			scale2=(camPos.vx-actorPos.vx)>>9;
			scale1=(hitBox.pX-actorPos.vx)>>9;
			if ( (scale2)>(scale1))
			{
				camVars.requiredDistance=(camVars.lookDistance*(scale1))/(scale2);
			}
			else
			{
				camVars.requiredDistance=camVars.lookDistance;
				//camVars.objectHeight=0;
				//camVars.requiredHeight=camVars.normalHeight;
			}
			break;
	}

	if (camVars.quadrant==0)
	{
		camVars.swingDirection=NULL;
		camVars.requiredHeight=camVars.normalHeight;
	}

}


////////////////////////////////////////////////////////////////////////////
//	works out which quadrant to do distance calcs in
//int	dx,dz,dx1,dz1;	// here only so debuger reports them

int		findQuadrant(VECTOR	camPos,VECTOR actorPos)
{
	int	gradient,gradient2;
	int	minX,maxX,minZ,maxZ,camDx,camDz,dx,dz,temp;
	int	quadrant=0;

	minX=hitBox.pX;
	maxX=hitBox.pX+hitBox.sX;
	minZ=hitBox.pZ;
	maxZ=hitBox.pZ+hitBox.sZ;

	// See if we can get away with quick checks
	if ( (actorPos.vx>minX) && (actorPos.vx<maxX) )
	{
		if (actorPos.vz<minZ) quadrant=3;
		else quadrant=1;
	}
	if ( (actorPos.vz>minZ) && (actorPos.vz<maxZ) )
	{
		if (actorPos.vx<minX) quadrant=4;
		else quadrant=2;
	}
	if (!quadrant)	// ok now do the complex stuff
	{
		camDx=camPos.vx-actorPos.vx;
		temp=camDz=camPos.vz-actorPos.vz;

		camDz=camDz/4096;

		if (!camDz)	// check to stop divide by 0
		{
			if (temp<0) camDz=-1;
			else camDz=1;
		}
		gradient=camDx/camDz;

		if ( (camDx<0) && (camDz<0) )
		{
			dx=maxX-actorPos.vx;
			temp=dz=maxZ-actorPos.vz;
			dz=dz/4096;
			if (!dz)
			{
				if (temp<0) dz=-1;
				else dz=1;
			}
			gradient2=dx/dz;
			if (gradient<gradient2) quadrant=2;
			else quadrant=1;
			//printf ("gr %d gr2 %d\n",gradient,gradient2);
		}
		if  ( (camDx<0) && (camDz>0) )
		{
			dx=maxX-actorPos.vx;
			temp=dz=minZ-actorPos.vz;
			dz=dz/4096;
			if (!dz)
			{
				if (temp<0) dz=-1;
				else dz=1;
			}
			gradient2=dx/dz;
			if (gradient<gradient2) quadrant=3;
			else quadrant=2;
			//printf ("gr %d gr2 %d\n",gradient,gradient2);
		}
		if ( (camDx>0) && (camDz>0) )
		{
			dx=minX-actorPos.vx;
			temp=dz=minZ-actorPos.vz;
			dz=dz/4096;
			if (!dz)
			{
				if (temp<0) dz=-1;
				else dz=1;
			}
			gradient2=dx/dz;
			if (gradient>gradient2) quadrant=3;
			else quadrant=4;
			//printf ("gr %d gr2 %d\n",gradient,gradient2);
		}
		if ( (camDx>0) && (camDz<0) )
		{
			dx=minX-actorPos.vx;
			temp=dz=maxZ-actorPos.vz;
			dz=dz/4096;
			if (!dz)
			{
				if (temp<0) dz=-1;
				else dz=1;
			}
			gradient2=dx/dz;
			if (gradient<gradient2) quadrant=1;
			else quadrant=4;
			//printf ("gr %d gr2 %d\n",gradient,gradient2);
		}
	}
	return(quadrant);
}

////////////////////////////////////////////////////////////////////////////
//	Performs bog standard north looking camera

void	standardCamera(CAMVARS *CamVars)
{
	mycamera.vry=(CamVars->targetEnemy->pos.vy-HEIGHTOFFSET)-CamVars->targetRadius/8;

	mycamera.vrx=CamVars->targetEnemy->pos.vx;
	mycamera.vrz=CamVars->targetEnemy->pos.vz;

	mycamera.vpx=mycamera.vrx;
	mycamera.vpy=mycamera.vry-CamVars->camHeight;
	mycamera.vpz=mycamera.vrz-(CamVars->camDistance);
}

////////////////////////////////////////////////////////////////////////////
//	swing cam behind chicken (mainly here for test perpasses) as it turns out this is going to be the main cam type
//	int	test1,test2,test3,test4;

//#define	USEDEADZONE
//#define	JUMPMOD
#define	DEADZONE	400


void	swingCameraOutside(CAMVARS *CamVars)
{
	int	angle,angle1;
	VECTOR	temp,cam;
	int	mag,temp1,temp2;
	int	rotFlag=FALSE;

	if (!camVars.holdPositionFlag)
	{
		camVars.holdPosition.vx=mycamera.vpx;
		camVars.holdPosition.vy=mycamera.vpy;
		camVars.holdPosition.vz=mycamera.vpz;
	}

#ifdef	JUMPMOD
	if (CamVars->targetEnemy->state==STATE_JUMPING)	// if chicken jumping
	{
		if (!camVars.offGroundFlag)
		{
			camVars.offGroundFlag=TRUE;
			camVars.offGroundPos=mycamera.vry;
		}
	}
#endif


#ifndef	USEDEADZONE	
	mycamera.vry=(CamVars->targetEnemy->pos.vy-HEIGHTOFFSET)-CamVars->targetRadius/8;
	mycamera.vrx=CamVars->targetEnemy->pos.vx;
	mycamera.vrz=CamVars->targetEnemy->pos.vz;
#else

	mycamera.vry=cam.vy=(CamVars->targetEnemy->pos.vy-HEIGHTOFFSET)-CamVars->targetRadius/8;
	cam.vx=CamVars->targetEnemy->pos.vx;
	cam.vz=CamVars->targetEnemy->pos.vz;

	temp.vx=testDeadZone.vx-cam.vx;
	temp.vz=testDeadZone.vz-cam.vz;
	temp.vy=0;
	mag=Magnitude2D(temp.vx,temp.vz);

	if (mag>DEADZONE)
	{
		mag=mag-DEADZONE;
		MakeUnit(&temp);
		SCALEVECTOR(&temp,mag);

		mycamera.vrx-=temp.vx;
		mycamera.vrz-=temp.vz;
		testDeadZone.vx-=temp.vx;
		testDeadZone.vz-=temp.vz;
		//cam.vx+=temp.vx;
		//cam.vz+=temp.vz;
	}
#endif	


	if (camVars.offGroundFlag)
		mycamera.vry=camVars.offGroundPos;

/*	temp.vx=0;
	temp.vy=0;
	temp.vz=-(camVars.targetEnemy->moveSpeed/32);

	RotateVector2D(&temp,&temp,CamVars->targetEnemy->dir);

	mycamera.vrx+=temp.vx;
	mycamera.vry+=temp.vy;
	mycamera.vrz+=temp.vz;
*/

	angle=utilCalcAngle( (mycamera.vpx-mycamera.vrx),(mycamera.vpz-mycamera.vrz) );
	CamVars->camAngle=(angle+2048)&4095;

	temp.vx=mycamera.vpx-mycamera.vrx;
	temp.vy=0;
	temp.vz=mycamera.vpz-mycamera.vrz;
	mag=Magnitude(&temp);

	if (mag==0) mag=1;

	if (!temp.vx && !temp.vz)
		temp.vx=1;

	temp1=CamVars->lookDistance;
	if (temp1)
	{
		temp.vx=(temp.vx*temp1)/mag;
		temp.vy=(temp.vy*temp1)/mag;
		temp.vz=(temp.vz*temp1)/mag;
	}
	temp1 = findShortestAngle(CamVars->camAngle+2048,(CamVars->targetEnemy->dir&4095));

	mag=abs(CamVars->camAngle-(CamVars->targetEnemy->dir&4095));


//	if (CamVars->area==OUTSIDE)
//	{

	if (mag<512) temp1=0;
	if (mag<1024 && mag>=512)
	{
		mag-=512;
		temp1=(temp1*mag)/512;
	}
	if (abs(temp1)<128) temp1=0;
	//temp1=(temp1*testchar_speed)/5000;
	temp1=(temp1*camVars.targetEnemy->moveSpeed)/5000;
	//DB("speed = %d\n",camVars.targetEnemy->moveSpeed);

/*	}
	else if (CamVars->area==INSIDE)
	{
		mag=abs(CamVars->camAngle-CamVars->targetModel->psiData.object->rotate.vy);
		if (mag>512) mag=512;
		if (mag<-512) mag=-512;
//	}

*/
	//if (CamVars->flags&FIXEDROT) temp1=0;

	if (CamVars->flags&LEVELSTARTFIXEDROT)
	{
		//DB("processing start cam angle\n");
		//CamVars->camAngle=CamVars->fixedAngle;
		temp2=findShortestAngle(CamVars->camAngle,CamVars->fixedAngle);
		RotateVector2D(&temp, &temp, -temp2);
	}
	else
	{
		if (! (CamVars->flags&FIXEDROT) )
		{
			int	dx;
			dx = padData.analogX2S[0] >> 2;

			if (dx)
			{
				temp1=dx;
				camVars.holdPosition.vx=-9999;	// This stops the camera frezzing with small movments
			}
			else
			{
				if (padData.digital[0] & PAD_R1)
				{
					temp1+=1024;
					camVars.holdPosition.vx=-9999;	// This stops the camera frezzing with small movments
				}
				if (padData.digital[0] & PAD_L1)
				{
					temp1-=1024;
					camVars.holdPosition.vx=-9999;	// This stops the camera frezzing with small movments
				}
			}
			RotateVector2D(&temp, &temp, -temp1/32);
		}
		//if (CamVars->flags&FIXEDROT)
		else
		{
			temp1=0;
			temp2=findShortestAngle(CamVars->camAngle,CamVars->fixedAngle);
			if (temp2>256) temp2=256;
			if (temp2<-256) temp2=-256;

			temp1=temp2/4;
			//DB("temp1 %d temp2 %d\n",temp1,temp2);
			RotateVector2D(&temp, &temp, -temp1);
		}
	}


	camVars.camPos2.vx=(mycamera.vrx+temp.vx)*512;
	camVars.camPos2.vz=(mycamera.vrz+temp.vz)*512;
	camVars.camPos2.vy=(mycamera.vry-CamVars->actualHeight)*512;

	temp1=CamVars->actualDistance;
	mag=Magnitude(&temp);
	if (mag==0) mag=1;

	if (temp1)
	{
		temp.vx=(temp.vx*temp1)/mag;
		temp.vy=(temp.vy*temp1)/mag;
		temp.vz=(temp.vz*temp1)/mag;
	}

	mycamera.vpx=mycamera.vrx+temp.vx;
	mycamera.vpz=mycamera.vrz+temp.vz;
	mycamera.vpy=mycamera.vry-CamVars->actualHeight;

//	if (camVars.offGroundFlag)
//		mycamera.vry=camVars.offGroundPos;

#ifdef	JUMPMOD
	if (camVars.offGroundFlag && CamVars->targetEnemy->state!=STATE_JUMPING)
	{
		int	change;
		change=mycamera.vry-(CamVars->targetEnemy->pos.vy-HEIGHTOFFSET)-CamVars->targetRadius/8;
		camVars.offGroundPos-=change/10;
	}
#endif
}

////////////////////////////////////////////////////////////////////////////
// swing camera for inside rooms
// int	deltaX,deltaZ;

void	swingCameraInside(CAMVARS *CamVars)
{
	int	angle,angle1;
	VECTOR	temp,camPos,actorPos,oldCamPos,newVect;
	int	mag,temp1,temp2,oldDist;
	int	rotFlag=FALSE;
	int	checkVal,point;

	oldDist=CamVars->camDistance;
	if (!camVars.holdPositionFlag)
	{
		camVars.holdPosition.vx=mycamera.vpx;
		camVars.holdPosition.vy=mycamera.vpy;
		camVars.holdPosition.vz=mycamera.vpz;
	}
	
	mycamera.vry=(CamVars->targetEnemy->pos.vy-HEIGHTOFFSET)-CamVars->targetRadius/8;
	mycamera.vrx=CamVars->targetEnemy->pos.vx;
	mycamera.vrz=CamVars->targetEnemy->pos.vz;

	angle=utilCalcAngle( (mycamera.vpx-mycamera.vrx),(mycamera.vpz-mycamera.vrz) );
	CamVars->camAngle=(angle+2048)&4095;

	temp.vx=mycamera.vpx-mycamera.vrx;
	temp.vy=0;
	temp.vz=mycamera.vpz-mycamera.vrz;
	mag=Magnitude(&temp);

	if (mag==0) mag=1;

	if (!temp.vx && !temp.vz)
		temp.vx=1;

	temp1=CamVars->lookDistance;
	if (temp1)
	{
		temp.vx=(temp.vx*temp1)/mag;
		temp.vy=(temp.vy*temp1)/mag;
		temp.vz=(temp.vz*temp1)/mag;
	}

	CamVars->oldRequiredDistance=CamVars->requiredDistance;

	checkObstructionsRotate2(CamVars);

	if ( (CamVars->oldRequiredDistance-CamVars->requiredDistance) >500)
	{
		//checkObstructionsRotate2(CamVars);
		//DB("doing checks\n"); 
		actorPos.vx=CamVars->targetEnemy->pos.vx*512;
		actorPos.vy=(CamVars->targetEnemy->pos.vy-HEIGHTOFFSET)*512;
		actorPos.vz=CamVars->targetEnemy->pos.vz*512;
		
		camPos.vx=camVars.camPos2.vx;
		camPos.vy=camVars.camPos2.vy;
		camPos.vz=camVars.camPos2.vz;

		point=findPointToUse(actorPos,camPos);

		//checkVal=CamVars->lookDistance>>5;

		hitBox.pX+=4096*10;	// move points in a bit (helps with judder)
		hitBox.pZ+=4096*10;
		hitBox.sX-=4096*20;
		hitBox.sZ-=4096*20;

		newVect.vy=0;
		switch(point)
		{
			case 1:
				//DB("point 1\n");
				newVect.vx=hitBox.pX-actorPos.vx;
				newVect.vz=(hitBox.pZ+hitBox.sZ)-actorPos.vz;
				break;
			case 2:
				//DB("point 2\n");
				newVect.vx=(hitBox.pX+hitBox.sX)-actorPos.vx;
				newVect.vz=(hitBox.pZ+hitBox.sZ)-actorPos.vz;
				break;
			case 3:
				//DB("point 3\n");
				newVect.vx=(hitBox.pX+hitBox.sX)-actorPos.vx;
				newVect.vz=hitBox.pZ-actorPos.vz;
				break;
			case 4:
				//DB("point 4\n");
				newVect.vx=hitBox.pX-actorPos.vx;
				newVect.vz=hitBox.pZ-actorPos.vz;
				break;

			case 5:
				//DB("special\n");
				if (!CamVars->special && CamVars->requiredDistance<1000)
				{
					CamVars->specialTime=15;
					CamVars->special=1;
				}
				else if (!CamVars->special) CamVars->special=2;
				break;
		}

		//temp1=CamVars->actualDistance;
		//if (special) temp1=CamVars->requiredDistance;
		temp1=CamVars->lookDistance;

		//mag=Magnitude(&temp);	// this method causes overflows
		MakeUnit(&newVect);
		mag=4096;
		if (temp1)
		{
			newVect.vx=(newVect.vx*temp1)/mag;
			newVect.vy=(newVect.vy*temp1)/mag;
			newVect.vz=(newVect.vz*temp1)/mag;

			switch(point)
			{
				case	1:
				case	4:
					if (newVect.vx<temp.vx)
					{
						temp.vx=newVect.vx;
						temp.vy=newVect.vy;
						temp.vz=newVect.vz;
					}
					break;

				case	2:
				case	3:
					if (newVect.vx>temp.vx)
					{
						temp.vx=newVect.vx;
						temp.vy=newVect.vy;
						temp.vz=newVect.vz;
					}
					break;
			}

			if (!CamVars->special) CamVars->requiredDistance=CamVars->oldRequiredDistance;
			//else CamVars->actualDistance=CamVars->requiredDistance;
			else camVars.actualDistance+=(camVars.requiredDistance-camVars.actualDistance)/4;
		}
	}
/////////
	actorPos.vx=CamVars->targetEnemy->pos.vx*512;
	actorPos.vy=(CamVars->targetEnemy->pos.vy-HEIGHTOFFSET)*512;
	actorPos.vz=CamVars->targetEnemy->pos.vz*512;

	oldCamPos.vx=CamVars->camPos2.vx;
	oldCamPos.vy=CamVars->camPos2.vy;
	oldCamPos.vz=CamVars->camPos2.vz;

//	oldCamPos.vx=CamVars->camPos2.vx-actorPos.vx;
//	oldCamPos.vy=CamVars->camPos2.vy-actorPos.vy;
//	oldCamPos.vz=CamVars->camPos2.vz-actorPos.vz;

	temp1 = findShortestAngle(CamVars->camAngle+2048,(CamVars->targetEnemy->dir&4095));
	//if (!testchar_speed) CamVars->inactiveTime++;
	if (!camVars.targetEnemy->moveSpeed) CamVars->inactiveTime++;
	else CamVars->inactiveTime=0;

	if (CamVars->inactiveTime<30)
	{
		mag=abs(CamVars->camAngle-(CamVars->targetEnemy->dir&4095));

		if (mag<512) temp1=0;
		if (mag<1024 && mag>=512)
		{
			mag-=512;
			if ( (camVars.oldRequiredDistance-camVars.requiredDistance) > 1000 ) mag*=5;
			temp1=(temp1*mag)/512;
		}
		//temp1=(temp1*testchar_speed)/2500;//5000;
		temp1=(temp1*camVars.targetEnemy->moveSpeed)/SWINGSPEEDMOD;//5000;
	}
	else
	{
		if (CamVars->inactiveTime<60)
			temp1=(temp1*CamVars->inactiveTime)/120;
		else
			temp1=temp1/2;
	}

	if (CamVars->flags&FIXEDROT) temp1=0;

	if (padData.digital[0] & PAD_R1)
	{
		temp1+=512;
		CamVars->inactiveTime=0;
	}
	if (padData.digital[0] & PAD_L1)
	{
		temp1-=512;
		CamVars->inactiveTime=0;
	}

//	if (CamVars->requiredDistance>1000)	// if final pos of cam too short dont move
		RotateVector2D(&temp, &temp, -temp1/32);

	if (CamVars->special==1)
	{
		CamVars->specialTime--;
		if (!CamVars->specialTime) CamVars->special=FALSE;
		if (CamVars->specialTime<10)
		{
			if (CamVars->specialDirection==LEFT)
				RotateVector2D(&temp, &temp, -51);
			else
				RotateVector2D(&temp, &temp, 51);
		}
	}

	if (CamVars->special==2) CamVars->special=0;

	if (CamVars->flags&FIXEDROT)
	{
		temp2=findShortestAngle(CamVars->camAngle,CamVars->fixedAngle);
		if (temp2>256) temp2=256;
		if (temp2<-256) temp2=-256;

		temp1=temp2/4;
		//DB("temp1 %d temp2 %d\n",temp1,temp2);
		RotateVector2D(&temp, &temp, -temp1);
	}

	camVars.camPos2.vx=(mycamera.vrx+temp.vx)*512;
	camVars.camPos2.vz=(mycamera.vrz+temp.vz)*512;
	camVars.camPos2.vy=(mycamera.vry-CamVars->actualHeight)*512;

	temp1=CamVars->requiredDistance;
	checkObstructionsRotate(CamVars);

	//DB("dist change %d\n",CamVars->requiredDistance-temp1);

	if (CamVars->requiredDistance<temp1 && CamVars->requiredDistance<1000)	// theres a problem here somewhere
	{
		//DB("staying at old possition\n");
		CamVars->camPos2.vx=oldCamPos.vx;
		CamVars->camPos2.vy=oldCamPos.vy;
		CamVars->camPos2.vz=oldCamPos.vz;

		temp.vx=(CamVars->camPos2.vx-actorPos.vx)/512;
		temp.vy=(CamVars->camPos2.vy-actorPos.vy)/512;
		temp.vz=(CamVars->camPos2.vz-actorPos.vz)/512;
	}
	CamVars->requiredDistance=temp1;

	temp1=CamVars->actualDistance;
	mag=Magnitude(&temp);

	if (temp1)
	{
		temp.vx=(temp.vx*temp1)/mag;
		temp.vy=(temp.vy*temp1)/mag;
		temp.vz=(temp.vz*temp1)/mag;
	}

	mycamera.vpx=mycamera.vrx+temp.vx;
	mycamera.vpz=mycamera.vrz+temp.vz;
	mycamera.vpy=mycamera.vry-CamVars->actualHeight;
}

////////////////////////////////////////////////////////////////////////////
// Find the point on collbox to swing cam around
int		findPointToUse(VECTOR actorPos,VECTOR camPos)
{
	VECTOR	main,p1,p2,p3;
	int		dot1,dot2,dot3;

//	int	deltaX,deltaZ;
//	deltaX=ABS(camPos.vx-actorPos.vx);
//	deltaZ=ABS(camPos.vz-actorPos.vz);

	main.vx=camPos.vx-actorPos.vx;
	//main.vy=camPos.vy-actorPos.vy;
	main.vy=0;
	main.vz=camPos.vz-actorPos.vz;

	MakeUnit(&main);

	if (actorPos.vx<hitBox.pX)	// to left of box
	{
		//DB("left\n");
		if (actorPos.vz<hitBox.pZ)  // bottom of box
		{
			//DB("bottom\n");
			p1.vx=hitBox.pX-actorPos.vx;
			p1.vy=0;
			p1.vz=(hitBox.pZ+hitBox.sZ)-actorPos.vz;

			p2.vx=(hitBox.pX+hitBox.sX)-actorPos.vx;
			p2.vy=0;
			p2.vz=hitBox.pZ-actorPos.vz;

			p3.vx=(hitBox.pX+hitBox.sX/2)-actorPos.vx;
			p3.vy=0;
			p3.vz=(hitBox.pZ+hitBox.sZ/2)-actorPos.vz;

			MakeUnit(&p1);
			MakeUnit(&p2);
			MakeUnit(&p3);
			dot1=DotProduct(&main, &p1);
			dot2=DotProduct(&main, &p2);
			dot3=DotProduct(&main, &p3);
			//DB("dot1 %d dot2 %d dot3 %d\n",dot1,dot2,dot3);
			if ( (dot3>dot2) && (dot3>dot1) )
			{
				if (dot2>dot1) camVars.specialDirection=RIGHT;
				else camVars.specialDirection=LEFT;
				return(5);
			}
			else if (dot1>dot2) return (1);
			else return(3);
		}
		else if (actorPos.vz > (hitBox.pZ+hitBox.sZ) ) // top of box
		{
			//DB("top\n");
			//if (deltaX>deltaZ) return(2);
			p1.vx=(hitBox.pX+hitBox.sX)-actorPos.vx;
			p1.vy=0;
			p1.vz=(hitBox.pZ+hitBox.sZ)-actorPos.vz;

			p2.vx=hitBox.pX-actorPos.vx;
			p2.vy=0;
			p2.vz=hitBox.pZ-actorPos.vz;

			p3.vx=(hitBox.pX+hitBox.sX/2)-actorPos.vx;
			p3.vy=0;
			p3.vz=(hitBox.pZ+hitBox.sZ/2)-actorPos.vz;

			MakeUnit(&p1);
			MakeUnit(&p2);
			MakeUnit(&p3);
			dot1=DotProduct(&main, &p1);
			dot2=DotProduct(&main, &p2);
			dot3=DotProduct(&main, &p3);
			//DB("dot1 %d dot2 %d\n",dot1,dot2);
			if ( (dot3>dot2) && (dot3>dot1) )
			{
				if (dot2>dot1) camVars.specialDirection=RIGHT;
				else camVars.specialDirection=LEFT;
				return(5);
			}
			else if (dot1>dot2) return (2);
			else return(4);
		}
		else
		{
			//DB("central\n");
			p1.vx=hitBox.pX-actorPos.vx;
			p1.vy=0;
			p1.vz=(hitBox.pZ+hitBox.sZ)-actorPos.vz;

			p2.vx=hitBox.pX-actorPos.vx;
			p2.vy=0;
			p2.vz=hitBox.pZ-actorPos.vz;

			p3.vx=hitBox.pX-actorPos.vx;
			p3.vy=0;
			p3.vz=(hitBox.pZ+hitBox.sZ/2)-actorPos.vz;

			MakeUnit(&p1);
			MakeUnit(&p2);
			MakeUnit(&p3);
			dot1=DotProduct(&main, &p1);
			dot2=DotProduct(&main, &p2);
			dot3=DotProduct(&main, &p3);

			if ( (dot3>dot2) && (dot3>dot1) )
			{
				if (dot2>dot1) camVars.specialDirection=RIGHT;
				else camVars.specialDirection=LEFT;
				return(5);
			}
			else if (dot1>dot2) return (1);
			else return(4);
			//if (camPos.vz<(hitBox.pZ+hitBox.sZ/2)) return(4);
			//else return(1);
		}
	}
	else if (actorPos.vx>(hitBox.pX+hitBox.sX)) // right of box
	{
		//DB("right\n");
		if (actorPos.vz<hitBox.pZ)  // bottom of box
		{
			//DB("bottom\n");
			p1.vx=(hitBox.pX+hitBox.sX)-actorPos.vx;
			p1.vy=0;
			p1.vz=(hitBox.pZ+hitBox.sZ)-actorPos.vz;

			p2.vx=hitBox.pX-actorPos.vx;
			p2.vy=0;
			p2.vz=hitBox.pZ-actorPos.vz;

			p3.vx=(hitBox.pX+hitBox.sX/2)-actorPos.vx;
			p3.vy=0;
			p3.vz=(hitBox.pZ+hitBox.sZ/2)-actorPos.vz;

			MakeUnit(&p1);
			MakeUnit(&p2);
			MakeUnit(&p3);
			dot1=DotProduct(&main, &p1);
			dot2=DotProduct(&main, &p2);
			dot3=DotProduct(&main, &p3);
			//DB("dot1 %d dot2 %d\n",dot1,dot2);
			if ( (dot3>dot2) && (dot3>dot1) )
			{
				if (dot2>dot1) camVars.specialDirection=LEFT;
				else camVars.specialDirection=RIGHT;
				return(5);
			}
			else if (dot1>dot2) return (2);
			else return(4);
		}
		else if (actorPos.vz > (hitBox.pZ+hitBox.sZ) ) // top of box
		{
			//DB("top\n");
			p1.vx=hitBox.pX-actorPos.vx;
			p1.vy=0;
			p1.vz=(hitBox.pZ+hitBox.sZ)-actorPos.vz;

			p2.vx=(hitBox.pX+hitBox.sX)-actorPos.vx;
			p2.vy=0;
			p2.vz=hitBox.pZ-actorPos.vz;

			p3.vx=(hitBox.pX+hitBox.sX/2)-actorPos.vx;
			p3.vy=0;
			p3.vz=(hitBox.pZ+hitBox.sZ/2)-actorPos.vz;

			MakeUnit(&p1);
			MakeUnit(&p2);
			MakeUnit(&p3);
			dot1=DotProduct(&main, &p1);
			dot2=DotProduct(&main, &p2);
			dot3=DotProduct(&main, &p3);
			//DB("dot1 %d dot2 %d\n",dot1,dot2);
			if ( (dot3>dot2) && (dot3>dot1) )
			{
				if (dot2>dot1) camVars.specialDirection=LEFT;
				else camVars.specialDirection=RIGHT;
				return(5);
			}
			else if (dot1>dot2) return (1);
			else return(3);
		}
		else
		{
			//DB("central\n");
			p1.vx=(hitBox.pX+hitBox.sX)-actorPos.vx;
			p1.vy=0;
			p1.vz=(hitBox.pZ+hitBox.sZ)-actorPos.vz;

			p2.vx=(hitBox.pX+hitBox.sX)-actorPos.vx;
			p2.vy=0;
			p2.vz=hitBox.pZ-actorPos.vz;

			p3.vx=(hitBox.pX+hitBox.sX)-actorPos.vx;
			p3.vy=0;
			p3.vz=(hitBox.pZ+hitBox.sZ/2)-actorPos.vz;

			MakeUnit(&p1);
			MakeUnit(&p2);
			MakeUnit(&p3);
			dot1=DotProduct(&main, &p1);
			dot2=DotProduct(&main, &p2);
			dot3=DotProduct(&main, &p3);

			if ( (dot3>dot2) && (dot3>dot1) )
			{
				if (dot2>dot1) camVars.specialDirection=LEFT;
				else camVars.specialDirection=RIGHT;
				return(5);
			}
			else if (dot1>dot2) return (2);
			else return(3);
			//if (camPos.vz<(hitBox.pZ+hitBox.sZ/2)) return(3);
			//else return(2);
		}
	}
	else	// must be top of bottom only
	{
		//DB("central\n");
		if (actorPos.vz<hitBox.pZ)	// bottom
		{
			//DB("bottom\n");
			p1.vx=hitBox.pX-actorPos.vx;
			p1.vy=0;
			p1.vz=hitBox.pZ-actorPos.vz;

			p2.vx=(hitBox.pX+hitBox.sX)-actorPos.vx;
			p2.vy=0;
			p2.vz=hitBox.pZ-actorPos.vz;

			p3.vx=(hitBox.pX+hitBox.sX/2)-actorPos.vx;
			p3.vy=0;
			p3.vz=hitBox.pZ-actorPos.vz;

			MakeUnit(&p1);
			MakeUnit(&p2);
			MakeUnit(&p3);
			dot1=DotProduct(&main, &p1);
			dot2=DotProduct(&main, &p2);
			dot3=DotProduct(&main, &p3);

			if ( (dot3>dot2) && (dot3>dot1) )
			{
				if (dot2>dot1) camVars.specialDirection=RIGHT;
				else camVars.specialDirection=LEFT;
				return(5);
			}
			else if (dot1>dot2) return (4);
			else return(3);

			//if (camPos.vx<(hitBox.pX+hitBox.sX/2)) return(4);
			//else return(3);
		}
		else // top (or a big *!%* up and we're inside the box)
		{
			//DB("top\n");
			p1.vx=hitBox.pX-actorPos.vx;
			p1.vy=0;
			p1.vz=(hitBox.pZ+hitBox.sZ)-actorPos.vz;

			p2.vx=(hitBox.pX+hitBox.sX)-actorPos.vx;
			p2.vy=0;
			p2.vz=(hitBox.pZ+hitBox.sZ)-actorPos.vz;

			p3.vx=(hitBox.pX+hitBox.sX/2)-actorPos.vx;
			p3.vy=0;
			p3.vz=(hitBox.pZ+hitBox.sZ)-actorPos.vz;

			MakeUnit(&p1);
			MakeUnit(&p2);
			MakeUnit(&p3);
			dot1=DotProduct(&main, &p1);
			dot2=DotProduct(&main, &p2);
			dot3=DotProduct(&main, &p3);

			if ( (dot3>dot2) && (dot3>dot1) )
			{
				if (dot2>dot1) camVars.specialDirection=LEFT;
				else camVars.specialDirection=RIGHT;
				return(5);
			}
			else if (dot1>dot2) return (1);
			else return(2);
			//if (camPos.vx<(hitBox.pX+hitBox.sX/2)) return(1);
			//else return(2);
		}
	}
}



////////////////////////////////////////////////////////////////////////////
// Moves the camera along a rail
void	railCamera(void)
{

	DB("this routine has been removed \n");
	ASSERT(0);

/*
	VECTOR	startPoint,endPoint;
	VECTOR	camPos,actorPos,temp;
	int		distance,angle,distance1,temp1,temp2,distance2,test;

	int		direction;	// for faceing
//	line along X axis

	//direction=camVars.railCamDirection;
	if (camVars.railCamDirection>0) direction=1;
	else direction=-1;

	test=TRUE;

	//camVars.railCamAxis=TRUE;
	//camVars.railCamAxis=FALSE;
	//camVars.lookDistance=2000;

	if (camVars.railCamAxis) //1=x axis 0=z axis
	{
		startPoint.vx=camVars.railCamPoint.vx+2000;
		startPoint.vy=camVars.railCamPoint.vy;
		startPoint.vz=camVars.railCamPoint.vz;

		endPoint.vx=camVars.railCamPoint.vx-2000;
		endPoint.vy=camVars.railCamPoint.vy;
		endPoint.vz=camVars.railCamPoint.vz;
	}
	else
	{
		startPoint.vx=camVars.railCamPoint.vx;
		startPoint.vy=camVars.railCamPoint.vy;
		startPoint.vz=camVars.railCamPoint.vz+2000;

		endPoint.vx=camVars.railCamPoint.vx;
		endPoint.vy=camVars.railCamPoint.vy;
		endPoint.vz=camVars.railCamPoint.vz-2000;
	}

	mycamera.vrx=camVars.targetEnemy->pos.vx;
	mycamera.vry=camVars.targetEnemy->pos.vy;
	mycamera.vrz=camVars.targetEnemy->pos.vz;

	actorPos.vx=camVars.targetEnemy->pos.vx;
	actorPos.vy=camVars.targetEnemy->pos.vy;
	actorPos.vz=camVars.targetEnemy->pos.vz;

	camPos.vx=mycamera.vpx;
	camPos.vy=mycamera.vpy;
	camPos.vz=mycamera.vpz;

	temp.vx=camPos.vx-actorPos.vx;
	temp.vy=camPos.vy-actorPos.vy;
	temp.vz=camPos.vz-actorPos.vz;

	distance=Magnitude(&temp);	// how far away are we?

	if (distance>camVars.lookDistance) // need to move forwards along line
	{
// for now line only changes in 1 axis (x or z)
// tdb deal with lines in more than 1 axis
		distance2=distance-camVars.lookDistance;	// difference between actual and required

		//if ( (startPoint.vx!=endPoint.vx) && (startPoint.vz==endPoint.vz) ) // change in x axis
		if (camVars.railCamAxis)
		{
			temp1=actorPos.vz-startPoint.vz;
			temp2=actorPos.vy-startPoint.vy;
			distance1=Magnitude2D(temp1,temp2);

			mycamera.vpz=startPoint.vz;
			mycamera.vpy=startPoint.vy;

			if (distance1>camVars.lookDistance)	// if too far away use second method
			{
				distance2=((camPos.vx-actorPos.vx)/3)*direction;
				test=FALSE;
			}

			temp1= distance2/4;
			temp1=temp1*direction;

			if ( direction>0 && (camPos.vx-actorPos.vx)<0 && test) temp1=-temp1;
			else if ( direction<0 && (camPos.vx-actorPos.vx)>0 && test) temp1=-temp1;

			mycamera.vpx-=temp1;
		}
		//else if ( (startPoint.vx==endPoint.vx) && (startPoint.vz!=endPoint.vz) ) // change in z axis
		else
		{
			temp1=actorPos.vx-startPoint.vx;
			temp2=actorPos.vy-startPoint.vy;
			distance1=Magnitude2D(temp1,temp2);

			if (distance1>camVars.lookDistance)	// if too far away use second method
			{
				distance2=((camPos.vz-actorPos.vz)/3)*direction;
				test=FALSE;
			}

			if ( direction>0 && (camPos.vz-actorPos.vz)<0 && test) temp1=-temp1;	// make sure cam stays correct side
			else if ( direction<0 && (camPos.vz-actorPos.vz)>0 && test) temp1=-temp1;

			mycamera.vpx=startPoint.vx;
			mycamera.vpy=startPoint.vy;

			temp1= distance2/4;

			temp1=temp1*direction;
			mycamera.vpz-=temp1;
		}
		//else // none aligned 
		//{
		//	printf ("ERROR");
		//	CRASH;
		//}
	}
	else
	{
		distance2=camVars.lookDistance-distance;
		if ( (startPoint.vx!=endPoint.vx) && (startPoint.vz==endPoint.vz) ) // change in x axis
		{
			temp1=actorPos.vz-startPoint.vz;
			temp2=actorPos.vy-startPoint.vy;
			distance1=Magnitude2D(temp1,temp2);

			mycamera.vpz=startPoint.vz;
			mycamera.vpy=startPoint.vy;

			if (distance1>camVars.lookDistance)
				distance2=((camPos.vx-actorPos.vx)/3)*direction;

			temp1= distance2/4;	// Just goes to show the simplest is often the best

			temp1=temp1*direction;
			mycamera.vpx+=temp1;
		}
		else if ( (startPoint.vx==endPoint.vx) && (startPoint.vz!=endPoint.vz) ) // change in z axis
		{
			temp1=actorPos.vx-startPoint.vx;
			temp2=actorPos.vy-startPoint.vy;
			distance1=Magnitude2D(temp1,temp2);

			if (distance1>camVars.lookDistance)	// if too far away use second method
				distance2=((camPos.vz-actorPos.vz)/3)*direction;

			mycamera.vpx=startPoint.vx;
			mycamera.vpy=startPoint.vy;

			temp1= distance2/4;
			temp1=temp1*direction;
			mycamera.vpz+=temp1;
		}
		else // none aligned 
		{
			printf ("ERROR");
			CRASH;
		}
	}

	angle=utilCalcAngle( (mycamera.vpx-mycamera.vrx),(mycamera.vpz-mycamera.vrz) );
	camVars.camAngle=(angle+2048)&4095;
*/
}

///////////////////////////////////////////////////////////
// Moves the camera along a rail between a serise of points
///////////////////////////////////////////////////////////
	// moved to here for debug only
//	VECTOR	startPoint,endPoint,delta,camDelta;
//	VECTOR	actorPos,camPos;
//	VECTOR	actorVec,camVec;

//#define		RAILDEBUG

#define		RAILCHANGEDIST		4000
// debug test only!
//int	shortestrail=9999999;
//

void	railCamNoneAligned(void)
{
	VECTOR	startPoint,endPoint,delta,camDelta,delta1;
	VECTOR	actorPos,camPos;
	VECTOR	actorVec,camVec;

	
	int		direction=-1;	// need to get this from the lnd use this for dogchase
	//int		direction=1;
	char	message[255];
	int		loop,startPointNum,lineLen,camDist,deltaDist,angle,temp,speed;
	int		firstPoint,secondPoint;
	int		railDirectionFlag=1;	// If rails run from +ve to -ve causes BIG problems


	if (camVars.railCamDirection>=0) direction=1;
	else direction=-1;


	if (camVars.timerTar)
	{
		camVars.startViewPos.vx=camVars.targetEnemy->pos.vx;
		//camVars.startViewPos.vy=camVars.targetEnemy->pos.vy;
		camVars.startViewPos.vy=(camVars.targetEnemy->pos.vy-HEIGHTOFFSET)-camVars.targetRadius/8;
		camVars.startViewPos.vz=camVars.targetEnemy->pos.vz;

//		camVars.targetViewPos.vx=camVars.targetEnemy->pos.vx;
		//camVars.targetViewPos.vy=camVars.targetEnemy->pos.vy;
//		camVars.targetViewPos.vy=(camVars.targetEnemy->pos.vy-HEIGHTOFFSET)-camVars.targetRadius/8;
//		camVars.targetViewPos.vz=camVars.targetEnemy->pos.vz;
	}



/*	// This is'nt working
	if (camVars.lastCamType!=camVars.camType)
	{
		camVars.lastCamType=camVars.camType;
		railCamStart();
	}
*/

/*
	if (camVars.lastCamType!=camVars.camType)
	{
		camVars.lastCamType=camVars.camType;
		DB("cam just changed\n");
		DB("starting point %d\n",camVars.currentRailPoint);
		DB("starting target pos X %d Y %d Z %d\n",camVars.targetEnemy->pos.vx/8,camVars.targetEnemy->pos.vy/8,camVars.targetEnemy->pos.vz/8);

		camVars.justStartedTimer=0;
		camVars.timer=0;
		camVars.posChange=FALSE;
	}
*/

	startPointNum=0;
	if (camVars.currentRailCamNum>0)
	{
		for (loop=0;loop<camVars.currentRailCamNum;loop++)
			startPointNum+=caminfo->numRails[loop];
	}

	firstPoint=camVars.currentRailPoint+startPointNum;
	secondPoint=firstPoint+1;

	//firstPoint=1;
	//secondPoint=0;

	mycamera.vrx=actorPos.vx=camVars.targetEnemy->pos.vx;
	//mycamera.vry=actorPos.vy=camVars.targetEnemy->pos.vy;
	mycamera.vry=actorPos.vy=(camVars.targetEnemy->pos.vy-HEIGHTOFFSET)-camVars.targetRadius/8;
	mycamera.vrz=actorPos.vz=camVars.targetEnemy->pos.vz;

	camPos.vx=mycamera.vpx;
	camPos.vy=mycamera.vpy;
	camPos.vz=mycamera.vpz;

	//showRailLines();

	startPoint.vx=caminfo->data[firstPoint].pointX;
	startPoint.vy=caminfo->data[firstPoint].pointY;
	startPoint.vz=caminfo->data[firstPoint].pointZ;

	endPoint.vx=caminfo->data[secondPoint].pointX;
	endPoint.vy=caminfo->data[secondPoint].pointY;
	endPoint.vz=caminfo->data[secondPoint].pointZ;

	// Depending on which direction the rail is pointing the rail cam either works or cocks up
	// I think by doing this vector differently depending on which way rail facing may fixit
	delta.vx=startPoint.vx-endPoint.vx;
	delta.vy=startPoint.vy-endPoint.vy;
	delta.vz=startPoint.vz-endPoint.vz;
	deltaDist=Magnitude(&delta);

	camDelta.vx=actorPos.vx-camPos.vx;
	camDelta.vy=actorPos.vy-camPos.vy;
	camDelta.vz=actorPos.vz-camPos.vz;
	camDist=Magnitude(&camDelta);

	actorVec.vx=delta.vz;
	actorVec.vz=-delta.vx;
	actorVec.vy=0;

	MakeUnit(&actorVec);

	camVec.vx=camPos.vx-actorPos.vx;
	camVec.vz=camPos.vz-actorPos.vz;
	camVec.vy=0;


	MakeUnit(&camVec);


	if ( ABS(delta.vx) > ABS(delta.vz) )// find major axis
	{
		if (delta.vx<0)
		{
			camVec.vx=-camVec.vx;
			camVec.vz=-camVec.vz;
			railDirectionFlag=-1;
		}
	}
	else if (delta.vz<0)
	{
		camVec.vx=-camVec.vx;
		camVec.vz=-camVec.vz;
		railDirectionFlag=-1;
	}




	temp=ABS(DotProduct(&camVec,&actorVec));
	if (temp>4095) temp=4095;
#ifdef	RAILDEBUG
	sprintf(message,"camVec   X %d Z %d",camVec.vx,camVec.vz);
	fontPrint(font, -220,-100, message, 128,128,0);
	sprintf(message,"actorVec X %d Z %d",actorVec.vx,actorVec.vz);
	fontPrint(font, -220,-85, message, 128,128,0);
	sprintf(message,"camera distance %d",camDist);
	fontPrint(font, -220,-70, message, 128,128,0);
	sprintf(message,"dot product %d",temp);
	fontPrint(font, -220,-55, message, 128,128,0);
#endif

	speed=ABS(camDist-camVars.lookDistance);
	if (speed>256) speed=256;
	if (speed<3) speed=0;

#ifdef	RAILDEBUG
	sprintf(message,"speed before %d",speed);
	fontPrint(font, -220,-40, message, 128,128,0);
#endif

	if (camDist>camVars.lookDistance)
	{
		if (temp>3400)
			//speed=ABS((speed*(4096-temp))/596);
			speed=ABS((speed*(4096-temp))/500);
	}

#ifdef	RAILDEBUG
	sprintf(message,"speed after %d",speed);
	fontPrint(font, -220,-25, message, 128,128,0);
	sprintf(message,"1st point %d",firstPoint);
	fontPrint(font, -220,-5, message, 128,128,0);
	sprintf(message,"cam pos x %d y %d z %d\n",camPos.vx,camPos.vy,camPos.vz);
	fontPrint(font, -220,10, message, 128,128,0);
	sprintf(message,"point 1 x %d y %d z %d\n",startPoint.vx,startPoint.vy,startPoint.vz);
	fontPrint(font, -220,25, message, 128,128,0);
	sprintf(message,"point 2 x %d y %d z %d\n",endPoint.vx,endPoint.vy,endPoint.vz);
	fontPrint(font, -220,40, message, 128,128,0);

#endif

	if ( ABS(delta.vx) > ABS(delta.vz) )// find major axis
	{
		// as x is the > axis compare the x part of the vectors to find which way to go
		// maybe use a dot product for a speed modifier
#ifdef	RAILDEBUG
		sprintf(message,"X axis\n");
		fontPrint(font, -220,80, message, 128,128,0);
#endif
		//if ( camVec.vx>actorVec.vx )
		if ( camVec.vx<actorVec.vx )
		{
			if (direction!=1)
			{
				if (camDist>camVars.lookDistance)
				{
					camVars.currentRailDist+=speed;
				}
				else camVars.currentRailDist-=speed;
			}
			else
			{
				camVars.currentRailDist+=speed;
				//camVars.currentRailDist+=10;
			}
		}
		else
		{
			if (direction==1)
			{
				if (camDist>camVars.lookDistance)
				{
					camVars.currentRailDist-=speed;
				}
				else camVars.currentRailDist+=speed;
			}
			else
			{
				camVars.currentRailDist-=speed;
				//camVars.currentRailDist-=10;
			}
		}
	}
	else
	{
#ifdef	RAILDEBUG
		sprintf(message,"Z axis\n");
		fontPrint(font, -220,80, message, 128,128,0);
#endif
		if (camVec.vz<actorVec.vz)
		{
			if (direction!=1)
			{
				if (camDist>camVars.lookDistance)
				{
					camVars.currentRailDist+=speed;
				}
				else camVars.currentRailDist-=speed;
			}
			else
			{
				camVars.currentRailDist+=speed;
				//camVars.currentRailDist+=10;
			}
		}
		else
		{
			if (direction==1)
			{
				if (camDist>camVars.lookDistance)
				{
					camVars.currentRailDist-=speed;
				}
				else camVars.currentRailDist+=speed;
			}
			else
			{
				camVars.currentRailDist-=speed;
				//camVars.currentRailDist-=10;
			}
		}
	}

	MakeUnit(&delta);
	SCALEVECTOR(&delta,camVars.currentRailDist);

	mycamera.vpx=startPoint.vx+delta.vx;
	mycamera.vpy=startPoint.vy+delta.vy;
	mycamera.vpz=startPoint.vz+delta.vz;

	angle=utilCalcAngle( (mycamera.vpx-mycamera.vrx),(mycamera.vpz-mycamera.vrz) );
	camVars.camAngle=(angle+2048)&4095;

	if (-camVars.currentRailDist>deltaDist) // off the end of current rail
	{
		if (camVars.currentRailPoint< caminfo->numRails[camVars.currentRailCamNum]-2)
		{
			camVars.currentRailPoint++;
			camVars.currentRailDist=camVars.currentRailDist+deltaDist;
		}
		else
		{
#ifdef	RAILDEBUG
			sprintf(message,"Cam at end of rail");
			fontPrint(font, -220,60, message, 0,128,0);
#endif
			// changes to stop cam going off end of rail

			camVars.currentRailDist=-deltaDist;
			MakeUnit(&delta);
			SCALEVECTOR(&delta,camVars.currentRailDist);

			mycamera.vpx=startPoint.vx-delta.vx;
			mycamera.vpy=startPoint.vy-delta.vy;
			mycamera.vpz=startPoint.vz-delta.vz;
		}
	}

	if (camVars.currentRailDist>0) // off the end of current rail
	{
		if (camVars.currentRailPoint>0)
		{
			camVars.currentRailPoint--;
			firstPoint=camVars.currentRailPoint+startPointNum;
			secondPoint=firstPoint+1;
			//camVars.currentRailDist-=deltaDist;
			// need to find dist of next line NOT current one
			startPoint.vx=caminfo->data[firstPoint].pointX;
			startPoint.vy=caminfo->data[firstPoint].pointY;
			startPoint.vz=caminfo->data[firstPoint].pointZ;

			endPoint.vx=caminfo->data[secondPoint].pointX;
			endPoint.vy=caminfo->data[secondPoint].pointY;
			endPoint.vz=caminfo->data[secondPoint].pointZ;

			delta.vx=startPoint.vx-endPoint.vx;
			delta.vy=startPoint.vy-endPoint.vy;
			delta.vz=startPoint.vz-endPoint.vz;
			deltaDist=Magnitude(&delta);
			camVars.currentRailDist-=deltaDist;

			DB("delta Dist %d\n",deltaDist);

		}
		else
		{
#ifdef	RAILDEBUG
			sprintf(message,"Cam at end of rail");
			fontPrint(font, -230,60, message, 128,0,0);
#endif
			camVars.currentRailDist=0;
			mycamera.vpx=startPoint.vx;
			mycamera.vpy=startPoint.vy;
			mycamera.vpz=startPoint.vz;
		}
	}

/*	if (camVars.timer)
	{
		camVars.targetCamPos.vx=mycamera.vpx;
		camVars.targetCamPos.vy=mycamera.vpy;
		camVars.targetCamPos.vz=mycamera.vpz;
	}
*/

//	addition to allow cam drag behind rail
//  tbd point cam other way if direction changed and deal with back to front rails
	//return;
	if (camVars.railTargetRail)
		lookAlongRail(startPointNum,firstPoint);

}
////////////////////////////////////////////////////////////////////////////
void	lookAlongRail(int	startPointNum,int firstNum)
{
	VECTOR	startPoint,endPoint,delta,camDelta,delta1;
	VECTOR	actorPos,camPos;
	VECTOR	actorVec,camVec;

	int		firstPoint,secondPoint,temp,direction,lastPoint;
	int		railChangeDist=RAILCHANGEDIST;


	firstPoint=firstNum;

	if (camVars.railCamDirection>0) direction=1;
	else direction=-1;


	if (direction==-1)
	{
		firstPoint=camVars.currentRailPoint+startPointNum;
		secondPoint=firstPoint+1;

		delta.vx=caminfo->data[firstPoint].pointX-caminfo->data[secondPoint].pointX;
		delta.vy=caminfo->data[firstPoint].pointY-caminfo->data[secondPoint].pointY;
		delta.vz=caminfo->data[firstPoint].pointZ-caminfo->data[secondPoint].pointZ;

		temp=Magnitude(&delta);
		if (temp<railChangeDist) railChangeDist=temp;

		if (camVars.currentRailDist<0 && camVars.currentRailDist>-railChangeDist)
		{
			// close to start if not 1st rail do interpolation between old and new
			if (firstPoint>startPointNum) // check if first rail
			{
				//firstPoint=camVars.currentRailPoint+startPointNum;
				//secondPoint=firstPoint+1;

				delta1.vx=caminfo->data[firstPoint-1].pointX-caminfo->data[secondPoint-1].pointX;
				delta1.vy=caminfo->data[firstPoint-1].pointY-caminfo->data[secondPoint-1].pointY;
				delta1.vz=caminfo->data[firstPoint-1].pointZ-caminfo->data[secondPoint-1].pointZ;

				MakeUnit(&delta);
				MakeUnit(&delta1);
				temp=-camVars.currentRailDist;

				camVars.railCamPoint.vx=-(((delta.vx*temp) + (delta1.vx*(railChangeDist-temp)))/railChangeDist);
				camVars.railCamPoint.vy=-(((delta.vy*temp) + (delta1.vy*(railChangeDist-temp)))/railChangeDist);
				camVars.railCamPoint.vz=-(((delta.vz*temp) + (delta1.vz*(railChangeDist-temp)))/railChangeDist);
				SCALEVECTOR(&camVars.railCamPoint,3000);
			}
			else
			{
				firstPoint=camVars.currentRailPoint+startPointNum;
				delta.vx=caminfo->data[firstPoint].pointX-caminfo->data[firstPoint+1].pointX;
				delta.vy=caminfo->data[firstPoint].pointY-caminfo->data[firstPoint+1].pointY;
				delta.vz=caminfo->data[firstPoint].pointZ-caminfo->data[firstPoint+1].pointZ;

				MakeUnit(&delta);
				SCALEVECTOR(&delta,3000);

				camVars.railCamPoint.vx=-delta.vx;
				camVars.railCamPoint.vy=-delta.vy;
				camVars.railCamPoint.vz=-delta.vz;
			}
		}
		else
		{
			firstPoint=camVars.currentRailPoint+startPointNum;
			delta.vx=caminfo->data[firstPoint].pointX-caminfo->data[firstPoint+1].pointX;
			delta.vy=caminfo->data[firstPoint].pointY-caminfo->data[firstPoint+1].pointY;
			delta.vz=caminfo->data[firstPoint].pointZ-caminfo->data[firstPoint+1].pointZ;

			MakeUnit(&delta);
			SCALEVECTOR(&delta,3000);

			camVars.railCamPoint.vx=-delta.vx;
			camVars.railCamPoint.vy=-delta.vy;
			camVars.railCamPoint.vz=-delta.vz;
		}
	}
	else
	{
		//DB("camVars.currentRailDist %d\n",camVars.currentRailDist);
		firstPoint=camVars.currentRailPoint+startPointNum;
		secondPoint=firstPoint+1;

		delta.vx=caminfo->data[firstPoint].pointX-caminfo->data[firstPoint+1].pointX;
		delta.vy=caminfo->data[firstPoint].pointY-caminfo->data[firstPoint+1].pointY;
		delta.vz=caminfo->data[firstPoint].pointZ-caminfo->data[firstPoint+1].pointZ;
		temp=Magnitude(&delta);
		if (temp<railChangeDist) railChangeDist=temp;

		temp+=camVars.currentRailDist;

		//if (camVars.currentRailDist<0 && camVars.currentRailDist>-RAILCHANGEDIST)
		if (camVars.currentRailDist<0 && temp<railChangeDist)
		{
			// close to start if not 1st rail do interpolation between old and new
			lastPoint=startPointNum+caminfo->numRails[camVars.currentRailCamNum];
			if (firstPoint< lastPoint-2 ) // check if last rail
			{
//				firstPoint=camVars.currentRailPoint+startPointNum;
//				secondPoint=firstPoint+1;

/*				startPoint.vx=caminfo->data[firstPoint].pointX;
				startPoint.vy=caminfo->data[firstPoint].pointY;
				startPoint.vz=caminfo->data[firstPoint].pointZ;

				endPoint.vx=caminfo->data[secondPoint].pointX;
				endPoint.vy=caminfo->data[secondPoint].pointY;
				endPoint.vz=caminfo->data[secondPoint].pointZ;

				delta.vx=startPoint.vx-endPoint.vx;
				delta.vy=startPoint.vy-endPoint.vy;
				delta.vz=startPoint.vz-endPoint.vz;
*/
				delta1.vx=caminfo->data[firstPoint+1].pointX-caminfo->data[secondPoint+1].pointX;
				delta1.vy=caminfo->data[firstPoint+1].pointY-caminfo->data[secondPoint+1].pointY;
				delta1.vz=caminfo->data[firstPoint+1].pointZ-caminfo->data[secondPoint+1].pointZ;

				MakeUnit(&delta);
				MakeUnit(&delta1);
				//temp=-camVars.currentRailDist;

				camVars.railCamPoint.vx=+(((delta.vx*temp) + (delta1.vx*(railChangeDist-temp)))/railChangeDist);
				camVars.railCamPoint.vy=+(((delta.vy*temp) + (delta1.vy*(railChangeDist-temp)))/railChangeDist);
				camVars.railCamPoint.vz=+(((delta.vz*temp) + (delta1.vz*(railChangeDist-temp)))/railChangeDist);
				SCALEVECTOR(&camVars.railCamPoint,3000);
			}
			else
			{
				firstPoint=camVars.currentRailPoint+startPointNum;
				delta.vx=caminfo->data[firstPoint].pointX-caminfo->data[firstPoint+1].pointX;
				delta.vy=caminfo->data[firstPoint].pointY-caminfo->data[firstPoint+1].pointY;
				delta.vz=caminfo->data[firstPoint].pointZ-caminfo->data[firstPoint+1].pointZ;

				MakeUnit(&delta);
				SCALEVECTOR(&delta,3000);

				camVars.railCamPoint.vx=+delta.vx;
				camVars.railCamPoint.vy=+delta.vy;
				camVars.railCamPoint.vz=+delta.vz;
			}
		}
		else
		{
			firstPoint=camVars.currentRailPoint+startPointNum;
			delta.vx=caminfo->data[firstPoint].pointX-caminfo->data[firstPoint+1].pointX;
			delta.vy=caminfo->data[firstPoint].pointY-caminfo->data[firstPoint+1].pointY;
			delta.vz=caminfo->data[firstPoint].pointZ-caminfo->data[firstPoint+1].pointZ;

			MakeUnit(&delta);
			SCALEVECTOR(&delta,3000);

			camVars.railCamPoint.vx=+delta.vx;
			camVars.railCamPoint.vy=+delta.vy;
			camVars.railCamPoint.vz=+delta.vz;
		}
	}
	//DB("first point %d\n",firstPoint);
}

////////////////////////////////////////////////////////////////////////////
void	showRailLines(void)
{
	int	loop;
	VECTOR	temp,temp1;

	//for (loop=0;loop<(caminfo->numRails[0]-1);loop++)
	for (loop=0;loop<(6);loop++)
	{
		temp.vx=caminfo->data[loop].pointX;
		temp.vy=caminfo->data[loop].pointY;
		temp.vz=caminfo->data[loop].pointZ;

		temp1.vx=caminfo->data[loop+1].pointX;
		temp1.vy=caminfo->data[loop+1].pointY;
		temp1.vz=caminfo->data[loop+1].pointZ;

		overlayShowDebugLine(&temp, &temp1, 0xff0000 , DEBUGPOLY_USEDEPTH);
	}

	//overlayShowSphere(mycamera.vpx, mycamera.vpy, mycamera.vpz, 4, 0xffff00); // broken 

}


////////////////////////////////////////////////////////////////////////////
// Set the rail cam to correct place
// not very good at the moment
void	railCamStart(void)
{
	VECTOR	startPoint,endPoint,camDelta,camPos;
	int		firstPoint,secondPoint,loop,startPointNum,dist;
	//VECTOR	actorPos,camPos;
	//VECTOR	actorVec,camVec;

	startPointNum=0;
	if (camVars.currentRailCamNum>0)
	{
		for (loop=0;loop<camVars.currentRailCamNum;loop++)
			startPointNum+=caminfo->numRails[loop];
	}

	firstPoint=camVars.currentRailPoint+startPointNum;
	secondPoint=firstPoint+1;

	camPos.vx=mycamera.vpx;
	camPos.vy=mycamera.vpy;
	camPos.vz=mycamera.vpz;

	startPoint.vx=caminfo->data[firstPoint].pointX;
	startPoint.vy=caminfo->data[firstPoint].pointY;
	startPoint.vz=caminfo->data[firstPoint].pointZ;

	endPoint.vx=caminfo->data[secondPoint].pointX;
	endPoint.vy=caminfo->data[secondPoint].pointY;
	endPoint.vz=caminfo->data[secondPoint].pointZ;

	camDelta.vx=camPos.vx-startPoint.vx;
	camDelta.vy=camPos.vy-startPoint.vy;
	camDelta.vz=camPos.vz-startPoint.vz;

	loop=Magnitude(&camDelta);
	//DB("dist %d \n",loop);
	camVars.currentRailDist=-loop;

	camVars.railCamPoint.vx=mycamera.vrx;
	camVars.railCamPoint.vy=mycamera.vry;
	camVars.railCamPoint.vz=mycamera.vrz;

	camVars.currentRailPoint=0;
	//camVars.currentRailPoint=8; 
}


////////////////////////////////////////////////////////////////////////////
//	Give first chicken view of precedings (NOTE debug only!!!)
/*
void	lookCamera(void)
{
	VECTOR	temp;

	mycamera.vpy=(camVars.targetEnemy->pos.vy-HEIGHTOFFSET)-camVars.targetRadius/8;
	mycamera.vpx=camVars.targetEnemy->pos.vx;
	mycamera.vpz=camVars.targetEnemy->pos.vz;

	temp.vx=0;
	temp.vy=0;
	temp.vz=200;

	camVars.lookCamFacing+= padData.analogX2S[0]/512;
	camVars.lookCamFacing=camVars.lookCamFacing&4095;

	camVars.lookCamHeight+= padData.analogY2S[0]/512;
	//dz1 = padData.analogYS[0];
	
	RotateVector2D(&temp, &temp, camVars.lookCamFacing);

	mycamera.vry=mycamera.vpy+camVars.lookCamHeight;
	mycamera.vrx=mycamera.vpx+temp.vx;
	mycamera.vrz=mycamera.vpz+temp.vz;
}
*/
////////////////////////////////////////////////////////////////////////////
// This routine is where the active actor's collision is tested
// Used for camera look tests
//COLLBOX	*boxToHoldSweep;

int	targetCharCollTest(COLLDATA	*collData)
{
	int	nHits;
	COLLBOX	*pBox,*pBox1;
	int	position=NULL;
	int	camPosition=NULL;
	char	message[255];


	pBox1=NULL;

//	DB ("chicken anim %d\n",characterVars.pMainChar->pEnemy->readData.pActor->animation.animData[0].segment);	// must ask Chris to make his code harder to understand

	camVars.numActorHits=collboxCheckSphere(collData);
	if (camVars.numActorHits/* && camVars.sweepFlag */) // well lets face it its nearly always going to hit something
	{
		for (nHits=0;nHits<camVars.numActorHits;nHits++)
		{
			if (pHitData[nHits].pCollBox->flags&COLLBOXFLAG_DEADLY)
			{
				//deathKill(CHARACTER *pC, int reason, ENEMY *pE)
				//CHARACTER *mainChar;
				//mainChar=characterGetMainCharacter()

				deathKill(characterGetMainCharacter(),DEATH_REASON_DEADLY_PLATFORM,NULL);
				DB("kill main char\n");
			}
		}



		pBox1=(COLLBOX*)checkBoxSides(&position,&camPosition);
		if ( position  && camVars.sweepFlag )
		{
			findMovePositions(&position,&camPosition,pBox1);
			if (!camVars.firstSweep)
			{
				camVars.startCamPos.vx=mycamera.vpx;
				camVars.startCamPos.vy=mycamera.vpy;
				camVars.startCamPos.vz=mycamera.vpz;
				camVars.firstSweep=TRUE;
			}
			camVars.posChangeOn=TRUE;
			//sprintf(message,"Sweep active ");
			//fontPrint(font, -220,-100, message, 128,128,0);
		}
		else camVars.firstSweep=FALSE;
	}
	camVars.sweepFlag=FALSE;
	return(camVars.numActorHits);
}

////////////////////////////////////////////////////////////////////////////
//	checks to see if camera needs to sweep down for look mode
//COLLBOX	box;
ULONG*	checkBoxSides(int *position,int *camPosition)
{
	int	loop,test,dot;
	COLLBOX	*pBox,*pBox1 = NULL;
	HITDATA	*pHit;
	VECTOR	actorPos;
	VECTOR	normal,normal1;

	actorPos.vx=camVars.targetEnemy->pos.vx*512;
	actorPos.vy=camVars.targetEnemy->pos.vy*512;
	actorPos.vz=camVars.targetEnemy->pos.vz*512;

	for (loop=0;loop<camVars.numActorHits;loop++)
	{
		pBox=pHitData[loop].pCollBox;
		//pBox=&box;
		if ( (pBox->pY+pBox->sY) < actorPos.vy && pBox->flags!=RAMP)	// check if floor or not
		{
			// need push checks
			pHit=&pHitData[loop];
			test=TRUE;
			if (pHit->type == PLANE)
			{
				switch(pHit->plane)
				{
					case U_XYPLANE:
						normal.vx = 0;
						normal.vy = 0;
						normal.vz = 4096;
						break;
					case D_XYPLANE:
						normal.vx = 0;
						normal.vy = 0;
						normal.vz = -4096;
						break;
					case U_YZPLANE:
						normal.vx = 4096;
						normal.vy = 0;
						normal.vz = 0;
						break;
					case D_YZPLANE:
						normal.vx = -4096;
						normal.vy = 0;
						normal.vz = 0;
						break;
					default:
						test=FALSE;
						break;
				}
			}
			else
			{
				//normal.vx=pHit->normal.vx;
				//normal.vy=pHit->normal.vy;
				//normal.vz=pHit->normal.vz;
				test=FALSE;
			}
			//DB ("normal x %d y %d z %d\n",normal.vx,normal.vy,normal.vz);
			if (test)
			{
				normal1.vx=0;
				normal1.vy=0;
				normal1.vz=-4096;
				RotateVector2D(&normal1, &normal1, (camVars.targetEnemy->dir&4095) );
				//DB ("normal1 x %d y %d z %d\n",normal1.vx,normal1.vy,normal1.vz);
				dot=DotProduct(&normal,&normal1);
				//DB("dot %d\n",dot);

				//DB("speed %d\n",camVars.targetEnemy->state
				if(camVars.targetEnemy->moveSpeed<3500 && camVars.targetEnemy->state!=STATE_AGAINSTWALL)
					test=FALSE;
				else
				{
					if(dot < 3000)
						test=FALSE;// This is where the push against wall should go
					else if ((pBox->camFlags&HUGWALL) )
					{
						//boxToHoldSweep=pBox;
						chickenPressingAgainstWall(NULL, &normal);
					}
					else test=FALSE;
				
				}

				//if (test) DB("press\n");
				//else DB("no press\n");
			}
			if (test)
			{
				if ( (actorPos.vx>pBox->pX) && (actorPos.vx< (pBox->pX+ACTIVEZONE)) ) *position=CAMLEFT;
				else if ( (actorPos.vz>pBox->pZ) && (actorPos.vz< (pBox->pZ+ACTIVEZONE)) ) *position=CAMNEAR;
				else if ( (actorPos.vx< (pBox->pX+pBox->sX)) && (actorPos.vx> (pBox->pX+pBox->sX-ACTIVEZONE)) ) *position=CAMRIGHT;
				else if ( (actorPos.vz< (pBox->pZ+pBox->sZ)) && (actorPos.vz> (pBox->pZ+pBox->sZ-ACTIVEZONE)) ) *position=CAMFAR;
			}
			//else *position=FALSE;
			if ( (*position) && camVars.sweepFlag ) // if in valid place
			{
				camVars.posChange=TRUE;

				pBox1=pBox;
				if ( (actorPos.vx-pBox->pX) > (pBox->sX/2) ) // are we to the left or right
					*camPosition=CAMRIGHT;
				else
					*camPosition=CAMLEFT;
				
				if ( (actorPos.vz-pBox->pZ) > (pBox->sZ/2) ) // are we to the near or far
					(*camPosition)+=CAMFAR;
				else
					(*camPosition)+=CAMNEAR;
			}
		}
	}
	return( (ULONG*)pBox1);
}
////////////////////////////////////////////////////////////////////////////
//	Updates timers of camera interpolation events
void	updateTimers(void)
{
	if (camVars.posChangeOn)
	{
		camVars.posChangeOn=FALSE;
		if (camVars.timer<camVars.camTransitionSpeed)	// start the timer
		{	
			int	test,mid;
			mid=camVars.camTransitionSpeed/2;
			if (camVars.timer>=mid) test=camVars.timer-mid;
			else test=mid-camVars.timer;
			test=mid-test;
			camVars.timer+=( (test*4)/mid );
			camVars.timer++;
			if (camVars.timer>camVars.camTransitionSpeed) camVars.timer=camVars.camTransitionSpeed;
		}
	}
	else
	{
/*		if (camVars.caseSpecials==UPDATEPOSITION)
		{
			camVars.startCamPos.vx=camVars.camAfterStart.vx;
			camVars.startCamPos.vy=camVars.camAfterStart.vy;
			camVars.startCamPos.vz=camVars.camAfterStart.vz;
			if (camVars.timer<=2) camVars.caseSpecials=NULL;
		}
*/
		if (camVars.timer)
		{
			int	test,mid;
			mid=camVars.camTransitionSpeed/2;
			if (camVars.timer>=mid) test=camVars.timer-mid;
			else test=mid-camVars.timer;

			test=mid-test;

			camVars.timer-=( (test*4)/mid );
			camVars.timer--;

			if (camVars.timer<=0)
			{
				camVars.posChange=FALSE;
				camVars.timer=0;
				camVars.camTypeChanged=FALSE;
			}
		}
	}


	if (camVars.tarChangeOn)
	{
		camVars.tarChangeOn=FALSE;
		if (camVars.timerTar<camVars.camTransitionSpeed)	// start the timer
		{	

			int	test,mid;
			mid=camVars.camTransitionSpeed/2;
			if (camVars.timerTar>=mid) test=camVars.timerTar-mid;
			else test=mid-camVars.timerTar;
			test=mid-test;
			camVars.timerTar+=( (test*4)/mid );
			camVars.timerTar++;
			if (camVars.timerTar>camVars.camTransitionSpeed) camVars.timerTar=camVars.camTransitionSpeed;
		}
	}
	else
	{
		if (camVars.timerTar)
		{
			int	test,mid;
			mid=camVars.camTransitionSpeed/2;
			if (camVars.timerTar>=mid) test=camVars.timerTar-mid;
			else test=mid-camVars.timerTar;

			test=mid-test;

			camVars.timerTar-=( (test*4)/mid );
			camVars.timerTar--;

			if (camVars.timerTar<=0)
			{
				camVars.tarChange=FALSE;
				camVars.timerTar=0;
				camVars.camTypeChanged=FALSE;
			}
		}
	}
}
////////////////////////////////////////////////////////////////////////////
//	setup points for cam to move to in look mode
//	tbd. needs to check box flags for cam cases
void	findMovePositions(int *position,int *camPosition,COLLBOX* pBox1) 
{

int	dist,height,offset,caseNum,areaNum = 0,test;

	dist=camVars.lookDistance;
	offset=camVars.offsetDistance;

	test=TRUE;

	//camVars.targetViewPos.vy=testchar_actor->position.vy;
	//camVars.targetCamPos.vy=testchar_actor->position.vy-camVars.lookHeight;

	camVars.targetViewPos.vy=mycamera.vry;
	camVars.targetCamPos.vy=mycamera.vry-MOVEHEIGHT;
	switch ( (*position) )
	{
		case	CAMRIGHT:
			if ((*camPosition)&CAMFAR) areaNum=4;
			else areaNum=7;
			break;
	
		case	CAMLEFT:
			if ((*camPosition)&CAMFAR) areaNum=3;
			else areaNum=0;
			break;

		case	CAMNEAR:
			if ((*camPosition)&CAMRIGHT) areaNum=6;
			else areaNum=1;
			break;

		case	CAMFAR:
			if ((*camPosition)&CAMRIGHT) areaNum=5;
			else areaNum=2;
			break;
	}

	//DB("cam Flags %d\n",pBox1->camFlags);
	//DB("CAMSWEEPCASE %d\n",CAMSWEEPCASE);

	//if (pBox1->camFlags&CAMSWEEPCASE)
	if (camVars.sweepNum)
	{
		caseNum=camVars.sweepNum-1;
		//DB("case num %d\n",caseNum);
		if ( (caminfo->rec[caseNum].data[areaNum].camX) || (caminfo->rec[caseNum].data[areaNum].camZ) )
		{
			test=FALSE;
			camVars.targetViewPos.vx=caminfo->rec[caseNum].data[areaNum].viewX;
			camVars.targetViewPos.vy=caminfo->rec[caseNum].data[areaNum].viewY;
			camVars.targetViewPos.vz=caminfo->rec[caseNum].data[areaNum].viewZ;

			camVars.targetCamPos.vx=caminfo->rec[caseNum].data[areaNum].camX;
			camVars.targetCamPos.vy=caminfo->rec[caseNum].data[areaNum].camY;
			camVars.targetCamPos.vz=caminfo->rec[caseNum].data[areaNum].camZ;
		}
	}
	if (test)
	{
		//DB("side %d \n",areaNum);
		camVars.posChange=TRUE;
		switch (areaNum)
		{
			case	0:
				camVars.targetViewPos.vx=(pBox1->pX)/512;
				camVars.targetCamPos.vx=((pBox1->pX)/512)-offset;
				camVars.targetViewPos.vz=((pBox1->pZ)/512);
				camVars.targetCamPos.vz=((pBox1->pZ)/512)-dist;
				break;

			case	1:
				camVars.targetViewPos.vz=(pBox1->pZ/512);
				camVars.targetCamPos.vz=(pBox1->pZ/512)-offset;
				camVars.targetViewPos.vx=((pBox1->pX)/512);
				camVars.targetCamPos.vx=((pBox1->pX)/512)-dist;
				break;

			case	2:
				camVars.targetViewPos.vz=(pBox1->pZ+pBox1->sZ)/512;
				camVars.targetCamPos.vz=((pBox1->pZ+pBox1->sZ)/512)+offset;
				camVars.targetViewPos.vx=((pBox1->pX)/512);
				camVars.targetCamPos.vx=((pBox1->pX)/512)-dist;
				break;

			case	3:
				camVars.targetViewPos.vx=(pBox1->pX)/512;
				camVars.targetCamPos.vx=((pBox1->pX)/512)-offset;
				camVars.targetViewPos.vz=((pBox1->pZ+pBox1->sZ)/512);
				camVars.targetCamPos.vz=((pBox1->pZ+pBox1->sZ)/512)+dist;
				break;

//				camVars.targetViewPos.vz=(pBox1->pZ+pBox1->sZ)/512;
//				camVars.targetCamPos.vz=((pBox1->pZ+pBox1->sZ)/512)+offset;
//				camVars.targetViewPos.vx=((pBox1->pX)/512);
//				camVars.targetCamPos.vx=((pBox1->pX)/512)-dist;
//				break;

			case	4:
				camVars.targetViewPos.vx=((pBox1->pX+pBox1->sX)/512);
				camVars.targetCamPos.vx=((pBox1->pX+pBox1->sX)/512)+offset;
				camVars.targetViewPos.vz=((pBox1->pZ+pBox1->sZ)/512);
				camVars.targetCamPos.vz=((pBox1->pZ+pBox1->sZ)/512)+dist;
				break;

			case	5:
				camVars.targetViewPos.vz=(pBox1->pZ+pBox1->sZ)/512;
				camVars.targetCamPos.vz=((pBox1->pZ+pBox1->sZ)/512)+offset;
				camVars.targetViewPos.vx=((pBox1->pX+pBox1->sX)/512);
				camVars.targetCamPos.vx=((pBox1->pX+pBox1->sX)/512)+dist;
				break;

			case	6:
				camVars.targetViewPos.vz=(pBox1->pZ/512);
				camVars.targetCamPos.vz=(pBox1->pZ/512)-offset;
				camVars.targetViewPos.vx=((pBox1->pX+pBox1->sX)/512);
				camVars.targetCamPos.vx=((pBox1->pX+pBox1->sX)/512)+dist;
				break;

			case	7:
				camVars.targetViewPos.vx=((pBox1->pX+pBox1->sX)/512);
				camVars.targetCamPos.vx=((pBox1->pX+pBox1->sX)/512)+offset;
				camVars.targetViewPos.vz=((pBox1->pZ)/512);
				camVars.targetCamPos.vz=((pBox1->pZ)/512)-dist;
				break;
		}
	}


//	camVars.startCamPos.vx=camVars.camAtStart.vx;
//	camVars.startCamPos.vy=camVars.camAtStart.vy;
//	camVars.startCamPos.vz=camVars.camAtStart.vz;


/*	switch ( (*position) )
	{
		case	CAMRIGHT:
			camVars.targetViewPos.vx=((pBox1->pX+pBox1->sX)/512);
			camVars.targetCamPos.vx=((pBox1->pX+pBox1->sX)/512)+offset;
			camVars.posChange=TRUE;

			if ((*camPosition)&CAMFAR)
			{
				camVars.targetViewPos.vz=((pBox1->pZ+pBox1->sZ)/512);
				camVars.targetCamPos.vz=((pBox1->pZ+pBox1->sZ)/512)+dist;
			}
			else
			{
				camVars.targetViewPos.vz=((pBox1->pZ)/512);
				camVars.targetCamPos.vz=((pBox1->pZ)/512)-dist;
			}
			break;

		case	CAMLEFT:
			camVars.targetViewPos.vx=(pBox1->pX)/512;
			camVars.targetCamPos.vx=((pBox1->pX)/512)-offset;
			camVars.posChange=TRUE;

			if ((*camPosition)&CAMFAR)
			{
				camVars.targetViewPos.vz=((pBox1->pZ+pBox1->sZ)/512);
				camVars.targetCamPos.vz=((pBox1->pZ+pBox1->sZ)/512)+dist;
			}
			else
			{
				camVars.targetViewPos.vz=((pBox1->pZ)/512);
				camVars.targetCamPos.vz=((pBox1->pZ)/512)-dist;
			}
			break;

		case	CAMNEAR:
			camVars.targetViewPos.vz=(pBox1->pZ/512);
			camVars.targetCamPos.vz=(pBox1->pZ/512)-offset;

			if ((*camPosition)&CAMRIGHT)
			{
				camVars.targetViewPos.vx=((pBox1->pX+pBox1->sX)/512);
				camVars.targetCamPos.vx=((pBox1->pX+pBox1->sX)/512)+dist;
			}
			else
			{
				camVars.targetViewPos.vx=((pBox1->pX)/512);
				camVars.targetCamPos.vx=((pBox1->pX)/512)-dist;
			}
			break;

		case	CAMFAR:
			camVars.targetViewPos.vz=(pBox1->pZ+pBox1->sZ)/512;
			camVars.targetCamPos.vz=((pBox1->pZ+pBox1->sZ)/512)+offset;

			if ((*camPosition)&CAMRIGHT)
			{
				camVars.targetViewPos.vx=((pBox1->pX+pBox1->sX)/512);
				camVars.targetCamPos.vx=((pBox1->pX+pBox1->sX)/512)+dist;
			}
			else
			{
				camVars.targetViewPos.vx=((pBox1->pX)/512);
				camVars.targetCamPos.vx=((pBox1->pX)/512)-dist;
			}
			break;
	}
*/
}

////////////////////////////////////////////////////////////////////////////
#define	HEIGHTADD	-1000


//#define	CASEDEBUG

void	caseHandler(void)
{
	char	message[255];
	int		test,test1,loop;

	//camVars.flags=camVars.flags&(~CHANGEHEIGHT);

	if (camVars.posCaseOnTime)
	{
		if (!camVars.posCaseToHold) camVars.posCaseToHold=(camVars.flags&ALLPOSTYPES);
		camVars.flags|=camVars.posCaseToHold;
		camVars.posCaseOnTime--;
		if (!camVars.posCaseOnTime)	camVars.posCaseToHold=0;
	}

	if (camVars.lookCaseOnTime)
	{
		if (!camVars.lookCaseToHold) camVars.lookCaseToHold=(camVars.flags&ALLLOOKTYPES);
		camVars.flags|=camVars.lookCaseToHold;
		camVars.lookCaseOnTime--;
		if (!camVars.lookCaseOnTime) camVars.lookCaseToHold=0;
		characterDisableController=CONTROLLER_DISABLED_RESET;	// I hope chris resets this (no he does'nt) (does now)
	}


	if ( camVars.flags&FIXEDPOS ) camVars.posChangeOn=TRUE;	// so we count up

	if ( (camVars.lastFlags&FIXEDPOS) && !(camVars.flags&FIXEDPOS) )	// just left a case
		camVars.caseSpecials=JUSTLEFTCASE;


	if ( !(camVars.lastFlags&FIXEDPOS) && (camVars.flags&FIXEDPOS) ) // entered  case from not in case
	{
		// ok we want to go from where the cam is now to the case position
		// at some time it might be a good idea to do somthing with the transistion time (later if pos)
		// so set the start positions with where the camera is now
		camVars.startCamPos.vx=camVars.camAtStart.vx;	// should be correct
		camVars.startCamPos.vy=camVars.camAtStart.vy;
		camVars.startCamPos.vz=camVars.camAtStart.vz;

		// set the target
		camVars.targetCamPos.vx=camVars.camMovePos.vx;
		camVars.targetCamPos.vy=camVars.camMovePos.vy;
		camVars.targetCamPos.vz=camVars.camMovePos.vz;
		// and set the times for the transistion
		camVars.timer=0;
		camVars.posChange=TRUE;	// so we know were changing
	}
	else if ( (camVars.lastFlags&FIXEDPOS) && (camVars.flags&FIXEDPOS) )
	{
		if ( (camVars.targetCamPos.vx!=camVars.camMovePos.vx)
		|| (camVars.targetCamPos.vy!=camVars.camMovePos.vy) 
		|| (camVars.targetCamPos.vz!=camVars.camMovePos.vz) )	// has the case data changed
		{
			if ( camVars.timer!=camVars.camTransitionSpeed )
			{
				camVars.startCamPos.vx= ((camVars.targetCamPos.vx*camVars.timer) + (camVars.startCamPos.vx*(camVars.camTransitionSpeed-camVars.timer)) )/camVars.camTransitionSpeed;
				camVars.startCamPos.vy= ((camVars.targetCamPos.vy*camVars.timer) + (camVars.startCamPos.vy*(camVars.camTransitionSpeed-camVars.timer)) )/camVars.camTransitionSpeed;
				camVars.startCamPos.vz= ((camVars.targetCamPos.vz*camVars.timer) + (camVars.startCamPos.vz*(camVars.camTransitionSpeed-camVars.timer)) )/camVars.camTransitionSpeed;
			}
			else
			{
				camVars.startCamPos.vx=camVars.targetCamPos.vx;	// the target position becomes the start positon
				camVars.startCamPos.vy=camVars.targetCamPos.vy;
				camVars.startCamPos.vz=camVars.targetCamPos.vz;
			}
			// set the target
			camVars.targetCamPos.vx=camVars.camMovePos.vx;
			camVars.targetCamPos.vy=camVars.camMovePos.vy;
			camVars.targetCamPos.vz=camVars.camMovePos.vz;
			camVars.timer=0;
			camVars.posChange=TRUE;	// so we know were changing
		}
	}


	if ( !(camVars.flags&FIXEDPOS) && camVars.timer) // returning from case to normal
	{
		if (camVars.timer<(camVars.camTransitionSpeed>>2) && (camVars.caseSpecials&JUSTLEFTCASE) )  // the lower the transistion time the worse the cam gets
		{
// ok the idea here is to do some fancy interpolations on the timer and positions
			//camVars.targetCamPos.vx= ((camVars.targetCamPos.vx*camVars.timer) + (camVars.startCamPos.vx*(camVars.camTransitionSpeed-camVars.timer)) )/camVars.camTransitionSpeed;
			//camVars.targetCamPos.vy= ((camVars.targetCamPos.vy*camVars.timer) + (camVars.startCamPos.vy*(camVars.camTransitionSpeed-camVars.timer)) )/camVars.camTransitionSpeed;
			//camVars.targetCamPos.vz= ((camVars.targetCamPos.vz*camVars.timer) + (camVars.startCamPos.vz*(camVars.camTransitionSpeed-camVars.timer)) )/camVars.camTransitionSpeed;
// no lets use the results from last time
			camVars.targetCamPos.vx= camVars.interpCamPos.vx;
			camVars.targetCamPos.vy= camVars.interpCamPos.vy;
			camVars.targetCamPos.vz= camVars.interpCamPos.vz;
			camVars.timer=camVars.camTransitionSpeed;			
		}
		camVars.caseSpecials|=UPDATEPOSITION;	// flag for updating return position
	}

/*
	if (camVars.flags&FIXEDPOSSNAP)
	{
		mycamera.vpx=camVars.camMovePosSnap.vx;
		mycamera.vpy=camVars.camMovePosSnap.vy;
		mycamera.vpz=camVars.camMovePosSnap.vz;
	}

	if (camVars.flags&FIXEDLOOKSNAP)
	{
		mycamera.vrx=camVars.viewMovePosSnap.vx;
		mycamera.vry=camVars.viewMovePosSnap.vy;
		mycamera.vrz=camVars.viewMovePosSnap.vz;

		//camVars.tarChangeOn=TRUE;
		//camVars.tarChange=TRUE;
	}
*/
	if (camVars.flags&FIXEDLOOK)
	{
		camVars.targetViewPos.vx=camVars.viewMovePos.vx;
		camVars.targetViewPos.vy=camVars.viewMovePos.vy;
		camVars.targetViewPos.vz=camVars.viewMovePos.vz;
		camVars.tarChangeOn=TRUE;
		camVars.tarChange=TRUE;

		if ( !(camVars.flags&FIXEDPOS) && !(camVars.flags&FIXEDPOSSNAP) )	// fixed look should never be used without a fixed pos
		{
			camVars.targetCamPos.vx=mycamera.vpx;	// This is here as a just in case
			camVars.targetCamPos.vy=mycamera.vpy;
			camVars.targetCamPos.vz=mycamera.vpz;
			camVars.posChangeOn=TRUE;
			camVars.posChange=TRUE;
			DB("fixed look used without fixed pos\n");
		}		
	}

	if (camVars.flags&CHANGEDISTANCE)
	{
		camVars.lookDistance=camVars.camDistance+camVars.caseDistance;
		//DB("change distance case\n");
	}
	else if (camVars.lastFlags&CHANGEDISTANCE)
		camVars.lookDistance=camVars.camDistance;


	if (camVars.flags&CHANGEHEIGHT)
	{
		camVars.normalHeight=camVars.camHeight+camVars.caseHeight;
		//DB("change height case\n");
	}
	else if (camVars.lastFlags&CHANGEHEIGHT)
	{
		camVars.normalHeight=camVars.camHeight;
	}
	camVars.lastFlags=camVars.flags;
	camVars.flags=NULL;

	//DB("Case Flag %d \n",camVars.lastFlags);
 #ifdef	CASEDEBUG
	sprintf(message,"Case Flag %d ",camVars.lastFlags);
	fontPrint(font, -220,-100, message, 128,128,0);
	sprintf(message,"timer %d timerTar %d transistion time %d",camVars.timer,camVars.timerTar,camVars.camTransitionSpeed);
	fontPrint(font, -220,-85, message, 128,128,0);
	sprintf(message,"cam from pos X %d  Y %d  Z %d",camVars.startCamPos.vx,camVars.startCamPos.vy,camVars.startCamPos.vz);
	fontPrint(font, -220,-70, message, 128,128,0);
	sprintf(message,"cam to pos X %d  Y %d  Z %d",camVars.targetCamPos.vx,camVars.targetCamPos.vy,camVars.targetCamPos.vz);
	fontPrint(font, -220,-55, message, 128,128,0);

	sprintf(message,"target from pos X %d  Y %d  Z %d",camVars.startViewPos.vx,camVars.startViewPos.vy,camVars.startViewPos.vz);
	fontPrint(font, -220,-40, message, 128,128,0);
	sprintf(message,"target to pos X %d  Y %d  Z %d",camVars.targetViewPos.vx,camVars.targetViewPos.vy,camVars.targetViewPos.vz);
	fontPrint(font, -220,-25, message, 128,128,0);


	sprintf(message,"Camera position X %d  Y %d  Z %d",mycamera.vpx,mycamera.vpy,mycamera.vpz);
	fontPrint(font, -220,-10, message, 128,128,0);

	switch(camVars.camType)
	{
		case HUTCAM:
			sprintf(message,"Camera type = HUTCAM");
			fontPrint(font, -220,5, message, 128,128,0);
			break;

		case ROTCAM:
			sprintf(message,"Camera type = ROTCAM");
			fontPrint(font, -220,5, message, 128,128,0);
			break;

		case RAILCAMAXIS:
			sprintf(message,"Camera type = RAILCAMAXIS");
			fontPrint(font, -220,5, message, 128,128,0);
			break;

		case RAILCAM:
			sprintf(message,"Camera type = RAILCAM");
			fontPrint(font, -220,5, message, 128,128,0);
			break;
	}
	loop=35;
	if (camVars.lastFlags&FIXEDPOS)
	{
		sprintf(message,"FIXEDPOS ");
		fontPrint(font, -220,loop, message, 128,128,0);
		loop+=15;
	}
	if (camVars.lastFlags&FIXEDPOSSNAP)
	{
		sprintf(message,"FIXEDPOSSNAP ");
		fontPrint(font, -220,loop, message, 128,128,0);
		loop+=15;
	}
	if (camVars.lastFlags&FIXEDLOOK)
	{
		sprintf(message,"FIXEDLOOK ");
		fontPrint(font, -220,loop, message, 128,128,0);
		loop+=15;
	}
	if (camVars.lastFlags&FIXEDLOOKSNAP)
	{
		sprintf(message,"FIXEDLOOKSNAP ");
		fontPrint(font, -220,loop, message, 128,128,0);
		loop+=15;
	}
	if (camVars.lastFlags&FIXEDROT)
	{
		sprintf(message,"FIXEDROT ");
		fontPrint(font, -220,loop, message, 128,128,0);
		loop+=15;
	}
	if (camVars.lastFlags&CHANGEHEIGHT)
	{
		sprintf(message,"CHANGEHEIGHT ");
		fontPrint(font, -220,loop, message, 128,128,0);
		loop+=15;
	}
	if (camVars.lastFlags&CHANGEDISTANCE)
	{
		sprintf(message,"CHANGEDISTANCE ");
		fontPrint(font, -220,loop, message, 128,128,0);
		loop+=15;
	}
	if (camVars.lastFlags&NOSWEEPLOOK)
	{
		sprintf(message,"NOSWEEPLOOK ");
		fontPrint(font, -220,loop, message, 128,128,0);
		loop+=15;
	}
#endif
	//DB("Case Flag %d \n",camVars.lastFlags);
	//DB("timer pos %d  transistion time %d\n",camVars.timer,camVars.camTransitionSpeed);
	//DB("from pos X %d  Y %d  Z %d\n",camVars.startCamPos.vx,camVars.startCamPos.vy,camVars.startCamPos.vz);
	//DB("to pos X %d  Y %d  Z %d\n",camVars.targetCamPos.vx,camVars.targetCamPos.vy,camVars.targetCamPos.vz);
	//sprintf(message,"cam pos X %d  Y %d  Z %d",mycamera.vpx,mycamera.vpy,mycamera.vpz);
	//fontPrint(font, -220,-40, message, 128,128,0);
}
////////////////////////////////////////////////////////////////////////////
// Routine to handle cam modes changing

void	changeCamMode(int mode)
{


	if (mode==camVars.camType || camVars.camTypeChanged) return;
	if (mode>=MAXCAMERAMODES)
	{
		DB("%d mode does not exist\n",mode);
		return;
	}

	camVars.lastFlags=NULL;

//	if (camVars.justStartedTimer) camVars.justStartedTimer=0;

	switch(mode)
	{
		case HUTCAM:
			DB("setting cam to hutcam\n");
			break;
		case ROTCAM:
			DB("setting cam to follow cam\n");
			break;
		case RAILCAMAXIS:
			DB("setting cam to axis aligned rail cam\n");
			break;
		case RAILCAM:
			DB("setting cam to rail cam\n");
			break;
	}

	if (camVars.timer)	// is cam already moveing between 2 points
	{
		camVars.targetCamPos.vx=mycamera.vpx;
		camVars.targetCamPos.vy=mycamera.vpy;
		camVars.targetCamPos.vz=mycamera.vpz;

//		camVars.timer=camVars.camTransitionSpeed;
//		camVars.caseSpecials|=UPDATEPOSITION;	// flag for updating return position
	}
	else
	{
		camVars.targetCamPos.vx=mycamera.vpx;
		camVars.targetCamPos.vy=mycamera.vpy;
		camVars.targetCamPos.vz=mycamera.vpz;

//		camVars.timer=camVars.camTransitionSpeed;
//		camVars.caseSpecials|=UPDATEPOSITION;	// flag for updating return position
	}

	if (camVars.justStartedTimer)
	{
		camVars.timer=0;
		camVars.caseSpecials=0;
		camVars.posChange=FALSE;
		camVars.posChangeOn=FALSE;
	}
	else
	{
		camVars.timer=camVars.camTransitionSpeed;
		camVars.caseSpecials|=UPDATEPOSITION;	// flag for updating return position
		camVars.posChange=TRUE;
		camVars.posChangeOn=FALSE;
	}

	camVars.lastCamType=camVars.camType;
	camVars.camType=mode;

	camVars.flags=NULL;
	camVars.lastFlags=NULL;

	//camVars.camTypeChanged=TRUE;

/*
	return;
	camVars.startCamPos.vx=camVars.camAfterStart.vx;
	camVars.startCamPos.vy=camVars.camAfterStart.vy;
	camVars.startCamPos.vz=camVars.camAfterStart.vz;

	if (mode!=RAILCAM)
	//if (camVars.camType!=RAILCAM)
	{
		camVars.timer=camVars.camTransitionSpeed;
		camVars.lastCamType=camVars.camType;
		camVars.camType=mode;
		camVars.camTypeChanged=TRUE;	// setup for positional changes
		camVars.requiredDistance=camVars.lookDistance;
		camVars.timer=camVars.camTransitionSpeed;
	}
	else
	{
		if (!camVars.timer)
		{
			camVars.timer=0;
			camVars.timer=camVars.camTransitionSpeed;
			camVars.lastCamType=camVars.camType;
			camVars.camType=mode;
			camVars.requiredDistance=camVars.lookDistance;

			camVars.targetViewPos.vx=camVars.targetEnemy->pos.vx;
			camVars.targetViewPos.vy=(camVars.targetEnemy->pos.vy-HEIGHTOFFSET)-camVars.targetRadius/8;
			camVars.targetViewPos.vz=camVars.targetEnemy->pos.vz;

			camVars.timerTar=camVars.camTransitionSpeed;
			camVars.tarChange=TRUE;

			camVars.targetCamPos.vx=mycamera.vpx;
			camVars.targetCamPos.vy=mycamera.vpy;
			camVars.targetCamPos.vz=mycamera.vpz;
		}
		else
		{
			camVars.timer=camVars.camTransitionSpeed;
			camVars.lastCamType=camVars.camType;
			camVars.camType=mode;
			camVars.requiredDistance=camVars.lookDistance;

			camVars.targetViewPos.vx=camVars.targetEnemy->pos.vx;
			camVars.targetViewPos.vy=(camVars.targetEnemy->pos.vy-HEIGHTOFFSET)-camVars.targetRadius/8;
			camVars.targetViewPos.vz=camVars.targetEnemy->pos.vz;


			camVars.timerTar=camVars.camTransitionSpeed;
			camVars.tarChange=TRUE;

			camVars.targetCamPos.vx=mycamera.vpx;
			camVars.targetCamPos.vy=mycamera.vpy;
			camVars.targetCamPos.vz=mycamera.vpz;
		}
	}

	//camVars.timer=CHANGETIME;
	camVars.posChange=TRUE;
	camVars.posChangeOn=FALSE;

	camVars.targetCamPos.vx=camVars.camRealPos.vx=mycamera.vpx;
	camVars.targetCamPos.vy=camVars.camRealPos.vy=mycamera.vpy;
	camVars.targetCamPos.vz=camVars.camRealPos.vz=mycamera.vpz;

	camVars.targetViewPos.vx=camVars.camRealView.vx=mycamera.vrx;
	camVars.targetViewPos.vy=camVars.camRealView.vy=mycamera.vry;
	camVars.targetViewPos.vz=camVars.camRealView.vz=mycamera.vrz;
	// setup to interpolate from where we are now to the new cam type

	camVars.startCamPos.vx=mycamera.vpx;
	camVars.startCamPos.vy=mycamera.vpy;
	camVars.startCamPos.vz=mycamera.vpz;

	camVars.startCamPos.vx=camVars.camAtStart.vx;
	camVars.startCamPos.vy=camVars.camAtStart.vy;
	camVars.startCamPos.vz=camVars.camAtStart.vz;

*/
}

////////////////////////////////////////////////////////////////////////////
// certain cases/changes not compatable with others this sorts it out
void	CamModesAllowed(void)
{
	if (camVars.camTypeChanged)	// If changing types disable just about everything
	{
		//camVars.flags&=(CHANGEHEIGHT+CHANGEDISTANCE);
		//camVars.flags|=NOSWEEPLOOK;
		camVars.flags=NULL;
	}
	if (camVars.flags&ALLFIXEDTYPES)
		camVars.flags|=NOSWEEPLOOK;

	if (camVars.camType==RAILCAM || camVars.camType==RAILCAMAXIS)
	{
		camVars.flags&=~(ALLFIXEDTYPES);	// will probably break railcam so remove them
		//camVars.flags|=NOSWEEPLOOK;
		camVars.sweepFlag=FALSE;
	}
	//else camVars.sweepFlag=TRUE;
}

/**************************************************************************
	FUNCTION:	intersectLines()
	PURPOSE:	Find intersection of two lines
	PARAMETERS:	Line end points, actual point return ptrs
	RETURNS:	0/1
	Problem with overflows
**************************************************************************/

UBYTE intersectLines(long x1,long y1,long x2,long y2,long x3,long y3,long x4,long y4, long *x,long *y)
{
	long	Ax,Bx,Cx,Ay,By,Cy,d,e,f,num,offset;

	Ax = x2-x1;
	Bx = x3-x4;
	Ay = y2-y1;
	By = y3-y4;
	Cx = x1-x3;
	Cy = y1-y3;
	//DB("By %d Cx %d Bx %d Cy %d\n",By,Cx,Bx,Cy);
	d = By*Cx-Bx*Cy;
	//DB("d %d\n",d);
	f = Ay*Bx-Ax*By;
	if (f>0)
	{
		if ((d<0)||(d>f))
			return 0;
	}
	else
	{
		if ((d>0)||(d<f))
			return 0;
	}
	e = Ax*Cy-Ay*Cx;
	if (f>0)
	{
		if ((e<0)||(e>f))
			return 0;
	}
	else
	{
		if ((e>0)||(e<f))
			return 0;
	}
	if (f==0)
		return 0;
	num = d*Ax;
	offset = SAMESIGN(num,f)?f/2:-f/2;
	*x = x1+(num+offset)/f;
	num = d*Ay;
	offset = SAMESIGN(num,f)?f/2:-f/2;
	*y = y1+(num+offset)/f;
	return 1;
}


////////////////////////////////////////////////////////////////////////////
/*
void	camPosChange(void)
{

	if (camVars.posChangeOn)	// moving from start to target
	{
		if (camVars.timer==camVars.camTransitionSpeed)	// at end
		{
			//camVars.startCamPos.vx=camVars.targetCamPos.vx;
			//camVars.startCamPos.vx=camVars.targetCamPos.vx;
			//camVars.startCamPos.vx=camVars.targetCamPos.vx;
			//camVars.timer=0;
			camVars.posChangeOn=FALSE;
		}
		else
		{
			camVars.targetCamPos.vx= ((camVars.targetCamPos.vx*camVars.timer) + (camVars.startCamPos.vx*(camVars.camTransitionSpeed-camVars.timerTar)) )/camVars.camTransitionSpeed;
			camVars.targetCamPos.vy= ((camVars.targetCamPos.vy*camVars.timer) + (camVars.startCamPos.vy*(camVars.camTransitionSpeed-camVars.timerTar)) )/camVars.camTransitionSpeed;
			camVars.targetCamPos.vz= ((camVars.targetCamPos.vz*camVars.timer) + (camVars.startCamPos.vz*(camVars.camTransitionSpeed-camVars.timerTar)) )/camVars.camTransitionSpeed;
			camVars.timer=camVars.camTransitionSpeed;
			camVars.posChangeOn=FALSE;
		}		
	}
	else
	{
		if (camVars.posChange) // moving from target to start
		{
			camVars.targetCamPos.vx= ((camVars.targetCamPos.vx*camVars.timer) + (camVars.startCamPos.vx*(camVars.camTransitionSpeed-camVars.timer)) )/camVars.camTransitionSpeed;
			camVars.targetCamPos.vy= ((camVars.targetCamPos.vy*camVars.timer) + (camVars.startCamPos.vy*(camVars.camTransitionSpeed-camVars.timer)) )/camVars.camTransitionSpeed;
			camVars.targetCamPos.vz= ((camVars.targetCamPos.vz*camVars.timer) + (camVars.startCamPos.vz*(camVars.camTransitionSpeed-camVars.timer)) )/camVars.camTransitionSpeed;

			//camVars.targetCamPos.vx= ((camVars.startCamPos.vx*camVars.timer) + (camVars.targetCamPos.vx*(camVars.camTransitionSpeed-camVars.timerTar)) )/camVars.camTransitionSpeed;
			//camVars.targetCamPos.vy= ((camVars.startCamPos.vy*camVars.timer) + (camVars.targetCamPos.vy*(camVars.camTransitionSpeed-camVars.timerTar)) )/camVars.camTransitionSpeed;
			//camVars.targetCamPos.vz= ((camVars.startCamPos.vz*camVars.timer) + (camVars.targetCamPos.vz*(camVars.camTransitionSpeed-camVars.timerTar)) )/camVars.camTransitionSpeed;

			camVars.timer=camVars.camTransitionSpeed;	// move from target to start
		}
		else
		{
			camVars.startCamPos.vx=mycamera.vpx;
			camVars.startCamPos.vy=mycamera.vpy;
			camVars.startCamPos.vz=mycamera.vpz;
			camVars.timer=camVars.camTransitionSpeed;
			camVars.posChange=TRUE;
		}
	}
}
*/
////////////////////////////////////////////////////////////////////////////
void	camTargetChange(void)
{
	//char	message[255];

	DB("attempting cam target change\n");

//	camVars.camPosAtTargetChange.vx=mycamera.vpx;
//	camVars.camPosAtTargetChange.vy=mycamera.vpy;
//	camVars.camPosAtTargetChange.vz=mycamera.vpz;
// updating puzzles before the camera sortted all this out
	if (!camVars.timerTar)
	{
		if (camVars.targetEnemy)
		{
			camVars.targetViewPos.vx=camVars.targetEnemy->pos.vx;
			camVars.targetViewPos.vy=(camVars.targetEnemy->pos.vy-HEIGHTOFFSET)-camVars.targetRadius/8;
			camVars.targetViewPos.vz=camVars.targetEnemy->pos.vz;
		}
		else
		{
			DB("no target enemy\n");
			camVars.tarChange=FALSE;
			return;
			//camVars.targetViewPos.vx=0;
			//camVars.targetViewPos.vy=0;
			//camVars.targetViewPos.vz=0;
		}
	}
	else
	{
		camVars.targetViewPos.vx= ((camVars.targetViewPos.vx*camVars.timerTar) + (camVars.startViewPos.vx*(camVars.camTransitionSpeed-camVars.timerTar)) )/camVars.camTransitionSpeed;
		camVars.targetViewPos.vy= ((camVars.targetViewPos.vy*camVars.timerTar) + (camVars.startViewPos.vy*(camVars.camTransitionSpeed-camVars.timerTar)) )/camVars.camTransitionSpeed;
		camVars.targetViewPos.vz= ((camVars.targetViewPos.vz*camVars.timerTar) + (camVars.startViewPos.vz*(camVars.camTransitionSpeed-camVars.timerTar)) )/camVars.camTransitionSpeed;
	}
	camVars.timerTar=camVars.camTransitionSpeed;
	camVars.tarChange=TRUE;

//	DB("Changing camera target \n");
	//fontPrint(font, -220,40, message, 128,128,0);
//	DB("start cam pos X %d Y %d Z %d\n",mycamera.vpx,mycamera.vpy,mycamera.vpz);
	//fontPrint(font, -220,55, message, 128,128,0);


}
////////////////////////////////////////////////////////////////////////////
void	hutCamera(void)
{
int	angle;

	angle=utilCalcAngle( (mycamera.vpx-mycamera.vrx),(mycamera.vpz-mycamera.vrz) );
	camVars.camAngle=(angle+2048)&4095;

	mycamera.vrx=camVars.targetEnemy->pos.vx;
	mycamera.vry=camVars.targetEnemy->pos.vy;
	mycamera.vrz=camVars.targetEnemy->pos.vz;

	mycamera.vpx=mycamera.vrx=0;
	//mycamera.vpy=mycamera.vry-levinfo->initial_cam_height;
	mycamera.vpy=-levinfo->initial_cam_height;
	mycamera.vpz=mycamera.vrz-levinfo->initial_cam_distance;


//	if (levinfo->initial_cam_distance<0) camVars.camAngle=2048;
//	else camVars.camAngle=0;

	if (camVars.justStartedTimer)	// stop camera going mad when level just started
	{
		camVars.justStartedTimer=0;
		camVars.timer=0;
		camVars.posChange=FALSE;
	}
	//DB("distance %d\n",levinfo->initial_cam_distance);
}
////////////////////////////////////////////////////////////////////////////
#define	TWEEDYTRANSISTIONSPEED	30

#define	TWEEDYCAMHOLDTIME	25

void	tweedyCaseHandler(void)
{
//	char	message[255];
	int		x,z;

// tdb if cam target close to door in eggroom then dont disable char control
	if (camVars.timeTillNextChange) camVars.timeTillNextChange--;

	if (camVars.tweedySpecial==1)
	{
		if (!camVars.timerTar)
		{
			if (camVars.timer) // oh joy
			{
				camVars.timer= (camVars.timer*TWEEDYTRANSISTIONSPEED)/camVars.camTransitionSpeed;
			}
			camVars.camTransitionSpeed=TWEEDYTRANSISTIONSPEED;	// set speed for fast pan
			characterDisableController=CONTROLLER_DISABLED_RESET;
		}

		if (camVars.timerTar<camVars.camTransitionSpeed)
		{
			camVars.tarChangeOn=TRUE;
			camVars.tarChange=TRUE;
		}
		else camVars.tweedySpecial=2;
		
		switch (levinfo->level_number)
		{
			case LEVNUMBER_A2_EGGROOM:
			case LEVNUMBER_A4_EGGROOM:
				camVars.targetViewPos.vx=288*8;
				camVars.targetViewPos.vy=-156*8;
				camVars.targetViewPos.vz=-641*8;

				x=camVars.targetEnemy->pos.vx>>3;
				z=camVars.targetEnemy->pos.vz>>3;

				//if (x>170 && x<510 && z>-712 && z<-372)
				//DB(" X %d Z %d\n",x,z);

				if ( x>510 || z>-372)
				{
					characterDisableController=CONTROLLER_DISABLED_RESET;
				}			

				break;

			case LEVNUMBER_A2_TOOLSHED_D:
				camVars.targetViewPos.vx=303*8;
				camVars.targetViewPos.vy=-103*8;
				camVars.targetViewPos.vz=670*8;
				characterDisableController=CONTROLLER_DISABLED_RESET;
				break;
		}

		camVars.startViewPos.vx=camVars.targetEnemy->pos.vx;
		camVars.startViewPos.vy=(camVars.targetEnemy->pos.vy-HEIGHTOFFSET)-camVars.targetRadius/8;
		camVars.startViewPos.vz=camVars.targetEnemy->pos.vz;
		camVars.tweedyHoldTime=TWEEDYCAMHOLDTIME;
		//characterDisableController=CONTROLLER_DISABLED_RESET;
	}

	if (camVars.tweedySpecial==2)
	{
		if (camVars.tweedyHoldTime)
		{
			camVars.tweedyHoldTime--;

			switch (levinfo->level_number)
			{
				case LEVNUMBER_A2_EGGROOM:
				case LEVNUMBER_A4_EGGROOM:
					camVars.targetViewPos.vx=288*8;
					camVars.targetViewPos.vy=-156*8;
					camVars.targetViewPos.vz=-641*8;

					x=camVars.targetEnemy->pos.vx>>3;
					z=camVars.targetEnemy->pos.vz>>3;

					//if (x>170 && x<510 && z>-712 && z<-372)
					//DB(" X %d Z %d\n",x,z);

					if ( x>510 || z>-372)
					{
						characterDisableController=CONTROLLER_DISABLED_RESET;
					}
					break;

				case LEVNUMBER_A2_TOOLSHED_D:
					camVars.targetViewPos.vx=303*8;
					camVars.targetViewPos.vy=-103*8;
					camVars.targetViewPos.vz=670*8;
					characterDisableController=CONTROLLER_DISABLED_RESET;
					break;
			}

			camVars.startViewPos.vx=camVars.targetEnemy->pos.vx;
			camVars.startViewPos.vy=(camVars.targetEnemy->pos.vy-HEIGHTOFFSET)-camVars.targetRadius/8;
			camVars.startViewPos.vz=camVars.targetEnemy->pos.vz;
			camVars.tarChangeOn=TRUE;
			camVars.tarChange=TRUE;
			//characterDisableController=CONTROLLER_DISABLED_RESET;
		}
		if (!camVars.timerTar)
		{
			camVars.tweedySpecial=0;
			camVars.camTransitionSpeed=levinfo->cam_transition_speed;
			if (camVars.timer) // needs to deal with fact that transition speed has changed
			{
				camVars.timer= (camVars.timer*camVars.camTransitionSpeed)/TWEEDYTRANSISTIONSPEED;
			}
		}
	}

//	sprintf(message,"Tweedy Flag %d ",camVars.tweedySpecial);
//	fontPrint(font, -220,-100, message, 128,128,0);
//	sprintf(message,"timer tar %d  transistion time %d",camVars.timerTar,camVars.camTransitionSpeed);
//	fontPrint(font, -220,-85, message, 128,128,0);
//	sprintf(message,"timer %d  transistion time %d",camVars.timer,camVars.camTransitionSpeed);
//	fontPrint(font, -220,-70, message, 128,128,0);


}

////////////////////////////////////////////////////////////////////////////
void	niceIdeasWhichDidntWork(void)
{
/*
	int	height,temp,loop,dist1,dist2;
	VECTOR	camPos;
	LONG	tempHeight[9];
	LONG	dist=500*512;
	LONG	left,right;
	LONG	start,end;
	
	camPos.vx=mycamera.vpx*512;
	camPos.vy=mycamera.vpy*512;
	camPos.vz=mycamera.vpz*512;

	dist1=9999999;

	tempHeight[0]=height=getHeightAtCam(camPos.vx,camPos.vy,camPos.vz, &hitBox[0] )/512;
	tempHeight[1]=getHeightAtCam(camPos.vx+dist,camPos.vy,camPos.vz, &hitBox[1] )/512;
	tempHeight[2]=getHeightAtCam(camPos.vx-dist,camPos.vy,camPos.vz, &hitBox[2] )/512;

	tempHeight[3]=getHeightAtCam(camPos.vx-dist,camPos.vy,camPos.vz-dist, &hitBox[3] )/512;
	tempHeight[4]=getHeightAtCam(camPos.vx,camPos.vy,camPos.vz-dist, &hitBox[4] )/512;
	tempHeight[5]=getHeightAtCam(camPos.vx+dist,camPos.vy,camPos.vz-dist, &hitBox[5] )/512;

	tempHeight[6]=getHeightAtCam(camPos.vx-dist,camPos.vy,camPos.vz+dist, &hitBox[6] )/512;
	tempHeight[7]=getHeightAtCam(camPos.vx,camPos.vy,camPos.vz+dist, &hitBox[7] )/512;
	tempHeight[8]=getHeightAtCam(camPos.vx+dist,camPos.vy,camPos.vz+dist, &hitBox[8] )/512;

	if ( (tempHeight[1]<camHeight) && (tempHeight[1]!=-1) )
	{
		right=(hitBox[1].pX-camPos.vx);
		if (right<0) right=0;
	}
	else right=999999;

	if ( (tempHeight[2]<camHeight) && (tempHeight[2]!=-1) )
	{
		left=(camPos.vx-(hitBox[2].pX+hitBox[2].sX));
		if (left<0) left=0;
	}
	else left=999999;

	if ( (tempHeight[0]<camHeight) && tempHeight[0]!=-1) 
	{
		temp=tempHeight[0]-camHeight;
		mycamera.vpy+=temp*CAMMOD;
	}
	else  if (left!=999999 || right!=999999)
	{
		if (left>right)
		{
			end=tempHeight[1]-camHeight;
			temp=(end*(dist-right))/dist;
			mycamera.vpy+=temp*CAMMOD;
		}
		else
		{
			end=tempHeight[2]-camHeight;
			temp=(end*(dist-left))/dist;
			mycamera.vpy+=temp*CAMMOD;
		}
	}
	GsSetRefView2L(&mycamera);
*/
//	I liked this one but mutiple objects fucked it up
/*
	int	angle,angle1;
	VECTOR	temp,camPos,actorPos;
	int	mag,temp1,temp2;
	int	rotFlag=FALSE;

	if (!camVars.holdPositionFlag)
	{
		camVars.holdPosition.vx=mycamera.vpx;
		camVars.holdPosition.vy=mycamera.vpy;
		camVars.holdPosition.vz=mycamera.vpz;
	}
	
	mycamera.vry=(CamVars->targetModel->position.vy-HEIGHTOFFSET)-CamVars->targetRadius/8;
	mycamera.vrx=CamVars->targetModel->position.vx;
	mycamera.vrz=CamVars->targetModel->position.vz;

	angle=utilCalcAngle( (mycamera.vpx-mycamera.vrx),(mycamera.vpz-mycamera.vrz) );
	CamVars->camAngle=(angle+2048)&4095;

	temp.vx=mycamera.vpx-mycamera.vrx;
	temp.vy=0;
	temp.vz=mycamera.vpz-mycamera.vrz;
	mag=Magnitude(&temp);

	if (mag==0) mag=1;

	if (!temp.vx && !temp.vz)
		temp.vx=1;

	temp1=CamVars->lookDistance;
	if (temp1)
	{
		temp.vx=(temp.vx*temp1)/mag;
		temp.vy=(temp.vy*temp1)/mag;
		temp.vz=(temp.vz*temp1)/mag;
	}
	temp1 = findShortestAngle(CamVars->camAngle+2048,CamVars->targetModel->psiData.object->rotate.vy);

	CamVars->camPos2.vx=(mycamera.vrx+temp.vx)*512;
	CamVars->camPos2.vz=(mycamera.vrz+temp.vz)*512;
	CamVars->camPos2.vy=(mycamera.vry-CamVars->actualHeight)*512;

	actorPos.vx=CamVars->targetModel->position.vx*512;
	actorPos.vy=CamVars->targetModel->position.vy*512;
	actorPos.vz=CamVars->targetModel->position.vz*512;

	findClosestBox(actorPos.vx,actorPos.vy,actorPos.vz,CamVars->camPos2.vx,CamVars->camPos2.vy,CamVars->camPos2.vz,&hitBox,FALSE);
	if (hitBox.sX)
	{
		CamVars->quadrant=findQuadrant(camPos,actorPos);
		findSwingDirection(camPos,actorPos);
	}
	else CamVars->swingDirection=NULL;

	temp1=0;

	if (CamVars->swingDirection==LEFT)
	{
		temp1=512;
	}
	if (CamVars->swingDirection==RIGHT)
	{
		temp1=-512;
	}

	RotateVector2D(&temp, &temp, -temp1/32);


	temp1=CamVars->actualDistance;
	mag=Magnitude(&temp);

	if (temp1)
	{
		temp.vx=(temp.vx*temp1)/mag;
		temp.vy=(temp.vy*temp1)/mag;
		temp.vz=(temp.vz*temp1)/mag;
	}

	mycamera.vpx=mycamera.vrx+temp.vx;
	mycamera.vpz=mycamera.vrz+temp.vz;
	mycamera.vpy=mycamera.vry-CamVars->actualHeight;
*/

}


void	oldjunk(void)
{
/*
	if (position==CAMRIGHT)
	//if ( camPosition&RIGHT)
	{
		camVars.targetCamPos.vx=(pBox1->pX+pBox1->sX)/512;
		camVars.targetViewPos.vx=((pBox1->pX+pBox1->sX)/512)+200;
		camVars.posChange=TRUE;

		camVars.targetCamPos.vz=mycamera.vrz;
		camVars.targetViewPos.vz=mycamera.vpz;

		if (camPosition&CAMFAR)
		{
			camVars.targetViewPos.vz=mycamera.vrz+(mycamera.vrz-mycamera.vpz);
		}
	}
	if (position==CAMLEFT)
	{
		camVars.targetCamPos.vx=(pBox1->pX)/512;
		camVars.targetViewPos.vx=((pBox1->pX)/512)-200;
		camVars.posChange=TRUE;
		camVars.targetCamPos.vz=mycamera.vrz;
		camVars.targetViewPos.vz=mycamera.vpz;

		if (camPosition&CAMFAR)
		{
			camVars.targetViewPos.vz=mycamera.vrz+(mycamera.vrz-mycamera.vpz);
		}
	}

	if (position==CAMNEAR)
	{
		dist=mycamera.vrz-mycamera.vpz;
		camVars.targetCamPos.vz=(pBox1->pZ/512);
		camVars.targetViewPos.vz=(pBox1->pZ/512)-800;

		if (camPosition&CAMRIGHT)
		{
			//camVars.targetViewPos.vx=(pBox1->pX+pBox1->sX)/512;
			//camVars.targetCamPos.vx=((pBox1->pX+pBox1->sX)/512)-dist;
			camVars.targetViewPos.vx=mycamera.vpx+dist;
			camVars.targetCamPos.vx=mycamera.vpx;//+dist;
		}
		else
		{
			//camVars.targetViewPos.vx=(pBox1->pX)/512;
			//camVars.targetCamPos.vx=((pBox1->pX)/512)+dist;
			camVars.targetViewPos.vx=mycamera.vpx-dist;
			camVars.targetCamPos.vx=mycamera.vpx;//+dist;
		}
	}

	if (position==CAMFAR)
	{
		dist=mycamera.vrz-mycamera.vpz;
		camVars.targetCamPos.vz=((pBox1->pZ+pBox1->sZ)/512);
		camVars.targetViewPos.vz=((pBox1->pZ+pBox1->sZ)/512)+800;

		if (camPosition&CAMRIGHT)
		{
			//camVars.targetViewPos.vx=(pBox1->pX+pBox1->sX)/512;
			//camVars.targetCamPos.vx=((pBox1->pX+pBox1->sX)/512)-dist;
			camVars.targetViewPos.vx=mycamera.vpx+dist;
			camVars.targetCamPos.vx=mycamera.vpx;//+dist;
		}
		else
		{
			//camVars.targetViewPos.vx=(pBox1->pX)/512;
			//camVars.targetCamPos.vx=((pBox1->pX)/512)+dist;
			camVars.targetViewPos.vx=mycamera.vpx-dist;
			camVars.targetCamPos.vx=mycamera.vpx;//+dist;
		}
	}
*/
	//if (!camVars.posChange ) mycamera.vpy=mycamera.vry-heightChange;
	//else
	//mycamera.vpy=mycamera.vry-heightChange;


/*	int quadrant,dx1,dz1;

	if (actorPos.vx<hitBox.pX)
	{
		dx1=hitBox.pX-actorPos.vx;
		if (actorPos.vz<hitBox.pZ)
		{
			dz1=hitBox.pZ-actorPos.vz;
			if (dx1>dz1) quadrant=4;	// left
			else quadrant=3;			// near
		}
		else if ( actorPos.vz>(hitBox.pZ+hitBox.sZ) )
		{
			dz1=actorPos.vz-(hitBox.pZ+hitBox.sZ);
			if (dx1>dz1) quadrant=2;	// right
			else quadrant=3;			// near
		}
		else quadrant=3;				// near
	}
	else if (actorPos.vx>(hitBox.pX+hitBox.sX))
	{
		dx1=actorPos.vx-(hitBox.pX+hitBox.sX);
		if (actorPos.vz<hitBox.pZ)
		{
			dz1=hitBox.pZ-actorPos.vz;
			if (dx1>dz1) quadrant=2;	// right
			else quadrant=1;			// far
		}
		else if ( actorPos.vz>(hitBox.pZ+hitBox.sZ) )
		{
			dz1=actorPos.vz-(hitBox.pZ+hitBox.sZ);
			if (dx1>dz1) quadrant=2;	// right
			else quadrant=1;			// far
		}
	}
	else
	{
		if (actorPos.vx<hitBox.pX) quadrant=4;					// left
		else if (actorPos.vx>(hitBox.pX+hitBox.sX)) quadrant=2;	// right
		else if (actorPos.vz<hitBox.pZ) quadrant=3;				// near
		else quadrant=1;										// far
	}
	return (quadrant);
*/

/*
	int	angle,angle1;
	VECTOR	temp,camPos,actorPos;
	int	mag,temp1,temp2;
	int	rotFlag=FALSE;

	if (!camVars.holdPositionFlag)
	{
		camVars.holdPosition.vx=mycamera.vpx;
		camVars.holdPosition.vy=mycamera.vpy;
		camVars.holdPosition.vz=mycamera.vpz;
	}
	
	mycamera.vry=(CamVars->targetModel->position.vy-HEIGHTOFFSET)-CamVars->targetRadius/8;

	mycamera.vrx=CamVars->targetModel->position.vx;
	mycamera.vrz=CamVars->targetModel->position.vz;

	angle=utilCalcAngle( (mycamera.vpx-mycamera.vrx),(mycamera.vpz-mycamera.vrz) );
	CamVars->camAngle=(angle+2048)&4095;

	temp.vx=mycamera.vpx-mycamera.vrx;
	temp.vy=0;
	temp.vz=mycamera.vpz-mycamera.vrz;
	mag=Magnitude(&temp);

	if (mag==0) mag=1;

	if (!temp.vx && !temp.vz)
		temp.vx=1;

	temp1=CamVars->lookDistance;
	if (temp1)
	{
		temp.vx=(temp.vx*temp1)/mag;
		temp.vy=(temp.vy*temp1)/mag;
		temp.vz=(temp.vz*temp1)/mag;
	}
	temp1 = findShortestAngle(CamVars->camAngle+2048,CamVars->targetModel->psiData.object->rotate.vy);

/////////
	actorPos.vx=CamVars->targetModel->position.vx*512;
	actorPos.vy=(CamVars->targetModel->position.vy-HEIGHTOFFSET)*512;
	actorPos.vz=CamVars->targetModel->position.vz*512;

	camPos.vx=0;//CamVars->camDistance;
	camPos.vy=0;
	camPos.vz=CamVars->camDistance;

	RotateVector2D(&camPos, &camPos, CamVars->targetModel->psiData.object->rotate.vy);

	camPos.vx*=512;
	camPos.vz*=512;

	camPos.vx+=actorPos.vx;
	camPos.vy+=actorPos.vy;
	camPos.vz+=actorPos.vz;

	findClosestBox(actorPos.vx,actorPos.vy,actorPos.vz,camPos.vx,camPos.vy,camPos.vz,&hitBox,FALSE);
//	This should give the box cam will hit when fully in position

	if (!testchar_speed) CamVars->inactiveTime++;
	else CamVars->inactiveTime=0;

	if (CamVars->inactiveTime<30)
		temp1=(temp1*testchar_speed)/5000;
	else
	{
		if (CamVars->inactiveTime<60)
			temp1=(temp1*CamVars->inactiveTime)/120;
		else
			temp1=temp1/2;
	}

	if (CamVars->flags&FIXEDROT) temp1=0;

	if (padData.digital[0] & PAD_R1)
	{
		temp1+=512;
		CamVars->inactiveTime=0;
	}
	if (padData.digital[0] & PAD_L1)
	{
		temp1-=512;
		CamVars->inactiveTime=0;
	}

//	RotateVector2D(&temp, &temp, -temp1/32);

	if (CamVars->flags&FIXEDROT)
	{
		temp2=findShortestAngle(CamVars->camAngle,CamVars->fixedAngle);
		if (temp2>256) temp2=256;
		if (temp2<-256) temp2=-256;

		temp1=temp2/4;
		//DB("temp1 %d temp2 %d\n",temp1,temp2);
		RotateVector2D(&temp, &temp, -temp1);
	}

	camVars.camPos2.vx=(mycamera.vrx+temp.vx)*512;
	camVars.camPos2.vz=(mycamera.vrz+temp.vz)*512;
	camVars.camPos2.vy=(mycamera.vry-CamVars->actualHeight)*512;

	temp1=CamVars->actualDistance;
	mag=Magnitude(&temp);

	if (temp1)
	{
		temp.vx=(temp.vx*temp1)/mag;
		temp.vy=(temp.vy*temp1)/mag;
		temp.vz=(temp.vz*temp1)/mag;
	}

	mycamera.vpx=mycamera.vrx+temp.vx;
	mycamera.vpz=mycamera.vrz+temp.vz;
	mycamera.vpy=mycamera.vry-CamVars->actualHeight;
*/
/*
				if ( ABS(temp.vx)<checkVal)
				{
					if ( actorPos.vx<(hitBox.pX+hitBox.sX/2) )
					{
						temp.vx=(hitBox.pX-actorPos.vx);
						temp.vz=((hitBox.pZ+hitBox.sZ)-actorPos.vz);
					}
					else
					{
						temp.vx=((hitBox.pX+hitBox.sX)-actorPos.vx);
						temp.vz=((hitBox.pZ+hitBox.sZ)-actorPos.vz);
					}
				}
				else if (temp.vx<0)
				{
					temp.vx=(hitBox.pX-actorPos.vx);
					temp.vz=((hitBox.pZ+hitBox.sZ)-actorPos.vz);
				}
				else
				{
					temp.vx=((hitBox.pX+hitBox.sX)-actorPos.vx);
					temp.vz=((hitBox.pZ+hitBox.sZ)-actorPos.vz);
				}
				break;
			case 2:
				DB("quad 2\n");
				//if (deltaZ>0)
				if ( ABS(temp.vz) < checkVal)
				{
					if (actorPos.vz<(hitBox.pZ+hitBox.sZ/2) )
					{
						temp.vx=((hitBox.pX+hitBox.sX)-actorPos.vx);
						temp.vz=(hitBox.pZ-actorPos.vz);
					}
					else
					{
						temp.vx=((hitBox.pX+hitBox.sX)-actorPos.vx);
						temp.vz=((hitBox.pZ+hitBox.sZ)-actorPos.vz);
					}
				}
				else if (temp.vz<0)
				{
					temp.vx=((hitBox.pX+hitBox.sX)-actorPos.vx);
					temp.vz=(hitBox.pZ-actorPos.vz);
				}
				else
				{
					temp.vx=((hitBox.pX+hitBox.sX)-actorPos.vx);
					temp.vz=((hitBox.pZ+hitBox.sZ)-actorPos.vz);
				}
				break;
			case 3:
				DB("quad 3\n");
				//if (deltaX>0)
				if ( ABS(temp.vx)<checkVal)
				{
					if ( actorPos.vx<(hitBox.pX+hitBox.sX/2) )
					{
						temp.vx=(hitBox.pX-actorPos.vx);
						temp.vz=(hitBox.pZ-actorPos.vz);
					}
					else
					{
						temp.vx=((hitBox.pX+hitBox.sX)-actorPos.vx);
						temp.vz=(hitBox.pZ-actorPos.vz);
					}
				}
				else if (temp.vx<0)
				{
					temp.vx=(hitBox.pX-actorPos.vx);
					temp.vz=(hitBox.pZ-actorPos.vz);
				}
				else
				{
					temp.vx=((hitBox.pX+hitBox.sX)-actorPos.vx);
					temp.vz=(hitBox.pZ-actorPos.vz);
				}
				break;
			case 4:
				DB("quad 4\n");
				//if (deltaZ>0)
				if ( ABS(temp.vz) < checkVal)
				{
					if (actorPos.vz<(hitBox.pZ+hitBox.sZ/2) )
					{
						temp.vx=(hitBox.pX-actorPos.vx);
						temp.vz=(hitBox.pZ-actorPos.vz);
					}
					else
					{
						temp.vx=(hitBox.pX-actorPos.vx);
						temp.vz=((hitBox.pZ+hitBox.sZ)-actorPos.vz);
					}
				}
				else if (temp.vz<0)
				{
					temp.vx=(hitBox.pX-actorPos.vx);
					temp.vz=(hitBox.pZ-actorPos.vz);
				}
				else
				{
					temp.vx=(hitBox.pX-actorPos.vx);
					temp.vz=((hitBox.pZ+hitBox.sZ)-actorPos.vz);
				}
				break;
*/
}