/***********************************************************************************************************/
/*                                                                                                         */
/* Cinematic Stuff                                                                               G.Rummery 1997 */
/*                                                                                                         */
/***********************************************************************************************************/

/*---------------------------------------------------------------------------
 *	Import Headers
\*--------------------------------------------------------------------------*/

#ifdef PSX_VERSION
#include <sys\types.h>
#include <stdio.h>
#include "../spec_psx/typedefs.h"
#include "../spec_psx/psxinput.h"
#include "../spec_psx/picture.h"
#include "../spec_psx/specific.h"
#include "../spec_psx/cd.h"
#include "../spec_psx/maths.h"
#else
#include "../specific/standard.h"
#include "../specific/global.h"
#include "../specific/input.h"
#include "../specific/output.h"
#endif

#include "objects.h"
#include "lara.h"
#include "camera.h"
#include "control.h"
#include "input.h"
#include "sound.h"
#include "savegame.h"
#include "inventry.h"
#include "hair.h"
#include "title.h"
#include "laramisc.h"
#include "setup.h"
#include "sphere.h"
#include "text.h"

#include "effect2.h"
#include "laraanim.h"

/*---------------------------------------------------------------------------
 *	Constants
\*--------------------------------------------------------------------------*/

#define CINE_ADJUST 6

#if defined(PC_VERSION) && defined(GAMEDEBUG)
#define MANUAL_CAMERA
#define DIK_PRIOR           0xC9    /* PgUp on arrow keypad */
#define DIK_NEXT            0xD1    /* PgDn on arrow keypad */
#define DIK_HOME            0xC7    /* Home on arrow keypad */
#define DIK_END             0xCF    /* End on arrow keypad */
#define DIK_INSERT          0xD2    /* Insert on arrow keypad */
#define DIK_DELETE          0xD3    /* Delete on arrow keypad */
#endif

/*---------------------------------------------------------------------------
 *	Externals
\*--------------------------------------------------------------------------*/

extern char exit_message[];
extern int level_complete;
extern int GnGameMode;
extern int cutscene_track;
extern int InfoFlag;

#ifdef PSX_VERSION
extern sint16 *cine;
extern sint16 cine_frame;
extern sint16 num_cine_frames;
extern PHD_3DPOS cinematic_pos;
extern void mQuickW2VMatrix();
#endif

/*---------------------------------------------------------------------------
 *	Globals
\*--------------------------------------------------------------------------*/

#if defined(PSX_VERSION) && defined(RELOC)

sint32 StartCinematic(int level_number);
sint32 DrawPhaseCinematic();
void InitialiseGenPlayer(sint16 item_num);
void	ControlCinematicPlayer(sint16 item_num);
void	InGameCinematicCamera();
#ifdef GAMEDEBUG
void SetCutscene(int cut);
void SetCutsceneAngle(int angle);
#endif

void *func[] = {
	&StartCinematic,
	&DrawPhaseCinematic,
	&InitialiseGenPlayer,
	&ControlCinematicPlayer,
	&InGameCinematicCamera,
#ifdef GAMEDEBUG
	&SetCutscene,
	&SetCutsceneAngle
#endif
};

#else

sint16 *cine;
sint16 cine_frame;
sint16 cine_loaded;
sint16 num_cine_frames;
PHD_3DPOS	cinematic_pos;

#ifdef MANUAL_CAMERA
PHD_3DPOS	mycam;
int useCineCam=1;
sint32 mycam_distance=1024;
#endif

#endif

/*---------------------------------------------------------------------------
 *	Locals
\*--------------------------------------------------------------------------*/

static sint16 cinematic_level;

#ifdef PSX_VERISON
static int cutscene_play=-1;
#else
int cutscene_play=-1;
#endif

static int cinematic_animation_rate = 32768;

static uint32 actual_current_frame=0;

#ifdef PSX_VERSION
//##static uint32 actual_start_frame=0;
#endif

static int original_room=0;

/*---------------------------------------------------------------------------
 *	Local Functions
\*--------------------------------------------------------------------------*/

/****************************************************************************
 *				Initialise rooms for drawing Cutscene
 ***************************************************************************/
