 
/*
Tested with LINT
*/
 
/**************
TEXTURE.C
Ver 1.0
***************/
#include "GLD.h"
#include "GEO.h"
#include "TEX.h"
#include "gli_st.h"
#include "textu_st.h"
#include "texture.h"
#include <string.h>
#ifdef KAMUI
#include <kamui.h>
#endif
#include "GLI_interface.h"
 
unsigned long ulTotalUsedMemory;
unsigned long ulAgpUsedMemory;
 
extern unsigned long GLI_gsCurrentMemoryChannel;
extern unsigned long gs_lRGBBitCount;
extern long gs_lTreeOfNamesNumberOfLastLetter;
extern long gs_lNumberOfTextureToCreate;
extern long gs_lLastIdxInDEFTableOfTextures;
extern long lNbTextureFormat;
extern long lCurrentTextureFormat;
 
/*extern long gs_aDEFTableOfTextureMemoryChannels[ C_lMaxNumberOfTexture ];*/
extern unsigned char *gs_aCurrentTextures;
/*extern GLI_tdstTexture *gs_aDEFTableOfTextureAlreadyRead [ C_lMaxNumberOfTexture ];*/
extern unsigned char g_ucGliModuleId;
/*extern void *GLI_gs_p_ConvertBufferMipMapping;*/
 
short TEXTURETWIDDLED[1024L*1024L];
 
static unsigned long GLI_a256FastTwiddledTable[256];
/*unsigned long GLI_a256FastTwiddledTableD4[256];*/
 
long GLI_fnLinear2CasseTete(unsigned long lLinear , long lPitch)
{
    unsigned long lreturnvalue = 0;
    unsigned long CMPX = 1;
    while  (lLinear != 0)
    {
        if (lLinear & 128) lreturnvalue += CMPX<<3;
        if (lLinear & 64) lreturnvalue += lPitch<<3;
        if (lLinear & 32) lreturnvalue += CMPX<<2;
        if (lLinear & 16) lreturnvalue += lPitch<<2;
        if (lLinear & 8) lreturnvalue += CMPX<<1;
        if (lLinear & 4) lreturnvalue += lPitch<<1;
        if (lLinear & 2) lreturnvalue += CMPX;
        if (lLinear & 1) lreturnvalue += lPitch;
        CMPX<<=4;
        lPitch<<=4;
        lLinear >>= 8;
    }
    return lreturnvalue;
}
 
void GLI_InitTwiddlingTable(long largeur)
{
    long i;
    for (i = 0 ; i < 256 ; i++ )
        GLI_a256FastTwiddledTable[i] = GLI_fnLinear2CasseTete(i, largeur);
}
 
void GLI_fnSwitchTwiddled(short *p_Texture , long size )
{
    unsigned long xcounter, SizeXSize , SizeXSizeD8;
    short *Pdest ;
    unsigned long *GLI_a256FastTwiddledTableLocal;
    static long largeur = 0;
    short *p_TextureLocal,*p_DestLast;
    Pdest = TEXTURETWIDDLED;
    if (size != largeur)
    {
        GLI_InitTwiddlingTable(size);
        largeur = size;
    }
    SizeXSize = size * size;
    if (!(SizeXSize & 0xFF))
    {
        SizeXSizeD8 = SizeXSize >> 8;
        for (xcounter = 0 ; xcounter < SizeXSizeD8 ; xcounter ++ )
        {
            p_TextureLocal = p_Texture + (GLI_a256FastTwiddledTable[xcounter & 0xFF]<<4);
            p_TextureLocal += GLI_a256FastTwiddledTable[(xcounter>>8) & 0xFF]<<8;
            p_DestLast = Pdest + 256;
            GLI_a256FastTwiddledTableLocal = GLI_a256FastTwiddledTable;    
            while (Pdest < p_DestLast)
                *(Pdest++)= *(p_TextureLocal + *(GLI_a256FastTwiddledTableLocal++));
        }
    }
    else
    {
        xcounter = SizeXSize ;
        for ( xcounter = 0 ; xcounter < SizeXSize ; xcounter++ )
            *(Pdest++)= *(p_Texture + 
            GLI_a256FastTwiddledTable[xcounter & 0xFF] + 
            (GLI_a256FastTwiddledTable[(xcounter>>8) & 0xFF]<<4) +
            (GLI_a256FastTwiddledTable[(xcounter>>16) & 0xFF]<<8));
    }
    memcpy( p_Texture,  TEXTURETWIDDLED , SizeXSize<<1);
}
 
 
/*void GLI_xLoadTextureInTexelField(GLI_tdstTexture *p_stTexture, long *p_lTexelField);*/
/*void GLI_vDivideBitmapSurfaceBy2NonZero (unsigned long *p_Source,unsigned long *p_Dest,long lWidthSurfSouce, long lLenghtSurfSouce);*/
/*void GLI_vDivideBitmapSurfaceBy2 (unsigned long *p_Source,unsigned long *p_Dest,long lWidthSurfSouce, long lLenghtSurfSouce);*/
/*long GLI_lComputeTexturesSize();*/
 
 
 
