/******************************************************************************************
	CRTEST PS   (c) 1999-2001 ISL

	seesaw.c:			Seesaw subgame code
******************************************************************************************/
/*
#include "global.h"
#include "main.h"
#include "menu.h"
#include "map_draw.h"
#include "bff_load.h"
#include "collide.h"
#include "debris.h"
#include "lights.h"
#include "timer.h"
#include "maths.h"
#include "overlays.h"
#include "fx.h"
#include "powerbar.h"

#include "puzzles.h"
#include "map_view.h"
#include "fixed.h"
#include "dualshock.h"
#include "subgame.h"
#include "seesaw.h"
#include "enemies.h"
#include "dogchase.h"
#include "demo.h"
#include "gametext.h"
#include "enemies.h"
//#include "text_ids.h"
*/
#include "global.h"
#include "main.h"
#include "menu.h"
#include "map_draw.h"
#include "bff_load.h"
#include "puzzles.h"
#include "collide.h"
#include "debris.h"
#include "lights.h"
#include "timer.h"
#include "maths.h"
#include "overlays.h"
#include "fx.h"
#include "powerbar.h"
#include "catapult.h"
#include "subgame.h"
#include "demo.h"
#include "map_view.h"
#include "ranges.h"
#include "gametext.h"
#include "charactr.h"
#include "deth.h"
#include "enemies.h"
#include "dualshock.h"
#include <psitypes.h>
#include "map_play.h"
#include "seesaw.h"
#include "card.h"
#include "sound.h"
#include "loadsnd.h"
#include "startup.h"
#include "pause.h"
#include "dcinc.h"


seesawStr seesawStruct;



#ifdef DEBUG	// Make double sure that debugging stuff isn't enabled on a cd build
	//for debugging
	//#define SEESAW_VIEW_POS
	//#define SEESAW_VIEW_DRONE_STATES
	//#define SEESAW_VIEW_MATTRESS_STATES
	//#define SEESAW_VIEW_WINDER
	//#define DEBUG_CONTROLS_ON
#endif


#define  COUNTDOWN_XPOS  -232


#ifdef DREAMCAST

int dcSeesawBodge = -300;

#if PALMODE == 1
int COUNTDOWN_YPOS = -114;
#else
int COUNTDOWN_YPOS = -105;
#endif

#else

//int dcseesawBodge = 0;

#if PALMODE == 1
	#define  COUNTDOWN_YPOS  -114
#else
	#define  COUNTDOWN_YPOS  -105
#endif

#endif

#define  CHICKENS_FREED_XPOS   -236



#define	CHICKEN_SEESAW_DEVICE_XCENTRE   -527
#define CHICKEN_SEESAW_DEVICE_YCENTRE   -85
#define	CHICKEN_SEESAW_DEVICE_ZCENTRE	-8715



// this is for off screen
#define DRONE_XSTART 2960
#define DRONE_YSTART -67
#define DRONE_ZSTART -9398

#define DRONE_XWAIT   2400

#define SEESAW_COUNTDOWN_TIME			  70
#define SEESAW_BRONZE_NUM_CHICKENS	      20
#define SEESAW_SILVER_NUM_CHICKENS	      25
#define SEESAW_GOLD_NUM_CHICKENS          30


#define SEESAW_GROUND_HEIGHT			-50
#define SEESAW_DRONE_GROUND_HEIGHT		-67


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

// values that say where the mattress can go - trapezoid I think
#define MATTRESS_BOTTOM_Z		  -4000 
#define MATTRESS_SIZE_Z		 	  1900  
int MATTRESS_SIZE_BORDER = 300;
#define MATTRESS_MIDDLE_X		  -400  
#define MATTRESS_WIDTH_BOTTOM	  2500  
#define MATTRESS_WIDTH_TOP		  3100  

#define MATTRESS_SORT_WIDTH   4000
#define MATTRESS_SORT_DEPTH   3300

#define MATTRESS_ACCEL			  7	  
#define MATTRESS_ARRIVE_DISTANCE  60	  
#define MATTRESS_INERTIA		  3950  


#define SEESAW_DRONE_RUNOFFZ	    -3734
#define SEESAW_DRONE_RUNOFFLEFTX	-4509
#define SEESAW_DRONE_RUNOFFRIGHTX	 2980
#define SEESAW_DRONE_FREEDOMLEFTX	-7509
#define SEESAW_DRONE_FREEDOMRIGHTX	 5980
#define SEESAW_DRONE_RUN_OFF_SPEED  110
#define SEESAW_GRAVITY				 64
#define SEESAW_BOUNCE_GRAVITY    54
#define SEESAW_DRONE_DIST_TO_JUMP    200
#define SEESAW_DRONE_MAX_SPEED		 120
#define SEESAW_DRONE_JUMPINGON_SPEED -200
#define SEESAW_HEIGHT_OF_MATTRESS	 -450
#define SEESAW_MATTRESS_BOUNCE_SPEED  -450

#define SEESAW_CAMERA_XPOS 	-498
#define SEESAW_CAMERA_YPOS 	-6276
#define SEESAW_CAMERA_ZPOS 	-20100
#define SEESAW_GARIB_XPOS 	-386
#define SEESAW_GARIB_YPOS 	-1407
#define SEESAW_GARIB_ZPOS 	-6137


#define SEESAW_BOUNCE_ROT_SPEED  700


#define T_BUZZER         1
#define T_BUZZER_TIME    2
#define T_MOTOR          1
#define T_MOTOR_START    400
#define T_MOTOR_ENDSPEED 0
#define T_MOTOR_ENDTIME  10



#define SEESAW_MIN_LAUNCH_SPEED          1400
#define SEESAW_LAUNCH_SPEED_INVFACTOR	 22



#define	SEESAW_BOUNCE_BACK  0
#define	SEESAW_BOUNCE_FRONT 1
#define	SEESAW_BOUNCE_HEAD  2


#define SEESAW_BOUNCE_BACK_SPEED  200
#define SEESAW_BOUNCE_FRONT_SPEED  90
#define SEESAW_BOUNCE_HEAD_SPEED   250



int SEESAW_MATTRESS_RUNOFFRIGHTX = 9000;

int SEESAW_MATTRESS_RUNOFFLEFTX = -9000;


#ifdef DREAMCAST
int seesawWorldDepth = 500;
int seesawBoxDepth = 1000;
int seesawFowlerBump = -1600;
#else
#define seesawBoxDepth 2
#endif

///LAUNCH_GAME_DATA seesaw;

seesawStr *seesaw=NULL;
//mattressStr mattress;

extern int pause_levelplaying;



// ===================================================================================================
// ===================================================================== Controller related stuff ====



char *seesawSounds[NUM_SEESAW_SAMPLES] =
{
	"hitfence2",   		//SFX_SEESAW_LAUNCH	 
	"boiing1",  		//SFX_SEESAW_BOUNCE			 
	"chickenthud1",		//SFX_SEESAW_CRASH			 
	"dropweights1",		//SFX_SEESAW_LAND			 
	"ing_argh_06",		//SFX_SEESAW_HIT1
	"ing_ooph_01",		//SFX_SEESAW_HIT2	
	"ing_ooph_03",		//SFX_SEESAW_HIT3	
	"ing_ouch_03",		//SFX_SEESAW_HIT4	
	"ing_ouch_07",		//SFX_SEESAW_HIT5
	"ing_wee_02a",		//SFX_SEESAW_WEE1	
	"ing_wee_06c",		//SFX_SEESAW_WEE2	
	"ing_wee_06i",		//SFX_SEESAW_WEE3	
	"ing_wee_10a",		//SFX_SEESAW_WEE4	
	"ing_wee_12c",		//SFX_SEESAW_WEE5	
	"ing_wee_16a",		//SFX_SEESAW_WEE6	
	"ing_wee_17a",		//SFX_SEESAW_WEE7
};


void seesawLoadsnd(int levelNum, SfxSampleType **pSamples, int arraySize)
{
	int i;

	ASSERT(pSamples);

	for(i=0; i<arraySize; i++)
		pSamples[i] = NULL;


	ASSERT(arraySize >= NUM_SEESAW_SAMPLES);


	for(i=0; i<NUM_SEESAW_SAMPLES; i++)
	{
		pSamples[i]	= sfxFindSampleInAllBanks(seesawSounds[i]);

#ifdef DEBUG
		if(pSamples[i] == NULL)
			DB("seesaw pSamples[%d] not found\n",i);
#endif
		ASSERT(pSamples[i]);
	}

	fowlerSubGameSample[SFX_FOWLER_BRONZE] = sfxFindSampleInAllBanks("sub_seesaw_bronze");
	ASSERT(fowlerSubGameSample[SFX_FOWLER_BRONZE]);

	fowlerSubGameSample[SFX_FOWLER_SILVER] = sfxFindSampleInAllBanks("sub_seesaw_silver");
	ASSERT(fowlerSubGameSample[SFX_FOWLER_SILVER]);

	fowlerSubGameSample[SFX_FOWLER_GOLD] = sfxFindSampleInAllBanks("sub_seesaw_gold");
	ASSERT(fowlerSubGameSample[SFX_FOWLER_GOLD]);

	fowlerSubGameSample[SFX_FOWLER_FAIL] = sfxFindSampleInAllBanks("sub_seesaw_fail");
	ASSERT(fowlerSubGameSample[SFX_FOWLER_FAIL]);

}








// ===================================================================================================
#define SS_CAM_ROT_FACTOR  512

void seesaw_UpdateCamAim(void)
{
	VECTOR pos = {(SEESAW_CAMERA_XPOS-CHICKEN_SEESAW_DEVICE_XCENTRE), SEESAW_CAMERA_YPOS, (SEESAW_CAMERA_ZPOS - CHICKEN_SEESAW_DEVICE_ZCENTRE)};
	VECTOR gar = {(SEESAW_GARIB_XPOS - CHICKEN_SEESAW_DEVICE_XCENTRE), SEESAW_GARIB_YPOS, ( SEESAW_GARIB_ZPOS - CHICKEN_SEESAW_DEVICE_ZCENTRE)};

	seesaw->camRot = (seesaw->device.yRot * SS_CAM_ROT_FACTOR)/4096;

	RotateVector2D(&pos, &pos, seesaw->camRot);
	mycamera.vpx = pos.vx + seesaw->device.actor->position.vx;
	mycamera.vpy = pos.vy;
	mycamera.vpz = pos.vz + seesaw->device.actor->position.vz;

	RotateVector2D(&pos, &pos, seesaw->camRot);
	mycamera.vrx = gar.vx + seesaw->device.actor->position.vx;
	mycamera.vry = gar.vy;
	mycamera.vrz = gar.vz + seesaw->device.actor->position.vz;

}




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



