804 lines
24 KiB
C++
804 lines
24 KiB
C++
//**************************************************************
|
||
//* OpenGLide - Glide to OpenGL Wrapper
|
||
//* http://openglide.sourceforge.net
|
||
//*
|
||
//* Glide Texture Functions
|
||
//*
|
||
//* OpenGLide is OpenSource under LGPL license
|
||
//* Originaly made by Fabio Barros
|
||
//* Modified by Paul for Glidos (http://www.glidos.net)
|
||
//* Mac version and additional features by Jens-Olaf Hemprich
|
||
//**************************************************************
|
||
|
||
#include "GlideSettings.h"
|
||
#include "GLextensions.h"
|
||
#include "GLRender.h"
|
||
#include "GLRenderUpdateState.h"
|
||
#include "PGTexture.h"
|
||
#include "PGUTexture.h"
|
||
|
||
|
||
// Functions
|
||
|
||
//*************************************************
|
||
//* Return the lowest start address for texture downloads
|
||
//*************************************************
|
||
FX_ENTRY FxU32 FX_CALL
|
||
grTexMinAddress( GrChipID_t tmu )
|
||
{
|
||
#ifdef OGL_DONE
|
||
GlideMsg( "grTexMinAddress( %d ) = 0\n", tmu );
|
||
#endif
|
||
|
||
return (FxU32) 0;
|
||
}
|
||
|
||
//*************************************************
|
||
//* Return the highest start address for texture downloads
|
||
//*************************************************
|
||
FX_ENTRY FxU32 FX_CALL
|
||
grTexMaxAddress( GrChipID_t tmu )
|
||
{
|
||
#ifdef OGL_DONE
|
||
GlideMsg( "grTexMaxAddress( %d ) = %lu\n", tmu, Glide.TexMemoryMaxPosition );
|
||
#endif
|
||
|
||
return (FxU32)( Glide.TexMemoryMaxPosition );
|
||
}
|
||
|
||
//*************************************************
|
||
//* Specify the current texture source for rendering
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexSource( GrChipID_t tmu,
|
||
FxU32 startAddress,
|
||
FxU32 evenOdd,
|
||
GrTexInfo *info )
|
||
{
|
||
#ifdef OPTIMISE_GLIDE_STATE_CHANGES
|
||
const GrTexInfo* current = Textures->GetCurrentTexInfo();
|
||
#endif
|
||
CHECK_STATE_CHANGED(Glide.State.TexSource.StartAddress == startAddress &&
|
||
Glide.State.TexSource.EvenOdd == evenOdd &&
|
||
current->aspectRatio == info->aspectRatio &&
|
||
current->format == info->format &&
|
||
current->largeLod == info->largeLod &&
|
||
current->smallLod == info->smallLod);
|
||
|
||
#ifdef OGL_PARTDONE
|
||
GlideMsg("grTexSource( %d, 0x%x, 0x%x, (%u, %u, ar=%u, fmt=%u) )\n",
|
||
tmu, startAddress, evenOdd,
|
||
info->smallLod, info->largeLod, info->aspectRatio, info->format);
|
||
#endif
|
||
|
||
// We're emulating tmu0 only
|
||
if ( tmu != GR_TMU0 )
|
||
{
|
||
return;
|
||
}
|
||
|
||
#ifdef OGL_DEBUG
|
||
if((startAddress & 7 ) != 0 || startAddress < 0 || startAddress > Glide.TexMemoryMaxPosition)
|
||
{
|
||
if (startAddress != GR_NULL_MIPMAP_HANDLE)
|
||
{
|
||
GlideMsg("Warning: grTexSource(%d, %d, %d, xxx) invalid startAddress\n", tmu, startAddress, evenOdd);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
RenderDrawTriangles();
|
||
Glide.State.TexSource.StartAddress = startAddress;
|
||
Glide.State.TexSource.EvenOdd = evenOdd;
|
||
Textures->Source( startAddress, evenOdd, info );
|
||
}
|
||
|
||
//*************************************************
|
||
//* Return the texture memory consumed by a texture
|
||
//*************************************************
|
||
FX_ENTRY FxU32 FX_CALL
|
||
grTexTextureMemRequired( FxU32 dwEvenOdd, GrTexInfo *texInfo )
|
||
{
|
||
#ifdef OGL_DONE
|
||
GlideMsg( "grTexTextureMemRequired( %u, --- )\n", dwEvenOdd );
|
||
#endif
|
||
|
||
return Textures->TextureMemRequired( dwEvenOdd, texInfo );
|
||
}
|
||
|
||
//*************************************************
|
||
//* Return the texture memory consumed by a texture
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexDownloadMipMap( GrChipID_t tmu,
|
||
FxU32 startAddress,
|
||
FxU32 evenOdd,
|
||
GrTexInfo *info )
|
||
{
|
||
#ifdef OGL_PARTDONE
|
||
GlideMsg( "grTexDownloadMipMap(%d, 0x%x, 0x%x, (%u, %u, ar=%u, fmt=%u) )\n",
|
||
tmu, startAddress, evenOdd,
|
||
info->smallLod, info->largeLod, info->aspectRatio, info->format);
|
||
#endif
|
||
|
||
if ( tmu != GR_TMU0 )
|
||
{
|
||
return;
|
||
}
|
||
|
||
RenderDrawTriangles( );
|
||
|
||
info->smallLod = info->largeLod;
|
||
Textures->DownloadMipMap( startAddress, evenOdd, info );
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexDownloadMipMapLevel( GrChipID_t tmu,
|
||
FxU32 startAddress,
|
||
GrLOD_t thisLod,
|
||
GrLOD_t largeLod,
|
||
GrAspectRatio_t aspectRatio,
|
||
GrTextureFormat_t format,
|
||
FxU32 evenOdd,
|
||
void *data )
|
||
{
|
||
#ifdef OGL_PARTDONE
|
||
GlideMsg( "grTexDownloadMipMapLevel( %d, 0x%x, %d, %d, %d, %d, 0x%x, --- )\n",
|
||
tmu, startAddress, thisLod, largeLod, aspectRatio, format, evenOdd );
|
||
#endif
|
||
|
||
if ( ( tmu != GR_TMU0 ) || ( thisLod != largeLod ) )
|
||
{
|
||
return;
|
||
}
|
||
Textures->DownloadMipMapLevel(startAddress, thisLod, largeLod, aspectRatio, format, evenOdd, data);
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexDownloadMipMapLevelPartial( GrChipID_t tmu,
|
||
FxU32 startAddress,
|
||
GrLOD_t thisLod,
|
||
GrLOD_t largeLod,
|
||
GrAspectRatio_t aspectRatio,
|
||
GrTextureFormat_t format,
|
||
FxU32 evenOdd,
|
||
void *data,
|
||
int start,
|
||
int end )
|
||
{
|
||
#ifdef OGL_PARTDONE
|
||
GlideMsg( "grTexDownloadMipMapLevelPartial( %d, 0x%x, %d, %d, %d, fmt=%d, 0x%x, ---, %d, %d )\n",
|
||
tmu, startAddress, thisLod, largeLod, aspectRatio, format, evenOdd, start, end );
|
||
#endif
|
||
if ( ( tmu != GR_TMU0 ) || ( thisLod != largeLod ) )
|
||
{
|
||
return;
|
||
}
|
||
|
||
Textures->DownloadMipMapLevelPartial(startAddress, thisLod, largeLod, aspectRatio, format, evenOdd, data, start, end);
|
||
}
|
||
|
||
//*************************************************
|
||
//* Set the texture map clamping/wrapping mode
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexClampMode( GrChipID_t tmu,
|
||
GrTextureClampMode_t s_clampmode,
|
||
GrTextureClampMode_t t_clampmode )
|
||
{
|
||
CHECK_STATE_CHANGED( Glide.State.SClampMode == s_clampmode
|
||
&& Glide.State.TClampMode == t_clampmode);
|
||
|
||
#ifdef OGL_DONE
|
||
GlideMsg( "grTexClampMode( %d, %d, %d )\n",
|
||
tmu, s_clampmode, t_clampmode );
|
||
#endif
|
||
|
||
if ( tmu != GR_TMU0 )
|
||
{
|
||
return;
|
||
}
|
||
|
||
RenderDrawTriangles( );
|
||
|
||
Glide.State.SClampMode = s_clampmode;
|
||
Glide.State.TClampMode = t_clampmode;
|
||
|
||
switch ( s_clampmode )
|
||
{
|
||
case GR_TEXTURECLAMP_CLAMP: OpenGL.SClampMode = InternalConfig.EXT_SGIS_texture_edge_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP; break;
|
||
case GR_TEXTURECLAMP_WRAP: OpenGL.SClampMode = GL_REPEAT; break;
|
||
}
|
||
switch ( t_clampmode )
|
||
{
|
||
case GR_TEXTURECLAMP_CLAMP: OpenGL.TClampMode = InternalConfig.EXT_SGIS_texture_edge_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP; break;
|
||
case GR_TEXTURECLAMP_WRAP: OpenGL.TClampMode = GL_REPEAT; break;
|
||
}
|
||
}
|
||
|
||
void grTexFilterMode_update(GrChipID_t tmu,
|
||
GrTextureFilterMode_t minfilter_mode,
|
||
GrTextureFilterMode_t magfilter_mode)
|
||
{
|
||
if ( tmu != GR_TMU0 )
|
||
{
|
||
return;
|
||
}
|
||
|
||
RenderDrawTriangles( );
|
||
|
||
Glide.State.MinFilterMode = minfilter_mode;
|
||
Glide.State.MagFilterMode = magfilter_mode;
|
||
// At least on Rage 128 OpenGL Engine 1.1.ATI-5.99, GL_NEAREST_MIPMAP_LINEAR
|
||
// and GL_NEAREST_MIPMAP_NEAREST seem to cause textures to not be displayed
|
||
// As a result, mipmaps are only available on renderers with EXT_SGIS_generate_mipmap
|
||
FxBool mipmapmode = InternalConfig.Mipmapping; // && InternalConfig.EXT_SGIS_generate_mipmap;
|
||
switch ( minfilter_mode )
|
||
{
|
||
case GR_TEXTUREFILTER_POINT_SAMPLED:
|
||
if ( ( Glide.State.MipMapMode != GR_MIPMAP_DISABLE ) && mipmapmode)
|
||
{
|
||
if ( Glide.State.LodBlend )
|
||
{
|
||
OpenGL.MinFilterMode = GL_NEAREST_MIPMAP_LINEAR;
|
||
}
|
||
else
|
||
{
|
||
OpenGL.MinFilterMode = GL_NEAREST_MIPMAP_NEAREST;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
OpenGL.MinFilterMode = GL_NEAREST;
|
||
}
|
||
break;
|
||
|
||
case GR_TEXTUREFILTER_BILINEAR:
|
||
if (mipmapmode)
|
||
{
|
||
if ( Glide.State.LodBlend )
|
||
{
|
||
OpenGL.MinFilterMode = GL_LINEAR_MIPMAP_LINEAR;
|
||
}
|
||
else
|
||
{
|
||
OpenGL.MinFilterMode = GL_LINEAR_MIPMAP_NEAREST;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
OpenGL.MinFilterMode = GL_LINEAR;
|
||
}
|
||
break;
|
||
}
|
||
switch ( magfilter_mode )
|
||
{
|
||
case GR_TEXTUREFILTER_POINT_SAMPLED:
|
||
OpenGL.MagFilterMode = GL_NEAREST;
|
||
break;
|
||
case GR_TEXTUREFILTER_BILINEAR:
|
||
OpenGL.MagFilterMode = GL_LINEAR;
|
||
break;
|
||
}
|
||
}
|
||
|
||
//*************************************************
|
||
//* Set the texture Min/Mag Filter
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexFilterMode( GrChipID_t tmu,
|
||
GrTextureFilterMode_t minfilter_mode,
|
||
GrTextureFilterMode_t magfilter_mode)
|
||
{
|
||
if (InternalConfig.TextureSmoothing) return;
|
||
CHECK_STATE_CHANGED(Glide.State.MinFilterMode == minfilter_mode
|
||
&& Glide.State.MagFilterMode == magfilter_mode);
|
||
|
||
#ifdef OGL_PARTDONE
|
||
GlideMsg("grTexFilterMode( %d, %d, %d )\n",
|
||
tmu, minfilter_mode, magfilter_mode);
|
||
#endif
|
||
|
||
grTexFilterMode_update(tmu, minfilter_mode, magfilter_mode);
|
||
}
|
||
|
||
|
||
//*************************************************
|
||
//* Set the texture MipMap Mode
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexMipMapMode( GrChipID_t tmu,
|
||
GrMipMapMode_t mode,
|
||
FxBool lodBlend )
|
||
{
|
||
if (InternalConfig.TextureSmoothing) return;
|
||
CHECK_STATE_CHANGED(Glide.State.MipMapMode == mode
|
||
&& Glide.State.LodBlend == lodBlend);
|
||
|
||
#ifdef OGL_PARTDONE
|
||
GlideMsg("grTexMipMapMode( %d, %d, %d )\n",
|
||
tmu, mode, lodBlend );
|
||
#endif
|
||
|
||
if ( tmu != GR_TMU0 )
|
||
{
|
||
return;
|
||
}
|
||
|
||
Glide.State.MipMapMode = mode;
|
||
Glide.State.LodBlend = lodBlend;
|
||
|
||
grTexFilterMode_update(tmu,
|
||
Glide.State.MinFilterMode,
|
||
Glide.State.MagFilterMode);
|
||
}
|
||
|
||
//*************************************************
|
||
//* Returns the memory occupied by a texture
|
||
//*************************************************
|
||
FX_ENTRY FxU32 FX_CALL
|
||
grTexCalcMemRequired( GrLOD_t lodmin, GrLOD_t lodmax,
|
||
GrAspectRatio_t aspect, GrTextureFormat_t fmt )
|
||
{
|
||
#ifdef OGL_DONE
|
||
GlideMsg( "grTexCalcMemRequired( %d, %d, %d, %d )\n",
|
||
lodmin, lodmax, aspect, fmt );
|
||
#endif
|
||
|
||
static GrTexInfo texInfo;
|
||
texInfo.aspectRatio = aspect;
|
||
texInfo.format = fmt;
|
||
texInfo.largeLod = lodmax;
|
||
texInfo.smallLod = lodmin;
|
||
|
||
return Textures->TextureMemRequired( 0, &texInfo );
|
||
}
|
||
|
||
//*************************************************
|
||
//* Download a subset of an NCC table or color palette
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexDownloadTablePartial( GrChipID_t tmu,
|
||
GrTexTable_t type,
|
||
void *data,
|
||
int start,
|
||
int end )
|
||
{
|
||
#ifdef OGL_PARTDONE
|
||
GlideMsg( "grTexDownloadTablePartial( %d, %d, ---, %d, %d )\n",
|
||
tmu, type, start, end );
|
||
#endif
|
||
|
||
if ( tmu != GR_TMU0 )
|
||
{
|
||
return;
|
||
}
|
||
|
||
RenderDrawTriangles( );
|
||
|
||
Textures->DownloadTable( type, (FxU32*)data, start, end + 1 - start );
|
||
}
|
||
|
||
//*************************************************
|
||
//* download an NCC table or color palette
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexDownloadTable( GrChipID_t tmu,
|
||
GrTexTable_t type,
|
||
void *data )
|
||
{
|
||
#ifdef OGL_PARTDONE
|
||
GlideMsg( "grTexDownloadTable( %d, %d, --- )\n", tmu, type );
|
||
#endif
|
||
|
||
if ( tmu != GR_TMU0 )
|
||
{
|
||
return;
|
||
}
|
||
|
||
RenderDrawTriangles( );
|
||
|
||
Textures->DownloadTable( type, (FxU32*)data, 0, 256 );
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexLodBiasValue( GrChipID_t tmu, float bias )
|
||
{
|
||
glReportErrors("grTexLodBiasValue");
|
||
|
||
#ifdef OGL_NOTDONE
|
||
GlideMsg( "grTexLodBiasValue( %d, %d )\n", tmu, bias );
|
||
#endif
|
||
|
||
if (tmu != GR_TMU0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
CHECK_STATE_CHANGED(bias == Glide.State.LodBias);
|
||
RenderDrawTriangles();
|
||
|
||
Glide.State.LodBias = bias;
|
||
if ( InternalConfig.EXT_texture_lod_bias )
|
||
{
|
||
if (OpenGL.ColorAlphaUnit2)
|
||
{
|
||
for(int unit_index = 1; unit_index >= 0; unit_index--)
|
||
{
|
||
glActiveTextureARB(OpenGL.ColorAlphaUnit1 + unit_index);
|
||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, bias);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, bias );
|
||
}
|
||
}
|
||
|
||
VERIFY_ACTIVE_TEXTURE_UNIT(OpenGL.ColorAlphaUnit1);
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexNCCTable( GrChipID_t tmu, GrNCCTable_t NCCTable )
|
||
{
|
||
#ifdef OGL_DONE
|
||
GlideMsg( "grTexNCCTable( %d, %u )\n", tmu, NCCTable );
|
||
#endif
|
||
|
||
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
|
||
if ( tmu != GR_TMU0 )
|
||
{
|
||
return;
|
||
}
|
||
|
||
RenderDrawTriangles();
|
||
Textures->NCCTable( NCCTable );
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexDetailControl( GrChipID_t tmu,
|
||
int lod_bias,
|
||
FxU8 detail_scale,
|
||
float detail_max )
|
||
{
|
||
// CHECK_STATE_CHANGED(...)
|
||
|
||
#ifdef OGL_NOTDONE
|
||
GlideMsg( "grTexDetailControl( %d, %d, %d, %-4.2f )\n",
|
||
tmu, lod_bias, detail_scale, detail_max );
|
||
#endif
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexMultibase( GrChipID_t tmu,
|
||
FxBool enable )
|
||
{
|
||
#ifdef OGL_NOTDONE
|
||
GlideMsg( "grTexMultibase( %d, %d )\n", tmu, enable );
|
||
#endif
|
||
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
|
||
if ( tmu != GR_TMU0 )
|
||
{
|
||
return;
|
||
}
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexMultibaseAddress( GrChipID_t tmu,
|
||
GrTexBaseRange_t range,
|
||
FxU32 startAddress,
|
||
FxU32 evenOdd,
|
||
GrTexInfo *info )
|
||
{
|
||
#ifdef OGL_NOTDONE
|
||
GlideMsg( "grTexMultibaseAddress( %d, %d, %lu, %lu, --- )\n",
|
||
tmu, range, startAddress, evenOdd );
|
||
#endif
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexCombine( GrChipID_t tmu,
|
||
GrCombineFunction_t rgb_function,
|
||
GrCombineFactor_t rgb_factor,
|
||
GrCombineFunction_t alpha_function,
|
||
GrCombineFactor_t alpha_factor,
|
||
FxBool rgb_invert,
|
||
FxBool alpha_invert )
|
||
{
|
||
CHECK_STATE_CHANGED( Glide.State.TextureCombineCFunction == rgb_function
|
||
&& Glide.State.TextureCombineCFactor == rgb_factor
|
||
&& Glide.State.TextureCombineAFunction == alpha_function
|
||
&& Glide.State.TextureCombineAFactor == alpha_factor
|
||
&& Glide.State.TextureCombineRGBInvert == rgb_invert
|
||
&& Glide.State.TextureCombineAInvert == alpha_invert);
|
||
|
||
#if defined( OGL_PARTDONE ) || defined( OGL_COMBINE )
|
||
GlideMsg( "grTexCombine( %d, %d, %d, %d, %d, %d, %d )\n",
|
||
tmu, rgb_function, rgb_factor, alpha_function, alpha_factor,
|
||
rgb_invert, alpha_invert );
|
||
#endif
|
||
|
||
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
|
||
if ( tmu != GR_TMU0 )
|
||
{
|
||
return;
|
||
}
|
||
|
||
RenderDrawTriangles( );
|
||
|
||
if (Glide.State.TextureCombineCFunction != rgb_function ||
|
||
Glide.State.TextureCombineCFactor != rgb_factor)
|
||
{
|
||
Glide.State.TextureCombineCFunction = rgb_function;
|
||
Glide.State.TextureCombineCFactor = rgb_factor;
|
||
SetColorTextureState();
|
||
SetTextureState();
|
||
}
|
||
if (Glide.State.TextureCombineAFunction != alpha_function ||
|
||
Glide.State.TextureCombineAFactor != alpha_factor)
|
||
{
|
||
Glide.State.TextureCombineAFunction = alpha_function;
|
||
Glide.State.TextureCombineAFactor = alpha_factor;
|
||
SetAlphaTextureState();
|
||
SetTextureState();
|
||
}
|
||
if (Glide.State.TextureCombineRGBInvert != rgb_invert)
|
||
{
|
||
Glide.State.TextureCombineRGBInvert = rgb_invert;
|
||
SetColorCombineState();
|
||
SetAlphaCombineState();
|
||
}
|
||
if (Glide.State.TextureCombineAInvert != alpha_invert)
|
||
{
|
||
Glide.State.TextureCombineAInvert = alpha_invert;
|
||
SetAlphaCombineState();
|
||
}
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
grTexCombineFunction( GrChipID_t tmu, GrTextureCombineFnc_t func )
|
||
{
|
||
#if defined( OGL_PARTDONE ) || defined( OGL_COMBINE )
|
||
GlideMsg( "grTexCombineFunction( %d, %d )\n", tmu, func );
|
||
#endif
|
||
|
||
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
|
||
if ( tmu != GR_TMU0 )
|
||
{
|
||
return;
|
||
}
|
||
|
||
switch ( func )
|
||
{
|
||
case GR_TEXTURECOMBINE_ZERO: // 0x00 per component
|
||
grTexCombine( tmu, GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO,
|
||
GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO, FXFALSE, FXFALSE );
|
||
break;
|
||
|
||
case GR_TEXTURECOMBINE_DECAL: // Clocal decal texture
|
||
grTexCombine( tmu, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE,
|
||
GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE );
|
||
break;
|
||
|
||
case GR_TEXTURECOMBINE_OTHER: // Cother pass through
|
||
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE,
|
||
GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE );
|
||
break;
|
||
|
||
case GR_TEXTURECOMBINE_ADD: // Cother + Clocal additive texture
|
||
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE,
|
||
GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE );
|
||
break;
|
||
|
||
case GR_TEXTURECOMBINE_MULTIPLY: // Cother * Clocal modulated texture
|
||
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL,
|
||
GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_LOCAL, FXFALSE, FXFALSE );
|
||
break;
|
||
|
||
case GR_TEXTURECOMBINE_SUBTRACT: // Cother <20> Clocal subtractive texture
|
||
grTexCombine( tmu, GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE,
|
||
GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE );
|
||
break;
|
||
|
||
case GR_TEXTURECOMBINE_ONE: // 255 0xFF per component
|
||
grTexCombine( tmu, GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO,
|
||
GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_ZERO, FXTRUE, FXTRUE );
|
||
break;
|
||
|
||
// case GR_TEXTURECOMBINE_DETAIL: // blend (Cother, Clocal) detail textures with detail on selected TMU
|
||
// case GR_TEXTURECOMBINE_DETAIL_OTHER: // blend (Cother, Clocal) detail textures with detail on neighboring TMU
|
||
// case GR_TEXTURECOMBINE_TRILINEAR_ODD: // blend (Cother, Clocal) LOD blended textures with odd levels on selected TMU
|
||
// case GR_TEXTURECOMBINE_TRILINEAR_EVEN: // blend (Cother, Clocal) LOD blended textures with even levels on selected TMU
|
||
// break;
|
||
}
|
||
}
|
||
|
||
//*************************************************
|
||
//* Return the amount of unallocated texture memory on a Texture Mapping Unit
|
||
//*************************************************
|
||
FX_ENTRY FxU32 FX_CALL
|
||
guTexMemQueryAvail( GrChipID_t tmu )
|
||
{
|
||
#ifdef OGL_PARTDONE
|
||
GlideMsg( "guTexMemQueryAvail( %d ) = %u\n", tmu, UTextures.MemQueryAvail( tmu ) );
|
||
#endif
|
||
|
||
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
|
||
if ( tmu != GR_TMU0 )
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
return UTextures.MemQueryAvail( tmu );
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
guTexCombineFunction( GrChipID_t tmu, GrTextureCombineFnc_t func )
|
||
{
|
||
#if defined( OGL_PARTDONE ) || defined( OGL_COMBINE )
|
||
GlideMsg( "guTexCombineFunction( %d, %d )\n", tmu, func );
|
||
#endif
|
||
// @todo: guTexCombineFunction() also keeps track of which TMUs
|
||
// require texture coordinates for the rendering routines.
|
||
// (see glide24pgm page 139)
|
||
grTexCombineFunction(tmu, func);
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY GrMipMapId_t FX_CALL
|
||
guTexGetCurrentMipMap( GrChipID_t tmu )
|
||
{
|
||
#ifdef OGL_DONE
|
||
GlideMsg( "guTexGetCurrentMipMap( %d ) = %d\n", tmu, UTextures.GetCurrentMipMap( tmu ) );
|
||
#endif
|
||
|
||
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
|
||
if ( tmu != GR_TMU0 )
|
||
{
|
||
return GR_NULL_MIPMAP_HANDLE;
|
||
}
|
||
|
||
return UTextures.GetCurrentMipMap( tmu );
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY FxBool FX_CALL
|
||
guTexChangeAttributes( GrMipMapId_t mmid,
|
||
int width, int height,
|
||
GrTextureFormat_t fmt,
|
||
GrMipMapMode_t mm_mode,
|
||
GrLOD_t smallest_lod, GrLOD_t largest_lod,
|
||
GrAspectRatio_t aspect,
|
||
GrTextureClampMode_t s_clamp_mode,
|
||
GrTextureClampMode_t t_clamp_mode,
|
||
GrTextureFilterMode_t minFilterMode,
|
||
GrTextureFilterMode_t magFilterMode )
|
||
{
|
||
#ifdef OGL_DONE
|
||
GlideMsg( "guTexChangeAttributes( %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d )\n",
|
||
mmid, width, height, fmt, mm_mode, smallest_lod, largest_lod, aspect,
|
||
s_clamp_mode, t_clamp_mode, minFilterMode, magFilterMode );
|
||
#endif
|
||
|
||
return UTextures.ChangeAttributes( mmid, width, height, fmt, mm_mode,
|
||
smallest_lod, largest_lod, aspect, s_clamp_mode, t_clamp_mode,
|
||
minFilterMode, magFilterMode );
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY GrMipMapInfo * FX_CALL
|
||
guTexGetMipMapInfo( GrMipMapId_t mmid )
|
||
{
|
||
#ifdef OGL_DONE
|
||
GlideMsg( "guTexGetMipMapInfo( ) = 0x%p\n" );
|
||
#endif
|
||
|
||
return UTextures.GetMipMapInfo( mmid );
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
guTexMemReset( void )
|
||
{
|
||
#ifdef OGL_PARTDONE
|
||
GlideMsg( "guTexMemReset( )\n" );
|
||
#endif
|
||
|
||
UTextures.MemReset( );
|
||
Textures->Clear( );
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
guTexDownloadMipMapLevel( GrMipMapId_t mmid, GrLOD_t lod, const void **src )
|
||
{
|
||
#ifdef OGL_DONE
|
||
GlideMsg( "guTexDownloadMipMapLevel( %d, %d, 0x%p )\n", mmid, lod, src );
|
||
#endif
|
||
|
||
UTextures.DownloadMipMapLevel( mmid, lod, src );
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
guTexDownloadMipMap( GrMipMapId_t mmid, const void *src, const GuNccTable *table )
|
||
{
|
||
#ifdef OGL_DONE
|
||
GlideMsg( "guTexDownloadMipMap( %d, 0x%p, 0x%p )\n", mmid, src, table );
|
||
#endif
|
||
|
||
UTextures.DownloadMipMap( mmid, src, table );
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY GrMipMapId_t FX_CALL
|
||
guTexAllocateMemory( GrChipID_t tmu,
|
||
FxU8 odd_even_mask,
|
||
int width, int height,
|
||
GrTextureFormat_t fmt,
|
||
GrMipMapMode_t mm_mode,
|
||
GrLOD_t smallest_lod, GrLOD_t largest_lod,
|
||
GrAspectRatio_t aspect,
|
||
GrTextureClampMode_t s_clamp_mode,
|
||
GrTextureClampMode_t t_clamp_mode,
|
||
GrTextureFilterMode_t minfilter_mode,
|
||
GrTextureFilterMode_t magfilter_mode,
|
||
float lod_bias,
|
||
FxBool trilinear )
|
||
{
|
||
#ifdef OGL_DONE
|
||
GlideMsg( "guTexAllocateMemory( %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d )\n",
|
||
tmu, odd_even_mask, width, height, fmt, mm_mode, smallest_lod, largest_lod, aspect,
|
||
s_clamp_mode, t_clamp_mode, minfilter_mode, magfilter_mode, lod_bias, trilinear );
|
||
#endif
|
||
|
||
// Ignoring TMU as we are only emulating Glide and assuming a well behaviored program
|
||
if ( tmu != GR_TMU0 )
|
||
{
|
||
return GR_NULL_MIPMAP_HANDLE;
|
||
}
|
||
|
||
return UTextures.AllocateMemory( tmu, odd_even_mask, width, height, fmt, mm_mode,
|
||
smallest_lod, largest_lod, aspect, s_clamp_mode, t_clamp_mode,
|
||
minfilter_mode, magfilter_mode, lod_bias, trilinear );
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY void FX_CALL
|
||
guTexSource( GrMipMapId_t id )
|
||
{
|
||
// Works because the current id isn't changed in UTextures.Source
|
||
// when id is GR_NULL_MIPMAP_HANDLE (todo: this might be a bug)
|
||
CHECK_STATE_CHANGED(id == GR_NULL_MIPMAP_HANDLE || id == UTextures.GetCurrentID());
|
||
|
||
#ifdef OGL_DONE
|
||
GlideMsg( "guTexSource( %d )\n", id );
|
||
#endif
|
||
|
||
RenderDrawTriangles();
|
||
|
||
UTextures.Source( id );
|
||
}
|
||
|
||
//*************************************************
|
||
FX_ENTRY FxU16 * FX_CALL
|
||
guTexCreateColorMipMap( void )
|
||
{
|
||
#ifdef OGL_NOTDONE
|
||
GlideMsg( "guTexCreateColorMipMap( ) = NULL\n" );
|
||
#endif
|
||
|
||
return NULL;
|
||
}
|
||
|