#ifdef KAMUI
unsigned long GLI_lCorrectOffset(unsigned long lHeight)
{
    long lReturnValue, LHeightLoc;
    lReturnValue = 0;
    LHeightLoc = lHeight;
    while (LHeightLoc)
    {
        LHeightLoc>>=1;
        lReturnValue += LHeightLoc * LHeightLoc;
    }
    return (lReturnValue + 1);
}
 
void GLI_KamuiComputeMipMapping(void *p_SRC ,unsigned long Size ,KMTEXTURETYPE mode)
{
    unsigned short *p_Local,*p_Local1;
    unsigned long *p_Local2;
    unsigned long *p_MEMCPY1 , *p_MEMCPY2 ,LocalSize;
    unsigned long SizeXSize, SizeXSizeLocal , ulLocalColor;
    p_Local = (unsigned short *)p_SRC;
    SizeXSize = Size * Size;
    p_Local1 = p_Local + GLI_lCorrectOffset(Size);
    p_MEMCPY1 = (unsigned long *)p_Local1;
    p_MEMCPY2 = (unsigned long *)p_Local;
    LocalSize = SizeXSize>>1;
    p_MEMCPY1 += LocalSize;
    p_MEMCPY2 += LocalSize;
    while (LocalSize--)
    {
        *(--p_MEMCPY1) = *(--p_MEMCPY2);
    }
    /*    return;//  */
    /*    memcpy( p_Local1 ,  p_Local , SizeXSize<<1);*/
    Size >>= 1;
    while (Size)
    {
        SizeXSize >>= 2;
        SizeXSizeLocal = SizeXSize;
        p_Local1 = p_Local + GLI_lCorrectOffset(Size);
        (unsigned short *)p_Local2 = p_Local1 + SizeXSize;
        switch (mode)
        {
        case KM_TEXTURE_RGB565:
            while (SizeXSizeLocal--)
            {
                ulLocalColor = ((*(p_Local2) & 0x0000001f) << 1) + ((*(p_Local2) & 0x000007e0) << 3) + ((*(p_Local2) & 0x0000f800) << 6) + ((*(p_Local2) & 0x001f0000) >> 15) + ((*(p_Local2) & 0x07e00000) >> 13) + ((*(p_Local2) & 0xf8000000) >> 10);
                p_Local2++;
                ulLocalColor += ((*(p_Local2) & 0x0000001f) << 1) + ((*(p_Local2) & 0x000007e0) << 3) + ((*(p_Local2) & 0x0000f800) << 6) + ((*(p_Local2) & 0x001f0000) >> 15) + ((*(p_Local2) & 0x07e00000) >> 13) + ((*(p_Local2) & 0xf8000000) >> 10);
                ulLocalColor <<= 8;
                ulLocalColor = (ulLocalColor & 0xf8000000) | ((ulLocalColor & 0x00f80000)<<3) | ((ulLocalColor & 0x0000f800)<<5);
                *(p_Local1++) = (unsigned short)(ulLocalColor>>16);
                p_Local2++;
            }
            break;
        case KM_TEXTURE_ARGB4444:
            while (SizeXSizeLocal--)
            {
                ulLocalColor  = ((*(p_Local2) & 0x0000000F) << 2 ) + ((*(p_Local2) & 0x000000F0) << 6 ) + ((*(p_Local2) & 0x00000F00) << 10) + ((*(p_Local2) & 0x0000f000) << 14) + ((*(p_Local2) & 0x000F0000) >> 14) + ((*(p_Local2) & 0x00F00000) >> 10) + ((*(p_Local2) & 0x0F000000) >> 6 ) + ((*(p_Local2) & 0xf0000000) >> 2 );
                p_Local2++;
                ulLocalColor += ((*(p_Local2) & 0x0000000F) << 2 ) + ((*(p_Local2) & 0x000000F0) << 6 ) + ((*(p_Local2) & 0x00000F00) << 10) + ((*(p_Local2) & 0x0000f000) << 14) + ((*(p_Local2) & 0x000F0000) >> 14) + ((*(p_Local2) & 0x00F00000) >> 10) + ((*(p_Local2) & 0x0F000000) >> 6 ) + ((*(p_Local2) & 0xf0000000) >> 2 );
                ulLocalColor = (ulLocalColor & 0xf0000000) | ((ulLocalColor & 0x00f00000)<<4) | ((ulLocalColor & 0x0000f000)<<8) | ((ulLocalColor & 0x000000f0)<<12);
                *(p_Local1++) = (unsigned short)(ulLocalColor>>16);
                p_Local2++;
            }
            break;
        case KM_TEXTURE_ARGB1555:
            while (SizeXSizeLocal--)
            {
                ulLocalColor  = ((*(p_Local2) & 0x0000001F) << 1 ) + ((*(p_Local2) & 0x000003E0) << 4 ) + ((*(p_Local2) & 0x00007C00) << 7 ) + ((*(p_Local2) & 0x00008000) << 14) + ((*(p_Local2) & 0x001F0000) >> 15) + ((*(p_Local2) & 0x03E00000) >> 12) + ((*(p_Local2) & 0x7C000000) >> 9 ) + ((*(p_Local2) & 0x80000000) >> 2 ) ;
                p_Local2++;
                ulLocalColor += ((*(p_Local2) & 0x0000001F) << 1 ) + ((*(p_Local2) & 0x000003E0) << 4 ) + ((*(p_Local2) & 0x00007C00) << 7 ) + ((*(p_Local2) & 0x00008000) << 14) + ((*(p_Local2) & 0x001F0000) >> 15) + ((*(p_Local2) & 0x03E00000) >> 12) + ((*(p_Local2) & 0x7C000000) >> 9 ) + ((*(p_Local2) & 0x80000000) >> 2 ) ;
                ulLocalColor = (ulLocalColor & 0x80000000) | ((ulLocalColor & 0x00f80000)<<7) | ((ulLocalColor & 0x0000f800)<<10) | ((ulLocalColor & 0x000000f8)<<13);
                *(p_Local1++) = (unsigned short)(ulLocalColor>>16);
                p_Local2++;
            }
            break;
        }
        Size >>= 1;
    }
}
void GLI_DRV_vDownLoadTextures(long bRestore, long _lTextureMode, BOOL bReloading )
{
    long lTextureCounter;
    KMTEXTURETYPE		nTextureType;
    GLI_tdstTexture *p_stTexture;
    for (lTextureCounter = 0; lTextureCounter < GLI_C_lNBMaxOfTextures ; lTextureCounter ++)
        if (gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] != GLI_TEXIsUnallocated )
        {
            p_stTexture = gs_aDEFTableOfTextureAlreadyRead[lTextureCounter];
            while (p_stTexture != NULL) 
            {
                p_stTexture -> bIsAvailable = 0;
                GLI_MDRV_xLoadTextureInTexelField(p_stTexture, GLI_gs_p_ConvertBufferMipMapping,TRUE);
                if (p_stTexture -> lTextureCaps & GLI_C_lNZTexture)
                {
                    GLI_MDRV_vCompressTex1555 ( p_stTexture , GLI_gs_p_ConvertBufferMipMapping);
                    nTextureType = KM_TEXTURE_ARGB1555;
                } else
                {
                    if ((p_stTexture -> lTextureCaps & GLI_C_lAlphaTexture) == 0)
                    {
                        GLI_MDRV_vCompressTex565 ( p_stTexture , GLI_gs_p_ConvertBufferMipMapping);
                        nTextureType = KM_TEXTURE_RGB565;
                    } else
                    {
                        
                        GLI_MDRV_vCompressTex4444 ( p_stTexture , GLI_gs_p_ConvertBufferMipMapping);
                        nTextureType = KM_TEXTURE_ARGB4444;
                    } 
                }
                p_stTexture-> p_stSpecParam = malloc(sizeof(KMSURFACEDESC));
                
                GLI_fnSwitchTwiddled(GLI_gs_p_ConvertBufferMipMapping , p_stTexture->lHeight );
                if (p_stTexture ->lNumberOfLod)
                {
                    GLI_KamuiComputeMipMapping(GLI_gs_p_ConvertBufferMipMapping ,p_stTexture->lHeight , nTextureType);
                    nTextureType |= KM_TEXTURE_TWIDDLED_MM;
                } else
                    nTextureType |= KM_TEXTURE_TWIDDLED;
                if (kmCreateTextureSurface((KMSURFACEDESC * )p_stTexture-> p_stSpecParam,p_stTexture->lHeight,p_stTexture->lWidth,nTextureType) == KMSTATUS_SUCCESS)
                {
                    kmLoadTexture((KMSURFACEDESC * )p_stTexture-> p_stSpecParam,GLI_gs_p_ConvertBufferMipMapping,FALSE,FALSE);
                    p_stTexture->bIsAvailable = 1;
                }
                p_stTexture = p_stTexture -> p_NextLodOfTexture;
                p_stTexture = NULL;
            }
        }
}
#endif
 