static void InitCinematicRooms()
{
	int		i;

	for ( i=0 ; i<number_rooms ; i++ )
	{
		if (room[i].flipped_room >= 0)
			room[room[i].flipped_room].bound_active = 1;
#ifdef PC_VERSION
		room[i].flags|=OUTSIDE;	// will this frig work maybe?
#endif
	}

	number_draw_rooms = 0;

	for ( i=0 ; i<number_rooms ; i++ )
	{
		if (!room[i].bound_active)
			draw_rooms[number_draw_rooms++] = i;
	}
}

/*****************************************************************************
 *			Simple Cinematic Object Control Routine
 ****************************************************************************/
static int GetCinematicRoom(sint32 x, sint32 y, sint32 z)
{
	int		i;

	for ( i=0 ; i<number_rooms ; i++ )
	{
		if ((x >= (room[i].x+WALL_L))
		&&  (x < (room[i].x+(room[i].y_size-1)*WALL_L))
		&&  (y >= room[i].maxceiling)
		&&  (y <= room[i].minfloor)
		&&  (z >= (room[i].z+WALL_L))
		&&  (z < (room[i].z+(room[i].x_size-1)*WALL_L)))
			return i;
	}

	return -1;	// room not found
}

static void UpdateLaraGuns()
{
	uint16 flag, lr=0;
	PHD_VECTOR posl, posr, *pos=&posl;

	if ((lara.left_arm.flash_gun)
	||  (lara.right_arm.flash_gun)
	||  (SmokeCountL)
	||  (SmokeCountR))
	{
		posl.x = -12;
		posl.y = (PISTOLS_YOFF>>2)+16;
		posl.z = PISTOLS_ZOFF;
		GetJointAbsPosition(lara_item, &posl, HAND_L);

		posr.x = 8;
		posr.y = (PISTOLS_YOFF>>2)+16;
		posr.z = PISTOLS_ZOFF;
		GetJointAbsPosition(lara_item, &posr, HAND_R);
	}
	else
		return;

	if ((flag = lara.left_arm.flash_gun))
	{
//		lr = 0;
//		pos = &posl;
		lara.left_arm.flash_gun--;
	}
	else if ((flag = lara.right_arm.flash_gun))
	{
		lr = 1;
		pos = &posr;
		lara.right_arm.flash_gun--;
	}

	if (flag)
	{
		if (flag == 3)
		{
			sint16 fx_number;
			sint16 room_number;

		/* -------- trigger gunshell */

			room_number = GetCinematicRoom(pos->x, pos->y, pos->z);

			if ((fx_number = CreateEffect(room_number)) != NO_ITEM)
			{
				FX_INFO *fx;

				fx = &effects[fx_number];
				fx->pos.x_pos = pos->x;
				fx->pos.y_pos = pos->y;
				fx->pos.z_pos = pos->z;
				fx->room_number = room_number;
				fx->pos.y_rot = 0;
				fx->pos.x_rot = 0;
				fx->pos.z_rot = GetRandomControl();
				fx->speed = 16 + (GetRandomControl() & 31);
				fx->fallspeed = - 48 - (GetRandomControl() & 7);
				fx->object_number = GUNSHELL;
				fx->frame_number = objects[GUNSHELL].mesh_index;
				fx->shade = 0x4210;
				fx->counter = (GetRandomControl()&1) + 1;	// Number of bounces (1 or 2).
//				fx->flag1 = GetRandomControl() << 1;
			}

		/* -------- initialise smoke */

			if (lr)
				SmokeCountR = 28;
			else
				SmokeCountL = 28;
		}

	/* -------- initialise dynamic light */

		TriggerDynamic(
			pos->x + ((GetRandomControl()&255)-128),
			pos->y - ((GetRandomControl()&127)-63),
			pos->z + ((GetRandomControl()&255)-128),
			10,
			(GetRandomControl()&7)+24,
			(GetRandomControl()&3)+16,
			GetRandomControl()&7
		);
	}

	if (SmokeCountL)
	{
		TriggerGunSmoke(posl.x, posl.y, posl.z, 0, 0, 0, 0, LG_PISTOLS, SmokeCountL);
		SmokeCountL--;
	}

	if (SmokeCountR)
	{
		TriggerGunSmoke(posr.x, posr.y, posr.z, 0, 0, 0, 0, LG_PISTOLS, SmokeCountR);
		SmokeCountR--;
	}
}

