#define D_CineInfo_StructureDefine
 
#include "ToolsCPA.h"
#include "Structur/State.h"
#include "Actions/AllActs.h"
#include "Actions/collset.h"
#include "structur/StdObjSt.h"
#include "structur/engmode.h"
#include "structur/objects.h"
#include "structur/MemGame.h"
#include "GameEng.h"
#include "ObjType.h"
#include "ia_dnm.h"
#include "ToolCam.h"
 
#ifdef SOUND_FOR_3DOS
#include "Micros.h"
#endif
 
#include "TypeCam.h"
#include "ToolMatr.h"
#include "collisio.h"
#include "ZdxStuff.h"
#include "ZeMem.h"
 
/****************************/
/* ANNECY MT - 14/09/98 { to display info on Wnd screen*/
#if defined(USE_PROFILER) && !defined(PRESS_DEMO)
	extern void DisplayPolices (char * _szText , long _lX , long _lY);
	#define GLI_vDisplayPolices(Text,X,Y)		DisplayPolices((char*)(Text),X,Y)
#endif
/* END ANNECY MT }*/
/****************************/
 
 
/* ANNECY AV DEMO {*/
#ifndef U64
    #include "Specif/Demos.h"
#endif
/* END ANNECY AV }*/
 
/*
 *=================================================================================================
 *	Get pointer on the ViewportManagement Structure
 *=================================================================================================
 */
tdxHandleToViewportManagement CAM_fn_p_stGetViewPortManagement(long _lViewportNumber)
{
	if
	(
		(_lViewportNumber > CAM_Nb_Viewport)
	||	(_lViewportNumber == (long) CAM_e_NoViewport)
	)
		return NULL;
	else
		return(&g_stEngineStructure.a_hViewportArray[_lViewportNumber - 1]);
}
 
/*
 *=================================================================================================
 *	Return handle of game's camera and pointer on camera's structur
 *=================================================================================================
 */
HIE_tdxHandleToSuperObject CAM_fn_hGetActiveCamera(long _lViewportNumber)
{
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	tdxHandleToViewportManagement	hViewport;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 
	hViewport = CAM_fn_p_stGetViewPortManagement(_lViewportNumber);
	return (hViewport->hCamera);
}
 
/*
 *=================================================================================================
 *	Assign a camera to a viewport
 *=================================================================================================
 */
void CAM_fn_vAssignCameraToAViewport(long _lViewportNumber, HIE_tdxHandleToSuperObject _hCamera)
{
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	tdxHandleToViewportManagement	hViewport;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 
	hViewport = CAM_fn_p_stGetViewPortManagement(_lViewportNumber);
	hViewport->hCamera = _hCamera;
	hViewport->bValid = TRUE;
}
 
/*
 *=================================================================================================
 *	Reinitialization of camera's lists
 *=================================================================================================
 */
void CAM_fn_vReInitCameras(void)
{
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
    long							i;
    tdstNodeCamera					*p_stTempNodeCamera;
    tdstNodeCamera					*p_stNextNodeCamera;
	HIE_tdxHandleToSuperObject		hSuperObject ;
	tdxHandleToViewportManagement	hViewport;
    MS_tdxHandleToInternalCineinfo	hIntCineinfo;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 
	/* Some inits */
	for (i = 1; i <= CAM_Nb_Viewport; i++)
	{
		hViewport = CAM_fn_p_stGetViewPortManagement(i);
		hViewport->hTempCamera = NULL;
		hViewport->bValid = FALSE;
	}
 
	LST2_M_DynamicForEachMovingElementOf(&g_stEngineStructure.hCameraList,p_stTempNodeCamera, p_stNextNodeCamera, i)
    {
       if (p_stTempNodeCamera != NULL)
       {
			/* Search the SuperObject with HIE_C_ulActor type */
			hSuperObject=p_stTempNodeCamera->p_stSuperObjectCamera;
			hIntCineinfo = M_GetCineinfo(hSuperObject,Init);
			if
			(
				(hIntCineinfo -> bIsActive)
			&&	(hIntCineinfo -> eTypeOfViewport != CAM_e_NoViewport)
			)
			{
				CAM_fn_vAssignCameraToAViewport
				(
					hIntCineinfo -> eTypeOfViewport,
					hSuperObject
				);
			}
		}
	}
}
 
/*
 *=================================================================================================
 *	Initialization of camera's lists
 *=================================================================================================
 */