/*
 ----------------------------------------------------------------------------------------
  Description   : get total memory size available for texture
 ----------------------------------------------------------------------------------------
 */
long GLI_DRV_lGetHardwareTotalTextureMemorySize(long _lTextureMode)
{
    return (6388608L);
}
 
/**********************************************************************************************/
/* Name: GLI_DRV_lGetHardwareMaxTextureSize() 1.0*/
/* OPTIMMIZED : No*/
/**********************************************************************************************/
long GLI_DRV_lGetHardwareMaxTextureSize(void)
{
    return (1024);
}
 
/**********************************************************************************************/
/* Name: GLI_DRV_lIsHardwareAcceptNonSquaredTextures() 1.0*/
/* OPTIMMIZED : No*/
/**********************************************************************************************/
long GLI_DRV_lIsHardwareAcceptNonSquaredTextures(void)
{
    return (0);
}
 
void GLI_DRV_vUnLoadTextures()
{
    long lTextureCounter;
    
    GLI_tdstTexture *p_stTexture;
    
    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)
                {
                    kmFreeTexture((KMSURFACEDESC * )p_stTexture-> p_stSpecParam);
                    free (p_stTexture-> p_stSpecParam);
                    p_stTexture->bIsAvailable = 0;
                }
            }
        }
    }
}
 
 
#ifdef __cplusplus
} /* extern "C" */
#endif
