/*=========================================================================
* GameEng.cpp : Engine of Game
*             It is in this file that the SuperObject Tree is explored.
* This is a part of the Game project.
*
* Version                      1.0
* Creation date        22/08/96
* Revision date
*
* That file needs to be compatible for all platforms.
*
* (c) Ubi Studios 1996
*====d==============================================u======dd======d=========*/
/*
*=======================================================================
Modifications: New LST_M_??? Macros / Michaël / 070297
*=======================================================================*/
#define D_CineInfo_StructureDefine
 
#include "ToolsCPA.h"
 
/* Oliv' - Portage v14 - ah ah ah... - vous n'avez jamais pensé au #ifdef PC ??*/
#ifndef U64
#include "X:\cpa\tempgrp\GLIGLOU\MULTIDRV\inc\PvObj_st.h"
#include "X:\CPA\tempgrp\GLIGLOU\MULTIDRV\inc\linear.h"
#endif
/* EndOfOliv'*/
 
#include "input.h"
 
#include "gli.h"
#include "tex.h"
/* SOUND*/
#include "SND.h"
/* SOUND fin*/
 
#include "Options/LightOpt.h"
#include "Macros.h"
 
#include "Structur/Input_s.h"
 
#include "Ai\AiBase\WPEngDsp.h"
 
#include "safe.h" /*BART*/
 
#include "SCT.h"
 
#include "GAM.h"
#include "Main.h"
 
#include "DspFix.h"
#include "ToolCam.h"
#include "ToolMatr.h"
#include "ZdxStuff.h"
#include "PhysiCol.h"
#include "MainChar.h"
#include "Effect.h"
#include "AlwAct.h"
/*#include "GamExtra.h"*/
/*XB980824*/
#ifndef D_THROW_MGT
#include "Mgt.h"
#endif /* D_THROW_MGT */
/*End XB*/
#include "DspFix.h"
 
#if defined(U64)
#include "rcptask.h"
#endif /* U64 */
 
#include "PRF.h"
#if defined(USE_PROFILER) && !defined(PRESS_DEMO)
extern void GAM_fn_vPrepareShowRasters (unsigned long);
extern void GAM_fn_vShowRasters();
extern void GAM_fn_vSlowDownEngine (unsigned long);
extern void GLI_fn_vShowFrameRate( GLD_tdstViewportAttributes *_p_stViewport );
#else
#define GLI_fn_vShowFrameRate(V)
#endif /* USE_PROFILER && PRESS_DEMO */
#if defined(_DEBUG)
 
/* ANNECY AV DEMO {*/
#ifndef U64
    #include "Specif/Demos.h"
#endif
/* END ANNECY AV }*/
 
/*--- For displaying Waypoints and Sector infos ---*/
extern unsigned char g_ucWhatDoIDisplay;
extern unsigned char g_ucZDCVisible;
extern char          * g_szZoneTypes[5];
extern char          * g_szDisplayTypes[2];
extern unsigned char g_ucDisplayWaypoints;
extern unsigned char g_ucSCTDisplaySectors;
extern void SECT_vDisplaySectorInfos(void);
 
extern unsigned char g_ucDisplayBoundingVolumes;
 
/* ANNECY CG KEY 4 ACTIVATED GENDOORS 18/06/98 {*/
extern unsigned char g_ucDisplayActivatedGendoors;
 
#if !defined(U64) && defined(_DEBUG)
extern unsigned char g_ucDisplayRayTraceSegments;
extern MTH3D_tdstVector g_stRayTraceSegmentOrigin[30];
extern MTH3D_tdstVector g_stRayTraceSegmentEnd[30];
extern short g_wRayTraceSegmentLife[30];
unsigned char g_ucSlowDownEngine;
unsigned char g_ucSlowDownTime;
#endif /* !U64 && _DEBUG */
 
/* } ENDANNECY CG*/
 
#endif	/*_DEBUG*/
 
/* Oliv' - 19/05/1999 - I want to see Zdx too */
#if defined(_U64_GLI_BENCH_)
	extern unsigned char g_ucZDCVisible;
	extern char          * g_szZoneTypes[5];
	extern ACP_tdxBool GLIBENCH_g_bWireFrame;
#endif /* _U64_GLI_BENCH_ */
/* EndOfOliv' */

#if defined(WIN32) && !defined(RETAIL) && !defined(PRESS_DEMO)
int GAM_g_iStepMode = -1 ;
#define M_IfCanDoFullStep() if ( GAM_g_iStepMode != 0 )
#define M_FullStepDone() ( ( void ) ( ( GAM_g_iStepMode > 0 ) ? ( -- GAM_g_iStepMode ) : GAM_g_iStepMode ) )
#define M_bIfIsNotStepping() if ( GAM_g_iStepMode == -1 )
#define M_bIfIsStepping() if ( GAM_g_iStepMode != -1 )
#else
#define M_IfCanDoFullStep() if ( 1 )
#define M_FullStepDone()
#define M_bIfIsNotStepping() if ( 1 )
#define M_bIfIsStepping() if ( 0 )
#endif /* WIN32 && !RETAIL */

#ifndef RETAIL 

/*--- for displaying choice of level*/
extern char g_cChooseLevel;

#endif /* !RETAIL */
 
extern void GLI_fnv_DrawRectangle( struct GLD_tdstViewportAttributes_ *p_stVpt, MTH3D_tdstVector *p_stFirstPoint, MTH3D_tdstVector *p_stLastPoint, long lColor );
/* XB 05/05/99 */
#ifdef U64
extern void MOR_fn_vUnLockAllMorphTasks(void);
extern void fn_vDisplaySky( GLD_tdstViewportAttributes *_p_stViewport);
extern void GLI_vPrintGuruError( int Y, char *p_szErrorString );
#include "INO\Specif\u_cont.h"
#endif /* U64 */
#ifdef WIN32
extern ACP_tdxBool fn_bDisplaySky( HIE_tdxHandleToSuperObject hSOSector, HIE_tdxHandleToSuperObject hSOCamera, GLD_tdstViewportAttributes *_p_stViewport );
#endif
/* End XB 05/05/99 */
 
/****************************/
/* functions declarations*/
/* See Olivier for details and comments*/
/****************************/
#if !defined(PRESS_DEMO)
ACP_tdxBool fn_bEdNOCLIP(HIE_tdxHandleToSuperObject hCharacter);
#endif /* PRESS_DEMO */
void fn_vTreatCharactersInSector(HIE_tdxHandleToSuperObject hCharacter);
extern void GEO_fn_vMorphAddInMainLoop();
 
void fn_vUpdateDynamicHierarchy();
 
/****************************/
/* 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)
#if !defined(U64)
	extern void GAM_fn_vRasterDump();
	extern void GAM_fn_vRasterDumpUpdate(unsigned long,unsigned long,unsigned long,unsigned long,unsigned long);
	extern void GAM_fn_vRasterDumpBeginLoop();
	extern void GAM_fn_vRasterDumpEndLoop();
#endif
#endif
/* END ANNECY MT }*/
/****************************/
 
#ifdef ACTIVE_EDITOR
extern void PLA_fn_vUpdateFrameCounterForModules(HIE_tdxHandleToSuperObject p_stSuperObject);
#endif
 
/* Oliv' - Enable loading once of all Maps - 08/06/1999 */
//	#define TEST_LOAD_ALL_MAPS
/* EndOfOliv' */

/****************************/
/* Init the dynam structure for a character*/
/* See Olivier for details and comments*/
/****************************/
void fn_vInitBehaviourOfACharacter(
								   HIE_tdxHandleToSuperObject _hCharacter)
{
	tdstEngineObject * p_stObject = HIE_fn_hGetSuperObjectObject(_hCharacter);
 
    /* DYNAM -> CINEINFO MT 26/08/98 {
	if( p_stObject->h_Dynam )
	{
		fn_vUpdateDynamicsMS(p_stObject);
	}
    DYNAM -> CINEINFO } */
	if( p_stObject->h_Brain )
	{
		fn_vReinitAI(M_pstGetMindOfBrain(p_stObject->h_Brain));
	}
	if( p_stObject->h_3dData )
	{
		PLA_fn_vInitNewState(_hCharacter,fn_h3dDataGetInitialState(M_GetMSHandle(_hCharacter,3dData)));
	}
}
 
/****************************/
/* Special function to teleport a character on the map*/
/* See Olivier for details and comments*/
/****************************/
 
#if !defined(PRESS_DEMO)
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
ACP_tdxBool fn_bMoveCharacterAtPosition(
										HIE_tdxHandleToSuperObject _hCharacter,
										MTH_tdxReal _xX,MTH_tdxReal _xY,MTH_tdxReal _xZ)
{
	MTH3D_tdstVector stV;
	ACP_tdxBool bTmp;
	HIE_tdxHandleToSuperObject hMainCamera = CAM_fn_hGetActiveCamera(CAM_e_MainViewport);
 
	if( _hCharacter == MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode()) )
	{
		fn_vReputCharacterSuperObjectAtTheWorld(_hCharacter);
		fn_vReputCharacterSuperObjectAtTheWorld(hMainCamera);
		MTH3D_M_vSetVectorElements(&stV,_xX,_xY,_xZ);
		POS_fn_vSetTranslationVector(HIE_fn_hGetSuperObjectMatrix(_hCharacter),&stV);
		POS_fn_vMulMatrixMatrix(HIE_fn_hGetSuperObjectGlobalMatrix(_hCharacter),HIE_fn_hGetSuperObjectGlobalMatrix(HIE_fn_hGetSuperObjectFather(_hCharacter)),HIE_fn_hGetSuperObjectMatrix(_hCharacter));
		POS_fn_vSetTranslationVector(HIE_fn_hGetSuperObjectMatrix(hMainCamera),&stV);
		POS_fn_vMulMatrixMatrix(HIE_fn_hGetSuperObjectGlobalMatrix(hMainCamera),HIE_fn_hGetSuperObjectGlobalMatrix(HIE_fn_hGetSuperObjectFather(hMainCamera)),HIE_fn_hGetSuperObjectMatrix(hMainCamera));
		bTmp = fn_bEdNOCLIP(_hCharacter);
		fn_bEdNOCLIP(hMainCamera);
	}
	else
	{
		fn_vReputCharacterSuperObjectAtTheWorld(_hCharacter);
		MTH3D_M_vSetVectorElements(&stV,_xX,_xY,_xZ);
		POS_fn_vSetTranslationVector(HIE_fn_hGetSuperObjectMatrix(_hCharacter),&stV);
		POS_fn_vMulMatrixMatrix(HIE_fn_hGetSuperObjectGlobalMatrix(_hCharacter),HIE_fn_hGetSuperObjectGlobalMatrix(HIE_fn_hGetSuperObjectFather(_hCharacter)),HIE_fn_hGetSuperObjectMatrix(_hCharacter));
		bTmp = fn_bEdNOCLIP(_hCharacter);
	}
	return bTmp;
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
#endif /* PRESS_DEMO */
 
 
/****************************/
/* Special function For updating the sector of camera*/
/* See Olivier for details and comments*/
/****************************/
void fn_vUpdateSectorInfoAfterNOCLIP(HIE_tdxHandleToSuperObject hCamera)
{
	MS_tdxHandleToCineinfo hCineinfo = M_GetMSHandle(hCamera,Cineinfo);
	HIE_tdxHandleToSuperObject hTarget;
	hTarget = CAM_fn_hCineInfoGetSuperObjectTargeted(hCineinfo->hInit);
	fn_vSectInfoSetCurrentSector(M_GetMSHandle(hCamera,SectInfo),fn_h_SectInfoGetCurrentSector(M_GetMSHandle(hTarget,SectInfo)));
	fn_vInsertObjectInSectorList(fn_h_SectInfoGetCurrentSector(M_GetMSHandle(hCamera,SectInfo)),hCamera);
	fn_vInsertObjectInSectorList(fn_h_SectInfoGetCurrentSector(M_GetMSHandle(hTarget,SectInfo)),hTarget);
}
/****************************/
/* Special function to move quickly Ed on map*/
/* See Olivier for details and comments*/
/****************************/

#if !defined(PRESS_DEMO)

