#include "GMT/GmtHandl.h"
#include "ACP_base.h"
#include "GEO.h"
#include "GLI.h"
#include "COL.h"
#include "SPO.h"
#include "LST.h"
#include "MTH.h"
#include "SND.h"
#include "SHW.h"
#include "SPO\HieSpObj.h"
#include "SCR.h"
#include "SCT.h"
#include "PRF.h"
 
#include "PCS.h"
#include "FIL.h"
#include "MEC.h"
#include "PRT.h"
#include "GAM.h"
 
 
extern ACP_tdxBool	bViewingInMirror;
extern ACP_tdxBool  g_bInGameMenu;
 
#ifndef U64
extern SCR_tdst_Link_Table SECT_stLinkTable; /* to be removed...*/
#endif /*U64 AR980316*/
 

#ifdef U64

	extern Gfx *g_CharacterNonTransparentLightsBegin;
	extern char g_HaveLightsBeenCopied;

#endif /* U64 */
 
#if defined(USE_PROFILER) && !defined(PRESS_DEMO)
	void SECT_fn_vUpdateRasterForSector(HIE_tdxHandleToSuperObject _hSprObjSector);
/* ANNECY MT - 14/09/98 { to display info on Wnd screen*/
	extern void DisplayPolices (char * _szText , long _lX , long _lY);
	#define GLI_vDisplayPolices(Text,X,Y)		DisplayPolices((char*)(Text),X,Y)
/* END ANNECY MT }*/
#else
	#define SECT_fn_vUpdateRasterForSector(SprObj)
#endif
 
static BOOL bNotCreateDefaultMaterial=TRUE;
void SCT_fn_vInitMaterialForGoThrough(void)
{
  bNotCreateDefaultMaterial=TRUE;
}
 
/*--- Flag used for displaying extra datas ---*/
unsigned char                g_ucSCTDisplaySectors = 0;
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
char                         * g_szDisplayTypes[2] = { "Static World Only", "Dynamic World Only" };
 
static HIE_tdxHandleToSuperObject		gs_hSprObjSectCurr;
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
/*
 **************************************************************************************************
 **************************************************************************************************
 **************************************************************************************************
 **************************************************************************************************
 */
 
/*
 *=================================================================================================
 *=================================================================================================
 */
void SECT_fn_vSendDynamicLightsOfASector
(
	struct GLD_tdstViewportAttributes_	*_p_stVpt,
	SECT_tdxHandleOfSectorObject _hSectorObject,
	long _lCullingResult
)
{
	SECT_tdxHandleOfElementLstDNMLights hDNMLightsElement, hPrevDNMLightsElement = NULL;
	ACP_tdxIndex						xI;
/* Oliv' - Portage v15 -*/
/* D'après François Queinnec, il vaut mieux laisser le Viewport décider pour la lumière...*/
/* Ceci s'explique d'autant plus que nous sommes sinon obligés de refaire le calcul de distance lumière->perso*/
/* pour simuler correctement l'atténuation de la lumière sphèrique par une lumière parallèle (seules lumières*/
/* temps-réel sur N64.*/
#ifndef U64
#ifdef pasnonpluspourpcvuquecadeconne
	struct GLI_tdstLight_ *hDnmLight;
	MTH_tdxReal xNear, xFar;
	ACP_tdxBool bAddThatOne;
#endif
#endif
 
	LST2_M_DynamicForEachElementOf
	(
		&(_hSectorObject->stListOfDNMLights),
		hDNMLightsElement,
		xI
	)
	{
		/* MR0310 (anti-bug)*/
		if (hDNMLightsElement == hPrevDNMLightsElement)
			break;
 
/* Oliv' - Portage v15*/
#ifndef U64
#ifdef pasnonpluspourpcvuquecadeconne
/* EndOfOliv'*/
		hDnmLight = hDNMLightsElement->hDNMLights;
		bAddThatOne = TRUE;
		if ( GLI_lGetLightType(hDnmLight) == GLI_C_lSphericalLight )
		{
			/*do a culling on the light if relevant (only spherical lights yet).*/
			/*QUESTION: IS THIS FASTER THAN ADDING THE LIGHT AND LET THE VIEWPORT DECIDE IF IT AFFECTS SOMETHING ?*/
			GLI_vGetLightNearFar(hDnmLight, &xNear, &xFar);
			if ( GEO_lCullingGlobalSphere(_p_stVpt, GLI_p_stGetLightTranslation(hDnmLight), xFar, _lCullingResult) == GEO_C_lCullingOut )
			{
				bAddThatOne = FALSE;
			}
		}
		/* if the culling is ok, or no culling was done, add the light*/
		if ( bAddThatOne )
/* Oliv' - Portage v15*/
#endif
#endif /* U64 */
/* EndOfOliv'*/
		{
			GLI_vAddLightToViewport(_p_stVpt, hDNMLightsElement->hDNMLights);
		}
		hPrevDNMLightsElement= hDNMLightsElement;
	}
}
 
/*
 *=================================================================================================
 *=================================================================================================
 */
