/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include "GLD.h"
#include "GEO.h"
#include "TEX.h"
#include "gli_st.h"
#include "textu_st.h"
#include "texture.h"
#include "ErrGli.h"
#include "DLLCaps.h"
#include <string.h>
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include "d3d.h"
#include "ddraw.h"
#include "TextuD3D.h"
#include "MacroD3D.h"
#include "DLLCom.h"
#include "DX6_Caps.h"
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
/*
 =======================================================================================
    externals globals 
 =======================================================================================
 */
extern LPDIRECT3DDEVICE3		g_pd3dDevice;
extern LPDIRECTDRAW4			g_pDD4;
extern LPDIRECTDRAWSURFACE4	    g_pddsPrimary;
 
extern long                     g_lFullScreenBpp;
 
/*
 =======================================================================================
    globals 
 =======================================================================================
 */
static long                     gs_lRestore = 0;
 
static LPDIRECTDRAWSURFACE4     g_p_stDDS4Temp  = NULL;
static LPDIRECTDRAWSURFACE4     g_p_stDDS4New   = NULL;
static LPDIRECT3DTEXTURE2       g_p_stD3DT2Temp = NULL;
static LPDIRECT3DTEXTURE2       g_p_stD3DT2New  = NULL;
 
/*
 =======================================================================================
    functions
 =======================================================================================
 */
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : get video memory size taken by a given texture
 ----------------------------------------------------------------------------------------
 */
long GLI_DRV_lGetSizeOfTexture( GLI_tdstTexture *_p_stTexture )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    char    cPixelFormat;
    char    cMipmap;
    long    lSize;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    if ( g_lFullScreenBpp == 32)
    {
        if ( _p_stTexture->lTextureCaps & GLI_C_lPaletteTexture )
		    cPixelFormat = GLI_DX6_TexFormatPalette8;
        else if ( _p_stTexture->lTextureCaps & (GLI_C_lAlphaTexture | GLI_C_lAlphaTest | GLI_C_lNZFilteredTexture) )
            cPixelFormat = GLI_DX6_TexFormat8888;
        else 
            cPixelFormat = GLI_DX6_TexFormat888;
    }
    else if ( g_lFullScreenBpp == 16)
    {
  	    if ( _p_stTexture->lTextureCaps & GLI_C_lPaletteTexture )
		    cPixelFormat = GLI_DX6_TexFormatPalette8;
        else if ( _p_stTexture->lTextureCaps & GLI_C_lAlphaTexture)
            cPixelFormat = GLI_DX6_TexFormat4444;
        else if ( _p_stTexture->lTextureCaps & (GLI_C_lAlphaTest | GLI_C_lNZFilteredTexture) )
            cPixelFormat = GLI_DX6_TexFormat1555;
        else
            cPixelFormat = GLI_DX6_TexFormat565;
    }
    else 
        cPixelFormat = GLI_DX6_TexFormat565;
 
 
    cMipmap = (char) ((_p_stTexture->lNumberOfLod) ? 1 : 0);
 
    lSize = GLI_DX6_fn_lGetPrecalculatedTextureSize( cPixelFormat, cMipmap, _p_stTexture->lWidth, _p_stTexture->lHeight );
    
    GLI_MDRV_TEXBENCH_vSetTextureSize( _p_stTexture, TEXBENCH_C_cComputedSize, lSize );
 
    return lSize;
}
 
 
/*
 =======================================================================================
    General functions 
 =======================================================================================
 */
 
typedef struct tdstD3DErrorDesc_
{
    HRESULT hErrorValue;
    char    *szText;
} tdstD3DErrorDesc;
 
#define C_cNumberOfD3DErrorDesc 65
 