ACP_tdxBool fn_bEdNOCLIP(HIE_tdxHandleToSuperObject hCharacter)
{
#if !defined(FINAL_VERSION) || defined(FINAL_VERSION_FOR_TESTERS)
	MTH3D_tdstVector stV,stAdd,stCumul;
	GLI_tdxValue xAngle,/*xX,xY,xZ,*/xAngle2;
/* ANNECY AV {*/
	static MTH_tdxReal xSpeed = MTH_C_ONE;
/* END ANNECY AV }*/
	MTH_tdxReal xCurrentSpeed;
	MTH_tdxReal xAlpha = MTH_M_xFloatToReal(0.15f);
	ACP_tdxBool bTmp;

	bTmp = TRUE;
	xAngle=fn_xComputeAngleOfPerso(hCharacter);
	xAngle2=0.0;
	MTH3D_M_vSetVectorElements(&stCumul,0.0,0.0,0.0);
	xCurrentSpeed = xSpeed;
	if (IPT_fn_bIsValidated(g_st_3DOS_EntryActions.hFlyingModeDoubleSpeed)==IPT_C_TRUE)
	{
		xAlpha *= 2.0;
		xCurrentSpeed = 2.0f*xSpeed;
	}

	M_bIfIsStepping()
	{
		xCurrentSpeed = MTH_M_xMul(xCurrentSpeed, MTH_M_xFloatToReal(0.1f)) ;
		xAlpha = MTH_M_xMul(xAlpha, MTH_M_xFloatToReal(0.1f)) ;
	}

	if (IPT_fn_bIsValidated(g_st_3DOS_EntryActions.hFlyingModeForward)==IPT_C_TRUE)
	{
		/* Straight away*/
		MTH3D_M_vSetVectorElements(&stAdd,0.0,-xCurrentSpeed,0.0);
		MTH3D_M_vAddVector(&stCumul,&stAdd,&stCumul);
	}
	if (IPT_fn_bIsValidated(g_st_3DOS_EntryActions.hFlyingModeBackward)==IPT_C_TRUE)
	{
		/* Rear*/
		MTH3D_M_vSetVectorElements(&stAdd,0.0,xCurrentSpeed,0.0);
		MTH3D_M_vAddVector(&stCumul,&stAdd,&stCumul);
	}
	if (IPT_fn_bIsValidated(g_st_3DOS_EntryActions.hFlyingModeStrafeLeft)==IPT_C_TRUE)
	{
		/* Strafe left*/
		MTH3D_M_vSetVectorElements(&stAdd,xCurrentSpeed,0.0,0.0);
		MTH3D_M_vAddVector(&stCumul,&stAdd,&stCumul);
	}
	if (IPT_fn_bIsValidated(g_st_3DOS_EntryActions.hFlyingModeStrafeRight)==IPT_C_TRUE)
	{
		/* Strafe right*/
		MTH3D_M_vSetVectorElements(&stAdd,-xCurrentSpeed,0.0,0.0);
		MTH3D_M_vAddVector(&stCumul,&stAdd,&stCumul);
	}
	if (IPT_fn_bIsValidated(g_st_3DOS_EntryActions.hFlyingModeLeft)==IPT_C_TRUE)
	{
		/* Left*/
		xAngle2+=(MTH_tdxReal)xAlpha;
	}
	if (IPT_fn_bIsValidated(g_st_3DOS_EntryActions.hFlyingModeRight)==IPT_C_TRUE)
	{
		/* Right*/
		xAngle2-=(MTH_tdxReal)xAlpha;
	}
	if (IPT_fn_bIsValidated(g_st_3DOS_EntryActions.hFlyingModeDown)==IPT_C_TRUE)
	{
		/* Down*/
		MTH3D_M_vSetVectorElements(&stAdd,0.0,0.0,-xCurrentSpeed);
		MTH3D_M_vAddVector(&stCumul,&stAdd,&stCumul);
	}
	if (IPT_fn_bIsValidated(g_st_3DOS_EntryActions.hFlyingModeUp)==IPT_C_TRUE)
	{
		/* Up*/
		MTH3D_M_vSetVectorElements(&stAdd,0.0,0.0,xCurrentSpeed);
		MTH3D_M_vAddVector(&stCumul,&stAdd,&stCumul);
	}
/* ANNECY AV {*/
/*
	if (IPT_fn_bIsValidated(g_st_3DOS_EntryActions.hFlyingModeSpeedIncrease)==IPT_C_TRUE)
	{
		if( xSpeed <= 6.0 )
			xSpeed += 0.1f;
	}
	if (IPT_fn_bIsValidated(g_st_3DOS_EntryActions.hFlyingModeSpeedDecrease)==IPT_C_TRUE)
	{
		if( xSpeed > 0.1 )
			xSpeed -= 0.1f;
	}
*/
/* END ANNECY AV }*/
	fn_vSetRotationMatrixZ(HIE_fn_hGetSuperObjectMatrix(hCharacter),(xAngle+xAngle2-MTH_C_PiBy2));
	POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectMatrix(hCharacter),&stV);
	POS_fn_vMulMatrixVector(&stCumul,HIE_fn_hGetSuperObjectMatrix(hCharacter),&stCumul);
	MTH3D_M_vAddVector(&stV,&stV,&stCumul);
	POS_fn_vSetTranslationVector(HIE_fn_hGetSuperObjectMatrix(hCharacter),&stV);
	POS_fn_vSetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(hCharacter),&stV);
/*	MEC_vInitTranslation(fn_p_stDynamGetDynamics(M_GetMSHandle(hCharacter,Dynam)),hCharacter,&stV);*/
	DNM_M_vDynamicsSetInit ( fn_p_stDynamGetDynamics(M_GetMSHandle(hCharacter,Dynam)), TRUE );
	return bTmp;

#else /* !defined(FINAL_VERSION) || defined(FINAL_VERSION_FOR_TESTERS) */
	return FALSE;
#endif /* !defined(FINAL_VERSION) || defined(FINAL_VERSION_FOR_TESTERS) */
}

#endif /* PRESS_DEMO */
 
 
/****************************/
/* Deal with a character.*/
/* See Olivier for details and comments*/
/* 20/04/98 Carlos Torres call PLA_fn_vOverWriteMatrixWithUCC*/
/* 		when frmae is skip to update UCC matrix*/
/****************************/
void fn_vTreatCharactersInSector(HIE_tdxHandleToSuperObject hCharacter)
{
    /*tdstEngineObject        *p_stEngObj;*/
    MTH3D_tdstVector        stOldV;
    MS_tdxHandleToDynam     h_Dynam;
    struct DNM_stDynamics   *p_stDynamic;
    ACP_tdxBool             bSectorChange=TRUE;
#if (defined(USE_PROFILER) && !defined(PRESS_DEMO) && !defined(U64))
	long					lDuration;
#endif
	/* equivalent a M_TreatObject */
    fn_vStandardGameSetLastTrame(M_GetMSHandle(hCharacter,StandardGame), g_stEngineStructure.stEngineTimer.ulTrameNumber);
	POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(hCharacter),&stOldV);
 
	/* fly mode is handled somewhere else, so don't handle main character when in fly mode here */
	if ( ( hCharacter != MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode()) ) || !g_ucIsEdInGhostMode )
	{
		/*p_stEngObj=(tdstEngineObject *)HIE_fn_hGetSuperObjectObject(hCharacter);
		M_TreatObject(p_stEngObj);*/
 
/* ANNECY AV DEMO {*/
#ifndef U64
        if(g_DEMO_KeybTest != DEMO_PLAY)
        {
#endif
/* END ANNECY AV }*/
			MS_tdxHandleTo3dData h_Current3dData;
 
			h_Current3dData  = M_GetMSHandle(hCharacter,3dData);
 
 
		    /* Play anims*/
		    if (h_Current3dData)
		    {
			    ACP_tdxBool			bSkip,bNoDisplay;
			    unsigned long		ulCurrentBits;
				struct tdstState_  *p_stCurrentState;
				struct tdstAnim3d_ *p_stCurrentAnim;
 
			    ulCurrentBits    = fn_ulStandardGameGetCustomBits(M_GetMSHandle(hCharacter,StandardGame));
				p_stCurrentState = fn_h3dDataGetCurrentState(h_Current3dData);
				p_stCurrentAnim	 = p_stCurrentState ? fn_p_stGetAnimInState(p_stCurrentState): NULL;
 
				/* GAM_C_CustBitNoAnimPlayer			=> no player*/
			    /* GAM_C_CustBitUnseenFrozen			=> nothing if actor not displayed*/
				/* GAM_C_CustBitUnseenFrozenAnimPlayer	=> no player if actor not displayed*/
				/* GAM_C_CustBitNoAnimPlayerWhenTooFar	=> no player if actor too far from Rayman*/
 
				bNoDisplay = (ACP_tdxBool) (
					(p_stCurrentAnim == NULL)
					|| ((ulCurrentBits & GAM_C_CustBitNoAnimPlayer) && (HIE_M_lGetNumberOfChildren(hCharacter) > 0))
					|| ((ulCurrentBits & GAM_C_CustBitOutOfVisibility) && (ulCurrentBits & (GAM_C_CustBitUnseenFrozen|GAM_C_CustBitUnseenFrozenAnimPlayer)))
					|| ((ulCurrentBits & GAM_C_CustBitNoAnimPlayerWhenTooFar) && fn_bStandardGameIsTooFar(M_GetMSHandle(hCharacter,StandardGame)))
				);
 
 
				if (!bNoDisplay || ulCurrentBits & GAM_C_CustBitSoundWhenInvisible)
			    {
				    PRF_fn_vStartChrono( PRF_C_ulFctAnimPlayer, hCharacter );
 
#if (defined(USE_PROFILER) && !defined(PRESS_DEMO) && !defined(U64))
    #pragma warning  (disable : 4146)
					lDuration = -TMR_fn_ulFastGetInternalCounter();
    #pragma warning (default  : 4146)
#endif
				    bSkip = PLA_fn_bSkipCurrentFrame(hCharacter);
 
/* ANNECY MT - 07/12/98 {*/
					/* if AI changes something which need to do frame, no skip*/
					bSkip &= !fn_b3dDataHasAnimMatrixChanged(h_Current3dData);
/* END ANNECY MT }*/
 
				    /* if current state is finished and next state is NULL, then stop playing the anim, skip it*/
				    bSkip |= fn_uc3dDataGetFlagEndState(h_Current3dData);
 
				    if (bSkip)
					{
					    PRF_fn_lIncIndependantVariable(PRF_C_ulIdpNbSkippedAnims,1);
#ifdef ACTIVE_EDITOR
						/* update modules SO frame number*/
						PLA_fn_vUpdateFrameCounterForModules(hCharacter);
#endif
					}
 
 
					/* if anim is not skipped, play it */
				    if ( ! bSkip )
					    PLA_fn_bDoAnimPlayerForCharacter ( hCharacter , bNoDisplay , ( ACP_tdxBool ) FALSE ) ;
 
 
#if (defined(USE_PROFILER) && !defined(PRESS_DEMO) && !defined(U64))
					lDuration += TMR_fn_ulFastGetInternalCounter();
					if(M_GetMSHandle(hCharacter,StandardGame))
					{
						GAM_fn_vRasterDumpUpdate((unsigned long)fn_otStandardGameGetModelType(M_GetMSHandle(hCharacter,StandardGame)),0,lDuration,0,0);
					}
#endif
 
				    PRF_fn_vStopChrono( PRF_C_ulFctAnimPlayer, hCharacter );
			    }
			    else
				{
#ifdef ACTIVE_EDITOR
					/* update modules SO frame number*/
					PLA_fn_vUpdateFrameCounterForModules(hCharacter);
#endif
				    bSkip = TRUE;
				}
 
/* ANNECY MT - 23/10/98 {*/
#if (defined(USE_PROFILER) && !defined(PRESS_DEMO) && !defined(U64))
				GAM_fn_vRasterDumpUpdate((unsigned long)fn_otStandardGameGetModelType(M_GetMSHandle(hCharacter,StandardGame)),0,0,0,1);
#endif
/* END ANNECY MT }*/
 
			    /* Do treatment*/
			    fn_vMakeCharacterReact(hCharacter);
 
			    /* JO 01/07/97*/
			    if( !M_GetMSHandle(hCharacter,StandardGame) )
				    return;
			    /* JO fin*/
 
		    }
/* ANNECY AV DEMO {*/
#ifndef U64
        }
        else
        {
            DEMO_fn_vGetACompleteCharacterPosition(hCharacter);
        }
 
#ifndef RETAIL		
		if (g_DEMO_KeybTest == DEMO_RECORD && ! CAM_fn_bSuperObjectIsACamera (hCharacter))  DEMO_SaveInfo (hCharacter);
#endif /* RETAIL */
#endif
/* END ANNECY AV }*/
 
		PRF_fn_vStartChrono( PRF_C_ulFctIADNMPLAMisc, NULL );
 
		/* water streak effect */
		fn_vWaterStreakEffect(&g_stEngineStructure.stViewportAttr,hCharacter,
			g_stEngineStructure.ulDisplayMode);
 
#ifndef D_THROW_PRT
		/* New particles generation */
		fn_vMSPrtSrcSourceGenerateParticles(hCharacter);
#endif /* D_THROW_PRT */
 
		/* MR2002*/
#ifdef __3DOSLIGHTS
		fn_vUpdateLight(hCharacter);
#endif
 
		/* Deal with changes of sector*/
		if( g_ucIsEdInGhostMode && CAM_fn_bSuperObjectIsACamera(hCharacter) )
		{
			fn_vSectInfoSetCurrentSector(
				M_GetMSHandle(hCharacter,SectInfo),
				fn_h_SectInfoGetCurrentSector(M_GetMSHandle(MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode()),SectInfo)));
			fn_vInsertObjectInSectorList(fn_h_SectInfoGetCurrentSector(M_GetMSHandle(hCharacter,SectInfo)),hCharacter);
		}
		else
		{
			/* Do not update sector for fix objects and camera without collisions */
			if
			(!(
				HIE_fn_SO_bIsSuperimposed(hCharacter)
				||
				(
					CAM_fn_bSuperObjectIsACamera(hCharacter) /* camera without collision */
					&& (g_stEngineStructure.cCameraMode == 1)
					&& ( M_GetMSHandle(hCharacter,Cineinfo)->hWork->uwDNMFlags & DNM_CAM_C_NoObstacle )
				)
			))
			{
				h_Dynam = M_GetMSHandle(hCharacter,Dynam);
				if (h_Dynam)
				{
					p_stDynamic = fn_p_stDynamGetDynamics(h_Dynam);
					if (p_stDynamic)
					{
						if ((DNM_M_bDynamicsIsAdvancedSize(p_stDynamic)) && (DNM_M_bDynamicsIsCollide(p_stDynamic)))
							bSectorChange = (ACP_tdxBool)(DNM_M_cDynamicsGetCollideCounter (p_stDynamic)==0);
						else
							bSectorChange = TRUE;
					}
				}
 
				if (bSectorChange)
				{
					GAM_fn_vSectInfoTestChangeSectorForCharacter(hCharacter);
				}
			}
		}
		PRF_fn_vStopChrono( PRF_C_ulFctIADNMPLAMisc, NULL );
    }
}
 
/*********************************************************************************************************************/
 