void SECT_fn_vSendDynamicLightsFromWhereIAmToViewport
(
	struct GLD_tdstViewportAttributes_	*_p_stVpt,
  HIE_tdxHandleToSuperObject			_hSprObjSector
)
{
	SECT_tdxHandleOfSectorObject					hSectorObject;
	SECT_tdxHandleOfElementLstGraphicInteraction	hGraphicInteractionChild;
	ACP_tdxIndex									xI;
 
	hSectorObject = (SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(_hSprObjSector);
 
	/* Send lights of sector where I am*/
	SECT_fn_vSendDynamicLightsOfASector(_p_stVpt, hSectorObject, GEO_C_lCullingOut);
 
	/* Send ligths from sectors in graphic interaction*/
	LST2_M_StaticForEachElementOf
	(
		&(hSectorObject->stListOfSectorsInGraphicInteraction),
		hGraphicInteractionChild,
		xI
	)
	{
		SECT_fn_vSendDynamicLightsOfASector(
			_p_stVpt,
			(SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(hGraphicInteractionChild->hPointerOfSectorSO),
			GEO_C_lCullingOut
		);
	}
}
 
/*
 *=================================================================================================
 *=================================================================================================
 */


#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
/* ------------------------------------------------------------------------------- */
/* ----------------------------- N O T  U S E D ---------------------------------- */
/* ------------------------------------------------------------------------------- */
void SECT_fn_vSendAllDynamicLights
(
	struct GLD_tdstViewportAttributes_	*_p_stVpt ,
	HIE_tdxHandleToSuperObject			_hSprObjSectorFather,
	long _lCullingResult
)
{
	HIE_tdxHandleToSuperObject	hExploredChild;
	ACP_tdxIndex				xI;
 
	HIE_M_ForEachChildOf(_hSprObjSectorFather, hExploredChild, xI)
	{
		if ( HIE_fn_ulGetSuperObjectType(hExploredChild) == HIE_C_ulSector )
		{
			SECT_fn_vSendDynamicLightsOfASector(
				_p_stVpt,
				(SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(hExploredChild),
				_lCullingResult
			);
		}
	}
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
/*
 **************************************************************************************************
 **************************************************************************************************
 **************************************************************************************************
 **************************************************************************************************
 */
 
/*
 *=================================================================================================
 *=================================================================================================
 */
ACP_tdxIndex SECT_fn_xSendStaticLightsToViewportForChar
(
	struct GLD_tdstViewportAttributes_	*_p_stVpt,
	HIE_tdxHandleToSuperObject			_hSprObjSector,
	long _lCullingResult
)
{
	ACP_tdxIndex							xI, xNotAdd = 0;
	SECT_tdxHandleOfSectorObject			hSectorObject;
	SECT_tdxHandleOfElementLstStaticLights	hStaticLightsElement;
	struct GLI_tdstLight_ *hStaticLight;
 
/* Oliv' - Portage v15 -*/
/* D'après François Queinnec, il vaut mieux laisser le Viewport décider pour la lumière...*/
/* Ceci s'explique d'autant plus que nous sommes sinon obligés de refaire le calcul de distance lumière->perso*/
/* pour simuler correctement l'atténuation de la lumière sphèrique par une lumière parallèle (seules lumières*/
/* temps-réel sur N64.*/
#ifndef U64
#ifdef pasnonpluspourpcvuquecadeconne
	ACP_tdxBool bAddThatOne;
#endif
#endif
/* EndOfOliv'*/
 
	hSectorObject=(SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(_hSprObjSector);
 
	LST2_M_StaticForEachElementOf
	(
		&(hSectorObject->stListOfStaticLights),
		hStaticLightsElement,
		xI
	)
	{
		hStaticLight = hStaticLightsElement->hStaticLights;
		if (GLI_ucGetObjectLighted(hStaticLight) & GLI_C_LightPerso)
		{
/* Oliv' - Porateg v15*/
#ifndef U64
#ifdef pasnonpluspourpcvuquecadeconne
/* EndOfOliv'*/
			bAddThatOne = TRUE;
			/*do a culling on the light if relevant (only spherical lights yet).*/
			/*QUESTION: IS THIS FASTER THAN ADDING THE LIGHT AND LET THE VIEWPORT DECIDE IF IT AFFECTS SOMETHING ?*/
            if ( (_lCullingResult != GEO_C_lCullingIn) && (GLI_lGetLightType(hStaticLight) == GLI_C_lSphericalLight) )
			{
				MTH_tdxReal xNear, xFar;
				GLI_vGetLightNearFar(hStaticLight, &xNear, &xFar);
				if ( GEO_lCullingGlobalSphere(_p_stVpt, GLI_p_stGetLightTranslation(hStaticLight), xFar, _lCullingResult) == GEO_C_lCullingOut )
				{
					bAddThatOne = FALSE;
				}
			}
            
			/* if the culling is ok, or no culling was done, add the light*/
			if ( bAddThatOne )
/* Oliv' - Portage v15*/
#endif
#endif /* U64 */
/* EndOfOliv'*/
			{
				GLI_vAddLightToViewport(_p_stVpt,hStaticLight);
				xNotAdd++;
			}
		}
	}
 
	return xNotAdd;
}
 
/*
 *=================================================================================================
 *=================================================================================================
 */
void SECT_fn_vSendFogToViewport
(
	struct GLD_tdstViewportAttributes_	*_p_stVpt,
	HIE_tdxHandleToSuperObject			_hSprObjSector
)
{
	/*VLNEWGLI char									cFog = 0;*/
	if(GLI_cGlobalFogIsOn)
	{
        /*VLNEWGLI*/
        GLI_vFogOn();
        return;
        /*
		GLI_vSetFog2
		(
			NULL,
			GLI_xFogBlendNear,
			GLI_xFogNear,
			GLI_xFogBlendFar,
			GLI_xFogFar,
			GLI_xFogInfinite,
			&GLI_stFogColor
		);
		cFog = 1;
        */
        /*EVL*/
	}
	else
	{
		ACP_tdxIndex							xI;
		SECT_tdxHandleOfSectorObject			hSectorObject = (SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(_hSprObjSector);
		SECT_tdxHandleOfElementLstStaticLights	hStaticLightsElement;
		struct GEO_tdstColor_	stColor;
		struct GLI_tdstLight_ *hStaticLight;
 
		LST2_M_StaticForEachElementOf
		(
			&(hSectorObject->stListOfStaticLights),
			hStaticLightsElement,
			xI
		)
		{
			hStaticLight = hStaticLightsElement->hStaticLights;
			if ( GLI_lGetLightType(hStaticLight) == GLI_C_lFogLight )
			{
 
				GLI_xGetLightColor(hStaticLight, &stColor);
 
				GLI_vSetFog2
				(
					/*VLNEWGLI hStaticLightsElement->hStaticLights,*/
					GLI_fn_xFogGetBlendNear(hStaticLight),
					GLI_fn_xFogGetNear(hStaticLight),
					GLI_fn_xFogGetBlendFar(hStaticLight),
					GLI_fn_xFogGetFar(hStaticLight),
					GLI_fn_xFogGetInfinite(hStaticLight),
					&stColor
				);
        /*VLNEWGLI*/
        GLI_vFogOn();
        return;
        /*cFog = 1;*/
        /*break;*/
        /*EVL*/
			}
		}
	}
	/*VLNEWGLI*/
    /*if(cFog)*/
	/*	GLI_vFogOn();*/
	/*else*/
	GLI_vFogOff();
    /*EVL*/
}
 
/*
 **************************************************************************************************
 **************************************************************************************************
 **************************************************************************************************
 **************************************************************************************************
 */
 
/*
 *=================================================================================================
 *=================================================================================================
 */
 
#if defined(_DEBUG)
unsigned char g_ucWhatDoIDisplay = 0;
#endif /* _DEBUG */
 
#if defined(_U64_GLI_BENCH_)
#include "u_draw.h"
extern ACP_tdxBool GLIBENCH_g_bBVBox;
#endif /* _U64_GLI_BENCH_ */
long SCT_fn_lSendSectorToViewportStatic(MTH3D_tdstVector					*_p_stAbsolutePositionOfCamera,
										struct GLD_tdstViewportAttributes_	*_p_stVpt,
										HIE_tdxHandleToSuperObject			_hSprObjSector ,
										long								_lDrawMask)
{
	SECT_tdxHandleOfSectorObject			hSectorObject;
	MTH3D_tdstVector						*p_stBdvMinPoint;
	MTH3D_tdstVector						*p_stBdvMaxPoint;
	MTH3D_tdstVector						*p_stBorderMinPoint;
	MTH3D_tdstVector						*p_stBorderMaxPoint;
	long									lCullingResult = GEO_C_lCullingOut;
	MTH3D_tdstVector						stDeltaMin, stDeltaMax;
 
	hSectorObject=(SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(_hSprObjSector);
	
	/* Send fog of that sector */
	/*PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendSector );*/
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
	PRF_fn_vStopChrono( PRF_C_ulFctDisplay , PRF_C_pvMisc);
	PRF_fn_vStartChrono( PRF_C_ulFctDisplaySpecific , PRF_C_pvMisc);
	
	SECT_fn_vSendFogToViewport(_p_stVpt, _hSprObjSector);
	
	PRF_fn_vStopChrono( PRF_C_ulFctDisplaySpecific , PRF_C_pvMisc);
	PRF_fn_vStartChrono( PRF_C_ulFctDisplay , PRF_C_pvMisc);
	/*PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendSector );*/
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
	
	/* Display the childrens of sector (static world) */
#if defined(_DEBUG)
	if( (g_ucWhatDoIDisplay == 0) || (g_ucWhatDoIDisplay == 1) )
#endif /* _dEBUG */
	{
		GEO_tdxHandleToParallelBox hParallelBox = (GEO_tdxHandleToParallelBox) HIE_fn_hGetSuperObjectBoundingVolume(_hSprObjSector);
		
		PRF_fn_vSetIndependantVariable( PRF_C_ulIdpDynOrSta, PRF_C_ulStatic );
		PRF_fn_vSetIndependantVariable( PRF_C_ulIdpDisplayedObjects, 0 );
		
		/*get the border extremities (the border has already been culled)*/
		p_stBorderMinPoint = SECT_fn_p_stGetMinPointInBorder(hSectorObject);
		p_stBorderMaxPoint = SECT_fn_p_stGetMaxPointInBorder(hSectorObject);
 
		/* first of all, check bounding volume and draw sector*/
		if ( hParallelBox )
		{
			/* there is a bounding volume*/
			/*get the bounding volume extremities*/
			p_stBdvMinPoint = GEO_fn_pGetMinPointOfParallelBox(hParallelBox);
			p_stBdvMaxPoint = GEO_fn_pGetMaxPointOfParallelBox(hParallelBox);
 
			/* draw bounding volume if asked*/
#if defined(_U64_GLI_BENCH_)
			if( GLIBENCH_g_bBVBox )
			{
				GLIBENCH_fn_vSendParallelBoxToViewport(
						_p_stVpt,
					p_stBdvMinPoint,
					p_stBdvMaxPoint
				);
			}
#endif /* _U64_GLI_BENCH_ */
 
			/* check if sector is visible*/
			lCullingResult = GEO_lCullingBox(_p_stVpt, p_stBdvMinPoint, p_stBdvMaxPoint, GEO_C_lCullingOut);
			if ( (lCullingResult != GEO_C_lCullingOut) || HIE_fn_SO_bCheckChildren(_hSprObjSector) )
			{
				/* sector visible --> draw*/
				HIE_fn_vSendStaticWorldToViewport(_p_stVpt, _hSprObjSector, _lDrawMask, lCullingResult);
			}
			
			if( PRF_fn_lGetIndependantVariable( PRF_C_ulIdpDisplayedObjects ) )
				PRF_fn_vIncreaseVariable( PRF_C_ulVarSectors, (void*) hSectorObject, 1 );
 
			/* now, correct the culling result according to the sector border*/
			/* so that the culling result represents the culling for the dynamic sector*/
			/*compute the distance between the BDV's and border's extremities*/
			MTH3D_M_vSubVector(&stDeltaMin, p_stBorderMinPoint, p_stBdvMinPoint);
			MTH3D_M_vSubVector(&stDeltaMax, p_stBorderMaxPoint, p_stBdvMaxPoint);
 
			if (!(MTH_M_bIsNullWithEpsilon(MTH3D_M_xNorm1Vector(&stDeltaMin), MTH_M_xFloatToReal(0.01f)) &&
				  MTH_M_bIsNullWithEpsilon(MTH3D_M_xNorm1Vector(&stDeltaMax), MTH_M_xFloatToReal(0.01f))))
			{ 
				long lMinInOut, lMaxInOut;
				/* the border size is quite different from the BDV size, so culling result may change...*/
				/* check the position of the BDV against the border*/
				/*check if the min BDV is inside or outside the border*/
				/* (-3) -> out, (3) -> in, [-2,2] -> intersect*/
				lMinInOut = (MTH_M_bLessZero(stDeltaMin.xX) ? 1 : -1) + (MTH_M_bLessZero(stDeltaMin.xY) ? 1 : -1) + (MTH_M_bLessZero(stDeltaMin.xZ) ? 1 : -1);
				if ( (lMinInOut == -3) || (lMinInOut == 3) )
				{
					/*check if the max BDV is inside or outside the border*/
					/* -3 -> out, 3 -> in, [-2,2] -> intersect*/
					lMaxInOut = (MTH_M_bLessZero(stDeltaMax.xX) ? -1 : 1) + (MTH_M_bLessZero(stDeltaMax.xY) ? -1 : 1) + (MTH_M_bLessZero(stDeltaMax.xZ) ? -1 : 1);
				}
				else
				{
					/* we know the BDV intersects the border, so we don't need to test the other extremity*/
					/* BTW, 0 can never be obtained through the above computation, which forces the culling on the BDV*/
					lMaxInOut = 0;
				}
				
				if ( lMinInOut != lMaxInOut )
				{
					/*both extremities are not on the same side of the border -> the BDV box intersects the border*/
					/*-> a culling on the Border is necessary*/
					lCullingResult = GEO_lCullingBox(_p_stVpt, p_stBorderMinPoint, p_stBorderMaxPoint, GEO_C_lCullingOut);
				}
				else /*both extremities are on the same side, the culling is not always necessary*/
				{
					if ( lMinInOut > 0 ) /* the BDV is strictly inside the border*/
					{
						/* check if the border intersects the culling planes*/
						/*
						if ( (lCullingResult != GEO_C_lCullingIn) && (lCullingResult != GEO_C_lCullingOut) )
						{
						*/
							/* if true, knowing where the BDV is relatively to the border is useless*/
							/* -> do the culling on the BDV*/
							lCullingResult = GEO_lCullingBox(_p_stVpt, p_stBorderMinPoint, p_stBorderMaxPoint, GEO_C_lCullingOut);
						/*
						}
						*/
						/*else the border does not intersect the culling planes*/
						/*the BDV wont either -> the culling result is inchanged*/
					}
					else /* the BDV is strictly larger than the border*/
					{
						/* check if the border intersects the culling planes*/
						if (!(lCullingResult != GEO_C_lCullingIn) && (lCullingResult != GEO_C_lCullingOut) )
						{
							/* the border does not intersect the culling planes*/
							/*that does not mean the BDV wont either -> do the culling on the BDV*/
							lCullingResult = GEO_lCullingBox(_p_stVpt, p_stBorderMinPoint, p_stBorderMaxPoint, GEO_C_lCullingOut);
						}
						/* else, result is unchanged...*/
					} /* the BDV is out the border*/
				} /* the BDV is either in or out the border*/
			} /* the BDV and the border are equal*/
		}
		else
		{
			/* no bounding volume...*/
			/* so nothing to display in the sector...*/
			/* so the culling IS the border culling*/
			lCullingResult = GEO_lCullingBox(_p_stVpt, p_stBorderMinPoint, p_stBorderMaxPoint, GEO_C_lCullingOut);
		}
	}
	return lCullingResult;
}
 
#ifdef U64
	extern char g_ulUseAntiAliasing;
#endif

void SCT_fn_vSendSectorToViewportDynamic(MTH3D_tdstVector *_p_stAbsolutePositionOfCamera,
										 struct GLD_tdstViewportAttributes_ *_p_stVpt,
										 HIE_tdxHandleToSuperObject _hSprObjSector,
										 long _lDrawMask,
										 long _lCullingResult)
{
	ACP_tdxIndex xI, xNbLights;
	SECT_tdxHandleOfSectorObject hSectorObject = (SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject(_hSprObjSector);
	SECT_tdxHandleOfElementLstCharacter		hCharacter;
	
	if ((_lCullingResult != GEO_C_lCullingOut ) || (g_bInGameMenu))
	{
		PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
		PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvLight );
#if !defined(U64)
		GLI_vResetTableOfActiveLightsForChar( GLI_C_ActivateLight );
#endif /* U64 */
		xNbLights = 0;
		
		PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvLight );
		
		/* Send fog of that sector */
        /*PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendActor );*/
		
		PRF_fn_vStopChrono( PRF_C_ulFctDisplay , PRF_C_pvMisc);
		PRF_fn_vStartChrono( PRF_C_ulFctDisplaySpecific , PRF_C_pvMisc);
		
		SECT_fn_vSendFogToViewport(_p_stVpt, _hSprObjSector);
		
		PRF_fn_vStopChrono( PRF_C_ulFctDisplaySpecific , PRF_C_pvMisc);
		PRF_fn_vStartChrono( PRF_C_ulFctDisplay , PRF_C_pvMisc);
		
		/*PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendActor );*/
		PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvLight );
		
#ifndef U64
		if((_lDrawMask & GLI_C_lIsUseStaticLights) && (HIE_fn_lGetSuperObjectDrawMask(_hSprObjSector)& GLI_C_lIsUseStaticLights))
		{
			xNbLights=SECT_fn_xSendStaticLightsToViewportForChar(_p_stVpt, _hSprObjSector, _lCullingResult);
		}
#else
		if(!(_lDrawMask & GLI_C_lIsUseStaticLights)||!(HIE_fn_lGetSuperObjectDrawMask(_hSprObjSector)& GLI_C_lIsUseStaticLights))
		{
			xNbLights=SECT_fn_xSendStaticLightsToViewportForChar(_p_stVpt, _hSprObjSector, _lCullingResult);
		}
#endif /* U64 */
		
		PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvLight );
		PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
		/*
		*	Display the characters and shadows.
		*/
#if defined(_DEBUG)
		if( (g_ucWhatDoIDisplay == 0) || (g_ucWhatDoIDisplay == 2) )
#endif /* _DEBUG */
		{
			HIE_tdxHandleToSuperObject hCharacterSO;
			long lDrawmaskOfCharacter;
			unsigned long ulCustomBits ;
			PRF_fn_vSetIndependantVariable( PRF_C_ulIdpDynOrSta, PRF_C_ulDynamic );
			/* ANNECY MT - 22/09/98 {*/
			GEO_vSetZFar( fn_xGetSectorZFar( _hSprObjSector ) );
			GEO_vSetZFarTransparencyZone( MTH_C_ZERO );
			/* END ANNECY MT }*/
			LST2_M_DynamicForEachElementOf(&(hSectorObject->stListOfCharacters), hCharacter, xI)
			{
				hCharacterSO = hCharacter->hPointerOfCharacter;
				lDrawmaskOfCharacter = HIE_fn_lGetSuperObjectDrawMask(hCharacterSO);
				ulCustomBits = fn_ulStandardGameGetCustomBitsSO(hCharacterSO) ;
 
				if ((!g_bInGameMenu) || (ulCustomBits & GAM_C_CustBitUnfreezable))
 
				if ( lDrawmaskOfCharacter & GLI_C_lDrawNothing )
				{
#ifdef U64
					/* FQ 12/04/99 :														 */
					/* A la demande de Pauline, on force l'antialiasing sur Rayman seulement */
					char SavedAAMode=g_ulUseAntiAliasing;

					{
						HIE_tdstSuperObject *p_stSO;
						/* Rayman */
						p_stSO=MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode());

						if (p_stSO==hCharacterSO) g_ulUseAntiAliasing=1;
					}
					/* END FQ */
#endif

					HIE_fn_vSendCharacterToViewport(
						_p_stVpt,
						hCharacterSO,
						lDrawmaskOfCharacter & _lDrawMask,
						_lCullingResult
						);

#ifdef U64
					g_ulUseAntiAliasing=SavedAAMode;
#endif
					
					PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
					PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvShadow );
					
					/* SHADOWS FROM MAO : DISPLAYED AT THE END*/
					
					if ( ulCustomBits & GAM_C_CustBitActorHasShadow )
					{
						SHW_fn_vDrawShadow(_p_stVpt,hCharacterSO,_hSprObjSector,_lDrawMask);
					}
					PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvShadow );
					PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
				}
			}
		}
		
		PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
		PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvLight );
		
		if(xNbLights)
			GLI_vPopLightsInViewport(_p_stVpt,(unsigned long) xNbLights);
		
		PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvLight );
		PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
	}
	else /* the sector's characters are not displayed: update some of their flags*/
	{
		/* ANNECY MT - 12/10/98 {*/
		unsigned long				ulCustomBits;
		HIE_tdxHandleToSuperObject  hCharacterSO;
		MS_tdxHandleToStandardGame hStdGame;
		/*
		MTH3D_tdstVector stDist;
		MTH3D_tdstVector*		    p_stMainCharTranslation;
		HIE_tdxHandleToSuperObject  hMainChar;
		 */
		/* get main character*/
		/*
		hMainChar				= MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode());
		p_stMainCharTranslation = POS_fn_p_stGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(hMainChar));
		 */
		LST2_M_DynamicForEachElementOf(&(hSectorObject->stListOfCharacters), hCharacter, xI)
		{
			hCharacterSO = hCharacter->hPointerOfCharacter;
			hStdGame = M_GetMSHandle(hCharacterSO,StandardGame);
			ulCustomBits = fn_ulStandardGameGetCustomBits(hStdGame);
			
			/* Set 'OutOfVisibility' flag*/
#ifdef U64
			/*unnecessary on PC, because it was set as default before anything is sent to the viewport (default value)*/
			ulCustomBits |= GAM_C_CustBitOutOfVisibility;
			fn_vStandardGameSetCustomBits(hStdGame, ulCustomBits);
#endif /* U64 */
			
			/* compute distance to Main character if needed */
			/*
			 * now computed for all active actors in the fn_vUpdateTooFarFlagOfAllActiveActors() function of GAM module 
			 *
			if ( ulCustomBits & (GAM_C_CustBitNoAnimPlayerWhenTooFar|GAM_C_CustBitNoAIWhenTooFar|GAM_C_CustBitNoMecaWhenTooFar) )
			{				
				if ( hCharacterSO == hMainChar )
				{
					fn_vStandardGameSetTooFar(hStdGame,FALSE);
				}
				else
				{
					
					MTH3D_M_vSubVector(
						&stDist,
						POS_fn_p_stGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(hCharacterSO)),
						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);
					}
				}
			}
			*/
		}
		/* END ANNECY MT }*/
	}
	
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
	/*PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendActor );*/
	PRF_fn_vStopChrono( PRF_C_ulFctDisplay, PRF_C_pvMisc );
	
	SECT_fn_vUpdateRasterForSector( _hSprObjSector );
	
	PRF_fn_vStartChrono( PRF_C_ulFctDisplay, PRF_C_pvMisc );
	/*PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendActor );*/
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
 
}
 
 
#ifdef U64
	unsigned char g_bDisplayingMainSector=0;
	#ifndef FINAL_VERSION
		#define ENABLE_SHOW_HIDE_MAP_PERSO
		#include "INO\Joystick.h"
	/* FQ SKYFOG*/
 
		/*#define SHOW_SENDSECTOR_TIME*/
	#endif /* FINAL_VERSION */
 
	#ifndef FINAL_VERSION
		#define SHOW_SENDSECTOR_TIME
	#endif /* FINAL_VERSION */