tdstD3DErrorDesc g_a_stD3DError[C_cNumberOfD3DErrorDesc] = 
    {
        { DDERR_SURFACELOST,                "DDERR_SURFACELOST"},                   { DDERR_SURFACEBUSY,                "DDERR_SURFACEBUSY"},
        { DDERR_INCOMPATIBLEPRIMARY,        "DDERR_INCOMPATIBLEPRIMARY"},           { DDERR_INVALIDCAPS,                "DDERR_INVALIDCAPS"},
        { DDERR_INVALIDOBJECT,              "DDERR_INVALIDOBJECT"},                 { DDERR_INVALIDPARAMS,              "DDERR_INVALIDPARAMS"},
        { DDERR_INVALIDPIXELFORMAT,         "DDERR_INVALIDPIXELFORMAT"},            { DDERR_NOALPHAHW,                  "DDERR_NOALPHAHW"},
        { DDERR_NOCOOPERATIVELEVELSET,      "DDERR_NOCOOPERATIVELEVELSET"},         { DDERR_NODIRECTDRAWHW,             "DDERR_NODIRECTDRAWHW"},
        { DDERR_NOEMULATION,                "DDERR_NOEMULATION"},                   { DDERR_NOEXCLUSIVEMODE,            "DDERR_NOEXCLUSIVEMODE"},
        { DDERR_NOFLIPHW,                   "DDERR_NOFLIPHW"},                      { DDERR_NOMIPMAPHW,                 "DDERR_NOMIPMAPHW"},
        { DDERR_NOOVERLAYHW,                "DDERR_NOOVERLAYHW"},                   { DDERR_NOZBUFFERHW,                "DDERR_NOZBUFFERHW"},
        { DDERR_OUTOFMEMORY,                "DDERR_OUTOFMEMORY"},                   { DDERR_OUTOFVIDEOMEMORY,           "DDERR_OUTOFVIDEOMEMORY"},
        { DDERR_PRIMARYSURFACEALREADYEXISTS,"DDERR_PRIMARYSURFACEALREADYEXISTS"},   { DDERR_UNSUPPORTEDMODE,            "DDERR_UNSUPPORTEDMODE"},
        { D3DERR_BADMAJORVERSION,           "D3DERR_BADMAJORVERSION"},              { D3DERR_BADMINORVERSION,           "D3DERR_BADMINORVERSION"},
        { D3DERR_EXECUTE_CLIPPED_FAILED,    "D3DERR_EXECUTE_CLIPPED_FAILED"},       { D3DERR_EXECUTE_CREATE_FAILED,     "D3DERR_EXECUTE_CREATE_FAILED"},
        { D3DERR_EXECUTE_DESTROY_FAILED,    "D3DERR_EXECUTE_DESTROY_FAILED"},       { D3DERR_EXECUTE_FAILED,            "D3DERR_EXECUTE_FAILED"},
        { D3DERR_EXECUTE_LOCK_FAILED,       "D3DERR_EXECUTE_LOCK_FAILED"},          { D3DERR_EXECUTE_LOCKED,            "D3DERR_EXECUTE_LOCKED"},
        { D3DERR_EXECUTE_NOT_LOCKED,        "D3DERR_EXECUTE_NOT_LOCKED"},           { D3DERR_EXECUTE_UNLOCK_FAILED,     "D3DERR_EXECUTE_UNLOCK_FAILED"},
        { D3DERR_INBEGIN,                   "D3DERR_INBEGIN"},                      { D3DERR_INVALID_DEVICE,            "D3DERR_INVALID_DEVICE"},
        { D3DERR_INVALIDCURRENTVIEWPORT,    "D3DERR_INVALIDCURRENTVIEWPORT"},       { D3DERR_INVALIDPRIMITIVETYPE,      "D3DERR_INVALIDPRIMITIVETYPE"},
        { D3DERR_INVALIDVERTEXTYPE,         "D3DERR_INVALIDVERTEXTYPE"},            { D3DERR_LIGHT_SET_FAILED,          "D3DERR_LIGHT_SET_FAILED"},
        { D3DERR_MATERIAL_CREATE_FAILED,    "D3DERR_MATERIAL_CREATE_FAILED"},       { D3DERR_MATERIAL_DESTROY_FAILED,   "D3DERR_MATERIAL_DESTROY_FAILED"},
        { D3DERR_MATERIAL_GETDATA_FAILED,   "D3DERR_MATERIAL_GETDATA_FAILED"},      { D3DERR_MATERIAL_SETDATA_FAILED,   "D3DERR_MATERIAL_SETDATA_FAILED"},
        { D3DERR_MATRIX_CREATE_FAILED,      "D3DERR_MATRIX_CREATE_FAILED"},         { D3DERR_MATRIX_DESTROY_FAILED,     "D3DERR_MATRIX_DESTROY_FAILED"},
        { D3DERR_MATRIX_GETDATA_FAILED,     "D3DERR_MATRIX_GETDATA_FAILED"},        { D3DERR_MATRIX_SETDATA_FAILED,     "D3DERR_MATRIX_SETDATA_FAILED"},
        { D3DERR_NOTINBEGIN,                "D3DERR_NOTINBEGIN"},                   { D3DERR_NOVIEWPORTS,               "D3DERR_NOVIEWPORTS"},
        { D3DERR_SCENE_BEGIN_FAILED,        "D3DERR_SCENE_BEGIN_FAILED"},           { D3DERR_SCENE_END_FAILED,          "D3DERR_SCENE_END_FAILED"},
        { D3DERR_SCENE_IN_SCENE,            "D3DERR_SCENE_IN_SCENE"},               { D3DERR_SCENE_NOT_IN_SCENE,        "D3DERR_SCENE_NOT_IN_SCENE"},
        { D3DERR_SETVIEWPORTDATA_FAILED,    "D3DERR_SETVIEWPORTDATA_FAILED"},       { D3DERR_TEXTURE_BADSIZE ,          "D3DERR_TEXTURE_BADSIZE"},
        { D3DERR_TEXTURE_CREATE_FAILED,     "D3DERR_TEXTURE_CREATE_FAILED"},        { D3DERR_TEXTURE_DESTROY_FAILED,    "D3DERR_TEXTURE_DESTROY_FAILED"},
        { D3DERR_TEXTURE_GETSURF_FAILED,    "D3DERR_TEXTURE_GETSURF_FAILED"},       { D3DERR_TEXTURE_LOAD_FAILED,       "D3DERR_TEXTURE_LOAD_FAILED"},
        { D3DERR_TEXTURE_LOCK_FAILED,       "D3DERR_TEXTURE_LOCK_FAILED"},          { D3DERR_TEXTURE_LOCKED,            "D3DERR_TEXTURE_LOCKED"},
        { D3DERR_TEXTURE_NO_SUPPORT,        "D3DERR_TEXTURE_NO_SUPPORT"},           { D3DERR_TEXTURE_NOT_LOCKED,        "D3DERR_TEXTURE_NOT_LOCKED"},
        { D3DERR_TEXTURE_SWAP_FAILED,       "D3DERR_TEXTURE_SWAP_FAILED"},          { D3DERR_TEXTURE_UNLOCK_FAILED,     "D3DERR_TEXTURE_UNLOCK_FAILED"},
        { D3DERR_VIEWPORTDATANOTSET,        "D3DERR_VIEWPORTDATANOTSET"},           { D3DERR_ZBUFF_NEEDS_SYSTEMMEMORY,  "D3DERR_ZBUFF_NEEDS_SYSTEMMEMORY"},
        { D3DERR_ZBUFF_NEEDS_VIDEOMEMORY,   "D3DERR_ZBUFF_NEEDS_VIDEOMEMORY"},
    };
 
