#define D_Effect_StructureDefine
#define D_Effect_VariableDefine
 
#include "ToolsCPA.h"
#include "Effect.h"
#include "GameEng.h"
#include "ia_dnm.h"
#include "Toolcam.h"
#include "Typecam.h"
 
#include "Structur/State.h"
 
#include "Actions/AllActs.h"
#include "Structur/GameScpt.h"
#include "Structur/ErrGame.h"
#include "Structur/MemGame.h"
#include "Structur/StdObjSt.h"
#include "Structur/EngMode.h"
#include "Structur/Objects.h"
 
#include "Basic.h"
#include "Zemem.h"
 
#define C_szWaterStreakEffectDescription     "WaterStreakDescription"
#define C_Entry_WaterStreakNbFoams           "NumberOfFoams"
#define C_Entry_WaterStreakZoomXY            "StreakZoom"
#define C_Entry_WaterStreakGeometricObject   "GraphicObject"
#define C_Entry_WaterStreakAttenuationCoeff  "AttenuationCoeff"
#define C_Entry_WaterStreakLifeTime          "LifeTime"
#define C_Entry_WaterStreakTimeBetweenTwoShifts "TimeBetweenShifts"
#define C_Entry_WaterStreakTimeWindow        "TimeWindow"
#define C_Entry_WaterStreakGap               "StreakGap"
#define C_ulTimeBetweenTwoShifts             50
 
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
ACP_tdxBool fn_bIsCharacterCrossingASurfaceOfWater(
   HIE_tdxHandleToSuperObject _hCharacter,
   MTH3D_tdstVector * _p_stRealPoint);
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
#if defined(GAM_USE_SCRIPT)
SCR_tde_Anl_ReturnValue fn_eCallBackWaterStreakEffect(SCR_tdst_File_Description *_p_stFile,char *_p_szName,char *_ap_szParams[],SCR_tde_Anl_Action	_eAction)
{
   SCR_tde_Anl_ReturnValue eReturnValue = SCR_ERV_Anl_NormalReturn;
   tdstWaterStreakEffect * p_stWSE;
   
   _p_stFile=_p_stFile;
   
   if(M_IsTitle)
   {
      M_CheckScriptParamNumber(2);
      p_stWSE = (tdstWaterStreakEffect *)M_p_GameMallocInHLM(sizeof(tdstWaterStreakEffect));
      p_stWSE->lNbFoams = atoi(_ap_szParams[0]);
      p_stWSE->a_stFoams = (tdstWaterFoam *)M_p_GameMallocInHLM(sizeof(tdstWaterFoam)*p_stWSE->lNbFoams);
      p_stWSE->lNbGraphicFoams = atoi(_ap_szParams[1]);
      p_stWSE->a_hFoamObjectTable = (ACP_tdxHandleOfObject*)M_p_GameMallocInHLM(sizeof(ACP_tdxHandleOfObject)*p_stWSE->lNbGraphicFoams);
      p_stWSE->lNbGraphicFoams = 0;
      /*** Default values ***/
      p_stWSE->xFoamXZoom = MTH_C_ONE;
      p_stWSE->xFoamYZoom = MTH_C_ONE;
      p_stWSE->lFoamFrameCounter = 0;
      p_stWSE->ulLastTimeOfShift = 0;
      p_stWSE->xAttenuationCoeff = 1.5f;
      p_stWSE->lLifeTime = 500;
      p_stWSE->xLifeTimeFrequency = p_stWSE->xAttenuationCoeff/((float)p_stWSE->lLifeTime);
      p_stWSE->lTimeBetweenTwoShifts = 50;
      SCR_M_RdL0_SetSectionLong(C_ThisSection,0,p_stWSE);
   }
   else if (M_IsEntry)
   {
      SCR_M_RdL0_GetSectionLong(C_ThisSection,0,tdstWaterStreakEffect *,p_stWSE);
      if( M_ActionIs(C_Entry_WaterStreakGeometricObject) )
      {
         *(p_stWSE->a_hFoamObjectTable+p_stWSE->lNbGraphicFoams) = GLI_pLoadGeometricInFile(_ap_szParams[0]);
         p_stWSE->lNbGraphicFoams++;
      }
      else if( M_ActionIs(C_Entry_WaterStreakZoomXY) )
      {
         p_stWSE->xFoamXZoom = MTH_M_xDoubleToReal(atof(_ap_szParams[0]));
         p_stWSE->xFoamYZoom = MTH_M_xDoubleToReal(atof(_ap_szParams[1]));
      }
      else if( M_ActionIs(C_Entry_WaterStreakTimeBetweenTwoShifts) )
      {
         p_stWSE->lTimeBetweenTwoShifts = atoi(_ap_szParams[0]);
      }
      else if( M_ActionIs(C_Entry_WaterStreakAttenuationCoeff) )
      {
         p_stWSE->xAttenuationCoeff = MTH_M_xDoubleToReal(atof(_ap_szParams[0]));
      }
      else if( M_ActionIs(C_Entry_WaterStreakLifeTime) )
      {
         p_stWSE->lLifeTime = atoi(_ap_szParams[0]);
      }
      else if( M_ActionIs(C_Entry_WaterStreakTimeWindow) )
      {
         p_stWSE->xTimeWindow = MTH_M_xDoubleToReal(atof(_ap_szParams[0]));
      }
      else if( M_ActionIs(C_Entry_WaterStreakGap) )
      {
         p_stWSE->xGap = MTH_M_xDoubleToReal(atof(_ap_szParams[0]));
      }
      else
      {
         M_GameInformationError(E_uwGameScriptCallBackDescriptionUnknownAction);
      }
   }
   else if( M_IsEnd )
   {
      SCR_M_RdL0_GetSectionLong(C_ThisSection,0,tdstWaterStreakEffect *,p_stWSE);
      p_stWSE->xLifeTimeFrequency = p_stWSE->xAttenuationCoeff/((float)p_stWSE->lLifeTime);
   }
   return(eReturnValue);
}
#endif /* GAM_USE_SCRIPT */
 