static void LaraControlCinematic(sint16 item_num)
{
	PHD_VECTOR pos;
	ITEM_INFO	*item;
	sint16 room_number;
#ifdef GAMEDEBUG
	int x,y,z;
	sint16 *bounds;
#endif

	item = &items[item_num];
	item->pos.y_rot = camera.target_angle;	// Always Align a cut scene
	item->pos.x_pos = camera.pos.x;		// player with the Camera and
	item->pos.y_pos = camera.pos.y;		// align how far we are in the
	item->pos.z_pos = camera.pos.z;		// anim with current cine_frame

#ifndef GAMEDEBUG
// Get true pos using first object's pivot point ...?
	pos.x = 0;
	pos.y = 0;
	pos.z = 0;
	GetJointAbsPosition(item,&pos,0);
	room_number = GetCinematicRoom( pos.x, pos.y, pos.z );
#else
	bounds = GetBoundsAccurate( lara_item );
	x = (bounds[0]+bounds[1]) >>1;
	y = (bounds[2]+bounds[3]) >>1;
	z = (bounds[4]+bounds[5]) >>1;

	switch (GF_Cutscene_Orientation)
	{
		case 0:
			pos.x = lara_item->pos.x_pos + x;
			pos.y = lara_item->pos.y_pos + y;
			pos.z = lara_item->pos.z_pos + z;
			break;
		case 16384:
			pos.x = lara_item->pos.x_pos + z;
			pos.y = lara_item->pos.y_pos + y;
			pos.z = lara_item->pos.z_pos - x;
			break;
		case 32768:
			pos.x = lara_item->pos.x_pos - x;
			pos.y = lara_item->pos.y_pos + y;
			pos.z = lara_item->pos.z_pos - z;
			break;
		case 49152:
			pos.x = lara_item->pos.x_pos - z;
			pos.y = lara_item->pos.y_pos + y;
			pos.z = lara_item->pos.z_pos + x;
			break;
	}
	room_number = GetCinematicRoom( pos.x, pos.y, pos.z );
#endif

	if ((room_number != -1)
	&&  (item->room_number != room_number))
		ItemNewRoom(item_num,room_number);

	AnimateLara(item);
}

/******************************************************************************
 *				Initialise First CutScene Player (camera is aligned )
 *****************************************************************************/
static void InitialisePlayer1( sint16 item_num )
{
	ITEM_INFO 	*item;
//	sint16		*temp;
//	int i;
	OBJECT_INFO *obj;

	obj = &objects[LARA];
	obj->draw_routine = DrawDummyItem;  // Lara is drawn seperately!!!
	obj->control = LaraControlCinematic;
	obj->shadow_size = 0;

	AddActiveItem( item_num );
	lara_item = item = &items[item_num];
	camera.pos.x = item->pos.x_pos;	// initialise what Camera is relative to...
	camera.pos.y = item->pos.y_pos;
	camera.pos.z = item->pos.z_pos;
	camera.target_angle = item->pos.y_rot = 0;
	original_room = camera.pos.room_number = item->room_number;

	item->goal_anim_state = 0;
	item->current_anim_state = 0;
	item->frame_number = 0;
	item->anim_number = 0;
	item->dynamic_light = 0;
	lara.hit_direction = -1;

//	printf("Lara Item %d: room:%d\n", item_num,items[item_num].room_number);

/*	if ( cinematic_level==CUTSCENE2 || cinematic_level==CUTSCENE4 )	// Lara is Player One so make her Start with guns in Holster
	{
		temp = meshes[objects[PLAYER_1].mesh_index + THIGH_L];
		meshes[objects[PLAYER_1].mesh_index + THIGH_L] = meshes[objects[PISTOLS].mesh_index + THIGH_L];
		meshes[objects[PISTOLS].mesh_index + THIGH_L] = temp;
		temp = meshes[objects[PLAYER_1].mesh_index + THIGH_R];
		meshes[objects[PLAYER_1].mesh_index + THIGH_R] = meshes[objects[PISTOLS].mesh_index + THIGH_R];
		meshes[objects[PISTOLS].mesh_index + THIGH_R] = temp;
	}
*/
}