/*
 ----------------------------------------------------------------------------------------
  Description   : return text that correspond to D3D error
 ----------------------------------------------------------------------------------------
 */
void vGetD3DError(HRESULT ddres,char *result)
{
    tdstD3DErrorDesc *p_stErrorDesc = g_a_stD3DError;
    tdstD3DErrorDesc *p_stLastErrorDesc = p_stErrorDesc + C_cNumberOfD3DErrorDesc;
 
    for ( ; p_stErrorDesc < p_stLastErrorDesc; p_stErrorDesc++ )
    {
        if ( p_stErrorDesc->hErrorValue == ddres )
        {
            strcpy( result, p_stErrorDesc->szText );
            return;    
        }
    }
    /* not a registered error*/
    strcpy(result, "DDERR : default");
}
 
/*
 =======================================================================================
    compute functions
 =======================================================================================
 */
 
/*
 ----------------------------------------------------------------------------------------
  Description   : 
 ----------------------------------------------------------------------------------------
 */
static void fn_vGetScaleAndShiftFromMask(unsigned long ulMask, long *p_lShift, long *p_lScale)
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    unsigned long ulTemp;
    long lNbBits;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    ulTemp = ulMask;
    *p_lShift = *p_lScale = lNbBits = 0;
 
    while( (lNbBits != 32) && ((ulTemp&0x1) == 0) )
    {
        ulTemp >>= 1;
        (*p_lShift)++;
        lNbBits++;
    }
 
    while( (lNbBits != 32) && ((ulTemp&0x1) == 1) )
    {
        ulTemp >>= 1;
        (*p_lScale)++;
        lNbBits++;
    }
 
    *p_lScale = 8 - (*p_lScale);
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : copy a bitmap to a D3D surface
 ----------------------------------------------------------------------------------------
 */