/****************************/
/* Deal with the Dynamic Hierarchy*/
/* See Olivier for details and comments*/
/* new : update TooFar Flag (MT 11/03/99) */
/****************************/
void fn_vTreatDynamicHierarchy(HIE_tdxHandleToSuperObject hSuperObj, HIE_tdxHandleToSuperObject hMainChar, MTH3D_tdstVector *p_stMainCharTranslation)
{
	HIE_tdxHandleToSuperObject hChild,hNextChild,hPrevChild;
	tdstEngineObject * p_stObj;
	long i;
	unsigned long ulCustomBits;
	MTH3D_tdstVector stDist;
 
	if(HIE_fn_ulGetSuperObjectType(hSuperObj) == HIE_C_ulActor)
	{
		/* here we are an actor*/
		MS_tdxHandleToStandardGame hStdGame = M_GetMSHandle(hSuperObj, StandardGame);
		p_stObj = (tdstEngineObject *) HIE_fn_hGetSuperObjectObject(hSuperObj);
		if( !hStdGame /* if it is a dead always*/
			||
			( /* or a non-platform that we already handled or which is inactive*/
				(fn_ucStandardGameGetPlatFormType(hStdGame) == 0)
				&&
				(!M_ObjectIsActive(p_stObj) || M_ObjectIsAlreadyTreated(p_stObj))
			)
		  )
		{
			/* do nothing*/
			return;
		}
 
		/* here we have either a platform, or a non-handled live normal actor that is not a camera*/
		HIE_fn_vPushMatrix(hSuperObj);
		if ( fn_ucStandardGameGetPlatFormType(hStdGame) == 0 ) /* if a normal actor*/
		{
			/* if the actor is protected from freeze, or the engine is no frozen -> lets do it!*/
			if ( !g_stEngineStructure.bEngineFrozen || (fn_ulStandardGameGetCustomBits(hStdGame) & GAM_C_CustBitUnfreezable) )
			{
				/* Update TooFar Flag */					
				if ( hSuperObj == hMainChar )
				{
					fn_vStandardGameSetTooFar(hStdGame,FALSE);
				}
				else
				{
					ulCustomBits = fn_ulStandardGameGetCustomBits(hStdGame);
					if ( ulCustomBits & (GAM_C_CustBitNoAnimPlayerWhenTooFar|GAM_C_CustBitNoAIWhenTooFar|GAM_C_CustBitNoMecaWhenTooFar) )
					{
						MTH3D_M_vSubVector( &stDist,
											POS_fn_p_stGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(hSuperObj)),
											p_stMainCharTranslation);
						
						if( MTH_M_bLess(MTH3D_M_xNorm1Vector(&stDist) , MTH_M_xLongToReal(fn_ucStandardGameGetTooFarLimit(hStdGame))) )
						{
							fn_vStandardGameSetTooFar(hStdGame,FALSE);
						}
						else
						{
							fn_vStandardGameSetTooFar(hStdGame,TRUE);
						}
					}
				}					
				fn_vTreatCharactersInSector(hSuperObj);
			}
#ifdef ACTIVE_EDITOR	/* { */
			else
			{
				/* update modules SO frame number*/
				PLA_fn_vUpdateFrameCounterForModules(hSuperObj);
			}
#endif	/* } */
			HIE_fn_vPopMatrix();
			HIE_fn_vPushMatrix(hSuperObj);
 
			if( hSuperObj == MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode()) )
			{
				/* The Main actor can have children, when carrying another one.*/
				HIE_M_ForEachMovingChildOf(hSuperObj,hChild,hNextChild,i)
				{
					if ((HIE_fn_ulGetSuperObjectType(hChild) == HIE_C_ulActor) && !CAM_fn_bSuperObjectIsACamera(hChild))
						fn_vTreatDynamicHierarchy(hChild, hMainChar, p_stMainCharTranslation);
				}
			}
		}
		else
		{
			/* hSuperObj is a platform : treat child actors, even if the platform is frozen,*/
			/* because the children have to be handled to have valid global matrixes*/
			HIE_M_InvForEachMovingChildOf(hSuperObj,hChild,hPrevChild,i)
			{
				if ((HIE_fn_ulGetSuperObjectType(hChild) == HIE_C_ulActor) && !CAM_fn_bSuperObjectIsACamera(hSuperObj))
				{
					fn_vTreatDynamicHierarchy(hChild, hMainChar, p_stMainCharTranslation);
				}
			}
		}
	}
	else /*not an actor*/
	{
  	HIE_fn_vPushMatrix(hSuperObj);
		HIE_M_ForEachMovingChildOf(hSuperObj,hChild,hNextChild,i)
		{
			if ( (HIE_fn_ulGetSuperObjectType(hChild) == HIE_C_ulActor) && !CAM_fn_bSuperObjectIsACamera(hChild) )
				fn_vTreatDynamicHierarchy(hChild, hMainChar, p_stMainCharTranslation);
		}
	}
	HIE_fn_vPopMatrix();
}
/*----------------------------------------------------------------------
* The same things, but for PlatForms
* new : update TooFar Flag (MT 11/03/99)
*----------------------------------------------------------------------*/
void fn_vTreatDynamicHierarchyOfPlatForms(HIE_tdxHandleToSuperObject hSuperObj)
{
	HIE_tdxHandleToSuperObject hChild,hNextChild;
	MS_tdxHandleToStandardGame hStdGame;
	tdstEngineObject * p_stObj;
	long lI;
	HIE_tdxHandleToSuperObject hMainChar;
	unsigned long ulCustomBits;
	MTH3D_tdstVector stDist , *p_stMainCharTranslation;
 
	/* get main character*/
	hMainChar				= MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode());
	p_stMainCharTranslation = POS_fn_p_stGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(hMainChar));

		
	HIE_fn_vPushMatrix(hSuperObj);
	/*
    * treat platforms
    */
	HIE_M_ForEachMovingChildOf(hSuperObj,hChild,hNextChild,lI)
	{
		/* Add on for editors*/
		if ( HIE_fn_ulGetSuperObjectType(hChild) == HIE_C_ulActor )
		{
			hStdGame = M_GetMSHandle(hChild, StandardGame);
			p_stObj  = (tdstEngineObject *) HIE_fn_hGetSuperObjectObject(hChild);
			if(
				!hStdGame /* if it is a dead always (because a platform can be an always too...)*/
				|| !M_ObjectIsActive(p_stObj)
				|| (g_stEngineStructure.bEngineFrozen && (fn_ulStandardGameGetCustomBits(hStdGame) ^ GAM_C_CustBitUnfreezable)) /* or an unprotected actor while the engine is frozen*/
			  )
			{
				/* skip this one and proceed to the next platform*/
#ifdef ACTIVE_EDITOR	/* { */
				if(g_stEngineStructure.bEngineFrozen && (fn_ulStandardGameGetCustomBits(hStdGame) ^ GAM_C_CustBitUnfreezable))
				{
					/* update modules SO frame number*/
					PLA_fn_vUpdateFrameCounterForModules(hChild);
				}
#endif	/* } */
				continue;
			}
 
			/* Is character a platform ?*/
			if ( fn_ucStandardGameGetPlatFormType(hStdGame) != 0 )
			{
				if ( !M_ObjectIsAlreadyTreated(p_stObj) )
				{
					/* JT 					PLA_fn_vDesInitAllChildOfCharacter(hChild);*/
					/* Update TooFar Flag */					
					if ( hChild == hMainChar )
					{
						fn_vStandardGameSetTooFar(hStdGame,FALSE);
					}
					else
					{
						ulCustomBits = fn_ulStandardGameGetCustomBits(hStdGame);
						if ( ulCustomBits & (GAM_C_CustBitNoAnimPlayerWhenTooFar|GAM_C_CustBitNoAIWhenTooFar|GAM_C_CustBitNoMecaWhenTooFar) )
						{
							MTH3D_M_vSubVector( &stDist,
												POS_fn_p_stGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(hChild)),
												p_stMainCharTranslation);
							
							if( MTH_M_bLess(MTH3D_M_xNorm1Vector(&stDist) , MTH_M_xLongToReal(fn_ucStandardGameGetTooFarLimit(hStdGame))) )
							{
								fn_vStandardGameSetTooFar(hStdGame,FALSE);
							}
							else
							{
								fn_vStandardGameSetTooFar(hStdGame,TRUE);
							}
						}
					}					
					/* */
					HIE_fn_vPushMatrix( hChild );
					fn_vTreatCharactersInSector( hChild );
					HIE_fn_vPopMatrix();
				}
			}
			else /*the hierarchy is built so that all platforms are before the other actors*/
			{
				break; /* -> when we encounter a non-platform, we know there are no other platform left to process, so break the loop*/
			}
		}
	}
	HIE_fn_vPopMatrix();
}
 
 
/*----------------------------------------------------------------------
* The same things, but for Cameras
*----------------------------------------------------------------------*/
void fn_vTreatCameraHierarchy(HIE_tdxHandleToSuperObject hSuperObj,
							  ACP_tdxBool bForcedActivity)
{
	HIE_tdxHandleToSuperObject hChild;
	tdstEngineObject * p_stObj;
	ACP_tdxBool bTmp = FALSE;
	long i;
	
	HIE_fn_vPushMatrix(hSuperObj);
	if(
		(HIE_fn_ulGetSuperObjectType(hSuperObj) == HIE_C_ulActor)
		&&
		( /* if the actor is protected from freezing, orthe engine is not in frozen mode, we can continue*/
		!g_stEngineStructure.bEngineFrozen
		|| (fn_ulStandardGameGetCustomBits(M_GetMSHandle(hSuperObj, StandardGame)) & GAM_C_CustBitUnfreezable)
		)
		)
	{
		p_stObj = (tdstEngineObject*) HIE_fn_hGetSuperObjectObject(hSuperObj);

		if ( bForcedActivity )
		{
			bTmp = TRUE;
		}

		if ( M_ObjectIsActivable(p_stObj) && (!M_ObjectIsAlreadyTreated(p_stObj)) )
		{
			HIE_tdxHandleToSuperObject hMainChar;
			unsigned long ulCustomBits;
			MTH3D_tdstVector stDist , *p_stMainCharTranslation;
			MS_tdxHandleToStandardGame hStdGame;

			/* get main character*/
			hMainChar				= MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode());
			p_stMainCharTranslation = POS_fn_p_stGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(hMainChar));
			
			/* Update tooFar Flag */
			hStdGame = M_GetMSHandle(hSuperObj, StandardGame);
			if (hStdGame)
			{
				ulCustomBits = fn_ulStandardGameGetCustomBits(hStdGame);
				if ( ulCustomBits & (GAM_C_CustBitNoAnimPlayerWhenTooFar|GAM_C_CustBitNoAIWhenTooFar|GAM_C_CustBitNoMecaWhenTooFar) )
				{
					MTH3D_M_vSubVector( &stDist,
						POS_fn_p_stGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(hSuperObj)),
						p_stMainCharTranslation);
					
					if( MTH_M_bLess(MTH3D_M_xNorm1Vector(&stDist) , MTH_M_xLongToReal(fn_ucStandardGameGetTooFarLimit(hStdGame))) )
					{
						fn_vStandardGameSetTooFar(hStdGame,FALSE);
					}
					else
					{
						fn_vStandardGameSetTooFar(hStdGame,TRUE);
					}
				}
			}
			fn_vTreatCharactersInSector(hSuperObj);
			bTmp=TRUE;
		}

		HIE_fn_vPopMatrix();
		HIE_fn_vPushMatrix(hSuperObj);
	}
#ifdef ACTIVE_EDITOR	/* { */
	else if(g_stEngineStructure.bEngineFrozen && (fn_ulStandardGameGetCustomBits(M_GetMSHandle(hSuperObj, StandardGame)) ^ GAM_C_CustBitUnfreezable))
	{
		/* update modules SO frame number*/
		PLA_fn_vUpdateFrameCounterForModules(hSuperObj);
	}
#endif	/* } */

	HIE_M_ForEachChildOf(hSuperObj,hChild,i)
	{
		fn_vTreatCameraHierarchy(hChild,bTmp);
	}
	HIE_fn_vPopMatrix();
}
 