void seesawCycle(void)
{
	
	int i;

	seesaw->frameCount++;

	dsEvent_Update();
	EXLIGHT_Update();
	updateStopWatch();

	switch(seesaw->state)
	{
		case SEESAW_STATE_FADEIN:
			break;


		case SEESAW_STATE_INTRO:

			if(pReadPad->debounce[0] & PAD_CROSS)
			{
				seesaw->state = SEESAW_STATE_RUNNING;
				subGameRestart = FALSE;
			}
#ifdef DREAMCAST
			else if(pReadPad->debounce[0] & PAD_CIRCLE)
#else
			else if(pReadPad->debounce[0] & PAD_TRIANGLE)
#endif
			{
				seesaw->frameCount = 1;
				seesaw->state = SEESAW_STATE_FADEOUT;
				subGameRestart = FALSE;
				return;
			}
			break;

		case SEESAW_STATE_RUNNING:
			seesawControls();
			seesaw_UpdateCamAim();
		
			if(pReadPad->debounce[0] & PAD_START)
			{
				pause_levelplaying = LEVNUMBER_A2_SEESAW;
				pauseStart();
				return;
			}


			if(countDownUpdate(&seesaw->timer))
			{
				seesaw->state = SEESAW_STATE_FINISH;
				seesaw->frameCount = 1;
				seesaw->mattress.state = MATTRESS_LEAVING;
				//countDownStart(&seesaw->timer, SEESAW_COUNTDOWN_TIME);
			}

			mattressUpdate();
			deviceUpdate();
			seesawDronesUpdate();

			debrisCycle();
			break;


		case SEESAW_STATE_FINISH:


			mattressUpdate();
			deviceUpdate();
			seesawDronesUpdate();
			
			debrisCycle();

			i=0;
			while(i < SEESAW_NUM_DRONES)
			{
				if(seesaw->drones[i].state == SEESAW_DRONE_ONDEVICE)
				{
					VECTOR *v;

					seesaw->drones[i].state = SEESAW_DRONE_RUNNINGOFF;
					actorAnimate(seesaw->drones[i].actor, DRONE_RUN_OFF_SCREAMING, TRUE, TRUE, 512, FALSE, 0);

					seesaw->drones[i].rotAim = 1024;


					seesaw->drones[i].target.vx = SEESAW_DRONE_FREEDOMLEFTX;
					seesaw->drones[i].target.vy = SEESAW_DRONE_GROUND_HEIGHT;
					seesaw->drones[i].target.vz = DRONE_ZSTART;

					v = &seesaw->drones[i].vel;
					SUBVECTOR(v, &seesaw->drones[i].target, &seesaw->drones[i].actor->position);  

					MakeUnit(v);
					SCALEVECTOR(v, SEESAW_DRONE_RUN_OFF_SPEED);

				}

				if((seesaw->drones[i].state != SEESAW_DRONE_INACTIVE))
					break;
				i++;

				if((i == SEESAW_NUM_DRONES)&&(seesaw->mattress.state == MATTRESS_STOPPED))
				{
					if(seesaw->numChickensSaved >= SEESAW_BRONZE_NUM_CHICKENS)
					{
						if(gameCalledFrom != GAMECALLEDFROM_DEBUG)
						{
							gamePlayData->SubGameStates[SUBGAME_SEESAW] = REPLAY_BEATEN;
							gameSaveData.levels_available[REPLAY_AVAILABLE_SEESAW] = REPLAY_BEATEN;
						}

						if(seesaw->numChickensSaved >= SEESAW_GOLD_NUM_CHICKENS)
						{
							seesaw->state = SEESAW_STATE_GOLD_SUCCESS;
//							fowlerSetMedalSfx(SFX_FOWLER_GOLD);
							startFowler(GOLD);

							gameSaveData.medals_won[MEDAL_WON_SEESAW] = 3; 
	#ifndef _WINDOWS
							sound_XA_Start(TUNE_3_COMPLETE + SOUND_XA_NOLOOP);
	#endif

						}
						else if(seesaw->numChickensSaved >= SEESAW_SILVER_NUM_CHICKENS)
						{
							seesaw->state = SEESAW_STATE_SILVER_SUCCESS;
//							fowlerSetMedalSfx(SFX_FOWLER_SILVER);
							startFowler(SILVER);

							if(gameSaveData.medals_won[MEDAL_WON_SEESAW] < 2)
								gameSaveData.medals_won[MEDAL_WON_SEESAW] = 2;
	#ifndef _WINDOWS						
							sound_XA_Start(TUNE_3_COMPLETE + SOUND_XA_NOLOOP);
 	#endif
						}
						else if(seesaw->numChickensSaved >= SEESAW_BRONZE_NUM_CHICKENS)
						{
							seesaw->state = SEESAW_STATE_BRONZE_SUCCESS;
//							fowlerSetMedalSfx(SFX_FOWLER_BRONZE);
							startFowler(BRONZE);

							if(gameSaveData.medals_won[MEDAL_WON_SEESAW] < 1)
								gameSaveData.medals_won[MEDAL_WON_SEESAW] = 1; 
	#ifndef _WINDOWS
							sound_XA_Start(TUNE_3_COMPLETE + SOUND_XA_NOLOOP);
	#endif
						}
					}
					else 
					{
						seesaw->state = SEESAW_STATE_FAIL;
//						fowlerSetMedalSfx(SFX_FOWLER_FAIL);
						startFowler(FAIL);

#ifndef _WINDOWS
						sound_XA_Start(TUNE_4_FAILED + SOUND_XA_NOLOOP);
#endif
					}
				}
			}

			break;


		case SEESAW_STATE_BRONZE_SUCCESS:
		case SEESAW_STATE_SILVER_SUCCESS:
		case SEESAW_STATE_GOLD_SUCCESS:

		case SEESAW_STATE_FAIL:

			makeFowlerSpeak();

			if(pReadPad->debounce[0] & PAD_CROSS)
			{
				seesaw->frameCount = 1;
				seesaw->state = SEESAW_STATE_FADEOUT;
				subGameRestart = TRUE;
			}
#ifdef DREAMCAST
			else if(pReadPad->debounce[0] & PAD_CIRCLE)
#else
	 		else if(pReadPad->debounce[0] & PAD_TRIANGLE)
#endif
			{
				seesaw->frameCount = 1;
				seesaw->state = SEESAW_STATE_FADEOUT;
				subGameRestart = FALSE;
			}
			break;



		case SEESAW_STATE_FADEOUT:
			if(subGameRestart == TRUE)
			{
				i= (seesaw->frameCount)*20;

				if(i >=255)
				{
					seesawEnd();
					return;
				}
			}
			else
			{
				seesawEnd();
				return;
			}
			break;
	}

	if(seesaw->playLaunchSample)
	{
		soundPlaySample(seesaw->pSamples[SFX_SEESAW_LAUNCH], 0xffff, RAND_FREQ(120));
		seesaw->playLaunchSample = 0;
	}



	seesawUpdateAnims();

}


void seesawUpdateAnims()
{
	actorMaintainAnimation(seesaw->device.actor);
	actorMaintainAnimation(seesaw->device.winderActor);
	actorMaintainAnimation(seesaw->mattress.actor);
	actorMaintainAnimation(seesaw->drones[0].actor);
	actorMaintainAnimation(seesaw->drones[1].actor);
	actorMaintainAnimation(seesaw->drones[2].actor);
	actorMaintainAnimation(seesaw->drones[3].actor);
}





// ====================================================================================================
void launchDrone()
{
	
	if((seesaw->device.droneOnDevice >= 0) && (seesaw->drones[seesaw->device.droneOnDevice].state == SEESAW_DRONE_ONDEVICE))
	{
		seesaw->drones[seesaw->device.droneOnDevice].state = SEESAW_DRONE_LAUNCHING;


//	  actorAnimate(seesaw->device.actor, DEVICE_DOWN_CONST, FALSE, FALSE, 2000, 0 , 0); 

		seesaw->device.actor->animation.animData[0].speed = 2400;

		actorAnimate(seesaw->device.actor, DEVICE_UP_CONST, FALSE, FALSE, 256, 0 , 0); 
		actorAnimate(seesaw->device.actor, DEVICE_DOWN_CONST, FALSE, TRUE, 0, 0 , 0); 

		seesaw->device.animPos = 0;

		seesaw->device.droneOnDevice = -1;

		if(seesaw->timer.active == FALSE)
		{
			seesaw->numChickensSaved = 0;//?
			countDownActivate(&seesaw->timer);
		}

		///soundPlaySample(seesaw->pSamples[SFX_SEESAW_LAUNCH], 0xffff, RAND_FREQ(120));
		seesaw->playLaunchSample = 1;


	}
}





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