/* Begin G.CLEMENT 28/07/1999 : added 'GLI_tdstTexture *p_stTexture' parameter for NZ special cases */
BOOL GLI_D3D_bCopyBitmapToSurface(char *hBitmap, LPDIRECTDRAWSURFACE4 p_stDDSurface, GLI_tdstTexture *p_stTexture)
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    long            lShiftRed, lScaleRed, lShiftGreen, lScaleGreen, lShiftBlue, lScaleBlue, lShiftAlpha, lScaleAlpha ;
    unsigned long   ulMaskRed, ulMaskGreen, ulMaskBlue, ulMaskAlpha;
    DDSURFACEDESC2  ddsd;
    HRESULT         ddres;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    memset(&ddsd,0,sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    do 
    {
        ddres = p_stDDSurface->lpVtbl->Lock( p_stDDSurface, NULL, &ddsd, 0, NULL);
    } while (ddres==DDERR_WASSTILLDRAWING);
  
    /*get the pixel format*/
	if (ddsd.ddpfPixelFormat.dwRGBBitCount == 8)
	{
		memcpy( ddsd.lpSurface, hBitmap, ddsd.dwWidth * ddsd.dwHeight );
	}
	else
	{
		ulMaskRed   = ddsd.ddpfPixelFormat.dwRBitMask;
		ulMaskGreen = ddsd.ddpfPixelFormat.dwGBitMask;
		ulMaskBlue  = ddsd.ddpfPixelFormat.dwBBitMask;
		ulMaskAlpha = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask;
  
		fn_vGetScaleAndShiftFromMask(ulMaskRed, &lShiftRed, &lScaleRed);
		fn_vGetScaleAndShiftFromMask(ulMaskGreen, &lShiftGreen, &lScaleGreen);
		fn_vGetScaleAndShiftFromMask(ulMaskBlue, &lShiftBlue, &lScaleBlue);
		fn_vGetScaleAndShiftFromMask(ulMaskAlpha, &lShiftAlpha, &lScaleAlpha);
 
		/*Translate load texture in the temporary texture*/
		switch (ddsd.ddpfPixelFormat.dwRGBBitCount)
		{
			case 16:
			{
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
                long            lHCounter,lWCounter;
                char            *p_cSource;
                unsigned short  *p_uwDest, *p_uwDestLocal;
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
      
                p_cSource=(char*)hBitmap;
                p_uwDestLocal = p_uwDest=(unsigned short *)ddsd.lpSurface;
      
				/* Here is the special NZ case */
				if ((p_stTexture!=NULL) && (p_stTexture->lTextureCaps & GLI_C_lNZTexture)) {
					/* It's mostly the same as non-NZ but we have to check that we don't add false chromakeyed pixels */
					/* For this we need : */
					char *p_cOriginalKey ; /* points to the original Chroma Key color, needed for comparison */
					unsigned short usConvertedKey; /* The corresponding 16-bit value, so as not to recalculate it endlessly */

					p_cOriginalKey = (char *) &(p_stTexture->lChromakeyColorRGBA);
					/* Yes, we could get it with GetColorKey instead of recompute it...
					   But that way we don't depend on wether SetColoKey was called before */
					usConvertedKey = (unsigned short)((((p_cOriginalKey[0]>>lScaleRed)  <<lShiftRed)   & ulMaskRed)
													|(((p_cOriginalKey[1]>>lScaleGreen)<<lShiftGreen) & ulMaskGreen)
													|(((p_cOriginalKey[2]>>lScaleBlue) <<lShiftBlue)  & ulMaskBlue));
					/* Note : no need for the alpha field in the chromakey */

					for (lHCounter=0;lHCounter<(long)ddsd.dwHeight;lHCounter++,(unsigned char *)p_uwDestLocal += ddsd.lPitch )
						for (lWCounter=0,p_uwDest = p_uwDestLocal;lWCounter<(long)ddsd.dwWidth;lWCounter++) 
						{
							*p_uwDest = (unsigned short)((((p_cSource[0]>>lScaleRed)  <<lShiftRed)  &ulMaskRed)
										|(((p_cSource[1]>>lScaleGreen)<<lShiftGreen)&ulMaskGreen)
										|(((p_cSource[2]>>lScaleBlue) <<lShiftBlue) &ulMaskBlue)
										|(((p_cSource[3]>>lScaleAlpha)<<lShiftAlpha)&ulMaskAlpha));

							if ( ((*p_uwDest & ~ulMaskAlpha) == usConvertedKey) /* converted RGB values match */ &&
								 ( (((*(unsigned long *)p_cSource) ^ (*(unsigned long *)p_cOriginalKey)) & 0x00ffffff) )) /* but original don't */ /* 0x00f8f8f8 */
							{
								/* We slightly change the converted value */
								/* by inverting the least significant green bit */
								*p_uwDest ^= ((unsigned short)1) << lShiftGreen;
								/* Why the green bit ? Because in 565 it shows the least, and otherwise, why not ! */
							} else if ((*p_uwDest & ~ulMaskAlpha) == usConvertedKey) {
								*p_uwDest &= ~ulMaskAlpha;
							}
							p_uwDest++;
							p_cSource+=4;
						}
				} else {
					for (lHCounter=0;lHCounter<(long)ddsd.dwHeight;lHCounter++,(unsigned char *)p_uwDestLocal += ddsd.lPitch )
						for (lWCounter=0,p_uwDest = p_uwDestLocal;lWCounter<(long)ddsd.dwWidth;lWCounter++) 
						{
							*p_uwDest = (unsigned short)((((p_cSource[0]>>lScaleRed)  <<lShiftRed)  &ulMaskRed)
										|(((p_cSource[1]>>lScaleGreen)<<lShiftGreen)&ulMaskGreen)
										|(((p_cSource[2]>>lScaleBlue) <<lShiftBlue) &ulMaskBlue)
										|(((p_cSource[3]>>lScaleAlpha)<<lShiftAlpha)&ulMaskAlpha));
 
							p_uwDest++;
							p_cSource+=4;
						}
				}
            }
            break;
        
			case 24:
            {
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
                long            lHCounter,lWCounter;
                char            *p_cSource;
                unsigned long   *p_ulDest , *p_ulDestLocal;
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
      
                p_cSource=(char*)hBitmap;
                p_ulDestLocal = p_ulDest=(unsigned long *)ddsd.lpSurface;
      
                for (lHCounter=0;lHCounter<(long)ddsd.dwHeight;lHCounter++, (unsigned char *)p_ulDestLocal += ddsd.lPitch )
                    for (lWCounter=0 , p_ulDest = p_ulDestLocal ;lWCounter<(long)ddsd.dwWidth;lWCounter++) 
                    {
                        *p_ulDest = (unsigned long)((((p_cSource[0]>>lScaleRed)  <<lShiftRed)  &ulMaskRed)
                                    |(((p_cSource[1]>>lScaleGreen)<<lShiftGreen)&ulMaskGreen)
                                    |(((p_cSource[2]>>lScaleBlue) <<lShiftBlue) &ulMaskBlue));
                        p_ulDest = (unsigned long*)((unsigned char*)p_ulDest + 3);
                        p_cSource+=4;
                    }
            }
            break;
        
			case 32:
            {
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
                long            lHCounter,lWCounter;
                char            *p_cSource;
                unsigned long   *p_ulDest, *p_ulDestLocal ;
                /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
      
                p_cSource=(char*)hBitmap;
                p_ulDest = p_ulDestLocal =(unsigned long *)ddsd.lpSurface;
      
                for (lHCounter=0;lHCounter<(long)ddsd.dwHeight;lHCounter++ , (unsigned char *)p_ulDestLocal += ddsd.lPitch )
                    for (lWCounter=0 , p_ulDest = p_ulDestLocal ;lWCounter<(long)ddsd.dwWidth;lWCounter++) 
                    {
                        *p_ulDest = (unsigned long)((((p_cSource[0]>>lScaleRed)  <<lShiftRed)  &ulMaskRed)
                                    |(((p_cSource[1]>>lScaleGreen)<<lShiftGreen)&ulMaskGreen)
                                    |(((p_cSource[2]>>lScaleBlue) <<lShiftBlue) &ulMaskBlue)
                                    |(((p_cSource[3]>>lScaleAlpha)<<lShiftAlpha)&ulMaskAlpha));
          
                        p_ulDest++;
                        p_cSource+=4;
                    }
            }
            break;
		}/*end switch*/  
	}
	
	ddres = p_stDDSurface->lpVtbl->Unlock(p_stDDSurface, ddsd.lpSurface);
    return (ddres == DD_OK);
}
/* End G.CLEMENT 28/07/1999 */
 
 
/*
 =======================================================================================
    D3D texture format
 =======================================================================================
 */
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : get good pixel format for given texture caps
 ----------------------------------------------------------------------------------------
 */