/*----------------------------------------------------------------------
*----------------------------------------------------------------------*/
void fn_vSendBackGroundColor(HIE_tdxHandleToSuperObject _hSprObjSector)
{
	ACP_tdxIndex							xI;
	SECT_tdxHandleOfSectorObject			hSectorObject;
	SECT_tdxHandleOfElementLstStaticLights	hStaticLightsElement;
	
 
	hSectorObject=(SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(_hSprObjSector);
 
	LST2_M_StaticForEachElementOf
		(
		&(hSectorObject->stListOfStaticLights),
		hStaticLightsElement,
		xI
		)
	{
		if (GLI_lGetLightType(hStaticLightsElement->hStaticLights) == GLI_C_lFogLight)
		{
			struct GEO_tdstColor_	stColor;
			GLI_xGetLightBackgroundColor(hStaticLightsElement->hStaticLights, &stColor);
			GLD_bSetBackgroundColorForDevice
				(
/* XB 23/06/99 */
#ifndef U64
				fn_hGetGLDDevice(0),
#else /* U64 */
				NULL,
#endif /* U64 */
/* End XB 23/06/99 */
				RGB
				(
				(char) (stColor.xR*255),
				(char) (stColor.xG*255),
				(char) (stColor.xB*255)
				)
				);
			break;
		}
	}
}
 
/* Oliv' - We NEED the default flag too, - 25/02/1999

 'coz sometimes the function SendCharacterToViewport which set or not the CustBitOutOfVisibility
 is not called (actor is not in a visible sector) */

/*#ifndef U64*/

/* this call is not necessary for U64, because there are no mirrors for them*/
/* -> only one camera at a time can see an actor, which means that no camera can*/
/*    override the outofvisisibity flag set by another camera*/

/* EndOfOliv' */

#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC 04/06/99 */
void fn_vSetOutOfVisibilityCustomBitOfAllActiveActors()
{
	HIE_tdxHandleToSuperObject hCharacter1, hCharacter2;
	MS_tdxHandleToStandardGame hStdGame;
	long i,j;
	unsigned long ulCustomBits;
 
	/* for each actor in the active hierarchy*/
	HIE_M_ForEachChildOf(gp_stDynamicWorld, hCharacter1, i)
	{
		/* assume it is not out of visibility*/
		hStdGame = M_GetMSHandle(hCharacter1, StandardGame);
		ulCustomBits = fn_ulStandardGameGetCustomBits(hStdGame) | GAM_C_CustBitOutOfVisibility;
		fn_vStandardGameSetCustomBits(hStdGame, ulCustomBits);
		/* if it is rayman of a platform, check the children actors*/
		if ( (fn_ucStandardGameGetPlatFormType(hStdGame) == C_ucPlatFormType_StandardPlatForm) || (ulCustomBits & GAM_C_CustBitRayman) )
		{
			HIE_M_ForEachChildOf(hCharacter1, hCharacter2, j)
			{
				if ( HIE_fn_ulGetSuperObjectType(hCharacter2) == HIE_C_ulActor )
				{
					hStdGame = M_GetMSHandle(hCharacter2, StandardGame);
					fn_vStandardGameSetCustomBits(hStdGame, fn_ulStandardGameGetCustomBits(hStdGame) | GAM_C_CustBitOutOfVisibility);
				}
			}
		}
	}
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC 04/06/99 */

/* Oliv' - We NEED the default flag too, - 25/02/1999 */
/* #endif */
/* EndOfOliv' */

/*-----------------------------------------------------------------------------
*  Description :   Game Engine Function
*-----------------------------------------------------------------------------
*  Input :         None
*  Output :
*-----------------------------------------------------------------------------
*  Creation date : 22/08/96            Author : Christophe
*-----------------------------------------------------------------------------
*  Modification date : 13/10/97        Modification Author : Gilles
*  Modifications : Cleaning
*---------------------------------------------------------------------------*/
 
#ifdef U64
/* FQ LIGHTVIS*/
#ifndef RETAIL
extern int g_LightDrawnThisFrame;
#endif /* RETAIL*/

//Declare these globals variables in gameeng.c because of overlay
// do not erase by default on u64
char gc_EraseBackground=0;
//End XB 22/06/99

#else /* u64 */

// erase by default on PC
char gc_EraseBackground=1;

#endif


void fn_vEngine()
{
/* XB 23/06/99 */
#ifndef U64
	GLD_tdhDevice mhDisplayDevice3D=g_stEngineStructure.hGLDDevice;
	GLD_tdhViewport mhDisplayViewport3D=g_stEngineStructure.hGLDViewport;
#else /* U64 */
	GLD_tdhDevice mhDisplayDevice3D=NULL;
	GLD_tdhViewport mhDisplayViewport3D=NULL;
#endif /* U64 */
/* End XB 23/06/99 */

	BOOL bEnabledWrite ;
/*   	tdxHandleToAlwaysActiveCharacterNode hCharAlwaysActiveNode;*/
/*	short i;*/
 
/*	ACP_tdxIndex xIndex, xIndexMax ;*/
 
#if defined(USE_PROFILER) && !defined(PRESS_DEMO)
	HIE_tdxHandleToSuperObject		hSOCurrentSector;
	SECT_tdxHandleOfSectorObject	hSECTCurrentSector;
	long                          ulRasterDuration;
#endif /* USE_PROFILER && PRESS_DEMO */
 
#if defined(ACTIVE_EDITOR)
    PRF_fn_vStartChrono( PRF_C_ulFctEditor, NULL );
	fn_vCheckEditor();
	fn_vCheckEnd();
    PRF_fn_vStopChrono( PRF_C_ulFctEditor, NULL );
	if (g_stEngineStructure.eEngineMode==EM_ModeStoppingProgram)
		return;
#endif /* ACTIVE_EDITOR */
 
 
	/******************/
	/*  Miscellaneous */
	/******************/
 
	/* sound */
#ifdef U64
    PRF_fn_vStartChrono( PRF_C_ulFctSound, PRF_C_pvSoundInit );
#else
    PRF_fn_vStartChrono( PRF_C_ulFctSoundInit, NULL );
#endif
 
	SND_fn_vSynchroSound();
 
#ifdef U64
    PRF_fn_vStopChrono( PRF_C_ulFctSound, PRF_C_pvSoundInit );
#else
    PRF_fn_vStopChrono( PRF_C_ulFctSoundInit, NULL );
#endif
 
    PRF_fn_vStartChrono( PRF_C_ulFctMainMisc, NULL );

#if !defined(PRESS_DEMO)

#if (!defined( FINAL_VERSION	) && !defined(RETAIL) ) || defined(FINAL_VERSION_FOR_TESTERS)
    /* cheat code, ghost mode */
	if (IPT_fn_bIsJustValidated(g_st_3DOS_EntryActions.hFlyingMode)==IPT_C_TRUE)
	{
 
	   /* All these functions must be done
		either when you enter the ghost mode or when you quit this mode*/
		g_ucIsEdInGhostMode=(unsigned char)(1-g_ucIsEdInGhostMode);
 
		if (g_ucIsEdInGhostMode)
		{
			fn_v3dDataSetDrawMask(
				M_GetMSHandle(MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode()),3dData), 
				HIE_fn_lGetSuperObjectDrawMask(MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode()))  & ~GLI_C_lIsNotWired
			);
			HIE_fn_vSetSuperObjectDrawMask(
				MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode()),
				HIE_fn_lGetSuperObjectDrawMask(MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode()))  & ~GLI_C_lIsNotWired
			);
		}
		else
		{
			fn_v3dDataSetDrawMask(
				M_GetMSHandle(MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode()),3dData), 
				HIE_fn_lGetSuperObjectDrawMask(MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode()))  | GLI_C_lIsNotWired
			);
			HIE_fn_vSetSuperObjectDrawMask(
				MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode()),
				HIE_fn_lGetSuperObjectDrawMask(MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode()))  | GLI_C_lIsNotWired
			);
		}
 
		fn_vUpdateSectorInfoAfterNOCLIP(CAM_fn_hGetActiveCamera(CAM_e_MainViewport));
		CAM_fn_vUpdateTargetPosition(M_GetMSHandle(CAM_fn_hGetActiveCamera(CAM_e_MainViewport),Cineinfo));
		fn_vInitBehaviourOfACharacter(MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode()));
#if !defined( U64 )
		fn_vReputCharacterSuperObjectAtTheWorld(MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode()));
#endif /* U64 */
		fn_vTakeControlOfChannel((tdstEngineObject *)HIE_fn_hGetSuperObjectObject(MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode())), (unsigned short) -1, FALSE);
	}
#endif /* (!defined( FINAL_VERSION	) && !defined(RETAIL) ) || defined(FINAL_VERSION_FOR_TESTERS) */

#endif /* PRESS_DEMO */
	
/* ANNECY MT - 25/06/99 { */
#if !defined(U64) && defined(_DEBUG)
	if ( !g_ucIsEdInGhostMode && g_ucSlowDownEngine )
		Sleep(g_ucSlowDownTime);
#endif
/* END ANNECY MT } */

	/* shadow init ??? */
	SHW_fn_vInitShadowCounter();

#if (!defined ( RETAIL ) && !defined(PRESS_DEMO)) || defined(FINAL_VERSION_FOR_TESTERS)
	/* we want to use fly mode even when the engine is stepped! */
	if( g_ucIsEdInGhostMode )
	{
		HIE_tdxHandleToSuperObject hCharacter = MC_fn_hGetCharacterInMainCharacterNode ( MC_fn_hGetFirstMainCharNode() ) ;
	    tdstEngineObject * p_stEngObj = (tdstEngineObject *) HIE_fn_hGetSuperObjectObject ( hCharacter );
		fn_bEdNOCLIP(hCharacter);
		M_TreatObject(p_stEngObj);
#ifdef __3DOSLIGHTS
		fn_vUpdateLight(hCharacter);
#endif
		GAM_fn_vSectInfoTestChangeSectorForCharacter(hCharacter);
	}
#endif /* (!defined ( RETAIL ) && !defined(PRESS_DEMO)) || defined(FINAL_VERSION_FOR_TESTERS) */

	M_IfCanDoFullStep()
	{
 
	if (!fn_bIsEngineInPause())
	{
		HIE_fn_vInvalidateAllGlobalMatrices();
/*		HIE_fn_vValidateGlobalMatrix(gp_stDynamicWorld);*/
#ifdef U64
		MOR_fn_vUnLockAllMorphTasks();
#endif
		/* Trame counter and timer */
		/*fn_vActualizeEngineClock();*/
 
		/* Mangement of Changing Main Character.*/
		if (MC_fn_hGetNewMainCharacter(MC_fn_hGetFirstMainCharNode()) != NULL)
		{
			MC_fn_vSetCharacterInMainCharacterNode(
				MC_fn_hGetFirstMainCharNode(),
				MC_fn_hGetNewMainCharacter(MC_fn_hGetFirstMainCharNode())
			);
			MC_fn_vSetNewMainCharacter(MC_fn_hGetFirstMainCharNode(), NULL);
		}
		fn_vUpdateDynamicHierarchy();
 
#if defined(USE_PROFILER) && !defined(PRESS_DEMO)
		hSOCurrentSector   = fn_h_SectInfoGetCurrentSector(M_GetMSHandle(MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode()),SectInfo));
		hSECTCurrentSector = (SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(hSOCurrentSector);
		PRF_fn_vIncreaseVariable( PRF_C_ulVarCurrentSector, PRF_C_pvMainCharCurrentSector, (unsigned long)hSOCurrentSector);
#endif /* USE_PROFILER && PRESS_DEMO */
 
/* ANNECY MT - 01/10/98 {*/
#ifndef U64
        if(g_DEMO_KeybTest != DEMO_PLAY)
#endif U64
/* END ANNECY MT }*/
			fn_vKillAllAlwaysInNonActiveSectors();
#ifndef U64
		else
			fn_vClearUnusedAlwaysInDemoMode();
#endif U64
		HIE_fn_vInitMatrixStack();
 
/*XB980824*/
#ifndef D_THROW_MGT
		if(bEnabledWrite)
			MGT_fn_vTreatMagnets();
#endif /* D_THROW_MGT */
/*End XB*/
 
        PRF_fn_vStopChrono( PRF_C_ulFctMainMisc, NULL );
        PRF_fn_vStartChrono( PRF_C_ulFctHIE, NULL );
 
		SAF_M_Try /*BART*/
 
/* ANNECY MT - 03/11/98 {*/
#if (defined(USE_PROFILER) && !defined(PRESS_DEMO) && !defined(U64))
		GAM_fn_vRasterDumpBeginLoop();
#endif
/* END ANNECY MT }*/
 
/* ANNECY AV DEMO {*/
#ifndef U64
        if(g_DEMO_KeybTest == DEMO_PLAY)
		{
			if(DEMO_fn_bUpdateDynamicHierarchy () == FALSE)
				return;
		}
        else
#endif U64
/* END ANNECY AV }*/
        {
			HIE_tdxHandleToSuperObject hMainChar = MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode());

		    fn_vTreatDynamicHierarchyOfPlatForms(gp_stDynamicWorld);
		    fn_vTreatDynamicHierarchy(gp_stDynamicWorld, hMainChar, POS_fn_p_stGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(hMainChar)));			
        }		
		CAM_fn_vCameraManagement();

/* Oliv' - Enable loading once of all Maps - 08/06/1999 */
#if defined(TEST_LOAD_ALL_MAPS)
		{
			#define TEST_LOAD_TIME		100
			static unsigned long s_ulWaitFrame = 0L;
			static unsigned long s_ulLoadAllLevel = 0L;
			if( (++s_ulWaitFrame) >= TEST_LOAD_TIME )
			{
				s_ulLoadAllLevel = (s_ulLoadAllLevel + 1) % (unsigned long)g_stEngineStructure.ucNumberOfLevels;
				GAM_fn_vAskToChangeLevel( g_stEngineStructure.a_szLevelName[ s_ulLoadAllLevel ] , TRUE );
				osSyncPrintf( "Change to level %s\n", g_stEngineStructure.a_szLevelName[s_ulLoadAllLevel] );
				s_ulWaitFrame = 0L;
			}
		}
#endif /* TEST_LOAD_ALL_MAPS */
/* EndOfOliv' */
 
/* ANNECY MT - 03/11/98 {*/
#if (defined(USE_PROFILER) && !defined(PRESS_DEMO) && !defined(U64))
		GAM_fn_vRasterDumpEndLoop();
#endif
/* END ANNECY MT }*/

		SAF_M_Catch /* BART: in case of ça marche pas => stop everything just après !*/
 
		PRF_fn_vReinitAllChrono();
 
		SAF_M_EndCatch /* BART*/
 
		PRF_fn_vStopChrono( PRF_C_ulFctHIE, NULL );
		PRF_fn_vStartChrono( PRF_C_ulFctMainMisc, NULL );
 
		/*********************/
		/* Special treatment */
		/*********************/
 
		/* Real-Time for cycling textures */
		GLI_vRefreshAllCyclingTextures(
			MTH_M_xDiv(
				MTH_M_xLongToReal(g_stEngineStructure.stEngineTimer.ulUsefulDeltaTime),
				MTH_M_xMul(M_xGetFrameLength(g_stEngineStructure.stEngineTimer), MTH_M_xFloatToReal(1000.0f))
			)
		);
 
#ifndef D_THROW_PRT
		/* New particles mechanics */
		/*fn_vMSPrtSysTreatAllParticlesSystemsForCharacter(g_stEngineStructure.h_WorldCaracter);*/
#endif /* D_THROW_PRT */
 
	} /* !fn_bIsEngineInPause() */

	} /* M_IfcanDoFullStep() */
 
	/**************************/
	/* Cheat code ! for debug */
	/**************************/
