1808 lines
68 KiB
C
1808 lines
68 KiB
C
/*
|
|
=======================================================================================
|
|
Name : Tex.c
|
|
Author : GLIGLOU
|
|
Description : texture function
|
|
=======================================================================================
|
|
*/
|
|
|
|
#define MTH_LOW
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
#include "gli_st.h"
|
|
#include "GLI_Defn.h"
|
|
#include "light_st.h"
|
|
#include "PvObj_st.h"
|
|
#include "texture.h"
|
|
#include "TEX.h"
|
|
#include "load.h"
|
|
|
|
#include "TMP.h"
|
|
#include "VIG.h"
|
|
|
|
#include "FIL.h"
|
|
#include "SNA.h"
|
|
|
|
#include "acp_opfi.h"
|
|
#include "texture.h"
|
|
#include "DLLInter.h"
|
|
#include "DLLCaps.h"
|
|
#include "TexName.h"
|
|
#include "TexArray.h"
|
|
#include "TexCompress.h"
|
|
#include "TexBench.h"
|
|
#include "MatBench.h"
|
|
#include "GliTExt.h"
|
|
#include "acp_driver.h"
|
|
|
|
/*
|
|
=======================================================================================
|
|
Macro
|
|
=======================================================================================
|
|
*/
|
|
|
|
/*
|
|
* Error
|
|
*/
|
|
#define TEX_M_ERROR(B)\
|
|
{\
|
|
Erm_M_UpdateLastError(GEO, C_ucErmDefaultChannel, E_uwGEOCanNotloadBitmap , C_lErmNoDebugData , C_ucErmOpenInfoWindow, C_ucAllowStopForDebug, B);\
|
|
}\
|
|
|
|
/*
|
|
=======================================================================================
|
|
Globals
|
|
=======================================================================================
|
|
*/
|
|
|
|
/*
|
|
* memory
|
|
*/
|
|
unsigned long GLI_gsCurrentMemoryChannel;
|
|
long g_lTextureMode = TEX_C_AGP;
|
|
|
|
/*
|
|
* array of texture name
|
|
*/
|
|
extern long gs_lNumberOfTextureToCreate;
|
|
|
|
/*
|
|
* to convert texture
|
|
*/
|
|
void * GLI_gs_p_ConvertBufferMipMapping;
|
|
long GLI_gs_lConvertBufferMipMappingSizeInBytes;
|
|
|
|
/*
|
|
* bigfile with textures
|
|
*/
|
|
FIL_tdxHandleToConcatFile GLI_g_hConcatTexturesFile = NULL;
|
|
|
|
/*
|
|
=======================================================================================
|
|
Prototype
|
|
=======================================================================================
|
|
*/
|
|
void GLI_vDownLoadTexture(BOOL);
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
/*
|
|
=======================================================================================
|
|
Texture memory mode / video memory mode
|
|
=======================================================================================
|
|
*/
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : set video memory mode
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vSetTextureMode(char *sMode)
|
|
{
|
|
if( stricmp(sMode, "Vram") == 0) g_lTextureMode = TEX_C_VRAM;
|
|
else if( stricmp(sMode, "Vram+") == 0) g_lTextureMode = TEX_C_VRAMAGP;
|
|
else if( stricmp(sMode, "Vram4") == 0) g_lTextureMode = TEX_C_VRAM4;
|
|
else if( stricmp(sMode, "Vram8") == 0) g_lTextureMode = TEX_C_VRAM8;
|
|
else if( stricmp(sMode, "Agp") == 0) g_lTextureMode = TEX_C_AGP;
|
|
else if( stricmp(sMode, "Agp4") == 0) g_lTextureMode = TEX_C_AGP4;
|
|
else if( stricmp(sMode, "Agp8") == 0) g_lTextureMode = TEX_C_AGP8;
|
|
else g_lTextureMode = TEX_C_AGP;
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : retrieve video memory mode
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
long GLI_lGetTextureMode()
|
|
{
|
|
return g_lTextureMode;
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : set current memory channel for texture
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_TEX_vSignalCurrentMemoryChannel(unsigned char ucCurrentChannel)
|
|
{
|
|
GLI_gsCurrentMemoryChannel = (long)ucCurrentChannel;
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : unallocate all the textures allocated in this channel.
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_TEX_vKillMemoryChannel(unsigned char ucCurrentChannel)
|
|
{
|
|
GLI_vUnloadTexture();
|
|
GLI_fn_vUnallocTextureInChannel( ucCurrentChannel );
|
|
/*GLI_vDownLoadTexture(TRUE); */
|
|
}
|
|
|
|
/*
|
|
=======================================================================================
|
|
Assert texture
|
|
=======================================================================================
|
|
*/
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : return the power of 2 of n
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
long GLI_lGetLog2n(long ln)
|
|
{
|
|
if (ln > 8192) return (13);
|
|
if (ln > 4096) return (12);
|
|
if (ln > 2048) return (11);
|
|
if (ln > 1024) return (10);
|
|
if (ln > 512) return (9);
|
|
if (ln > 256) return (8);
|
|
if (ln > 128) return (7);
|
|
if (ln > 64) return (6);
|
|
if (ln > 32) return (5);
|
|
if (ln > 16) return (4);
|
|
if (ln > 8) return (3);
|
|
if (ln > 4) return (2);
|
|
if (ln > 2) return (1);
|
|
return (0);
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : return 1 if number is a power of 2
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
long GLI_lIsPowerOf2(long ln)
|
|
{
|
|
if (
|
|
(ln == 128) || (ln == 64) || (ln == 32) || (ln == 16) || (ln == 8) || (ln == 4) || (ln == 2) || (ln == 1) ||
|
|
(ln == 8192) || (ln == 4096) || (ln == 2048) || (ln == 1024) || (ln == 512) || (ln == 256)
|
|
)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : check texture size (two dimension have to be power of 2)
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vAssertTexture( GLI_tdstTexture *p_stTexture )
|
|
{
|
|
if ( GLI_lIsPowerOf2(p_stTexture->lHeight) && ( (p_stTexture->lHeight == p_stTexture->lWidth) || GLI_lIsPowerOf2(p_stTexture->lWidth) ) )
|
|
return;
|
|
|
|
TEX_M_ERROR( p_stTexture->a255_cFileName );
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : init texture reading
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vIniTextRead()
|
|
{
|
|
GLI_fn_vUnallocAllTextures();
|
|
gs_lNumberOfTextureToCreate = 0;
|
|
};
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : Open big file for textures
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_fn_vOpenBigFileTextures(char *p_szFileName)
|
|
{
|
|
/* Multi-install Open file */
|
|
ACP_M_OPENFILE(FIL_fn_vOpenConcatFile,GLI_g_hConcatTexturesFile,NULL,p_szFileName,(p_szFileName));
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : close big file for textures
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_fn_vCloseBigFileTextures(void)
|
|
{
|
|
FIL_fn_vCloseConcatFile(&GLI_g_hConcatTexturesFile);
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : Create a texture (alloc and init)
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_xCreateTexture ( GLI_tdstTexture **h_stTexture )
|
|
{
|
|
MMG_fn_vAddMemoryInfo (MMG_C_lTypeGLI , MMG_C_lSubTypeTexture , NULL);
|
|
GEO_M_CPAMalloc(*h_stTexture,GLI_tdstTexture *,sizeof(GLI_tdstTexture),E_uwGEONotEnoughtMemory );
|
|
memset(*h_stTexture,0,sizeof(GLI_tdstTexture));
|
|
TEX_vSetTextureQualityLevel( (*h_stTexture) , (char)TEX_C_QNORMAL);
|
|
}
|
|
|
|
/*
|
|
=======================================================================================
|
|
=======================================================================================
|
|
Tranform Bitmap
|
|
=======================================================================================
|
|
=======================================================================================
|
|
*/
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : Will detect frontier between chromakey and non-chromakey colors, for
|
|
filtering the black-border visible when bi-linear filtering is enable.
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vComputeNZFiltering( GLI_tdstTexture *p_stTexture , void *GLI_gs_p_ConvertBuffer)
|
|
{
|
|
long ADDY ,SUBY ,ADDX ,SUBX ;
|
|
unsigned long lBitmapCounter,lBitmapCounter2,p_vConvertBufferCount , lLocalColor;
|
|
unsigned long lChromakeyColor = p_stTexture -> lChromakeyColorRGBA & 0x00ffffff; /* 0x00f8f8f8 */
|
|
|
|
p_vConvertBufferCount = (long)GLI_gs_p_ConvertBuffer ;
|
|
|
|
if ((p_stTexture -> lWidth == 1) && (p_stTexture -> lHeight == 1))
|
|
return;
|
|
|
|
for (lBitmapCounter2 = 0;lBitmapCounter2 < (unsigned long) (p_stTexture -> lHeight * p_stTexture -> lWidth);lBitmapCounter2 += p_stTexture -> lWidth)
|
|
for (lBitmapCounter = 0;lBitmapCounter < (p_stTexture -> lWidth);lBitmapCounter ++)
|
|
{
|
|
if ((*(((unsigned long *)p_vConvertBufferCount)+ lBitmapCounter + lBitmapCounter2)& 0x00ffffff) == lChromakeyColor) /* 0x00f8f8f8 */
|
|
*(((unsigned long *)p_vConvertBufferCount)+lBitmapCounter + lBitmapCounter2) &= 0xffffff;
|
|
else
|
|
*(((unsigned long *)p_vConvertBufferCount)+lBitmapCounter + lBitmapCounter2) |= 0xff000000;
|
|
}
|
|
|
|
for (lBitmapCounter2 = 0;lBitmapCounter2 < (unsigned long) (p_stTexture -> lHeight * p_stTexture -> lWidth);lBitmapCounter2 += p_stTexture -> lWidth)
|
|
for (lBitmapCounter = 0;lBitmapCounter < ((p_stTexture -> lWidth));lBitmapCounter ++)
|
|
{
|
|
ADDY = p_stTexture -> lWidth;
|
|
SUBY = -(signed long)p_stTexture -> lWidth;
|
|
ADDX = 1;
|
|
SUBX = -1;
|
|
if (lBitmapCounter2 == 0)
|
|
SUBY = ADDY;
|
|
if (lBitmapCounter2 == (unsigned long) ((p_stTexture -> lHeight-1) * p_stTexture -> lWidth))
|
|
ADDY = SUBY ;
|
|
if (lBitmapCounter == 0)
|
|
SUBX = ADDX;
|
|
if (lBitmapCounter == (unsigned long) ((p_stTexture -> lWidth - 1)))
|
|
ADDX = SUBX;
|
|
|
|
lLocalColor = 0;
|
|
|
|
if ((*(((unsigned long *)p_vConvertBufferCount) + lBitmapCounter + lBitmapCounter2)& 0xFF000000) == 0)
|
|
{
|
|
if ((*(((unsigned long *)p_vConvertBufferCount)+ADDX + lBitmapCounter + lBitmapCounter2)& 0xFF000000) != 0)
|
|
lLocalColor = ((*(((unsigned long *)p_vConvertBufferCount) +ADDX + lBitmapCounter + lBitmapCounter2) & 0xfefefefe) >> 1) + ((lLocalColor & 0xfefefefe) >> 1);
|
|
if ((*(((unsigned long *)p_vConvertBufferCount)+SUBX + lBitmapCounter + lBitmapCounter2)& 0xFF000000) != 0)
|
|
lLocalColor = ((*(((unsigned long *)p_vConvertBufferCount) +SUBX + lBitmapCounter + lBitmapCounter2) & 0xfefefefe) >> 1) + ((lLocalColor & 0xfefefefe) >> 1);
|
|
if ((*(((unsigned long *)p_vConvertBufferCount)+ADDY + lBitmapCounter + lBitmapCounter2)& 0xFF000000) != 0)
|
|
lLocalColor = ((*(((unsigned long *)p_vConvertBufferCount) +ADDY + lBitmapCounter + lBitmapCounter2) & 0xfefefefe) >> 1) + ((lLocalColor & 0xfefefefe) >> 1);
|
|
if ((*(((unsigned long *)p_vConvertBufferCount)+ADDX+ADDY + lBitmapCounter + lBitmapCounter2)& 0xFF000000) != 0)
|
|
lLocalColor = ((*(((unsigned long *)p_vConvertBufferCount)+ADDX +ADDY + lBitmapCounter + lBitmapCounter2) & 0xfefefefe) >> 1) + ((lLocalColor & 0xfefefefe) >> 1);
|
|
if ((*(((unsigned long *)p_vConvertBufferCount)+SUBX +ADDY + lBitmapCounter + lBitmapCounter2)& 0xFF000000) != 0)
|
|
lLocalColor = ((*(((unsigned long *)p_vConvertBufferCount)+SUBX +ADDY + lBitmapCounter + lBitmapCounter2) & 0xfefefefe) >> 1) + ((lLocalColor & 0xfefefefe) >> 1);
|
|
if ((*(((unsigned long *)p_vConvertBufferCount)+SUBY + lBitmapCounter + lBitmapCounter2)& 0xFF000000) != 0)
|
|
lLocalColor = ((*(((unsigned long *)p_vConvertBufferCount)+SUBY + lBitmapCounter + lBitmapCounter2) & 0xfefefefe) >> 1) + ((lLocalColor & 0xfefefefe) >> 1);
|
|
if ((*(((unsigned long *)p_vConvertBufferCount)+ADDX+SUBY + lBitmapCounter + lBitmapCounter2)& 0xFF000000) != 0)
|
|
lLocalColor = ((*(((unsigned long *)p_vConvertBufferCount)+ADDX+SUBY + lBitmapCounter + lBitmapCounter2) & 0xfefefefe) >> 1) + ((lLocalColor & 0xfefefefe) >> 1);
|
|
if ((*(((unsigned long *)p_vConvertBufferCount)+SUBX+SUBY + lBitmapCounter + lBitmapCounter2)& 0xFF000000) != 0)
|
|
lLocalColor = ((*(((unsigned long *)p_vConvertBufferCount)+SUBX+SUBY + lBitmapCounter + lBitmapCounter2) & 0xfefefefe) >> 1) + ((lLocalColor & 0xfefefefe) >> 1);
|
|
lLocalColor &= 0xffffff;
|
|
*(((unsigned long *)p_vConvertBufferCount)+lBitmapCounter + lBitmapCounter2) = lLocalColor ;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : smooth chromakey border. And set alpha channel.
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_fn_vFilterNZForAlphaTest( void *_p_vBuffer, long _lWidth, long _lHeight, unsigned long _ulChromakey )
|
|
{
|
|
long ADDY ,SUBY ,ADDX ,SUBX ;
|
|
unsigned long lBitmapCounter,lBitmapCounter2 ,lLocalColor;
|
|
unsigned long ulSize;
|
|
unsigned long *p_ulBuffer, *p_ulEndBuffer;
|
|
float fRed, fBlue, fGreen;
|
|
char ucNbColor;
|
|
|
|
if ( (_lWidth == 1) && ( _lHeight == 1) )
|
|
return;
|
|
|
|
p_ulBuffer = (unsigned long *) _p_vBuffer;
|
|
p_ulEndBuffer = p_ulBuffer + (_lWidth * _lHeight );
|
|
_ulChromakey &= 0xFfFfFf; /* 0xf8f8f8 */
|
|
|
|
for ( ; p_ulBuffer < p_ulEndBuffer; p_ulBuffer++) /* Set the chromakeys to alpha=0, otherwise alpha=1 */
|
|
{
|
|
if ( (*p_ulBuffer & 0xFfFfFf) == _ulChromakey )/* 0xf8f8f8 */
|
|
*p_ulBuffer &= 0xFFFFFF;
|
|
else
|
|
*p_ulBuffer |= 0xFF000000;
|
|
}
|
|
|
|
p_ulBuffer = (unsigned long *) _p_vBuffer;
|
|
ulSize = (unsigned long) _lWidth * _lHeight;
|
|
|
|
for (lBitmapCounter2 = 0;lBitmapCounter2 < ulSize ;lBitmapCounter2 += _lWidth) /* For each line */
|
|
{
|
|
SUBY = ((lBitmapCounter2 == 0) ? 1 : -1) * _lWidth;
|
|
ADDY = ( (lBitmapCounter2 == (unsigned long) ((_lHeight - 1) * _lWidth)) ? -1 : 1 ) * _lWidth;
|
|
|
|
for (lBitmapCounter = 0;lBitmapCounter < (unsigned long) _lWidth;lBitmapCounter ++) /* For each pixel in the line */
|
|
{
|
|
ADDX = ( lBitmapCounter == (unsigned long) ( _lWidth - 1) ) ? -1 : 1;
|
|
SUBX = ( lBitmapCounter == 0) ? 1 : -1;
|
|
|
|
lLocalColor = 0;
|
|
|
|
p_ulEndBuffer = p_ulBuffer + lBitmapCounter + lBitmapCounter2;
|
|
|
|
if ((*p_ulEndBuffer & 0xFF000000) == 0)
|
|
{
|
|
fRed = fBlue = fGreen = 0.0f;
|
|
|
|
if ((*( p_ulEndBuffer + ADDX ) & 0xFF000000) != 0)
|
|
{
|
|
fRed += ( (float) ( (*( p_ulEndBuffer + ADDX ) & 0xFF0000) >> 16 ) ) / 9.f;
|
|
fGreen += ( (float) ( (*( p_ulEndBuffer + ADDX ) & 0x00FF00) >> 8 ) ) / 9.f;
|
|
fBlue += ( (float) ( (*( p_ulEndBuffer + ADDX ) & 0x0000FF) ) ) / 9.f;
|
|
}
|
|
if ((*(p_ulEndBuffer + SUBX)& 0xFF000000) != 0)
|
|
{
|
|
fRed += ( (float) ( (*( p_ulEndBuffer + SUBX ) & 0xFF0000) >> 16 ) ) / 9.f;
|
|
fGreen += ( (float) ( (*( p_ulEndBuffer + SUBX ) & 0x00FF00) >> 8 ) ) / 9.f;
|
|
fBlue += ( (float) ( (*( p_ulEndBuffer + SUBX ) & 0x0000FF) ) ) / 9.f;
|
|
}
|
|
if ((*(p_ulEndBuffer + ADDY )& 0xFF000000) != 0)
|
|
{
|
|
fRed += ( (float) ( (*( p_ulEndBuffer + ADDY ) & 0xFF0000) >> 16 ) ) / 9.f;
|
|
fGreen += ( (float) ( (*( p_ulEndBuffer + ADDY ) & 0x00FF00) >> 8 ) ) / 9.f;
|
|
fBlue += ( (float) ( (*( p_ulEndBuffer + ADDY ) & 0x0000FF) ) ) / 9.f;
|
|
}
|
|
if ((*(p_ulEndBuffer + ADDX + ADDY)& 0xFF000000) != 0)
|
|
{
|
|
fRed += ( (float) ( (*( p_ulEndBuffer + ADDY + ADDX ) & 0xFF0000) >> 16 ) ) / 9.f;
|
|
fGreen += ( (float) ( (*( p_ulEndBuffer + ADDY + ADDX ) & 0x00FF00) >> 8 ) ) / 9.f;
|
|
fBlue += ( (float) ( (*( p_ulEndBuffer + ADDY + ADDX ) & 0x0000FF) ) ) / 9.f;
|
|
}
|
|
if ((*(p_ulEndBuffer+ SUBX +ADDY )& 0xFF000000) != 0)
|
|
{
|
|
fRed += ( (float) ( (*( p_ulEndBuffer + ADDY + SUBX ) & 0xFF0000) >> 16 ) ) / 9.f;
|
|
fGreen += ( (float) ( (*( p_ulEndBuffer + ADDY + SUBX ) & 0x00FF00) >> 8 ) ) / 9.f;
|
|
fBlue += ( (float) ( (*( p_ulEndBuffer + ADDY + SUBX ) & 0x0000FF) ) ) / 9.f;
|
|
}
|
|
if ((*(p_ulEndBuffer + SUBY )& 0xFF000000) != 0)
|
|
{
|
|
fRed += ( (float) ( (*( p_ulEndBuffer + SUBY ) & 0xFF0000) >> 16 ) ) / 9.f;
|
|
fGreen += ( (float) ( (*( p_ulEndBuffer + SUBY ) & 0x00FF00) >> 8 ) ) / 9.f;
|
|
fBlue += ( (float) ( (*( p_ulEndBuffer + SUBY ) & 0x0000FF) ) ) / 9.f;
|
|
}
|
|
if ((*(p_ulEndBuffer + ADDX + SUBY )& 0xFF000000) != 0)
|
|
{
|
|
fRed += ( (float) ( (*( p_ulEndBuffer + SUBY + ADDX ) & 0xFF0000) >> 16 ) ) / 9.f;
|
|
fGreen += ( (float) ( (*( p_ulEndBuffer + SUBY + ADDX ) & 0x00FF00) >> 8 ) ) / 9.f;
|
|
fBlue += ( (float) ( (*( p_ulEndBuffer + SUBY + ADDX ) & 0x0000FF) ) ) / 9.f;
|
|
}
|
|
if ((*(p_ulEndBuffer + SUBX + SUBY )& 0xFF000000) != 0)
|
|
{
|
|
fRed += ( (float) ( (*( p_ulEndBuffer + SUBY + SUBX ) & 0xFF0000) >> 16 ) ) / 9.f;
|
|
fGreen += ( (float) ( (*( p_ulEndBuffer + SUBY + SUBX ) & 0x00FF00) >> 8 ) ) / 9.f;
|
|
fBlue += ( (float) ( (*( p_ulEndBuffer + SUBY + SUBX ) & 0x0000FF) ) ) / 9.f;
|
|
}
|
|
|
|
|
|
lLocalColor = (unsigned long) (fRed) << 16;
|
|
lLocalColor |= (unsigned long) (fGreen) << 8;
|
|
lLocalColor |= (unsigned long) (fBlue);
|
|
/*if ( ucNbColor < 5 )*/
|
|
lLocalColor &= 0x00FFFFFF;
|
|
|
|
*p_ulEndBuffer = lLocalColor ;
|
|
}
|
|
else
|
|
{
|
|
ucNbColor = 0;
|
|
if ((*( p_ulEndBuffer + ADDX ) & 0xFF000000) == 0)
|
|
ucNbColor++;
|
|
if ((*(p_ulEndBuffer + SUBX)& 0xFF000000) == 0)
|
|
ucNbColor++;
|
|
if ((*(p_ulEndBuffer + ADDY )& 0xFF000000) == 0)
|
|
ucNbColor++;
|
|
if ((*(p_ulEndBuffer + ADDX + ADDY)& 0xFF000000) == 0)
|
|
ucNbColor++;
|
|
if ((*(p_ulEndBuffer+ SUBX +ADDY )& 0xFF000000) == 0)
|
|
ucNbColor++;
|
|
if ((*(p_ulEndBuffer + SUBY )& 0xFF000000) == 0)
|
|
ucNbColor++;
|
|
if ((*(p_ulEndBuffer + ADDX + SUBY )& 0xFF000000) == 0)
|
|
ucNbColor++;
|
|
if ((*(p_ulEndBuffer + SUBX + SUBY )& 0xFF000000) == 0)
|
|
ucNbColor++;
|
|
|
|
if (ucNbColor >= 7)
|
|
*p_ulEndBuffer &= 0xFFFFFF;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : compute alpha value for NZ texture
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vComputeAlphaForNZTexture( GLI_tdstTexture *_p_stTexture, unsigned long *_p_ulTexel )
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
unsigned long ulChromakeyColor = _p_stTexture->lChromakeyColorRGBA & 0x00f8f8f8;
|
|
unsigned long *_p_ulLast;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
if ((_p_stTexture->lWidth == 1) && (_p_stTexture->lHeight == 1))
|
|
return;
|
|
|
|
_p_ulLast = _p_ulTexel + (_p_stTexture->lWidth * _p_stTexture->lHeight);
|
|
for ( ; _p_ulTexel < _p_ulLast; _p_ulTexel++ )
|
|
{
|
|
if ( (*_p_ulTexel & 0x00F8F8F8) == ulChromakeyColor )
|
|
*_p_ulTexel &= 0xFFFFFF;
|
|
else
|
|
*_p_ulTexel |= 0xFF000000;
|
|
}
|
|
}
|
|
|
|
/*
|
|
=======================================================================================
|
|
Function to divide a bitmap surface by 2
|
|
=======================================================================================
|
|
*/
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : divide 32b bitmap width by 2
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vDivideBitmapBy2InX( unsigned long *p_SourceFF,unsigned long *p_DestFF,long lHSurfSouce, long lWSurfSouce )
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
long lWDest,lHDest;
|
|
unsigned long *p_Source,*p_Dest, *p_stLast;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
lWDest = lWSurfSouce >> 1;
|
|
lHDest = lHSurfSouce;
|
|
|
|
if (lWDest <=1)
|
|
return;
|
|
|
|
p_Source = p_SourceFF;
|
|
p_Dest = p_DestFF;
|
|
p_stLast = p_Dest + lWDest * lHDest;
|
|
|
|
for ( ; p_Dest < p_stLast; p_Dest++, p_Source+=2)
|
|
*p_Dest = ((*p_Source & 0xfefefefe) >> 1) + ((*(p_Source+1) & 0xfefefefe) >> 1);
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : divide 32b bitmap height by 2
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vDivideBitmapBy2InY(unsigned long *p_SourceFF,unsigned long *p_DestFF,long lHSurfSouce, long lWSurfSouce)
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
long lWDest,lHDest,lXCounter,lYCounter;
|
|
unsigned long *p_Source,*p_Dest;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
lWDest = lWSurfSouce ;
|
|
lHDest = lHSurfSouce >>1;
|
|
|
|
if (lHDest <=1 )
|
|
return;
|
|
|
|
p_Source = p_SourceFF;
|
|
p_Dest = p_DestFF;
|
|
|
|
for (lYCounter = 0; lYCounter < lHDest ; lYCounter++, p_Source+=lWSurfSouce)
|
|
for (lXCounter = 0; lXCounter < lWDest ; lXCounter++ , p_Dest++ , p_Source+=1)
|
|
*p_Dest = ((*p_Source & 0xfefefefe) >> 1) + ((*(p_Source+lWSurfSouce) & 0xfefefefe) >> 1) ;
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : divide 32b bitmap width by 2 (do not take care of zero pixels )
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
/* Begin G.CLEMENT 29/07/1999 : NZ can be non-black */
|
|
void GLI_vDivideBitmapBy2InXNonZero(unsigned long *p_SourceFF,unsigned long *p_DestFF,long lHSurfSouce, long lWSurfSouce, unsigned long ulChromaKey)
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
long lWDest;
|
|
unsigned long *p_ulLast, Psource1,Psource2;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
lWDest = lWSurfSouce >>1;
|
|
|
|
if (lWDest <=1)
|
|
return;
|
|
|
|
p_ulLast = p_DestFF + lWDest * lHSurfSouce;
|
|
|
|
/*for ( ; p_DestFF < p_ulLast; p_DestFF++, p_SourceFF+=2)
|
|
{
|
|
Psource1 = ((*p_SourceFF & 0xfefefefe) );
|
|
Psource2 = ((*(p_SourceFF+1) & 0xfefefefe) );
|
|
if ((Psource1 & 0x00f8f8f8) != 0)
|
|
{
|
|
if ((Psource2 & 0x00f8f8f8) != 0)
|
|
*p_DestFF = (Psource1 >> 1) + (Psource2 >> 1);
|
|
else
|
|
*p_DestFF = Psource1;
|
|
}
|
|
else
|
|
*p_DestFF = Psource2;
|
|
}*/
|
|
for ( ; p_DestFF < p_ulLast; p_DestFF++, p_SourceFF+=2)
|
|
{
|
|
Psource1 = *p_SourceFF;
|
|
Psource2 = *(p_SourceFF+1);
|
|
if ((Psource1 ^ ulChromaKey) & 0x00ffffff) /* 0x00f8f8f8 */
|
|
{
|
|
if ((Psource2 ^ ulChromaKey) & 0x00ffffff) /* 0x00f8f8f8 */
|
|
*p_DestFF = ((Psource1 & 0xfefefefe) >> 1) + ((Psource2 & 0xfefefefe) >> 1);
|
|
else
|
|
*p_DestFF = Psource1;
|
|
}
|
|
else
|
|
*p_DestFF = Psource2;
|
|
}
|
|
}
|
|
/* End G.CLEMENT 29/07/1999 */
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : divide 32b bitmap Height by 2 (do not take care of zero pixels )
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
/* Begin G.CLEMENT 29/07/1999 : NZ can be non-black */
|
|
void GLI_vDivideBitmapBy2InYNonZero(unsigned long *p_SourceFF,unsigned long *p_DestFF,long lHSurfSouce, long lWSurfSouce, unsigned long ulChromaKey)
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
long lWDest,lHDest,lXCoounter,lYCoounter;
|
|
unsigned long *p_Source,*p_Dest ,Psource1,Psource2;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
lWDest = lWSurfSouce ;
|
|
lHDest = lHSurfSouce >>1;
|
|
|
|
if (lHDest <=1)
|
|
return;
|
|
|
|
p_Source = p_SourceFF;
|
|
p_Dest = p_DestFF;
|
|
|
|
/*for (lYCoounter = 0; lYCoounter < lHDest ; lYCoounter++, p_Source+=lWSurfSouce)
|
|
for (lXCoounter = 0; lXCoounter < lWDest ; lXCoounter++ , p_Dest++ , p_Source+=1)
|
|
{
|
|
Psource1 = *p_Source & 0xfefefefe;
|
|
Psource2 = *(p_Source+lWSurfSouce) & 0xfefefefe;
|
|
if ((Psource1 & 0x00f8f8f8) != 0)
|
|
{
|
|
if ((Psource2 & 0x00f8f8f8) != 0)
|
|
*p_Dest = (Psource1 >> 1) + (Psource2 >> 1);
|
|
else
|
|
*p_Dest = Psource1;
|
|
}
|
|
else
|
|
*p_Dest = Psource2;
|
|
}*/
|
|
for (lYCoounter = 0; lYCoounter < lHDest ; lYCoounter++, p_Source+=lWSurfSouce)
|
|
for (lXCoounter = 0; lXCoounter < lWDest ; lXCoounter++ , p_Dest++ , p_Source+=1)
|
|
{
|
|
Psource1 = *p_Source;
|
|
Psource2 = *(p_Source+lWSurfSouce);
|
|
if ((Psource1 ^ ulChromaKey) & 0x00ffffff) /* 0x00f8f8f8 */
|
|
{
|
|
if ((Psource2 ^ ulChromaKey) & 0x00ffffff) /* 0x00f8f8f8 */
|
|
*p_Dest = ((Psource1 & 0xfefefefe) >> 1) + ((Psource2 & 0xfefefefe) >> 1);
|
|
else
|
|
*p_Dest = Psource1;
|
|
}
|
|
else
|
|
*p_Dest = Psource2;
|
|
}
|
|
}
|
|
/* End G.CLEMENT 29/07/1999 */
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : divide 32b bitmap (width and height) by 2
|
|
!!! Lenght & Width are inverted !!!
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vDivideBitmapSurfaceBy2 (unsigned long *p_SourceFF,unsigned long *p_DestFF,long lWidthSurfSouce, long lLenghtSurfSouce)
|
|
/* !!! Lenght & Width are inverted !!! */
|
|
{
|
|
GLI_vDivideBitmapBy2InX(p_SourceFF,p_DestFF,lWidthSurfSouce, lLenghtSurfSouce);
|
|
GLI_vDivideBitmapBy2InY(p_SourceFF,p_DestFF,lWidthSurfSouce >> 1, lLenghtSurfSouce);
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : divide 32b bitmap (width and height) by 2 (do not take care of zero pixels )
|
|
!!! Lenght & Width are inverted !!!
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
/* Begin G.CLEMENT 29/07/1999 : added chromakey */
|
|
void GLI_vDivideBitmapSurfaceBy2NonZero (unsigned long *p_SourceFF,unsigned long *p_DestFF,long lWidthSurfSouce, long lLenghtSurfSouce, unsigned long ulChromaKey)
|
|
{
|
|
GLI_vDivideBitmapBy2InXNonZero(p_SourceFF,p_DestFF,lWidthSurfSouce, lLenghtSurfSouce, ulChromaKey);
|
|
GLI_vDivideBitmapBy2InYNonZero(p_SourceFF,p_DestFF,lWidthSurfSouce >> 1, lLenghtSurfSouce, ulChromaKey);
|
|
}
|
|
/* End G.CLEMENT 29/07/1999 */
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : divide 8b paletized bitmap (width and height) by 2
|
|
algorithm to have best result
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
#ifdef DREAMCAST
|
|
#pragma inline(GLI_fn_vRGB2YIQ)
|
|
#endif
|
|
|
|
INLINE
|
|
void GLI_fn_vRGB2YIQ( unsigned char *_p_ulRGB, float *_p_fYIQ )
|
|
{
|
|
*_p_fYIQ++ = (float) (0.299 * *(_p_ulRGB + 2) + 0.587 * *(_p_ulRGB + 1) + 0.114 * *_p_ulRGB);
|
|
*_p_fYIQ++ = (float) (0.596 * *(_p_ulRGB + 2) - 0.274 * *(_p_ulRGB + 1) - 0.322 * *_p_ulRGB);
|
|
*_p_fYIQ = (float) (0.211 * *(_p_ulRGB + 2) - 0.522 * *(_p_ulRGB + 1) + 0.311 * *_p_ulRGB);
|
|
}
|
|
|
|
/*
|
|
static inline GLI_fn_vYIQ2RGB( float *_p_fYIQ, unsigned char *_p_ulRGB )
|
|
{
|
|
*_p_ulRGB++ = 1.00 * *_p_fYIQ + 0.956 * *(_p_fYIQ + 1) +0.623 * *(_p_fYIQ + 2);
|
|
*_p_ulRGB++ = 1.00 * *_p_fYIQ - 0.272 * *(_p_fYIQ + 1) -0.648 * *(_p_fYIQ + 2);
|
|
*_p_ulRGB = 1.00 * *_p_fYIQ - 1.105 * *(_p_fYIQ + 1) +0.705 * *(_p_fYIQ + 2);
|
|
}
|
|
*/
|
|
|
|
void GLI_vDivideBitmapSurfaceBy2Palette(unsigned char *_p_ucBitMap,unsigned long *_p_ulPalette,long _lWidth, long _lHeight )
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
long lIndex, lBestIndex;
|
|
float a_fYIQPalette[ 256 ][ 3 ];
|
|
float a_fYIQSum[3];
|
|
float *p_fYIQ, *p_fYIQLast;
|
|
unsigned char *p_ucSrc1, *p_ucSrc2, *p_ucDest, *p_ucEndLine, *p_ucSrcLast;
|
|
float fDiff, fDiffLocal, fBestDiff;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
/*
|
|
* compute palette in YIQ
|
|
*/
|
|
p_ucSrc1 = (unsigned char *) _p_ulPalette;
|
|
p_ucSrcLast = p_ucSrc1 + 1024;
|
|
p_fYIQ = (float *) a_fYIQPalette;
|
|
p_fYIQLast = p_fYIQ + 256 * 3;
|
|
for ( ; p_ucSrc1 < p_ucSrcLast; p_ucSrc1 += 4, p_fYIQ += 3 )
|
|
GLI_fn_vRGB2YIQ( p_ucSrc1, p_fYIQ);
|
|
|
|
p_ucSrc1 = _p_ucBitMap; /* for even line*/
|
|
p_ucSrc2 = _p_ucBitMap + _lWidth; /* for odd line*/
|
|
p_ucDest = _p_ucBitMap;
|
|
p_ucSrcLast = _p_ucBitMap + _lWidth * _lHeight;
|
|
|
|
for ( ; p_ucSrc1 < p_ucSrcLast; p_ucSrc1 += _lWidth, p_ucSrc2 += _lWidth )
|
|
{
|
|
p_ucEndLine = p_ucSrc1 + _lWidth;
|
|
for ( ; p_ucSrc1 < p_ucEndLine; )
|
|
{
|
|
a_fYIQSum[0] = a_fYIQPalette[ *p_ucSrc1 ][0];
|
|
a_fYIQSum[1] = a_fYIQPalette[ *p_ucSrc1 ][1];
|
|
a_fYIQSum[2] = a_fYIQPalette[ *p_ucSrc1++ ][2];
|
|
a_fYIQSum[0] += a_fYIQPalette[ *p_ucSrc1 ][0];
|
|
a_fYIQSum[1] += a_fYIQPalette[ *p_ucSrc1 ][1];
|
|
a_fYIQSum[2] += a_fYIQPalette[ *p_ucSrc1++ ][2];
|
|
a_fYIQSum[0] += a_fYIQPalette[ *p_ucSrc2 ][0];
|
|
a_fYIQSum[1] += a_fYIQPalette[ *p_ucSrc2 ][1];
|
|
a_fYIQSum[2] += a_fYIQPalette[ *p_ucSrc2++ ][2];
|
|
a_fYIQSum[0] = (float) ((a_fYIQSum[0] + a_fYIQPalette[ *p_ucSrc2 ][0]) / 4.);
|
|
a_fYIQSum[1] = (float) ((a_fYIQSum[1] + a_fYIQPalette[ *p_ucSrc2 ][1]) / 4.);
|
|
a_fYIQSum[2] = (float) ((a_fYIQSum[2] + a_fYIQPalette[ *p_ucSrc2++ ][2]) /4.);
|
|
|
|
/*
|
|
* Search better color in palette that fit with average value
|
|
*/
|
|
fBestDiff = 10000.f;
|
|
for ( lIndex = 0, p_fYIQ = (float *) a_fYIQPalette; p_fYIQ < p_fYIQLast; lIndex++ )
|
|
{
|
|
fDiffLocal = a_fYIQSum[0] - *p_fYIQ++;
|
|
fDiff = fDiffLocal * fDiffLocal;
|
|
fDiffLocal = a_fYIQSum[1] - *p_fYIQ++;
|
|
fDiff += fDiffLocal * fDiffLocal;
|
|
fDiffLocal = a_fYIQSum[2] - *p_fYIQ++;
|
|
fDiff += fDiffLocal * fDiffLocal;
|
|
|
|
if (fDiff < fBestDiff)
|
|
{
|
|
lBestIndex = lIndex;
|
|
fBestDiff = fDiff;
|
|
}
|
|
}
|
|
|
|
*p_ucDest++ = (unsigned char) lBestIndex;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
=======================================================================================
|
|
Mirror textures
|
|
=======================================================================================
|
|
*/
|
|
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : mirrored a texture by X
|
|
|
|
_lWidth
|
|
<->
|
|
^ |--x | mirror |--xx--|
|
|
_lHeight | |-x- | ------> |-x--x-|
|
|
v |--x | |--xx--|
|
|
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void TEX_vMirrorX( unsigned long *_p_ulBitmap, long _lWidth, long _lHeight )
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
unsigned long *p_ulLastEndLine, *p_ulEndLine, *p_ulStopLine;
|
|
unsigned long *p_ulDestLineMirror, *p_ulDestLine;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
p_ulLastEndLine = _p_ulBitmap;
|
|
p_ulEndLine = _p_ulBitmap + _lWidth * _lHeight - 1;
|
|
p_ulDestLine = _p_ulBitmap + (_lWidth * 2 * _lHeight ) - _lWidth - 1;
|
|
|
|
while (p_ulEndLine > p_ulLastEndLine )
|
|
{
|
|
p_ulStopLine = p_ulEndLine - _lWidth;
|
|
p_ulDestLineMirror = p_ulDestLine + 1;
|
|
|
|
while (p_ulEndLine > p_ulStopLine )
|
|
{
|
|
*p_ulDestLineMirror++ = *p_ulEndLine;
|
|
*p_ulDestLine-- = *p_ulEndLine--;
|
|
}
|
|
|
|
p_ulEndLine = p_ulStopLine;
|
|
p_ulDestLine -= _lWidth;
|
|
}
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : mirrored a texture by Y, apply an inversion before
|
|
|
|
_lWidth
|
|
<-->
|
|
^ |-XXX| | | |--XX|
|
|
_lHeight v |--XX| inversion | | mirror |-XXX|
|
|
| | ----------> |-XXX| ------> |-XXX|
|
|
| | |--XX| |--XX|
|
|
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void TEX_vMirrorY_WithInversion( unsigned long *_p_ulBitmap, long _lWidth, long _lHeight )
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
unsigned long *p_ulStartCopy, *p_ulDestLine, *p_ulStartLine, *p_ulEndLine, *p_ulCurrent;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
p_ulStartLine = _p_ulBitmap;
|
|
p_ulDestLine = p_ulEndLine = p_ulStartLine + _lWidth * _lHeight;
|
|
while (p_ulStartLine < p_ulEndLine )
|
|
*p_ulDestLine++ = *p_ulStartLine++;
|
|
|
|
p_ulStartCopy = _p_ulBitmap + _lWidth * _lHeight;
|
|
|
|
p_ulDestLine = _p_ulBitmap;
|
|
p_ulEndLine = _p_ulBitmap + (_lWidth * _lHeight * 2);
|
|
p_ulStartLine = p_ulEndLine - _lWidth;
|
|
while (p_ulStartLine >= p_ulStartCopy )
|
|
{
|
|
p_ulCurrent = p_ulStartLine;
|
|
while (p_ulCurrent < p_ulEndLine)
|
|
{
|
|
*p_ulDestLine++ = *p_ulCurrent++;
|
|
}
|
|
|
|
p_ulEndLine = p_ulStartLine;
|
|
p_ulStartLine -= _lWidth;
|
|
}
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : mirrored a texture by Y
|
|
|
|
_lWidth
|
|
<-->
|
|
^ |--XX| |--XX|
|
|
_lHeight v |-XXX| mirror |-XXX|
|
|
| | ------> |-XXX|
|
|
| | |--XX|
|
|
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void TEX_vMirrorY( unsigned long *_p_ulBitmap, long _lWidth, long _lHeight )
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
unsigned long *p_ulDestLine, *p_ulStartLine, *p_ulEndLine, *p_ulCurrent;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
p_ulDestLine = _p_ulBitmap + _lWidth * _lHeight ;
|
|
p_ulEndLine = _p_ulBitmap + (_lWidth * _lHeight );
|
|
p_ulStartLine = p_ulEndLine - _lWidth;
|
|
|
|
while (p_ulStartLine >= _p_ulBitmap )
|
|
{
|
|
p_ulCurrent = p_ulStartLine;
|
|
while (p_ulCurrent < p_ulEndLine)
|
|
{
|
|
*p_ulDestLine++ = *p_ulCurrent++;
|
|
}
|
|
|
|
p_ulEndLine = p_ulStartLine;
|
|
p_ulStartLine -= _lWidth;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
=======================================================================================
|
|
Loading textures
|
|
=======================================================================================
|
|
*/
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : special function to find texture in some other directories
|
|
used only in not final version
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
#if !defined (_FINAL)
|
|
char GLI_cLoadTextureInOtherDirectories( char *szTGAName, char *szGFName, FIL_tdstGF *_p_stHeader, BOOL _bJustInfo )
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
static char szTexturePath[_MAX_PATH];
|
|
static ACP_tdxBool bSecondDirectory = FALSE;
|
|
static char szTexturePath1[_MAX_PATH];
|
|
static ACP_tdxBool bThirdDirectory = FALSE;
|
|
static char cFirst = 1;
|
|
char *subpath;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
if (cFirst)
|
|
{
|
|
cFirst = 0;
|
|
if ( *gsz_Version != 0 )
|
|
{
|
|
bSecondDirectory = TRUE;
|
|
strcpy(szTexturePath, gsz_Version);
|
|
if ( (subpath = strchr(GLI_fn_szGetPathOfTexture(), '\\')) != NULL)
|
|
strcat(szTexturePath, subpath );
|
|
|
|
if ( *gsz_Version1 != 0)
|
|
{
|
|
bThirdDirectory = TRUE;
|
|
strcpy(szTexturePath1, gsz_Version1);
|
|
if ( subpath != NULL)
|
|
strcat(szTexturePath1, subpath );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if ( _bJustInfo )
|
|
{
|
|
if ( bSecondDirectory )
|
|
FIL_fn_vGFLoadInformationFromConcatFile( GLI_g_hConcatTexturesFile, szTexturePath, szGFName, _p_stHeader );
|
|
if ( _p_stHeader->stFileHeader.ucBpp != 0)
|
|
return 1;
|
|
|
|
if ( bThirdDirectory )
|
|
FIL_fn_vGFLoadInformationFromConcatFile( GLI_g_hConcatTexturesFile, szTexturePath1, szGFName, _p_stHeader );
|
|
if ( _p_stHeader->stFileHeader.ucBpp != 0)
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
if (bSecondDirectory)
|
|
FIL_fn_vLoadGFFromConcatFileWithoutInvertPicture( GLI_g_hConcatTexturesFile, szTexturePath, szGFName, _p_stHeader );
|
|
if (_p_stHeader->stFileHeader.ucBpp != 0)
|
|
return 1;
|
|
|
|
if ( bThirdDirectory )
|
|
FIL_fn_vLoadGFFromConcatFileWithoutInvertPicture(GLI_g_hConcatTexturesFile,szTexturePath1,szGFName, _p_stHeader );
|
|
if (_p_stHeader->stFileHeader.ucBpp != 0)
|
|
return 1;
|
|
}
|
|
|
|
|
|
#if defined(_DEBUG)
|
|
if ( _bJustInfo )
|
|
{
|
|
FIL_fn_vTGALoadInformationFromConcatFile(GLI_g_hConcatTexturesFile,GLI_fn_szGetPathOfTexture(),szTGAName, _p_stHeader );
|
|
if ( _p_stHeader->stFileHeader.ucBpp != 0 )
|
|
return 0;
|
|
|
|
if (bSecondDirectory)
|
|
FIL_fn_vTGALoadInformationFromConcatFile(GLI_g_hConcatTexturesFile,szTexturePath,szTGAName, _p_stHeader );
|
|
if ( _p_stHeader->stFileHeader.ucBpp != 0 )
|
|
return 0;
|
|
|
|
if (bThirdDirectory)
|
|
FIL_fn_vTGALoadInformationFromConcatFile(GLI_g_hConcatTexturesFile,szTexturePath1,szTGAName, _p_stHeader);
|
|
}
|
|
else
|
|
{
|
|
FIL_fn_vTGALoadFromConcatFileWithoutInvertPicture(GLI_g_hConcatTexturesFile,GLI_fn_szGetPathOfTexture(),szTGAName,_p_stHeader );
|
|
if (_p_stHeader->stFileHeader.ucBpp != 0)
|
|
return 0;
|
|
|
|
if (bSecondDirectory)
|
|
FIL_fn_vTGALoadFromConcatFileWithoutInvertPicture(GLI_g_hConcatTexturesFile,szTexturePath,szTGAName,_p_stHeader );
|
|
if (_p_stHeader->stFileHeader.ucBpp != 0)
|
|
return 0;
|
|
|
|
if ( bThirdDirectory )
|
|
FIL_fn_vTGALoadFromConcatFileWithoutInvertPicture(GLI_g_hConcatTexturesFile,szTexturePath1,szTGAName,_p_stHeader );
|
|
}
|
|
|
|
if ( _p_stHeader->stFileHeader.ucBpp == 0 )
|
|
{
|
|
FILE *p_stFile;
|
|
|
|
if ((p_stFile=fopen("EngTex.log","at"))!=NULL)
|
|
{
|
|
fprintf(p_stFile,"Can not load : %s\n",szTGAName);
|
|
fclose(p_stFile);
|
|
}
|
|
}
|
|
return 0;
|
|
|
|
#endif /* _DEBUG */
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : Load TGA texture
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
void GLI_xLoadTextureTGA(GLI_tdstTexture *p_stTexture, char *d_ucFileName , long *p_TexelField)
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
long lBad32Detector;
|
|
unsigned long lColumnConvertCounter;
|
|
unsigned long *p_lTexturePtr, *p_lLastTexturePtr;
|
|
unsigned char *p_ucSource;
|
|
char szCompleteName[_MAX_PATH];
|
|
FIL_tdstGF stHeader;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
strcpy(szCompleteName,d_ucFileName);
|
|
strcpy(strrchr(szCompleteName,'.'),".gf");
|
|
FIL_fn_vLoadGFFromConcatFileWithoutInvertPicture(GLI_g_hConcatTexturesFile,GLI_fn_szGetPathOfTexture(),szCompleteName, &stHeader );
|
|
|
|
#if !defined (_FINAL)
|
|
if (stHeader.p_ucBitMap == NULL)
|
|
{
|
|
GLI_cLoadTextureInOtherDirectories( d_ucFileName, szCompleteName, &stHeader, FALSE );
|
|
}
|
|
#endif /* _FINAL */
|
|
|
|
if (stHeader.stFileHeader.ucBpp == 0)
|
|
{
|
|
p_stTexture = NULL;
|
|
return;
|
|
}
|
|
|
|
stHeader.stFileHeader.ucBpp *= 8;
|
|
p_stTexture->lRealWidth = p_stTexture->lWidth = (unsigned short) stHeader.stFileHeader.ulWidth;
|
|
p_stTexture->lRealHeight= p_stTexture->lHeight = (unsigned short) stHeader.stFileHeader.ulHeight;
|
|
|
|
if (stHeader.stFileHeader.ucBpp == 32)
|
|
{
|
|
p_stTexture->lTextureCaps |= GLI_C_lAlphaTexture;
|
|
lBad32Detector = 0xFFFFFFFF;
|
|
p_lTexturePtr = (long *) p_TexelField ;
|
|
|
|
for (lColumnConvertCounter = 0; lColumnConvertCounter < (unsigned long) (p_stTexture->lWidth * p_stTexture->lHeight) ; lColumnConvertCounter ++)
|
|
{
|
|
p_lTexturePtr[lColumnConvertCounter] = (long) stHeader.p_ucBitMap[lColumnConvertCounter*4+2] | (((long) stHeader.p_ucBitMap[lColumnConvertCounter*4+1])<<8) | (((long) stHeader.p_ucBitMap[lColumnConvertCounter*4+0])<<16) | (((long) stHeader.p_ucBitMap[lColumnConvertCounter*4+3])<<24);
|
|
lBad32Detector &= p_lTexturePtr[lColumnConvertCounter];
|
|
}
|
|
if ((lBad32Detector & 0xF0000000) == 0xf0000000)
|
|
p_stTexture->lTextureCaps &= 0xffffffff - GLI_C_lAlphaTexture;
|
|
|
|
if ( (p_stTexture->lTextureCaps & GLI_C_lAlphaTexture) && ( p_stTexture->lTextureCaps & GLI_C_lAddTransparencyTexture) )
|
|
p_stTexture->lTextureCaps &= 0xffffffff - GLI_C_lAddTransparencyTexture;
|
|
}
|
|
else if (stHeader.stFileHeader.ucBpp == 24)
|
|
{
|
|
p_lTexturePtr = (long * )p_TexelField;
|
|
p_lLastTexturePtr = p_lTexturePtr + p_stTexture->lWidth * p_stTexture->lHeight;
|
|
p_ucSource = stHeader.p_ucBitMap;
|
|
|
|
for ( ; p_lTexturePtr < p_lLastTexturePtr ;p_lTexturePtr++)
|
|
{
|
|
*p_lTexturePtr = (long) *(p_ucSource + 2) | (((long) *(p_ucSource + 1))<<8) | (((long) *p_ucSource)<<16);
|
|
p_ucSource += 3;
|
|
}
|
|
}
|
|
else if (stHeader.stFileHeader.ucBpp == 8)
|
|
{
|
|
if (GLI_g_stCaps.ulTextureCaps & GLICAPS_TEX_C_ulSupport8P)
|
|
{
|
|
unsigned char *p_ucColorTable;
|
|
unsigned char *p_ucLast;
|
|
|
|
p_lTexturePtr = (long * )p_TexelField;
|
|
p_stTexture->p_vColorTable = stHeader.p_ucPalette;
|
|
/* Copy loaded palette to temp texture palette*/
|
|
/* p_stTexture->p_vColorTable = TMP_M_p_Malloc(256*sizeof(RGBQUAD));
|
|
memcpy(p_stTexture->p_vColorTable,stHeader.p_ucBitMap,256*sizeof(RGBQUAD)); */
|
|
p_ucColorTable = ((unsigned char *) p_stTexture->p_vColorTable + 3);
|
|
p_ucLast = p_ucColorTable + 256*sizeof(RGBQUAD);
|
|
for ( ; p_ucColorTable < p_ucLast; p_ucColorTable += 4 )
|
|
{
|
|
*p_ucColorTable = 0xFF;
|
|
}
|
|
/* Copy loaded bitmap to TexelField*/
|
|
memcpy(p_lTexturePtr,stHeader.p_ucBitMap/*+256*sizeof(RGBQUAD)*/,p_stTexture->lHeight*p_stTexture->lWidth*stHeader.stFileHeader.ucBpp/8);
|
|
}
|
|
else
|
|
{
|
|
/* driver doesn't support 8 bit paletized texture, transform it*/
|
|
unsigned char *p_cPtr;
|
|
unsigned long *p_lColorTable = p_stTexture->p_vColorTable;
|
|
unsigned char ucSave;
|
|
|
|
p_lTexturePtr = (long * )p_TexelField;
|
|
|
|
#ifdef USE_DIRECTX
|
|
p_stTexture->p_vColorTable = stHeader.p_ucPalette;
|
|
p_lColorTable = p_stTexture->p_vColorTable;
|
|
#endif
|
|
/* p_lColorTable=TMP_M_p_Malloc(256*4);*/
|
|
|
|
/* Copy loaded palette to temp texture palette*/
|
|
/*memcpy(p_lColorTable,stHeader.p_ucBitMap,(256*4));*/
|
|
for (lColumnConvertCounter = 0; lColumnConvertCounter < 256; lColumnConvertCounter++)
|
|
{
|
|
ucSave = *((unsigned char *) &p_lColorTable[lColumnConvertCounter]);
|
|
*(((unsigned char *) &p_lColorTable[lColumnConvertCounter]) + 0) = *(((unsigned char *) &p_lColorTable[lColumnConvertCounter]) + 2);
|
|
*(((unsigned char *) &p_lColorTable[lColumnConvertCounter]) + 2) = ucSave;
|
|
}
|
|
|
|
p_cPtr = (char *)stHeader.p_ucBitMap;
|
|
for (lColumnConvertCounter = 0;lColumnConvertCounter < (unsigned long) (p_stTexture -> lWidth * p_stTexture -> lHeight) ;lColumnConvertCounter ++, p_cPtr ++)
|
|
p_lTexturePtr[lColumnConvertCounter] = p_lColorTable[ *p_cPtr ];
|
|
|
|
//TMP_M_Free(p_lColorTable);
|
|
}
|
|
}
|
|
else
|
|
TEX_M_ERROR(d_ucFileName);
|
|
|
|
FIL_fn_vTGAFree(&stHeader.p_ucBitMap);
|
|
}
|
|
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : Load header of TGA file
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
long TEX_fnl_LoadHeaderTextureTGA(GLI_tdstTexture *_pst_Texture, char *d_ucFileName, long lTextureCaps, long lTextureQuality)
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
FIL_tdstGF stHeader;
|
|
char szCompleteName[_MAX_PATH];
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
_pst_Texture->lTextureCaps = lTextureCaps;
|
|
|
|
strcpy(szCompleteName,d_ucFileName);
|
|
strcpy(strrchr(szCompleteName,'.'),".gf");
|
|
FIL_fn_vGFLoadInformationFromConcatFile(GLI_g_hConcatTexturesFile,GLI_fn_szGetPathOfTexture(),szCompleteName, &stHeader );
|
|
|
|
#if !defined (_FINAL)
|
|
if (stHeader.stFileHeader.ucBpp == 0)
|
|
GLI_cLoadTextureInOtherDirectories( d_ucFileName, szCompleteName, &stHeader, TRUE );
|
|
|
|
if ( stHeader.stFileHeader.ucBpp == 0 )
|
|
{
|
|
FILE *p_stFile;
|
|
|
|
if ((p_stFile=fopen("EngTex.log","at"))!=NULL)
|
|
{
|
|
fprintf(p_stFile,"Missing : %s\n",d_ucFileName);
|
|
fclose(p_stFile);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
if (stHeader.stFileHeader.ucBpp == 0)
|
|
return 0;
|
|
|
|
_pst_Texture->lRealWidth = _pst_Texture->lWidth = (unsigned short) stHeader.stFileHeader.ulWidth;
|
|
_pst_Texture->lRealHeight = _pst_Texture->lHeight = (unsigned short) stHeader.stFileHeader.ulHeight;
|
|
|
|
strcpy( _pst_Texture->a255_cFileName, d_ucFileName);
|
|
|
|
GLI_vAssertTexture( _pst_Texture );
|
|
|
|
if ( (stHeader.stFileHeader.ucBpp == 1) && (GLI_g_stCaps.ulTextureCaps & GLICAPS_TEX_C_ulSupport8P) )
|
|
_pst_Texture->lTextureCaps |= GLI_C_lPaletteTexture;
|
|
if (stHeader.stFileHeader.ucBpp == 4)
|
|
_pst_Texture->lTextureCaps |= GLI_C_lAlphaTexture;
|
|
}
|
|
|
|
|
|
/*
|
|
=======================================================================================
|
|
BMP Files
|
|
=======================================================================================
|
|
*/
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : Load Header of BMP file
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
long TEX_fnl_LoadHeaderTextureBMP( GLI_tdstTexture *_pst_Texture, char *d_ucFileName, long lTextureCaps, long lTextureQuality)
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
char ucBBP;
|
|
char szCompleteName[_MAX_PATH];
|
|
unsigned long ulWidth, ulHeight;
|
|
FIL_tdstGF stHeader;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
strcpy(szCompleteName,d_ucFileName);
|
|
strcpy(strrchr(szCompleteName,'.'),".gf");
|
|
|
|
FIL_fn_vGFLoadInformationFromConcatFile(GLI_g_hConcatTexturesFile,GLI_fn_szGetPathOfTexture(),szCompleteName,&stHeader );
|
|
ucBBP = stHeader.stFileHeader.ucBpp;
|
|
ulWidth = stHeader.stFileHeader.ulWidth;
|
|
ulHeight = stHeader.stFileHeader.ulHeight;
|
|
|
|
|
|
#if defined(_DEBUG)
|
|
if (ucBBP ==0 )
|
|
FIL_fn_vLoadBMPInformationFromConcatFile(GLI_g_hConcatTexturesFile,GLI_fn_szGetPathOfTexture(),d_ucFileName,&ucBBP,&ulWidth,&ulHeight );
|
|
|
|
if ( ucBBP == 0 )
|
|
{
|
|
FILE *p_stFile;
|
|
|
|
if ((p_stFile=fopen("EngTex.log","at"))!=NULL)
|
|
{
|
|
fprintf(p_stFile,"Missing : %s\n",d_ucFileName);
|
|
fclose(p_stFile);
|
|
}
|
|
}
|
|
#endif /* _DEBUG */
|
|
|
|
if (ucBBP ==0 )
|
|
return 0;
|
|
|
|
strcpy( _pst_Texture->a255_cFileName, d_ucFileName);
|
|
|
|
_pst_Texture->lRealWidth = _pst_Texture->lWidth = (unsigned short) ulWidth;
|
|
_pst_Texture->lRealHeight = _pst_Texture->lHeight = (unsigned short) ulHeight;
|
|
|
|
GLI_vAssertTexture( _pst_Texture );
|
|
|
|
_pst_Texture->lTextureCaps = lTextureCaps;
|
|
if (ucBBP == 4)
|
|
_pst_Texture->lTextureCaps |= GLI_C_lAlphaTexture;
|
|
if (ucBBP == 1)
|
|
_pst_Texture->lTextureCaps |= GLI_C_lPaletteTexture;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : Load BMP file
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_xLoadTextureBMP(GLI_tdstTexture *p_stTexture, char *d_ucFileName , long *p_TexelField)
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
char ucBBP;
|
|
unsigned long ulWidth, ulHeight;
|
|
long lBad32Detector;
|
|
unsigned long lColumnConvertCounter;
|
|
unsigned long *p_lTexturePtr;
|
|
unsigned char *pDEF_ucReadBuffer=NULL;
|
|
char szCompleteName[_MAX_PATH];
|
|
FIL_tdstGF stHeader;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
strcpy(szCompleteName,d_ucFileName);
|
|
strcpy(strrchr(szCompleteName,'.'),".gf");
|
|
|
|
FIL_fn_vLoadGFFromConcatFileWithoutInvertPicture(GLI_g_hConcatTexturesFile,GLI_fn_szGetPathOfTexture(),szCompleteName,&stHeader );
|
|
ucBBP = stHeader.stFileHeader.ucBpp;
|
|
ulWidth = stHeader.stFileHeader.ulWidth;
|
|
ulHeight = stHeader.stFileHeader.ulHeight;
|
|
pDEF_ucReadBuffer = stHeader.p_ucBitMap;
|
|
|
|
#if defined(_DEBUG)
|
|
if (pDEF_ucReadBuffer == NULL)
|
|
FIL_fn_vLoadBMPFromConcatFileWithoutInvertPicture(GLI_g_hConcatTexturesFile,GLI_fn_szGetPathOfTexture(),d_ucFileName,&pDEF_ucReadBuffer,&ucBBP,&ulWidth,&ulHeight);
|
|
#endif /* _DEBUG */
|
|
|
|
if (pDEF_ucReadBuffer!=NULL)
|
|
{
|
|
ucBBP*=8;
|
|
p_stTexture->lRealWidth = p_stTexture->lWidth = (unsigned short) ulWidth;
|
|
p_stTexture->lRealHeight = p_stTexture->lHeight = (unsigned short) ulHeight;
|
|
|
|
if (ucBBP == 32)
|
|
{
|
|
p_stTexture -> lTextureCaps |= GLI_C_lAlphaTexture;
|
|
lBad32Detector = 0xFFFFFFFF;
|
|
p_lTexturePtr = (long * )p_TexelField ;
|
|
for (lColumnConvertCounter = 0; lColumnConvertCounter < (unsigned long) (p_stTexture -> lWidth * p_stTexture -> lHeight) ; lColumnConvertCounter ++)
|
|
{
|
|
p_lTexturePtr[lColumnConvertCounter] =
|
|
(long) pDEF_ucReadBuffer[lColumnConvertCounter*4+2] |
|
|
(((long) pDEF_ucReadBuffer[lColumnConvertCounter*4+1])<<8) |
|
|
(((long) pDEF_ucReadBuffer[lColumnConvertCounter*4+0])<<16) |
|
|
(((long) pDEF_ucReadBuffer[lColumnConvertCounter*4+3])<<24);
|
|
lBad32Detector &= p_lTexturePtr[lColumnConvertCounter];
|
|
}
|
|
if ((lBad32Detector & 0xF0000000) == 0xf0000000)
|
|
p_stTexture -> lTextureCaps &= 0xffffffff - GLI_C_lAlphaTexture;
|
|
}
|
|
else if (ucBBP == 24)
|
|
{
|
|
p_lTexturePtr = (long * )p_TexelField;
|
|
for (lColumnConvertCounter = 0;lColumnConvertCounter < (unsigned long) (p_stTexture -> lWidth * p_stTexture -> lHeight) ;lColumnConvertCounter ++)
|
|
p_lTexturePtr[lColumnConvertCounter] = (long) pDEF_ucReadBuffer[lColumnConvertCounter*3+2] | (((long) pDEF_ucReadBuffer[lColumnConvertCounter*3+1])<<8) | (((long) pDEF_ucReadBuffer[lColumnConvertCounter*3+0])<<16);
|
|
}
|
|
else if (ucBBP == 8)
|
|
{
|
|
p_stTexture -> lTextureCaps |= GLI_C_lPaletteTexture;
|
|
p_lTexturePtr = (long * )p_TexelField;
|
|
MMG_fn_vAddMemoryInfo (MMG_C_lTypeGLI , MMG_C_lSubTypeTexture , NULL);
|
|
p_stTexture->p_vColorTable=TMP_M_p_Malloc(256*sizeof(RGBQUAD));
|
|
/* Copy loaded palette to temp texture palette*/
|
|
memcpy(p_stTexture->p_vColorTable,pDEF_ucReadBuffer,256*sizeof(RGBQUAD));
|
|
/* Copy loaded bitmap to TexelField*/
|
|
memcpy(p_lTexturePtr,pDEF_ucReadBuffer+256*sizeof(RGBQUAD),p_stTexture->lHeight*p_stTexture->lWidth*ucBBP);
|
|
}
|
|
else
|
|
TEX_M_ERROR(d_ucFileName);
|
|
}
|
|
else
|
|
{
|
|
p_stTexture = NULL;
|
|
#if defined(_DEBUG)
|
|
{
|
|
FILE *p_stFile;
|
|
if ((p_stFile=fopen("EngTex.log","at"))!=NULL)
|
|
{
|
|
fprintf(p_stFile,"Can not load : %s\n",d_ucFileName);
|
|
fclose(p_stFile);
|
|
}
|
|
}
|
|
#endif /* _DEBUG */
|
|
}
|
|
|
|
FIL_fn_vTGAFree(&pDEF_ucReadBuffer);
|
|
}
|
|
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : analyse texture name and load texture header to set texture parameters
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
long TEX_fnl_LoadTextureParameters(GLI_tdstTexture **h_stTexture, char *d_ucFileName, long lTextureCaps, long lTextureQuality)
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
unsigned char ucCyclingMode;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
if ( ( h_stTexture == NULL ) || (*h_stTexture == NULL) )
|
|
return 0;
|
|
|
|
if ( GLI_fn_lAnalyseTextureName( d_ucFileName, &lTextureCaps, &ucCyclingMode ) == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if ( lTextureCaps & GLI_C_lBMPTexture)
|
|
{
|
|
if ( !TEX_fnl_LoadHeaderTextureBMP( *h_stTexture, d_ucFileName, lTextureCaps, lTextureQuality) )
|
|
return 0;
|
|
}
|
|
else if (lTextureCaps & GLI_C_lTGATexture)
|
|
{
|
|
if (!TEX_fnl_LoadHeaderTextureTGA( *h_stTexture, d_ucFileName,lTextureCaps, lTextureQuality) )
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* if texture mirror in case they are not supported
|
|
*/
|
|
if ( (ucCyclingMode & GLI_C_lMirrorUV) && !(GLI_g_stCaps.ulTextureCaps & GLICAPS_TEX_C_ulSupportMirror) )
|
|
{
|
|
if (ucCyclingMode & GLI_C_lMirrorU)
|
|
{
|
|
(*h_stTexture)->lWidth *= 2;
|
|
(*h_stTexture)->lRealWidth *= 2;
|
|
}
|
|
if (ucCyclingMode & GLI_C_lMirrorV)
|
|
{
|
|
(*h_stTexture)->lHeight *= 2;
|
|
(*h_stTexture)->lRealHeight *= 2;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* special for texture maa : double texture use to do multitexture with Ultra64
|
|
*/
|
|
if ( lTextureCaps & GLI_C_lMAATexture )
|
|
{
|
|
(*h_stTexture)->lHeight /= 2;
|
|
(*h_stTexture)->lRealHeight /= 2;
|
|
}
|
|
|
|
/*
|
|
* VL : we set Cycling mode of texture with the one we found in the name of file
|
|
* we keep the 4 high bit of cycling mode because we have to keep bit 5 :
|
|
* ---X000 : indicate that texture is a texture used for shadow drawing
|
|
*/
|
|
(*h_stTexture)->ucCylingMode = ((*h_stTexture)->ucCylingMode & 0xF0) | ucCyclingMode;
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : Create new texture and set its parameters
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_xLoadTexture(GLI_tdstTexture **h_stTexture, GLD_tdstDeviceAttributes *p_stDev, char *d_ucFileName, long lTextureCaps, long lTextureQuality)
|
|
{
|
|
char szTextureName[ 256 ];
|
|
|
|
TEX_fnv_FixTextureName( szTextureName, d_ucFileName );
|
|
|
|
(*h_stTexture) = TEX_fnpst_DoesTextureExist( szTextureName );
|
|
if ((*h_stTexture) != NULL)
|
|
return;
|
|
|
|
GLI_xCreateTexture ( h_stTexture );
|
|
if ( !TEX_fnl_LoadTextureParameters(h_stTexture, szTextureName, lTextureCaps, lTextureQuality) )
|
|
return;
|
|
|
|
TEX_fnv_MakeItExisting( (*h_stTexture) );
|
|
}
|
|
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : set texture parameters and make texture existing
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_xLoadTextureHeader(GLI_tdstTexture **h_stTexture, GLD_tdstDeviceAttributes *p_stDev, char *d_ucFileName, long lTextureCaps, long lTextureQuality)
|
|
{
|
|
if ((*h_stTexture) == NULL)
|
|
return ;
|
|
|
|
if ( !TEX_fnl_LoadTextureParameters(h_stTexture, d_ucFileName, lTextureCaps, lTextureQuality) )
|
|
return;
|
|
|
|
TEX_fnv_MakeItExisting( (*h_stTexture) );
|
|
}
|
|
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : load texture bitmap data
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_xLoadTextureInTexelField(GLI_tdstTexture *p_stTexture, long *p_lTexelField, BOOL bReloading)
|
|
{
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
unsigned short lWidth,lHeight;
|
|
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
|
|
|
if (p_stTexture == NULL)
|
|
return;
|
|
|
|
/*
|
|
* progress bar information
|
|
*/
|
|
GLI_g_ulNumberOfLoadedTexture++;
|
|
|
|
if (!bReloading) {
|
|
/* No progress bar for textures in binary load mode*/
|
|
if( SNA_fn_ucGetLoadType() != SNA_LOAD_SNAPSHOT )
|
|
if (!(GLI_g_ulNumberOfLoadedTexture%20))
|
|
VIG_fn_vAddToProgressBar(1);
|
|
}
|
|
|
|
/*
|
|
* keep compression information
|
|
*/
|
|
lWidth = p_stTexture->lWidth;
|
|
lHeight = p_stTexture->lHeight;
|
|
|
|
/*
|
|
* load texture bitmap
|
|
*/
|
|
if ( p_stTexture->lTextureCaps & GLI_C_lTGATexture)
|
|
GLI_xLoadTextureTGA(p_stTexture, p_stTexture->a255_cFileName, p_lTexelField);
|
|
else if ( p_stTexture->lTextureCaps & GLI_C_lBMPTexture)
|
|
GLI_xLoadTextureBMP(p_stTexture, p_stTexture->a255_cFileName, p_lTexelField);
|
|
else
|
|
return;
|
|
|
|
p_stTexture->p_vBitMap = p_lTexelField;
|
|
|
|
/*
|
|
* restore compression information
|
|
*/
|
|
p_stTexture->lHeight = lHeight;
|
|
p_stTexture->lWidth = lWidth;
|
|
|
|
/*
|
|
* special thing to do with texture reserved for shadow
|
|
*/
|
|
if ( p_stTexture->ucCylingMode & GLI_C_lSpecialMirrorForShadow )
|
|
p_stTexture->ucCylingMode |= GLI_C_lMirrorUV;
|
|
|
|
/*
|
|
* in case of mirror texture and if mirror texture are not supported
|
|
*/
|
|
if ( ( p_stTexture->ucCylingMode & GLI_C_lMirrorUV ) && !(GLI_g_stCaps.ulTextureCaps & GLICAPS_TEX_C_ulSupportMirror))
|
|
{
|
|
/*
|
|
* Mirror X/U
|
|
*/
|
|
if (p_stTexture->ucCylingMode & GLI_C_lMirrorU )
|
|
{
|
|
if ( p_stTexture->ucCylingMode & GLI_C_lSpecialMirrorForShadow )
|
|
p_stTexture->ucCylingMode &= ~GLI_C_lMirrorU;
|
|
|
|
p_stTexture->ucCylingMode |= GLI_C_lCylingU;
|
|
TEX_vMirrorX( p_lTexelField, p_stTexture->lRealWidth, p_stTexture->lRealHeight );
|
|
p_stTexture->lRealWidth *= 2;
|
|
}
|
|
|
|
/*
|
|
* Mirror Y/V
|
|
*/
|
|
if (p_stTexture->ucCylingMode & GLI_C_lMirrorV )
|
|
{
|
|
p_stTexture->ucCylingMode |= GLI_C_lCylingV;
|
|
|
|
if ( p_stTexture->ucCylingMode & GLI_C_lSpecialMirrorForShadow )
|
|
{
|
|
p_stTexture->ucCylingMode &= ~GLI_C_lMirrorV;
|
|
TEX_vMirrorY( p_lTexelField, p_stTexture->lRealWidth, p_stTexture->lRealHeight );
|
|
}
|
|
else
|
|
{
|
|
TEX_vMirrorY_WithInversion( p_lTexelField, p_stTexture->lRealWidth, p_stTexture->lRealHeight );
|
|
}
|
|
|
|
p_stTexture->lRealHeight *= 2;
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
* special for texture maa : double texture use to do multitexture with Ultra64
|
|
*/
|
|
if ( p_stTexture->lTextureCaps & GLI_C_lMAATexture )
|
|
{
|
|
p_stTexture->lRealHeight /= 2;
|
|
memmove( p_lTexelField, p_lTexelField + p_stTexture->lRealHeight * p_stTexture->lRealWidth , p_stTexture->lRealHeight * p_stTexture->lRealWidth * 4);
|
|
}
|
|
|
|
/*
|
|
* Compress texelfield
|
|
*/
|
|
lHeight = p_stTexture->lRealHeight;
|
|
lWidth = p_stTexture->lRealWidth;
|
|
|
|
if ( p_stTexture->lTextureCaps & GLI_C_lNZTexture )
|
|
{
|
|
while (lWidth > p_stTexture->lWidth)
|
|
{
|
|
GLI_vDivideBitmapBy2InXNonZero(p_lTexelField, p_lTexelField, lHeight, lWidth, p_stTexture->lChromakeyColorRGBA); /* G.CLEMENT 29/07/1999 : added chromakey */
|
|
lWidth >>= 1;
|
|
}
|
|
while (lHeight > p_stTexture->lHeight)
|
|
{
|
|
GLI_vDivideBitmapBy2InYNonZero(p_lTexelField, p_lTexelField, lHeight, lWidth, p_stTexture->lChromakeyColorRGBA); /* G.CLEMENT 29/07/1999 : added chromakey */
|
|
lHeight >>= 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (lWidth > p_stTexture->lWidth)
|
|
{
|
|
GLI_vDivideBitmapBy2InX(p_lTexelField, p_lTexelField, lHeight ,lWidth );
|
|
lWidth >>= 1;
|
|
}
|
|
while (lHeight > p_stTexture->lHeight)
|
|
{
|
|
GLI_vDivideBitmapBy2InY(p_lTexelField, p_lTexelField, lHeight, lWidth );
|
|
lHeight >>= 1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* other filterings
|
|
*/
|
|
if ( (p_stTexture->lTextureCaps & GLI_C_lAlphaTest) || ( (p_stTexture->lTextureCaps & GLI_C_lNZTexture) && (GLI_g_stCaps.ulDriverCaps & GLICAPS_DRV_C_ulSupportAlphaTest ) ) )
|
|
{
|
|
GLI_fn_vFilterNZForAlphaTest( p_lTexelField, p_stTexture->lWidth, p_stTexture->lHeight, p_stTexture->lChromakeyColorRGBA );
|
|
p_stTexture->lTextureCaps &= 0xFFFFFFFF - GLI_C_lNZTexture - GLI_C_lNZFilteredTexture;
|
|
p_stTexture->lTextureCaps |= GLI_C_lAlphaTest;
|
|
}
|
|
else
|
|
{
|
|
if ((!(p_stTexture -> lTextureCaps & GLI_C_lAlphaTexture)) && (p_stTexture -> lTextureCaps & GLI_C_lNZFilteredTexture))
|
|
GLI_vComputeNZFiltering ( p_stTexture , p_lTexelField);
|
|
}
|
|
}
|
|
|
|
/*
|
|
=======================================================================================
|
|
Mipmap LOD function
|
|
=======================================================================================
|
|
*/
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : load mipmap LOD and add it to texture
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vLoadLodAndAddItToTexture(GLI_tdstTexture *p_stTexture, GLD_tdstDeviceAttributes *p_stDev,char *d_ucFileName, long lTextureCaps, long lTextureQuality)
|
|
{
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : compute LOD (just set texture as texture with Mipmap LOD)
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vComputeLod(GLI_tdstTexture *p_stTexture)
|
|
{
|
|
p_stTexture -> lNumberOfLod = 1;
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : compute LOD
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vRealyComputeLod(GLI_tdstTexture *p_stTexture)
|
|
{
|
|
/* Compute Number of LOD*/
|
|
if ( (p_stTexture->lHeight<=1) || (p_stTexture -> lWidth <= 1) )
|
|
return;
|
|
|
|
if ( GLI_lGetLog2n(p_stTexture -> lHeight) < GLI_lGetLog2n(p_stTexture -> lWidth) )
|
|
p_stTexture -> lNumberOfLod = GLI_lGetLog2n(p_stTexture -> lHeight) + 1;
|
|
else
|
|
p_stTexture -> lNumberOfLod = GLI_lGetLog2n(p_stTexture -> lWidth) + 1;
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : compute LOD of all textures
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void TEX_fn_vComputeLODForAllTextures( void )
|
|
{
|
|
long lTextureCounter;
|
|
|
|
for (lTextureCounter =0 ; lTextureCounter < GLI_C_lNBMaxOfTextures; lTextureCounter ++)
|
|
{
|
|
if (gs_aDEFTableOfTextureMemoryChannels[ lTextureCounter ] != GLI_TEXIsUnallocated)
|
|
{
|
|
if (gs_aDEFTableOfTextureAlreadyRead [lTextureCounter] -> lNumberOfLod != 0)
|
|
{
|
|
GLI_vRealyComputeLod(gs_aDEFTableOfTextureAlreadyRead[ lTextureCounter ]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
=======================================================================================
|
|
Function to unload / download all textures
|
|
=======================================================================================
|
|
*/
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : Compute textures :
|
|
Init (init tree name and unload/uncompress textures)
|
|
compute compression
|
|
Compute LOD and download textures
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vComputeTextures ()
|
|
{
|
|
|
|
TEXBENCH_fn_vInitTextureSize();
|
|
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cBeginUnload );
|
|
GLI_vUnloadTexture();
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cEndUnload );
|
|
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cBeginUncompress );
|
|
GLI_vUnCompressExistantTexture();
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cEndUncompress );
|
|
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cBeginCompression );
|
|
TEX_lComputeCompression();
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cEndcompression );
|
|
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cBeginComputeLod );
|
|
TEX_fn_vComputeLODForAllTextures();
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cEndComputeLod );
|
|
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cBeginDownload );
|
|
GLI_vDownLoadTexture(FALSE);
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cEndDownload );
|
|
|
|
TEXBENCH_fn_vWriteSizeInFile();
|
|
MATBENCH_fn_vWriteMaterialInfoInFile( "After download texture" );
|
|
}
|
|
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : Unload all textures
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vUnloadTexture(void)
|
|
{
|
|
GLI_DRV_vUnLoadTextures();
|
|
//GLITEXT_fnv_Close();
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : Alloc loading bloc ( alarge bloc that will contain the bigest texture)
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vAllocLoadingBloc()
|
|
{
|
|
GLI_gs_lConvertBufferMipMappingSizeInBytes = GLI_lGetBigestSizeOfTexture();
|
|
if (GLI_gs_lConvertBufferMipMappingSizeInBytes != 0)
|
|
{
|
|
MMG_fn_vAddMemoryInfo (MMG_C_lTypeGLI , MMG_C_lSubTypeMipMapping , NULL);
|
|
GLI_gs_p_ConvertBufferMipMapping = TMP_M_p_Malloc(GLI_gs_lConvertBufferMipMappingSizeInBytes);
|
|
GLI_DRV_lSendDataToDll("ConvertBufferMipMapping", GLI_gs_p_ConvertBufferMipMapping);
|
|
}
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : Free loading bloc
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vUnAllocLoadingBloc()
|
|
{
|
|
if (GLI_gs_lConvertBufferMipMappingSizeInBytes != 0)
|
|
TMP_M_Free(GLI_gs_p_ConvertBufferMipMapping);
|
|
|
|
FIL_fn_vFreeGlobalHandleToFileInConcatFile();
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : Load all textures
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vDownLoadTexture(BOOL bReloading)
|
|
{
|
|
|
|
/*
|
|
* initialize text data (for raster display) in retail mode this line does nothing
|
|
*/
|
|
GLITEXT_fnv_Init();
|
|
|
|
/*
|
|
* Init
|
|
*/
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cBeginDownload1 );
|
|
GLI_vAllocLoadingBloc();
|
|
FIL_fn_vInitGlobalHandleToFileInConcatFile();
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cEndDownload1 );
|
|
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cBeginDownload2 );
|
|
GLI_g_ulNumberOfLoadedTexture = 0;
|
|
GLI_DRV_vDownLoadTextures(0, GLI_lGetTextureMode(), bReloading );
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cEndDownload2 );
|
|
|
|
/*
|
|
* end
|
|
*/
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cBeginDownload3 );
|
|
GLI_vUnAllocLoadingBloc();
|
|
FIL_fn_vFreeGlobalHandleToFileInConcatFile();
|
|
TEXBENCH_fn_vSetTime( TEXBENCH_C_cEndDownload3 );
|
|
}
|
|
|
|
/*
|
|
----------------------------------------------------------------------------------------
|
|
Description : Load all textures
|
|
----------------------------------------------------------------------------------------
|
|
*/
|
|
void GLI_vReloadTextures(void)
|
|
{
|
|
GLI_vDownLoadTexture(TRUE);
|
|
}
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|