void GLI_fn_vGetPixelFormat( long _lTexCaps, DDPIXELFORMAT *_p_stPixelFormat )
{
    if ( g_lFullScreenBpp == 32)
    {
        if ( _lTexCaps & GLI_C_lPaletteTexture )
            GLI_DX6_fn_vGetPixelFormat( GLI_DX6_TexFormatPalette8, _p_stPixelFormat );
        else if ( _lTexCaps & (GLI_C_lAlphaTexture | GLI_C_lAlphaTest | GLI_C_lNZFilteredTexture) )
            GLI_DX6_fn_vGetPixelFormat( GLI_DX6_TexFormat8888, _p_stPixelFormat );
        else 
            GLI_DX6_fn_vGetPixelFormat( GLI_DX6_TexFormat888, _p_stPixelFormat );
    }
    else if ( g_lFullScreenBpp == 16)
    {
  		if (_lTexCaps & GLI_C_lPaletteTexture )
	    	GLI_DX6_fn_vGetPixelFormat( GLI_DX6_TexFormatPalette8, _p_stPixelFormat );
        else if(_lTexCaps & GLI_C_lAlphaTexture)
            GLI_DX6_fn_vGetPixelFormat( GLI_DX6_TexFormat4444, _p_stPixelFormat );
        else if (_lTexCaps & (GLI_C_lAlphaTest | GLI_C_lNZFilteredTexture) )
            GLI_DX6_fn_vGetPixelFormat( GLI_DX6_TexFormat1555, _p_stPixelFormat );
        else
            GLI_DX6_fn_vGetPixelFormat( GLI_DX6_TexFormat565, _p_stPixelFormat );
    }
}
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : get memory for creating a texture 
                    ( depend on use of AGP, size of texture, memory left )
 ----------------------------------------------------------------------------------------
 */
unsigned long GLI_fn_ulGetMemoryFlag( GLI_tdstTexture *_p_stTexture, long _lTextureMode, BOOL _bUseAgp )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    unsigned long           ulLeftMem, ulTotalMem;
    unsigned long           ulTextureSize;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /*ulTextureSize = (unsigned long) GLI_D3D_lGetSizeOfTexture( _p_stTexture );*/
    ulTextureSize = GLI_DRV_lGetSizeOfTexture( _p_stTexture );
 
    if ( ( _lTextureMode == TEX_C_VRAM ) || ( _lTextureMode == TEX_C_VRAMAGP ) || ( _lTextureMode == TEX_C_VRAM4 ) || ( _lTextureMode == TEX_C_VRAM8 ) )
    {
        /* memoire video*/
        GLI_DX6_hGetVideoMemory( g_pDD4, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP, &ulTotalMem, &ulLeftMem );
        if (ulLeftMem > ulTextureSize + 5 * 1024) /* 5*1024 cache texture*/
            return (DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY);
        /* memoire AGP*/
        GLI_DX6_hGetVideoMemory( g_pDD4, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_MIPMAP, &ulTotalMem, &ulLeftMem );
        if( _bUseAgp && (ulLeftMem > ulTextureSize ))
            return (DDSCAPS_NONLOCALVIDMEM | DDSCAPS_VIDEOMEMORY);
    }
    else
    {
        /* memoire AGP*/
        GLI_DX6_hGetVideoMemory( g_pDD4, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_MIPMAP, &ulTotalMem, &ulLeftMem );
        if( _bUseAgp && (ulLeftMem > ulTextureSize ) )
            return (DDSCAPS_NONLOCALVIDMEM | DDSCAPS_VIDEOMEMORY);
        /* memoire video*/
        GLI_DX6_hGetVideoMemory( g_pDD4, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP, &ulTotalMem, &ulLeftMem );
        if (ulLeftMem > ulTextureSize + 5 * 1024) /* 5*1024 cache texture*/
            return (DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY);
    }
    /* memoire system*/
    return DDSCAPS_SYSTEMMEMORY;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : when an error occors while downloading texture
 ----------------------------------------------------------------------------------------
 */
void GLI_DX6_fn_vErrorLoadingTexture( GLI_tdstTexture *_p_stTexture, HRESULT _hError, char *_szErrorText )
{
    char szMessage[128];
    
    sprintf(szMessage, "texture.c :%s : %X -> ", _szErrorText, _hError );
    GLI_MDRV_vErmPrintMsg(szMessage, _p_stTexture->a255_cFileName);
            
    if (g_p_stD3DT2Temp)
    {
        do
        {
            _hError = g_p_stD3DT2Temp->lpVtbl->Release( g_p_stD3DT2Temp );
        } while (_hError > 0);
    }
    else if (g_p_stDDS4Temp)
        g_p_stDDS4Temp->lpVtbl->Release( g_p_stDDS4Temp );
 
    if (g_p_stD3DT2New)
    {
        do
        {
            _hError = g_p_stD3DT2Temp->lpVtbl->Release( g_p_stD3DT2New );
        } while (_hError > 0);
    }
    else if (g_p_stDDS4New)
        g_p_stDDS4New->lpVtbl->Release( g_p_stDDS4New );
}
 
