2013-04-04 21:22:19 +00:00
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators .
* Copyright ( c ) 2002 Dave2001
* Copyright ( c ) 2003 - 2009 Sergey ' Gonetz ' Lipski
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators
// Project started on December 29th, 2001
//
// Authors:
// Dave2001, original author, founded the project in 2001, left it in 2002
// Gugaman, joined the project in 2002, left it in 2002
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
//
//****************************************************************
//
// To modify Glide64:
// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
//
//****************************************************************
2015-10-22 21:01:48 +00:00
# ifndef _WIN32
2015-10-12 21:12:16 +00:00
# include <SDL.h>
2015-10-22 21:01:48 +00:00
# endif
2015-10-09 00:07:09 +00:00
# include "Gfx_1.3.h"
2015-10-22 21:01:48 +00:00
2013-04-04 21:22:19 +00:00
# include "TexCache.h"
# include "Combine.h"
2015-10-13 22:50:35 +00:00
# include "Util.h"
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
void LoadTex ( int id , int tmu ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
uint8_t tex1 [ 1024 * 1024 * 4 ] ; // temporary texture
uint8_t tex2 [ 1024 * 1024 * 4 ] ;
2016-01-20 06:17:45 +00:00
uint8_t * texture ;
uint8_t * texture_buffer = tex1 ;
2013-04-04 21:22:19 +00:00
# include "TexLoad.h" // texture loading functions, ONLY INCLUDE IN THIS FILE!!!
# include "MiClWr32b.h"
# include "MiClWr16b.h" // Mirror/Clamp/Wrap functions, ONLY INCLUDE IN THIS FILE!!!
# include "MiClWr8b.h" // Mirror/Clamp/Wrap functions, ONLY INCLUDE IN THIS FILE!!!
# include "TexConv.h" // texture conversions, ONLY INCLUDE IN THIS FILE!!!
# include "TexMod.h"
# include "TexModCI.h"
# include "CRC.h"
# ifdef TEXTURE_FILTER // Hiroshi Morii <koolsmoky@users.sourceforge.net>
extern int ghq_dmptex_toggle_key ;
# endif
typedef struct TEXINFO_t {
2016-01-20 10:00:15 +00:00
int real_image_width , real_image_height ; // FOR ALIGNMENT PURPOSES ONLY!!!
int tile_width , tile_height ;
int mask_width , mask_height ;
int width , height ;
int wid_64 , line ;
uint32_t crc ;
uint32_t flags ;
int splits , splitheight ;
2013-04-04 21:22:19 +00:00
# ifdef TEXTURE_FILTER
2016-01-20 10:00:15 +00:00
uint64 ricecrc ;
2013-04-04 21:22:19 +00:00
# endif
} TEXINFO ;
TEXINFO texinfo [ 2 ] ;
int tex_found [ 2 ] [ MAX_TMU ] ;
# ifdef TEXTURE_FILTER
typedef struct HIRESTEX_t {
2016-01-20 10:00:15 +00:00
int width , height ;
uint16_t format ;
uint8_t * data ;
2013-04-04 21:22:19 +00:00
} HIRESTEX ;
# endif
//****************************************************************
// List functions
typedef struct NODE_t {
2016-01-20 10:00:15 +00:00
uint32_t crc ;
2016-01-25 11:13:35 +00:00
uintptr_t data ;
2016-01-20 10:00:15 +00:00
int tmu ;
int number ;
NODE_t * pNext ;
2013-04-04 21:22:19 +00:00
} NODE ;
NODE * cachelut [ 65536 ] ;
2016-01-25 11:13:35 +00:00
void AddToList ( NODE * * list , uint32_t crc , uintptr_t data , int tmu , int number )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
NODE * node = new NODE ;
node - > crc = crc ;
node - > data = data ;
node - > tmu = tmu ;
node - > number = number ;
node - > pNext = * list ;
* list = node ;
rdp . n_cached [ tmu ] + + ;
if ( voodoo . tex_UMA )
rdp . n_cached [ tmu ^ 1 ] = rdp . n_cached [ tmu ] ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
void DeleteList ( NODE * * list )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
while ( * list )
{
NODE * next = ( * list ) - > pNext ;
delete ( * list ) ;
* list = next ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
void TexCacheInit ( )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
for ( int i = 0 ; i < 65536 ; i + + )
{
cachelut [ i ] = NULL ;
}
2013-04-04 21:22:19 +00:00
}
//****************************************************************
// ClearCache - clear the texture cache for BOTH tmus
2016-01-20 10:00:15 +00:00
void ClearCache ( )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
voodoo . tmem_ptr [ 0 ] = offset_textures ;
rdp . n_cached [ 0 ] = 0 ;
voodoo . tmem_ptr [ 1 ] = voodoo . tex_UMA ? offset_textures : offset_texbuf1 ;
rdp . n_cached [ 1 ] = 0 ;
for ( int i = 0 ; i < 65536 ; i + + )
{
DeleteList ( & cachelut [ i ] ) ;
}
2013-04-04 21:22:19 +00:00
}
//****************************************************************
2015-10-14 00:38:47 +00:00
uint32_t textureCRC ( uint8_t * addr , int width , int height , int line )
2015-10-13 04:54:52 +00:00
{
2016-01-20 10:00:15 +00:00
uint32_t crc = 0 ;
uint32_t * pixelpos ;
unsigned int i ;
uint64_t twopixel_crc ;
pixelpos = ( uint32_t * ) addr ;
for ( ; height ; height - - ) {
for ( i = width ; i ; - - i ) {
twopixel_crc = i * ( uint64_t ) ( pixelpos [ 1 ] + pixelpos [ 0 ] + crc ) ;
2016-01-20 17:39:18 +00:00
crc = ( uint32_t ) ( ( ( twopixel_crc > > 32 ) + twopixel_crc ) & 0xFFFFFFFF ) ;
2016-01-20 10:00:15 +00:00
pixelpos + = 2 ;
}
crc = ( ( unsigned int ) height * ( uint64_t ) crc > > 32 ) + height * crc ;
pixelpos = ( uint32_t * ) ( ( char * ) pixelpos + line ) ;
2015-10-14 00:38:47 +00:00
}
2016-01-20 10:00:15 +00:00
return crc ;
2015-10-13 04:54:52 +00:00
}
2015-10-14 00:38:47 +00:00
// GetTexInfo - gets information for either t0 or t1, checks if in cache & fills tex_found
2015-10-13 04:54:52 +00:00
2016-01-20 10:00:15 +00:00
void GetTexInfo ( int id , int tile )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
FRDP ( " | |-+ GetTexInfo (id: %d, tile: %d) \n " , id , tile ) ;
// this is the NEW cache searching, searches only textures with similar crc's
int t ;
for ( t = 0 ; t < MAX_TMU ; t + + )
tex_found [ id ] [ t ] = - 1 ;
TBUFF_COLOR_IMAGE * pFBTex = 0 ;
if ( rdp . aTBuffTex [ 0 ] & & rdp . aTBuffTex [ 0 ] - > tile = = id )
pFBTex = rdp . aTBuffTex [ 0 ] ;
else if ( rdp . aTBuffTex [ 1 ] & & rdp . aTBuffTex [ 1 ] - > tile = = id )
pFBTex = rdp . aTBuffTex [ 1 ] ;
if ( pFBTex & & pFBTex - > cache )
return ;
TEXINFO * info = & texinfo [ id ] ;
int tile_width , tile_height ;
int mask_width , mask_height ;
int width , height ;
int wid_64 , line , bpl ;
// Get width and height
tile_width = rdp . tiles [ tile ] . lr_s - rdp . tiles [ tile ] . ul_s + 1 ;
tile_height = rdp . tiles [ tile ] . lr_t - rdp . tiles [ tile ] . ul_t + 1 ;
mask_width = ( rdp . tiles [ tile ] . mask_s = = 0 ) ? ( tile_width ) : ( 1 < < rdp . tiles [ tile ] . mask_s ) ;
mask_height = ( rdp . tiles [ tile ] . mask_t = = 0 ) ? ( tile_height ) : ( 1 < < rdp . tiles [ tile ] . mask_t ) ;
2016-02-01 08:56:25 +00:00
if ( g_settings - > alt_tex_size )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
// ** ALTERNATE TEXTURE SIZE METHOD **
// Helps speed in some games that loaded weird-sized textures, but could break other
// textures.
// Get the width/height to load
if ( ( rdp . tiles [ tile ] . clamp_s & & tile_width < = 256 ) | | ( mask_width > 256 ) )
{
// loading width
2016-01-25 09:58:29 +00:00
width = minval ( mask_width , tile_width ) ;
2016-01-20 10:00:15 +00:00
// actual width
rdp . tiles [ tile ] . width = tile_width ;
}
else
{
// wrap all the way
2016-01-25 09:58:29 +00:00
width = minval ( mask_width , tile_width ) ; // changed from mask_width only
2016-01-20 10:00:15 +00:00
rdp . tiles [ tile ] . width = width ;
}
if ( ( rdp . tiles [ tile ] . clamp_t & & tile_height < = 256 ) | | ( mask_height > 256 ) )
{
// loading height
2016-01-25 09:58:29 +00:00
height = minval ( mask_height , tile_height ) ;
2016-01-20 10:00:15 +00:00
// actual height
rdp . tiles [ tile ] . height = tile_height ;
}
else
{
// wrap all the way
2016-01-25 09:58:29 +00:00
height = minval ( mask_height , tile_height ) ;
2016-01-20 10:00:15 +00:00
rdp . tiles [ tile ] . height = height ;
}
2013-04-04 21:22:19 +00:00
}
else
{
2016-01-20 10:00:15 +00:00
// ** NORMAL TEXTURE SIZE METHOD **
// This is the 'correct' method for determining texture size, but may cause certain
// textures to load too large & make the whole game go slow.
if ( mask_width > 256 & & mask_height > 256 )
{
mask_width = tile_width ;
mask_height = tile_height ;
}
// Get the width/height to load
if ( ( rdp . tiles [ tile ] . clamp_s & & tile_width < = 256 ) ) //|| (mask_width > 256))
{
// loading width
2016-01-25 09:58:29 +00:00
width = minval ( mask_width , tile_width ) ;
2016-01-20 10:00:15 +00:00
// actual width
rdp . tiles [ tile ] . width = tile_width ;
}
else
{
// wrap all the way
width = mask_width ;
rdp . tiles [ tile ] . width = mask_width ;
}
if ( ( rdp . tiles [ tile ] . clamp_t & & tile_height < = 256 ) | | ( mask_height > 256 ) )
{
// loading height
2016-01-25 09:58:29 +00:00
height = minval ( mask_height , tile_height ) ;
2016-01-20 10:00:15 +00:00
// actual height
rdp . tiles [ tile ] . height = tile_height ;
}
else
{
// wrap all the way
height = mask_height ;
rdp . tiles [ tile ] . height = mask_height ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
// without any large texture fixing-up; for alignment
int real_image_width = rdp . tiles [ tile ] . width ;
int real_image_height = rdp . tiles [ tile ] . height ;
int crc_height = height ;
if ( rdp . timg . set_by = = 1 )
crc_height = tile_height ;
bpl = width < < rdp . tiles [ tile ] . size > > 1 ;
// ** COMMENT THIS TO DISABLE LARGE TEXTURES
# ifdef LARGE_TEXTURE_HANDLING
if ( ! voodoo . sup_large_tex & & width > 256 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
info - > splits = ( ( width - 1 ) > > 8 ) + 1 ;
info - > splitheight = rdp . tiles [ tile ] . height ;
rdp . tiles [ tile ] . height * = info - > splits ;
rdp . tiles [ tile ] . width = 256 ;
width = 256 ;
2013-04-04 21:22:19 +00:00
}
else
2016-01-20 10:00:15 +00:00
# endif
// **
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
info - > splits = 1 ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
LRDP ( " | | |-+ Texture approved: \n " ) ;
FRDP ( " | | | |- tmem: %08lx \n " , rdp . tiles [ tile ] . t_mem ) ;
FRDP ( " | | | |- load width: %d \n " , width ) ;
FRDP ( " | | | |- load height: %d \n " , height ) ;
FRDP ( " | | | |- actual width: %d \n " , rdp . tiles [ tile ] . width ) ;
FRDP ( " | | | |- actual height: %d \n " , rdp . tiles [ tile ] . height ) ;
FRDP ( " | | | |- size: %d \n " , rdp . tiles [ tile ] . size ) ;
FRDP ( " | | | +- format: %d \n " , rdp . tiles [ tile ] . format ) ;
LRDP ( " | | |- Calculating CRC... " ) ;
// ** CRC CHECK
wid_64 = width < < ( rdp . tiles [ tile ] . size ) > > 1 ;
if ( rdp . tiles [ tile ] . size = = 3 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
if ( wid_64 & 15 ) wid_64 + = 16 ;
wid_64 & = 0xFFFFFFF0 ;
2013-04-04 21:22:19 +00:00
}
else
{
2016-01-20 10:00:15 +00:00
if ( wid_64 & 7 ) wid_64 + = 8 ; // round up
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
wid_64 = wid_64 > > 3 ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
// Texture too big for tmem & needs to wrap? (trees in mm)
2016-01-25 09:58:29 +00:00
if ( rdp . tiles [ tile ] . t_mem + minval ( height , tile_height ) * ( rdp . tiles [ tile ] . line < < 3 ) > 4096 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
LRDP ( " TEXTURE WRAPS TMEM!!! " ) ;
// calculate the y value that intersects at 4096 bytes
int y = ( 4096 - rdp . tiles [ tile ] . t_mem ) / ( rdp . tiles [ tile ] . line < < 3 ) ;
rdp . tiles [ tile ] . clamp_t = 0 ;
rdp . tiles [ tile ] . lr_t = rdp . tiles [ tile ] . ul_t + y - 1 ;
// calc mask
int shift ;
for ( shift = 0 ; ( 1 < < shift ) < y ; shift + + ) ;
rdp . tiles [ tile ] . mask_t = shift ;
// restart the function
LRDP ( " restarting... \n " ) ;
GetTexInfo ( id , tile ) ;
return ;
}
line = rdp . tiles [ tile ] . line ;
if ( rdp . tiles [ tile ] . size = = 3 )
line < < = 1 ;
uint32_t crc = 0 ;
2016-02-01 08:56:25 +00:00
if ( g_settings - > fast_crc )
2016-01-20 10:00:15 +00:00
{
line = ( line - wid_64 ) < < 3 ;
if ( wid_64 < 1 ) wid_64 = 1 ;
uint8_t * addr = ( ( ( uint8_t * ) rdp . tmem ) + ( rdp . tiles [ tile ] . t_mem < < 3 ) ) ;
if ( crc_height > 0 ) // Check the CRC
{
if ( rdp . tiles [ tile ] . size < 3 )
crc = textureCRC ( addr , wid_64 , crc_height , line ) ;
else //32b texture
{
int line_2 = line > > 1 ;
2016-01-25 09:58:29 +00:00
int wid_64_2 = maxval ( 1 , wid_64 > > 1 ) ;
2016-01-20 10:00:15 +00:00
crc = textureCRC ( addr , wid_64_2 , crc_height , line_2 ) ;
crc + = textureCRC ( addr + 0x800 , wid_64_2 , crc_height , line_2 ) ;
}
}
2013-04-04 21:22:19 +00:00
}
else
{
2016-01-20 10:00:15 +00:00
crc = 0xFFFFFFFF ;
2016-01-25 11:13:35 +00:00
uintptr_t addr = uintptr_t ( rdp . tmem ) + ( rdp . tiles [ tile ] . t_mem < < 3 ) ;
2016-01-25 09:58:29 +00:00
uint32_t line2 = maxval ( line , 1 ) ;
2016-01-20 10:00:15 +00:00
if ( rdp . tiles [ tile ] . size < 3 )
{
line2 < < = 3 ;
for ( int y = 0 ; y < crc_height ; y + + )
{
crc = CRC32 ( crc , reinterpret_cast < void * > ( addr ) , bpl ) ;
addr + = line2 ;
}
}
else //32b texture
{
line2 < < = 2 ;
//32b texel is split in two 16b parts, so bpl/2 and line/2.
//Min value for bpl is 4, because when width==1 first 2 bytes of tmem will not be used.
2016-01-25 09:58:29 +00:00
bpl = maxval ( bpl > > 1 , 4 ) ;
2016-01-20 10:00:15 +00:00
for ( int y = 0 ; y < crc_height ; y + + )
{
crc = CRC32 ( crc , reinterpret_cast < void * > ( addr ) , bpl ) ;
crc = CRC32 ( crc , reinterpret_cast < void * > ( addr + 0x800 ) , bpl ) ;
addr + = line2 ;
}
}
line = ( line - wid_64 ) < < 3 ;
if ( wid_64 < 1 ) wid_64 = 1 ;
}
if ( ( rdp . tiles [ tile ] . size < 2 ) & & ( rdp . tlut_mode | | rdp . tiles [ tile ] . format = = 2 ) )
{
if ( rdp . tiles [ tile ] . size = = 0 )
crc + = rdp . pal_8_crc [ rdp . tiles [ tile ] . palette ] ;
else
crc + = rdp . pal_256_crc ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
FRDP ( " Done. CRC is: %08lx. \n " , crc ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
uint32_t flags = ( rdp . tiles [ tile ] . clamp_s < < 23 ) | ( rdp . tiles [ tile ] . mirror_s < < 22 ) |
( rdp . tiles [ tile ] . mask_s < < 18 ) | ( rdp . tiles [ tile ] . clamp_t < < 17 ) |
( rdp . tiles [ tile ] . mirror_t < < 16 ) | ( rdp . tiles [ tile ] . mask_t < < 12 ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
info - > real_image_width = real_image_width ;
info - > real_image_height = real_image_height ;
info - > tile_width = tile_width ;
info - > tile_height = tile_height ;
info - > mask_width = mask_width ;
info - > mask_height = mask_height ;
info - > width = width ;
info - > height = height ;
info - > wid_64 = wid_64 ;
info - > line = line ;
info - > crc = crc ;
info - > flags = flags ;
// Search the texture cache for this texture
LRDP ( " | | |-+ Checking cache... \n " ) ;
CACHE_LUT * cache ;
if ( rdp . noise = = RDP : : noise_texture )
return ;
uint32_t mod , modcolor , modcolor1 , modcolor2 , modfactor ;
if ( id = = 0 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
mod = cmb . mod_0 ;
modcolor = cmb . modcolor_0 ;
modcolor1 = cmb . modcolor1_0 ;
modcolor2 = cmb . modcolor2_0 ;
modfactor = cmb . modfactor_0 ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
else
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
mod = cmb . mod_1 ;
modcolor = cmb . modcolor_1 ;
modcolor1 = cmb . modcolor1_1 ;
modcolor2 = cmb . modcolor2_1 ;
modfactor = cmb . modfactor_1 ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
NODE * node = cachelut [ crc > > 16 ] ;
uint32_t mod_mask = ( rdp . tiles [ tile ] . format = = 2 ) ? 0xFFFFFFFF : 0xF0F0F0F0 ;
while ( node )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
if ( node - > crc = = crc )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
cache = ( CACHE_LUT * ) node - > data ;
if ( /*tex_found[id][node->tmu] == -1 &&
rdp . tiles [ tile ] . palette = = cache - > palette & &
rdp . tiles [ tile ] . format = = cache - > format & &
rdp . tiles [ tile ] . size = = cache - > size & & */
rdp . tiles [ tile ] . width = = cache - > width & &
rdp . tiles [ tile ] . height = = cache - > height & &
flags = = cache - > flags )
{
if ( ! ( mod + cache - > mod ) | | ( cache - > mod = = mod & &
( cache - > mod_color & mod_mask ) = = ( modcolor & mod_mask ) & &
( cache - > mod_color1 & mod_mask ) = = ( modcolor1 & mod_mask ) & &
( cache - > mod_color2 & mod_mask ) = = ( modcolor2 & mod_mask ) & &
abs ( ( int ) ( cache - > mod_factor - modfactor ) ) < 8 ) )
{
FRDP ( " | | | |- Texture found in cache (tmu=%d). \n " , node - > tmu ) ;
tex_found [ id ] [ node - > tmu ] = node - > number ;
if ( voodoo . tex_UMA )
{
tex_found [ id ] [ node - > tmu ^ 1 ] = node - > number ;
return ;
}
}
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
node = node - > pNext ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
LRDP ( " | | | +- Done. \n | | +- GetTexInfo end \n " ) ;
2013-04-04 21:22:19 +00:00
}
//****************************************************************
// ChooseBestTmu - chooses the best TMU to load to (the one with the most memory)
2016-01-20 10:00:15 +00:00
int ChooseBestTmu ( int tmu1 , int tmu2 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 18:22:45 +00:00
if ( ! GfxInitDone ) return tmu1 ;
2016-01-20 10:00:15 +00:00
if ( voodoo . tex_UMA ) return 0 ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
if ( tmu1 > = voodoo . num_tmu ) return tmu2 ;
if ( tmu2 > = voodoo . num_tmu ) return tmu1 ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
if ( voodoo . tex_max_addr [ tmu1 ] - voodoo . tmem_ptr [ tmu1 ] >
voodoo . tex_max_addr [ tmu2 ] - voodoo . tmem_ptr [ tmu2 ] )
return tmu1 ;
else
return tmu2 ;
2013-04-04 21:22:19 +00:00
}
//****************************************************************
// SelectTBuffTex - select texture from texture buffer
static void SelectTBuffTex ( TBUFF_COLOR_IMAGE * pTBuffTex )
{
2016-01-20 10:00:15 +00:00
FRDP ( " SelectTBuffTex: tex: %d, tmu: %d, tile: %d \n " , rdp . tex , pTBuffTex - > tmu , pTBuffTex - > tile ) ;
grTexSource ( pTBuffTex - > tile , pTBuffTex - > tex_addr , GR_MIPMAPLEVELMASK_BOTH , & ( pTBuffTex - > info ) ) ;
2013-04-04 21:22:19 +00:00
}
//****************************************************************
// TexCache - does texture loading after combiner is set
int SwapTextureBuffer ( ) ;
2016-01-20 10:00:15 +00:00
void TexCache ( )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
LRDP ( " |-+ TexCache called \n " ) ;
2013-04-04 21:22:19 +00:00
# ifdef TEXTURE_FILTER /* Hiroshi Morii <koolsmoky@users.sourceforge.net> */ // POSTNAPALM
2016-02-01 08:56:25 +00:00
if ( g_settings - > ghq_use & & g_settings - > ghq_hirs_dump ) {
2016-01-20 10:00:15 +00:00
/* Force reload hi-res textures. Useful for texture artists */
if ( CheckKeyPressed ( G64_VK_R , 0x0001 ) ) {
if ( ext_ghq_reloadhirestex ( ) ) ClearCache ( ) ;
}
/* Turn on texture dump */
else if ( CheckKeyPressed ( G64_VK_D , 0x0001 ) ) {
extern void DisplayLoadProgress ( const wchar_t * format , . . . ) ;
ghq_dmptex_toggle_key = ! ghq_dmptex_toggle_key ;
if ( ghq_dmptex_toggle_key ) {
DisplayLoadProgress ( L " Texture dump - ON \n " ) ;
ClearCache ( ) ;
}
else {
DisplayLoadProgress ( L " Texture dump - OFF \n " ) ;
}
2015-10-22 21:01:48 +00:00
# if defined(_WIN32)
2016-01-20 10:00:15 +00:00
Sleep ( 1000 ) ;
2015-10-22 21:01:48 +00:00
# else
2016-01-20 10:00:15 +00:00
SDL_Delay ( 1000 ) ;
2015-10-22 21:01:48 +00:00
# endif
2016-01-20 10:00:15 +00:00
}
2013-04-04 21:22:19 +00:00
}
# endif
2016-01-20 10:00:15 +00:00
if ( rdp . tex & 1 )
GetTexInfo ( 0 , rdp . cur_tile ) ;
if ( rdp . tex & 2 )
GetTexInfo ( 1 , rdp . cur_tile + 1 ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
TBUFF_COLOR_IMAGE * aTBuff [ 2 ] = { 0 , 0 } ;
if ( rdp . aTBuffTex [ 0 ] )
aTBuff [ rdp . aTBuffTex [ 0 ] - > tile ] = rdp . aTBuffTex [ 0 ] ;
if ( rdp . aTBuffTex [ 1 ] )
aTBuff [ rdp . aTBuffTex [ 1 ] - > tile ] = rdp . aTBuffTex [ 1 ] ;
2013-04-04 21:22:19 +00:00
# define TMUMODE_NORMAL 0
# define TMUMODE_PASSTHRU 1
# define TMUMODE_NONE 2
2016-01-20 10:00:15 +00:00
int tmu_0 , tmu_1 ;
int tmu_0_mode = 0 , tmu_1_mode = 0 ;
// Select the best TMUs to use (removed 3 tmu support, unnecessary)
if ( rdp . tex = = 3 ) // T0 and T1
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
tmu_0 = 0 ;
tmu_1 = 1 ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
else if ( rdp . tex = = 2 ) // T1
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
if ( tex_found [ 1 ] [ 0 ] ! = - 1 ) // T1 found in tmu 0
tmu_1 = 0 ;
else if ( tex_found [ 1 ] [ 1 ] ! = - 1 ) // T1 found in tmu 1
tmu_1 = 1 ;
else // T1 not found
tmu_1 = ChooseBestTmu ( 0 , 1 ) ;
tmu_0 = ! tmu_1 ;
tmu_0_mode = ( tmu_0 = = 1 ) ? TMUMODE_NONE : TMUMODE_PASSTHRU ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
else if ( rdp . tex = = 1 ) // T0
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
if ( tex_found [ 0 ] [ 0 ] ! = - 1 ) // T0 found in tmu 0
tmu_0 = 0 ;
else if ( tex_found [ 0 ] [ 1 ] ! = - 1 ) // T0 found in tmu 1
tmu_0 = 1 ;
else // T0 not found
tmu_0 = ChooseBestTmu ( 0 , 1 ) ;
tmu_1 = ! tmu_0 ;
tmu_1_mode = ( tmu_1 = = 1 ) ? TMUMODE_NONE : TMUMODE_PASSTHRU ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
else // no texture
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
tmu_0 = 0 ;
tmu_0_mode = TMUMODE_NONE ;
tmu_1 = 0 ;
tmu_1_mode = TMUMODE_NONE ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
FRDP ( " | |-+ Modes set: \n | | |- tmu_0 = %d \n | | |- tmu_1 = %d \n " ,
tmu_0 , tmu_1 ) ;
FRDP ( " | | |- tmu_0_mode = %d \n | | |- tmu_1_mode = %d \n " ,
tmu_0_mode , tmu_1_mode ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
if ( tmu_0_mode = = TMUMODE_PASSTHRU ) {
cmb . tmu0_func = cmb . tmu0_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER ;
cmb . tmu0_fac = cmb . tmu0_a_fac = GR_COMBINE_FACTOR_ONE ;
if ( cmb . tex_cmb_ext_use )
{
cmb . t0c_ext_a = GR_CMBX_OTHER_TEXTURE_RGB ;
cmb . t0c_ext_a_mode = GR_FUNC_MODE_X ;
cmb . t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB ;
cmb . t0c_ext_b_mode = GR_FUNC_MODE_ZERO ;
cmb . t0c_ext_c = GR_CMBX_ZERO ;
cmb . t0c_ext_c_invert = 1 ;
cmb . t0c_ext_d = GR_CMBX_ZERO ;
cmb . t0c_ext_d_invert = 0 ;
cmb . t0a_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA ;
cmb . t0a_ext_a_mode = GR_FUNC_MODE_X ;
cmb . t0a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA ;
cmb . t0a_ext_b_mode = GR_FUNC_MODE_ZERO ;
cmb . t0a_ext_c = GR_CMBX_ZERO ;
cmb . t0a_ext_c_invert = 1 ;
cmb . t0a_ext_d = GR_CMBX_ZERO ;
cmb . t0a_ext_d_invert = 0 ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
else if ( tmu_0_mode = = TMUMODE_NONE ) {
cmb . tmu0_func = cmb . tmu0_a_func = GR_COMBINE_FUNCTION_NONE ;
cmb . tmu0_fac = cmb . tmu0_a_fac = GR_COMBINE_FACTOR_NONE ;
if ( cmb . tex_cmb_ext_use )
{
cmb . t0c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB ;
cmb . t0c_ext_a_mode = GR_FUNC_MODE_ZERO ;
cmb . t0c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB ;
cmb . t0c_ext_b_mode = GR_FUNC_MODE_ZERO ;
cmb . t0c_ext_c = GR_CMBX_ZERO ;
cmb . t0c_ext_c_invert = 0 ;
cmb . t0c_ext_d = GR_CMBX_ZERO ;
cmb . t0c_ext_d_invert = 0 ;
cmb . t0a_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA ;
cmb . t0a_ext_a_mode = GR_FUNC_MODE_ZERO ;
cmb . t0a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA ;
cmb . t0a_ext_b_mode = GR_FUNC_MODE_ZERO ;
cmb . t0a_ext_c = GR_CMBX_ZERO ;
cmb . t0a_ext_c_invert = 0 ;
cmb . t0a_ext_d = GR_CMBX_ZERO ;
cmb . t0a_ext_d_invert = 0 ;
}
}
if ( tmu_1_mode = = TMUMODE_PASSTHRU ) {
cmb . tmu1_func = cmb . tmu1_a_func = GR_COMBINE_FUNCTION_SCALE_OTHER ;
cmb . tmu1_fac = cmb . tmu1_a_fac = GR_COMBINE_FACTOR_ONE ;
if ( cmb . tex_cmb_ext_use )
{
cmb . t1c_ext_a = GR_CMBX_OTHER_TEXTURE_RGB ;
cmb . t1c_ext_a_mode = GR_FUNC_MODE_X ;
cmb . t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB ;
cmb . t1c_ext_b_mode = GR_FUNC_MODE_ZERO ;
cmb . t1c_ext_c = GR_CMBX_ZERO ;
cmb . t1c_ext_c_invert = 1 ;
cmb . t1c_ext_d = GR_CMBX_ZERO ;
cmb . t1c_ext_d_invert = 0 ;
cmb . t1a_ext_a = GR_CMBX_OTHER_TEXTURE_ALPHA ;
cmb . t1a_ext_a_mode = GR_FUNC_MODE_X ;
cmb . t1a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA ;
cmb . t1a_ext_b_mode = GR_FUNC_MODE_ZERO ;
cmb . t1a_ext_c = GR_CMBX_ZERO ;
cmb . t1a_ext_c_invert = 1 ;
cmb . t1a_ext_d = GR_CMBX_ZERO ;
cmb . t1a_ext_d_invert = 0 ;
}
}
else if ( tmu_1_mode = = TMUMODE_NONE ) {
cmb . tmu1_func = cmb . tmu1_a_func = GR_COMBINE_FUNCTION_NONE ;
cmb . tmu1_fac = cmb . tmu1_a_fac = GR_COMBINE_FACTOR_NONE ;
if ( cmb . tex_cmb_ext_use )
{
cmb . t1c_ext_a = GR_CMBX_LOCAL_TEXTURE_RGB ;
cmb . t1c_ext_a_mode = GR_FUNC_MODE_ZERO ;
cmb . t1c_ext_b = GR_CMBX_LOCAL_TEXTURE_RGB ;
cmb . t1c_ext_b_mode = GR_FUNC_MODE_ZERO ;
cmb . t1c_ext_c = GR_CMBX_ZERO ;
cmb . t1c_ext_c_invert = 0 ;
cmb . t1c_ext_d = GR_CMBX_ZERO ;
cmb . t1c_ext_d_invert = 0 ;
cmb . t1a_ext_a = GR_CMBX_LOCAL_TEXTURE_ALPHA ;
cmb . t1a_ext_a_mode = GR_FUNC_MODE_ZERO ;
cmb . t1a_ext_b = GR_CMBX_LOCAL_TEXTURE_ALPHA ;
cmb . t1a_ext_b_mode = GR_FUNC_MODE_ZERO ;
cmb . t1a_ext_c = GR_CMBX_ZERO ;
cmb . t1a_ext_c_invert = 0 ;
cmb . t1a_ext_d = GR_CMBX_ZERO ;
cmb . t1a_ext_d_invert = 0 ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
// little change to make single-tmu cards look better, use first texture no matter what
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
if ( voodoo . num_tmu = = 1 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
if ( rdp . best_tex = = 0 )
{
cmb . tmu0_func = cmb . tmu0_a_func = GR_COMBINE_FUNCTION_LOCAL ;
cmb . tmu0_fac = cmb . tmu0_a_fac = GR_COMBINE_FACTOR_NONE ;
tmu_0 = 0 ;
tmu_1 = 1 ;
}
else
{
cmb . tmu1_func = cmb . tmu1_a_func = GR_COMBINE_FUNCTION_LOCAL ;
cmb . tmu1_fac = cmb . tmu1_a_fac = GR_COMBINE_FACTOR_NONE ;
tmu_1 = 0 ;
tmu_0 = 1 ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
rdp . t0 = tmu_0 ;
rdp . t1 = tmu_1 ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
// SET the combiner
2016-01-20 18:22:45 +00:00
if ( GfxInitDone )
2013-04-04 21:22:19 +00:00
{
2016-01-20 18:22:45 +00:00
if ( rdp . allow_combine )
2016-01-20 10:00:15 +00:00
{
2016-01-20 18:22:45 +00:00
// Now actually combine
if ( cmb . cmb_ext_use )
{
LRDP ( " | | | |- combiner extension \n " ) ;
if ( ! ( cmb . cmb_ext_use & COMBINE_EXT_COLOR ) )
ColorCombinerToExtension ( ) ;
if ( ! ( cmb . cmb_ext_use & COMBINE_EXT_ALPHA ) )
AlphaCombinerToExtension ( ) ;
cmb . grColorCombineExt ( cmb . c_ext_a , cmb . c_ext_a_mode ,
cmb . c_ext_b , cmb . c_ext_b_mode ,
cmb . c_ext_c , cmb . c_ext_c_invert ,
cmb . c_ext_d , cmb . c_ext_d_invert , 0 , 0 ) ;
cmb . grAlphaCombineExt ( cmb . a_ext_a , cmb . a_ext_a_mode ,
cmb . a_ext_b , cmb . a_ext_b_mode ,
cmb . a_ext_c , cmb . a_ext_c_invert ,
cmb . a_ext_d , cmb . a_ext_d_invert , 0 , 0 ) ;
}
else
{
grColorCombine ( cmb . c_fnc , cmb . c_fac , cmb . c_loc , cmb . c_oth , FXFALSE ) ;
grAlphaCombine ( cmb . a_fnc , cmb . a_fac , cmb . a_loc , cmb . a_oth , FXFALSE ) ;
}
grConstantColorValue ( cmb . ccolor ) ;
grAlphaBlendFunction ( cmb . abf1 , cmb . abf2 , GR_BLEND_ZERO , GR_BLEND_ZERO ) ;
if ( ! rdp . tex ) //nothing more to do
return ;
2016-01-20 10:00:15 +00:00
}
2013-04-04 21:22:19 +00:00
2016-01-20 18:22:45 +00:00
if ( tmu_1 < voodoo . num_tmu )
2016-01-20 10:00:15 +00:00
{
2016-01-20 18:22:45 +00:00
if ( cmb . tex_cmb_ext_use )
{
LRDP ( " | | | |- combiner extension tmu1 \n " ) ;
if ( ! ( cmb . tex_cmb_ext_use & TEX_COMBINE_EXT_COLOR ) )
TexColorCombinerToExtension ( GR_TMU1 ) ;
if ( ! ( cmb . tex_cmb_ext_use & TEX_COMBINE_EXT_ALPHA ) )
TexAlphaCombinerToExtension ( GR_TMU1 ) ;
cmb . grTexColorCombineExt ( tmu_1 , cmb . t1c_ext_a , cmb . t1c_ext_a_mode ,
cmb . t1c_ext_b , cmb . t1c_ext_b_mode ,
cmb . t1c_ext_c , cmb . t1c_ext_c_invert ,
cmb . t1c_ext_d , cmb . t1c_ext_d_invert , 0 , 0 ) ;
cmb . grTexAlphaCombineExt ( tmu_1 , cmb . t1a_ext_a , cmb . t1a_ext_a_mode ,
cmb . t1a_ext_b , cmb . t1a_ext_b_mode ,
cmb . t1a_ext_c , cmb . t1a_ext_c_invert ,
cmb . t1a_ext_d , cmb . t1a_ext_d_invert , 0 , 0 ) ;
cmb . grConstantColorValueExt ( tmu_1 , cmb . tex_ccolor ) ;
}
else
{
grTexCombine ( tmu_1 , cmb . tmu1_func , cmb . tmu1_fac , cmb . tmu1_a_func , cmb . tmu1_a_fac , cmb . tmu1_invert , cmb . tmu1_a_invert ) ;
if ( cmb . combine_ext )
cmb . grConstantColorValueExt ( tmu_1 , 0 ) ;
}
grTexDetailControl ( tmu_1 , cmb . dc1_lodbias , cmb . dc1_detailscale , cmb . dc1_detailmax ) ;
grTexLodBiasValue ( tmu_1 , cmb . lodbias1 ) ;
2016-01-20 17:12:15 +00:00
}
2016-01-20 18:22:45 +00:00
if ( tmu_0 < voodoo . num_tmu )
2016-01-20 17:12:15 +00:00
{
2016-01-20 18:22:45 +00:00
if ( cmb . tex_cmb_ext_use )
{
LRDP ( " | | | |- combiner extension tmu0 \n " ) ;
if ( ! ( cmb . tex_cmb_ext_use & TEX_COMBINE_EXT_COLOR ) )
TexColorCombinerToExtension ( GR_TMU0 ) ;
if ( ! ( cmb . tex_cmb_ext_use & TEX_COMBINE_EXT_ALPHA ) )
TexAlphaCombinerToExtension ( GR_TMU0 ) ;
cmb . grTexColorCombineExt ( tmu_0 , cmb . t0c_ext_a , cmb . t0c_ext_a_mode ,
cmb . t0c_ext_b , cmb . t0c_ext_b_mode ,
cmb . t0c_ext_c , cmb . t0c_ext_c_invert ,
cmb . t0c_ext_d , cmb . t0c_ext_d_invert , 0 , 0 ) ;
cmb . grTexAlphaCombineExt ( tmu_0 , cmb . t0a_ext_a , cmb . t0a_ext_a_mode ,
cmb . t0a_ext_b , cmb . t0a_ext_b_mode ,
cmb . t0a_ext_c , cmb . t0a_ext_c_invert ,
cmb . t0a_ext_d , cmb . t0a_ext_d_invert , 0 , 0 ) ;
cmb . grConstantColorValueExt ( tmu_0 , cmb . tex_ccolor ) ;
}
else
{
grTexCombine ( tmu_0 , cmb . tmu0_func , cmb . tmu0_fac , cmb . tmu0_a_func , cmb . tmu0_a_fac , cmb . tmu0_invert , cmb . tmu0_a_invert ) ;
if ( cmb . combine_ext )
cmb . grConstantColorValueExt ( tmu_0 , 0 ) ;
}
grTexDetailControl ( tmu_0 , cmb . dc0_lodbias , cmb . dc0_detailscale , cmb . dc0_detailmax ) ;
grTexLodBiasValue ( tmu_0 , cmb . lodbias0 ) ;
2016-01-20 10:00:15 +00:00
}
}
2015-02-01 17:47:09 +00:00
2016-01-20 10:00:15 +00:00
if ( ( rdp . tex & 1 ) & & tmu_0 < voodoo . num_tmu )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
if ( aTBuff [ 0 ] & & aTBuff [ 0 ] - > cache )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
LRDP ( " | |- Hires tex T0 found in cache. \n " ) ;
2016-01-20 18:22:45 +00:00
if ( GfxInitDone )
{
rdp . cur_cache [ 0 ] = aTBuff [ 0 ] - > cache ;
rdp . cur_cache [ 0 ] - > last_used = frame_count ;
rdp . cur_cache [ 0 ] - > uses = rdp . debug_n ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
else if ( tex_found [ 0 ] [ tmu_0 ] ! = - 1 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
LRDP ( " | |- T0 found in cache. \n " ) ;
2016-01-20 18:22:45 +00:00
if ( GfxInitDone )
{
CACHE_LUT * cache = voodoo . tex_UMA ? & rdp . cache [ 0 ] [ tex_found [ 0 ] [ 0 ] ] : & rdp . cache [ tmu_0 ] [ tex_found [ 0 ] [ tmu_0 ] ] ;
rdp . cur_cache_n [ 0 ] = tex_found [ 0 ] [ tmu_0 ] ;
rdp . cur_cache [ 0 ] = cache ;
rdp . cur_cache [ 0 ] - > last_used = frame_count ;
rdp . cur_cache [ 0 ] - > uses = rdp . debug_n ;
grTexSource ( tmu_0 ,
( voodoo . tex_min_addr [ tmu_0 ] + cache - > tmem_addr ) ,
GR_MIPMAPLEVELMASK_BOTH ,
& cache - > t_info ) ;
}
2013-04-04 21:22:19 +00:00
}
else
2016-01-20 10:00:15 +00:00
LoadTex ( 0 , tmu_0 ) ;
}
if ( ( rdp . tex & 2 ) & & tmu_1 < voodoo . num_tmu )
{
if ( aTBuff [ 1 ] & & aTBuff [ 1 ] - > cache )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
LRDP ( " | |- Hires tex T1 found in cache. \n " ) ;
2016-01-20 18:22:45 +00:00
if ( GfxInitDone )
{
rdp . cur_cache [ 1 ] = aTBuff [ 1 ] - > cache ;
rdp . cur_cache [ 1 ] - > last_used = frame_count ;
rdp . cur_cache [ 1 ] - > uses = rdp . debug_n ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
else if ( tex_found [ 1 ] [ tmu_1 ] ! = - 1 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
LRDP ( " | |- T1 found in cache. \n " ) ;
2016-01-20 18:22:45 +00:00
if ( GfxInitDone )
{
CACHE_LUT * cache = voodoo . tex_UMA ? & rdp . cache [ 0 ] [ tex_found [ 1 ] [ 0 ] ] : & rdp . cache [ tmu_1 ] [ tex_found [ 1 ] [ tmu_1 ] ] ;
rdp . cur_cache_n [ 1 ] = tex_found [ 1 ] [ tmu_1 ] ;
rdp . cur_cache [ 1 ] = cache ;
rdp . cur_cache [ 1 ] - > last_used = frame_count ;
rdp . cur_cache [ 1 ] - > uses = rdp . debug_n ;
grTexSource ( tmu_1 ,
( voodoo . tex_min_addr [ tmu_1 ] + cache - > tmem_addr ) ,
GR_MIPMAPLEVELMASK_BOTH ,
& cache - > t_info ) ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
else
LoadTex ( 1 , tmu_1 ) ;
}
2013-04-04 21:22:19 +00:00
2016-01-20 18:22:45 +00:00
if ( GfxInitDone )
2016-01-20 10:00:15 +00:00
{
2016-01-20 18:22:45 +00:00
int tmu_v [ 2 ] ;
2016-01-20 10:00:15 +00:00
2016-01-20 18:22:45 +00:00
tmu_v [ 0 ] = tmu_0 ;
tmu_v [ 1 ] = tmu_1 ;
for ( int i = 0 ; i < 2 ; i + + )
{
const int tmu = tmu_v [ i ] ;
2016-01-20 10:00:15 +00:00
2016-01-20 18:22:45 +00:00
if ( tmu > = voodoo . num_tmu ) continue ;
2016-01-20 10:00:15 +00:00
2016-01-20 18:22:45 +00:00
int tile = rdp . cur_tile + i ;
2016-01-20 10:00:15 +00:00
2016-02-01 08:56:25 +00:00
if ( g_settings - > filtering = = 0 )
2016-01-20 10:00:15 +00:00
{
2016-01-20 18:22:45 +00:00
int filter = ( rdp . filter_mode ! = 2 ) ? GR_TEXTUREFILTER_POINT_SAMPLED : GR_TEXTUREFILTER_BILINEAR ;
grTexFilterMode ( tmu , filter , filter ) ;
2016-01-20 10:00:15 +00:00
}
else
{
2016-02-01 08:56:25 +00:00
int filter = ( g_settings - > filtering = = 1 ) ? GR_TEXTUREFILTER_BILINEAR : GR_TEXTUREFILTER_POINT_SAMPLED ;
2016-01-20 18:22:45 +00:00
grTexFilterMode ( tmu , filter , filter ) ;
2016-01-20 10:00:15 +00:00
}
2016-01-20 18:22:45 +00:00
if ( rdp . cur_cache [ i ] )
2016-01-20 10:00:15 +00:00
{
2016-01-20 18:22:45 +00:00
uint32_t mode_s , mode_t ;
int clamp_s , clamp_t ;
if ( rdp . force_wrap & & ! rdp . texrecting )
{
clamp_s = rdp . tiles [ tile ] . clamp_s & & rdp . tiles [ tile ] . lr_s - rdp . tiles [ tile ] . ul_s < 256 ;
clamp_t = rdp . tiles [ tile ] . clamp_t & & rdp . tiles [ tile ] . lr_t - rdp . tiles [ tile ] . ul_t < 256 ;
}
2016-01-20 10:00:15 +00:00
else
2016-01-20 18:22:45 +00:00
{
clamp_s = ( rdp . tiles [ tile ] . clamp_s | | rdp . tiles [ tile ] . mask_s = = 0 ) & &
rdp . tiles [ tile ] . lr_s - rdp . tiles [ tile ] . ul_s < 256 ;
clamp_t = ( rdp . tiles [ tile ] . clamp_t | | rdp . tiles [ tile ] . mask_t = = 0 ) & &
rdp . tiles [ tile ] . lr_t - rdp . tiles [ tile ] . ul_t < 256 ;
}
if ( rdp . cur_cache [ i ] - > f_mirror_s )
mode_s = GR_TEXTURECLAMP_MIRROR_EXT ;
else if ( rdp . cur_cache [ i ] - > f_wrap_s )
2016-01-20 17:12:15 +00:00
mode_s = GR_TEXTURECLAMP_WRAP ;
2016-01-20 18:22:45 +00:00
else if ( clamp_s )
mode_s = GR_TEXTURECLAMP_CLAMP ;
else
{
if ( rdp . tiles [ tile ] . mirror_s & & voodoo . sup_mirroring )
mode_s = GR_TEXTURECLAMP_MIRROR_EXT ;
else
mode_s = GR_TEXTURECLAMP_WRAP ;
}
2016-01-20 10:00:15 +00:00
2016-01-20 18:22:45 +00:00
if ( rdp . cur_cache [ i ] - > f_mirror_t )
2016-01-20 10:00:15 +00:00
mode_t = GR_TEXTURECLAMP_MIRROR_EXT ;
2016-01-20 18:22:45 +00:00
else if ( rdp . cur_cache [ i ] - > f_wrap_t )
2016-01-20 17:12:15 +00:00
mode_t = GR_TEXTURECLAMP_WRAP ;
2016-01-20 18:22:45 +00:00
else if ( clamp_t )
mode_t = GR_TEXTURECLAMP_CLAMP ;
else
{
if ( rdp . tiles [ tile ] . mirror_t & & voodoo . sup_mirroring )
mode_t = GR_TEXTURECLAMP_MIRROR_EXT ;
else
mode_t = GR_TEXTURECLAMP_WRAP ;
}
2016-01-20 17:12:15 +00:00
2016-01-20 18:22:45 +00:00
grTexClampMode ( tmu ,
mode_s ,
mode_t ) ;
}
if ( aTBuff [ i ] & & ( rdp . tex & ( i + 1 ) ) )
SelectTBuffTex ( aTBuff [ i ] ) ;
2016-01-20 10:00:15 +00:00
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
LRDP ( " | +- TexCache End \n " ) ;
2013-04-04 21:22:19 +00:00
}
# ifdef TEXTURE_FILTER
/** cite from RiceVideo */
2016-01-20 06:14:48 +00:00
inline uint32_t CalculateDXT ( uint32_t txl2words )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
if ( txl2words = = 0 ) return 1 ;
else return ( 2048 + txl2words - 1 ) / txl2words ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
uint32_t sizeBytes [ 4 ] = { 0 , 1 , 2 , 4 } ;
2013-04-04 21:22:19 +00:00
2016-01-20 06:14:48 +00:00
inline uint32_t Txl2Words ( uint32_t width , uint32_t size )
2013-04-04 21:22:19 +00:00
{
2016-01-25 11:13:35 +00:00
return size = = 0 ? maxval ( 1 , width / 16 ) : maxval ( 1 , width * sizeBytes [ size ] / 8 ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 06:14:48 +00:00
inline uint32_t ReverseDXT ( uint32_t val , uint32_t /*lrs*/ , uint32_t width , uint32_t size )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
if ( val = = 0x800 ) return 1 ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
int low = 2047 / val ;
if ( CalculateDXT ( low ) > val ) low + + ;
int high = 2047 / ( val - 1 ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
if ( low = = high ) return low ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
for ( int i = low ; i < = high ; i + + )
{
if ( Txl2Words ( width , size ) = = ( uint32_t ) i )
return i ;
}
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
return ( low + high ) / 2 ;
2013-04-04 21:22:19 +00:00
}
/** end RiceVideo cite */
# endif
//****************************************************************
// LoadTex - does the actual texture loading after everything is prepared
2016-01-20 10:00:15 +00:00
void LoadTex ( int id , int tmu )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
FRDP ( " | |-+ LoadTex (id: %d, tmu: %d) \n " , id , tmu ) ;
int td = rdp . cur_tile + id ;
int lod , aspect ;
CACHE_LUT * cache ;
if ( texinfo [ id ] . width < 0 | | texinfo [ id ] . height < 0 )
return ;
// Clear the cache if it's full
if ( rdp . n_cached [ tmu ] > = MAX_CACHE )
{
LRDP ( " Cache count reached, clearing... \n " ) ;
ClearCache ( ) ;
if ( id = = 1 & & rdp . tex = = 3 )
LoadTex ( 0 , rdp . t0 ) ;
}
// Get this cache object
cache = voodoo . tex_UMA ? & rdp . cache [ 0 ] [ rdp . n_cached [ 0 ] ] : & rdp . cache [ tmu ] [ rdp . n_cached [ tmu ] ] ;
memset ( cache , 0 , sizeof ( * cache ) ) ;
rdp . cur_cache [ id ] = cache ;
rdp . cur_cache_n [ id ] = rdp . n_cached [ tmu ] ;
//!Hackalert
//GoldenEye water texture. It has CI format in fact, but the game set it to RGBA
2016-02-01 08:56:25 +00:00
if ( ( g_settings - > hacks & hack_GoldenEye ) & & rdp . tiles [ td ] . format = = 0 & & rdp . tlut_mode = = 2 & & rdp . tiles [ td ] . size = = 2 )
2016-01-20 10:00:15 +00:00
{
rdp . tiles [ td ] . format = 2 ;
rdp . tiles [ td ] . size = 1 ;
}
// Set the data
cache - > line = rdp . tiles [ td ] . line ;
cache - > addr = rdp . addr [ rdp . tiles [ td ] . t_mem ] ;
cache - > crc = texinfo [ id ] . crc ;
cache - > palette = rdp . tiles [ td ] . palette ;
cache - > width = rdp . tiles [ td ] . width ;
cache - > height = rdp . tiles [ td ] . height ;
cache - > format = rdp . tiles [ td ] . format ;
cache - > size = rdp . tiles [ td ] . size ;
cache - > tmem_addr = voodoo . tmem_ptr [ tmu ] ;
cache - > set_by = rdp . timg . set_by ;
cache - > texrecting = rdp . texrecting ;
cache - > last_used = frame_count ;
cache - > uses = rdp . debug_n ;
cache - > flags = texinfo [ id ] . flags ;
cache - > f_mirror_s = FALSE ;
cache - > f_mirror_t = FALSE ;
cache - > f_wrap_s = FALSE ;
cache - > f_wrap_t = FALSE ;
2013-04-04 21:22:19 +00:00
# ifdef TEXTURE_FILTER
2016-01-20 10:00:15 +00:00
cache - > is_hires_tex = FALSE ;
cache - > ricecrc = texinfo [ id ] . ricecrc ;
2013-04-04 21:22:19 +00:00
# endif
2016-01-20 10:00:15 +00:00
// Add this cache to the list
2016-01-25 10:23:28 +00:00
AddToList ( & cachelut [ cache - > crc > > 16 ] , cache - > crc , uintptr_t ( cache ) , tmu , rdp . n_cached [ tmu ] ) ;
2016-01-20 10:00:15 +00:00
// temporary
cache - > t_info . format = GR_TEXFMT_ARGB_1555 ;
// Calculate lod and aspect
uint32_t size_x = rdp . tiles [ td ] . width ;
uint32_t size_y = rdp . tiles [ td ] . height ;
// make size_x and size_y both powers of two
if ( ! voodoo . sup_large_tex )
{
if ( size_x > 256 ) size_x = 256 ;
if ( size_y > 256 ) size_y = 256 ;
}
int shift ;
for ( shift = 0 ; ( 1 < < shift ) < ( int ) size_x ; shift + + ) ;
size_x = 1 < < shift ;
for ( shift = 0 ; ( 1 < < shift ) < ( int ) size_y ; shift + + ) ;
size_y = 1 < < shift ;
// Voodoo 1 support is all here, it will automatically mirror to the full extent.
if ( ! voodoo . sup_mirroring )
{
if ( rdp . tiles [ td ] . mirror_s & & ! rdp . tiles [ td ] . clamp_s & & ( voodoo . sup_large_tex | | size_x < = 128 ) )
size_x < < = 1 ;
if ( rdp . tiles [ td ] . mirror_t & & ! rdp . tiles [ td ] . clamp_t & & ( voodoo . sup_large_tex | | size_y < = 128 ) )
size_y < < = 1 ;
}
// Calculate the maximum size
2016-01-25 09:58:29 +00:00
int size_max = maxval ( size_x , size_y ) ;
2016-01-20 10:00:15 +00:00
uint32_t real_x = size_max , real_y = size_max ;
switch ( size_max )
2013-04-04 21:22:19 +00:00
{
case 1 :
2016-01-20 10:00:15 +00:00
lod = GR_LOD_LOG2_1 ;
cache - > scale = 256.0f ;
break ;
2013-04-04 21:22:19 +00:00
case 2 :
2016-01-20 10:00:15 +00:00
lod = GR_LOD_LOG2_2 ;
cache - > scale = 128.0f ;
break ;
2013-04-04 21:22:19 +00:00
case 4 :
2016-01-20 10:00:15 +00:00
lod = GR_LOD_LOG2_4 ;
cache - > scale = 64.0f ;
break ;
case 8 :
lod = GR_LOD_LOG2_8 ;
cache - > scale = 32.0f ;
break ;
case 16 :
lod = GR_LOD_LOG2_16 ;
cache - > scale = 16.0f ;
break ;
case 32 :
lod = GR_LOD_LOG2_32 ;
cache - > scale = 8.0f ;
break ;
case 64 :
lod = GR_LOD_LOG2_64 ;
cache - > scale = 4.0f ;
break ;
case 128 :
lod = GR_LOD_LOG2_128 ;
cache - > scale = 2.0f ;
break ;
case 256 :
lod = GR_LOD_LOG2_256 ;
cache - > scale = 1.0f ;
break ;
case 512 :
lod = GR_LOD_LOG2_512 ;
cache - > scale = 0.5f ;
break ;
2013-04-04 21:22:19 +00:00
default :
2016-01-20 10:00:15 +00:00
lod = GR_LOD_LOG2_1024 ;
cache - > scale = 0.25f ;
break ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
// Calculate the aspect ratio
if ( size_x > = size_y )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
int ratio = size_x / size_y ;
switch ( ratio )
{
case 1 :
aspect = GR_ASPECT_LOG2_1x1 ;
cache - > scale_x = 1.0f ;
cache - > scale_y = 1.0f ;
break ;
case 2 :
aspect = GR_ASPECT_LOG2_2x1 ;
cache - > scale_x = 1.0f ;
cache - > scale_y = 0.5f ;
real_y > > = 1 ;
break ;
case 4 :
aspect = GR_ASPECT_LOG2_4x1 ;
cache - > scale_x = 1.0f ;
cache - > scale_y = 0.25f ;
real_y > > = 2 ;
break ;
default :
aspect = GR_ASPECT_LOG2_8x1 ;
cache - > scale_x = 1.0f ;
cache - > scale_y = 0.125f ;
real_y > > = 3 ;
break ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
else
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
int ratio = size_y / size_x ;
switch ( ratio )
{
case 2 :
aspect = GR_ASPECT_LOG2_1x2 ;
cache - > scale_x = 0.5f ;
cache - > scale_y = 1.0f ;
real_x > > = 1 ;
break ;
case 4 :
aspect = GR_ASPECT_LOG2_1x4 ;
cache - > scale_x = 0.25f ;
cache - > scale_y = 1.0f ;
real_x > > = 2 ;
break ;
default :
aspect = GR_ASPECT_LOG2_1x8 ;
cache - > scale_x = 0.125f ;
cache - > scale_y = 1.0f ;
real_x > > = 3 ;
break ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
if ( real_x ! = cache - > width | | real_y ! = cache - > height )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
cache - > scale_x * = ( float ) cache - > width / ( float ) real_x ;
cache - > scale_y * = ( float ) cache - > height / ( float ) real_y ;
}
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
int splits = texinfo [ id ] . splits ;
cache - > splits = texinfo [ id ] . splits ;
cache - > splitheight = real_y / cache - > splits ;
if ( cache - > splitheight < texinfo [ id ] . splitheight )
cache - > splitheight = texinfo [ id ] . splitheight ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
// ** Calculate alignment values
int wid = cache - > width ;
int hei = cache - > height ;
if ( splits > 1 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
wid = texinfo [ id ] . real_image_width ;
hei = texinfo [ id ] . real_image_height ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
cache - > c_off = cache - > scale * 0.5f ;
if ( wid ! = 1 ) cache - > c_scl_x = cache - > scale ;
else cache - > c_scl_x = 0.0f ;
if ( hei ! = 1 ) cache - > c_scl_y = cache - > scale ;
else cache - > c_scl_y = 0.0f ;
// **
uint32_t mod , modcolor , modcolor1 , modcolor2 , modfactor ;
if ( id = = 0 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
mod = cmb . mod_0 ;
modcolor = cmb . modcolor_0 ;
modcolor1 = cmb . modcolor1_0 ;
modcolor2 = cmb . modcolor2_0 ;
modfactor = cmb . modfactor_0 ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
else
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
mod = cmb . mod_1 ;
modcolor = cmb . modcolor_1 ;
modcolor1 = cmb . modcolor1_1 ;
modcolor2 = cmb . modcolor2_1 ;
modfactor = cmb . modfactor_1 ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
uint16_t tmp_pal [ 256 ] ;
int modifyPalette = ( mod & & ( cache - > format = = 2 ) & & ( rdp . tlut_mode = = 2 ) ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
if ( modifyPalette )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
memcpy ( tmp_pal , rdp . pal_8 , 512 ) ;
ModifyPalette ( mod , modcolor , modcolor1 , modfactor ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
cache - > mod = mod ;
cache - > mod_color = modcolor ;
cache - > mod_color1 = modcolor1 ;
cache - > mod_factor = modfactor ;
for ( int t = 0 ; t < 2 ; t + + ) {
if ( rdp . aTBuffTex [ t ] & & rdp . aTBuffTex [ t ] - > tile = = id ) //texture buffer will be used instead of frame buffer texture
{
rdp . aTBuffTex [ t ] - > cache = cache ;
FRDP ( " tbuff_tex selected: %d, tile=%d \n " , t , id ) ;
return ;
}
}
uint32_t result = 0 ; // keep =0 so it doesn't mess up on the first split
texture = tex1 ;
// Hiroshi Morii <koolsmoky@users.sourceforge.net>
// NOTE: Loading Hi-res texture packs and filtering should be done
// before the texture is modified with color palettes, etc.
//
// Since the internal texture identification needs Glide64CRC, (RiceCRC
// doesn't always return unique values) it seems reasonable that the
// extra CRC calculation for hires textures should be executed only
// when we get passed the texture ram cache and texture buffers for
// minimal calculation overhead.
//
# ifdef TEXTURE_FILTER // Hiroshi Morii <koolsmoky@users.sourceforge.net>
GHQTexInfo ghqTexInfo ;
memset ( & ghqTexInfo , 0 , sizeof ( GHQTexInfo ) ) ;
uint32_t g64_crc = cache - > crc ;
2016-02-01 08:56:25 +00:00
if ( g_settings - > ghq_use )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
int bpl ;
uint8_t * addr = ( uint8_t * ) ( gfx . RDRAM + rdp . addr [ rdp . tiles [ td ] . t_mem ] ) ;
int tile_width = texinfo [ id ] . width ;
int tile_height = texinfo [ id ] . height ;
LOAD_TILE_INFO & info = rdp . load_info [ rdp . tiles [ td ] . t_mem ] ;
if ( rdp . timg . set_by = = 1 )
{
bpl = info . tex_width < < info . tex_size > > 1 ;
addr + = ( info . tile_ul_t * bpl ) + ( ( ( info . tile_ul_s < < info . tex_size ) + 1 ) > > 1 ) ;
2016-01-25 09:58:29 +00:00
tile_width = minval ( info . tile_width , info . tex_width ) ;
2016-01-20 10:00:15 +00:00
if ( info . tex_size > rdp . tiles [ td ] . size )
tile_width < < = info . tex_size - rdp . tiles [ td ] . size ;
if ( rdp . tiles [ td ] . lr_t > rdp . bg_image_height )
tile_height = rdp . bg_image_height - rdp . tiles [ td ] . ul_t ;
else
tile_height = info . tile_height ;
}
2013-04-04 21:22:19 +00:00
else
2016-01-20 10:00:15 +00:00
{
if ( rdp . tiles [ td ] . size = = 3 )
bpl = rdp . tiles [ td ] . line < < 4 ;
else if ( info . dxt = = 0 )
bpl = rdp . tiles [ td ] . line < < 3 ;
else {
uint32_t dxt = info . dxt ;
if ( dxt > 1 )
dxt = ReverseDXT ( dxt , info . tile_width , texinfo [ id ] . width , rdp . tiles [ td ] . size ) ;
bpl = dxt < < 3 ;
}
}
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
// uint8_t* addr = (uint8_t*)(gfx.RDRAM+rdp.addr[rdp.tiles[td].t_mem] + (rdp.tiles[td].ul_t * bpl) + (((rdp.tiles[td].ul_s<<rdp.tiles[td].size)+1)>>1));
uint8_t * paladdr = 0 ;
uint16_t * palette = 0 ;
if ( ( rdp . tiles [ td ] . size < 2 ) & & ( rdp . tlut_mode | | rdp . tiles [ td ] . format = = 2 ) )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
if ( rdp . tiles [ td ] . size = = 1 )
paladdr = ( uint8_t * ) ( rdp . pal_8_rice ) ;
2016-02-01 08:56:25 +00:00
else if ( g_settings - > ghq_hirs_altcrc )
2016-01-20 10:00:15 +00:00
paladdr = ( uint8_t * ) ( rdp . pal_8_rice + ( rdp . tiles [ td ] . palette < < 5 ) ) ;
else
paladdr = ( uint8_t * ) ( rdp . pal_8_rice + ( rdp . tiles [ td ] . palette < < 4 ) ) ;
palette = ( rdp . pal_8 + ( rdp . tiles [ td ] . palette < < 4 ) ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
// XXX: Special combiner modes are ignored for hires textures
// for now. Come back to this later!! The following is needed
// for (2xSai, hq4x, etc) enhanced/filtered textures.
g64_crc = CRC32 ( g64_crc , & cache - > mod , 4 ) ;
g64_crc = CRC32 ( g64_crc , & cache - > mod_color , 4 ) ;
g64_crc = CRC32 ( g64_crc , & cache - > mod_color1 , 4 ) ;
//g64_crc = CRC32( g64_crc, &cache->mod_color2, 4 ); // not used?
g64_crc = CRC32 ( g64_crc , & cache - > mod_factor , 4 ) ;
cache - > ricecrc = ext_ghq_checksum ( addr , tile_width , tile_height , ( unsigned short ) ( rdp . tiles [ td ] . format < < 8 | rdp . tiles [ td ] . size ) , bpl , paladdr ) ;
FRDP ( " CI RICE CRC. format: %d, size: %d, CRC: %08lx, PalCRC: %08lx \n " , rdp . tiles [ td ] . format , rdp . tiles [ td ] . size , ( uint32_t ) ( cache - > ricecrc & 0xFFFFFFFF ) , ( uint32_t ) ( cache - > ricecrc > > 32 ) ) ;
if ( ext_ghq_hirestex ( ( uint64 ) g64_crc , cache - > ricecrc , palette , & ghqTexInfo ) )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
cache - > is_hires_tex = ghqTexInfo . is_hires_tex ;
if ( ! ghqTexInfo . is_hires_tex & & aspect ! = ghqTexInfo . aspectRatioLog2 )
ghqTexInfo . data = 0 ; //if aspects of current texture and found filtered texture are different, texture must be filtered again.
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
}
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
// ** handle texture splitting **
if ( ghqTexInfo . data )
; //do nothing
else
# endif
if ( splits > 1 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 10:00:15 +00:00
cache - > scale_y = 0.125f ;
int i ;
for ( i = 0 ; i < splits ; i + + )
{
int start_dst = i * cache - > splitheight * 256 ; // start lower
start_dst < < = HIWORD ( result ) ; // 1st time, result is set to 0, but start_dst is 0 anyway so it doesn't matter
int start_src = i * 256 ; // start 256 more to the right
start_src = start_src < < ( rdp . tiles [ td ] . size ) > > 1 ;
if ( rdp . tiles [ td ] . size = = 3 )
start_src > > = 1 ;
result = load_table [ rdp . tiles [ td ] . size ] [ rdp . tiles [ td ] . format ]
2016-01-25 10:23:28 +00:00
( uintptr_t ( texture ) + start_dst , uintptr_t ( rdp . tmem ) + ( rdp . tiles [ td ] . t_mem < < 3 ) + start_src ,
2016-01-20 10:00:15 +00:00
texinfo [ id ] . wid_64 , texinfo [ id ] . height , texinfo [ id ] . line , real_x , td ) ;
uint32_t size = HIWORD ( result ) ;
// clamp so that it looks somewhat ok when wrapping
if ( size = = 1 )
Clamp16bT ( ( texture ) + start_dst , texinfo [ id ] . height , real_x , cache - > splitheight ) ;
else if ( size ! = 2 )
Clamp8bT ( ( texture ) + start_dst , texinfo [ id ] . height , real_x , cache - > splitheight ) ;
else
Clamp32bT ( ( texture ) + start_dst , texinfo [ id ] . height , real_x , cache - > splitheight ) ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 10:00:15 +00:00
// ** end texture splitting **
2013-04-04 21:22:19 +00:00
else
{
2016-01-20 10:00:15 +00:00
result = load_table [ rdp . tiles [ td ] . size ] [ rdp . tiles [ td ] . format ]
2016-01-25 10:23:28 +00:00
( uintptr_t ( texture ) , uintptr_t ( rdp . tmem ) + ( rdp . tiles [ td ] . t_mem < < 3 ) ,
2016-01-20 10:00:15 +00:00
texinfo [ id ] . wid_64 , texinfo [ id ] . height , texinfo [ id ] . line , real_x , td ) ;
uint32_t size = HIWORD ( result ) ;
int min_x , min_y ;
if ( rdp . tiles [ td ] . mask_s ! = 0 )
2016-01-25 09:58:29 +00:00
min_x = minval ( ( int ) real_x , 1 < < rdp . tiles [ td ] . mask_s ) ;
2016-01-20 10:00:15 +00:00
else
min_x = real_x ;
if ( rdp . tiles [ td ] . mask_t ! = 0 )
2016-01-25 09:58:29 +00:00
min_y = minval ( ( int ) real_y , 1 < < rdp . tiles [ td ] . mask_t ) ;
2016-01-20 10:00:15 +00:00
else
min_y = real_y ;
// Load using mirroring/clamping
if ( min_x > texinfo [ id ] . width )
{
if ( size = = 1 )
Clamp16bS ( ( texture ) , texinfo [ id ] . width , min_x , real_x , texinfo [ id ] . height ) ;
else if ( size ! = 2 )
Clamp8bS ( ( texture ) , texinfo [ id ] . width , min_x , real_x , texinfo [ id ] . height ) ;
else
Clamp32bS ( ( texture ) , texinfo [ id ] . width , min_x , real_x , texinfo [ id ] . height ) ;
}
if ( texinfo [ id ] . width < ( int ) real_x )
{
if ( rdp . tiles [ td ] . mirror_s )
{
if ( size = = 1 )
Mirror16bS ( ( texture ) , rdp . tiles [ td ] . mask_s ,
real_x , real_x , texinfo [ id ] . height ) ;
else if ( size ! = 2 )
Mirror8bS ( ( texture ) , rdp . tiles [ td ] . mask_s ,
real_x , real_x , texinfo [ id ] . height ) ;
else
Mirror32bS ( ( texture ) , rdp . tiles [ td ] . mask_s ,
real_x , real_x , texinfo [ id ] . height ) ;
}
else
{
if ( size = = 1 )
Wrap16bS ( ( texture ) , rdp . tiles [ td ] . mask_s ,
real_x , real_x , texinfo [ id ] . height ) ;
else if ( size ! = 2 )
Wrap8bS ( ( texture ) , rdp . tiles [ td ] . mask_s ,
real_x , real_x , texinfo [ id ] . height ) ;
else
Wrap32bS ( ( texture ) , rdp . tiles [ td ] . mask_s ,
real_x , real_x , texinfo [ id ] . height ) ;
}
}
if ( min_y > texinfo [ id ] . height )
{
if ( size = = 1 )
Clamp16bT ( ( texture ) , texinfo [ id ] . height , real_x , min_y ) ;
else if ( size ! = 2 )
Clamp8bT ( ( texture ) , texinfo [ id ] . height , real_x , min_y ) ;
else
Clamp32bT ( ( texture ) , texinfo [ id ] . height , real_x , min_y ) ;
}
if ( texinfo [ id ] . height < ( int ) real_y )
{
if ( rdp . tiles [ td ] . mirror_t )
{
if ( size = = 1 )
Mirror16bT ( ( texture ) , rdp . tiles [ td ] . mask_t ,
real_y , real_x ) ;
else if ( size ! = 2 )
Mirror8bT ( ( texture ) , rdp . tiles [ td ] . mask_t ,
real_y , real_x ) ;
else
Mirror32bT ( ( texture ) , rdp . tiles [ td ] . mask_t ,
real_y , real_x ) ;
}
else
{
if ( size = = 1 )
Wrap16bT ( ( texture ) , rdp . tiles [ td ] . mask_t ,
real_y , real_x ) ;
else if ( size ! = 2 )
Wrap8bT ( ( texture ) , rdp . tiles [ td ] . mask_t ,
real_y , real_x ) ;
else
Wrap32bT ( ( texture ) , rdp . tiles [ td ] . mask_t ,
real_y , real_x ) ;
}
}
2013-04-04 21:22:19 +00:00
}
if ( modifyPalette )
{
2016-01-20 10:00:15 +00:00
memcpy ( rdp . pal_8 , tmp_pal , 512 ) ;
2013-04-04 21:22:19 +00:00
}
# ifdef TEXTURE_FILTER
if ( mod & & ! modifyPalette & & ! ghqTexInfo . data )
# else
if ( mod & & ! modifyPalette )
# endif
{
2016-01-20 10:00:15 +00:00
// Convert the texture to ARGB 4444
if ( LOWORD ( result ) = = GR_TEXFMT_ARGB_1555 )
{
TexConv_ARGB1555_ARGB4444 ( ( texture ) , ( tex2 ) , real_x , real_y ) ;
texture = tex2 ;
}
else if ( LOWORD ( result ) = = GR_TEXFMT_ALPHA_INTENSITY_88 )
{
TexConv_AI88_ARGB4444 ( ( texture ) , ( tex2 ) , real_x , real_y ) ;
texture = tex2 ;
}
else if ( LOWORD ( result ) = = GR_TEXFMT_ALPHA_INTENSITY_44 )
{
TexConv_AI44_ARGB4444 ( ( texture ) , ( tex2 ) , real_x , real_y ) ;
texture = tex2 ;
}
else if ( LOWORD ( result ) = = GR_TEXFMT_ALPHA_8 )
{
TexConv_A8_ARGB4444 ( ( texture ) , ( tex2 ) , real_x , real_y ) ;
texture = tex2 ;
}
/*else if (LOWORD(result) == GR_TEXFMT_ARGB_4444)
{
memcpy ( tex2 , texture , ( real_x * real_y ) < < 1 ) ;
2013-04-04 21:22:19 +00:00
texture = tex2 ;
2016-01-20 10:00:15 +00:00
} */ // we can skip memcpy since "texture" won't be swapped between "tex1" and "tex2" after this.
// Hiroshi Morii <koolsmoky@users.sourceoforge.net>
result = ( 1 < < 16 ) | GR_TEXFMT_ARGB_4444 ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
// Now convert the color to the same
modcolor = ( ( modcolor & 0xF0000000 ) > > 16 ) | ( ( modcolor & 0x00F00000 ) > > 12 ) |
( ( modcolor & 0x0000F000 ) > > 8 ) | ( ( modcolor & 0x000000F0 ) > > 4 ) ;
modcolor1 = ( ( modcolor1 & 0xF0000000 ) > > 16 ) | ( ( modcolor1 & 0x00F00000 ) > > 12 ) |
( ( modcolor1 & 0x0000F000 ) > > 8 ) | ( ( modcolor1 & 0x000000F0 ) > > 4 ) ;
modcolor2 = ( ( modcolor2 & 0xF0000000 ) > > 16 ) | ( ( modcolor2 & 0x00F00000 ) > > 12 ) |
( ( modcolor2 & 0x0000F000 ) > > 8 ) | ( ( modcolor2 & 0x000000F0 ) > > 4 ) ;
int size = ( real_x * real_y ) < < 1 ;
switch ( mod )
{
case TMOD_TEX_INTER_COLOR_USING_FACTOR :
mod_tex_inter_color_using_factor ( ( uint16_t * ) texture , size , modcolor , modfactor ) ;
break ;
case TMOD_TEX_INTER_COL_USING_COL1 :
mod_tex_inter_col_using_col1 ( ( uint16_t * ) texture , size , modcolor , modcolor1 ) ;
break ;
case TMOD_FULL_COLOR_SUB_TEX :
mod_full_color_sub_tex ( ( uint16_t * ) texture , size , modcolor ) ;
break ;
case TMOD_COL_INTER_COL1_USING_TEX :
mod_col_inter_col1_using_tex ( ( uint16_t * ) texture , size , modcolor , modcolor1 ) ;
break ;
case TMOD_COL_INTER_COL1_USING_TEXA :
mod_col_inter_col1_using_texa ( ( uint16_t * ) texture , size , modcolor , modcolor1 ) ;
break ;
case TMOD_COL_INTER_COL1_USING_TEXA__MUL_TEX :
mod_col_inter_col1_using_texa__mul_tex ( ( uint16_t * ) texture , size , modcolor , modcolor1 ) ;
break ;
case TMOD_COL_INTER_TEX_USING_TEXA :
mod_col_inter_tex_using_texa ( ( uint16_t * ) texture , size , modcolor ) ;
break ;
case TMOD_COL2_INTER__COL_INTER_COL1_USING_TEX__USING_TEXA :
mod_col2_inter__col_inter_col1_using_tex__using_texa ( ( uint16_t * ) texture , size , modcolor , modcolor1 , modcolor2 ) ;
break ;
case TMOD_TEX_SCALE_FAC_ADD_FAC :
mod_tex_scale_fac_add_fac ( ( uint16_t * ) texture , size , modfactor ) ;
break ;
case TMOD_TEX_SUB_COL_MUL_FAC_ADD_TEX :
mod_tex_sub_col_mul_fac_add_tex ( ( uint16_t * ) texture , size , modcolor , modfactor ) ;
break ;
case TMOD_TEX_SCALE_COL_ADD_COL :
mod_tex_scale_col_add_col ( ( uint16_t * ) texture , size , modcolor , modcolor1 ) ;
break ;
case TMOD_TEX_ADD_COL :
mod_tex_add_col ( ( uint16_t * ) texture , size , modcolor ) ;
break ;
case TMOD_TEX_SUB_COL :
mod_tex_sub_col ( ( uint16_t * ) texture , size , modcolor ) ;
break ;
case TMOD_TEX_SUB_COL_MUL_FAC :
mod_tex_sub_col_mul_fac ( ( uint16_t * ) texture , size , modcolor , modfactor ) ;
break ;
case TMOD_COL_INTER_TEX_USING_COL1 :
mod_col_inter_tex_using_col1 ( ( uint16_t * ) texture , size , modcolor , modcolor1 ) ;
break ;
case TMOD_COL_MUL_TEXA_ADD_TEX :
mod_col_mul_texa_add_tex ( ( uint16_t * ) texture , size , modcolor ) ;
break ;
case TMOD_COL_INTER_TEX_USING_TEX :
mod_col_inter_tex_using_tex ( ( uint16_t * ) texture , size , modcolor ) ;
break ;
case TMOD_TEX_INTER_NOISE_USING_COL :
mod_tex_inter_noise_using_col ( ( uint16_t * ) texture , size , modcolor ) ;
break ;
case TMOD_TEX_INTER_COL_USING_TEXA :
mod_tex_inter_col_using_texa ( ( uint16_t * ) texture , size , modcolor ) ;
break ;
case TMOD_TEX_MUL_COL :
mod_tex_mul_col ( ( uint16_t * ) texture , size , modcolor ) ;
break ;
case TMOD_TEX_SCALE_FAC_ADD_COL :
mod_tex_scale_fac_add_col ( ( uint16_t * ) texture , size , modcolor , modfactor ) ;
break ;
default :
;
}
2016-01-20 17:12:15 +00:00
}
2013-04-04 21:22:19 +00:00
cache - > t_info . format = LOWORD ( result ) ;
cache - > realwidth = real_x ;
cache - > realheight = real_y ;
cache - > lod = lod ;
cache - > aspect = aspect ;
2016-01-20 18:22:45 +00:00
if ( GfxInitDone )
2016-01-20 17:12:15 +00:00
{
2016-01-20 18:22:45 +00:00
# ifdef TEXTURE_FILTER // Hiroshi Morii <koolsmoky@users.sourceforge.net>
2016-02-01 08:56:25 +00:00
if ( g_settings - > ghq_use )
2016-01-20 18:22:45 +00:00
{
if ( ! ghqTexInfo . data & & ghq_dmptex_toggle_key ) {
unsigned char * tmpbuf = ( unsigned char * ) texture ;
int tmpwidth = real_x ;
if ( texinfo [ id ] . splits > 1 ) {
int dstpixoffset , srcpixoffset ;
int shift ;
switch ( LOWORD ( result ) & 0x7fff ) { // XXX is there a better way of determining the pixel color depth?
case GR_TEXFMT_ARGB_8888 :
shift = 3 ;
break ;
case GR_TEXFMT_ALPHA_INTENSITY_44 :
case GR_TEXFMT_ALPHA_8 :
shift = 0 ;
break ;
default :
shift = 1 ;
}
tmpwidth = texinfo [ id ] . real_image_width ;
tmpbuf = ( unsigned char * ) malloc ( ( 256 * 256 ) < < 3 ) ; // XXX performance overhead
for ( int i = 0 ; i < cache - > splitheight ; i + + ) {
dstpixoffset = texinfo [ id ] . real_image_width * i ;
srcpixoffset = 256 * i ;
for ( int k = 0 ; k < texinfo [ id ] . splits ; k + + ) {
memcpy ( tmpbuf + ( dstpixoffset < < shift ) , texture + ( srcpixoffset < < shift ) , ( 256 < < shift ) ) ;
dstpixoffset + = 256 ;
srcpixoffset + = ( 256 * cache - > splitheight ) ;
}
2016-01-20 17:12:15 +00:00
}
2016-01-20 10:00:15 +00:00
}
2016-01-20 18:22:45 +00:00
ext_ghq_dmptx ( tmpbuf , ( int ) texinfo [ id ] . real_image_width , ( int ) texinfo [ id ] . real_image_height , ( int ) tmpwidth , ( unsigned short ) LOWORD ( result ) , ( unsigned short ) ( ( cache - > format < < 8 ) | ( cache - > size ) ) , cache - > ricecrc ) ;
if ( tmpbuf ! = texture & & tmpbuf ) {
free ( tmpbuf ) ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 18:22:45 +00:00
if ( ! ghqTexInfo . data )
2016-02-01 08:56:25 +00:00
if ( ! g_settings - > ghq_enht_nobg | | ! rdp . texrecting | | ( texinfo [ id ] . splits = = 1 & & texinfo [ id ] . width < = 256 ) )
2016-01-20 18:22:45 +00:00
ext_ghq_txfilter ( ( unsigned char * ) texture , ( int ) real_x , ( int ) real_y , LOWORD ( result ) , ( uint64 ) g64_crc , & ghqTexInfo ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 18:22:45 +00:00
if ( ghqTexInfo . data )
2013-04-04 21:22:19 +00:00
{
2016-01-20 18:22:45 +00:00
if ( ghqTexInfo . aspectRatioLog2 < GR_ASPECT_LOG2_1x8 | |
ghqTexInfo . aspectRatioLog2 > GR_ASPECT_LOG2_8x1 | |
ghqTexInfo . largeLodLog2 > GR_LOD_LOG2_2048 | |
ghqTexInfo . largeLodLog2 < GR_LOD_LOG2_1 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 18:22:45 +00:00
/* invalid dimensions */
}
else
{
texture = ( uint8_t * ) ghqTexInfo . data ;
lod = ghqTexInfo . largeLodLog2 ;
int splits = cache - > splits ;
if ( ghqTexInfo . is_hires_tex )
2016-01-20 17:12:15 +00:00
{
2016-01-20 18:22:45 +00:00
if ( ghqTexInfo . tiles /*ghqTexInfo.untiled_width > max_tex_size*/ )
2016-01-20 17:12:15 +00:00
{
2016-01-20 18:22:45 +00:00
cache - > scale = 1.0f ;
cache - > c_off = 0.5f ;
cache - > splits = ghqTexInfo . tiles ; //((hirestex.width-1)>>8)+1;
cache - > splitheight = ghqTexInfo . untiled_height ;
cache - > scale_x = 1.0f ;
cache - > scale_y = float ( ghqTexInfo . untiled_height * ghqTexInfo . tiles ) / float ( ghqTexInfo . width ) ; //*sy;
if ( splits = = 1 )
2016-01-20 10:00:15 +00:00
{
2016-01-20 18:22:45 +00:00
int shift ;
for ( shift = 9 ; ( 1 < < shift ) < ghqTexInfo . untiled_width ; shift + + ) ;
float mult = float ( 1 < < shift > > 8 ) ;
cache - > c_scl_x * = mult ;
cache - > c_scl_y * = mult ;
2016-01-20 10:00:15 +00:00
}
else
{
2016-01-20 18:22:45 +00:00
int tile_width = rdp . tiles [ td ] . width ;
if ( rdp . timg . set_by = = 1 )
tile_width = rdp . load_info [ rdp . tiles [ td ] . t_mem ] . tex_width ;
float mult = float ( ghqTexInfo . untiled_width / tile_width ) ;
cache - > c_scl_x * = mult ;
cache - > c_scl_y * = mult ;
2016-01-20 10:00:15 +00:00
}
2016-01-20 18:22:45 +00:00
}
else
{
cache - > scale = 256.0f / float ( 1 < < lod ) ;
cache - > c_off = cache - > scale * 0.5f ;
cache - > splits = 1 ;
if ( aspect ! = ghqTexInfo . aspectRatioLog2 )
2016-01-20 10:00:15 +00:00
{
2016-01-20 18:22:45 +00:00
float mscale = float ( 1 < < abs ( aspect - ghqTexInfo . aspectRatioLog2 ) ) ;
if ( abs ( aspect ) > abs ( ghqTexInfo . aspectRatioLog2 ) )
{
cache - > c_scl_y * = mscale ;
cache - > c_scl_x * = mscale ;
}
/*
else
{
if ( rdp . tiles [ td ] . mirror_s & & sup_mirroring )
cache - > f_mirror_s = TRUE ;
if ( rdp . tiles [ td ] . mirror_t & & sup_mirroring )
cache - > f_mirror_t = TRUE ;
//cache->c_scl_y /= mscale;
//cache->c_scl_x /= mscale;
}
*/
if ( ghqTexInfo . aspectRatioLog2 > = 0 )
{
cache - > scale_x = 1.0f ;
cache - > scale_y = 1.0f / float ( 1 < < ghqTexInfo . aspectRatioLog2 ) ;
}
else
{
cache - > scale_y = 1.0f ;
cache - > scale_x = 1.0f / float ( 1 < < ( - ghqTexInfo . aspectRatioLog2 ) ) ;
}
2016-01-20 10:00:15 +00:00
}
2016-01-20 18:22:45 +00:00
else if ( splits > 1 )
2016-01-20 10:00:15 +00:00
{
2016-01-20 18:22:45 +00:00
cache - > c_scl_x / = splits ;
cache - > c_scl_y / = splits ;
2016-01-20 10:00:15 +00:00
}
}
2016-01-20 18:22:45 +00:00
if ( voodoo . sup_mirroring )
2016-01-20 10:00:15 +00:00
{
2016-01-20 18:22:45 +00:00
if ( rdp . tiles [ td ] . mirror_s & & texinfo [ id ] . tile_width = = 2 * texinfo [ id ] . width )
cache - > f_mirror_s = TRUE ;
else if ( texinfo [ id ] . tile_width > = 2 * texinfo [ id ] . width )
cache - > f_wrap_s = TRUE ;
if ( rdp . tiles [ td ] . mirror_t & & texinfo [ id ] . tile_height = = 2 * texinfo [ id ] . height )
cache - > f_mirror_t = TRUE ;
else if ( texinfo [ id ] . tile_height > = 2 * texinfo [ id ] . height )
cache - > f_wrap_t = TRUE ;
if ( cache - > f_mirror_s & & cache - > f_mirror_t )
{
cache - > c_scl_x * = 2.0f ;
cache - > c_scl_y * = 2.0f ;
}
2016-01-20 10:00:15 +00:00
}
2016-01-20 18:22:45 +00:00
aspect = ghqTexInfo . aspectRatioLog2 ;
cache - > lod = lod ;
cache - > aspect = aspect ;
2016-01-20 10:00:15 +00:00
}
2016-01-20 18:22:45 +00:00
else
2016-01-20 10:00:15 +00:00
{
2016-01-20 18:22:45 +00:00
//cache->scale = 256.0f / float(1<<lod);
cache - > c_off = 128.0f / float ( 1 < < lod ) ;
2016-01-20 10:00:15 +00:00
}
2016-01-20 18:22:45 +00:00
real_x = ghqTexInfo . width ;
real_y = ghqTexInfo . height ;
result = ( 1 < < 16 ) | ghqTexInfo . format ;
cache - > t_info . format = ghqTexInfo . format ;
cache - > realwidth = real_x ;
cache - > realheight = real_y ;
2013-04-04 21:22:19 +00:00
}
}
}
# endif
2016-01-20 10:00:15 +00:00
// Load the texture into texture memory
GrTexInfo * t_info = & cache - > t_info ;
t_info - > data = texture ;
t_info - > smallLodLog2 = lod ;
t_info - > largeLodLog2 = lod ;
t_info - > aspectRatioLog2 = aspect ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
uint32_t texture_size = grTexTextureMemRequired ( GR_MIPMAPLEVELMASK_BOTH , t_info ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 10:00:15 +00:00
// Check for 2mb boundary
// Hiroshi Morii <koolsmoky@users.sourceforge.net> required only for V1,Rush, and V2
if ( voodoo . has_2mb_tex_boundary & &
( voodoo . tmem_ptr [ tmu ] < TEXMEM_2MB_EDGE ) & & ( voodoo . tmem_ptr [ tmu ] + texture_size > TEXMEM_2MB_EDGE ) )
{
voodoo . tmem_ptr [ tmu ] = TEXMEM_2MB_EDGE ;
cache - > tmem_addr = voodoo . tmem_ptr [ tmu ] ;
}
// Check for end of memory (too many textures to fit, clear cache)
if ( voodoo . tmem_ptr [ tmu ] + texture_size > = voodoo . tex_max_addr [ tmu ] )
{
LRDP ( " Cache size reached, clearing... \n " ) ;
ClearCache ( ) ;
if ( id = = 1 & & rdp . tex = = 3 )
LoadTex ( 0 , rdp . t0 ) ;
LoadTex ( id , tmu ) ;
return ;
// DON'T CONTINUE (already done)
}
uint32_t tex_addr = GetTexAddr ( tmu , texture_size ) ;
grTexDownloadMipMap ( tmu ,
tex_addr ,
GR_MIPMAPLEVELMASK_BOTH ,
t_info ) ;
grTexSource ( tmu ,
tex_addr ,
GR_MIPMAPLEVELMASK_BOTH ,
t_info ) ;
2013-04-04 21:22:19 +00:00
}
LRDP ( " | | +- LoadTex end \n " ) ;
2016-01-20 10:00:15 +00:00
}