extern void	CAM_fn_vLoadCameraConstants(void);
void CAM_fn_vInitCameras(void)
{
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	long							lSize;
    long							i;
	tdxHandleToViewportManagement	hViewport;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 
	/* Allocation */
	lSize = sizeof(struct tdstViewportManagement_) * CAM_Nb_Viewport;
    MMG_fn_vAddMemoryInfo( MMG_C_lTypeGAM , MMG_C_lSubTypeViewPortArray , 0 );
	g_stEngineStructure.a_hViewportArray = (tdxHandleToViewportManagement)M_p_GameMallocInHLM(lSize);
 
	CAM_fn_vReInitCameras();
 
	for (i = 1; i <= CAM_Nb_Viewport; i++)
	{
		hViewport = CAM_fn_p_stGetViewPortManagement(i);
		GLI_xCreateCamera(&hViewport->p_stCamera,GLI_C_lPersCamWithoutDistorsion);
		/*GLI_xSetCameraAspectAndRatio(hViewport->p_stCamera, MTH_M_xFloatToReal(1.5f), MTH_C_ONE);*/
    GLI_xSetCameraAspectAndRatio(hViewport->p_stCamera, MTH_M_xFloatToReal(1.5f), MTH_M_xFloatToReal(0.75f));
	}
 
	CAM_fn_vLoadCameraConstants();
}
 
/*
 *=================================================================================================
 *	Test if the super object is a camera
 *=================================================================================================
 */
ACP_tdxBool CAM_fn_bSuperObjectIsACamera(HIE_tdxHandleToSuperObject _h_SprObj)
{
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
    MS_tdxHandleToCineinfo	h_Cineinfo;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 
	if(HIE_fn_ulGetSuperObjectType(_h_SprObj) != HIE_C_ulActor)
	   return FALSE;
	else
	{
 
		h_Cineinfo = M_GetMSHandle(_h_SprObj,Cineinfo);
		if ((struct tdstCineinfo_ *) h_Cineinfo == NULL)
			return FALSE;
		else
			return TRUE;
	}
}
 
/*
 *=================================================================================================
 *	Actualize a viewport
 *=================================================================================================
 */
void CAM_fn_vActualizeAViewport(long _lViewport)
{
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	tdxHandleToViewportManagement	hViewport;
	struct GLI_tdstCamera_			*p_Camera;
	POS_tdstCompletePosition		stMatrix;
	MTH_tdxReal						xAngle,xRatio, xFocal;
	MTH3D_tdstVector				I,J,K;
	POS_tdstCompletePosition		*p_stCamera;
	HIE_tdxHandleToSuperObject		hCamera;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 
	hViewport = CAM_fn_p_stGetViewPortManagement(_lViewport);
	hCamera = hViewport->hCamera;
 
	p_stCamera = HIE_fn_hGetSuperObjectGlobalMatrix(hCamera);
 
	POS_fn_vGetRotationMatrix( p_stCamera, &I, &J, &K );
/*	POS_fn_vSetType(&stMatrix, POS_C_xCompletePosition);*/
 
	POS_fn_vCopyMatrix( &stMatrix, p_stCamera );
 
	MTH3D_M_vNegVector( &J, &J );
	POS_fn_vSetRotationMatrix( &stMatrix, &I, &K, &J );
	POS_fn_vInvertIsoMatrix( &stMatrix, &stMatrix );
 
#if defined(WIN32)
    WaitForSingleObject(g_stEngineStructure.hDrawSem, INFINITE);
#endif /*WIN32*/
 
	p_Camera = hViewport->p_stCamera;
	GLI_xSetCameraMatrix(p_Camera, &stMatrix);
	GLI_xGetCameraAspectAndRatio(p_Camera, &xAngle, &xRatio);
	xFocal = M_GetMSHandle(hCamera, Cineinfo)->hWork->xFocal;
 
	if (MTH_M_bIsNull(xFocal))
		xFocal = M_GetMSHandle(hCamera, Cineinfo)->hCurrent->xFocal;
 
	if (!MTH_M_bEqual(xFocal, xAngle))
	{
		GLI_xSetCameraAspectAndRatio(p_Camera, xFocal, xRatio);
/* XB 23/06/99 */	
#ifndef U64
		GLI_xSetViewportCamera(g_stEngineStructure.hGLDDevice, g_stEngineStructure.hGLDViewport, p_Camera);
		GLI_xAdjustCameraToViewport(g_stEngineStructure.hGLDDevice, g_stEngineStructure.hGLDViewport, p_Camera);
#else /* U64 */
		GLI_xSetViewportCamera(NULL, NULL, p_Camera);
		GLI_xAdjustCameraToViewport(NULL, NULL, p_Camera);
#endif /* U64 */
/* End XB 23/06/99 */	
	}
	else
/* XB 23/06/99 */	
#ifndef U64
		GLI_xSetViewportCamera(g_stEngineStructure.hGLDDevice, g_stEngineStructure.hGLDViewport, p_Camera);
#else /* U64 */
		GLI_xSetViewportCamera(NULL, NULL, p_Camera);
#endif /* U64 */
/* End XB 23/06/99 */	
 
 
#if defined(WIN32)
	ReleaseSemaphore(g_stEngineStructure.hDrawSem,1,NULL);
#endif /*WIN32*/
}
 