/*****************************************************************************
 *				Get Camera Position for Cinematics
 ****************************************************************************/
static void CalculateCinematicCamera()
{
	sint32		tx,ty,tz;
	sint32		cx,cy,cz;
	sint32		c,s;
	sint16		roll,fov;
	sint16		*ptr;
	PHD_VECTOR	campos,camtar;
//	PHD_VECTOR pos;
	int	room_number;
#ifdef MANUAL_CAMERA
	int			x,y,z;
#endif

	ptr = cine + (int)(8*cine_frame);
	tx = (sint32)*(ptr+0);
	ty = (sint32)*(ptr+1);
	tz = (sint32)*(ptr+2);
	cx = (sint32)*(ptr+3);
	cy = (sint32)*(ptr+4);
	cz = (sint32)*(ptr+5);
	fov = *(ptr+6);
	roll = *(ptr+7);

	c = phd_cos( camera.target_angle );									// Rotate Scene
	s = phd_sin( camera.target_angle );                                 // into backGround

//#ifdef MANUAL_CAMERA
//	camtar.x = camera.pos.x + ((tx*c + tz*s)>>W2V_SHIFT);
//	camtar.y = camera.pos.y + ty;
//	camtar.z = camera.pos.z + ((tz*c - tx*s)>>W2V_SHIFT);
//	campos.x = camera.pos.x + ((cx*c + cz*s)>>W2V_SHIFT);
//	campos.y = camera.pos.y + cy;
//	campos.z = camera.pos.z + ((cz*c - cx*s)>>W2V_SHIFT);
//#else
	camtar.x = lara_item->pos.x_pos + ((tx*c + tz*s)>>W2V_SHIFT);
	camtar.y = lara_item->pos.y_pos + ty;
	camtar.z = lara_item->pos.z_pos + ((tz*c - tx*s)>>W2V_SHIFT);
	campos.x = lara_item->pos.x_pos + ((cx*c + cz*s)>>W2V_SHIFT);
	campos.y = lara_item->pos.y_pos + cy;
	campos.z = lara_item->pos.z_pos + ((cz*c - cx*s)>>W2V_SHIFT);
//#endif

	if ((room_number = GetCinematicRoom( campos.x, campos.y, campos.z ))>=0)
		camera.pos.room_number = room_number;

#ifdef MANUAL_CAMERA
	mycam.x_pos = campos.x;
	mycam.y_pos = campos.y;
	mycam.z_pos = campos.z;
	mycam.z_rot = roll;
	x = campos.x-camtar.x;
	y = campos.y-camtar.y;
	z = campos.z-camtar.z;
	mycam_distance = phd_sqrt(x*x + z*z);
	mycam.y_rot = phd_atan(z,x);
	mycam.x_rot = phd_atan(mycam_distance,y);
#endif
	AlterFOV( fov );
	phd_LookAt( campos.x, campos.y, campos.z, camtar.x, camtar.y, camtar.z, roll );
#ifdef PSX_VERSION
	mQuickW2VMatrix();
#endif
}

/****************************************************************************
 *					Play Cinematic CutScene
 ***************************************************************************/