#endif
 
#ifdef SHOW_SENDSECTOR_TIME
extern unsigned long	g_ulSendSectorTime;
#endif /* SHOW_SENDSECTOR_TIME */
 
 
/* main function to display the world */
/* this function is called on the sector that contains the camera */
void SCT_fn_vSendSectorWhereIAmToViewport(MTH3D_tdstVector						*_p_stAbsolutePositionOfCamera,
										  struct GLD_tdstViewportAttributes_	*_p_stVpt,
										  HIE_tdxHandleToSuperObject			_hSprObjSector,
										  long									_lDrawMask)
{

/* how the function works with lights :
	- add all the dynamic lights of the visible sectors in the list of lights
	- send all visible static sectors (--> dynamic lights affect static objects)
	- For every dynamic sector :
		- turn on all light activation --> available lights will affect every actor
		- add static lights to list of lights --> dynamic lights + static light will be used for actors of this sector
		- for each actor of the sector
			- for each light of the list, update the light activation for the given actor (--> lights will not affect distant actors)
			- send the actor to display
		- remove all the lights that have been added for this sector
*/	 

	ACP_tdxIndex									xI;
	SECT_tdxHandleOfSectorObject					hSectorObject;
	SECT_tdxHandleOfElementLstGraphicInteraction	hGraphicInteractionChild;
	long											*a_lCullingResultArray;
 
#ifdef ENABLE_SHOW_HIDE_MAP_PERSO
static char cDrawMap=1;
static char cDrawPerso=1;
#endif /* ENABLE_SHOW_HIDE_MAP_PERSO */
 
#ifdef SHOW_SENDSECTOR_TIME
	g_ulSendSectorTime = osGetCount();
#endif /* SHOW_SENDSECTOR_TIME */
 
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvLight );
 