#if !defined(PRESS_DEMO)
/* Oliv' - 19/05/1999 - I want to see Zdx too */
#if defined(_DEBUG) || defined(_U64_GLI_BENCH_)

	if (IPT_fn_bIsJustValidated(g_st_3DOS_EntryActions.hDisplayZDC)==IPT_C_TRUE)
	{
		g_ucZDCVisible = (unsigned char)( (g_ucZDCVisible + 1) % 6);
	}

#endif /* _DEBUG || _U64_GLI_BENCH_ */
#endif /* PRESS_DEMO */
/* EndOfOliv' */

#if !defined(PRESS_DEMO)

#if defined(_DEBUG)
	if (IPT_fn_bIsJustValidated(g_st_3DOS_EntryActions.hDisplayOnlyStatic)==IPT_C_TRUE)
	{
		unsigned long ulRasterDisplayMode = PRF_fn_lGetIndependantVariable(PRF_C_ulIdpRasterDisplayMode);
 
		ulRasterDisplayMode &= ~PRF_C_ulShowAll;	/* unset all bits*/
		g_ucWhatDoIDisplay = (unsigned char)( (g_ucWhatDoIDisplay + 1) % 3);
		switch(g_ucWhatDoIDisplay)
		{
		case 0:	ulRasterDisplayMode |= PRF_C_ulShowAll;			break;/* all*/
		case 1: ulRasterDisplayMode |= PRF_C_ulShowStatic;		break;/* static*/
		case 2: ulRasterDisplayMode |= PRF_C_ulShowDynamic;		break;/* dynamic*/
		}
		PRF_fn_vSetIndependantVariable( PRF_C_ulIdpRasterDisplayMode , ulRasterDisplayMode );
	}
 
 
	if (IPT_fn_bIsJustValidated(g_st_3DOS_EntryActions.hDisplayBoundingVolumes)==IPT_C_TRUE)
	{
		g_ucDisplayBoundingVolumes =(unsigned char)(1 - g_ucDisplayBoundingVolumes);
	}
 
#endif	/*_DEBUG*/

#endif /* PRESS_DEMO */
 
    PRF_fn_vStopChrono( PRF_C_ulFctMainMisc, NULL );
 
	/**************************/
	/*       Display          */
	/**************************/
    PRF_fn_vStartChrono( PRF_C_ulFctDisplay, PRF_C_pvRest );
 
 
    PRF_fn_vStopChrono( PRF_C_ulFctDisplay, PRF_C_pvRest );
    PRF_fn_vStartChrono( PRF_C_ulFctDisplaySpecific, PRF_C_pvRest );
 
#if defined(WIN32)
    WaitForSingleObject(g_stEngineStructure.hDrawSem,INFINITE);
#endif /* WIN32 */
 
    PRF_fn_vStopChrono( PRF_C_ulFctDisplaySpecific, PRF_C_pvRest );
 
/* XB 23/06/99 */
#ifndef U64
	if (!GLD_bFlipDeviceWithSynchro(g_stEngineStructure.hGLDDevice,C_DefaultSynchro))
#else /* U64 */
	if (!GLD_bFlipDeviceWithSynchro(NULL,C_DefaultSynchro))
#endif /* U64 */
/* End XB 23/06/99 */
		M_GameFatalError(E_uwGameCantFlipDevice);

	/* Trame counter and timer, right after the VBL synchro! */
	M_bIfIsNotStepping()
	{
		fn_vActualizeEngineClock();
	}
 
#if defined(USE_PROFILER) && !defined(PRESS_DEMO)
	{
 
    PRF_fn_vStopChrono( PRF_C_ulFctMainLoop, NULL );
 
    ulRasterDuration = PRF_fn_lGetIndependantVariable( PRF_C_ulIdpRasterTime );
#pragma warning  (disable : 4146)
    PRF_fn_vSetIndependantVariable( PRF_C_ulIdpRasterTime, -TMR_fn_ulFastGetInternalCounter() );
#pragma warning  (default : 4146)
 
    PRF_fn_vComputeAllChrono ();
 
    PRF_fn_lIncIndependantVariable( PRF_C_ulIdpRasterTime, TMR_fn_ulFastGetInternalCounter() );
	GAM_fn_vSlowDownEngine (PRF_fn_ulTimerCount2Duration( ulRasterDuration ));
#pragma warning  (disable : 4146)
    PRF_fn_lIncIndependantVariable( PRF_C_ulIdpRasterTime, -TMR_fn_ulFastGetInternalCounter() );
#pragma warning  (default : 4146)
 
    GAM_fn_vPrepareShowRasters( PRF_fn_ulTimerCount2Duration( ulRasterDuration ) );
    PRF_fn_vResetAllChrono ();
	PRF_fn_vSetIndependantVariable(PRF_C_ulIdpNbSkippedAnims,0);
    PRF_fn_lIncIndependantVariable( PRF_C_ulIdpRasterTime, TMR_fn_ulFastGetInternalCounter() );
 
    PRF_fn_vStartChrono( PRF_C_ulFctMainLoop, NULL );
    PRF_fn_vStartChrono( PRF_C_ulFctDisplaySpecific, PRF_C_pvRest );
 
 
	}
#endif /* USE_PROFILER && PRESS_DEMO */
#ifdef U64
    PRF_fn_vStartChrono( PRF_C_ulFctDisplay, PRF_C_pvDisplayClearVP );
#endif
 
 
	/* FQ HIGHRES*/
#ifdef U64
 
#if defined(_U64_GLI_BENCH_)
	if(gc_EraseBackground || GLIBENCH_g_bWireFrame)
#else
	if(gc_EraseBackground)
#endif /* _U64_GLI_BENCH_ */
	{
		if (!GLD_bClearViewportWithChoice(NULL,g_stEngineStructure.hGLDFixViewport,GLD_C_CLEAR_BACKBUF | GLD_C_CLEAR_ZBUF))
			M_GameFatalError(E_uwGameCantClearViewPort);
	}	
	else
	{
		if (!GLD_bClearViewportWithChoice(NULL,g_stEngineStructure.hGLDFixViewport,GLD_C_CLEAR_ZBUF))
			M_GameFatalError(E_uwGameCantClearViewPort);
	}
 
#else /* !U64 */
 
	if(gc_EraseBackground)
	{
		if (!GLD_bClearViewportWithChoice(g_stEngineStructure.hGLDDevice,g_stEngineStructure.hGLDFixViewport,GLD_C_CLEAR_BACKBUF | GLD_C_CLEAR_ZBUF))
			M_GameFatalError(E_uwGameCantClearViewPort);
	}
	else
	{
		if (!GLD_bClearViewportWithChoice(g_stEngineStructure.hGLDDevice,g_stEngineStructure.hGLDFixViewport,GLD_C_CLEAR_ZBUF))
			M_GameFatalError(E_uwGameCantClearViewPort);
	}
 
#endif /* U64 */
 
    GLI_xClearViewingList();
 
#ifdef U64
    PRF_fn_vStopChrono( PRF_C_ulFctDisplay, PRF_C_pvDisplayClearVP);
#endif
 
#if defined(WIN32)
	/* GuS :  We tell the device we are going to do the rendering. 
	          Must be called before any rendering !*/
	GLD_bBeginWriteToDevice( mhDisplayDevice3D );
#endif /*WIN32*/
 
#ifndef U64
	GLI_vUpdateEffectData( g_stEngineStructure.stEngineTimer.ulUsefulDeltaTime );
#endif
 
    PRF_fn_vStopChrono( PRF_C_ulFctDisplaySpecific, PRF_C_pvRest);
    PRF_fn_vStartChrono( PRF_C_ulFctMainMisc, NULL );
 

#if !defined(PRESS_DEMO)

#if !defined(U64) && defined(USE_PROFILER) && !defined(PRESS_DEMO)
    if (GetAsyncKeyState ('M') && GetAsyncKeyState (VK_CONTROL) && GetAsyncKeyState (VK_SHIFT))
    {
        MMG_fn_vDumpMemory ();
        fn_vGameTestMemory();
		GAM_fn_vRasterDump();
    }
#endif

#endif /* PRESS_DEMO */
 
    /******************************/
    /* Saving Game and Extra Game */
    /******************************/
#if !defined(ACTIVE_EDITOR)
    /*if (g_stSavedGame.bSaveAsked)
    {
		fn_bPlayerSaveGameAll();
    }*/
    /*if (g_stExtrasGame.bSaveAsked)
    {
		fn_bSaveCurrentExtrasGame();
    }*/
#endif /* ACTIVE_EDITOR */
 
	if (!GLD_bRequestWriteToViewport(mhDisplayDevice3D, mhDisplayViewport3D, &g_stEngineStructure.stViewportAttr, &bEnabledWrite))
		M_GameFatalError(E_uwGameCantWriteToViewPort);
 
 
	if (bEnabledWrite)
	{
		HIE_tdxHandleToSuperObject   hSprObjCamera;
		MTH3D_tdstVector stAbsolutePositionOfCamera;
		HIE_tdxHandleToSuperObject hCamCurrentSector;
 
		GEO_fn_vMorphAddInMainLoop();
 
/* Oliv' - 19/05/1999 - I want to see Zdx too */
#if defined(_DEBUG) || defined(_U64_GLI_BENCH_)
/* EndOfOliv' */
 
		/* Zones display */
		if(g_ucZDCVisible)
		{
			HIE_fn_vInitMatrixStack();
			HIE_fn_bInitCameraMatrixStack(&g_stEngineStructure.stViewportAttr);
			ZDX_fn_vDisplayAllZdx(&g_stEngineStructure.stViewportAttr,
				fn_h_SectInfoGetCurrentSector(
				M_GetMSHandle(CAM_fn_hGetActiveCamera(CAM_e_MainViewport),SectInfo)));
		}
 
/* Oliv' - 19/05/1999 - I want to see Zdx too */
#endif /* _DEBUG || _U64_GLI_BENCH_ */
/* EndOfOliv' */
 
#if defined(_DEBUG)

		/*ANNECY TQ 11/03/98{*/
		if(g_ucDisplayBoundingVolumes)
		{
			HIE_fn_vInitMatrixStack();
			HIE_fn_bInitCameraMatrixStack(&g_stEngineStructure.stViewportAttr);
			ZDX_fn_vDisplayAllBoundingVolumes(&g_stEngineStructure.stViewportAttr,
				fn_h_SectInfoGetCurrentSector(
				M_GetMSHandle(CAM_fn_hGetActiveCamera(CAM_e_MainViewport),SectInfo)));
		}
		/*ENDANNECY TQ}*/
 
		/*ANNECY TQ 27/04/98{*/
#endif	/*_DEBUG*/
		/*ENDANNECY TQ}*/
 
		        PRF_fn_vStopChrono( PRF_C_ulFctMainMisc, NULL );
        PRF_fn_vStartChrono( PRF_C_ulFctDisplay, PRF_C_pvMisc );
		PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
 
		/* total display */
#ifdef __3DOSLIGHTS
 
		hSprObjCamera = CAM_fn_hGetActiveCamera(CAM_e_MainViewport);
/* ANNECY AV DEMO {*/
#ifndef U64
#ifndef RETAIL
        if (g_DEMO_KeybTest == DEMO_RECORD )  DEMO_SaveInfo (hSprObjCamera);
#endif /* RETAIL */
#endif
/* END ANNECY AV }*/
		POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix ( hSprObjCamera), &stAbsolutePositionOfCamera);
		hCamCurrentSector = fn_h_SectInfoGetCurrentSector(M_GetMSHandle(hSprObjCamera,SectInfo));
 
		fn_vSendBackGroundColor(hCamCurrentSector);
 
	/*FQ : Here we display the Sky... of course ;-)*/
	/*/////////////////////////////////////////////*/
		#ifdef U64
		#ifndef RETAIL
			/* FQ LIGHTVIS*/
			g_LightDrawnThisFrame=0;
		#endif /* RETAIL*/
			fn_vDisplaySky(&g_stEngineStructure.stViewportAttr);
		#endif /*U64*/
 
        PRF_fn_vIncreaseVariable( PRF_C_ulVarCurrentSector, PRF_C_pvCameraCurrentSector, (unsigned long)hCamCurrentSector);
 
/* Oliv' - We NEED the default flag too, - 25/02/1999 */
		/*#ifndef U64*/
		/* this call is not necessary for U64, because there are no mirrors for them*/	/* YES WE WANT IT TOO ON U64 !!*/
/* ANNECY MT - 11/03/99 { */
		/* fn_vSetOutOfVisibilityCustomBitOfAllActiveActors(); */
/* END ANNECY MT } */
		/*#endif*/
/* EndOfOliv' */
 
/* XB 23/06/99 */
#ifndef U64
		SCT_fn_vSendSectorWhereIAmToViewportWithMirror(
			&stAbsolutePositionOfCamera,
			g_stEngineStructure.hGLDDevice,
			g_stEngineStructure.hGLDViewport,
			&g_stEngineStructure.stViewportAttr,
			hCamCurrentSector,
			g_stEngineStructure.ulDisplayMode
		);
#else /* U64 */
		SCT_fn_vSendSectorWhereIAmToViewportWithMirror(
			&stAbsolutePositionOfCamera,
			NULL,
			NULL,
			&g_stEngineStructure.stViewportAttr,
			hCamCurrentSector,
			g_stEngineStructure.ulDisplayMode
		);
#endif /* U64 */
/* End XB 23/06/99 */
 
#ifdef WIN32
	fn_bDisplaySky(hCamCurrentSector, hSprObjCamera, &g_stEngineStructure.stViewportAttr);
#endif
 
#endif	/* __3DOSLIGHTS*/
 
#ifndef D_THROW_PRT
		/* New particles display */
		/*if( g_stEngineStructure.h_WorldCaracter!=NULL )
			fn_vMSPrtSysPreDrawAllParticlesSystemsForCharacter(g_stEngineStructure.h_WorldCaracter);*/