static sint32 DoCinematic(sint32 nframes)
{
	sint16 		item_num,nex;
	static int	framecount = 0;

#ifdef PAL
	framecount += nframes * 6;
	for ( ; framecount>=0; framecount-=10 )
#else
	framecount += nframes;
	for ( ; framecount>0 ; framecount-=2 )
#endif

	{
#ifdef PC_VERSION
		if (S_UpdateInput())
			return 3;					// do an EXITGAME because the window has been closed!
#else
		S_UpdateInput();
#endif

		if (input & IN_ACTION)			// hit action to leave cinematic sequence on psx...
			return (1);
#ifdef PSX_VERSION
		if (input & IN_PAUSE)			// hit start to leave story so far sequence on psx...
			return (2);

#ifdef GAMEDEBUG
		if (input & IN_BACK)
		{
			while (input & IN_BACK)
				S_UpdateInput();
		}
#endif
#else
		if ( input&IN_OPTION)			// hit esc to leave story so far sequence on psx...
			return (2);
#endif

		ClearDynamics();

	/* Call control routines for active items on linked list (can create/destroy items) */
		item_num = next_item_active;
		while ( item_num!=NO_ITEM )
		{
			nex = items[item_num].next_active;
			if ( objects[items[item_num].object_number].control )
				(*objects[items[item_num].object_number].control)(item_num);
			item_num = nex;
		}

	/* Call control routines for active effects on linked list (can create/destroy items) */
		item_num = next_fx_active;
		while ( item_num!=NO_ITEM )
		{
			nex = effects[item_num].next_active;
			if ( objects[ effects[item_num].object_number ].control )
				(*objects[ effects[item_num].object_number ].control)(item_num);
			item_num = nex;
		}

		UpdateLaraGuns();

		UpdateSparks();

		HairControl(1);

#ifdef MANUAL_CAMERA
		if (useCineCam)
#endif
		CalculateCinematicCamera();
		cine_frame++;
		if ( cine_frame>=num_cine_frames )			// Return True If Finished Playing Cinematics
			return(1);
	}

#ifdef PSX_VERSION
//	actual_current_frame = S_CDGetLoc() / 32;
	actual_current_frame = 200;
#else
	actual_current_frame=(S_CDGetLoc()*4)/5; // Get 75Hz CDLoc in current track
#endif

#if defined(PSX_VERSION) && defined(GAMEDEBUG)
	if (InfoFlag)
	{
		sprintf(exit_message,"Cine %d Actual %d Dif %d",cine_frame*2, (int)actual_current_frame, (int)((cine_frame*2)-actual_current_frame-CINE_ADJUST));
		PrintDbug(1, 2, exit_message);
	}
#endif

	return 0;
}


/*---------------------------------------------------------------------------
 *	Public Functions
\*--------------------------------------------------------------------------*/

sint32 DrawPhaseCinematic()
{
#ifndef PC_VERSION
	S_InitialisePolyList();
	S_ClearScreen();
#endif
	camera_underwater = 0;                    // No underwater cameras

	DrawRooms(camera.pos.room_number);

	S_DrawSparks();

#if defined(GAMEDEBUG) || defined(SHOW_ROOM_INFO)
	T_DrawText();
#endif
	S_OutputPolyList();

	camera.number_frames = S_DumpScreen();

#ifdef PC_VERSION
	if (S_DumpCine() == 1)
		camera.number_frames = 2;
#endif

#ifdef SAVE_CINI
	camera.number_frames = 2;
	S_SavePicture();
#endif

	S_AnimateTextures(camera.number_frames);

	return (camera.number_frames);
}

/******************************************************************************
 *				Initialise General player
 *****************************************************************************/
void InitialiseGenPlayer(sint16 item_num)
{
	AddActiveItem( item_num );
	items[item_num].pos.y_rot = 0;
	items[item_num].dynamic_light = 0;
}

/******************************************************************************
 *					Start A Cinematic Cut-Scene
 *****************************************************************************/