#ifdef ENABLE_SHOW_HIDE_MAP_PERSO
	if( INO_fn_wJoystickButtonJustPressed(0,R_JPAD) == C_wJoyTrue &&
		INO_fn_wIsJoystickButtonPressed(0,Z_TRIG) == C_wJoyTrue)
	{
		cDrawMap = (cDrawMap == 0) ? 1 : 0;
	}
 
	if( INO_fn_wJoystickButtonJustPressed(0,L_JPAD) == C_wJoyTrue &&
		INO_fn_wIsJoystickButtonPressed(0,Z_TRIG) == C_wJoyTrue)
	{
		cDrawPerso=(cDrawPerso==0)?1:0;
	}
	
	PRF_fn_vStartChrono( PRF_C_ulFctDisplay, PRF_C_pvDisplayDisplayFix );
	PRF_fn_vStopChrono( PRF_C_ulFctDisplay, PRF_C_pvDisplayDisplayFix );
#endif /* ENABLE_SHOW_HIDE_MAP_PERSO */
	
	
#ifdef U64
	PRF_fn_vStartChrono( PRF_C_ulFctDisplay, PRF_C_pvDisplaySendSector );
#endif /* U64 */
	
	hSectorObject = (SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(_hSprObjSector);
	
	/* alloc array to get the culling result*/
#ifdef CODEWARRIOR
	a_lCullingResultArray = __alloca(sizeof(long) * (LST2_M_StaticGetNumberOfElements(&(hSectorObject->stListOfSectorsInGraphicInteraction)) +1 ));
#else	
	a_lCullingResultArray = alloca(sizeof(long) * (LST2_M_StaticGetNumberOfElements(&(hSectorObject->stListOfSectorsInGraphicInteraction)) +1 ));
#endif	
 
/* Oliv' - those lines should stay OUT of the cDrawMap test*/
	/* Send dynamic lights */
	SECT_fn_vSendDynamicLightsFromWhereIAmToViewport(_p_stVpt, _hSprObjSector);
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvLight );
	HIE_fn_bInitCameraMatrixStack(_p_stVpt);