/* Begin G.CLEMENT 29/07/1999 : new function to set the chromakey with the pixel format of the texture */
/*
-----------------------------------------------------------------------------------------
Description : set the chromakey of the texture to the DDSurface4 with the right format
-----------------------------------------------------------------------------------------
*/
BOOL GLI_DX6_ConvertAndSetChromakey(GLI_tdstTexture *p_stTexture, LPDIRECTDRAWSURFACE4 p_stDDSurface)
{
    DDSURFACEDESC2  ddsd;
    DDCOLORKEY      stColorKey;
    HRESULT         ddres;

    memset(&ddsd,0,sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddres = p_stDDSurface->lpVtbl->GetSurfaceDesc( p_stDDSurface, &ddsd);
	if (ddres != DD_OK)
	{
			return FALSE;
	}
  
    /*get the pixel format*/
	if (ddsd.ddpfPixelFormat.dwRGBBitCount == 8)
	{
		/* Dunno what to do ! */
		return FALSE;
	}
	else
	{
		/* Neat ! Works the same with 16, 24, and 32 bits formats */
		long            lShiftRed, lScaleRed, lShiftGreen, lScaleGreen, lShiftBlue, lScaleBlue ;
		unsigned long   ulMaskRed, ulMaskGreen, ulMaskBlue;
		unsigned long   ulConvertedKey;
		char *p_cOriginalKey = (char *)&(p_stTexture->lChromakeyColorRGBA);

		ulMaskRed   = ddsd.ddpfPixelFormat.dwRBitMask;
		ulMaskGreen = ddsd.ddpfPixelFormat.dwGBitMask;
		ulMaskBlue  = ddsd.ddpfPixelFormat.dwBBitMask;

		fn_vGetScaleAndShiftFromMask(ulMaskRed, &lShiftRed, &lScaleRed);
		fn_vGetScaleAndShiftFromMask(ulMaskGreen, &lShiftGreen, &lScaleGreen);
		fn_vGetScaleAndShiftFromMask(ulMaskBlue, &lShiftBlue, &lScaleBlue);

		/* This is done for NZ textures, so we don't care about the alpha part */
		ulConvertedKey = (unsigned long)((((p_cOriginalKey[0]>>lScaleRed)  <<lShiftRed)   & ulMaskRed)
										|(((p_cOriginalKey[1]>>lScaleGreen)<<lShiftGreen) & ulMaskGreen)
										|(((p_cOriginalKey[2]>>lScaleBlue) <<lShiftBlue)  & ulMaskBlue));
		stColorKey.dwColorSpaceLowValue = ulConvertedKey;
		stColorKey.dwColorSpaceHighValue = ulConvertedKey;
		ddres = p_stDDSurface->lpVtbl->SetColorKey( p_stDDSurface, DDCKEY_SRCBLT, &stColorKey);
		return (ddres == DD_OK);
	}
}
/* End G.CLEMENT 29/07/1999 */

/*
 ----------------------------------------------------------------------------------------
  Description   : Download texture
 ----------------------------------------------------------------------------------------
 */
void GLI_DRV_vDownLoadTextures(long bRestore, long _lTextureMode, BOOL bReloading )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    long                    lMipMappingLocalSwitch, lTextureCounter;
    GLI_tdstTexture         *p_stTexture;
    DDSURFACEDESC2          ddsd;
    LPDIRECTDRAWSURFACE4    p_stDDSurfaceCurrentTemp;
    HRESULT                 ddres;
    DDSCAPS2                ddsCaps; 
    BOOL                    bCanUseMipmap;
    BOOL                    bUseAGPMemory;
	LPPALETTEENTRY			p_stPalette;
	
	unsigned long			ulMemoryBefore, ulMemoryAfter, ulTotal, ulLeft;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    /*GLI_vInitD3DTextureFormat();*/
 
    bCanUseMipmap = g_p_stGliCaps->ulTextureCaps & GLICAPS_TEX_C_ulSupportMipmap;
    bUseAGPMemory = g_p_stGliCaps->ulDriverCaps & GLICAPS_DRV_C_ulCanUseAGP;
  
    /* loop on textures*/
    for (lTextureCounter = 0; lTextureCounter < GLI_C_lNBMaxOfTextures ; lTextureCounter ++)
    {
        if ( ( gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] == GLI_TEXIsUnallocated ) || ( (p_stTexture = gs_aDEFTableOfTextureAlreadyRead[lTextureCounter]) == NULL ) )
            continue;
 
        g_p_stDDS4Temp  = NULL;
        g_p_stDDS4New   = NULL;
        g_p_stD3DT2Temp = NULL;
        g_p_stD3DT2New  = NULL;

        /* Load bitmap*/


        GLI_MDRV_xLoadTextureInTexelField(p_stTexture, GLI_gs_p_ConvertBufferMipMapping, bReloading);

		/* 
		 * Bench : compute memory before texture creation
		 */
		GLI_DX6_hGetVideoMemory( g_pDD4, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP, &ulTotal, &ulMemoryBefore );
        if (bUseAGPMemory)
        {
            GLI_DX6_hGetVideoMemory( g_pDD4, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_MIPMAP, &ulTotal, &ulLeft);
		    ulMemoryBefore += ulLeft;
        }
 
 
        /*
         * set surface parameters
         */
        memset(&ddsd, 0, sizeof(ddsd));
        ddsd.dwSize = sizeof(ddsd);
        ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT ;
        GLI_fn_vGetPixelFormat( p_stTexture->lTextureCaps, &ddsd.ddpfPixelFormat );
        ddsd.dwWidth = p_stTexture->lWidth;
        ddsd.dwHeight = p_stTexture->lHeight;
        ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD;
        
        /*
         * some more parameters in case of mipmap texture
         */
        if( bCanUseMipmap && p_stTexture->lNumberOfLod)
        {
            ddsd.ddsCaps.dwCaps |= DDSCAPS_MIPMAP | DDSCAPS_COMPLEX;
            ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
            ddsd.dwMipMapCount = p_stTexture->lNumberOfLod + 1;
        }
        else
            ddsd.dwMipMapCount = 0;
            
    
        ddsd.ddsCaps.dwCaps |= GLI_fn_ulGetMemoryFlag( p_stTexture, _lTextureMode, bUseAGPMemory );
 
 
        /*
         *  create texture surface
         */
        ddres = g_pDD4->lpVtbl->CreateSurface( g_pDD4, &ddsd, &g_p_stDDS4New, NULL );
        if ( (ddres != DD_OK) || !(g_p_stDDS4New) )
        {
            GLI_DX6_fn_vErrorLoadingTexture( p_stTexture, ddres, "Create surface failed" );
            continue;
        }
 
        /* create temporary surface*/
        ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE;
        if( bCanUseMipmap && p_stTexture->lNumberOfLod)
            ddsd.ddsCaps.dwCaps |= DDSCAPS_MIPMAP  | DDSCAPS_COMPLEX;
        
        ddres = g_pDD4->lpVtbl->CreateSurface( g_pDD4, &ddsd, &g_p_stDDS4Temp,NULL);
        if ( (ddres != DD_OK) || !(g_p_stDDS4Temp) )
        {
            GLI_DX6_fn_vErrorLoadingTexture( p_stTexture, ddres, "Create surface temp failed" );
            continue;
        }
 
		/*
		 * Set palette
		 */
		if ( p_stTexture->lTextureCaps & GLI_C_lPaletteTexture )
		{
			LPDIRECTDRAWPALETTE		p_stDDPalette;
			long					lColor;
			unsigned char			ucSave;
 
			p_stPalette	= (LPPALETTEENTRY) p_stTexture->p_vColorTable;
			for (lColor = 0; lColor < 256; lColor++)
			{
				ucSave = p_stPalette[lColor].peRed;
				p_stPalette[lColor].peRed = p_stPalette[lColor].peBlue;
				p_stPalette[lColor].peBlue = ucSave;
			}
 
			ddres = g_pDD4->lpVtbl->CreatePalette( g_pDD4, DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, p_stPalette, &p_stDDPalette, NULL );
			ddres = g_p_stDDS4Temp->lpVtbl->SetPalette( g_p_stDDS4Temp, p_stDDPalette );
			ddres = g_p_stDDS4New->lpVtbl->SetPalette( g_p_stDDS4New, p_stDDPalette );
			ddres = p_stDDPalette->lpVtbl->Release( p_stDDPalette );
		}
 
		/* Begin G.CLEMENT 28/07/1999 : reverted chromakey settings and bitmap copy (we need the former in the latter) */
        /* Set the color key (chroma key) ([G.CLEMENT] using my new function) */
        if(p_stTexture->lTextureCaps & GLI_C_lNZTexture)
        {
			if (!GLI_DX6_ConvertAndSetChromakey(p_stTexture, g_p_stDDS4New))
            {
                GLI_DX6_fn_vErrorLoadingTexture( p_stTexture, ddres, "SetColorKey failed" );
                continue;
            }
        }
 
        /* Copy bitmap in the temporary surface*/
        if(!GLI_D3D_bCopyBitmapToSurface(p_stTexture->p_vBitMap, g_p_stDDS4Temp,p_stTexture)) /* G.CLEMENT 28/07/1999 : added 'p_stTexture' as an argument */
        {
            GLI_DX6_fn_vErrorLoadingTexture( p_stTexture, ddres, "Copy bitmap failed" );
            continue;
        }
		/* End G.CLEMENT 28/07/1999 */
 
        /* compute next mipmaping levels*/
		if( bCanUseMipmap )
		{
            unsigned short uwWidth, uwHeight;

            uwWidth                     = p_stTexture->lWidth; 
            uwHeight                    = p_stTexture->lHeight;
            lMipMappingLocalSwitch      = p_stTexture->lNumberOfLod;
			p_stDDSurfaceCurrentTemp    = g_p_stDDS4Temp;
            ddres                       = DD_OK;
 
			while ( lMipMappingLocalSwitch-- )
			{
				/* Compute the bitmap from the prev level of mipmaping*/
				if ( p_stTexture->lTextureCaps & GLI_C_lPaletteTexture )
					GLI_MDRV_vDivideBitmapSurfaceBy2Palette( (unsigned long *)GLI_gs_p_ConvertBufferMipMapping , (unsigned long *) p_stPalette, uwHeight, uwWidth );
				else if (p_stTexture -> lTextureCaps & GLI_C_lNZTexture)
                    GLI_MDRV_vDivideBitmapSurfaceBy2NonZero((unsigned long *)GLI_gs_p_ConvertBufferMipMapping , (unsigned long *)GLI_gs_p_ConvertBufferMipMapping, uwHeight, uwWidth, p_stTexture->lChromakeyColorRGBA); /* G.CLEMENT 29/07/1999 : added chromakey */
				else
					GLI_MDRV_vDivideBitmapSurfaceBy2((unsigned long *)GLI_gs_p_ConvertBufferMipMapping, (unsigned long *)GLI_gs_p_ConvertBufferMipMapping, uwHeight, uwWidth );
 
				/* Get the temporary surface of the current mipmaping level*/
				ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
                ddres = p_stDDSurfaceCurrentTemp->lpVtbl->GetAttachedSurface( p_stDDSurfaceCurrentTemp, &ddsCaps ,&p_stDDSurfaceCurrentTemp);
				if(ddres != DD_OK)
				{
                    GLI_DX6_fn_vErrorLoadingTexture( p_stTexture, ddres, "GetAttachedSurface failed" );
					break;
				}
 
				/* Copy the bitmap in the current temporary surface*/
				if(!GLI_D3D_bCopyBitmapToSurface(GLI_gs_p_ConvertBufferMipMapping, p_stDDSurfaceCurrentTemp,p_stTexture)) /* G.CLEMENT 28/07/1999 : added 'p_stTexture' as an argument */
				{
                    GLI_DX6_fn_vErrorLoadingTexture( p_stTexture, ddres, "Copy bitmap level failed" );
					break;
				}

                uwWidth >>= 1;
                uwHeight >>= 1;
			}
            if (ddres != DD_OK)
                continue;
        }
 
        /* Get the texture interface*/
        ddres = g_p_stDDS4New->lpVtbl->QueryInterface( g_p_stDDS4New, &IID_IDirect3DTexture2, (void**) &g_p_stD3DT2New );
        if (ddres != DD_OK) 
        {
            GLI_DX6_fn_vErrorLoadingTexture( p_stTexture, ddres, "QueryInterface texture2 failed" );
            continue;
        }
 
        ddres = g_p_stDDS4Temp->lpVtbl->QueryInterface( g_p_stDDS4Temp , &IID_IDirect3DTexture2, (void**) &g_p_stD3DT2Temp );
        if (ddres != DD_OK) 
        {
            GLI_DX6_fn_vErrorLoadingTexture( p_stTexture, ddres, "QueryInterface TempTexture2 failed" );
            continue;
        }
 
        /* Load temporary texture in the good texture*/
        ddres = g_p_stD3DT2New->lpVtbl->Load( g_p_stD3DT2New, g_p_stD3DT2Temp ); 
        if (ddres != DD_OK) 
        {
            GLI_DX6_fn_vErrorLoadingTexture( p_stTexture, ddres, "load failed" );
            continue;
        }
 
        /* Delete the texture interface*/
        do
        {
            ddres = g_p_stD3DT2Temp->lpVtbl->Release( g_p_stD3DT2Temp );
        } while (ddres > 0);
 
        /* Delete the temporary surface*/
        p_stTexture->p_stSpecParam = (void *) g_p_stD3DT2New;
		p_stTexture->bIsAvailable = 1;
 
		/* 
		 * Bench : compute memory after texture creation
		 */
		GLI_DX6_hGetVideoMemory( g_pDD4, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP, &ulTotal, &ulMemoryAfter );
        if (bUseAGPMemory)
        {
            GLI_DX6_hGetVideoMemory( g_pDD4, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_MIPMAP, &ulTotal, &ulLeft);
		    ulMemoryAfter += ulLeft;
        }
		GLI_MDRV_TEXBENCH_vSetTextureSize( p_stTexture, 1, ulMemoryBefore - ulMemoryAfter );
    }
};
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Compute total memory size available for texture
 ----------------------------------------------------------------------------------------
 */
