/*
Tested with LINT
*/
#define MTH_LOW
 
#include "gli_st.h"
#include "GLI_Defn.h"
#include "mater_st.h"
#include "light_st.h"
#include "PvObj_st.h"
#include "material.h"
#include "GeoSprit.h"
#include "proj.h"
#include "linear.h"
#include "vpt3D.h"
#include "camera.h"
#include "DLLInter.h"
 
extern GLI_tdstInternalGlobalValuesFor3dEngine *GLI_BIG_GLOBALS;
 
 
#ifdef __cplusplus
extern "C" 
{
#endif
  
/*extern void GLI_NJA_vSendSpriteToClip(GLI_tdstAligned2DVector *a4_st2DVertex , MTH_tdxReal xZ , GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT);*/
/*extern void GLI_NJA_vSendSpriteToClipWithUV(GLI_tdstAligned2DVector *a4_st2DVertex ,MTH_tdxReal *a8_stUVVertex,MTH_tdxReal xZ ,GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT);*/
extern void GLI_vDoMaterialSelection(GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT);
  /**********************************************************************************************/
  /* Name: GLI_xDraw2DSprite*/
  /* Goal: */
  /* Code: Philippe Vimont / 1.0*/
  /**********************************************************************************************/
  void GLI_vDraw2DSprite ( GLD_tdstViewportAttributes *p_stVpt ,MTH_tdxReal  xXMin,MTH_tdxReal  xXMax,MTH_tdxReal  xYMin,MTH_tdxReal  xYMax,ACP_tdxHandleOfMaterial hMaterial)
  {
    GLI_tdstAligned2DVector a4_st2DVertex  [5];
    GEO_tdstColor stLocalColor;
    stLocalColor . xG = stLocalColor . xB = stLocalColor. xR = 0.0f;
    GLI_xSetMaterialAmbientCoef(hMaterial , &stLocalColor);
    stLocalColor . xG = stLocalColor . xB = stLocalColor. xR = 1.0f;
    GLI_xSetMaterialDiffuseCoef(hMaterial , &stLocalColor);
    stLocalColor . xG = stLocalColor . xB = stLocalColor. xR = 0.0f;
    GLI_xSetMaterialSpecularCoef(hMaterial , 0 , &stLocalColor);
 
    a4_st2DVertex  [0] . xX = (float)(long)xXMin;
    a4_st2DVertex  [0] . xY = (float)(long)xYMin;
    a4_st2DVertex  [0] . xOoZ =1.0f;
    a4_st2DVertex  [1] . xX = (float)(long)xXMax;
    a4_st2DVertex  [1] . xY = (float)(long)xYMin;
    a4_st2DVertex  [1] . xOoZ =1.0f;
    a4_st2DVertex  [2] . xX = (float)(long)xXMax;
    a4_st2DVertex  [2] . xY = (float)(long)xYMax;
    a4_st2DVertex  [2] . xOoZ =1.0f;
    a4_st2DVertex  [3] . xX = (float)(long)xXMin;
    a4_st2DVertex  [3] . xY = (float)(long)xYMax;
    a4_st2DVertex  [3] . xOoZ =1.0f;
    GLI_BIG_GLOBALS -> hCurrentMaterial = hMaterial;
    GLI_BIG_GLOBALS -> hCurrentMaterial -> xMaterialType = 0xFFFFFFFF - GLI_C_lIsTestingBackface;
    GLI_BIG_GLOBALS -> lCurrentDrawMask = 0xFFFFFFFF - GLI_C_lIsTestingBackface;
    GLI_BIG_GLOBALS -> lHierachDrawMask = 0xFFFFFFFF - GLI_C_lIsTestingBackface;
    GLI_vDoMaterialSelection(GLI_BIG_GLOBALS );
    GLI_DRV_vSendSpriteToClip( a4_st2DVertex , 1.0f / GLI_C_xZClippingNear, GLI_BIG_GLOBALS);
  }
  
  /**********************************************************************************************/
  /* Name: GLI_xDraw2DSpriteWithUV*/
  /* Goal: */
  /* Code: Philippe Vimont / 1.0*/
  /**********************************************************************************************/
  void 
    GLI_vDraw2DSpriteWithUV ( GLD_tdstViewportAttributes *p_stVpt ,
                       MTH_tdxReal  xXMin,
                       MTH_tdxReal  xXMax,
                       MTH_tdxReal  xYMin,
                       MTH_tdxReal  xYMax,
                       MTH_tdxReal  xUMin,
                       MTH_tdxReal  xUMax,
                       MTH_tdxReal  xVMin,
                       MTH_tdxReal  xVMax,
                       ACP_tdxHandleOfMaterial hMaterial)
  {
    GLI_tdstAligned2DVector a4_st2DVertex  [5];
    MTH_tdxReal   a4_stUVVertex  [10];
    GEO_tdstColor stLocalColor;
    stLocalColor . xG = stLocalColor . xB = stLocalColor. xR = 0.0f;
    GLI_xSetMaterialAmbientCoef(hMaterial , &stLocalColor);
    stLocalColor . xG = stLocalColor . xB = stLocalColor. xR = 1.0f;
    GLI_xSetMaterialDiffuseCoef(hMaterial , &stLocalColor);
    stLocalColor . xG = stLocalColor . xB = stLocalColor. xR = 0.0f;
    GLI_xSetMaterialSpecularCoef(hMaterial , 0 , &stLocalColor);
 
    a4_st2DVertex  [0] . xX = (float)(long)xXMin;
    a4_st2DVertex  [0] . xY = (float)(long)xYMin;
    a4_st2DVertex  [0] . xOoZ =1.0f;
    a4_st2DVertex  [1] . xX = (float)(long)xXMax;
    a4_st2DVertex  [1] . xY = (float)(long)xYMin;
    a4_st2DVertex  [1] . xOoZ =1.0f;
    a4_st2DVertex  [2] . xX = (float)(long)xXMax;
    a4_st2DVertex  [2] . xY = (float)(long)xYMax;
    a4_st2DVertex  [2] . xOoZ =1.0f;
    a4_st2DVertex  [3] . xX = (float)(long)xXMin;
    a4_st2DVertex  [3] . xY = (float)(long)xYMax;
    a4_st2DVertex  [3] . xOoZ =1.0f;
    a4_stUVVertex  [0]   = xUMin;
    a4_stUVVertex  [0+1] = xVMin;
    a4_stUVVertex  [2]   = xUMax;
    a4_stUVVertex  [2+1] = xVMin;
    a4_stUVVertex  [4]   = xUMax;
    a4_stUVVertex  [4+1] = xVMax;
    a4_stUVVertex  [6]   = xUMin;
    a4_stUVVertex  [6+1] = xVMax;
    
    GLI_BIG_GLOBALS -> hCurrentMaterial = hMaterial;
    GLI_BIG_GLOBALS -> hCurrentMaterial -> xMaterialType = 0xFFFFFFFF - GLI_C_lIsTestingBackface;
    GLI_BIG_GLOBALS -> lCurrentDrawMask = 0xFFFFFFFF - GLI_C_lIsTestingBackface;
    GLI_BIG_GLOBALS -> lHierachDrawMask = 0xFFFFFFFF - GLI_C_lIsTestingBackface;
    GLI_vDoMaterialSelection(GLI_BIG_GLOBALS );
    GLI_DRV_vSendSpriteToClipWithUV ( a4_st2DVertex ,a4_stUVVertex ,1.0f / GLI_C_xZClippingNear,GLI_BIG_GLOBALS);
  }
  
/* STM- get rid of this in final version if we really don't need the old rot. code*/
#define USE_NEW_SPRITE
#ifdef USE_NEW_SPRITE
#pragma message(__FILE__ ": Using new sprite code")
  /**********************************************************************************************/
  /* Name: GLI_xDrawIndexedSprite*/
  /* Goal: */
  /* Code: Steve McCalla / 2.0*/
  /* This function assumes that scale is always diagonal*/
  /**********************************************************************************************/
 
void 
GLI_vDrawIndexedSprite ( GLD_tdstViewportAttributes *p_stVpt ,
						GEO_tdstGeometricObject *p_stObj ,
						GEO_tdstIndexedSprite *p_stISpr ,
						GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT)
{
    GLI_tdstAligned3DVector stScaledPt[3];
    GLI_tdstAligned2DVector a4_st2DVertex  [4];
    GLI_tdstAligned2DVector a2_st2DVertexLocal[3];
	GLI_tdScreenVertx		a4_ScrVertex[4];
	GLI_tdScreenVertx		*pVtx1, *pVtx2, *pVtx3, *pVtx4;
    ACP_tdxIndex xSpriteNumber;
 
	MTH_tdxReal xTempZ; 
	xSpriteNumber = 0;
    
	if ((p_stISpr -> hSprite == NULL)  
		|| ((p_stGlobaleMT -> GLI_ScreenPoint + p_stISpr -> xCenterPoint) -> xOoZ < 0.0f)
		|| (p_stISpr -> hSprite -> d_xSpriteDrawMode[xSpriteNumber] & GEO_C_lSpriteDrawDisable))
		return;
 
	assert (p_stISpr -> hSprite -> xNbSprites == 1);
	assert (!(p_stISpr -> hSprite -> d_xSpriteDrawMode[xSpriteNumber] & GEO_C_lSpriteDrawMode2DRotativ));
    assert (p_stISpr -> stSize.xX == 1.0);
    assert (p_stISpr -> stSize.xY == 1.0);
 
	pVtx1 = a4_ScrVertex;
	pVtx2 = a4_ScrVertex+1;
	pVtx3 = a4_ScrVertex+2;
	pVtx4 = a4_ScrVertex+3;
 
	stScaledPt[0].xX = p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xX;
	stScaledPt[0].xY = 0.0;
	stScaledPt[1].xX = 0.0;
	stScaledPt[1].xY = -p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xY;
	stScaledPt[2].xX = 0.0;
	stScaledPt[2].xY = 0.0;
 
	if (!POS_fn_ulIsNotScaledMatrix ( &p_stGlobaleMT -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix))
	{
		MTH_tdxReal xScaleX;
		MTH_tdxReal xScaleY;
		xScaleX = POS_fn_xGetXScale(&(p_stGlobaleMT->gs_st_CurrentMatrixMultiplyedWithCameraMatrix));
		xScaleY = POS_fn_xGetYScale(&(p_stGlobaleMT->gs_st_CurrentMatrixMultiplyedWithCameraMatrix));
 
		stScaledPt[0].xX = xScaleX * p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xX;
		stScaledPt[1].xY = xScaleY * (-p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xY);
	}
 
	xTempZ = p_stGlobaleMT->GLI_TurnedScaledDisplecedPoint[p_stISpr->xCenterPoint].xZ;
 
	stScaledPt[0].xZ = xTempZ;
	stScaledPt[1].xZ = xTempZ;
	stScaledPt[2].xZ = xTempZ;
 
	if (p_stISpr -> hSprite -> d_xSpriteDrawMode[xSpriteNumber] & GEO_C_lSpriteDrawMode2DScaled) {
 
		GLI_xSerialProjectionNoTrans ( (( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD)->p_stCam,
										3, stScaledPt, a2_st2DVertexLocal);
		SetX(pVtx1, p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xX - a2_st2DVertexLocal[0].xX - a2_st2DVertexLocal[1].xX + a2_st2DVertexLocal[2].xX);
		SetY(pVtx1, p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xY - a2_st2DVertexLocal[0].xY - a2_st2DVertexLocal[1].xY + a2_st2DVertexLocal[2].xY);
		SetX(pVtx2, p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xX + a2_st2DVertexLocal[0].xX - a2_st2DVertexLocal[1].xX + a2_st2DVertexLocal[2].xX);
		SetY(pVtx2, p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xY + a2_st2DVertexLocal[0].xY - a2_st2DVertexLocal[1].xY + a2_st2DVertexLocal[2].xY);
		SetX(pVtx3, p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xX + a2_st2DVertexLocal[0].xX + a2_st2DVertexLocal[1].xX + a2_st2DVertexLocal[2].xX);
		SetY(pVtx3, p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xY + a2_st2DVertexLocal[0].xY + a2_st2DVertexLocal[1].xY + a2_st2DVertexLocal[2].xY);
		SetX(pVtx4, p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xX - a2_st2DVertexLocal[0].xX + a2_st2DVertexLocal[1].xX + a2_st2DVertexLocal[2].xX);
		SetY(pVtx4, p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xY - a2_st2DVertexLocal[0].xY + a2_st2DVertexLocal[1].xY + a2_st2DVertexLocal[2].xY);
 
		a4_st2DVertex [0] . xX = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX - a2_st2DVertexLocal[0] . xX - a2_st2DVertexLocal[1] . xX + a2_st2DVertexLocal[2] . xX ;
		a4_st2DVertex [0] . xY = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY - a2_st2DVertexLocal[0] . xY - a2_st2DVertexLocal[1] . xY + a2_st2DVertexLocal[2] . xY ;
		a4_st2DVertex [1] . xX = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX + a2_st2DVertexLocal[0] . xX - a2_st2DVertexLocal[1] . xX + a2_st2DVertexLocal[2] . xX ;
		a4_st2DVertex [1] . xY = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY + a2_st2DVertexLocal[0] . xY - a2_st2DVertexLocal[1] . xY + a2_st2DVertexLocal[2] . xY ;
		a4_st2DVertex [2] . xX = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX + a2_st2DVertexLocal[0] . xX + a2_st2DVertexLocal[1] . xX + a2_st2DVertexLocal[2] . xX ;
		a4_st2DVertex [2] . xY = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY + a2_st2DVertexLocal[0] . xY + a2_st2DVertexLocal[1] . xY + a2_st2DVertexLocal[2] . xY ;
		a4_st2DVertex [3] . xX = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX - a2_st2DVertexLocal[0] . xX + a2_st2DVertexLocal[1] . xX + a2_st2DVertexLocal[2] . xX ;
		a4_st2DVertex [3] . xY = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY - a2_st2DVertexLocal[0] . xY + a2_st2DVertexLocal[1] . xY + a2_st2DVertexLocal[2] . xY ;
	}
	else {
		SetX(pVtx1, (float)(p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xX + stScaledPt[0].xX + stScaledPt[1].xX));
		SetY(pVtx1, (float)(p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xY + stScaledPt[0].xY + stScaledPt[1].xY));
		SetX(pVtx2, (float)(p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xX - stScaledPt[0].xX + stScaledPt[1].xX));
		SetY(pVtx2, (float)(p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xY - stScaledPt[0].xY + stScaledPt[1].xY));
		SetX(pVtx3, (float)(p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xX - stScaledPt[0].xX - stScaledPt[1].xX));
		SetY(pVtx3, (float)(p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xY - stScaledPt[0].xY - stScaledPt[1].xY));
		SetX(pVtx4, (float)(p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xX + stScaledPt[0].xX - stScaledPt[1].xX));
		SetY(pVtx4, (float)(p_stGlobaleMT->GLI_ScreenPoint [p_stISpr->xCenterPoint].xY + stScaledPt[0].xY - stScaledPt[1].xY));
 
		a4_st2DVertex [0] . xX = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX + stScaledPt[0] . xX + stScaledPt[1] . xX);
		a4_st2DVertex [0] . xY = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY + stScaledPt[0] . xY + stScaledPt[1] . xY);
		a4_st2DVertex [1] . xX = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX - stScaledPt[0] . xX + stScaledPt[1] . xX);
		a4_st2DVertex [1] . xY = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY - stScaledPt[0] . xY + stScaledPt[1] . xY);
		a4_st2DVertex [2] . xX = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX - stScaledPt[0] . xX - stScaledPt[1] . xX);
		a4_st2DVertex [2] . xY = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY - stScaledPt[0] . xY - stScaledPt[1] . xY);
		a4_st2DVertex [3] . xX = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX + stScaledPt[0] . xX - stScaledPt[1] . xX);
		a4_st2DVertex [3] . xY = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY + stScaledPt[0] . xY - stScaledPt[1] . xY);
 
	}
    
    p_stGlobaleMT -> hCurrentMaterial = GMT_fn_hGetVisualMaterial(p_stISpr -> hSprite -> d_hMaterial[xSpriteNumber]);
    {
        unsigned long xSaveDrawMsk;
        xSaveDrawMsk = p_stGlobaleMT -> lHierachDrawMask ;
        p_stGlobaleMT -> lHierachDrawMask &= ~GLI_C_lIsTestingBackface;
        GLI_vDoMaterialSelection(p_stGlobaleMT);
 
        p_stGlobaleMT->ulSpecularColorForSprite = ((unsigned long *) p_stGlobaleMT->GLI_aDEF_stColorsRLIS)[p_stISpr -> xCenterPoint];
        GLI_DRV_vSendSpriteToClip(a4_st2DVertex , p_stGlobaleMT->GLI_ScreenPoint [p_stISpr -> xCenterPoint].xOoZ, p_stGlobaleMT);
        p_stGlobaleMT -> lHierachDrawMask = xSaveDrawMsk;
    }
}
 