/*
 *=================================================================================================
 *	Management of all cameras in the game
 *=================================================================================================
 */
void CAM_fn_vCameraManagement(void)
{
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	tdxHandleToNodeCamera			p_stNodeCamera;
	long							i;
	tdxHandleToViewportManagement	hViewport;
	HIE_tdxHandleToSuperObject		hCamera;
	MS_tdxHandleToInternalCineinfo	hIntCineinfo;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 
	/*
	 * Treat each camera.
	 */
/* ANNECY AV DEMO {*/
#ifndef U64
    if(g_DEMO_KeybTest != DEMO_PLAY)
#endif
/* END ANNECY AV }*/
    {
	    LST2_M_DynamicForEachElementOf(&g_stEngineStructure.hCameraList, p_stNodeCamera, i)
	    {
		    if (p_stNodeCamera != NULL)
		    {
			    hCamera = p_stNodeCamera->p_stSuperObjectCamera;
			    if(M_GetMSHandle(hCamera, Cineinfo)->ucVolIAFlags & C_VolIAFlags_CurrentAlreadyCopiedInWork)
			    {
				    hIntCineinfo = M_GetCineinfo(hCamera, Work);
			    }
			    else
			    {
				    hIntCineinfo = M_GetCineinfo(hCamera, Current);
			    }
			    if((hIntCineinfo->bIsActive) || (hIntCineinfo->eTypeOfViewport != CAM_e_NoViewport))
			    {
				    if(hIntCineinfo->eTypeOfViewport != CAM_e_NoViewport)
					    fn_vTreatCameraHierarchy(p_stNodeCamera->p_stSuperObjectCamera, TRUE);
				    else
					    fn_vTreatCameraHierarchy(p_stNodeCamera->p_stSuperObjectCamera, FALSE);
			    }
		    }
	    }
    }
 
	 /*
	  * Actualise all viewports.
	  */
	 for(i = CAM_Nb_Viewport; i > 0; i--)
	 {
		hViewport = CAM_fn_p_stGetViewPortManagement(i);
		if(hViewport->bValid)
			CAM_fn_vActualizeAViewport(i);
	 }
}
 
/*
 *=================================================================================================
 *	Display camera parameters
 *=================================================================================================
 */

#if !defined(PRESS_DEMO)