void seesawDronesUpdate()
{
	int i;
	int dist;

	VECTOR *v=NULL;
	VECTOR tempVect;

	for(i=0; i< SEESAW_NUM_DRONES; i++)
	{
		if(seesaw->drones[i].actor->psiData.object->rotate.vy != seesaw->drones[i].rotAim)
		{

			dist = seesaw->drones[i].rotAim - seesaw->drones[i].actor->psiData.object->rotate.vy;
			seesaw->drones[i].actor->psiData.object->rotate.vy += (dist)/4;
			if((dist < 6) && (dist > -6))
			{
				seesaw->drones[i].actor->psiData.object->rotate.vy = seesaw->drones[i].rotAim;
			}

		}
		
		switch(seesaw->drones[i].state)
		{
			case SEESAW_DRONE_INACTIVE:     
				break;
			
			case SEESAW_DRONE_RUNNINGON:    
				SUBVECTOR(&tempVect, &seesaw->device.chickenPos, &seesaw->drones[i].actor->position);

				if((tempVect.vx < SEESAW_DRONE_DIST_TO_JUMP) && (tempVect.vx > -SEESAW_DRONE_DIST_TO_JUMP))
				{
					seesaw->drones[i].state = SEESAW_DRONE_JUMPINGON;
					actorAnimate(seesaw->drones[i].actor, DRONE_JUMP, FALSE, FALSE, 256, FALSE, 0);       
					actorAnimate(seesaw->drones[i].actor, DRONE_DOWN_FLAPPING, FALSE, TRUE, 256, FALSE, 0);       
					actorAnimate(seesaw->drones[i].actor, DRONE_LAND_ON_SEESAW, FALSE, TRUE, 256, FALSE, 0);       
					actorAnimate(seesaw->drones[i].actor, DRONE_SEESAW_GULP, FALSE, TRUE, 256, FALSE, 0);       
					actorAnimate(seesaw->drones[i].actor, DRONE_SEESAW_COVER_EYES, FALSE, TRUE, 256, FALSE, 0);       

					seesaw->drones[i].vel.vy = SEESAW_DRONE_JUMPINGON_SPEED;
					seesaw->drones[i].vel.vx = 0;
					seesaw->drones[i].vel.vz = 0;
					seesaw->drones[i].rotAim = 2048;
					break;
				}

				SCALEVECTOR(&tempVect, 2048);
				dist = Magnitude(&tempVect);
				if(dist > SEESAW_DRONE_MAX_SPEED)
				{
					SCALEVECTOR(&tempVect, 4096*SEESAW_DRONE_MAX_SPEED/dist);
				}
				ADDTOVECTOR(&seesaw->drones[i].actor->position, &tempVect);
				seesaw->drones[i].actor->position.vy = SEESAW_DRONE_GROUND_HEIGHT;

				break;

			case SEESAW_DRONE_JUMPINGON:    
				SUBVECTOR(&tempVect, &seesaw->device.chickenPos, &seesaw->drones[i].actor->position);
				SCALEVECTOR(&tempVect, 2048);
				dist = Magnitude(&tempVect);
				if(dist > SEESAW_DRONE_MAX_SPEED)
				{
					SCALEVECTOR(&tempVect, 4096*SEESAW_DRONE_MAX_SPEED/dist);
				}
				ADDTOVECTOR(&seesaw->drones[i].actor->position, &tempVect);
				if(dist < 32)
				{
					seesaw->drones[i].state = SEESAW_DRONE_ONDEVICE;

					if(seesaw->timer.active == FALSE)
					{
						seesaw->numChickensSaved = 0;//?
						countDownActivate(&seesaw->timer);
					}
				}

				seesaw->drones[i].actor->position.vy += seesaw->drones[i].vel.vy;
				seesaw->drones[i].vel.vy = seesaw->drones[i].vel.vy * 4096 / 5000;  
				break;

			case SEESAW_DRONE_ONDEVICE:
				seesaw->drones[i].actor->position = seesaw->device.chickenPos;
//				seesaw->drones[i].actor->psiData.object->rotate.vy = 2048 + seesaw->device.yRot;
				seesaw->drones[i].rotAim = 2048 + seesaw->device.yRot;
				break;



			case SEESAW_DRONE_LAUNCHING:

				
				//dsEvent_Add(T_BUZZER, T_BUZZER_TIME, T_MOTOR, T_MOTOR_START, T_MOTOR_ENDSPEED, T_MOTOR_ENDTIME, NULL);


				dsEvent_Add(1, 1, 1, 180, 0, 6, FALSE);
				
				//actorAnimate(seesaw->drones[i].actor, DRONE_SEESAW_FIRE, FALSE, FALSE, 600, FALSE, 0);
				actorAnimate(seesaw->drones[i].actor, DRONE_MID_AIR_CYCLE, TRUE, FALSE, 750, FALSE, 0);


				actorAnimate(seesaw->device.winderActor, CRANKER_CRANK, FALSE, FALSE, 800, TRUE, 0);
				actorAnimate(seesaw->device.winderActor, CRANKER_CRANK, FALSE, TRUE, 800, FALSE, 0);
				actorAnimate(seesaw->device.winderActor, CRANKER_IDLE, FALSE, TRUE, 300, FALSE, 0);
				actorAnimate(seesaw->device.winderActor, CRANKER_BREATHE, TRUE, TRUE, 240, FALSE, 0);

				
				// find velocity
				v = &seesaw->drones[i].vel;
				v->vx = 0;
				v->vy = -1536;
				v->vz = 1024;


				RotateVector2D(v, v, seesaw->device.yRot);

				//SCALEVECTOR(v, (SEESAW_MIN_LAUNCH_SPEED - (pReadPad->analogYS[0]/SEESAW_LAUNCH_SPEED_INVFACTOR)));
				SCALEVECTOR(v, (SEESAW_MIN_LAUNCH_SPEED + seesaw->device.power));

				
				seesaw->drones[i].state = SEESAW_DRONE_FLYING;
				seesaw->drones[i].sound = 0;

				//Estimate where the chicken will land
				//dist = -2*(v->vy + SEESAW_HEIGHT_OF_MATTRESS) / SEESAW_GRAVITY; // frames till hit

				dist =  -2*(v->vy) / SEESAW_GRAVITY; // frames till hit
				seesaw->drones[i].target.vx = seesaw->drones[i].actor->position.vx + v->vx * dist;
				seesaw->drones[i].target.vy	= seesaw->drones[i].actor->position.vy + 0;
				seesaw->drones[i].target.vz = seesaw->drones[i].actor->position.vz + v->vz * dist;// +200 is adjustment

				mattressCatchChicken(i, dist);

//				seesaw->device.winderActor->position = seesaw->drones[i].target;
				
				ADDTOVECTOR(&seesaw->drones[i].actor->position, v);
				break;

			case SEESAW_DRONE_FLYING:

				if(seesaw->drones[i].sound != 1)
				{
					int sample;
					seesaw->drones[i].sound = 1;
					//careful here there are currently 7 wee sounds. If this changes (I'm not expecting it to) then this has to change also.
					sample = utilRandomInt(6) + SFX_SEESAW_WEE1;
					seesaw->drones[i].weeSample = seesaw->pSamples[sample];
					soundPlaySample(seesaw->pSamples[sample], 0x8080, 0);
				}
				


				seesaw->drones[i].vel.vy += SEESAW_GRAVITY;
				ADDTOVECTOR(&seesaw->drones[i].actor->position, &seesaw->drones[i].vel);
				
				if(seesaw->mattress.incomingChicken == i)
				{
					if(seesaw->drones[i].actor->position.vy > SEESAW_HEIGHT_OF_MATTRESS)
					{
	 					seesaw->drones[i].actor->position.vy = SEESAW_HEIGHT_OF_MATTRESS;

						dsEvent_Add(0, 0, 1, 140, 0, 6, FALSE);

						soundPlaySample(seesaw->pSamples[SFX_SEESAW_BOUNCE], 0xffff, RAND_FREQ(120));



						tempVect = seesaw->drones[i].actor->position;
						tempVect.vz -=150;
						//tempVect.vy -= 50;
						tempVect.vx -= (tempVect.vx - MATTRESS_MIDDLE_X) / 10;
						debrisDust(&tempVect, 10 , 1024);


						actorAnimate(seesaw->mattress.actor, MATTRESS_BOUNCE, FALSE, FALSE, 450, FALSE, 0);
						actorAnimate(seesaw->mattress.actor, MATTRESS_RUN_AROUND, TRUE, TRUE, 300, FALSE, 0);

						actorAnimate(seesaw->drones[i].actor, DRONE_RUN_OFF_SCREAMING, FALSE, FALSE, 512, FALSE, 0);
						actorAnimate(seesaw->drones[i].actor, DRONE_TOP_OF_JUMP, FALSE, TRUE, 512, FALSE, 0);
						actorAnimate(seesaw->drones[i].actor, DRONE_DOWN_FLAPPING, TRUE, TRUE, 512, FALSE, 0);

						seesaw->drones[i].vel.vy = SEESAW_MATTRESS_BOUNCE_SPEED;
						seesaw->drones[i].vel.vz = seesaw->drones[i].vel.vz * 8 / 10;
						seesaw->drones[i].vel.vx = seesaw->drones[i].vel.vx * 8 / 10;

						seesaw->drones[i].state = SEESAW_DRONE_BOUNCING;


						seesaw->drones[i].xRotState = random(3);
						
						switch(seesaw->drones[i].xRotState)
						{
							case SEESAW_BOUNCE_BACK:
								seesaw->drones[i].xRotSpeed = SEESAW_BOUNCE_BACK_SPEED;
								break;
							case SEESAW_BOUNCE_FRONT:
								seesaw->drones[i].xRotSpeed = SEESAW_BOUNCE_FRONT_SPEED;
								break;
							case SEESAW_BOUNCE_HEAD:
								seesaw->drones[i].xRotSpeed = SEESAW_BOUNCE_HEAD_SPEED;
								break;
						}
					}
				}
				else if(seesaw->drones[i].actor->position.vy > SEESAW_DRONE_GROUND_HEIGHT)
				{
					seesaw->drones[i].actor->position.vy = SEESAW_DRONE_GROUND_HEIGHT;

					dsEvent_Add(0, 0, 1, 180, 0, 8, FALSE);
					soundPlaySample(seesaw->pSamples[SFX_SEESAW_CRASH], 0xffff, RAND_FREQ(120));



					tempVect = seesaw->drones[i].actor->position;
					tempVect.vz -=300;
					debrisDust(&tempVect, 8 , 1024);
					tempVect.vx -= (tempVect.vx - MATTRESS_MIDDLE_X) / 14;
					debrisDust(&tempVect, 10 , 1024);
					tempVect.vy -= 100;
					debrisDust(&tempVect, 6 , 1024);

					actorAnimate(seesaw->mattress.actor, MATTRESS_MISS, FALSE, FALSE, 450, FALSE, 0);
					actorAnimate(seesaw->mattress.actor, MATTRESS_RUN_AROUND, TRUE, TRUE, 300, FALSE, 0);
					
					dist = random(30)/10;


					if(dist == 0)
					{
						actorAnimate(seesaw->drones[i].actor, DRONE_FALL_ON_BACK, FALSE, FALSE, 600, FALSE, 0);
						actorAnimate(seesaw->drones[i].actor, DRONE_GET_UP, FALSE, TRUE, 600, FALSE, 0);
					}
					else if(dist == 1)
					{
						actorAnimate(seesaw->drones[i].actor, DRONE_LAND_ON_FRONT, FALSE, FALSE, 600, FALSE, 0);
						actorAnimate(seesaw->drones[i].actor, DRONE_GET_UP_OFF_FRONT, FALSE, TRUE, 600, FALSE, 0);
					}
					else
					{
						actorAnimate(seesaw->drones[i].actor, DRONE_LAND_ON_HEAD, FALSE, FALSE, 600, FALSE, 0);
						actorAnimate(seesaw->drones[i].actor, DRONE_GET_UP_OFF_FRONT, FALSE, TRUE, 600, FALSE, 0);
					}

					actorAnimate(seesaw->drones[i].actor, DRONE_RUN_OFF_SCREAMING, TRUE, TRUE, 512, FALSE, 0);


					seesaw->drones[i].state = SEESAW_DRONE_CRASHING;//RUNNINGOFF;

				}
				break;

			case SEESAW_DRONE_CRASHING:     


				if(seesaw->drones[i].sound != 2)
				{
					int sample;

					if(seesaw->drones[i].weeSample)
					{
						sfxStopSample(seesaw->drones[i].weeSample, -1);
						seesaw->drones[i].weeSample = 0;
					}


					seesaw->drones[i].sound = 2;
					//careful here there are currently 5 crash sounds. If this changes (I'm not expecting it to) then this has to change also.
					sample = utilRandomInt(4) + SFX_SEESAW_HIT1;
					soundPlaySample(seesaw->pSamples[sample], 0x8080, 0);
				}


				//if((seesaw->drones[i].actor->animation.endOfCurrentAnim) && (seesaw->drones[i].actor->animation.animData[0].segment==DRONE_GET_UP))
				if(seesaw->drones[i].actor->animation.animData[0].segment==DRONE_RUN_OFF_SCREAMING)
				{
					seesaw->drones[i].state = SEESAW_DRONE_RUNNINGOFF;
					//actorAnimate(seesaw->drones[i].actor, DRONE_RUN_OFF_SCREAMING, TRUE, FALSE, 512, FALSE, 0);

					seesaw->drones[i].target.vz = SEESAW_DRONE_RUNOFFZ;
					seesaw->drones[i].target.vy = SEESAW_DRONE_GROUND_HEIGHT;

					if(seesaw->drones[i].actor->position.vx > seesaw->mattress.actor->position.vx)
					{
						seesaw->drones[i].rotAim = 3072;
						seesaw->drones[i].target.vx = SEESAW_DRONE_RUNOFFRIGHTX;
					}
					else
					{
						seesaw->drones[i].rotAim = 1024;
						seesaw->drones[i].target.vx = SEESAW_DRONE_RUNOFFLEFTX;
					}


					v = &seesaw->drones[i].vel;

					SUBVECTOR(v, &seesaw->drones[i].target, &seesaw->drones[i].actor->position);  

					MakeUnit(v);
					SCALEVECTOR(v, SEESAW_DRONE_RUN_OFF_SPEED);
					v->vy = 0;



				}
				break;
			case SEESAW_DRONE_BOUNCING:

				seesaw->drones[i].vel.vy += SEESAW_BOUNCE_GRAVITY;
				ADDTOVECTOR(&seesaw->drones[i].actor->position, &seesaw->drones[i].vel);

				seesaw->drones[i].actor->psiData.object->rotate.vx += seesaw->drones[i].xRotSpeed;

				if(seesaw->drones[i].actor->position.vy > SEESAW_DRONE_GROUND_HEIGHT)
				{
					seesaw->drones[i].actor->psiData.object->rotate.vx = 0;

					seesaw->drones[i].actor->position.vy = SEESAW_DRONE_GROUND_HEIGHT;

					dsEvent_Add(0, 0, 1, 140, 0, 6, FALSE);
					soundPlaySample(seesaw->pSamples[SFX_SEESAW_LAND], 0xffff, RAND_FREQ(120));

					tempVect = seesaw->drones[i].actor->position;
					tempVect.vz -=400;
					debrisDust(&tempVect, 8 , 1024);
					tempVect.vx -= (tempVect.vx - MATTRESS_MIDDLE_X) / 14;
					debrisDust(&tempVect, 10 , 1024);
					tempVect.vy -= 100;
					debrisDust(&tempVect, 6 , 1024);


					switch(seesaw->drones[i].xRotState)
					{
						case SEESAW_BOUNCE_BACK:
							actorAnimate(seesaw->drones[i].actor, DRONE_ON_BACK, FALSE, FALSE, 600, FALSE, 0);
							actorAnimate(seesaw->drones[i].actor, DRONE_GET_UP, FALSE, TRUE, 600, FALSE, 0);
							break;
						case SEESAW_BOUNCE_FRONT:
							actorAnimate(seesaw->drones[i].actor, DRONE_ON_FRONT, FALSE, FALSE, 600, FALSE, 0);
							actorAnimate(seesaw->drones[i].actor, DRONE_GET_UP_OFF_FRONT, FALSE, TRUE, 600, FALSE, 0);
							break;
						case SEESAW_BOUNCE_HEAD:
							actorAnimate(seesaw->drones[i].actor, DRONE_LAND_ON_HEAD, FALSE, FALSE, 600, FALSE, 0);
							actorAnimate(seesaw->drones[i].actor, DRONE_GET_UP_OFF_FRONT, FALSE, TRUE, 600, FALSE, 0);
							break;
					}

					
					
					actorAnimate(seesaw->drones[i].actor, DRONE_RUN_OFF_SCREAMING, TRUE, TRUE, 512, FALSE, 0);
					//actorAnimate(seesaw->drones[i].actor, DRONE_RUN_OFF_SCREAMING, TRUE, FALSE, 256, FALSE, 128);
					
					seesaw->numChickensSaved++;

					seesaw->drones[i].state = SEESAW_DRONE_LANDING;//RUNNINGOFF;

				}
				break;

			case SEESAW_DRONE_LANDING: 
				
				if(seesaw->drones[i].actor->animation.animData[0].segment==DRONE_RUN_OFF_SCREAMING)
				{
					
					seesaw->drones[i].state = SEESAW_DRONE_RUNNINGOFF;
					//actorAnimate(seesaw->drones[i].actor, DRONE_RUN_OFF_SCREAMING, TRUE, FALSE, 512, FALSE, 0);

					seesaw->drones[i].target.vz = seesaw->drones[i].actor->position.vz;
					seesaw->drones[i].target.vy = SEESAW_DRONE_GROUND_HEIGHT;


					//DB("Run off screaming\n");

					if(seesaw->drones[i].actor->position.vx > seesaw->mattress.actor->position.vx)
					{
						seesaw->drones[i].rotAim = 3072;
						seesaw->drones[i].target.vx = SEESAW_DRONE_FREEDOMRIGHTX ;
					}
					else
					{
						seesaw->drones[i].rotAim = 1024;
						seesaw->drones[i].target.vx = SEESAW_DRONE_FREEDOMLEFTX;
					}


					v = &seesaw->drones[i].vel;

					SUBVECTOR(v, &seesaw->drones[i].target, &seesaw->drones[i].actor->position);  

					MakeUnit(v);
					SCALEVECTOR(v, SEESAW_DRONE_RUN_OFF_SPEED);
					v->vy = 0;

				}




				break;
			case SEESAW_DRONE_RUNNINGOFF: 
				ADDTOVECTOR(&seesaw->drones[i].actor->position, &seesaw->drones[i].vel);
//				dist = seesaw->drones[i].actor->position.vx - seesaw->drones[i].target.vx;
//				dist = dist*dist;
				if ( ((seesaw->drones[i].vel.vx > 0)&&(seesaw->drones[i].actor->position.vx > seesaw->drones[i].target.vx)) || ((seesaw->drones[i].vel.vx < 0) && (seesaw->drones[i].actor->position.vx < seesaw->drones[i].target.vx)) )
				{
					// make Inactive
					seesaw->drones[i].state = SEESAW_DRONE_INACTIVE;
					seesaw->drones[i].actor->position.vx = DRONE_XSTART;
					seesaw->drones[i].actor->position.vy = DRONE_YSTART;
					seesaw->drones[i].actor->position.vz = DRONE_ZSTART;
					seesaw->drones[i].rotAim = 1024;
					actorAnimate(seesaw->drones[i].actor, DRONE_WAVE_CYCLE, FALSE, FALSE, 256, FALSE, 0);
				}
				break;

			case SEESAW_DRONE_RUNNINGFREEDOM:
				break;
			case SEESAW_DRONE_LOOKAT:
				break;
		}
	}
}    




// ====================================================================================================
// if gonna catch set seesaw->mattress.incomingChicken = chicken
// if NOT set seesaw->mattress.incomingChicken = -1	and set next target pos away from chicken
// ====================================================================================================
//todo
int SEESAW_MATTRESS_CATCHING_DISTANCE = 700;