#else /* using old sprite code*/
#pragma message(__FILE__ ": Using old sprite code")
  /**********************************************************************************************/
  /* Name: GLI_xDrawIndexedSprite*/
  /* Goal: */
  /* Code: Philippe Vimont / 1.0*/
  /**********************************************************************************************/
  /*typedef struct GEO_tdstIndexedSprite_
  {	ACP_tdxIndex			xCenterPoint;
  ACP_tdxHandleOfSprite	hSprite;
  MTH2D_tdstVector 		stSize;
} GEO_tdstIndexedSprite;*/
 
  void 
    GLI_vDrawIndexedSprite ( GLD_tdstViewportAttributes *p_stVpt ,
    GEO_tdstGeometricObject *p_stObj ,
    GEO_tdstIndexedSprite *p_stISpr ,
    GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT)
  {
    GLI_tdstAligned3DVector stRotatedAxis[5];
    GLI_tdstAligned2DVector a4_st2DVertex  [5];
    GLI_tdstAligned2DVector a2_st2DVertexLocal[3];
    MTH_tdxReal xCos,xSin,xLen;
    ACP_tdxIndex xSpriteNumber;
    MTH3D_tdstVector stYVector;
    POS_tdstCompletePosition stTempMatrix1,stTempMatrix2;
    xSpriteNumber = 0;
    
    if (p_stISpr -> hSprite == NULL) return;    
 
/*	POS_fn_vSetIdentityMatrix(&stTempMatrix1);*/
/*	POS_fn_vSetType(&stTempMatrix1,POS_C_xCompletePosition); // Optimization*/
/*	POS_fn_vSetIdentityMatrix(&stTempMatrix2); // AR971214 not usefull*/
 
    if ((p_stGlobaleMT -> GLI_ScreenPoint + p_stISpr -> xCenterPoint) -> xOoZ < 0.0f) return;
 
    GLI_xSerialLinearOp ( 1, p_stObj->d_stListOfPointsNormals + p_stISpr -> xCenterPoint, stRotatedAxis , &p_stGlobaleMT -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix);
    
    POS_fn_vGetTranslationVector ( p_stGlobaleMT -> gs_st_CurrentMatrix ,(MTH3D_tdstVector *) &stRotatedAxis[1]);
    
    MTH3D_M_vSubVector ( (MTH3D_tdstVector *)&stRotatedAxis[0], (MTH3D_tdstVector *)&stRotatedAxis[0], (MTH3D_tdstVector *)&stRotatedAxis[1]);
    
    
    if (p_stISpr -> hSprite -> xNbSprites > 1)
    {
      xLen = MTH3D_M_xDotProductVector( (MTH3D_tdstVector *)stRotatedAxis , (MTH3D_tdstVector *)(p_stGlobaleMT->GLI_TurnedScaledDisplecedPoint + p_stISpr -> xCenterPoint) );
      xLen = xLen / MTH3D_M_xNormVector ( p_stGlobaleMT->GLI_TurnedScaledDisplecedPoint + p_stISpr -> xCenterPoint);
      for (xSpriteNumber = 0;
      xSpriteNumber < p_stISpr -> hSprite -> xNbSprites - 1;
      xSpriteNumber ++)
      {
        if ( p_stISpr -> hSprite -> d_xThresholds [ xSpriteNumber + 1 ] > xLen ) break;
      }
    } else {
      xSpriteNumber = 0;
    }
    
    if (p_stISpr -> hSprite -> d_xSpriteDrawMode[xSpriteNumber] & GEO_C_lSpriteDrawDisable) return;
    
    
    if (p_stISpr -> hSprite -> d_xSpriteDrawMode[xSpriteNumber] & GEO_C_lSpriteDrawMode2DRotativ)
    {
      xLen = MTH_M_xSqr( stRotatedAxis[0] . xX ) + MTH_M_xSqr( stRotatedAxis[0] . xY ) ;
      if (xLen > 0.1f)
      {
        xSin = stRotatedAxis[0] . xX ;
        if (xSin != xLen)
          xCos = xLen - MTH_M_xSqr( xSin );
        else
          xCos = 0.0f;
        xLen = MTH_M_xInvSqrt( xLen );
        xCos = MTH_M_xSqrt( xCos ) * xLen;
        xSin *= xLen;
        if (stRotatedAxis[0] . xY < 0.0)
          xCos = -xCos ;
      } else{
        xSin = 0.0;
        xCos = 1.0;
      }
    } else
    {
      xSin = 0.0;
      xCos = 1.0;
    }
    
    if (p_stISpr -> hSprite -> d_xSpriteDrawMode[xSpriteNumber] & GEO_C_lSpriteDrawMode2DScaled)
    {
      
      stRotatedAxis[0] . xX =   p_stISpr -> stSize . xX * xCos * p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xX;
      stRotatedAxis[0] . xY =  -p_stISpr -> stSize . xX * xSin * p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xX;
      stRotatedAxis[1] . xX =  -p_stISpr -> stSize . xY * xSin * p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xY;
      stRotatedAxis[1] . xY =  -p_stISpr -> stSize . xY * xCos * p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xY;
      stRotatedAxis[2] . xX =  (-p_stISpr -> hSprite -> d_xDisplacementOfSprite [xSpriteNumber].xX * xCos - p_stISpr -> hSprite -> d_xDisplacementOfSprite [xSpriteNumber].xY * xSin) ;
      stRotatedAxis[2] . xY =  ( p_stISpr -> hSprite -> d_xDisplacementOfSprite [xSpriteNumber].xX * xSin - p_stISpr -> hSprite -> d_xDisplacementOfSprite [xSpriteNumber].xY * xCos) ;
      if (!POS_fn_ulIsNotScaledMatrix ( &p_stGlobaleMT -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix))
      {
        stRotatedAxis[0] . xZ = stRotatedAxis[1] . xZ =  stRotatedAxis[2] . xZ =  0.f;
        stTempMatrix2 =  p_stGlobaleMT -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix;
        POS_fn_vInvertIsoMatrix  ( &stTempMatrix1 , &p_stGlobaleMT -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix) ;
        POS_fn_vResetScaleMatrix ( &stTempMatrix1 ) ;
        stYVector . xX = stYVector . xY = stYVector . xZ = 0.f;
        POS_fn_vSetTranslationVector ( &stTempMatrix1 ,&stYVector);
        POS_fn_vSetTranslationVector ( &stTempMatrix2 ,&stYVector);
        POS_fn_vMulMatrixVertex  ( (MTH3D_tdstVector *) &stRotatedAxis[0] , &stTempMatrix1 , (MTH3D_tdstVector *) &stRotatedAxis[0] ) ;
        POS_fn_vMulMatrixVertex  ( (MTH3D_tdstVector *) &stRotatedAxis[0] , &stTempMatrix2 , (MTH3D_tdstVector *) &stRotatedAxis[0] ) ;
        POS_fn_vMulMatrixVertex  ( (MTH3D_tdstVector *) &stRotatedAxis[1] , &stTempMatrix1 , (MTH3D_tdstVector *) &stRotatedAxis[1] ) ;
        POS_fn_vMulMatrixVertex  ( (MTH3D_tdstVector *) &stRotatedAxis[1] , &stTempMatrix2 , (MTH3D_tdstVector *) &stRotatedAxis[1] ) ;
        POS_fn_vMulMatrixVertex  ( (MTH3D_tdstVector *) &stRotatedAxis[2] , &stTempMatrix1 , (MTH3D_tdstVector *) &stRotatedAxis[2] ) ;
        POS_fn_vMulMatrixVertex  ( (MTH3D_tdstVector *) &stRotatedAxis[2] , &stTempMatrix2 , (MTH3D_tdstVector *) &stRotatedAxis[2] ) ;
      }
      
      /*stRotatedAxis[0] . xX =   p_stISpr -> stSize . xX ;*/
      /*stRotatedAxis[0] . xY =   p_stISpr -> stSize . xY ;*/
      stRotatedAxis[0] . xZ =p_stGlobaleMT->GLI_TurnedScaledDisplecedPoint[p_stISpr -> xCenterPoint].xZ;
      stRotatedAxis[1] . xZ =p_stGlobaleMT->GLI_TurnedScaledDisplecedPoint[p_stISpr -> xCenterPoint].xZ;
      stRotatedAxis[2] . xZ =p_stGlobaleMT->GLI_TurnedScaledDisplecedPoint[p_stISpr -> xCenterPoint].xZ;
      GLI_xSerialProjection ( (( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD)->p_stCam,
        3,
        stRotatedAxis,
        a2_st2DVertexLocal ) ;
      a2_st2DVertexLocal [0] . xX -= (( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD) -> p_stCam -> stTrans . xX ;
      a2_st2DVertexLocal [0] . xY -= (( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD) -> p_stCam -> stTrans . xY ;
      a2_st2DVertexLocal [1] . xX -= (( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD) -> p_stCam -> stTrans . xX ;
      a2_st2DVertexLocal [1] . xY -= (( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD) -> p_stCam -> stTrans . xY ;
      a2_st2DVertexLocal [2] . xX -= (( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD) -> p_stCam -> stTrans . xX ;
      a2_st2DVertexLocal [2] . xY -= (( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD) -> p_stCam -> stTrans . xY ;
      a4_st2DVertex [0] . xX = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX - a2_st2DVertexLocal[0] . xX - a2_st2DVertexLocal[1] . xX + a2_st2DVertexLocal[2] . xX ;
      a4_st2DVertex [0] . xY = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY - a2_st2DVertexLocal[0] . xY - a2_st2DVertexLocal[1] . xY + a2_st2DVertexLocal[2] . xY ;
      a4_st2DVertex [1] . xX = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX + a2_st2DVertexLocal[0] . xX - a2_st2DVertexLocal[1] . xX + a2_st2DVertexLocal[2] . xX ;
      a4_st2DVertex [1] . xY = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY + a2_st2DVertexLocal[0] . xY - a2_st2DVertexLocal[1] . xY + a2_st2DVertexLocal[2] . xY ;
      a4_st2DVertex [2] . xX = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX + a2_st2DVertexLocal[0] . xX + a2_st2DVertexLocal[1] . xX + a2_st2DVertexLocal[2] . xX ;
      a4_st2DVertex [2] . xY = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY + a2_st2DVertexLocal[0] . xY + a2_st2DVertexLocal[1] . xY + a2_st2DVertexLocal[2] . xY ;
      a4_st2DVertex [3] . xX = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX - a2_st2DVertexLocal[0] . xX + a2_st2DVertexLocal[1] . xX + a2_st2DVertexLocal[2] . xX ;
      a4_st2DVertex [3] . xY = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY - a2_st2DVertexLocal[0] . xY + a2_st2DVertexLocal[1] . xY + a2_st2DVertexLocal[2] . xY ;
    }
    else 
    {
      stRotatedAxis[0] . xX =   p_stISpr -> stSize . xX * xCos * p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xX;
      stRotatedAxis[0] . xY =  -p_stISpr -> stSize . xX * xSin * p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xX;
      stRotatedAxis[1] . xX =  -p_stISpr -> stSize . xY * xSin * p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xY;
      stRotatedAxis[1] . xY =  -p_stISpr -> stSize . xY * xCos * p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xY;
      stRotatedAxis[2] . xX =  ( p_stISpr -> hSprite -> d_xDisplacementOfSprite [xSpriteNumber].xX * xCos + p_stISpr -> hSprite -> d_xDisplacementOfSprite [xSpriteNumber].xY * xSin) ;
      stRotatedAxis[2] . xY =  (-p_stISpr -> hSprite -> d_xDisplacementOfSprite [xSpriteNumber].xX * xSin + p_stISpr -> hSprite -> d_xDisplacementOfSprite [xSpriteNumber].xY * xCos) ;
      if (!POS_fn_ulIsNotScaledMatrix ( &p_stGlobaleMT -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix))
      {
        stRotatedAxis[0] . xZ = stRotatedAxis[1] . xZ =  stRotatedAxis[2] . xZ =  0.f;
        stTempMatrix2 =  p_stGlobaleMT -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix;
        POS_fn_vInvertIsoMatrix  ( &stTempMatrix1 , &p_stGlobaleMT -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix) ;
        POS_fn_vResetScaleMatrix ( &stTempMatrix1 ) ;
        stYVector . xX = stYVector . xY = stYVector . xZ = 0.f;
        POS_fn_vSetTranslationVector ( &stTempMatrix1 ,&stYVector);
        POS_fn_vSetTranslationVector ( &stTempMatrix2 ,&stYVector);
        POS_fn_vMulMatrixVertex  ( (MTH3D_tdstVector *) &stRotatedAxis[0] , &stTempMatrix1 , (MTH3D_tdstVector *) &stRotatedAxis[0] ) ;
        POS_fn_vMulMatrixVertex  ( (MTH3D_tdstVector *) &stRotatedAxis[0] , &stTempMatrix2 , (MTH3D_tdstVector *) &stRotatedAxis[0] ) ;
        POS_fn_vMulMatrixVertex  ( (MTH3D_tdstVector *) &stRotatedAxis[1] , &stTempMatrix1 , (MTH3D_tdstVector *) &stRotatedAxis[1] ) ;
        POS_fn_vMulMatrixVertex  ( (MTH3D_tdstVector *) &stRotatedAxis[1] , &stTempMatrix2 , (MTH3D_tdstVector *) &stRotatedAxis[1] ) ;
        POS_fn_vMulMatrixVertex  ( (MTH3D_tdstVector *) &stRotatedAxis[2] , &stTempMatrix1 , (MTH3D_tdstVector *) &stRotatedAxis[2] ) ;
        POS_fn_vMulMatrixVertex  ( (MTH3D_tdstVector *) &stRotatedAxis[2] , &stTempMatrix2 , (MTH3D_tdstVector *) &stRotatedAxis[2] ) ;
      }
      
      a4_st2DVertex [0] . xX = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX + stRotatedAxis[0] . xX + stRotatedAxis[1] . xX + stRotatedAxis[2] . xX );
      a4_st2DVertex [0] . xY = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY + stRotatedAxis[0] . xY + stRotatedAxis[1] . xY + stRotatedAxis[2] . xY );
      a4_st2DVertex [1] . xX = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX - stRotatedAxis[0] . xX + stRotatedAxis[1] . xX + stRotatedAxis[2] . xX );
      a4_st2DVertex [1] . xY = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY - stRotatedAxis[0] . xY + stRotatedAxis[1] . xY + stRotatedAxis[2] . xY );
      a4_st2DVertex [2] . xX = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX - stRotatedAxis[0] . xX - stRotatedAxis[1] . xX + stRotatedAxis[2] . xX );
      a4_st2DVertex [2] . xY = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY - stRotatedAxis[0] . xY - stRotatedAxis[1] . xY + stRotatedAxis[2] . xY );
      a4_st2DVertex [3] . xX = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX + stRotatedAxis[0] . xX - stRotatedAxis[1] . xX + stRotatedAxis[2] . xX );
      a4_st2DVertex [3] . xY = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY + stRotatedAxis[0] . xY - stRotatedAxis[1] . xY + stRotatedAxis[2] . xY );
    }
    
    p_stGlobaleMT -> hCurrentMaterial = GMT_fn_hGetVisualMaterial(p_stISpr -> hSprite -> d_hMaterial[xSpriteNumber]);
    {
        unsigned long xSaveDrawMsk;
        xSaveDrawMsk = p_stGlobaleMT -> lHierachDrawMask ;
        p_stGlobaleMT -> lHierachDrawMask &= ~GLI_C_lIsTestingBackface;
        GLI_vDoMaterialSelection(p_stGlobaleMT);
 
        GLI_DRV_vSendSpriteToClip( a4_st2DVertex , p_stGlobaleMT->GLI_ScreenPoint [p_stISpr -> xCenterPoint].xOoZ, p_stGlobaleMT);
        p_stGlobaleMT -> lHierachDrawMask = xSaveDrawMsk;
    }
}
 