/* EndOfOliv'*/
 
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
 
	/* FQ*/
	/* Since it causes too many graphics bugs on some maps, */
	/* I had to draw all the map first, and then, the actors..*/


#ifdef ENABLE_SHOW_HIDE_MAP_PERSO
	if ( cDrawMap )
	{
#endif
 
#ifdef U64

	g_CharacterNonTransparentLightsBegin=NULL;
	g_HaveLightsBeenCopied=0;
#endif
	if (!g_bInGameMenu)
	{
#ifdef U64
		/* FQ SKYFOG*/
		g_bDisplayingMainSector=1;
#endif
		/* Draw the sector where we are */
		a_lCullingResultArray[0] = SCT_fn_lSendSectorToViewportStatic(_p_stAbsolutePositionOfCamera,_p_stVpt,_hSprObjSector,_lDrawMask);
		/* the culling result here is ready to use for dynamic */
 
#ifdef U64
		/* FQ SKYFOG*/
		g_bDisplayingMainSector=0;
#endif
	}
 
#ifdef ENABLE_SHOW_HIDE_MAP_PERSO
	}
	else
	{
		a_lCullingResultArray[0] = GEO_C_lCullingIntersect;
	}
#endif
 
 
	if (!g_bInGameMenu)
	{
	/* Draw all sectors in graphic list */
	LST2_M_StaticForEachElementOf(&(hSectorObject->stListOfSectorsInGraphicInteraction),hGraphicInteractionChild,xI)
	{
		/* Begin Shaitan ModeLook*/
		if ( !( (g_stEngineStructure.cCameraMode != C_CamModeLook) && (hGraphicInteractionChild->cDisplayMode == C_SECT_ModeLookOnly) ) )
		{
		/* End Shaitan ModeLook*/
#ifdef ENABLE_SHOW_HIDE_MAP_PERSO
			if ( cDrawMap )
			{
#endif 

#ifdef U64
	g_CharacterNonTransparentLightsBegin=NULL;
	g_HaveLightsBeenCopied=0;
#endif /* U64 */
				/* Draw the sector where we are */
				a_lCullingResultArray[xI+1] = SCT_fn_lSendSectorToViewportStatic(_p_stAbsolutePositionOfCamera,_p_stVpt,hGraphicInteractionChild->hPointerOfSectorSO,_lDrawMask);
#ifdef ENABLE_SHOW_HIDE_MAP_PERSO
			}
#endif 
 
 
		/* Begin Shaitan ModeLook*/
		}
		/* End Shaitan ModeLook*/
	}
 
	}
 
 
 