void mattressCatchChicken(int chicken, int framesToHit)
{
	long dist;
	VECTOR tempVect;
	VECTOR matPos;
	//VECTOR vel

	SUBVECTOR(&matPos, &seesaw->mattress.pos, &seesaw->mattress.oldPos);

	//matPos = seesaw->mattress.vel;
#if defined _WINDOWS || defined DREAMCAST
	SCALEVECTOR(&matPos, ((4096*framesToHit)));
#else
	// RFW, reintroduced (even if the above was a bugfix),
	// so the euro/uk/us versions of Crun PSX are consistant
	SCALEVECTOR(&matPos, ((4096*framesToHit)/2));
#endif

	ADDTOVECTOR(&matPos, &seesaw->mattress.pos);

	SUBVECTOR(&tempVect, &seesaw->drones[chicken].target, &matPos);
	
	dist = Magnitude(&tempVect);

	if(dist < SEESAW_MATTRESS_CATCHING_DISTANCE)
	{
		seesaw->mattress.incomingChicken = chicken;
		seesaw->mattress.state = MATTRESS_CATCHING;
	}
	else
	{
		seesaw->mattress.incomingChicken = -1 - chicken;
		seesaw->mattress.state = MATTRESS_MISSING;
	}
}

//todo
int MATTRESS_MIN_REQUIRED_AVOID_DIST = 2000;

int MATTRESS_COLL_DISTANCE  = 2300;
int MATTRESS_SIDE_PUSH = 0;

int MATTRESS_COLL_FACTOR = 12;

// ====================================================================================================
void mattressUpdate()
{				
	//odo 
	//char str[32]="empty";
	
	int i, targetChick;
	int avoidingChicken = 0;
	long tempInt, distanceToMove;
	VECTOR tempVect;

	switch(seesaw->mattress.state)
	{

		case MATTRESS_MOVING:
		//	sprintf(str,"MOVING");
			//if(mattress.count-- == 0)
			//	mattress.state = MATTRESS_ARRIVED;
			//SUBVECTOR
			

			for(i=0; i< SEESAW_NUM_DRONES; i++)
			{
				//check  for drones just landed or running
				// if too close accelerate away from them
				if((seesaw->drones[i].state == SEESAW_DRONE_RUNNINGOFF)||(seesaw->drones[i].state == SEESAW_DRONE_CRASHING)||(seesaw->drones[i].state == SEESAW_DRONE_FLYING))
				{
					//char str[52];

///					fontPrint(font, -200, -20, "colliding", 128, 128, 128);

					SUBVECTOR(&tempVect, &seesaw->mattress.pos, &seesaw->drones[i].actor->position);
					tempInt = Magnitude2D(tempVect.vx, tempVect.vz);

					//odo
					{
///						char str[24];
///						sprintf(str,"dist=%d",tempInt);
///						fontPrint(font, -200, -30, str, 128, 128, 128);
					}

					if((tempInt < MATTRESS_COLL_DISTANCE)&&(tempInt > 0))
					{
						distanceToMove = MATTRESS_COLL_DISTANCE - tempInt;

						SCALEVECTOR(&tempVect, ((MATTRESS_COLL_FACTOR*distanceToMove)/(tempInt))); 


						// try extra inertia before adding this
						SCALEVECTOR(&seesaw->mattress.vel, MATTRESS_INERTIA);

						seesaw->mattress.vel.vx += tempVect.vx;
						seesaw->mattress.vel.vz += tempVect.vz;

					
						///???????????????
						if((seesaw->mattress.pos.vz + seesaw->mattress.vel.vz) > (MATTRESS_BOTTOM_Z+MATTRESS_SIZE_Z))
						{
						//mattress is being pushed out past the fence

///							fontPrint(font, -200, 0, "touching fence", 128, 128, 128);

							if(tempVect.vx > 0)
							{
								seesaw->mattress.vel.vx += MATTRESS_SIDE_PUSH;//((seesaw->mattress.pos.vz - (MATTRESS_BOTTOM_Z+MATTRESS_SIZE_Z))/2);
							}
							else
							{
								seesaw->mattress.vel.vx -= MATTRESS_SIDE_PUSH;//((seesaw->mattress.pos.vz - (MATTRESS_BOTTOM_Z+MATTRESS_SIZE_Z))/2);
							}
						}
						// stop accelerating towards target if running away		
						avoidingChicken = 1;
						// 
					}
					//sprintf(str, "MATTRESS_COLL_DISTANCE=%d actual =%d", MATTRESS_COLL_DISTANCE,tempInt);
					//fontPrintCentred(font, 0, 0, str, 128, 128, 128);
		
				}
			}

			if(avoidingChicken)
			{
				ADDTOVECTOR(&seesaw->mattress.pos, &seesaw->mattress.vel);
				seesaw->mattress.pos.vy = SEESAW_GROUND_HEIGHT;
				seesaw->mattress.actor->position = seesaw->mattress.pos;
				break;
			}

			// accelerate towards target
			SUBVECTOR(&seesaw->mattress.acc, &seesaw->mattress.targetPos, &seesaw->mattress.pos);
			tempInt = Magnitude2D(seesaw->mattress.acc.vx, seesaw->mattress.acc.vz);
			
			if(tempInt > 0)
				SCALEVECTOR(&seesaw->mattress.acc, (MATTRESS_ACCEL*4096)/tempInt);


			ADDTOVECTOR(&seesaw->mattress.vel, &seesaw->mattress.acc);
			SCALEVECTOR(&seesaw->mattress.vel, MATTRESS_INERTIA);

			tempInt = Magnitude2D((seesaw->mattress.pos.vx - seesaw->mattress.targetPos.vx), (seesaw->mattress.pos.vz - seesaw->mattress.targetPos.vz));
			if(tempInt < MATTRESS_ARRIVE_DISTANCE)	//here
			{
				if(seesaw->state == SEESAW_STATE_FINISH)
					seesaw->mattress.state = MATTRESS_STOPPED;
				else
					seesaw->mattress.state = MATTRESS_ARRIVED;
			}

			if(seesaw->state ==	SEESAW_STATE_FINISH)
			{
				if((seesaw->mattress.pos.vx > 6000) || (seesaw->mattress.pos.vx < -6500))
					seesaw->mattress.state = MATTRESS_STOPPED;
			}
					

			ADDTOVECTOR(&seesaw->mattress.pos, &seesaw->mattress.vel);

			seesaw->mattress.pos.vy = SEESAW_GROUND_HEIGHT;
			seesaw->mattress.actor->position = seesaw->mattress.pos;
			break;

		case MATTRESS_ARRIVED:
			//sprintf(str,"ARRIVED");

			//calculate next pos they aim for
			//1. calculate z pos
			seesaw->mattress.targetPos.vz = MATTRESS_BOTTOM_Z + (long)random((MATTRESS_SIZE_Z-MATTRESS_SIZE_BORDER));

			//2. calculate range in xDirection
			tempInt = (seesaw->mattress.targetPos.vz - MATTRESS_BOTTOM_Z)<<8;
			tempInt = tempInt/MATTRESS_SIZE_Z;
			tempInt = (tempInt * (MATTRESS_WIDTH_TOP - MATTRESS_WIDTH_BOTTOM));
			tempInt = tempInt >> 8;
			tempInt = tempInt + MATTRESS_WIDTH_BOTTOM;

			//3. calculate xPos
			seesaw->mattress.targetPos.vx = MATTRESS_MIDDLE_X + random((ULONG)tempInt) - tempInt/2;
			seesaw->mattress.targetPos.vy = SEESAW_GROUND_HEIGHT;

//			DB("xPos %d, yPos %d\n", xPos, zPos);

			SUBVECTOR(&seesaw->mattress.acc, &seesaw->mattress.targetPos, &seesaw->mattress.pos);

			tempInt = Magnitude2D(seesaw->mattress.acc.vx, seesaw->mattress.acc.vz);
			if(tempInt > 0)
				SCALEVECTOR(&seesaw->mattress.acc, (MATTRESS_ACCEL*4096)/tempInt);
			
//			seesaw->mattress.count = 20;//temp
			seesaw->mattress.state = MATTRESS_MOVING;
			break;

		case MATTRESS_CATCHING:
			//sprintf(str,"CATCHING");


			SUBVECTOR(&seesaw->mattress.acc, &seesaw->drones[seesaw->mattress.incomingChicken].target, &seesaw->mattress.pos);
			tempInt = Magnitude2D(seesaw->mattress.acc.vx, seesaw->mattress.acc.vz);
			if(tempInt > 0)
				SCALEVECTOR(&seesaw->mattress.acc, (MATTRESS_ACCEL*4096)/tempInt);


			ADDTOVECTOR(&seesaw->mattress.vel, &seesaw->mattress.acc);
			SCALEVECTOR(&seesaw->mattress.vel, MATTRESS_INERTIA);

			ADDTOVECTOR(&seesaw->mattress.pos, &seesaw->mattress.vel);

			seesaw->mattress.pos.vy = SEESAW_GROUND_HEIGHT;
			seesaw->mattress.actor->position = seesaw->mattress.pos;

			if(seesaw->drones[seesaw->mattress.incomingChicken].state != SEESAW_DRONE_FLYING)
			{
				seesaw->mattress.state = MATTRESS_ARRIVED;
				//actorAnimate(seesaw->mattress
			}
			break;

		case MATTRESS_MISSING:
			//sprintf(str,"MISSING");


			// move away from drone
			// if drone is missing incoming is -ve -1 !!! ie 0 ==> -1   1 ==> -2  etc. 


			targetChick = -seesaw->mattress.incomingChicken - 1;

			if((targetChick < 0)||(targetChick >= SEESAW_NUM_DRONES))
			{
				DB("*!\n*!\neRRoR targetChick=%d\n", targetChick);
				break;
			}

			SUBVECTOR(&seesaw->mattress.acc, &seesaw->mattress.pos, &seesaw->drones[targetChick].target);
			tempInt = Magnitude2D(seesaw->mattress.acc.vx, seesaw->mattress.acc.vz);

			// If it's far enough away don't need to accelerate further away

//			if(tempInt > MATTRESS_MIN_REQUIRED_AVOID_DIST)
//				seesaw->mattress.state = MATTRESS_ARRIVED;
			if(((seesaw->mattress.acc.vx * seesaw->mattress.acc.vx) > (MATTRESS_MIN_REQUIRED_AVOID_DIST*MATTRESS_MIN_REQUIRED_AVOID_DIST))
				|| (seesaw->drones[targetChick].state != SEESAW_DRONE_FLYING))
			{
				seesaw->mattress.state = MATTRESS_ARRIVED;
				break;
			}

			
			if(tempInt > 0)
				SCALEVECTOR(&seesaw->mattress.acc, (MATTRESS_ACCEL*4096)/tempInt);

			ADDTOVECTOR(&seesaw->mattress.vel, &seesaw->mattress.acc);
			SCALEVECTOR(&seesaw->mattress.vel, MATTRESS_INERTIA);

			ADDTOVECTOR(&seesaw->mattress.pos, &seesaw->mattress.vel);

			seesaw->mattress.pos.vy = SEESAW_GROUND_HEIGHT;
			seesaw->mattress.actor->position = seesaw->mattress.pos;

			if(seesaw->drones[targetChick].state == SEESAW_DRONE_RUNNINGOFF)//!= SEESAW_DRONE_FLYING)
			{
				seesaw->mattress.state = MATTRESS_ARRIVED;
				//actorAnimate(seesaw->mattress
			}

			//seesaw->mattress.state = MATTRESS_MOVING;
			break;

		case MATTRESS_LEAVING:
			//sprintf(str,"LEAVING");


			if(seesaw->mattress.pos.vx > MATTRESS_MIDDLE_X)
				seesaw->mattress.targetPos.vx = SEESAW_MATTRESS_RUNOFFRIGHTX;
			else
				seesaw->mattress.targetPos.vx = SEESAW_MATTRESS_RUNOFFLEFTX; 

			seesaw->mattress.targetPos.vz = MATTRESS_BOTTOM_Z + MATTRESS_SIZE_Z/2;
			seesaw->mattress.state = MATTRESS_MOVING;
			break;

		case MATTRESS_STOPPED:
			break;

	}

	// check it doesn't go outside range
	if(seesaw->mattress.pos.vz < MATTRESS_BOTTOM_Z)
		seesaw->mattress.pos.vz = MATTRESS_BOTTOM_Z;

	if(seesaw->mattress.pos.vz > MATTRESS_BOTTOM_Z+MATTRESS_SIZE_Z)
	{
		seesaw->mattress.pos.vz = MATTRESS_BOTTOM_Z+MATTRESS_SIZE_Z;
		if(seesaw->mattress.vel.vz > 0)
		{
			seesaw->mattress.vel.vz = 0;
		}
	}

	seesaw->mattress.oldPos = seesaw->mattress.pos;

	//1. find z pos
//	tempInt = seesaw->mattress.pos.vz;

	//2. calculate range in xDirection
//	tempInt = (tempInt - MATTRESS_BOTTOM_Z)<<8;
//	tempInt = tempInt/MATTRESS_SIZE_Z;
//	tempInt = (tempInt * (MATTRESS_WIDTH_TOP - MATTRESS_WIDTH_BOTTOM));
//	tempInt = tempInt >> 8;
//	tempInt = tempInt + MATTRESS_WIDTH_BOTTOM;
//	tempInt /= 2;

	//3. check x pos isn't too wide

//	if(seesaw->mattress.pos.vx > MATTRESS_MIDDLE_X + tempInt)
//		seesaw->mattress.pos.vx = MATTRESS_MIDDLE_X + tempInt;

//	if(seesaw->mattress.pos.vx < MATTRESS_MIDDLE_X - tempInt)
//		seesaw->mattress.pos.vx = MATTRESS_MIDDLE_X - tempInt;

	//odo
//	fontPrint(font, -200, 0, str, 158, 128, 128);


}