sint32 StartCinematic(int level_number)
{
	int saved_music_vol;
	int saved_sound_active;
	sint32 nframes, cine_over;

#ifdef GAMEDEBUG
	int nPaused=0, nPausedDebounce=0, nAdvanceDebounce=0;
	nPaused=nPausedDebounce=nAdvanceDebounce=0;
#endif

	title_loaded = 0;
	cinematic_level = level_number;

#ifdef PC_VERSION
//##	S_FadeToBlack();
#endif

//##	if (!InitialiseLevel( level_number, IL_CUTSCENE))
//##		return(END_ACTION);
	InitCinematicRooms();

#ifdef PSX_VERSION
	saved_music_vol = Option_Music_Volume;		// Use SoundFX Volume for Cutscenes
	Option_Music_Volume = Option_SoundFX_Volume;
#ifdef PLAY_CDTRACKS
	CDDA_SetMasterVolume(255);				// Set Volume of CD on PlayStation
#endif
#endif

	InitialisePlayer1(lara.item_number);

	// Start Audio!!!
	camera.target_angle = GF_Cutscene_Orientation;
	saved_sound_active = sound_active;
	sound_active = 0;
	cine_frame = 0;

	S_ClearScreen();

#ifdef PC_VERSION
	if (!S_StartSyncedAudio( cutscene_track ))
		return 1;
	S_CDVolume(255); // set volume of CD to max for cutscene
#else
	S_StartSyncedAudio( cutscene_track );
#endif

#ifdef MANUAL_CAMERA
	useCineCam = 1;
#endif

#ifdef PSX_VERSION
	fades_enabled = 0;

//	S_Wait(16);
//	GPU_ResetLastFrameCount();
//	actual_start_frame = GPU_GetFrameCount();

//	DoCinematic(2);
	actual_current_frame = 0;
#else
	//DoCinematic(2);
	//S_DumpScreen();
	actual_current_frame = 0;
#endif

/* -------- Cinematic loop */

	GnGameMode = GAMEMODE_IN_CUTSCENE;

	GnLastFrameCount=0;

	do {
		DrawPhaseCinematic();

		nframes = camera.number_frames;

#ifdef PC_VERSION
		if(framedump)
			nframes = 2;
#endif
		cine_over = DoCinematic(nframes);

	} while (!cine_over);

	GnGameMode = GAMEMODE_NOT_IN_GAME;

/* -------- end cinematic stuff */

#ifdef PSX_VERSION
	fades_enabled = 1;
	DrawSync(0);				// added by del... to fix gpu timeout..
	XAFade(0);
	XAWaitFade();

	Option_Music_Volume = saved_music_vol;

#ifdef PLAY_CDTRACKS
//	CDDA_SetMasterVolume(200);	// Set Volume of CD on PlayStation
#endif
#else
	// reset CD audio to users chosen in game level
	if (Option_Music_Volume)
		S_CDVolume(Option_Music_Volume*25 + 5);
	else
		S_CDVolume(0);
#endif
	S_CDStop();

	sound_active = saved_sound_active;
	S_SoundStopAllSamples();			// Stop any remaining samples
	level_complete = 1;				// Indicate weve finished with this level

	return(cine_over);
}


void	ControlCinematicPlayer( sint16 item_num )
{
	ITEM_INFO	*item;
	PHD_VECTOR pos;
	sint16	room_number;

#ifdef GAMEDEBUG
	sint16 *bounds;
	int		x,y,z;
#endif


//	CRASH_TELL( __FILE__, __LINE__ );

	item = &items[item_num];
	item->pos.y_rot = camera.target_angle;		// Always Align a cut scene
	item->pos.x_pos = camera.pos.x;             // player with the Camera
	item->pos.y_pos = camera.pos.y;             // and align how far we are in animation
	item->pos.z_pos = camera.pos.z;             // with current cine_frame...

//	room_number = item->room_number;

#ifndef GAMEDEBUG
	// Get true pos using first object's pivot point ...?
	pos.x = 0;
	pos.y = 0;
	pos.z = 0;
	GetJointAbsPosition(item,&pos,0);
	room_number = GetCinematicRoom( pos.x, pos.y, pos.z );
#else
	bounds = GetBoundsAccurate( item );
	x = (bounds[0]+bounds[1]) >>1;
	y = (bounds[2]+bounds[3]) >>1;
	z = (bounds[4]+bounds[5]) >>1;
	switch (GF_Cutscene_Orientation)
	{
		case 0:
			pos.x = lara_item->pos.x_pos + x;
			pos.y = lara_item->pos.y_pos + y;
			pos.z = lara_item->pos.z_pos + z;
			break;
		case 16384:
			pos.x = lara_item->pos.x_pos + z;
			pos.y = lara_item->pos.y_pos + y;
			pos.z = lara_item->pos.z_pos - x;
			break;
		case 32768:
			pos.x = lara_item->pos.x_pos - x;
			pos.y = lara_item->pos.y_pos + y;
			pos.z = lara_item->pos.z_pos - z;
			break;
		case 49152:
			pos.x = lara_item->pos.x_pos - z;
			pos.y = lara_item->pos.y_pos + y;
			pos.z = lara_item->pos.z_pos + x;
			break;
	}
	room_number = GetCinematicRoom( pos.x, pos.y, pos.z );
#endif

//	GetFloor(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, &room_number);
	if (room_number!=-1 && item->room_number!=room_number)
		ItemNewRoom(item_num,room_number);

	if ( item->dynamic_light && item->status!=INVISIBLE )
	{
		pos.x = 0;
		pos.y = 0;
		pos.z = 0;
		GetJointAbsPosition(item,&pos,0);
//		AddDynamicLight(pos.x, pos.y, pos.z, 12, 11 );
	}
	AnimateItem( item );
}