#endif /* D_THROW_PRT */
 
		PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
        PRF_fn_vStopChrono( PRF_C_ulFctDisplay, PRF_C_pvMisc );
 
	}
    else
        PRF_fn_vStopChrono( PRF_C_ulFctMainMisc, NULL );


	M_FullStepDone() ;

#if defined(WIN32) && !defined(RETAIL) && !defined(PRESS_DEMO)
	if (IPT_fn_bIsJustValidated(g_st_3DOS_EntryActions.hStartStopStep) == IPT_C_TRUE)
	{
		if ( GAM_g_iStepMode >= 0 )
		{
			GAM_g_iStepMode = -1 ;
			/* fake a 1 VBL frame rate */
			fn_vLoadEngineClock ( ) ;
#if !defined(U64) && defined(_DEBUG)
			Sleep ( ( g_ucSlowDownEngine && g_ucSlowDownTime ) ? g_ucSlowDownTime : 16 ) ;
#else
			Sleep ( 16 ) ;
#endif
			fn_vActualizeEngineClock() ;
		}
		else
		{
			GAM_g_iStepMode = 0 ;
			/* remember the date when the step mode is engaged */
			fn_vSaveEngineClock ( ) ;
		}
	}

	if (IPT_fn_bIsJustValidated(g_st_3DOS_EntryActions.hPulseStep) == IPT_C_TRUE)
	{
		if ( GAM_g_iStepMode >= 0 )
		{
			GAM_g_iStepMode = 1 ;
			/* fake a 1 VBL frame rate */
			fn_vLoadEngineClock ( ) ;
#if !defined(U64) && defined(_DEBUG)
			Sleep ( ( g_ucSlowDownEngine && g_ucSlowDownTime ) ? g_ucSlowDownTime : 16 ) ;
#else
			Sleep ( 16 ) ;
#endif
			fn_vActualizeEngineClock() ;
			fn_vSaveEngineClock ( ) ;
		}
	}
#endif /* WIN32 && !RETAIL && !PRESS_DEMO */

}
 
/*-----------------------------------------------------------------------------
*  Description : reput the character at root
*-----------------------------------------------------------------------------
*  Input :         Super-Object
*  Output :        void
*-----------------------------------------------------------------------------
*  Creation date : 14/10/96            Author : François
*-----------------------------------------------------------------------------
*  Modification date :                 Modification Author :
*  Modifications :
*---------------------------------------------------------------------------*/
void fn_vReputCharacterSuperObjectAtTheWorld(HIE_tdxHandleToSuperObject h_SupObject)
{
	HIE_fn_vChangeFather(h_SupObject,gp_stDynamicWorld, fn_ucStandardGameGetPlatFormType(M_GetMSHandle(h_SupObject,StandardGame)));
}
 
/*-----------------------------------------------------------------------------
*  Description : Search all character's super object, and link to the root
*                recurse function.
*-----------------------------------------------------------------------------
*  Input :    void
*  Output :   void
*-----------------------------------------------------------------------------
*  Creation date : 07/06/97            Author : Olivier Jourdan
*-----------------------------------------------------------------------------
*  Modification date :                 Modification Author :
*  Modifications :
*---------------------------------------------------------------------------*/
/*
void fn_vRecursivePartOfFatherSonLinksDestruction(
												  HIE_tdxHandleToSuperObject _hSuperObj,
												  ACP_tdxBool _bFather)
{
	HIE_tdxHandleToSuperObject hChild, hSon;
 
	if( HIE_fn_ulGetSuperObjectType(_hSuperObj)==C_ucCharacter )
	{
		//hChild = _hSuperObj->hFirstElementSta;
		hChild = HIE_M_hFirstChild(_hSuperObj);
		while(hChild)
		{
			//hSon = hChild->hNextBrotherSta;
			hSon = HIE_M_hNextChild(hChild);
			fn_vRecursivePartOfFatherSonLinksDestruction(hChild,TRUE);
			hChild = hSon;
		}
		// if(_hSuperObj->hFatherSta != gp_stDynamicWorld)
		if(HIE_M_hGetSuperObjectFather(_hSuperObj) != gp_stDynamicWorld)
			fn_vReputCharacterSuperObjectAtTheWorld(_hSuperObj);
	}
	else
	{
		//hChild = _hSuperObj->hFirstElementSta;
		hChild = HIE_M_hFirstChild(_hSuperObj);
		while(hChild)
		{
			//hSon = hChild->hNextBrotherSta;
			hSon = HIE_M_hNextChild(hChild);
			fn_vRecursivePartOfFatherSonLinksDestruction(hChild,FALSE);
			hChild = hSon;
		}
	}
}
*/
void fn_vRecurseDestructChildLink(HIE_tdxHandleToSuperObject _hSuperObjRoot)
{
	HIE_tdxHandleToSuperObject hChild,hNextChild,hPlatformChild,hPlatformNextChild;
	long xI, xJ;
 
	HIE_M_ForEachMovingChildOf(_hSuperObjRoot,hChild,hNextChild,xI)
	{
		if( HIE_fn_ulGetSuperObjectType(hChild)==HIE_C_ulActor )
		{
			if( fn_ucStandardGameGetPlatFormType(M_GetMSHandle(hChild,StandardGame))!=0 )
			{
				/* Destruct child Links*/
				HIE_M_ForEachMovingChildOf(hChild,hPlatformChild,hPlatformNextChild,xJ)
				{
					if( HIE_fn_ulGetSuperObjectType(hPlatformChild)==HIE_C_ulActor )
					{
            /*since we handle the children of a platform, they cannot be platform themselves!*/
						HIE_fn_vChangeFather(hPlatformChild,_hSuperObjRoot, FALSE);
					}
				}
			}
			else
			{
				break;
			}
		}
	}
}
 
void fn_vDestructAllFatherSonLinks(void)
{
	HIE_tdxHandleToSuperObject hChild,hNextChild,hMainCharacter;
	long xI;
 
	hMainCharacter = MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode());
	HIE_M_ForEachMovingChildOf(hMainCharacter,hChild,hNextChild,xI)
	{
		if( HIE_fn_ulGetSuperObjectType(hChild)==HIE_C_ulActor )
		{
			HIE_fn_vChangeFather(hChild,gp_stDynamicWorld, fn_ucStandardGameGetPlatFormType(M_GetMSHandle(hChild,StandardGame)));
		}
	}
 
	/*fn_vRecursivePartOfFatherSonLinksDestruction(gp_stDynamicWorld,FALSE);*/
 
	fn_vRecurseDestructChildLink(gp_stDynamicWorld);
 
	fn_vRecurseDestructChildLink(gp_stInactiveDynamicWorld);
}
 
/*ANNECY CG DISPLAY ACTIVATED GENDOORS 16/06/98 {*/
 
#ifndef U64
 
static GEO_tdstGeometricObject * p_stGeoModel4Gendoors;
static GEO_tdstGeometricObject * p_stGeoCurr4Gendoors;
/*static*/ unsigned char           ucIsInitDone4Gendoors = 0;
BOOL bDisplayCenterInitIsDone = FALSE;
 
 
/***********************************************************************************************/
/*  Name        : InitGeoModel4Gendoors*/
/*  Description : Loads the Geo Obj used to display the Gendoors from .mod file*/
/*  Author      : Christophe Giraud*/
/*  Date        : 18/06/98*/
/***********************************************************************************************/
GEO_tdstGeometricObject * InitGeoModel4Gendoors()
{
  GEO_tdstGeometricObject * p_stLoaded;
 
 
  p_stLoaded = (GEO_tdstGeometricObject *) SCR_M_ul_RdL0_ExtractLongValue(
  SCR_fnp_st_RdL0_AnalyseSection( "GameData\\World\\Graphics\\Objects\\Banks\\KeyGendoor\\KeyGendoor.mod^Geometric:KeyGendoor", SCR_CDF_uw_Anl_ForceAnalyse ), 0 );
 
/*
  p_stLoaded = (GEO_tdstGeometricObject *) SCR_M_ul_RdL0_ExtractLongValue(
    SCR_fnp_st_RdL0_AnalyseSection( "GameData\\World\\Graphics\\Objects\\Banks\\Waypoints\\wp.mod^Geometric:Box01", SCR_CDF_uw_Anl_ForceAnalyse ), 0 );
*/
  return p_stLoaded;
}
 
/***********************************************************************************************/
/*  Name        : fn_vDisplayActivatedGendoors*/
/*  Description : Displays Activated Gendoors*/
/*  Author      : Christophe Giraud*/
/*  Date        : 18/06/98*/
/***********************************************************************************************/
#if !defined(PRESS_DEMO)

#ifndef RETAIL
void fn_vDisplayActivatedGendoors( GLD_tdstViewportAttributes * p_stViewport, unsigned long ulDrawMask )
{
	tdxHandleToObjectsTablesList		hObjetTable;
	ACP_tdxIndex		                xNbVertices;
	MTH3D_tdstVector	                stVector;
	HIE_tdxHandleToSuperObject			hCurrentSector,
										hPersoPrincipal,
										hCharacterSO;
	SECT_tdxHandleOfElementLstCharacter	hCharacterElement;
    char szText[255];
	int i;
 
	/****** ONLY FOR DEBUG ****************************/
	/**/ char					*cName;
	/**/ MS_tdxHandleToBrain	hBrain;
	/****** ONLY FOR DEBUG ****************************/
 
	/*--- First time we are here ??? ---*/
    if( !ucIsInitDone4Gendoors )
    {
      /*--- Loading Geo Objs from file ---*/
      p_stGeoModel4Gendoors = InitGeoModel4Gendoors();
      p_stGeoCurr4Gendoors  = InitGeoModel4Gendoors();
      ucIsInitDone4Gendoors = 1;
	  GLI_vEndofGeometricLoad();
	}
 
	sprintf( szText, "[G] Display Gendoors" );
	GLI_vDisplayPolices( (unsigned char *)szText, 450, 435 );
 
	/* Point to the current sector where is the character*/
	hPersoPrincipal = MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode());
	hCurrentSector  = fn_h_SectInfoGetCurrentSector(M_GetMSHandle(hPersoPrincipal, SectInfo));
 
	/* Find all characters in the current sector of the list*/
	SECT_M_ForEachCharListInSector(hCurrentSector, hCharacterElement, i)
	{
 
	  /* Get character in the list*/
	  hCharacterSO = SECT_GetCharacterInList( hCharacterElement );
 
	  hObjetTable = fn_vGetDefaultObjectsTableOfFamily( fn_h3dDataGetFamily(M_GetMSHandle(hCharacterSO,3dData)) );
 
	  /****** ONLY FOR DEBUG ****************************/
	  /**/	  hBrain = M_GetMSHandle(hCharacterSO,Brain);
	  /**/	  if (hBrain)
	  /**/			cName = AI_M_szGetPersoName(AI_M_stGetMindOfSuperObj(hCharacterSO));
	  /****** ONLY FOR DEBUG ****************************/
 
	  if ( hObjetTable== NULL )
	  {
		  /* Coordinates of the character*/
		  POS_fn_vGetTranslationVector( HIE_fn_hGetSuperObjectGlobalMatrix( hCharacterSO ), &stVector );
 
		  for(xNbVertices=0; xNbVertices<p_stGeoCurr4Gendoors->xNbPoints ; xNbVertices++)
		  {
			/*--- Translates the current object at the waypoint position*/
			MTH3D_M_vAddVector(
								&(p_stGeoCurr4Gendoors->d_stListOfPoints[ xNbVertices ]),
		  						&(p_stGeoModel4Gendoors->d_stListOfPoints[ xNbVertices ]),
								&stVector
							  );
		  }
          /*--- Translates the current object bounding sphere center at the gendoor position*/
          MTH3D_M_vAddVector( &(p_stGeoCurr4Gendoors->xBoudingSphereCenter),&(p_stGeoModel4Gendoors->xBoudingSphereCenter),&stVector);
 
		  /*--- Sends the object to the Display Routines*/
		  GLI_xSendObjectToViewportWithLights( p_stViewport, p_stGeoCurr4Gendoors, ulDrawMask );
	  }
 
	}
}		  
#endif /*RETAI*/

#endif /* PRESS_DEMO */

 
#ifndef RETAIL
void fn_vDisplayCenterOfPersos( GLD_tdstViewportAttributes *p_stViewport, unsigned long ulDrawMask )
{
    static ACP_tdxHandleOfMaterial      hCenterMaterial;
	ACP_tdxHandleOfTexture              pCenterTexture;
    HIE_tdxHandleToSuperObject          hCurrentSector,
                                        hPersoPrincipal,
                                        hCharacterSO;
    SECT_tdxHandleOfElementLstCharacter	hCharacterElement;
    GEO_tdxHandleToMatrix               hGlobalMatrix;
    GLI_tdstSpecificAttributesFor3D     *p_st3DAtributes;
    POS_tdstCompletePosition            matrix;
 
    GLI_tdstAligned2DVector             a2_st2DVertex;
    GLI_tdstAligned3DVector             a2_stVertex;
 
    MTH3D_tdstVector p;
 
    register int i;
    register float near1;
    
    /**** First time ****/
    if(!bDisplayCenterInitIsDone)
    {
        GLI_xCreateMaterial(&hCenterMaterial);
        GLI_xLoadTexture(&pCenterTexture, NULL, "center.bmp", 0, 0);
        if (pCenterTexture) 
        {
            TEX_vSetTextureQualityLevel(pCenterTexture,(char)TEX_C_QHIGH);
        }
        GLI_vEndofGeometricLoad(); 
        GLI_xSetMaterialTexture(hCenterMaterial,pCenterTexture);
        bDisplayCenterInitIsDone = TRUE;
    }
 
   	/* Point to the current sector where is the character*/
	hCurrentSector  = fn_h_SectInfoGetCurrentSector( M_GetMSHandle( MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode() ),	SectInfo ) );
	hPersoPrincipal = MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode() );
 
	/* Find all characters in the current sector of the list*/
	SECT_M_ForEachCharListInSector(hCurrentSector, hCharacterElement, i)
	{
        /* Get character in the list*/
        hCharacterSO  = SECT_GetCharacterInList( hCharacterElement );
        hGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix(hCharacterSO);
        POS_fn_vGetTranslationVector(hGlobalMatrix, &p);
 
        p_st3DAtributes = (GLI_tdstSpecificAttributesFor3D*)(p_stViewport->p_vSpecificToXD);
        GLI_xGetCameraMatrix(p_st3DAtributes->p_stCam, &matrix);
        GLI_xSerialLinearOp(1, &p, &a2_stVertex, &matrix);
        GLI_xSerialProjection(p_st3DAtributes->p_stCam, 1, &a2_stVertex, &a2_st2DVertex);
 
        near1 = (float)p_st3DAtributes->p_stCam->xNear;
        p_st3DAtributes->p_stCam->xNear += 0.01f; 
        GLI_vDraw2DSprite(p_stViewport, a2_st2DVertex.xX-5, a2_st2DVertex.xX + 5, a2_st2DVertex.xY-5, a2_st2DVertex.xY + 5, hCenterMaterial);           
        p_st3DAtributes->p_stCam->xNear = near1; 
    }
}		  
#endif /* RETAIL */
 