#define CHICKEN_SEESAW_XOFFSET (0)
#define	CHICKEN_SEESAW_ZOFFSET (-600)


void deviceUpdate()
{
	int tempInt;
	PSIOBJECT *object;
	VECTOR tempVect;


	if((seesaw->device.droneOnDevice >= 0)&&(seesaw->drones[seesaw->device.droneOnDevice].state == SEESAW_DRONE_ONDEVICE))
	{
		seesaw->device.animPos += ((8*(353 -(seesaw->device.power + 177))) - seesaw->device.animPos)/5;
		seesaw->device.actor->animation.animData[0].scaledFrameOffset = seesaw->device.animPos;
	}
	
	tempInt = seesaw->device.yTargetRot - seesaw->device.yRot;
	tempInt /= 5;

	seesaw->device.yRot += tempInt;

// need to find PSIOBJECT of DEVICE
	object = psiObjectScan(seesaw->device.actor->psiData.object, "PLANK");
	if(object)
		object->rotate.vy = seesaw->device.yRot;


	tempVect.vx = CHICKEN_SEESAW_XOFFSET;
	tempVect.vy = 0;
	tempVect.vz = CHICKEN_SEESAW_ZOFFSET;

	RotateVector2D(&tempVect, &tempVect, seesaw->device.yRot);

	seesaw->device.chickenPos.vx = CHICKEN_SEESAW_DEVICE_XCENTRE + tempVect.vx;
#ifdef DREAMCAST
	seesaw->device.chickenPos.vy = CHICKEN_SEESAW_DEVICE_YCENTRE - seesaw->device.animPos/20 + dcSeesawBodge;
#else
	seesaw->device.chickenPos.vy = CHICKEN_SEESAW_DEVICE_YCENTRE - seesaw->device.animPos/20;
#endif
	seesaw->device.chickenPos.vz = CHICKEN_SEESAW_DEVICE_ZCENTRE + tempVect.vz;

//	if((seesaw->device.droneOnDevice >= 0) && (seesaw->drones[seesaw->device.droneOnDevice].state == SEESAW_DRONE_ONDEVICE))
//	{
		// make sure chicken is on the seesaw-device

//		seesaw->drones[0].actor->position.vx = CHICKEN_SEESAW_DEVICE_XCENTRE + tempVect.vx;
//		seesaw->drones[0].actor->position.vz = CHICKEN_SEESAW_DEVICE_ZCENTRE + tempVect.vz;

//		seesaw->drones[0].actor->psiData.object->rotate.vy = 2048 + seesaw->device.yRot;

//	}


	// There is no chicken on or running towards the seesaw
	// look for next one intil one is inactive
	if((seesaw->device.droneOnDevice < 0) && (seesaw->state == SEESAW_STATE_RUNNING))
	{
		if(seesaw->device.nextDrone >= 0)
		{
			seesaw->drones[seesaw->device.nextDrone].state = SEESAW_DRONE_RUNNINGON;
			actorAnimate(seesaw->drones[seesaw->device.nextDrone].actor, DRONE_RUN, YES, FALSE, 400, FALSE, 0);

			seesaw->device.droneOnDevice = seesaw->device.nextDrone;
			seesaw->device.nextDrone = -1;
			for(tempInt=0; ((tempInt < SEESAW_NUM_DRONES) && (seesaw->device.nextDrone < 0)); tempInt++)
			{
				if(seesaw->drones[tempInt].state == SEESAW_DRONE_INACTIVE)
					seesaw->device.nextDrone = tempInt;

			}

		}
		else
		{
			for(tempInt=0; ((tempInt < SEESAW_NUM_DRONES) && (seesaw->device.nextDrone < 0)); tempInt++)
			{
				if(seesaw->drones[tempInt].state == SEESAW_DRONE_INACTIVE)
				{
					seesaw->device.nextDrone = tempInt;
				}
			}
		}
	}
}


#define SEESAW_SHADOW_HEIGHT  -100
#define SEESAW_SHADOW_SIZE  240

#define SEESAW_INRO_TEXT_XPOS  -130
// ====================================================================================================

#define SS_PB_XPOS   -225

#ifdef DREAMCAST

//SB please leave these as ints I know what I'm doing Dave...
#if PALMODE==1
int SS_PB_YPOS = 74;
#else
int SS_PB_YPOS = 60;
#endif

#else

#if PALMODE==1
#define SS_PB_YPOS   74
#else
#define SS_PB_YPOS   60
#endif

#endif

#define SS_POWER_RANGE 176

#ifdef DREAMCAST

//SB please leave these as ints I know what I'm doing Dave...
//OK. I spend a lot of time hunting for int's I've left behind to change them into #define's
//Apologies if I ever change anyone elses by mistake!

int seesawproj = 1165;
#if PALMODE==1
int SEESAW_CRICKET_X = -228;
int SEESAW_CRICKET_Y = -110;
#else
int SEESAW_CRICKET_X = -228;
int SEESAW_CRICKET_Y = -100;
#endif

#else

#if PALMODE==1
#define SEESAW_CRICKET_X  -228
#define SEESAW_CRICKET_Y  -110
#else
#define SEESAW_CRICKET_X  -228
#define SEESAW_CRICKET_Y  -100
#endif

#endif
				   
void seesawDraw(void)
{

	long i;
	int prev_lighting, temp;
	PSIMODELCTRL		*modctrl = &PSImodelctrl;

#ifdef DREAMCAST
	GsSetProjection(seesawproj);//MIKEY
	depthBump = seesawWorldDepth;
#endif


	max_map_ot_depth = 1023;
#ifndef _WINDOWS
	seesawDrawSky();
#endif

//	actorMaintainAnimation(seesaw->device.actor);
//	actorMaintainAnimation(seesaw->device.winderActor);
//	actorMaintainAnimation(seesaw->mattress.actor);
//	actorMaintainAnimation(seesaw->drones[0].actor);
//	actorMaintainAnimation(seesaw->drones[1].actor);
//	actorMaintainAnimation(seesaw->drones[2].actor);
//	actorMaintainAnimation(seesaw->drones[3].actor);


	mapCamSetRefView2L(&mycamera); //? here?
	TIMER_START(TIMER_MAPREND);

	MapDraw_DrawFMA_World((FMA_WORLD2 *)mapview_fma_world);
	TIMER_STOP(TIMER_MAPREND);
#ifdef _WINDOWS
	seesawDrawSky();
#endif


	EXLIGHT_SetupActorLights(seesaw->device.winderActor);
#ifndef _WINDOWS
	actorDraw(seesaw->device.winderActor);
#else
	d2mActorDraw(seesaw->device.winderActor);
#endif

	EXLIGHT_SetupActorLights(seesaw->mattress.actor);
#ifndef _WINDOWS
	actorDraw(seesaw->mattress.actor);
#else
	d2mActorDraw(seesaw->mattress.actor);
#endif

/*
				{
				temp = modctrl->depthoverride;
				modctrl->depthoverride = 40;//depth_floater - 40;	// 20 should do the job
				actorDraw(cat->drones[i].actor);
				modctrl->depthoverride = temp;
			}
			else
				actorDraw(cat->drones[i].actor);
*/

	for(i=0; i<SEESAW_NUM_DRONES; i++)
	{
	
	if(seesaw->drones[i].state != SEESAW_DRONE_INACTIVE)
	{
//		EXLIGHT_SetupActorLights(seesaw->drones[0].actor);
#ifndef _WINDOWS

		if(	 // look away, avert your eyes.
			(seesaw->drones[i].state <= SEESAW_DRONE_FLYING)
			||
			( 
			  (seesaw->drones[i].actor->position.vz < seesaw->mattress.pos.vz )
			  &&( (seesaw->drones[i].state == SEESAW_DRONE_CRASHING) || (seesaw->drones[i].state == SEESAW_DRONE_RUNNINGOFF) )
			  &&(seesaw->drones[i].actor->position.vx > (MATTRESS_MIDDLE_X - MATTRESS_SORT_WIDTH))
			  &&(seesaw->drones[i].actor->position.vx < (MATTRESS_MIDDLE_X + MATTRESS_SORT_WIDTH))
			)
		   )
		{

#ifdef DREAMCAST
			EXLIGHT_SetupActorLights(seesaw->drones[i].actor);
			actorDraw(seesaw->drones[i].actor);
#else
			temp = modctrl->depthoverride;
			//todo
			if(seesaw->drones[i].state > SEESAW_DRONE_FLYING)
			{
				modctrl->depthoverride = MATTRESS_SORT_DEPTH;
//				fontPrint(font, 0, 0, "sort", 128, 128, 128);
			}
			else
			{
				modctrl->depthoverride = 40;
			}

			EXLIGHT_SetupActorLights(seesaw->drones[i].actor);

#ifndef _WINDOWS
			actorDraw(seesaw->drones[i].actor);
#else
			d2mActorDraw(seesaw->drones[i].actor);
#endif
			modctrl->depthoverride = temp;
#endif
		}
		else

		{
			EXLIGHT_SetupActorLights(seesaw->drones[i].actor);
#ifndef _WINDOWS
			actorDraw(seesaw->drones[i].actor);
#else
			d2mActorDraw(seesaw->drones[i].actor);
#endif

		}

				
#else
			EXLIGHT_SetupActorLights(seesaw->drones[i].actor);
#ifndef _WINDOWS
			actorDraw(seesaw->drones[i].actor);
#else
			d2mActorDraw(seesaw->drones[i].actor);
#endif

#endif

			if((seesaw->drones[i].state == SEESAW_DRONE_FLYING) || (seesaw->drones[i].state == SEESAW_DRONE_BOUNCING))
			{
				seesawDrawShadow(seesaw->shadow, seesaw->drones[i].actor->position.vx, SEESAW_SHADOW_HEIGHT, seesaw->drones[i].actor->position.vz, SEESAW_SHADOW_SIZE);
			}

		}
	}

/*
	if(seesaw->drones[1].state != SEESAW_DRONE_INACTIVE)
	{
		EXLIGHT_SetupActorLights(seesaw->drones[1].actor);
#ifndef _WINDOWS
		actorDraw(seesaw->drones[1].actor);
#else
		d2mActorDraw(seesaw->drones[1].actor);
#endif


		if((seesaw->drones[1].state == SEESAW_DRONE_FLYING) || (seesaw->drones[1].state == SEESAW_DRONE_BOUNCING))
		{
			seesawDrawShadow(seesaw->shadow, seesaw->drones[1].actor->position.vx, SEESAW_SHADOW_HEIGHT, seesaw->drones[1].actor->position.vz, SEESAW_SHADOW_SIZE);
		}

	}

	if(seesaw->drones[2].state != SEESAW_DRONE_INACTIVE)
	{
		EXLIGHT_SetupActorLights(seesaw->drones[2].actor);
#ifndef _WINDOWS
		actorDraw(seesaw->drones[2].actor);
#else
		d2mActorDraw(seesaw->drones[2].actor);
#endif
		if((seesaw->drones[2].state == SEESAW_DRONE_FLYING) || (seesaw->drones[2].state == SEESAW_DRONE_BOUNCING))
		{
			seesawDrawShadow(seesaw->shadow, seesaw->drones[2].actor->position.vx, SEESAW_SHADOW_HEIGHT, seesaw->drones[2].actor->position.vz, SEESAW_SHADOW_SIZE);
		}
	}

	if(seesaw->drones[3].state != SEESAW_DRONE_INACTIVE)
	{
		EXLIGHT_SetupActorLights(seesaw->drones[3].actor);
#ifndef _WINDOWS
		actorDraw(seesaw->drones[3].actor);
#else
		d2mActorDraw(seesaw->drones[3].actor);
#endif
		if((seesaw->drones[3].state == SEESAW_DRONE_FLYING) || (seesaw->drones[3].state == SEESAW_DRONE_BOUNCING))
		{
			seesawDrawShadow(seesaw->shadow, seesaw->drones[3].actor->position.vx, SEESAW_SHADOW_HEIGHT, seesaw->drones[3].actor->position.vz, SEESAW_SHADOW_SIZE);
		}																																	
	}
*/

#ifdef _WINDOWS
	{
		int oldXPos = stopWatchXPos;
		int oldYPos = stopWatchYPos;

		stopWatchXPos = 420;
		stopWatchYPos = 50;

		stopWatchXPosBack = 130;
		stopWatchYPosBack = -110;

		IDirect3DDevice7_SetRenderState ( g_pd3dDevice, D3DRENDERSTATE_ZENABLE, D3DZB_FALSE );
		IDirect3DDevice7_SetRenderState ( g_pd3dDevice, D3DRENDERSTATE_ZWRITEENABLE, FALSE  );
		IDirect3DDevice7_SetRenderState ( g_pd3dDevice, D3DRENDERSTATE_ZFUNC, D3DCMP_NEVER  );
#endif

	if(seesaw->state == SEESAW_STATE_RUNNING)
		drawStopWatch(4096 - ((4096*seesaw->timer.startCount)/(seesaw->timer.initialStartCount)));
	else							//*/
		drawStopWatch(0);

#ifdef _WINDOWS
		stopWatchXPos = oldXPos;
		stopWatchYPos = oldYPos;
	}
#endif

	// Draw Gourad
	prev_lighting = PSImodelctrl.lighting;
	PSImodelctrl.lighting = NOLIGHTING;

//	EXLIGHT_SetupActorLights(seesaw->device.actor);
#ifndef _WINDOWS
	actorDraw(seesaw->device.actor);
#else
	d2mActorDraw(seesaw->device.actor);
#endif
		
	PSImodelctrl.lighting = prev_lighting;

	
	
	debrisDraw();


	seesawPrintDebugText();


	switch(seesaw->state)
	{

		case SEESAW_STATE_FADEIN:			

			if(subGameRestart == TRUE)
			{

				i= 255 - (seesaw->frameCount)*20;
				if(i <= 0)
					seesaw->state = SEESAW_STATE_INTRO;
				else
					deathScreenAdd(i, i, i, SEMITRANS_SUB, 2);
				break;
			}
			else
				seesaw->state = SEESAW_STATE_INTRO;
			break;

		case SEESAW_STATE_INTRO:
			seesawDrawIntro();
			break;


		case SEESAW_STATE_FINISH:
			fontPrintCentred(font, 0, 0, TEXTSTR(TEXTSTR_SUB_TIMES_UP), 128, 128 , 128);

		case SEESAW_STATE_RUNNING:
			//seesawDrawSpeedMeter();


			//seesaw->device.power

			subgameDrawPowerBar(SS_PB_XPOS, SS_PB_YPOS, 4096 * (seesaw->device.power + SS_POWER_RANGE) / (2 * SS_POWER_RANGE));

	//		countDownDraw(&seesaw->timer, COUNTDOWN_XPOS, COUNTDOWN_YPOS);
//			seesawPrintChickenCount();

			drawCricketScores(SEESAW_CRICKET_X, SEESAW_CRICKET_Y, seesaw->numChickensSaved);
		

//			nmeDrawHourglass(HGLASS_X, HGLASS_Y, 20 - 20*seesaw->timer.startCount/seesaw->timer.initialStartCount, 1);
			break;

		case SEESAW_STATE_GOLD_SUCCESS:
#ifdef _WINDOWS			// JH: Nice and simple fix, draw them the other way around and they work.
			fowlerDraw();
			seesawDrawGoldSuccessScreen();
#else

			seesawDrawGoldSuccessScreen();
#ifdef DREAMCAST
			depthBump = seesawFowlerBump;
#endif
			fowlerDraw();
#endif
			break;


		case SEESAW_STATE_SILVER_SUCCESS:
#ifdef _WINDOWS			// JH: Nice and simple fix, draw them the other way around and they work.
			fowlerDraw();
			seesawDrawSilverSuccessScreen();
#else

			seesawDrawSilverSuccessScreen();
#ifdef DREAMCAST
			depthBump = seesawFowlerBump;
#endif
			fowlerDraw();
#endif
			break;


		case SEESAW_STATE_BRONZE_SUCCESS:
#ifdef _WINDOWS			// JH: Nice and simple fix, draw them the other way around and they work.
			fowlerDraw();
			seesawDrawBronzeSuccessScreen();
#else

			seesawDrawBronzeSuccessScreen();
#ifdef DREAMCAST
			depthBump = seesawFowlerBump;
#endif
			fowlerDraw();
#endif
			break;



		case SEESAW_STATE_FAIL:
#ifdef _WINDOWS			// JH: Nice and simple fix, draw them the other way around and they work.
			fowlerDraw();
			seesawDrawFailScreen();
#else

			seesawDrawFailScreen();

#ifdef DREAMCAST
			depthBump = seesawFowlerBump;
#endif

			fowlerDraw();
#endif
			break;

		case SEESAW_STATE_FADEOUT:

			if(subGameRestart == TRUE)
			{
				i= (seesaw->frameCount)*20;
				if(i > 220)
					deathScreenAdd(255, 255, 255, SEMITRANS_SUB, 0);

//				if(i >=255)
//				{
//					deathScreenAdd(255, 255, 255, SEMITRANS_SUB, 0);
//					seesawEnd();
//				}
				else
					deathScreenAdd(i, i, i, SEMITRANS_SUB, 0);
			}
//			else
//				seesawEnd();

	
			break;



	}
#ifdef DREAMCAST
	depthBump = 0;
#endif


}