/******************************************************************************
 ******************************************************************************
 *	Pre-Calculated Camera Movement and Action for In-Game stuff
 ******************************************************************************
 *****************************************************************************/
void	InGameCinematicCamera( void )
{
	sint32		c,s;
	sint32		tx,ty,tz;
	sint32		cx,cy,cz;
	sint16		roll,fov;
	sint16		*ptr;

	cine_frame++;
	if ( cine_frame>=num_cine_frames )
		cine_frame = num_cine_frames-1;

	ptr = cine + (int)(8*cine_frame);
	tx = (sint32)*(ptr+0);
	ty = (sint32)*(ptr+1);
	tz = (sint32)*(ptr+2);
	cx = (sint32)*(ptr+3);
	cy = (sint32)*(ptr+4);
	cz = (sint32)*(ptr+5);
	fov = *(ptr+6);
	roll = *(ptr+7);

	c = phd_cos( cinematic_pos.y_rot );
	s = phd_sin( cinematic_pos.y_rot );
	camera.target.x = cinematic_pos.x_pos + ((tx*c + tz*s)>>W2V_SHIFT);
	camera.target.y = cinematic_pos.y_pos + ty;
	camera.target.z = cinematic_pos.z_pos + ((tz*c - tx*s)>>W2V_SHIFT);
	camera.pos.x = cinematic_pos.x_pos + ((cx*c + cz*s)>>W2V_SHIFT);
	camera.pos.y = cinematic_pos.y_pos + cy;
	camera.pos.z = cinematic_pos.z_pos + ((cz*c - cx*s)>>W2V_SHIFT);

	AlterFOV( fov );
	phd_LookAt( camera.pos.x, camera.pos.y, camera.pos.z, camera.target.x, camera.target.y, camera.target.z, roll );
	GetFloor(camera.pos.x, camera.pos.y, camera.pos.z, &camera.pos.room_number);		// Update Cameras Room

#ifdef PC_VERSION
	if (camera.mike_at_lara)
	{
		camera.actual_angle=lara_item->pos.y_rot+lara.head_y_rot+lara.torso_y_rot;
		camera.mike_pos.x=lara_item->pos.x_pos;
		camera.mike_pos.y=lara_item->pos.y_pos;
		camera.mike_pos.z=lara_item->pos.z_pos;
	}
	else
#endif
	{
		camera.actual_angle = phd_atan(camera.target.z - camera.pos.z, camera.target.x - camera.pos.x);
		camera.mike_pos.x=camera.pos.x+((phd_persp*phd_sin(camera.actual_angle))>>W2V_SHIFT);
		camera.mike_pos.z=camera.pos.z+((phd_persp*phd_cos(camera.actual_angle))>>W2V_SHIFT);
		camera.mike_pos.y=camera.pos.y;
	}
}

#ifdef GAMEDEBUG
void SetCutscene(int cut)
{
	cutscene_play = cut-1;
	cutscene_track = cut+1;
}

void SetCutsceneAngle( int angle )
{
	GF_Cutscene_Orientation =(uint16) angle*0x4000;
}
#endif