#ifdef __old__
long GLI_DRV_lGetHardwareTotalTextureMemorySize( long _lTextureMode )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    unsigned long   ulTotal, ulLeft;
    long            lReturn;
    HRESULT         ddres;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    switch( _lTextureMode )
    {
        case TEX_C_VRAM:
            ddres = GLI_DX6_hGetVideoMemory( g_pDD4, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP, &ulTotal, &ulLeft );
            lReturn = (ddres != DD_OK) ? -1 : (long) ulLeft;
            break;  
 
        case TEX_C_VRAM4:
        case TEX_C_AGP4:
            lReturn = 0x400000; /* 4 Mo*/
            break;
 
        case TEX_C_VRAM8:
        case TEX_C_AGP8:
            lReturn = 0x800000; /* 8 Mo */
            break;
 
        case TEX_C_VRAMAGP:
        case TEX_C_AGP:
 
            ddres = GLI_DX6_hGetVideoMemory( g_pDD4, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP, &ulTotal, &ulLeft );
            lReturn = (ddres != DD_OK) ? -1 : (long) ulLeft;
 
            ddres = GLI_DX6_hGetVideoMemory( g_pDD4, DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_MIPMAP, &ulTotal, &ulLeft );
            if (ddres != DD_OK)
                lReturn = -1;
            else
                lReturn += (long) ulLeft;
            break;
    }
  
    return lReturn;
}
#endif
 