void seesawDrawSky()
{

	POLY_G4 *sky;				// A quad gouraud for the sky

	BEGINPRIM(sky, POLY_G4);
	setPolyG4(sky);				
	sky->x0 = -256;				
	sky->y0 = -128;	
	sky->x1 = 256;
	sky->y1 = -128;
	sky->x2 = -256;
	sky->y2 = -78;
	sky->x3 = 256;
	sky->y3 = -78;

	sky->r0 = 190;
	sky->g0 = 200;
	sky->b0 = 235;
	sky->r1 = 190;
	sky->g1 = 200;
	sky->b1 = 235;
	sky->r2 = 50;
	sky->g2 = 80;
	sky->b2 = 250;
	sky->r3 = 50;
	sky->g3 = 80;
	sky->b3 = 250;
	
#ifdef _WINDOWS
	ENDPRIM(sky, 49152, POLY_G4);
#else
#ifdef DREAMCAST
	ENDPRIM(sky, 4096, POLY_G4);
#else
#endif
	ENDPRIM(sky, 1023, POLY_G4);	// max OT depth is 1023 on the PSX. Ta. Fred
#endif

}

void seesawDrawShadow(TextureType *shadow, int x, int y, int z, int size)
{

	VECTOR v[4];
	int colour;

	v[0].vx = x - size;
	v[0].vy = y;
	v[0].vz = z - size;

	v[1].vx = x + size;
	v[1].vy = y;
	v[1].vz = z - size;

	v[2].vx = x - size;
	v[2].vy = y;
	v[2].vz = z + size;

	v[3].vx = x + size;
	v[3].vy = y;
	v[3].vz = z + size;


	colour = 16|(16<<8)|(16<<16);


	overlayAlphaPoly(shadow, v, 4, colour, ALPHA_POLY_ST_SUB);

}

//------------------------------------------------------------------------------------------------------------------
void seesawDrawIntro()
{
	char string[400];					  

	sprintf(string, "%s\n\n%s\n\n%s\n%s\n\n%s", 
		fontUpper((char*)TEXTSTR(TEXTSTR_NAME_OF_SEESAW)),
		(char*)TEXTSTR(TEXTSTR_SUB_SEESAW_INTRO1),
		(char*)TEXTSTR(TEXTSTR_SUB_FIRE_CHICK),   
		(char*)TEXTSTR(TEXTSTR_SUB_SEESAW_AIM),   
		(char*)TEXTSTR(TEXTSTR_SUB_XSTART)
		);

	fontPrintMultiLineBox(font, 0, 20, 340, string, 40, 40, 20);

}



#define SEESAW_TEXT_OUTRO_X  0
#define SEESAW_TEXT_OUTRO_Y  10
#define SEESAW_TEXT_OUTRO_WIDTH  400
																		  
//------------------------------------------------------------------------------------------------------------------
void seesawDrawGoldSuccessScreen()
{
	char string[256];					  

	sprintf(string, "%s %d %s %s\n%s", (char*)TEXTSTR(TEXTSTR_SUB_SUBGAME_SAVED), seesaw->numChickensSaved, (char*)TEXTSTR(TEXTSTR_SUB_SUBGAME_CHICKENS), (char*)TEXTSTR(TEXTSTR_SUB_SEESAW_GOLD), (char*)TEXTSTR(TEXTSTR_SUB_GAME_EXIT_RESTART));
	fontPrintMultiLineBoxSetDepth(font, SEESAW_TEXT_OUTRO_X, SEESAW_TEXT_OUTRO_Y, 340, string, 40, 40, 20, seesawBoxDepth);
}

//------------------------------------------------------------------------------------------------------------------
void seesawDrawSilverSuccessScreen()
{
	char string[256];

	sprintf(string, "%s %d %s %s\n%s", (char*)TEXTSTR(TEXTSTR_SUB_SUBGAME_SAVED), 
		seesaw->numChickensSaved, 
		(char*)TEXTSTR(TEXTSTR_SUB_SUBGAME_CHICKENS),
		(char*)TEXTSTR(TEXTSTR_SUB_SEESAW_SILVER), 
		(char*)TEXTSTR(TEXTSTR_SUB_GAME_EXIT_RESTART));
	fontPrintMultiLineBoxSetDepth(font, SEESAW_TEXT_OUTRO_X, SEESAW_TEXT_OUTRO_Y, 340, string, 40, 40, 20, seesawBoxDepth);
}



//------------------------------------------------------------------------------------------------------------------
void seesawDrawBronzeSuccessScreen()
{
	char string[256];

	sprintf(string, "%s %d %s %s\n%s", (char*)TEXTSTR(TEXTSTR_SUB_SUBGAME_SAVED), 
		seesaw->numChickensSaved, 
		(char*)TEXTSTR(TEXTSTR_SUB_SUBGAME_CHICKENS), 
		(char*)TEXTSTR(TEXTSTR_SUB_SEESAW_BRONZE), 
		(char*)TEXTSTR(TEXTSTR_SUB_GAME_EXIT_RESTART));
	fontPrintMultiLineBoxSetDepth(font, SEESAW_TEXT_OUTRO_X, SEESAW_TEXT_OUTRO_Y, SEESAW_TEXT_OUTRO_WIDTH, string, 40, 40, 20, seesawBoxDepth);
}

//------------------------------------------------------------------------------------------------------------------
void seesawDrawFailScreen()
{
	char string[256];

	if(seesaw->numChickensSaved == 0)		
	{
		sprintf(string, "%s\n%s\n%s", (char*)TEXTSTR(TEXTSTR_SUB_SUBGAME_SAVED_NONE), 
			(char*)TEXTSTR(TEXTSTR_SUB_SEESAW_FAIL), 
			(char*)TEXTSTR(TEXTSTR_SUB_GAME_EXIT_RESTART));
	}
	else if(seesaw->numChickensSaved == 1)
	{											  
		sprintf(string, "%s \n%s\n%s", (char*)TEXTSTR(TEXTSTR_SUB_SUBGAME_SAVED_ONE), 
			(char*)TEXTSTR(TEXTSTR_SUB_SEESAW_FAIL), 
			(char*)TEXTSTR(TEXTSTR_SUB_GAME_EXIT_RESTART));
	}
	else
	{																										
		sprintf(string, "%s %d %s %s\n%s", (char*)TEXTSTR(TEXTSTR_SUB_SUBGAME_SAVED), 
			seesaw->numChickensSaved, 
			(char*)TEXTSTR(TEXTSTR_SUB_SUBGAME_CHICKENS), 
			(char*)TEXTSTR(TEXTSTR_SUB_SEESAW_FAIL), 
			(char*)TEXTSTR(TEXTSTR_SUB_GAME_EXIT_RESTART));
	}
	fontPrintMultiLineBoxSetDepth(font, SEESAW_TEXT_OUTRO_X, SEESAW_TEXT_OUTRO_Y, 340, string, 40, 40, 20, seesawBoxDepth);
}


//------------------------------------------------------------------------------------------------------------------
void seesawPrintDebugText(void)
{
	char strBuff[128];

#ifdef SEESAW_VIEW_POS
	sprintf(strBuff, "camPosxyz : %d,%d,%d", mycamera.vpx, mycamera.vpy, mycamera.vpz);
	fontPrint(font, -250, -120, strBuff, 128, 128, 0);

	sprintf(strBuff, "camGrbxyz : %d,%d,%d", mycamera.vrx, mycamera.vry, mycamera.vrz);
	fontPrint(font, -250, -104, strBuff, 128, 128, 0);

//	sprintf(strBuff, "seesawPOS : %d,%d,%d", seesaw->device.actor->position.vx, seesaw->device.actor->position.vy, seesaw->device.actor->position.vz);
//	fontPrint(font, -250, -88, strBuff, 128, 128, 0);

//	sprintf(strBuff, "drone1  : %d,%d,%d, rot %d", seesaw->drones[1].actor->position.vx, seesaw->drones[1].actor->position.vy, seesaw->drones[1].actor->position.vz, seesaw->drones[1].actor->psiData.object->rotate.vy);
//	fontPrint(font, -250, -72, strBuff, 128, 128, 0);

//	sprintf(strBuff, "target  : %d,%d,%d", seesaw->mattress.targetPos.vx, seesaw->mattress.targetPos.vy, seesaw->mattress.targetPos.vz);
//	fontPrint(font, -250, -56, strBuff, 128, 128, 0);

#endif

#ifdef SEESAW_VIEW_DRONE_STATES
	sprintf(strBuff, "drone[0].xstate : %d", seesaw->drones[0].xRotState);
	fontPrint(font, -250, -120, strBuff, 128, 128, 0);

	sprintf(strBuff, "drone[1].xstate : %d", seesaw->drones[1].xRotState);
	fontPrint(font, -250, -104, strBuff, 128, 128, 0);

	sprintf(strBuff, "drone[2].xstate : %d", seesaw->drones[2].xRotState);
	fontPrint(font, -250, -88, strBuff, 128, 128, 0);

	sprintf(strBuff, "drone[3].xstate : %d", seesaw->drones[3].xRotState);
	fontPrint(font, -250, -72, strBuff, 128, 128, 0);

#endif

#ifdef SEESAW_VIEW_WINDER
	sprintf(strBuff, "winderPos : %d, %d, %d", seesaw->device.winderActor->position.vx, seesaw->device.winderActor->position.vy, seesaw->device.winderActor->position.vz);
	fontPrint(font, -250, -104, strBuff, 128, 128, 0);

	sprintf(strBuff, "seesawPOS : %d,%d,%d", seesaw->device.actor->position.vx, seesaw->device.actor->position.vy, seesaw->device.actor->position.vz);
	fontPrint(font, -250, -120, strBuff, 128, 128, 0);

	sprintf(strBuff, "seesawPower : %d", seesaw->device.power);
	fontPrint(font, -250, -88, strBuff, 128, 128, 0);


#endif


#ifdef SEESAW_VIEW_MATTRESS_STATES
	sprintf(strBuff, "incoming : %d", seesaw->mattress.incomingChicken);
	fontPrint(font, -250, -120, strBuff, 128, 128, 0);
#endif



}