#ifdef ENABLE_SHOW_HIDE_MAP_PERSO
	if ( cDrawPerso )
	{
#endif
		/* DYN: Draw the sector where we are */
		SCT_fn_vSendSectorToViewportDynamic(_p_stAbsolutePositionOfCamera,_p_stVpt,_hSprObjSector,_lDrawMask,a_lCullingResultArray[0]);
#ifdef ENABLE_SHOW_HIDE_MAP_PERSO
	}
#endif
 
 
	/* Draw all sectors in graphic list */
	LST2_M_StaticForEachElementOf(&(hSectorObject->stListOfSectorsInGraphicInteraction),hGraphicInteractionChild,xI)
	{
		/* Begin Shaitan ModeLook*/
		if ((g_bInGameMenu) || ( !( (g_stEngineStructure.cCameraMode != C_CamModeLook) && (hGraphicInteractionChild->cDisplayMode == C_SECT_ModeLookOnly) ) ))
		{
		/* End Shaitan ModeLook*/
 
#ifdef ENABLE_SHOW_HIDE_MAP_PERSO
			if ( cDrawPerso )
			{
#endif 
				/* End Shaitan ModeLook*/
				SCT_fn_vSendSectorToViewportDynamic(_p_stAbsolutePositionOfCamera,
													_p_stVpt,
													hGraphicInteractionChild->hPointerOfSectorSO,
													_lDrawMask,
													a_lCullingResultArray[xI+1]);
 
#ifdef ENABLE_SHOW_HIDE_MAP_PERSO
			}
#endif 
		/* Begin Shaitan ModeLook*/
		}
		/* End Shaitan ModeLook*/
	}
 
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvLight );
 
	/* Clear all lights of viewport */
	GLI_vClearListOfLightInViewport (_p_stVpt);
 
	PRF_fn_vStopChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvLight );
	PRF_fn_vStartChrono( PRF_C_ulFctDisplayCommon, PRF_C_pvSendToViewPort );
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
	gs_hSprObjSectCurr = _hSprObjSector;