/*
 ----------------------------------------------------------------------------------------
  Description   : recursive callback function to release the mipmap texture surfaces
 ----------------------------------------------------------------------------------------
 */
//HRESULT WINAPI ReleaseAttachedSurfaceCallback(LPDIRECTDRAWSURFACE7 lpDDSurface, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext)
//{
//	lpDDSurface->lpVtbl->EnumAttachedSurfaces(lpDDSurface, NULL, ReleaseAttachedSurfaceCallback);
//	lpDDSurface->lpVtbl->Release(lpDDSurface);
//	return DDENUMRET_OK;
//}

/*

/*
 ----------------------------------------------------------------------------------------
  Description   : unload textures
 ----------------------------------------------------------------------------------------
 */
void GLI_DRV_vUnLoadTextures()
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    HRESULT                 hr;
    long                    lTextureCounter;
    LPDIRECT3DTEXTURE2      lpD3DT2;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
    GLI_tdstTexture *p_stTexture;

	//chbani : add this line sinon ca plante dans UnLoadTex (changement de map et display WayPoint)
    if( g_pd3dDevice )
        g_pd3dDevice->lpVtbl->SetTexture(g_pd3dDevice,0, NULL );
    
    for ( lTextureCounter = 0 ; lTextureCounter < C_lMaxNumberOfTexture ;lTextureCounter ++)
    {
        if (gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] != GLI_TEXIsUnallocated )
        {
            p_stTexture = gs_aDEFTableOfTextureAlreadyRead[lTextureCounter];
            if (p_stTexture != NULL)
            {
                if ( (p_stTexture->bIsAvailable) && ( p_stTexture->p_stSpecParam ) )
                {
                    /*lpD3DT2 = ((GLI_tdstTextureD3D *) p_stTexture->p_stSpecParam)->p_stD3DTexture; */
                    lpD3DT2 = (LPDIRECT3DTEXTURE2) p_stTexture->p_stSpecParam;
                    if (lpD3DT2 != NULL)
						/* Don't forget to release mipmap (attached) textures too */
						//lpD3DT2->lpVtbl->EnumAttachedSurfaces(lpD3DT2, NULL, ReleaseAttachedSurfaceCallback);
                        do
                        {
                          hr =lpD3DT2->lpVtbl->Release( lpD3DT2 );
                        } while (hr > 0);
 
                    /*GLI_MDRV_vTmpFree( p_stTexture->p_stSpecParam );*/
                    p_stTexture->p_stSpecParam = NULL;
                    p_stTexture->bIsAvailable = 0;
                }
            }
        }
    }
}
 
#ifdef __cplusplus
} /* extern "C" */
#endif