/* Init water streak and bubble effects */
void fn_vInitWaterStreakEffect()
{
#if defined(GAM_USE_SCRIPT)
   SCR_fn_v_RdL0_RegisterCallback(C_szWaterStreakEffectDescription,
      fn_eCallBackWaterStreakEffect, SCR_CRC_c_RdL0_ForSection);
#endif /* GAM_USE_SCRIPT */
}
 
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_vShiftTableOfPosition(GAM_tdxHandleToWaterStreakEffect _hWSE,MTH3D_tdstVector * _p_stV,ACP_tdxBool _bIsOK)
{
   long lI;
   tdstWaterFoam * p_stWF;
 
   /* Taking in account real time */
   if( (g_stEngineStructure.stEngineTimer.ulCurrentTimerCount-_hWSE->ulLastTimeOfShift) > C_ulTimeBetweenTwoShifts )
   {
      p_stWF = _hWSE->a_stFoams+_hWSE->lNbFoams-1;
      _hWSE->ulLastTimeOfShift = g_stEngineStructure.stEngineTimer.ulCurrentTimerCount;
      for( lI=_hWSE->lNbFoams-1; lI>0; lI--,p_stWF-- )
      {
         MTH3D_M_vCopyVector(&p_stWF->stPosition,&(p_stWF-1)->stPosition);
         p_stWF->bFoamIsActive = (p_stWF-1)->bFoamIsActive;
         p_stWF->lLifeTime = (p_stWF-1)->lLifeTime - _hWSE->lTimeBetweenTwoShifts;
      }
      MTH3D_M_vCopyVector( &_hWSE->a_stFoams->stPosition,_p_stV );
      _hWSE->a_stFoams->bFoamIsActive = _bIsOK;
      _hWSE->a_stFoams->lLifeTime = _hWSE->lLifeTime;
      _hWSE->lFoamFrameCounter++;
      if( _hWSE->lFoamFrameCounter == _hWSE->lNbGraphicFoams )
         _hWSE->lFoamFrameCounter = 0;
   }
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_vTreatWaterStreak(
   GAM_tdxHandleToWaterStreakEffect _hWSE,long _lElapsedTime)
{
   long lI;
   tdstWaterFoam * p_stWF;
 
   p_stWF = _hWSE->a_stFoams;
   for( lI=0; lI<_hWSE->lNbFoams; lI++,p_stWF++ )
   {
      /* If foam is living*/
      if( p_stWF->bFoamIsActive )
      {
         p_stWF->lLifeTime -= _lElapsedTime;
         /* Is foam dead?*/
         if( p_stWF->lLifeTime<=0 )
            p_stWF->bFoamIsActive = FALSE;
      }
   }
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_vGenerateFoamInStreak(
   GAM_tdxHandleToWaterStreakEffect _hWSE,long _lElapsedTime,
   MTH3D_tdstVector * _p_stPosition)
{
   long lI;
   tdstWaterFoam * p_stWF;
 
   if( _hWSE->ulLastTimeOfShift - g_stEngineStructure.stEngineTimer.ulCurrentTimerCount>(unsigned long)_hWSE->lTimeBetweenTwoShifts )
   {
      _hWSE->ulLastTimeOfShift = g_stEngineStructure.stEngineTimer.ulCurrentTimerCount;
      p_stWF = _hWSE->a_stFoams;
      for( lI=0; lI<_hWSE->lNbFoams; lI++,p_stWF++ )
      {
         /* Search for a dead foam*/
         if( !p_stWF->bFoamIsActive )
         {
            /* Initialise datas for foam*/
            p_stWF->lLifeTime = _hWSE->lLifeTime;
            MTH3D_M_vCopyVector(&p_stWF->stPosition,_p_stPosition);
            /* Activate the foam */
            p_stWF->bFoamIsActive = TRUE;
            break;
         }
      }
   }
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_vZoomAndDrawObjectOnXAndY(
   GLD_tdstViewportAttributes * _p_stViewportAttr,
   ACP_tdxHandleOfObject _hGeoObj,
   MTH_tdxReal _xXScale,
   MTH_tdxReal _xYScale,
   long _lDrawMask);
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_vDisplayWaterStreak(GLD_tdstViewportAttributes * _p_stViewportAttr,GAM_tdxHandleToWaterStreakEffect _hWSE,long _lDrawMask)
{
   POS_tdstCompletePosition stMatrix;
   long lI;
   MTH_tdxReal xTmp;
   long lTmp;
   tdstWaterFoam * p_stWF;
 
   p_stWF = _hWSE->a_stFoams;
   POS_fn_vSetIdentityMatrix(&stMatrix);
   for( lI=0; lI<_hWSE->lNbFoams; lI++,p_stWF++ )
   {
      /* if plouf state is correct */
      if( p_stWF->bFoamIsActive )
      {
         /* Let's draw this plouf */
         POS_fn_vSetTranslationVector(&stMatrix,&p_stWF->stPosition);
         HIE_fn_bLoadMatrix(&stMatrix);
         xTmp = _hWSE->xLifeTimeFrequency*(float)(_hWSE->lLifeTime - p_stWF->lLifeTime);
         xTmp = 1.0f - _hWSE->xFoamXZoom*xTmp;
         lTmp = lI + _hWSE->lFoamFrameCounter;
         lTmp = ( lTmp>=_hWSE->lNbGraphicFoams ? lTmp%_hWSE->lNbGraphicFoams : lTmp );
         fn_vZoomAndDrawObjectOnXAndY(
            _p_stViewportAttr,_hWSE->a_hFoamObjectTable[lTmp],xTmp,xTmp,_lDrawMask);
         HIE_fn_vPopMatrix();
      }
   }
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_vZoomAndDrawObjectOnXAndY(
   GLD_tdstViewportAttributes * _p_stViewportAttr,
   ACP_tdxHandleOfObject _hGeoObj,
   MTH_tdxReal _xXScale,
   MTH_tdxReal _xYScale,
   long _lDrawMask)
{
   MTH3D_tdstVector a_stPoints[4];
   MTH3D_tdstVector a_stScaledPoints[4];
   MTH_tdxReal xX,xY,xZ;
   MTH_tdxReal xXMin,xXMax,xYMin,xYMax;
 
   GEO_vGetPointOfObject(_hGeoObj,&a_stPoints[0],0);
   GEO_vGetPointOfObject(_hGeoObj,&a_stPoints[1],1);
   GEO_vGetPointOfObject(_hGeoObj,&a_stPoints[2],2);
   GEO_vGetPointOfObject(_hGeoObj,&a_stPoints[3],3);
 
   MTH3D_M_vGetVectorElements(&xX,&xY,&xZ,&a_stPoints[0]);
   xXMin = xX*_xXScale;
   xYMin = xY*_xYScale;
   MTH3D_M_vGetVectorElements(&xX,&xY,&xZ,&a_stPoints[2]);
   xXMax = xX*_xXScale;
   xYMax = xY*_xYScale;
   MTH3D_M_vSetVectorElements(&a_stScaledPoints[0],xXMin,xYMin,xZ);
   MTH3D_M_vSetVectorElements(&a_stScaledPoints[1],xXMax,xYMin,xZ);
   MTH3D_M_vSetVectorElements(&a_stScaledPoints[2],xXMax,xYMax,xZ);
   MTH3D_M_vSetVectorElements(&a_stScaledPoints[3],xXMin,xYMax,xZ);
 
   GEO_vSetPointOfObject(_hGeoObj,&a_stScaledPoints[0],0);
   GEO_vSetPointOfObject(_hGeoObj,&a_stScaledPoints[1],1);
   GEO_vSetPointOfObject(_hGeoObj,&a_stScaledPoints[2],2);
   GEO_vSetPointOfObject(_hGeoObj,&a_stScaledPoints[3],3);
 
   GLI_xSendObjectToViewport( 
      _p_stViewportAttr,_hGeoObj,gp_stLight,
      _lDrawMask&(GLI_C_lAllIsEnable-GLI_C_lNotForceZSorting));
 
   GEO_vSetPointOfObject(_hGeoObj,&a_stPoints[0],0);
   GEO_vSetPointOfObject(_hGeoObj,&a_stPoints[1],1);
   GEO_vSetPointOfObject(_hGeoObj,&a_stPoints[2],2);
   GEO_vSetPointOfObject(_hGeoObj,&a_stPoints[3],3);
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
void fn_vWaterStreakEffect(
   GLD_tdstViewportAttributes * _p_stViewportAttr,
   HIE_tdxHandleToSuperObject _hCharacter,
   long _lDrawMask)
{
#ifndef D_THROW_PRT
   GAM_tdxHandleToWaterStreakEffect hWaterStreak;
   long lElapsedTime;
   MTH3D_tdstVector stV;
 
   if( M_GetMSHandle(_hCharacter,MSPrtSrc) )
   {
      hWaterStreak = fn_hMSPrtSrcGetWaterStreakGenerator( M_GetMSHandle(_hCharacter,MSPrtSrc) );
      if( !hWaterStreak )
         return;
      /* Computing elapsed time*/
      lElapsedTime = g_stEngineStructure.stEngineTimer.ulUsefulDeltaTime;
 
      if( fn_bIsCharacterCrossingASurfaceOfWater(_hCharacter,&stV) )
      {
         /* Generate a foam*/
         fn_vGenerateFoamInStreak(hWaterStreak,lElapsedTime,&stV);
      }
      /* Treat the water streak*/
      fn_vTreatWaterStreak(hWaterStreak,lElapsedTime);
   }
#endif /* D_THROW_PRT */
}
 
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
ACP_tdxBool fn_bIsCharacterCrossingASurfaceOfWater(
   HIE_tdxHandleToSuperObject _hCharacter,
   MTH3D_tdstVector * _p_stRealPoint)
{
/* 
   DNM_tdeFluidEnvironment eDnmEnvironment;
   MTH3D_tdstVector stPositionOnWaterPlane;
   MTH_tdxReal xDepth;
 
   if( GAM_fn_bGetEnvironmentOfPointOfType(
          _hCharacter,DNM_Point_Feet,&eDnmEnvironment) )
   {
      if( eDnmEnvironment==DNM_Fluid_Water )
      {
         if( GAM_fn_bGetEnvironmentOfPointOfType(
            _hCharacter,DNM_Point_Head,&eDnmEnvironment) )
         {
            if( eDnmEnvironment==DNM_Fluid_Air )
            {
               POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(_hCharacter),&stPositionOnWaterPlane);
               SECT_hGetDNMEnvironmentAndDepth(
                  NULL,
                  &stPositionOnWaterPlane,
                  fn_h_SectInfoGetCurrentSector(M_GetMSHandle(_hCharacter,SectInfo)), 
                  &xDepth);
               MTH3D_M_vSetZofVector(&stPositionOnWaterPlane,MTH3D_M_xGetZofVector(&stPositionOnWaterPlane)+xDepth+0.05f);
               MTH3D_M_vCopyVector(_p_stRealPoint,&stPositionOnWaterPlane);
               return TRUE;
            }
         }
      }
   }*/
   return FALSE;
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
/*ANNECY VL 03/11/97{*/
/*
 =======================================================================================
  =======================================================================================
	 special code for footpath effect
  =======================================================================================
 =======================================================================================
 */
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : allocate and initialize a footpath effect structure
  Returns (GAM_tdxHandleToFootPathEffect ) allocated footpath structure
 ----------------------------------------------------------------------------------------
 */
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
GAM_tdxHandleToFootPathEffect fn_h_FootPath_Alloc()
{
	tdstFootPath *p_stFootPath;
 
	p_stFootPath = (tdstFootPath *) M_p_GameMallocInHLM ( sizeof( tdstFootPath) );
	memset( p_stFootPath, 0, sizeof( tdstFootPath ) );
	return (GAM_tdxHandleToFootPathEffect) p_stFootPath;
}
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : create footpath internal data ( geom object )
  _hFootPath          -> foot path that is to be created
 ----------------------------------------------------------------------------------------
 */
void fn_v_FootPath_Create( GAM_tdxHandleToFootPathEffect _hFootPath )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	tdstFootPath					*p_stFP;
	GMT_tdxHandleToGameMaterial		hGMCopy;
	ACP_tdxHandleOfMaterial			hVisual;
	GLI_tdstColor					stColor;
	ACP_tdxHandleOfElement			hElement;
	ACP_tdst2DUVValues				a_stUV[4] = { {0.0f,0.0f}, {1.0f,0.0f}, {1.0f,1.0f}, {0.0f,1.0f} };
	ACP_tdxIndex					xPoint, xFace, xObj;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
	p_stFP = (tdstFootPath *) _hFootPath;
	/* creation of game material that represent a left foot print */
	hVisual = GMT_fn_hGetVisualMaterial( p_stFP->hFootPrintMaterial );
	GLI_xGetMaterialType( hVisual, (unsigned long *)&xPoint );
	xPoint &= ~( GLI_C_lIsNotGrided | GLI_C_lIsNotLightAlphaSensitive );
	GLI_xSetMaterialType( hVisual, xPoint );
 
	for (xObj = 0; xObj < p_stFP->xNumberOfAlphaLevels; xObj ++)
	{
		/* creation of geometric object */
		GEO_vCreateGeometricObject( &p_stFP->a8_hGeomObj[ xObj ], p_stFP->a8_xNumberOfPoints[ xObj ], 1 );
		p_stFP->a8_xMaxNumberOfFaces[ xObj ] = (ACP_tdxIndex)(p_stFP->a8_xNumberOfPoints[ xObj ] >> 1);
 
		/* creation of element */
		GEO_vCreateElementIndexedTriangles( p_stFP->a8_hGeomObj[ xObj ], &hElement, p_stFP->a8_xMaxNumberOfFaces[ xObj ], 4);
 
		/* set material of element */
		if (xObj != 0)
		{
			hGMCopy = GMT_fn_hCreateGameMaterial();
			GMT_fn_vCopyGameMaterial( hGMCopy, p_stFP->hFootPrintMaterial );
		}
		else
			hGMCopy = p_stFP->hFootPrintMaterial;
 
#ifndef CONST_VMT
		hVisual = GMT_fn_hGetVisualMaterial( hGMCopy );
		GLI_xGetMaterialAmbientCoef( hVisual, &stColor );
		stColor.xA = p_stFP->a8_xAlphaColor[ xObj ];
		GLI_xSetMaterialAmbientCoef( hVisual, &stColor );
#endif
 
		GEO_vSetGameMaterialOfIndexedTriangles( p_stFP->a8_hGeomObj[ xObj ], hElement, hGMCopy );
 
		/* set uv coordinates */
		for (xPoint = 0; xPoint < 4; xPoint++ )
			GEO_vSetUVOfIndexedTriangles( p_stFP->a8_hGeomObj[ xObj ], hElement, xPoint, a_stUV + xPoint);
		
		/*for (xPoint = 0, xFace = 0; xFace < g_stFootPath.a8_xMaxNumberOfFaces[ xObj ]; )*/
		for (xPoint = 0, xFace = 0; xFace < p_stFP->a8_xMaxNumberOfFaces[ xObj ]; )
		{
			GEO_vSetFaceOfIndexedTriangles(p_stFP->a8_hGeomObj[ xObj ], hElement, xFace++, xPoint, (ACP_tdxIndex)(xPoint + 1), (ACP_tdxIndex)(xPoint + 3));
			GEO_vSetFaceOfIndexedTriangles(p_stFP->a8_hGeomObj[ xObj ], hElement, xFace++, (ACP_tdxIndex)(xPoint + 1), (ACP_tdxIndex)(xPoint + 2), (ACP_tdxIndex)(xPoint + 3));
			xPoint += 4;
		}
		((GEO_tdstElementIndexedTriangles *) p_stFP->a8_hGeomObj[xObj]->d_stListOfElements[ 0 ])->xNbFaces = 0;
	}
	GLI_vEndofGeometricLoad();
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : reinit (emptied the foot path)
  _hFootPath          -> footpath to clear
  Returns (void )
 ----------------------------------------------------------------------------------------
 */
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_v_FootPath_ReInit( GAM_tdxHandleToFootPathEffect _hFootPath )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	tdstFootPath	*p_stFP;
	ACP_tdxIndex	xObj;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
	p_stFP = (tdstFootPath *) _hFootPath;
	
	if (p_stFP->a8_hGeomObj[0] == NULL )
		return;
 
	for (xObj = 0; xObj < p_stFP->xNumberOfAlphaLevels; xObj++)
	{
		p_stFP->a8_xNumberOfFaces[ xObj ] = p_stFP->a8_xNextFaces[ xObj ] = 0;
		((GEO_tdstElementIndexedTriangles *) p_stFP->a8_hGeomObj[xObj]->d_stListOfElements[ 0 ])->xNbFaces = 0;
	}
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_v_FootPath_Compute( HIE_tdxHandleToSuperObject _hCharacter, ACP_tdxIndex _xType );
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : add a footprint into the foot path
  hHandleOfCharacter  -> character that have a footpath
  _xFootPrintType     -> left (0) or right (1) foot print
 ----------------------------------------------------------------------------------------
 */
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_v_FootPath_Add( HIE_tdxHandleToSuperObject _hCharacter, ACP_tdxIndex _xFootPrintType )
{
#ifndef D_THROW_PRT
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	MS_tdxHandleToMSPrtSrc	hMSPrtSrc;
	tdstFootPath			*p_stFP;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
	/* retrieve footpath information */
	hMSPrtSrc = M_GetMSHandle(_hCharacter,MSPrtSrc);
	if (hMSPrtSrc == NULL)
		return;
 
	p_stFP = (tdstFootPath *) fn_hMSPrtSrcGetFootPath( hMSPrtSrc );
	if (p_stFP->a8_hGeomObj[0] == NULL)
		return;
 
	fn_v_FootPath_Compute( _hCharacter, _xFootPrintType );
	return;
#endif /* D_THROW_PRT */
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
/*
 ----------------------------------------------------------------------------------------
  Description   : display a foot path
  _hFootPath          -> foot path that is to be displayed
  _p_stViewportAttr   ->
  Returns (void )
 ----------------------------------------------------------------------------------------
 */
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_v_FootPath_Display(GAM_tdxHandleToFootPathEffect _hFootPath, GLD_tdstViewportAttributes * _p_stViewportAttr, long _lDrawMask)
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	tdstFootPath	*p_stFP;
	ACP_tdxIndex	xObj;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
	p_stFP = (tdstFootPath *) _hFootPath;
 
	for (xObj = 0; xObj < p_stFP->xNumberOfAlphaLevels; xObj ++)
	{
		if (p_stFP->a8_hGeomObj[ xObj ] == NULL)
			return;
	
		HIE_fn_bLoadIdentity();
		GLI_xSendObjectToViewport( _p_stViewportAttr, p_stFP->a8_hGeomObj[ xObj ], gp_stLight, _lDrawMask );
		HIE_fn_vPopMatrix();
	}
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
/**********************************************************************************************/
/* Name: fn_v_FootPath_Compute*/
/* Goal: Compute geometric point to define a footprint*/
/**********************************************************************************************/
 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Oliv' - Portage v15 - remove warnings and unused variables*/
#ifndef D_THROW_PRT
static float			gs_fDeltaZ = 0.01f;
static float			gs_fSPZ = 0.3f;
static MTH3D_tdstVector	gs_stPicking = { 0, 0, -0.6f};
static ACP_tdxIndex		gs_a2a6_xUV[2][6] = { {0,1,3,1,2,3}, {1,0,2,0,3,2} };
static ACP_tdxIndex		gs_a4a2_xChangeSign[4][2] = { { 0, 0}, { 1, 0}, { 0, 1}, { 1,0} };
#endif /* D_THROW_PRT */
/* EndOfOliv'*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
/*
 ----------------------------------------------------------------------------------------
  Description   : compute foot print emplacement
  _hCharacter         -> caractere that will have a new foot print in it's foot path
  _xType              -> type of foot print : 0 -> left, 1 -> right
 ----------------------------------------------------------------------------------------
 */
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
void fn_v_FootPath_Compute( HIE_tdxHandleToSuperObject _hCharacter, ACP_tdxIndex _xType )
{
#ifndef D_THROW_PRT
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	tdstFootPath						*p_stFP;
	HIE_tdxHandleToSuperObject			hSector;
 
	GEO_tdxHandleToMatrix               hGlobalMatrixOfCharacter;
	MTH3D_tdstVector                    stVectX, stVectY, stVectZ, stTrans;
	MTH3D_tdstVector                    stEndPicking;
	MTH3D_tdstVector                    stStartPicking;
	ACP_tdxIndex                        xResultIntersection = 0;
 
	MTH3D_tdstVector                    a4_stPickedPoint[4];
/*	HIE_tdxHandleToSuperObject          hPickedSpObj;*/
	ACP_tdxHandleOfObject               hPickedObject = NULL;
	ACP_tdxIndex                        xPickedElement = 0;
/*	ACP_tdxIndex                        xPickedFace;*/
/*XB890504*/
/*	short                               xNbObjPicked=0;*/
/*End XB*/
	GMT_tdxHandleToGameMaterial			hMaterial;
	GMT_tdxHandleToCollideMaterial hCM;
 
	ACP_tdxIndex						xPoint, xObj;
 
	ACP_tdxIndex						*p_xFaceSource, *p_xFaceDest;
	MTH3D_tdstVector					*p_stPointSource, *p_stPointDest;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
	/* get foot path struct */
	p_stFP = (tdstFootPath *) fn_hMSPrtSrcGetFootPath( M_GetMSHandle(_hCharacter,MSPrtSrc) );
  
	/* get sector where perso is */
	hSector = fn_h_SectInfoGetCurrentSector( M_GetMSHandle( _hCharacter, SectInfo) );
	/* get matrix and position of character */
	hGlobalMatrixOfCharacter = HIE_fn_hGetSuperObjectGlobalMatrix( _hCharacter );
    POS_fn_vGetTranslationVector( hGlobalMatrixOfCharacter, &stTrans );
	POS_fn_vGetRotationMatrix( hGlobalMatrixOfCharacter, &stVectX, &stVectY, &stVectZ );
	
	/* ZVector of rotation matrix isn't used, use it to store rotation of footprint offset */
	POS_fn_vRotateVector( &stVectZ, hGlobalMatrixOfCharacter, &p_stFP->a2_stOffset[ _xType ] );
	/* shift position of foot print */
	MTH3D_M_vAddVector( &stTrans, &stTrans, &stVectZ );
	/* increase Z of position to be sure to be above the floor */
    stTrans.xZ = MTH_M_xAdd(stTrans.xZ, gs_fSPZ);
 
	/* set X and Y to good foot print dimension */
	MTH3D_M_vMulScalarVector( &stVectX, p_stFP->a2_xScale[0], &stVectX );
	MTH3D_M_vMulScalarVector( &stVectY, p_stFP->a2_xScale[1], &stVectY );
	
	for ( xPoint = 0; xPoint < 4; xPoint++ )
	{
		/* compute point position */
		if (gs_a4a2_xChangeSign[ xPoint ][ 0 ])	MTH3D_M_vNegVector( &stVectX, &stVectX );	
		if (gs_a4a2_xChangeSign[ xPoint ][ 1 ])	MTH3D_M_vNegVector( &stVectY, &stVectY );	
 
		MTH3D_M_vAddVector( &stStartPicking, &stVectX, &stVectY );
		MTH3D_M_vAddVector( &stStartPicking, &stStartPicking, &stTrans );
 
		MTH3D_M_vAddVector( &stEndPicking, &stStartPicking, &gs_stPicking );
 
		/* get impact on the floor of sector */
		/*
		xResultIntersection = SHW_fn_bIntersectShadowSuperObject
								(
									&stStartPicking, 
									&stEndPicking, 
									&gs_stPicking, 
									1.1f,
									hSector,
									&a4_stPickedPoint[ xPoint ], 
									&hPickedSpObj, 
									&hPickedObject, 
									&xPickedElement, 
									&xPickedFace, 
									&xNbObjPicked
								);
								*/
/*		xResultIntersection = SHW_fn_bIntersectShadowSuperObjectLevel1
								(
									&stStartPicking, 
									&stEndPicking, 
									&gs_stPicking, 
									hSector,
									&a4_stPickedPoint[ xPoint ], 
									&hPickedSpObj, 
									&hPickedObject, 
									&xPickedElement, 
									&xPickedFace, 
									&stVectZ,
									_hCharacter
								);
 
*/		/* no impact : stop */
		if (xResultIntersection == 0)
			break;
 
		/* get material of picked face to know if trace could be leaved */
		if ( p_stFP->xConsiderMaterial )
		{
			hMaterial = NULL;
			switch (GEO_xGetElementType( hPickedObject, xPickedElement ) )
			{
				case GEO_C_xElementIndexedTriangles:
					GEO_vGetGameMaterialOfIndexedTriangles( hPickedObject, xPickedElement, &hMaterial );
					break;
/*				case GEO_C_xElementFaceMapDescriptors:*/
/*					break;*/
			}
 
			if ( hMaterial == NULL)
				break;
 
			hCM = GMT_fn_hGetCollideMaterial( hMaterial );
			if (hCM == GMT_C_InvalidCollideMaterial)
				break;
		
			if ( (GMT_fn_hGetCollideMaterialIdentifier( hCM ) & p_stFP->xConsiderMaterial ) == 0 )
				break;
		}
		a4_stPickedPoint[ xPoint ].xZ += gs_fDeltaZ;
	}
	
	/* all 4 points of foot print are good  : add it*/
	if (xPoint == 4)
	{
		/* move erased point to more transparent object */
		for (xObj = (ACP_tdxIndex)(p_stFP->xNumberOfAlphaLevels - 2); xObj >= 0; xObj-- )
		{
			if ( p_stFP->a8_xNextFaces[ xObj ] < p_stFP->a8_xNumberOfFaces[ xObj ] )
			{
				/* get pointer on data to be moved */
				p_xFaceSource	= (ACP_tdxIndex *) &((GEO_tdstElementIndexedTriangles *) p_stFP->a8_hGeomObj[ xObj ]->d_stListOfElements[ 0 ])->d_stListOfFacesTripledIndexUV[ p_stFP->a8_xNextFaces[xObj] ];
				p_stPointSource	= &p_stFP->a8_hGeomObj[ xObj ]->d_stListOfPoints[p_stFP->a8_xNextFaces[xObj] * 2];
 
				/* get pointer where data will be moved (in next object) */
				p_xFaceDest		= (ACP_tdxIndex *) &((GEO_tdstElementIndexedTriangles *) p_stFP->a8_hGeomObj[ xObj + 1 ]->d_stListOfElements[ 0 ])->d_stListOfFacesTripledIndexUV[ p_stFP->a8_xNextFaces[xObj + 1] ];
				p_stPointDest	= &p_stFP->a8_hGeomObj[ xObj + 1 ]->d_stListOfPoints[p_stFP->a8_xNextFaces[xObj + 1] * 2];
 
				/* move points : decrease Z of each point*/
				memcpy( p_stPointDest, p_stPointSource, 4 * sizeof( MTH3D_tdstVector ) );
				for (xPoint = 0; xPoint < 4; xPoint ++ )
					p_stPointDest[ xPoint ].xZ -= 0.001f;
 
				/* move uv indexes */
				memcpy( p_xFaceDest, p_xFaceSource, 6 * sizeof( ACP_tdxIndex ) );
 
				/* a face is added in object current + 1, change footpath data */
				p_stFP->a8_xNextFaces[xObj + 1] += 2;
				if (p_stFP->a8_xNextFaces[xObj + 1] > p_stFP->a8_xNumberOfFaces[ xObj + 1])
				{
					((GEO_tdstElementIndexedTriangles *) p_stFP->a8_hGeomObj[xObj+1]->d_stListOfElements[0])->xNbFaces = p_stFP->a8_xNextFaces[ xObj + 1];
					p_stFP->a8_xNumberOfFaces[ xObj + 1] = p_stFP->a8_xNextFaces[ xObj + 1];
				}
				if (p_stFP->a8_xNextFaces[ xObj + 1] == p_stFP->a8_xMaxNumberOfFaces[ xObj + 1] )
					p_stFP->a8_xNextFaces[ xObj + 1] = 0;
			}
		}
 
		/* add new point to object 0 */
		
		/* get pointer where data will be moved */
		p_stPointDest = &p_stFP->a8_hGeomObj[ 0 ]->d_stListOfPoints[p_stFP->a8_xNextFaces[0] * 2];
		p_xFaceDest	  = (ACP_tdxIndex *) &((GEO_tdstElementIndexedTriangles *) p_stFP->a8_hGeomObj[ 0 ]->d_stListOfElements[ 0 ])->d_stListOfFacesTripledIndexUV[ p_stFP->a8_xNextFaces[ 0 ] ];
		
		/* copy point and UV indexes */
		memcpy( p_stPointDest, a4_stPickedPoint, 4 * sizeof( MTH3D_tdstVector ) );
		memcpy( p_xFaceDest, gs_a2a6_xUV[ _xType ], 6 * sizeof( ACP_tdxIndex ) );
 
		/* update object 0 footpath data */
		p_stFP->a8_xNextFaces[ 0 ] += 2;
		if (p_stFP->a8_xNextFaces[ 0 ] > p_stFP->a8_xNumberOfFaces[ 0 ] )
		{
			((GEO_tdstElementIndexedTriangles *) p_stFP->a8_hGeomObj[0]->d_stListOfElements[ 0 ])->xNbFaces = p_stFP->a8_xNextFaces[ 0 ];
			p_stFP->a8_xNumberOfFaces[ 0 ] = p_stFP->a8_xNextFaces[ 0 ];
		}
		if (p_stFP->a8_xNextFaces[ 0 ] == p_stFP->a8_xMaxNumberOfFaces[ 0 ] )
		{
			p_stFP->a8_xNextFaces[ 0 ] = 0;
		}
	}
#endif /* D_THROW_PRT */
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
/*ENDANNECY VL }*/