void CAM_vDisplayInfo(void)
{
#ifndef RETAIL
#ifndef U64
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
    MS_tdxHandleToDynam				h_Dynam = NULL;
    DNM_tdstDynamics				*p_stDynamics = NULL;
	DNM_tdstReport					*p_stReport = NULL;
	MTH_tdxReal						xNorm;
	MTH3D_tdstVector				stShifting;
	unsigned char					szLine[100];
	long							lX;
	long							lY;
	MTH3D_tdstVector				*p_stTarget;
	HIE_tdxHandleToSuperObject		pSuperObjectCamera;
	MS_tdxHandleToCineinfo			hCineInfo;
	MS_tdxHandleToInternalCineinfo	hWorkCI;
	MTH3D_tdstVector				stSightAxis;
	MTH3D_tdstVector				stFirstComplementaryAxis;
	MTH3D_tdstVector				stSecondComplementaryAxis;
	MTH3D_tdstVector				stTempVector, stTempVector1, stTempVector2;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 
	pSuperObjectCamera = CAM_fn_hGetActiveCamera(CAM_e_MainViewport);
	hCineInfo = M_GetMSHandle(pSuperObjectCamera, Cineinfo);
	h_Dynam = M_GetMSHandle(pSuperObjectCamera, Dynam);
	if(h_Dynam)
		p_stDynamics = fn_p_stDynamGetDynamics(h_Dynam);
	if(p_stDynamics)
		p_stReport = DNM_M_p_stDynamicsGetReport(p_stDynamics);
 
	if (!(hCineInfo->ucPerIAFlags & C_PerIAFlags_ShowInfo))
		return;
 
	hWorkCI = hCineInfo->hWork;
 
	lX = 320;
	lY = 0;
 
	p_stTarget = &hWorkCI->stShiftTarget;
	sprintf ((char *) szLine, "ShiftTgt²²²²²%.2f²%.2f²%.2f", p_stTarget->xX, p_stTarget->xY, p_stTarget->xZ);
	GLI_vDisplayPolices(szLine, lX , lY);
	lY += 16;
 
	p_stTarget = &hWorkCI->stShiftPos;
	sprintf ((char *) szLine, "ShiftPos²²²²²%.2f²%.2f²%.2f", p_stTarget->xX, p_stTarget->xY, p_stTarget->xZ);
	GLI_vDisplayPolices(szLine, lX , lY);
	lY += 16;
 
	sprintf((char *) szLine, "Distance²²²²²²%.2f²%.2f²%.2f²%.2f", hWorkCI->xDistMin, hWorkCI->xDistMax, hWorkCI->xBoundDistMin, hWorkCI->xBoundDistMax);
	GLI_vDisplayPolices(szLine, lX , lY);
	lY += 16;
 
	sprintf ((char *) szLine, "Alpha²²²²²²²²%.2f²%.2f", hWorkCI->xAngleAlpha, hWorkCI->xAngleShiftAlpha);
	GLI_vDisplayPolices(szLine, lX , lY);
	lY += 16;
 
	sprintf ((char *) szLine, "Theta²²²²²²²²%.2f²%.2f", hWorkCI->xAngleTheta, hWorkCI->xAngleShiftTheta);
	GLI_vDisplayPolices( szLine, lX , lY);
	lY += 16;
 
	sprintf ((char *) szLine, "ZMinMax²²²²²²%.2f²%.2f", hWorkCI->xZMin, hWorkCI->xZMax);
	GLI_vDisplayPolices( szLine, lX , lY);
	lY += 16;
 
	/* Sight axis of targeted perso */
	if(hWorkCI->hSuperObjectTargeted)
	{
		fn_vGetPersoSightAxisSystem
		(
			hCineInfo,
			&stSightAxis,
			&stFirstComplementaryAxis,
			&stSecondComplementaryAxis
		);
		sprintf((char *) szLine, "Sight²²²²²²²²%.2f²%.2f²%.2f", stSightAxis.xX, stSightAxis.xY, stSightAxis.xZ);
		GLI_vDisplayPolices(szLine, lX , lY);
		lY += 16;
	}
 
	/* Delta T */
	sprintf((char *) szLine, "DeltaT²²²²²²²%.4f", M_xGetUsefulDeltaTimeInSeconds(g_stEngineStructure.stEngineTimer));
	GLI_vDisplayPolices(szLine, lX , lY);
	lY += 16;
 
	/* Real move camera */
	if(p_stReport != NULL)
	{
		MTH3D_M_vCopyVector(&stShifting, DNM_M_p_stReportGetLastMove(p_stReport));
		xNorm = MTH3D_M_xNormVector(&stShifting);
 
		sprintf((char *) szLine, "RealMove²²²²²%.4f", xNorm);
		GLI_vDisplayPolices(szLine, lX , lY);
		lY += 16;
	}
 
	/* Distance to target */
	if(hWorkCI->hSuperObjectTargeted)
	{
		if (hWorkCI->hSuperObjectTargeted)
		{
			POS_fn_vGetTranslationVector
			(
				HIE_fn_hGetSuperObjectGlobalMatrix(pSuperObjectCamera),
				&stTempVector1
			);
			CAM_fn_vAveragePosition(hCineInfo, CAM_g_stCameraConstants.xAverageForComputePos, &stTempVector);
			POS_fn_vGetTranslationVector
			(
				HIE_fn_hGetSuperObjectGlobalMatrix(hWorkCI->hSuperObjectTargeted),
				&stTempVector2
			);
			MTH3D_M_vSubVector(&stTempVector, &stTempVector, &stTempVector1);
			MTH3D_M_vSubVector(&stTempVector2, &stTempVector2, &stTempVector1);
 
			sprintf((char *) szLine, "DAver²DReal²²%.2f %.2f", MTH3D_M_xNormVector(&stTempVector), MTH3D_M_xNormVector(&stTempVector2));
		}
		GLI_vDisplayPolices(szLine, lX , lY);
		lY += 16;
	}
#endif /*!U64*/
#endif /*!RETAIL*/
}

#endif /* PRESS_DEMO */
 
 
