2009-05-08 13:28:41 +00:00
/*
* OpenClonk , http : //www.openclonk.org
*
2013-12-17 20:01:09 +00:00
* Copyright ( c ) 1998 - 2000 , Matthes Bender
* Copyright ( c ) 2001 - 2009 , RedWolf Design GmbH , http : //www.clonk.de/
* Copyright ( c ) 2009 - 2013 , The OpenClonk Team and contributors
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* Distributed under the terms of the ISC license ; see accompanying file
* " COPYING " for details .
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* " Clonk " is a registered trademark of Matthes Bender , used with permission .
* See accompanying file " TRADEMARK " for details .
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* To redistribute this file separately , substitute the full license texts
* for the above references .
2009-05-08 13:28:41 +00:00
*/
/* Textures used by the landscape */
# include <C4Include.h>
# include <C4Texture.h>
# include <C4Group.h>
# include <C4Game.h>
# include <C4Config.h>
# include <C4Components.h>
# include <C4Material.h>
# include <C4Landscape.h>
2009-06-12 18:52:21 +00:00
# include <C4Log.h>
2009-05-08 13:28:41 +00:00
2014-03-25 17:26:51 +00:00
# include <ctype.h>
# include <algorithm>
2009-05-08 13:28:41 +00:00
C4Texture : : C4Texture ( )
2010-03-28 18:58:01 +00:00
{
2010-03-27 16:05:02 +00:00
Surface32 = NULL ;
2010-04-10 12:24:38 +00:00
AvgColor = 0x00000000 ;
2010-03-27 16:05:02 +00:00
Next = NULL ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
C4Texture : : ~ C4Texture ( )
2010-03-28 18:58:01 +00:00
{
2010-03-27 16:05:02 +00:00
delete Surface32 ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
C4TexMapEntry : : C4TexMapEntry ( )
2010-03-28 18:58:01 +00:00
: iMaterialIndex ( MNone ) , pMaterial ( NULL )
{
}
2009-05-08 13:28:41 +00:00
void C4TexMapEntry : : Clear ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Material . Clear ( ) ; Texture . Clear ( ) ;
iMaterialIndex = MNone ;
pMaterial = NULL ;
MatPattern . Clear ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4TexMapEntry : : Create ( const char * szMaterial , const char * szTexture )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Clear previous data
Clear ( ) ;
// Save names
Material = szMaterial ; Texture = szTexture ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4TexMapEntry : : Init ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Find material
2009-06-05 18:46:03 +00:00
iMaterialIndex = : : MaterialMap . Get ( Material . getData ( ) ) ;
2010-03-28 18:58:01 +00:00
if ( ! MatValid ( iMaterialIndex ) )
{
2009-05-08 13:28:41 +00:00
DebugLogF ( " Error initializing material %s-%s: Invalid material! " , Material . getData ( ) , Texture . getData ( ) ) ;
return false ;
2010-03-28 18:58:01 +00:00
}
2009-06-05 18:46:03 +00:00
pMaterial = & : : MaterialMap . Map [ iMaterialIndex ] ;
2009-05-08 13:28:41 +00:00
// Find texture
2011-08-20 00:25:08 +00:00
StdStrBuf FirstTexture ;
FirstTexture . CopyUntil ( Texture . getData ( ) , ' - ' ) ;
C4Texture * sfcTexture = : : TextureMap . GetTexture ( FirstTexture . getData ( ) ) ;
2010-03-28 18:58:01 +00:00
if ( ! sfcTexture )
{
2011-08-20 00:25:08 +00:00
DebugLogF ( " Error initializing material %s-%s: Invalid texture! " , Material . getData ( ) , FirstTexture . getData ( ) ) ;
2009-05-08 13:28:41 +00:00
Clear ( ) ;
return false ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Get overlay properties
int32_t iOverlayType = pMaterial - > OverlayType ;
int32_t iZoom = 0 ;
if ( iOverlayType & C4MatOv_Exact ) iZoom = 1 ;
if ( iOverlayType & C4MatOv_HugeZoom ) iZoom = 4 ;
// Create pattern
2009-07-24 21:50:04 +00:00
MatPattern . Set ( sfcTexture - > Surface32 , iZoom ) ;
2009-05-08 13:28:41 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
C4TextureMap : : C4TextureMap ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Default ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
C4TextureMap : : ~ C4TextureMap ( )
2010-03-28 18:58:01 +00:00
{
2010-03-27 16:05:02 +00:00
Clear ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2009-08-15 18:50:32 +00:00
bool C4TextureMap : : AddEntry ( BYTE byIndex , const char * szMaterial , const char * szTexture )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Security
2010-03-28 18:58:01 +00:00
if ( byIndex < = 0 | | byIndex > = C4M_MaxTexIndex )
2009-08-15 18:50:32 +00:00
return false ;
2009-05-08 13:28:41 +00:00
// Set entry and initialize
Entry [ byIndex ] . Create ( szMaterial , szTexture ) ;
2010-03-28 18:58:01 +00:00
if ( fInitialized )
{
if ( ! Entry [ byIndex ] . Init ( ) )
2009-05-08 13:28:41 +00:00
{
// Clear entry if it could not be initialized
Entry [ byIndex ] . Clear ( ) ;
2009-08-15 18:50:32 +00:00
return false ;
2009-05-08 13:28:41 +00:00
}
// Landscape must be notified (new valid pixel clr)
2009-06-05 15:20:41 +00:00
: : Landscape . HandleTexMapUpdate ( ) ;
2010-03-27 16:05:02 +00:00
}
2010-03-28 18:58:01 +00:00
return true ;
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:06:41 +00:00
bool C4TextureMap : : AddTexture ( const char * szTexture , C4Surface * sfcSurface )
2010-03-28 18:58:01 +00:00
{
2010-03-27 16:05:02 +00:00
C4Texture * pTexture ;
if ( ! ( pTexture = new C4Texture ) ) return false ;
2012-09-05 20:51:25 +00:00
pTexture - > Name . Copy ( szTexture ) ;
2010-03-27 16:05:02 +00:00
pTexture - > Surface32 = sfcSurface ;
pTexture - > Next = FirstTexture ;
FirstTexture = pTexture ;
2010-04-10 12:24:38 +00:00
// Compute average texture color
2012-02-12 18:41:48 +00:00
if ( sfcSurface )
2010-04-10 12:24:38 +00:00
{
2012-02-12 18:41:48 +00:00
sfcSurface - > Lock ( ) ;
uint32_t avg_c [ 4 ] = { 0 , 0 , 0 , 0 } ;
for ( int32_t y = 0 ; y < sfcSurface - > Hgt ; + + y )
2010-04-10 12:24:38 +00:00
{
2012-02-12 18:41:48 +00:00
for ( int32_t x = 0 ; x < sfcSurface - > Wdt ; + + x )
{
DWORD c = sfcSurface - > GetPixDw ( x , y , false ) ;
avg_c [ 0 ] + = c & 0xff ;
avg_c [ 1 ] + = ( c > > 8 ) & 0xff ;
avg_c [ 2 ] + = ( c > > 16 ) & 0xff ;
avg_c [ 3 ] + = ( c > > 24 ) & 0xff ;
}
2010-04-10 12:24:38 +00:00
}
2012-02-12 18:41:48 +00:00
sfcSurface - > Unlock ( ) ;
double Size = sfcSurface - > Wdt * sfcSurface - > Hgt ;
avg_c [ 0 ] = static_cast < uint32_t > ( avg_c [ 0 ] / Size + 0.5 ) ;
avg_c [ 1 ] = static_cast < uint32_t > ( avg_c [ 1 ] / Size + 0.5 ) ;
avg_c [ 2 ] = static_cast < uint32_t > ( avg_c [ 2 ] / Size + 0.5 ) ;
avg_c [ 3 ] = static_cast < uint32_t > ( avg_c [ 3 ] / Size + 0.5 ) ;
2013-01-07 23:24:41 +00:00
pTexture - > SetAverageColor ( avg_c [ 0 ] | ( avg_c [ 1 ] < < 8 ) | ( avg_c [ 2 ] < < 16 ) | ( avg_c [ 3 ] < < 24 ) ) ;
2010-04-10 12:24:38 +00:00
}
2012-02-12 18:41:48 +00:00
else
{
2013-01-07 23:24:41 +00:00
pTexture - > SetAverageColor ( 0x00000000 ) ;
2010-04-10 12:24:38 +00:00
}
2012-02-12 18:41:48 +00:00
2010-03-27 16:05:02 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4TextureMap : : Clear ( )
2010-03-28 18:58:01 +00:00
{
for ( int32_t i = 1 ; i < C4M_MaxTexIndex ; i + + )
2009-05-08 13:28:41 +00:00
Entry [ i ] . Clear ( ) ;
2010-03-27 16:05:02 +00:00
C4Texture * ctex , * next2 ;
for ( ctex = FirstTexture ; ctex ; ctex = next2 )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
next2 = ctex - > Next ;
delete ctex ;
2010-03-28 18:58:01 +00:00
}
2010-03-27 16:05:02 +00:00
FirstTexture = NULL ;
2009-05-08 13:28:41 +00:00
fInitialized = false ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2009-08-15 18:50:32 +00:00
bool C4TextureMap : : LoadFlags ( C4Group & hGroup , const char * szEntryName , bool * pOverloadMaterials , bool * pOverloadTextures )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Load the file
StdStrBuf TexMap ;
2011-03-05 01:44:26 +00:00
if ( ! hGroup . LoadEntryString ( szEntryName , & TexMap ) )
2009-08-15 18:50:32 +00:00
return false ;
2009-05-08 13:28:41 +00:00
// Reset flags
2010-03-28 18:58:01 +00:00
if ( pOverloadMaterials ) * pOverloadMaterials = false ;
if ( pOverloadTextures ) * pOverloadTextures = false ;
2009-05-08 13:28:41 +00:00
// Check if there are flags in there
2010-03-28 18:58:01 +00:00
for ( const char * pPos = TexMap . getData ( ) ; pPos & & * pPos ; pPos = SSearch ( pPos + 1 , " \n " ) )
{
2009-05-08 13:28:41 +00:00
// Go over newlines
2010-03-28 18:58:01 +00:00
while ( * pPos = = ' \r ' | | * pPos = = ' \n ' ) pPos + + ;
2009-05-08 13:28:41 +00:00
// Flag?
if ( pOverloadMaterials & & SEqual2 ( pPos , " OverloadMaterials " ) )
2009-08-15 18:50:32 +00:00
* pOverloadMaterials = true ;
2009-05-08 13:28:41 +00:00
if ( pOverloadTextures & & SEqual2 ( pPos , " OverloadTextures " ) )
2009-08-15 18:50:32 +00:00
* pOverloadTextures = true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Done
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2009-08-15 18:50:32 +00:00
int32_t C4TextureMap : : LoadMap ( C4Group & hGroup , const char * szEntryName , bool * pOverloadMaterials , bool * pOverloadTextures )
2010-03-28 18:58:01 +00:00
{
2014-03-25 17:26:51 +00:00
static re : : regex line_terminator ( " \r ? \n " , static_cast < re : : regex : : flag_type > ( re : : regex_constants : : optimize | re : : regex_constants : : ECMAScript ) ) ;
2010-03-27 16:05:02 +00:00
char * bpMap ;
2014-03-25 17:26:51 +00:00
size_t map_size ;
int32_t iTextures = 0 ;
2010-03-27 16:05:02 +00:00
// Load text file into memory
2014-03-25 17:26:51 +00:00
if ( ! hGroup . LoadEntry ( szEntryName , & bpMap , & map_size , 1 ) ) return 0 ;
char * begin = bpMap ;
char * end = begin + map_size ;
size_t line = 1 ; // Counter for error messages
for ( auto it = re : : cregex_token_iterator ( begin , end , line_terminator , - 1 ) ; it ! = re : : cregex_token_iterator ( ) ; + + it , + + line )
{
if ( it - > compare ( " OverloadMaterials " ) = = 0 )
2010-03-28 18:58:01 +00:00
{
2014-03-25 17:26:51 +00:00
fOverloadMaterials = true ;
if ( pOverloadMaterials )
* pOverloadMaterials = true ;
}
else if ( it - > compare ( " OverloadTextures " ) = = 0 )
{
fOverloadTextures = true ;
if ( pOverloadTextures )
* pOverloadTextures = true ;
}
else if ( it - > length ( ) = = 0 | | it - > first [ 0 ] = = ' # ' | | std : : all_of ( it - > first , it - > second , & isspace ) )
{
// Skip empty lines, comments, and all-whitespace lines
continue ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
else
2010-03-28 18:58:01 +00:00
{
2014-03-25 17:26:51 +00:00
// This must be a texmap entry now
std : : string value ;
// Read index
unsigned long index ;
try
{
size_t separator ;
index = std : : stoul ( it - > str ( ) , & separator , 10 ) ;
if ( index > = C4M_MaxTexIndex )
throw std : : out_of_range ( " Texture index out of range " ) ;
value . assign ( it - > first + separator + 1 , it - > second ) ;
}
catch ( std : : invalid_argument & )
{
DebugLogF ( " TexMap line %u: Texture index is not numeric " , static_cast < unsigned > ( line ) ) ;
continue ;
}
catch ( std : : out_of_range & )
{
DebugLogF ( " TexMap line %u: Texture index is out of range " , static_cast < unsigned > ( line ) ) ;
continue ;
}
// Split material/texture combination
std : : string : : const_iterator separator = std : : find ( value . cbegin ( ) , value . cend ( ) , ' - ' ) ;
if ( separator = = value . cend ( ) )
{
DebugLogF ( " TexMap line %u: Texture name \" %s \" is invalid (missing \" - \" ) " , static_cast < unsigned > ( line ) , value . c_str ( ) ) ;
continue ;
}
std : : string material ( value . cbegin ( ) , separator ) ;
std : : string texture ( separator + 1 , value . cend ( ) ) ;
if ( AddEntry ( index , material . c_str ( ) , texture . c_str ( ) ) )
+ + iTextures ;
2010-03-28 18:58:01 +00:00
}
2014-03-25 17:26:51 +00:00
}
2010-03-27 16:05:02 +00:00
// Delete buffer, return entry count
delete [ ] bpMap ;
2009-05-08 13:28:41 +00:00
fEntriesAdded = false ;
2010-03-27 16:05:02 +00:00
return iTextures ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
int32_t C4TextureMap : : Init ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
int32_t iRemoved = 0 ;
// Initialize texture mappings
int32_t i ;
for ( i = 0 ; i < C4M_MaxTexIndex ; i + + )
if ( ! Entry [ i ] . isNull ( ) )
if ( ! Entry [ i ] . Init ( ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
LogF ( " Error in TextureMap initialization at entry %d " , ( int ) i ) ;
Entry [ i ] . Clear ( ) ;
iRemoved + + ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
fInitialized = true ;
return iRemoved ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4TextureMap : : SaveMap ( C4Group & hGroup , const char * szEntryName )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// build file in memory
StdStrBuf sTexMapFile ;
// add desc
sTexMapFile . Append ( " # Automatically generated texture map " LineFeed ) ;
sTexMapFile . Append ( " # Contains material-texture-combinations added at runtime " LineFeed ) ;
// add overload-entries
if ( fOverloadMaterials ) sTexMapFile . Append ( " # Import materials from global file as well " LineFeed " OverloadMaterials " LineFeed ) ;
if ( fOverloadTextures ) sTexMapFile . Append ( " # Import textures from global file as well " LineFeed " OverloadTextures " LineFeed ) ;
sTexMapFile . Append ( LineFeed ) ;
// add entries
for ( int32_t i = 0 ; i < C4M_MaxTexIndex ; i + + )
if ( ! Entry [ i ] . isNull ( ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// compose line
sTexMapFile . AppendFormat ( " %d=%s-%s " LineFeed , i , Entry [ i ] . GetMaterialName ( ) , Entry [ i ] . GetTextureName ( ) ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// create new buffer allocated with new [], because C4Group cannot handle StdStrBuf-buffers
size_t iBufSize = sTexMapFile . getLength ( ) ;
BYTE * pBuf = new BYTE [ iBufSize ] ;
memcpy ( pBuf , sTexMapFile . getData ( ) , iBufSize ) ;
// add to group
bool fSuccess = ! ! hGroup . Add ( szEntryName , pBuf , iBufSize , false , true ) ;
if ( ! fSuccess ) delete [ ] pBuf ;
// done
return fSuccess ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
int32_t C4TextureMap : : LoadTextures ( C4Group & hGroup , C4Group * OverloadFile )
2010-03-28 18:58:01 +00:00
{
2009-05-09 15:08:10 +00:00
int32_t texnum = 0 ;
2009-05-08 13:28:41 +00:00
// overload: load from other file
if ( OverloadFile ) texnum + = LoadTextures ( * OverloadFile ) ;
2009-05-09 15:08:10 +00:00
char texname [ 256 + 1 ] ;
2009-05-08 13:28:41 +00:00
C4Surface * ctex ;
2009-05-09 15:08:10 +00:00
size_t binlen ;
2011-05-23 23:12:19 +00:00
2009-05-08 13:28:41 +00:00
hGroup . ResetSearch ( ) ;
2009-05-09 15:08:10 +00:00
while ( hGroup . AccessNextEntry ( " * " , & binlen , texname ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// check if it already exists in the map
2009-05-09 15:08:10 +00:00
if ( GetTexture ( GetFilenameOnly ( texname ) ) ) continue ;
// create surface
ctex = new C4Surface ( ) ;
if ( ctex - > Read ( hGroup , GetExtension ( texname ) ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
SReplaceChar ( texname , ' . ' , 0 ) ;
2009-05-09 15:08:10 +00:00
if ( AddTexture ( texname , ctex ) ) texnum + + ;
2009-05-08 13:28:41 +00:00
else delete ctex ;
2010-03-28 18:58:01 +00:00
}
2009-05-09 15:08:10 +00:00
else
2010-03-28 18:58:01 +00:00
{
2009-05-09 15:08:10 +00:00
delete ctex ;
2009-05-08 13:28:41 +00:00
}
}
2011-05-23 23:12:19 +00:00
2010-03-28 18:58:01 +00:00
return texnum ;
}
2009-05-08 13:28:41 +00:00
bool C4TextureMap : : HasTextures ( C4Group & hGroup )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
return hGroup . EntryCount ( C4CFN_PNGFiles ) | | hGroup . EntryCount ( C4CFN_BitmapFiles ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4TextureMap : : MoveIndex ( BYTE byOldIndex , BYTE byNewIndex )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Entry [ byNewIndex ] = Entry [ byOldIndex ] ;
fEntriesAdded = true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2009-08-15 18:50:32 +00:00
int32_t C4TextureMap : : GetIndex ( const char * szMaterial , const char * szTexture , bool fAddIfNotExist , const char * szErrorIfFailed )
2010-03-28 18:58:01 +00:00
{
2010-03-27 16:05:02 +00:00
BYTE byIndex ;
// Find existing
2009-05-08 13:28:41 +00:00
for ( byIndex = 1 ; byIndex < C4M_MaxTexIndex ; byIndex + + )
if ( ! Entry [ byIndex ] . isNull ( ) )
if ( SEqualNoCase ( Entry [ byIndex ] . GetMaterialName ( ) , szMaterial ) )
if ( ! szTexture | | SEqualNoCase ( Entry [ byIndex ] . GetTextureName ( ) , szTexture ) )
return byIndex ;
2010-03-27 16:05:02 +00:00
// Add new entry
if ( fAddIfNotExist )
for ( byIndex = 1 ; byIndex < C4M_MaxTexIndex ; byIndex + + )
if ( Entry [ byIndex ] . isNull ( ) )
2010-03-28 18:58:01 +00:00
{
2010-03-27 16:05:02 +00:00
if ( AddEntry ( byIndex , szMaterial , szTexture ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
fEntriesAdded = true ;
return byIndex ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
if ( szErrorIfFailed ) DebugLogF ( " Error getting MatTex %s-%s for %s from TextureMap: Init failed. " , szMaterial , szTexture , szErrorIfFailed ) ;
2010-03-27 16:05:02 +00:00
return 0 ;
2010-03-28 18:58:01 +00:00
}
2010-03-27 16:05:02 +00:00
// Else, fail
2009-05-08 13:28:41 +00:00
if ( szErrorIfFailed ) DebugLogF ( " Error getting MatTex %s-%s for %s from TextureMap: %s. " , szMaterial , szTexture , szErrorIfFailed , fAddIfNotExist ? " Map is full! " : " Entry not found. " ) ;
2010-03-27 16:05:02 +00:00
return 0 ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2009-08-15 18:50:32 +00:00
int32_t C4TextureMap : : GetIndexMatTex ( const char * szMaterialTexture , const char * szDefaultTexture , bool fAddIfNotExist , const char * szErrorIfFailed )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// split material/texture pair
StdStrBuf Material , Texture ;
Material . CopyUntil ( szMaterialTexture , ' - ' ) ;
Texture . Copy ( SSearch ( szMaterialTexture , " - " ) ) ;
// texture not given or invalid?
int32_t iMatTex = 0 ;
2010-03-28 18:58:01 +00:00
if ( Texture . getData ( ) )
if ( ( iMatTex = GetIndex ( Material . getData ( ) , Texture . getData ( ) , fAddIfNotExist ) ) )
2009-05-08 13:28:41 +00:00
return iMatTex ;
2010-03-28 18:58:01 +00:00
if ( szDefaultTexture )
if ( ( iMatTex = GetIndex ( Material . getData ( ) , szDefaultTexture , fAddIfNotExist ) ) )
2009-05-08 13:28:41 +00:00
return iMatTex ;
// search material
2009-06-05 18:46:03 +00:00
long iMaterial = : : MaterialMap . Get ( szMaterialTexture ) ;
2009-05-08 13:28:41 +00:00
if ( ! MatValid ( iMaterial ) )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if ( szErrorIfFailed ) DebugLogF ( " Error getting MatTex for %s: Invalid material " , szErrorIfFailed ) ;
return 0 ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// return default map entry
2009-06-05 18:46:03 +00:00
return : : MaterialMap . Map [ iMaterial ] . DefaultMatTex ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
C4Texture * C4TextureMap : : GetTexture ( const char * szTexture )
2010-03-28 18:58:01 +00:00
{
2010-03-27 16:05:02 +00:00
C4Texture * pTexture ;
for ( pTexture = FirstTexture ; pTexture ; pTexture = pTexture - > Next )
2012-09-05 20:51:25 +00:00
if ( SEqualNoCase ( pTexture - > Name . getData ( ) , szTexture ) )
2010-03-27 16:05:02 +00:00
return pTexture ;
return NULL ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-05-23 23:12:19 +00:00
int32_t C4TextureMap : : GetTextureIndex ( const char * szName )
{
C4Texture * pTexture ;
int32_t i = 0 ;
for ( pTexture = FirstTexture ; pTexture ; pTexture = pTexture - > Next , i + + )
2012-09-05 20:51:25 +00:00
if ( SEqualNoCase ( pTexture - > Name . getData ( ) , szName ) )
2011-05-23 23:12:19 +00:00
return i ;
return - 1 ;
}
2009-05-08 13:28:41 +00:00
bool C4TextureMap : : CheckTexture ( const char * szTexture )
2010-03-28 18:58:01 +00:00
{
2010-03-27 16:05:02 +00:00
C4Texture * pTexture ;
for ( pTexture = FirstTexture ; pTexture ; pTexture = pTexture - > Next )
2012-09-05 20:51:25 +00:00
if ( SEqualNoCase ( pTexture - > Name . getData ( ) , szTexture ) )
2010-03-27 16:05:02 +00:00
return true ;
return false ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
const char * C4TextureMap : : GetTexture ( int32_t iIndex )
2010-03-28 18:58:01 +00:00
{
2010-03-27 16:05:02 +00:00
C4Texture * pTexture ;
2009-05-08 13:28:41 +00:00
int32_t cindex ;
2010-03-27 16:05:02 +00:00
for ( pTexture = FirstTexture , cindex = 0 ; pTexture ; pTexture = pTexture - > Next , cindex + + )
2009-05-08 13:28:41 +00:00
if ( cindex = = iIndex )
2012-09-05 20:51:25 +00:00
return pTexture - > Name . getData ( ) ;
2009-05-08 13:28:41 +00:00
return NULL ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4TextureMap : : Default ( )
2010-03-28 18:58:01 +00:00
{
2010-03-27 16:05:02 +00:00
FirstTexture = NULL ;
2009-05-08 13:28:41 +00:00
fEntriesAdded = false ;
fOverloadMaterials = false ;
fOverloadTextures = false ;
fInitialized = false ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2012-08-15 22:45:27 +00:00
void C4TextureMap : : StoreMapPalette ( CStdPalette * Palette , C4MaterialMap & rMaterial )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Sky color
2012-08-15 22:45:27 +00:00
Palette - > Colors [ 0 ] = C4RGB ( 192 , 196 , 252 ) ;
2009-05-08 13:28:41 +00:00
// Material colors by texture map entries
bool fSet [ 256 ] ;
2010-03-27 16:05:02 +00:00
ZeroMem ( & fSet , sizeof ( fSet ) ) ;
2009-05-08 13:28:41 +00:00
int32_t i ;
2010-03-28 18:58:01 +00:00
for ( i = 0 ; i < C4M_MaxTexIndex ; i + + )
{
2009-05-08 13:28:41 +00:00
// Find material
2009-07-24 21:50:04 +00:00
DWORD dwPix = Entry [ i ] . GetPattern ( ) . PatternClr ( 0 , 0 ) ;
2012-08-15 22:45:27 +00:00
Palette - > Colors [ i ] = dwPix ;
Palette - > Colors [ i + IFT ] = dwPix | 0x0F ; // IFT arbitrarily gets more blue
2009-07-24 21:50:04 +00:00
fSet [ i ] = fSet [ i + IFT ] = true ;
2010-03-28 18:58:01 +00:00
}
2010-03-27 16:05:02 +00:00
// Crosscheck colors, change equal palette entries
2010-03-28 18:58:01 +00:00
for ( i = 0 ; i < 256 ; i + + ) if ( fSet [ i ] )
for ( ; ; )
2010-03-27 16:05:02 +00:00
{
2010-03-28 18:58:01 +00:00
// search equal entry
int32_t j = 0 ;
2012-08-15 22:45:27 +00:00
for ( ; j < i ; j + + )
if ( fSet [ j ] & & Palette - > Colors [ i ] = = Palette - > Colors [ j ] )
2010-03-28 18:58:01 +00:00
break ;
// not found? ok then
if ( j > = i ) break ;
// change randomly
2012-08-15 22:45:27 +00:00
Palette - > Colors [ i ] = C4RGB (
( rand ( ) < RAND_MAX / 2 ) ? GetRedValue ( Palette - > Colors [ i ] ) + 3 : GetRedValue ( Palette - > Colors [ i ] ) - 3 ,
( rand ( ) < RAND_MAX / 2 ) ? GetGreenValue ( Palette - > Colors [ i ] ) + 3 : GetGreenValue ( Palette - > Colors [ i ] ) - 3 ,
( rand ( ) < RAND_MAX / 2 ) ? GetBlueValue ( Palette - > Colors [ i ] ) + 3 : GetBlueValue ( Palette - > Colors [ i ] ) - 3 ) ;
2010-03-27 16:05:02 +00:00
}
2010-03-28 18:58:01 +00:00
}
2009-06-05 15:09:54 +00:00
C4TextureMap TextureMap ;