#endif /* _FIRE_DEADCODE_U64_ */
 
/*XB*/
#ifdef U64
  PRF_fn_vStopChrono( PRF_C_ulFctDisplay, PRF_C_pvDisplaySendSector );
#endif /* U64 */
 
#ifdef SHOW_SENDSECTOR_TIME
	g_ulSendSectorTime = osGetCount() - g_ulSendSectorTime;
#endif /* SHOW_SENDSECTOR_TIME */
}
 
 
/***********************************************************************************************/
/*  Name        : SECT_vDisplaySectorInfos*/
/*  Description : Displays infos about interacting sectors of one indicated sector*/
/*  Author      : Marc FASCIA*/
/*  Date        : 04/03/98*/
/*  Optimized ? : No*/
/***********************************************************************************************/
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void SECT_vDisplaySectorInfos(void)
{
#if (defined(_DEBUG) || defined(USE_PROFILER) && !defined(PRESS_DEMO))
#ifndef U64
  ACP_tdxIndex									                  xI;
  SECT_tdxHandleOfSectorObject					          hSectorObject;
  SECT_tdxHandleOfElementLstGraphicInteraction	  hGraphicInteractionChild;
  SECT_tdxHandleOfElementLstCollisionInteraction	hCollisionInteractionChild;
  SECT_tdxHandleOfElementLstActivityInteraction	  hActivityInteractionChild;
  SECT_tdxHandleOfElementLstSoundInteraction	    hSoundInteractionChild;
	char	                                          szInfos[ 255 ];
 
  hSectorObject = (SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(gs_hSprObjSectCurr );
 
	if( g_ucSCTDisplaySectors )
	{
      sprintf( szInfos, "[1] %s", strrchr(gs_hSprObjSectCurr->hLinkedObject.p_stSector->szSectorName, ':') + 1);
      GLI_vDisplayPolices( szInfos, 10, 50 );
	}
 
  /*--- Display sectors in interaction : VISIBLE*/
  if( g_ucSCTDisplaySectors == 1 )
  {
    sprintf( szInfos, "Secteurs Visibles" );
    GLI_vDisplayPolices( szInfos, 10, 10 );
 
    LST2_M_StaticForEachElementOf( &(hSectorObject->stListOfSectorsInGraphicInteraction), hGraphicInteractionChild, xI )
    {
      sprintf( szInfos, "[%i] %s", xI+2, strrchr(hGraphicInteractionChild->hPointerOfSectorSO->hLinkedObject.p_stSector->szSectorName, ':') + 1);
      GLI_vDisplayPolices( szInfos, 10, 70 + 20*xI );
    }
  }
 
  /*--- Display sectors in interaction : COLLISION*/
  if( g_ucSCTDisplaySectors == 2 )
  {
    sprintf( szInfos, "Secteurs Collisionnables" );
    GLI_vDisplayPolices( szInfos, 10, 10 );
 
    LST2_M_StaticForEachElementOf( &(hSectorObject->stListOfSectorsInCollisionInteraction), hCollisionInteractionChild, xI )
    {
      sprintf( szInfos, "[%i] %s", xI+2, strrchr(hCollisionInteractionChild->hPointerOfSectorSO->hLinkedObject.p_stSector->szSectorName, ':')+1);
      GLI_vDisplayPolices( szInfos, 10, 70 + 20*xI );
    }
  }
 
  /*--- Display sectors in interaction : ACTIVITY*/
  if( g_ucSCTDisplaySectors == 3 )
  {
    sprintf( szInfos, "Secteurs Actifs - Persos Actifs" );
    GLI_vDisplayPolices( szInfos, 10, 10 );
 
    LST2_M_StaticForEachElementOf( &(hSectorObject->stListOfSectorsInActivityInteraction), hActivityInteractionChild, xI )
    {
      sprintf( szInfos, "[%i] %s", xI+2, strrchr(hActivityInteractionChild->hPointerOfSectorSO->hLinkedObject.p_stSector->szSectorName,':')+1);
      GLI_vDisplayPolices( szInfos, 10, 70 + 20*xI );
	}
  }
 
  /*--- Display sectors in interaction : SOUND*/
  if( g_ucSCTDisplaySectors == 4 )
  {
    sprintf( szInfos, "Secteurs Sons" );
    GLI_vDisplayPolices( szInfos, 10, 10 );
    LST2_M_StaticForEachElementOf( &(hSectorObject->stListOfSectorsInSoundInteraction), hSoundInteractionChild, xI )
    {
      sprintf( szInfos, "[%i] %s", xI+2,strrchr(hSoundInteractionChild->hPointerOfSectorSO->hLinkedObject.p_stSector->szSectorName,':')+1);
      GLI_vDisplayPolices( szInfos, 10, 70 + 20*xI );
    }
  }
#endif /*U64 AR980316*/
#endif
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
/***********************************************************************************************/
/***********************************************************************************************/
/***********************************************************************************************/
/***********************************************************************************************/
/***********************************************************************************************/
 
#if defined(USE_PROFILER) && !defined(PRESS_DEMO)
 
extern void HIE_fn_vUpdateRasterForSuperObject( HIE_tdxHandleToSuperObject _hSuperObject,
											    unsigned long _ulRasterObject,
												unsigned long _ulRasterFace,
												unsigned long _ulRasterElement);
 
/***********************************************************************************************/
/*  Name        : SECT_fn_vUpdateRasterForSector*/
/*  Description : compute number of objects and faces on sector*/
/*  Author      : Marc TRABUCATO*/
/*  Date        : 23/04/98*/
/*  Optimized ? : No*/
/***********************************************************************************************/
void SECT_fn_vUpdateRasterForSector(HIE_tdxHandleToSuperObject _hSprObjSector)
{
    ACP_tdxIndex                            xI;
    HIE_tdxHandleToSuperObject              hChild;
	SECT_tdxHandleOfSectorObject			hSectorObject;
	SECT_tdxHandleOfElementLstCharacter		hCharacter;
 
    /* static objects*/
#if defined(_DEBUG)
	if( (g_ucWhatDoIDisplay == 0) || (g_ucWhatDoIDisplay == 1) )
#endif /* _DEBUG */
	{
		HIE_M_ForEachChildOf(_hSprObjSector, hChild, xI)
		{
			HIE_fn_vUpdateRasterForSuperObject( hChild, PRF_C_ulVarStaObjects, PRF_C_ulVarStaFaces, PRF_C_ulVarStaElements );
		}
	}
 
    /* dynamic objects*/
#if defined(_DEBUG)
	if( (g_ucWhatDoIDisplay == 0) || (g_ucWhatDoIDisplay == 2) )
#endif /* _DEBUG */
	{
		hSectorObject=(SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(_hSprObjSector);
 
		LST2_M_DynamicForEachElementOf(&(hSectorObject->stListOfCharacters), hCharacter, xI)
		{
			HIE_fn_vUpdateRasterForSuperObject( hCharacter->hPointerOfCharacter, PRF_C_ulVarDynObjects, PRF_C_ulVarDynFaces, PRF_C_ulVarDynElements );
		}
	}
}
 
#endif /* USE_PROFILER && PRESS_DEMO */