#endif
/* }ENDANNECY CG*/
 
/*-----------------------------------------------------------------------------
*  Description : Display All Objects in Main Viewport
*-----------------------------------------------------------------------------
*  Input :         none
*  Output :        none
*-----------------------------------------------------------------------------
*  Creation date : 26/08/96            Author : Christophe
*-----------------------------------------------------------------------------
*  Modification date :                 Modification Author :
*  Modifications :
*---------------------------------------------------------------------------*/

#ifdef U64
extern int SCREEN_HT;
#endif

void fn_vDisplayAll()
{
	PRF_fn_vStartChrono( PRF_C_ulFctDisplaySpecific, PRF_C_pvSendToList );
#ifdef U64
	PRF_fn_vStartChrono( PRF_C_ulFctDisplay, PRF_C_pvDisplaySendToList );
#endif

#if !defined(PRESS_DEMO)

#if !defined(U64) && defined(_DEBUG)
	if (g_ucSlowDownEngine)
	{
		char szText[255];

		sprintf( szText, "[A] Slowdown engine : %d" , g_ucSlowDownTime);
		DisplayPolices( (char *)szText, 280, 450 );
	}
#endif

#if defined(_DEBUG)
	/*--- Displaying Waypoints ---*/
	if( g_ucDisplayWaypoints == 1 )
		WP_SendWaypointsToViewport( &g_stEngineStructure.stViewportAttr, g_stEngineStructure.ulDisplayMode );
 
	/*ANNECY CG DISPLAY ACTIVATED GENDOORS 16/06/98 {*/
	/*--- Displaying Activated Gendoors ---*/
#ifndef RETAIL
    if(g_ucDisplayActivatedGendoors)
	{
	  fn_vDisplayActivatedGendoors( &g_stEngineStructure.stViewportAttr, g_stEngineStructure.ulDisplayMode );
	}
#endif
	/* } ENDANNECY CG 16/06/98*/
 
 
  	/*--- Display center of perso ---*/
#ifndef RETAIL
    if(g_ucDisplayCenters)
	{
	  fn_vDisplayCenterOfPersos( &g_stEngineStructure.stViewportAttr, g_stEngineStructure.ulDisplayMode );
	}
#endif
 
#endif	/*_DEBUG*/

#endif /* PRESS_DEMO */

 
	GLI_xSendListToViewport(&g_stEngineStructure.stViewportAttr);
 
#ifndef U64
	if (!GLD_bWriteToViewportFinished(g_stEngineStructure.hGLDDevice, g_stEngineStructure.hGLDViewport))
		M_GameFatalError(E_uwGameCantWriteToViewPortFinished);
#endif

#if !defined(PRESS_DEMO)

#if !defined(U64) && defined(_DEBUG)
	if ( g_ucDisplayRayTraceSegments )
	{
		int i;
		/* push the camera matrix*/
		POS_tdstCompletePosition stMatrix;
		GLI_xGetCameraMatrix(((GLI_tdstSpecificAttributesFor3D*)(g_stEngineStructure.stViewportAttr.p_vSpecificToXD))->p_stCam,&stMatrix);
		GLI_xLoadMatrix(&stMatrix);
		/*loop over the recorded segments and draw them, then clear the segment list!*/
		for ( i = 0; i < 30; i ++ )
		if ( g_wRayTraceSegmentLife[i] )
		{
			g_wRayTraceSegmentLife[i] --;
			GLI_xDraw3DLine16(
				&g_stEngineStructure.stViewportAttr,
				&g_stRayTraceSegmentOrigin[i],
				&g_stRayTraceSegmentEnd[i],
				0xFFFFFFFF
			);
		}
		GLI_xPopMatrix();
		GLI_vDisplayPolices( "[H] Display Raytrace", 450, 420 );
	}
#endif /* !U64 && _DEBUG */

#endif /* PRESS_DEMO */

	fn_vDisplayFix();


#if !defined(PRESS_DEMO)
#ifdef WIN32
#ifndef RETAIL
    {
        static MTH3D_tdstVector stTopLeft       = { 0.0685f, 0.125f, 0 };/* = { 0.067f, 0.067f, 0 };*/
        static MTH3D_tdstVector stBottomRight   = { 1.0f-0.0684f, 1.0f-0.0625f, 0 };/*= { 0.934f, 0.937f, 0 };*/
        static char cDisplayRectangle = 0;
        static char cColor = 0;
        static unsigned long aul_Color[5] = { 0xFFFFFFFF , 0xFF0000, 0xFF00, 0xFF, 0 };

		if (IPT_fn_bIsJustValidated(g_st_3DOS_EntryActions.hDisplayTextOverScanLimit)==IPT_C_TRUE)
        {
            if (IPT_fn_bIsJustValidated(g_st_3DOS_EntryActions.hAltDisplayTextOverScanLimit)==IPT_C_TRUE)
                cColor = (char) ((cColor + 1) % 5);
            else
                cDisplayRectangle = (char) ~cDisplayRectangle;
        }

        if (cDisplayRectangle)
            GLI_fnv_DrawRectangle( &g_stEngineStructure.stViewportAttr, &stTopLeft, &stBottomRight, aul_Color[cColor] );
    }
#endif /* RETAIL */
#endif /* WIN32 */
#endif /* PRESS_DEMO */
 
#if defined(U64) && ( (defined(USE_PROFILER) && !defined(PRESS_DEMO)) || defined(_U64_GLI_BENCH_) )
 GLD_bDisplayRastersForDeviceWithNoLock(&g_stEngineStructure.stViewportAttr, /*g_stEngineStructure.hGLDDevice*/NULL);
#endif
 
	/*--- Infos display ---*/
#if !defined(PRESS_DEMO)
	CAM_vDisplayInfo();
 
	PRF_fn_vStopChrono( PRF_C_ulFctDisplaySpecific, PRF_C_pvSendToList );
	PRF_fn_vStartChrono( PRF_C_ulFctMainMisc, NULL );
 
#endif /* PRESS_DEMO */

#if !defined(RETAIL) || defined(FINAL_VERSION_FOR_TESTERS)
	if ( g_cChooseLevel > -1 )
	{
		char szString[100];
		sprintf( szString, "Change To Map : %s", g_stEngineStructure.a_szLevelName[ g_cChooseLevel ] );
#if !defined(U64)
#ifndef RETAIL
		GLI_vDisplayPolices( (unsigned char *) szString, 0, 0 );
#endif
#else
		GLI_vPrintGuruError( SCREEN_HT-40 ,(unsigned char *)szString );
#endif /* U64 */
	}
#endif /* !defined(RETAIL) || defined(FINAL_VERSION_FOR_TESTERS) */
 
 
/* Oliv' - 01/07/1998 - Who moved this ???? Arrrggg !!!*/
#if defined(U64)
	PRF_fn_vStopChrono( PRF_C_ulFctMainMisc, NULL );
	if (!GLD_bWriteToViewportFinished(NULL,NULL))
		M_GameFatalError(E_uwGameCantWriteToViewPortFinished);
	PRF_fn_vStartChrono( PRF_C_ulFctMainMisc, NULL );
#endif /* U64 */
/* EndOfOliv'*/
 

/* Oliv' - 19/05/1999 - I want to see Zdx too */
#if defined(_U64_GLI_BENCH_)
	if( g_ucZDCVisible )
		GLI_vPrintGuruError( SCREEN_HT-60, (unsigned char *) g_szZoneTypes[g_ucZDCVisible-1] );
#endif /* _U64_GLI_BENCH_ */
/* EndOfOliv'*/
 
#if !defined(PRESS_DEMO)

#if defined(_DEBUG)

#ifndef RETAIL
	if( g_ucZDCVisible )
		GLI_vDisplayPolices( (unsigned char *) g_szZoneTypes[g_ucZDCVisible-1], 560, 10);
#endif /*RETAIL*/
 
	/*
	if( g_ucWhatDoIDisplay )
		GLI_vDisplayPolices( (unsigned char *) g_szDisplayTypes[g_ucWhatDoIDisplay-1], 260, 10);
	*/
 
#ifndef RETAIL
	if( g_ucSCTDisplaySectors )
	{
		SECT_vDisplaySectorInfos();
#if defined(GAM_USE_SCRIPT)
		if( g_ucSCTDisplaySectors == 3 )
		{
			unsigned int        Pos = 0;
			struct tdstEngineObject_  *Pointer;
			long            j = 0;
			char            szInfos[ 255 ];
			while(Pos < g_st3DOSLinkTable.stCharacter.stLinkArray.uiNumValues)
			{
				if(g_st3DOSLinkTable.stCharacter.stLinkArray.d_stDynArray[Pos].eState != SCR_EDAS_DyAr_Free)
				{
					Pointer = (struct tdstEngineObject_ *) ((SCR_tdst_Link_Value *)(g_st3DOSLinkTable.stCharacter.stLinkArray.d_stDynArray[Pos].d_vElement))->ulValue;
					if(Pointer->h_StandardGame)
					{
						if(/*M_ObjectIsActive(Pointer) || */M_ObjectIsAlreadyTreated(Pointer))
						{
							sprintf( szInfos, "[%i] %s", j+1, 1+strrchr( ((SCR_tdst_Link_Value *) (g_st3DOSLinkTable.stCharacter.stLinkArray.d_stDynArray[Pos].d_vElement))->p_szKey ,':'));
							GLI_vDisplayPolices( (unsigned char *) szInfos, 150, 50 + 20*j);
							j++;
						}
					}
				}
				(Pos)++;
			}
		}
#endif
	}
#endif /* RETAIL */
#endif	/*_DEBUG*/
 
	PRF_fn_vStopChrono( PRF_C_ulFctMainMisc, NULL );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplaySpecific, PRF_C_pvSendToList );
 
#endif /* PRESS_DEMO */

#if defined(WIN32)
	GLI_fn_vShowFrameRate( &g_stEngineStructure.stViewportAttr );
	ReleaseSemaphore(g_stEngineStructure.hDrawSem,1,NULL);
	GLD_bEndWriteToDevice( g_stEngineStructure.hGLDDevice );
#endif ./* WIN32 */
 
	PRF_fn_vStopChrono( PRF_C_ulFctDisplaySpecific, PRF_C_pvSendToList );
}
 
/*-----------------------------------------------------------------------------
*  Description : get nb perso activable in the sector
*-----------------------------------------------------------------------------
*  Input :         Sector
*  Output :        Nb Perso Activable
*-----------------------------------------------------------------------------
*  Creation date : 04/03/98            Author : Carlos Torres
*---------------------------------------------------------------------------*/
long GAM_fn_lGetNbPersoActivableInSector(HIE_tdxHandleToSuperObject hSector)
{
	long lNbPerso=0;
	SECT_tdxHandleOfElementLstCharacter hCharacterList;
	int i;
 
	/* Look in character list*/
	SECT_M_ForEachCharListInSector(hSector,hCharacterList,i) {
		if( M_ObjectIsActivable((struct tdstEngineObject_*)HIE_fn_hGetSuperObjectObject(SECT_GetCharacterInList(hCharacterList))) )
			lNbPerso++;
	}
 
	return lNbPerso;
}
 
/*-----------------------------------------------------------------------------
*  Description : get nb perso active
*		a Perso is active if it is in an active(or associated) sector and
*			if it is activable
*-----------------------------------------------------------------------------
*  Output :        Nb Perso Active
*-----------------------------------------------------------------------------
*  Creation date : 04/03/98            Author : Carlos Torres
*---------------------------------------------------------------------------*/
long GAM_fn_lGetNbPersoActive()
{
	long lNbPerso;
	HIE_tdxHandleToSuperObject hActiveSector;
	SECT_tdxHandleOfElementLstActivityInteraction hActivityList;
	int i;
 
	/* Get Active Sector*/
	hActiveSector=fn_h_SectInfoGetCurrentSector(M_GetMSHandle(MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode()),SectInfo));
 
	/* get nb perso in active sector*/
	lNbPerso = GAM_fn_lGetNbPersoActivableInSector(hActiveSector);
 
	/* get nb perso in associated sector*/
	SECT_M_ForEachActivityNodeInActivityInteractionList(hActiveSector,hActivityList,i) {
		lNbPerso += GAM_fn_lGetNbPersoActivableInSector(SECT_GetSectorInActivityList(hActivityList));
	}
 
	return lNbPerso;
}
 