//-------------------------------------------------------------------------------------------
void seesawExit()
{
	seesaw->frameCount = 1;
	seesaw->state = SEESAW_STATE_FADEOUT;
	subGameRestart = FALSE;
}

//-------------------------------------------------------------------------------------------
void seesawReset()
{
	int i;
	PSIOBJECT *object;
#ifdef DREAMCAST
	// JIM : I've added this as the tune number in the level info seems to be wrong......
	sound_XA_Resume(TUNE_8_GOLF);
#endif

	seesaw->frameCount = 0;
	seesaw->state = SEESAW_STATE_FADEIN;

	seesaw->mattress.state = MATTRESS_ARRIVED;

	actorAnimate(seesaw->mattress.actor, 0, 1, 0, 300, 1, 0);
	
	seesaw->mattress.actor->position.vx = -400;  
	seesaw->mattress.actor->position.vy = -47;  
	seesaw->mattress.actor->position.vz = -3100; 

	seesaw->mattress.pos = seesaw->mattress.actor->position;
	seesaw->mattress.vel.vx = seesaw->mattress.vel.vy = seesaw->mattress.vel.vz = 0;

	countDownStart(&seesaw->timer, SEESAW_COUNTDOWN_TIME);


	for(i=0; i<SEESAW_NUM_DRONES; i++)
	{
		seesaw->drones[i].actor->position.vx =  DRONE_XSTART;//386;    //         -513;  
		seesaw->drones[i].actor->position.vy =  DRONE_YSTART;//-307;     //       CHICKEN_SEESAW_DEVICE_YCENTRE;   
		seesaw->drones[i].actor->position.vz =  DRONE_ZSTART;//-8877;      //    -9332; 
		seesaw->drones[i].rotAim = 1024;
		seesaw->drones[i].state = SEESAW_DRONE_INACTIVE;//SEESAW_DRONE_ONDEVICE;
	}
	
	// The device knows which chicken if any is on it
	seesaw->device.droneOnDevice = -1;
	seesaw->device.nextDrone = 0;

	actorAnimate(seesaw->device.actor, DEVICE_DOWN_CONST, FALSE, FALSE, 0, 0 , 0); 




	seesaw->numChickensSaved = 0;
	seesaw->device.power = 0;
	seesaw->device.yRot = 0;
	seesaw->device.yTargetRot = 0;

	seesaw_UpdateCamAim();


	object = psiObjectScan(seesaw->device.actor->psiData.object, "PLANK");
	if(object)
		object->rotate.vy = seesaw->device.yRot;


    resetCricketScores();
	resetStopWatch();

	sound_XA_Start(levinfo->tune_number);
}

//-------------------------------------------------------------------------------------------
void seesawStart()
{

	subGameRestart = FALSE;

//	pReadPad->shockEnable=1;	// Need to go from the options screen now. Sorry. Fred

	overlayLoadingBegin(1);


	// ====
	// Setup the cycle and draw routines
	// ===
	draw_routine = seesawDraw;
	cycle_routine = seesawCycle;

	seesaw = &seesawStruct;//(seesawStr*)MALLOC(sizeof(seesawStr));
	memset(seesaw, 0, sizeof(seesawStr));
								   

	if(gameCalledFrom != GAMECALLEDFROM_DEBUG)
	{
		if(!gameSaveData.levels_available[REPLAY_AVAILABLE_SEESAW])
		{
			gameSaveData.levels_available[REPLAY_AVAILABLE_SEESAW] = REPLAY_NOTBEATEN;
		}
	}


	seesaw->shadow = textureFindInAllBanks("SHAD");
	ASSERT(seesaw->shadow);

//	debrisInit();



	seesaw->frameCount = 0;
	seesaw->state = SEESAW_STATE_FADEIN;
	seesaw->camDistToLookAt = 800;

	seesaw->mattress.state = MATTRESS_ARRIVED;

//	mattress = (mattressStr*)MALLOC(sizeof(mattressStr));
//	memset(mattress, 0, sizeof(mattressStr));


	// ============
	// Load the world map that we'll be using
	// ============
//	loadsndLoadBank("A2_SEESAW");
	sound_FreeLanguageBank();
	sound_LoadLanguageBankBody(gameTextLang, "A2_SEESAW");	// Loads "A2_SEESAW\\A2_SEESAW_ENG.sbb" (or other language versions)


	mapviewLoadMap("A2_SEESAW");			// Load the map we're going to use
	setupCollision("A2_SEESAW");			// Setup the collision for the level map
	EXLIGHT_PostBFF();


//	loadsndSubGames(LEVNUMBER_A2_SEESAW, seesaw->pSamples, NUM_SEESAW_SAMPLES);
	seesawLoadsnd(LEVNUMBER_A2_SEESAW, seesaw->pSamples, NUM_SEESAW_SAMPLES);

	overlayLoadingEnd();



//	GsSetProjection(950);
	initFowler(950, SG_SEESAW);

	// ============
	// Setup the camera and stuff
	// ============
//	seesaw_SetupCamera();

	PSImodelctrl.farclip =  1023;



		// Load Mattres
//	mattress.model = BFF_IsModelLoaded("MANNEQUIN");
	seesaw->mattress.model = BFF_IsModelLoaded("MATTRESS");

	ASSERT(seesaw->mattress.model);

	seesaw->mattress.actor = actorCreate(seesaw->mattress.model);
	ASSERT(seesaw->mattress.actor);

	actorInitAnim(seesaw->mattress.actor);	
	ASSERT(seesaw->mattress.actor);

	actorAnimate(seesaw->mattress.actor, 0, 1, 0, 300, 1, 0);
	
	seesaw->mattress.actor->position.vx = -400;  
	seesaw->mattress.actor->position.vy = -47;  
	seesaw->mattress.actor->position.vz = -3100; 

	seesaw->mattress.pos = seesaw->mattress.actor->position;


	// Load the model that will wind up the device
	seesaw->device.winderModel = BFF_IsModelLoaded("CRANKER");
	ASSERT(seesaw->device.winderModel);

	seesaw->device.winderActor = actorCreate(seesaw->device.winderModel);
	ASSERT(seesaw->device.winderActor);

	actorInitAnim(seesaw->device.winderActor);

	seesaw->device.winderActor->position.vx = 386;
	seesaw->device.winderActor->position.vy	= -307;
	seesaw->device.winderActor->position.vz	= -8877;

	seesaw->device.winderActor->psiData.object->rotate.vy = 2048;


	actorAnimate(seesaw->device.winderActor, CRANKER_BREATHE, TRUE, FALSE, 300, 0, 0);


	// Load Drones

	seesaw->drones[0].model = BFF_IsModelLoaded("DRONE1");
	ASSERT(seesaw->drones[0].model);

	seesaw->drones[0].actor = actorCreate(seesaw->drones[0].model);
	ASSERT(seesaw->drones[0].actor);

	actorInitAnim(seesaw->drones[0].actor);	

	seesaw->drones[0].actor->position.vx =  DRONE_XSTART;//386;    //         -513;  
	seesaw->drones[0].actor->position.vy =  DRONE_YSTART;//-307;     //       CHICKEN_SEESAW_DEVICE_YCENTRE;   
	seesaw->drones[0].actor->position.vz =  DRONE_ZSTART;//-8877;      //    -9332; 

	seesaw->drones[0].state = SEESAW_DRONE_INACTIVE;//SEESAW_DRONE_ONDEVICE;
	
	// The device knows which chicken if any is on it
	seesaw->device.droneOnDevice = -1;
	seesaw->device.nextDrone = 0;

	//seesaw->drones[0].actor->psiData.object->rotate.vy = 1024;//2048;

	seesaw->drones[0].rotAim = 1024;



	//Drone 2
	seesaw->drones[1].model = BFF_IsModelLoaded("DRONE2");
	ASSERT(seesaw->drones[1].model);

	seesaw->drones[1].actor = actorCreate(seesaw->drones[1].model);
	ASSERT(seesaw->drones[1].actor);

	actorInitAnim(seesaw->drones[1].actor);	

	seesaw->drones[1].actor->position.vx = DRONE_XSTART;  
	seesaw->drones[1].actor->position.vy = DRONE_YSTART;   
	seesaw->drones[1].actor->position.vz = DRONE_ZSTART; 

	seesaw->drones[1].state = SEESAW_DRONE_INACTIVE;
	seesaw->drones[1].rotAim = 1024;



	//Drone3
	seesaw->drones[2].model = BFF_IsModelLoaded("DRONE3");
	ASSERT(seesaw->drones[2].model);
						
	seesaw->drones[2].actor = actorCreate(seesaw->drones[2].model);
	ASSERT(seesaw->drones[2].actor);

	actorInitAnim(seesaw->drones[2].actor);	

	seesaw->drones[2].actor->position.vx = DRONE_XSTART;  
	seesaw->drones[2].actor->position.vy = DRONE_YSTART;   
	seesaw->drones[2].actor->position.vz = DRONE_ZSTART; 

	seesaw->drones[2].state = SEESAW_DRONE_INACTIVE;
	seesaw->drones[2].rotAim = 1024;


	//Drone4
	seesaw->drones[3].model = BFF_IsModelLoaded("DRONE4");
	ASSERT(seesaw->drones[3].model);

	seesaw->drones[3].actor = actorCreate(seesaw->drones[3].model);
	ASSERT(seesaw->drones[3].actor);

	actorInitAnim(seesaw->drones[3].actor);	

	seesaw->drones[3].actor->position.vx = DRONE_XSTART; 
	seesaw->drones[3].actor->position.vy = DRONE_YSTART;  
	seesaw->drones[3].actor->position.vz = DRONE_ZSTART;

	seesaw->drones[3].state = SEESAW_DRONE_INACTIVE;

	seesaw->drones[3].rotAim = 1024;





	// Load seesaw

	seesaw->device.model = BFF_IsModelLoaded("DEVICE");
	ASSERT(seesaw->device.model);



	seesaw->device.actor = actorCreate(seesaw->device.model);
	ASSERT(seesaw->device.actor);

	actorInitAnim(seesaw->device.actor);	
	ASSERT(seesaw->device.actor);

	
	seesaw->device.actor->position.vx = CHICKEN_SEESAW_DEVICE_XCENTRE - 8;//mycamera.vrx;
	seesaw->device.actor->position.vy = CHICKEN_SEESAW_DEVICE_YCENTRE;//mycamera.vry;
	seesaw->device.actor->position.vz = CHICKEN_SEESAW_DEVICE_ZCENTRE;//mycamera.vrz;

	actorAnimate(seesaw->device.actor, DEVICE_DOWN_CONST, FALSE, FALSE, 0, 0 , 0); 


	countDownStart(&seesaw->timer, SEESAW_COUNTDOWN_TIME);

	initCricketScores(SEESAW_CRICKET_X, SEESAW_CRICKET_Y, SEESAW_BRONZE_NUM_CHICKENS, SEESAW_SILVER_NUM_CHICKENS, SEESAW_GOLD_NUM_CHICKENS, 2);

	// ===========
	// Clear the structure we're going to use
	// ===========
///	memset(&seesaw, 0, sizeof(seesaw));

//	nmeDogEnsureHourglass();

#ifdef DREAMCAST
	initStopWatch(164, -72, 950);
#else
#if PALMODE==1
	initStopWatch(164, -68, 950);
#else
	initStopWatch(164, -64, 950);
#endif
#endif

			    
	subgameInitPowerBar();

	// make sure camera's pointing in the right place
	seesaw_UpdateCamAim();

	// allows debris to be drawn
	DEBRISDISTANCE = SUBGAME_DEBRISDISTANCE;


	dsEvent_Init();
#ifdef DREAMCAST
	// JIM : I've added this as the tune number in the level info seems to be wrong......
	sound_XA_Resume(TUNE_8_GOLF);
#endif
} 


//------------------------------------------------
// seesawEnd()
//
// Free memory and quit back to the menu
//------------------------------------------------