#endif /* USE_NEW_SPRITE*/
 
/**********************************************************************************************/
/* Name: GLI_vPickIndexedSprite*/
/* Goal: return's !0 if p_stScreenCoord is in the sprite.*/
/* Code: Philippe Vimont / 1.0*/
/**********************************************************************************************/
#define GLI_M_bIsOnTheLeft(a,b) ( (a4_st2DVertex[b].xY - a4_st2DVertex[a].xY) * (p_stScreenCoord->xX - a4_st2DVertex[a].xX) > (a4_st2DVertex[b].xX - a4_st2DVertex[a].xX) * (p_stScreenCoord->xY - a4_st2DVertex[a].xY) )
 
long GLI_vPickIndexedSprite 
    ( 
        GLD_tdstViewportAttributes *p_stVpt ,
        GEO_tdstGeometricObject *p_stObj ,
        GEO_tdstIndexedSprite *p_stISpr , 
        MTH2D_tdstVector *p_stScreenCoord,
        GLI_tdstInternalGlobalValuesFor3dEngine *p_stGlobaleMT
    )
{
#ifdef _DEBUG
    ACP_tdxHandleOfMaterial hVisualMat;
    GLI_tdstAligned3DVector stScaledPt[3];
    GLI_tdstAligned2DVector a4_st2DVertex  [4];
    GLI_tdstAligned2DVector a2_st2DVertexLocal[3];
    ACP_tdxIndex xSpriteNumber;
 
 
	MTH_tdxReal xTempZ; /* make this a MTH_XXX something or another*/
	xSpriteNumber = 0;
    
	if ((p_stISpr -> hSprite == NULL) || ((p_stGlobaleMT -> GLI_ScreenPoint + p_stISpr -> xCenterPoint) -> xOoZ < 0.0f) || (p_stISpr -> hSprite -> d_xSpriteDrawMode[xSpriteNumber] & GEO_C_lSpriteDrawDisable))
		return 0;
 
	assert (p_stISpr -> hSprite -> xNbSprites == 1);
	assert (!(p_stISpr -> hSprite -> d_xSpriteDrawMode[xSpriteNumber] & GEO_C_lSpriteDrawMode2DRotativ));
    assert (p_stISpr -> stSize.xX == 1.0);
    assert (p_stISpr -> stSize.xY == 1.0);
 
	stScaledPt[0].xX = p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xX;
	stScaledPt[0].xY = 0.0;
	stScaledPt[1].xX = 0.0;
	stScaledPt[1].xY = -p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xY;
	stScaledPt[2].xX = 0.0;
	stScaledPt[2].xY = 0.0;
 
	if (!POS_fn_ulIsNotScaledMatrix ( &p_stGlobaleMT -> gs_st_CurrentMatrixMultiplyedWithCameraMatrix))
	{
		MTH_tdxReal xScaleX;
		MTH_tdxReal xScaleY;
		xScaleX = POS_fn_xGetXScale(&(p_stGlobaleMT->gs_st_CurrentMatrixMultiplyedWithCameraMatrix));
		xScaleY = POS_fn_xGetYScale(&(p_stGlobaleMT->gs_st_CurrentMatrixMultiplyedWithCameraMatrix));
 
		stScaledPt[0].xX = xScaleX * p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xX;
		stScaledPt[1].xY = xScaleY * (-p_stISpr -> hSprite -> d_xSizeOfSprite[xSpriteNumber].xY);
	}
 
	xTempZ = p_stGlobaleMT->GLI_TurnedScaledDisplecedPoint[p_stISpr->xCenterPoint].xZ;
 
	stScaledPt[0].xZ = xTempZ;
	stScaledPt[1].xZ = xTempZ;
	stScaledPt[2].xZ = xTempZ;
 
	if (p_stISpr -> hSprite -> d_xSpriteDrawMode[xSpriteNumber] & GEO_C_lSpriteDrawMode2DScaled) {
 
		GLI_xSerialProjectionNoTrans ( (( GLI_tdstSpecificAttributesFor3D *)p_stVpt->p_vSpecificToXD)->p_stCam,
										3, stScaledPt, a2_st2DVertexLocal);
		a4_st2DVertex [0] . xX = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX - a2_st2DVertexLocal[0] . xX - a2_st2DVertexLocal[1] . xX + a2_st2DVertexLocal[2] . xX ;
		a4_st2DVertex [0] . xY = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY - a2_st2DVertexLocal[0] . xY - a2_st2DVertexLocal[1] . xY + a2_st2DVertexLocal[2] . xY ;
		a4_st2DVertex [1] . xX = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX + a2_st2DVertexLocal[0] . xX - a2_st2DVertexLocal[1] . xX + a2_st2DVertexLocal[2] . xX ;
		a4_st2DVertex [1] . xY = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY + a2_st2DVertexLocal[0] . xY - a2_st2DVertexLocal[1] . xY + a2_st2DVertexLocal[2] . xY ;
		a4_st2DVertex [2] . xX = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX + a2_st2DVertexLocal[0] . xX + a2_st2DVertexLocal[1] . xX + a2_st2DVertexLocal[2] . xX ;
		a4_st2DVertex [2] . xY = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY + a2_st2DVertexLocal[0] . xY + a2_st2DVertexLocal[1] . xY + a2_st2DVertexLocal[2] . xY ;
		a4_st2DVertex [3] . xX = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX - a2_st2DVertexLocal[0] . xX + a2_st2DVertexLocal[1] . xX + a2_st2DVertexLocal[2] . xX ;
		a4_st2DVertex [3] . xY = p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY - a2_st2DVertexLocal[0] . xY + a2_st2DVertexLocal[1] . xY + a2_st2DVertexLocal[2] . xY ;
	}
	else {
		a4_st2DVertex [0] . xX = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX + stScaledPt[0] . xX + stScaledPt[1] . xX);
		a4_st2DVertex [0] . xY = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY + stScaledPt[0] . xY + stScaledPt[1] . xY);
		a4_st2DVertex [1] . xX = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX - stScaledPt[0] . xX + stScaledPt[1] . xX);
		a4_st2DVertex [1] . xY = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY - stScaledPt[0] . xY + stScaledPt[1] . xY);
		a4_st2DVertex [2] . xX = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX - stScaledPt[0] . xX - stScaledPt[1] . xX);
		a4_st2DVertex [2] . xY = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY - stScaledPt[0] . xY - stScaledPt[1] . xY);
		a4_st2DVertex [3] . xX = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xX + stScaledPt[0] . xX - stScaledPt[1] . xX);
		a4_st2DVertex [3] . xY = (float)(p_stGlobaleMT->GLI_ScreenPoint  [p_stISpr -> xCenterPoint] . xY + stScaledPt[0] . xY - stScaledPt[1] . xY);
	}
    
    hVisualMat=GMT_fn_hGetVisualMaterial(p_stISpr -> hSprite -> d_hMaterial[xSpriteNumber]);
    if (GLI_M_bIsOnTheLeft(0,1))
        if (GLI_M_bIsOnTheLeft(1,2))
            if (GLI_M_bIsOnTheLeft(2,3))
                if (GLI_M_bIsOnTheLeft(3,0))
                    return ( 1 );
  
#endif
    return(0);
}
 
#ifdef __cplusplus
} /*extern "C"*/
#endif