/*-----------------------------------------------------------------------------
*  Description : check if a character is active
*		a Perso is active if it is active or already treated
*-----------------------------------------------------------------------------
*  Output :        Boolean
*-----------------------------------------------------------------------------
*  Creation date : 04/03/98            Author : Carlos Torres
*---------------------------------------------------------------------------*/
unsigned char GAM_fn_bIsCharacterActive(HIE_tdxHandleToSuperObject hSuperObj)
{
	/*return (unsigned char)(M_ObjectIsActive(M_GetEngineObject(hSuperObj)) ||
		M_ObjectIsAlreadyTreated(M_GetEngineObject(hSuperObj)));*/
 
    return (unsigned char)
           ( ((HIE_fn_hGetSuperObjectFather(hSuperObj)==gp_stDynamicWorld) ||
              (HIE_fn_hGetSuperObjectFather(HIE_fn_hGetSuperObjectFather(hSuperObj))==gp_stDynamicWorld))
             && M_ObjectIsActive(M_GetEngineObject(hSuperObj))
           );
}
 
/*-----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------*/
 
/*-----------------------------------------------------------------------------
*  Description :
*
*-----------------------------------------------------------------------------
*  Output :
*-----------------------------------------------------------------------------
*  Creation date : 04/03/98            Author :
*---------------------------------------------------------------------------*/
void fn_vClearDynamicHierarchy(HIE_tdxHandleToSuperObject _hSOCurrentSector)
{
	HIE_tdxHandleToSuperObject						hCharacter,hNextCharacter;
	HIE_tdxHandleToSuperObject						hChildSector;
    SECT_tdxHandleOfElementLstActivityInteraction	hActivityList;
	long											i;
	char											cCounter;
 
	HIE_M_ForEachMovingChildOf(gp_stDynamicWorld,hCharacter,hNextCharacter,i)
	{
		if( ( HIE_fn_ulGetSuperObjectType(hCharacter)==HIE_C_ulActor ) &&
			!CAM_fn_bSuperObjectIsACamera(hCharacter) )
		{
			HIE_fn_vIsolate(hCharacter);
			if( fn_ucStandardGameGetPlatFormType(M_GetMSHandle(hCharacter,StandardGame))!=0 )
			{
				HIE_fn_vSuperObjectAddHead(gp_stInactiveDynamicWorld,hCharacter);
			}
			else
			{
				HIE_fn_vSuperObjectAddTail(gp_stInactiveDynamicWorld,hCharacter);
			}
      /*M_UnactivateObject((struct tdstEngineObject_*)HIE_fn_hGetSuperObjectObject(hCharacter));*/
		}
	}
 
	/**/
	if(_hSOCurrentSector)
	{
		cCounter = (char)g_stEngineStructure.stEngineTimer.ulTrameNumber;
		SECT_vSetCounterInSector( _hSOCurrentSector , cCounter );
		/**/
		SECT_M_ForEachActivityNodeInActivityInteractionList(_hSOCurrentSector,hActivityList,i)
		{
			hChildSector = SECT_GetSectorInActivityList(hActivityList);
			SECT_vSetCounterInSector( hChildSector , cCounter );
		}
	}
}
 
 
/*-----------------------------------------------------------------------------
*  Description :
*
*-----------------------------------------------------------------------------
*  Output :
*-----------------------------------------------------------------------------
*  Creation date : 04/03/98            Author :
* Modif 19/11/98 : stop sound when perso is desactivated - Carlos Torres
*---------------------------------------------------------------------------*/
void fn_vDesinitInactivePerso()
{
	HIE_tdxHandleToSuperObject hCharacter,hChild;
	long i,j;
 
	HIE_M_ForEachChildOf(gp_stInactiveDynamicWorld,hCharacter,i)
	{
		if (M_ObjectIsActive((struct tdstEngineObject_*)HIE_fn_hGetSuperObjectObject(hCharacter)))
		{
			if( fn_ucStandardGameGetPlatFormType(M_GetMSHandle(hCharacter,StandardGame))!=0 )
			{
				HIE_M_ForEachChildOf(hCharacter,hChild,j)
				{
					if (HIE_fn_ulGetSuperObjectType(hChild) == HIE_C_ulActor)
					{
						PLA_fn_vDesInitAllChildOfCharacter(hChild,(struct tdstEngineObject_*)HIE_fn_hGetSuperObjectObject(hChild));
						M_UnactivateObject((struct tdstEngineObject_*)HIE_fn_hGetSuperObjectObject(hChild));
						SND_fn_vKillObjectSound2((long)hChild,g_lSoundObjectTypeAnim);
					}
				}
			}
			PLA_fn_vDesInitAllChildOfCharacter(hCharacter,(struct tdstEngineObject_*)HIE_fn_hGetSuperObjectObject(hCharacter));
			M_UnactivateObject((struct tdstEngineObject_*)HIE_fn_hGetSuperObjectObject(hCharacter));
			SND_fn_vKillObjectSound2((long)hCharacter,g_lSoundObjectTypeAnim);
		}
	}
}
 
 
/*-----------------------------------------------------------------------------
*  Description :
*
*-----------------------------------------------------------------------------
*  Output :
*-----------------------------------------------------------------------------
*  Creation date : 04/03/98            Author :
*---------------------------------------------------------------------------*/
void fn_vInsertActorInDynamicHierarchy(HIE_tdxHandleToSuperObject _hCharacter, ACP_tdxBool _bNewInsert)
{
	/*unsigned long				ulCurrentBits;*/
	struct tdstEngineObject_*	p_stObject;
 
	p_stObject = (struct tdstEngineObject_*)HIE_fn_hGetSuperObjectObject(_hCharacter);
 
/* ANNECY MT - 18/09/98 {*/
	if(	M_ObjectIsActivable(p_stObject)
		&&
		(
		  ( _bNewInsert	/* sector becomes active*/
		    &&
			(
			  !fn_bf1StandardGameGetIsDesactivateAtAll(p_stObject->h_StandardGame)	/* actor alive*/
			  ||
			  (fn_eStandardGameGetInitFlagWhenDeadOrTaken(p_stObject->h_StandardGame) < OI_WhenPlayerIsDead)	/* reinit 'always' or 'OutOfzone'*/
			)
		  )
		  ||	/* sector already active*/
		  (
			!fn_bf1StandardGameGetIsDesactivateAtAll(p_stObject->h_StandardGame)	/* actor alive*/
		  )
		)
	  )
/* END ANNECY MT }*/
	{
		if( HIE_fn_hGetSuperObjectFather(_hCharacter) == gp_stInactiveDynamicWorld )
		{
			if( fn_ucStandardGameGetPlatFormType(M_GetMSHandle(_hCharacter,StandardGame))!=0 )
			{
				HIE_fn_vSuperObjectAddHead(gp_stDynamicWorld,_hCharacter);
			}
			else
			{
				HIE_fn_vSuperObjectAddTail(gp_stDynamicWorld,_hCharacter);
			}
			M_ActivateObject(p_stObject);
			if( _bNewInsert )
			{
				MS_tdxHandleToStandardGame hStdGame = M_GetMSHandle(_hCharacter,StandardGame);
/* ANNECY MT - 11/03/99 { */
				/* fn_vStandardGameSetCustomBits(hStdGame, fn_ulStandardGameGetCustomBits(hStdGame) & ~GAM_C_CustBitOutOfVisibility); */
				fn_vStandardGameSetCustomBits(hStdGame, fn_ulStandardGameGetCustomBits(hStdGame) | GAM_C_CustBitOutOfVisibility);
/* END ANNECY MT } */
			}
		}
	}
}
 
/*-----------------------------------------------------------------------------
*  Description :
*
*-----------------------------------------------------------------------------
*  Output :
*-----------------------------------------------------------------------------
*  Creation date : 04/03/98            Author :
*---------------------------------------------------------------------------*/
void fn_vFillDynamicHierarchy(HIE_tdxHandleToSuperObject _hSOCurrentSector, ACP_tdxBool _bInit)
{
    long											i,j;
    SECT_tdxHandleOfElementLstCharacter				hCharacterList;
    SECT_tdxHandleOfElementLstActivityInteraction	hActivityList;
    HIE_tdxHandleToSuperObject						hCharacter;
    HIE_tdxHandleToSuperObject						hChildSector;
    tdxHandleToAlwaysActiveCharacterNode			hCharAlwaysActiveNode;
    HIE_tdxHandleToSuperObject						*p_hGenerator;
    HIE_tdxHandleToSuperObject						*p_hLastGenerator;
	ACP_tdxIndex									xIndex , xIndexMax;
	char											cCounter;
	ACP_tdxBool										bNewSector;
 
	cCounter = (char)g_stEngineStructure.stEngineTimer.ulTrameNumber;
	/* add actors on actived sectors*/
	bNewSector = (ACP_tdxBool) (_bInit || ( SECT_cGetCounterInSector(_hSOCurrentSector) != cCounter ));
 
    SECT_M_ForEachCharListInSector(_hSOCurrentSector,hCharacterList,i)
    {
        hCharacter = SECT_GetCharacterInList(hCharacterList);
		fn_vInsertActorInDynamicHierarchy(hCharacter , bNewSector);
    }
    /* treat actived sectors*/
    SECT_M_ForEachActivityNodeInActivityInteractionList(_hSOCurrentSector,hActivityList,i)
    {
        hChildSector = SECT_GetSectorInActivityList(hActivityList);
		bNewSector = (ACP_tdxBool) (_bInit || ( SECT_cGetCounterInSector(hChildSector) != cCounter ));
        SECT_M_ForEachCharListInSector(hChildSector,hCharacterList,j)
        {
            hCharacter = SECT_GetCharacterInList(hCharacterList);
			fn_vInsertActorInDynamicHierarchy(hCharacter , bNewSector);
        }
    }
	/* add always actived actors*/
    M_ForEachAlwaysActiveCharacterNode(hCharAlwaysActiveNode,i)
    {
        hCharacter = fn_hGetCharacterInAlwaysActiveCharacterNode(hCharAlwaysActiveNode);
		fn_vInsertActorInDynamicHierarchy(hCharacter , _bInit);
    }
	/* add always*/
    hCharacter = g_stAlways.d_stAlwaysSuperObject;
    p_hGenerator = g_stAlways.d_hAlwaysGenerator;
    p_hLastGenerator = p_hGenerator + g_stAlways.ulMaxNumberOfAlways;
    for( ; p_hGenerator < p_hLastGenerator; hCharacter++, p_hGenerator++ )
    {
		if( M_GetMSHandle(hCharacter, StandardGame) )
		{
			bNewSector = (ACP_tdxBool) (_bInit ||
						(	M_GetMSHandle(hCharacter,SectInfo) &&
							fn_h_SectInfoGetCurrentSector(M_GetMSHandle(hCharacter,SectInfo)) &&
							(SECT_cGetCounterInSector(fn_h_SectInfoGetCurrentSector(M_GetMSHandle(hCharacter,SectInfo))) != cCounter) ));
 
			fn_vInsertActorInDynamicHierarchy(hCharacter , bNewSector);
		}
    }
	/* add fix*/
	xIndexMax = HIE_fn_xGetNumberOfElementInFixViewport () ;
	for ( xIndex=0 ; xIndex<xIndexMax ; xIndex++)
	{
		HIE_tdxHandleToSuperObject hFixSPO ;
 
		hFixSPO = HIE_fn_hGetElementFormFixViewport (xIndex) ;
		fn_vInsertActorInDynamicHierarchy(hFixSPO , _bInit);
	}
}
 
void fn_vUpdateDynamicHierarchy()
{
	HIE_tdxHandleToSuperObject hActualSector;
 
	hActualSector = fn_h_SectInfoGetCurrentSector(M_GetMSHandle(MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode()),SectInfo));
	if( hActualSector != g_hSOCurrentMainSector )
	{
		ACP_tdxBool		bInit;
 
		bInit = (ACP_tdxBool)(g_hSOCurrentMainSector == NULL);
		g_hSOPreviousMainSector = g_hSOCurrentMainSector;
		g_hSOCurrentMainSector = hActualSector;
		fn_vClearDynamicHierarchy(g_hSOPreviousMainSector);
		fn_vFillDynamicHierarchy(g_hSOCurrentMainSector,bInit);
		fn_vDesinitInactivePerso();
	}
}
 
#ifdef ACTIVE_EDITOR
/*-----------------------------------------------------------------------------
*  Description :
*
*-----------------------------------------------------------------------------
*  Output :
*-----------------------------------------------------------------------------
*  Creation date : 04/03/98            Author :
*---------------------------------------------------------------------------*/
void GAM_fn_vFillHierarchyBeforeEditor(void)
{
	/* add all actors in the hierarchy*/
	HIE_tdxHandleToSuperObject hCharacter,hNextCharacter;
	long i;
 
	HIE_M_ForEachMovingChildOf(gp_stInactiveDynamicWorld,hCharacter,hNextCharacter,i)
	{
		if( fn_ucStandardGameGetPlatFormType(M_GetMSHandle(hCharacter,StandardGame))!=0 )
		{
			HIE_fn_vSuperObjectAddHead(gp_stDynamicWorld,hCharacter);
		}
		else
		{
			HIE_fn_vSuperObjectAddTail(gp_stDynamicWorld,hCharacter);
		}
	}
}
 
/*-----------------------------------------------------------------------------
*  Description :
*
*-----------------------------------------------------------------------------
*  Output :
*-----------------------------------------------------------------------------
*  Creation date : 04/03/98            Author :
*---------------------------------------------------------------------------*/
void GAM_fn_vFillHierarchyAfterEditor(void)
{
	HIE_tdxHandleToSuperObject hActualSector;
 
	hActualSector = fn_h_SectInfoGetCurrentSector(M_GetMSHandle(MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode()),SectInfo));
	fn_vClearDynamicHierarchy(hActualSector);
	fn_vFillDynamicHierarchy(hActualSector,TRUE);
 
    TFMT_vInitTextAfficheStructure();
}
#endif
 