//

void seesawEnd(void)
{

	sound_XA_Stop();
	sfxStopChannel(-1);

	if (seesaw->numChickensSaved > gameSaveData.best_chickens_rescued[RESCUELEVEL_SEESAW])
		gameSaveData.best_chickens_rescued[RESCUELEVEL_SEESAW]=seesaw->numChickensSaved;

	if (seesaw->numChickensSaved > gamePlayData->best_chickens_rescued_this_act[RESCUELEVEL_SEESAW])
		gamePlayData->best_chickens_rescued_this_act[RESCUELEVEL_SEESAW]=seesaw->numChickensSaved;


	if(subGameRestart == TRUE)
	{
		seesawReset();

	}
	else
	{
		seesawFree();

		//psiDestroy();
		//menuStart();
		DB("cat %d fire %d see %d\n",gameSaveData.best_chickens_rescued[RESCUELEVEL_CATAPULT],gameSaveData.best_chickens_rescued[RESCUELEVEL_FIREWORKS],gameSaveData.best_chickens_rescued[RESCUELEVEL_SEESAW]);

		memoryShowStats();
		memoryShow();

		act2SubgameComplete("A2_WORKHUT3");
	}



//	if(subGameRestart == TRUE)
//	{
//		seesawStart();
//		seesawRestart();

//	}
//	else
//	{
//		act2SubgameComplete("A2_WORKHUT3");
//	}

	
}




//extern GsRVIEW2	mycamera;
// get rid of this func..
/*
void seesaw_SetupCamera(void)
{

	mycamera.vpx = SEESAW_CAMERA_XPOS;//-223;
	mycamera.vpy = SEESAW_CAMERA_YPOS;//-7496;
	mycamera.vpz = SEESAW_CAMERA_ZPOS;//-19648;

	mycamera.vrx = SEESAW_GARIB_XPOS;//-387;//posMark->x;
	mycamera.vry = SEESAW_GARIB_YPOS;//-887;//posMark->y;
	mycamera.vrz = SEESAW_GARIB_ZPOS;//-6172;//posMark->z;
}
*/



#define SEESAW_DEVICE_MAX_POWER  176

#define DEVICE_ROT_FACTOR 20

void seesawControls()
{
	VECTOR v;
	v.vx = v.vy = v.vz = 0;


	if(((pReadPad->digital[0] & PAD_CROSS)))
	{
		launchDrone();
	}
	
#ifdef DREAMCAST
	seesaw->device.yTargetRot = pReadPad->analogXS[0]/14;//DEVICE_ROT_FACTOR;
	seesaw->device.power = seesaw->device.power + (-12*(pReadPad->analogYS[0]/12)/10 - seesaw->device.power) * 1/10;
#else

	if(pReadPad->digital[0]&PAD_LEFT)
	{
		seesaw->device.yTargetRot = -4000/DEVICE_ROT_FACTOR;
	}
	else if(pReadPad->digital[0]&PAD_RIGHT)
	{
		seesaw->device.yTargetRot = 4000/DEVICE_ROT_FACTOR;
	}
	else
	{
		seesaw->device.yTargetRot = pReadPad->analogXS[0]/DEVICE_ROT_FACTOR;
	}

	if(pReadPad->digital[0]&PAD_UP)
	{
		seesaw->device.power = seesaw->device.power + ((4096/SEESAW_LAUNCH_SPEED_INVFACTOR) - seesaw->device.power) * 1/10;
	}
	else if(pReadPad->digital[0]&PAD_DOWN)
	{
		seesaw->device.power = seesaw->device.power + ((-4096/SEESAW_LAUNCH_SPEED_INVFACTOR) - seesaw->device.power) * 1/10;
	}
	else
	{
		seesaw->device.power = seesaw->device.power + (-12*(pReadPad->analogYS[0]/SEESAW_LAUNCH_SPEED_INVFACTOR)/10 - seesaw->device.power) * 1/10;
	}
#endif
	if(seesaw->device.power > SEESAW_DEVICE_MAX_POWER)
		seesaw->device.power = SEESAW_DEVICE_MAX_POWER;

	if(seesaw->device.power < -SEESAW_DEVICE_MAX_POWER)
		seesaw->device.power = -SEESAW_DEVICE_MAX_POWER;
}

/*

void RotateCameraAroundLookAtPoint(int delta)
{
	VECTOR v;

	v.vx = mycamera.vpx - mycamera.vrx;
	v.vy = mycamera.vpy - mycamera.vry;
	v.vz = mycamera.vpz - mycamera.vrz;

	RotateVector2D(&v, &v, delta);

	mycamera.vpx = v.vx	+ mycamera.vrx; 
	mycamera.vpy = v.vy	+ mycamera.vry;
	mycamera.vpz = v.vz	+ mycamera.vrz;
}
*/

#define MIN_SEESAW_CAM_DIST 80

/*
void ssMoveCameraTowardsLookAtPoint(int delta)
{
	VECTOR v;


	if((delta < 0) && ((delta + seesaw->camDistToLookAt) < MIN_SEESAW_CAM_DIST) )
		return;

	v.vx = mycamera.vpx - mycamera.vrx;
	v.vy = mycamera.vpy - mycamera.vry;
	v.vz = mycamera.vpz - mycamera.vrz;

	v.vx = v.vx * (delta + seesaw->camDistToLookAt)/seesaw->camDistToLookAt;
	v.vy = v.vy * (delta + seesaw->camDistToLookAt)/seesaw->camDistToLookAt;
	v.vz = v.vz * (delta + seesaw->camDistToLookAt)/seesaw->camDistToLookAt;

	mycamera.vpx = v.vx	+ mycamera.vrx; 
	mycamera.vpy = v.vy	+ mycamera.vry;
	mycamera.vpz = v.vz	+ mycamera.vrz;

	seesaw->camDistToLookAt = delta + seesaw->camDistToLookAt;
}
*/
//----------------------------------------

void seesawDrawSpeedMeter(void)
{
	POLY_G4 *speedbar;
		
	unsigned short r1,b1,g1;

	BEGINPRIM(speedbar, POLY_G4);
	setPolyG4(speedbar);				
	speedbar->x0 = SEESAW_BAR_LEFT+SEESAW_BAR_SLANT;				
	speedbar->y0 = SEESAW_BAR_TOP;	
	
	// depends on power
	speedbar->x1 = 4 + SEESAW_BAR_SLANT + (SEESAW_BAR_WIDTH/2) + SEESAW_BAR_LEFT + seesaw->device.power * SEESAW_BAR_WIDTH * SEESAW_LAUNCH_SPEED_INVFACTOR / 7600 ;

	if(speedbar->x1 > (SEESAW_BAR_SLANT + SEESAW_BAR_LEFT + SEESAW_BAR_WIDTH))
		speedbar->x1 = (SEESAW_BAR_SLANT + SEESAW_BAR_LEFT + SEESAW_BAR_WIDTH);

	if(speedbar->x1  < SEESAW_BAR_LEFT)
		speedbar->x1 = SEESAW_BAR_LEFT;
	
	speedbar->y1 = SEESAW_BAR_TOP;

	speedbar->x2 = SEESAW_BAR_LEFT;
	speedbar->y2 = SEESAW_BAR_TOP + SEESAW_BAR_HEIGHT;
	
	// on power
	speedbar->x3 = speedbar->x1 - SEESAW_BAR_SLANT;

	
	speedbar->y3 = SEESAW_BAR_TOP + SEESAW_BAR_HEIGHT;

	speedbar->r0 = 20;
	speedbar->g0 = 20;
	speedbar->b0 = 160;
	speedbar->r1 = 20 + speedbar->x1;
	speedbar->g1 = 20 + speedbar->x1;
	speedbar->b1 = 160;

	speedbar->r2 = speedbar->r0;
	speedbar->g2 = speedbar->g0;
	speedbar->b2 = speedbar->b0;
	speedbar->r3 = speedbar->r1;
	speedbar->g3 = speedbar->g1;
	speedbar->b3 = speedbar->b1;
		
	ENDPRIM(speedbar, 0, POLY_G4);
	
	fontPrintCentred(font,(4 + SEESAW_BAR_LEFT + SEESAW_BAR_WIDTH/2),85,TEXTSTR(TEXTSTR_SUB_POWER), 110, 110, 110);
	seesawDrawBoxOutline(SEESAW_BAR_LEFT - 1, SEESAW_BAR_TOP - 1,SEESAW_BAR_WIDTH + 2,SEESAW_BAR_HEIGHT+1,0x000000);

}

//--------------------------------------------------
// dogchaseDrawBoxOutline()
//
// Draws an outlined box at x,y of w,h in dimension
//--------------------------------------------------

void seesawDrawBoxOutline(int x, int y, int w, int h, unsigned int colour)
{
	overlayLine(x+SEESAW_BAR_SLANT,y,x+w+SEESAW_BAR_SLANT,y,colour);			// top
	overlayLine(x+w+SEESAW_BAR_SLANT,y,x+w,y+h,colour);			// right
	overlayLine(x,y+h,x+w,y+h,colour);				// bottom
	overlayLine(x+SEESAW_BAR_SLANT,y,x,y+h,colour);				// left
}

//--------------------------------------------------
// timerStuff
//--------------------------------------------------
void countDownStart(countDownTimerStr *timer, long secs)
{
	timer->initialStartCount = timer->startCount = secs * FRAMESEC;
	
	timer->startCount++;
	countDownUpdate(timer);
	timer->active = FALSE;

}

//--------------------------------------------------
void countDownActivate(countDownTimerStr *timer)
{
	timer->active = TRUE;
}

//--------------------------------------------------
int countDownUpdate(countDownTimerStr *timer)
{
	long i;

#ifdef DEBUG
	if(SwimCheatCycle())
	{
		timer->startCount = 0;
		if(padData.digital[0] & PAD_L1)	// "L" is for "Lose"
		{
		}
		else if(padData.digital[0] & PAD_R1)	// "R" is for, ummm, "Really good win"
		{
			seesaw->numChickensSaved = SEESAW_GOLD_NUM_CHICKENS;
		}
		else
		{
			seesaw->numChickensSaved = SEESAW_BRONZE_NUM_CHICKENS;
		}
		DB("Aha!\n");
		return TRUE;
	}
#endif


	if(timer->active == FALSE)
		return FALSE;

	timer->startCount--;


	
// new
	if(timer->startCount == 0)
	{
//		timer->startCount = 1500;
		return TRUE;
	}


	return FALSE;

// to here

	// old....
/*
	i = timer->startCount;
	timer->minutes = i / ( 60 * FRAMESEC);
	i -= timer->minutes * 60 * FRAMESEC;

	timer->tensseconds = i / (10 * FRAMESEC);
	i -= timer->tensseconds * 10 * FRAMESEC;

	timer->seconds = i / (FRAMESEC);
	i -= timer->seconds * FRAMESEC;
	
	timer->tenths = 10 * i / (FRAMESEC);
	i-= timer->tenths * FRAMESEC / 10;

	timer->hundredths = i;






	if(timer->startCount == 0)
	{
//		timer->startCount = 1500;
		return TRUE;
	}

	return FALSE;
*/
}


//--------------------------------------------------
void countDownDraw(countDownTimerStr *timer, int x, int y)
{
	char *time={"0:00:00"};

	*time = (unsigned char) timer->minutes+48;			// 0 is ascii 48
	*(time+2) = (unsigned char)timer->tensseconds+48;
	*(time+3) = (unsigned char)timer->seconds+48;
	*(time+5) = (unsigned char)timer->tenths+48;
	*(time+6) = (unsigned char)timer->hundredths+48;

	fontPrint(font,x,y,time,110,110,110);
}



//--------------------------------------------------
/*
void seesawPrintChickenCount()
{
	char str[24];

	sprintf(str, "%s %d", TEXTSTR(TEXTSTR_SUB_CHICKENS_FREED), seesaw->numChickensSaved);
	//sprintf(str, "%d", seesaw->numChickensSaved);
								   

//	fontPrint(font, CHICKENS_FREED_XPOS, COUNTDOWN_YPOS, TEXTSTR(TEXTSTR_SUB_CHICKENS_FREED), 110, 110, 110); 
	fontPrint(font, CHICKENS_FREED_XPOS, COUNTDOWN_YPOS, str, 110, 110, 110); 
}
*/

void seesawFree(void)
{
	dsEvent_Init();
	debrisFree();

	freeFowler();
	actorFree(seesaw->device.actor);
	actorFree(seesaw->drones[0].actor);
	actorFree(seesaw->drones[1].actor);
	actorFree(seesaw->drones[2].actor);
	actorFree(seesaw->drones[3].actor);

	actorFree(seesaw->mattress.actor);
	actorFree(seesaw->device.winderActor);
	freeStopWatch();

	enemyDeleteAll();
	
//	FREE(seesaw);

	mapviewReleaseMap();

	sound_XA_Stop();
	sound_LoadLanguageBank(gameTextLang);
}


/*	--------------------------------------------------------------------------------
	Function 	: 
	Purpose 	: 
	Parameters 	: 
	Returns 	: 
	Info 		:
*/
void seesawRestart()
{
	subGameRestart = TRUE;
	seesaw->frameCount = 1;
	seesaw->state = SEESAW_STATE_FADEOUT;
}


