OpenClonk
C4TextureMap Class Reference

#include <C4Texture.h>

Collaboration diagram for C4TextureMap:
[legend]

Public Member Functions

 C4TextureMap ()
 
 ~C4TextureMap ()
 
const C4TexMapEntryGetEntry (int32_t iIndex) const
 
void RemoveEntry (int32_t iIndex)
 
void Clear ()
 
void StoreMapPalette (CStdPalette *, C4MaterialMap &rMaterials)
 
int32_t LoadMap (C4Group &hGroup, const char *szEntryName, bool *pOverloadMaterials, bool *pOverloadTextures)
 
int32_t Init ()
 
bool SaveMap (C4Group &hGroup, const char *szEntryName)
 
int32_t LoadTextures (C4Group &hGroup, C4Group *OverloadFile=nullptr)
 
bool HasTextures (C4Group &hGroup)
 
const char * GetTexture (int32_t iIndex)
 
void MoveIndex (BYTE byOldIndex, BYTE byNewIndex)
 
int32_t GetIndex (const char *szMaterial, const char *szTexture, bool fAddIfNotExist=true, const char *szErrorIfFailed=nullptr)
 
int32_t GetIndexMatTex (const char *szMaterialTexture, const char *szDefaultTexture=nullptr, bool fAddIfNotExist=true, const char *szErrorIfFailed=nullptr)
 
C4TextureGetTexture (const char *szTexture)
 
bool CheckTexture (const char *szTexture)
 
bool AddEntry (BYTE byIndex, const char *szMaterial, const char *szTexture)
 
bool AddTexture (const char *szTexture, C4Surface *sfcSurface)
 
int32_t GetTextureIndex (const char *pTexName)
 
BYTE DefaultBkgMatTex (BYTE fg) const
 

Static Public Member Functions

static bool LoadFlags (C4Group &hGroup, const char *szEntryName, bool *pOverloadMaterials, bool *pOverloadTextures)
 

Public Attributes

bool fEntriesAdded {false}
 

Protected Attributes

C4TexMapEntry Entry [C4M_MaxTexIndex]
 
std::vector< int32_t > Order
 
C4TextureFirstTexture {nullptr}
 
bool fOverloadMaterials {false}
 
bool fOverloadTextures {false}
 
bool fInitialized {false}
 

Friends

class C4Landscape
 

Detailed Description

Definition at line 70 of file C4Texture.h.

Constructor & Destructor Documentation

◆ C4TextureMap()

C4TextureMap::C4TextureMap ( )

Definition at line 93 of file C4Texture.cpp.

94 {
95  Order.reserve(C4M_MaxTexIndex);
96 }
const int C4M_MaxTexIndex
Definition: C4Constants.h:51
std::vector< int32_t > Order
Definition: C4Texture.h:77

References C4M_MaxTexIndex, and Order.

◆ ~C4TextureMap()

C4TextureMap::~C4TextureMap ( )

Definition at line 98 of file C4Texture.cpp.

99 {
100  Clear();
101 }
void Clear()
Definition: C4Texture.cpp:168

References Clear().

Here is the call graph for this function:

Member Function Documentation

◆ AddEntry()

bool C4TextureMap::AddEntry ( BYTE  byIndex,
const char *  szMaterial,
const char *  szTexture 
)

Definition at line 103 of file C4Texture.cpp.

104 {
105  // Security
106  if (byIndex <= 0 || byIndex >= C4M_MaxTexIndex)
107  return false;
108  // Set entry and initialize
109  Entry[byIndex].Create(szMaterial, szTexture);
110  if (fInitialized)
111  {
112  if (!Entry[byIndex].Init())
113  {
114  // Clear entry if it could not be initialized
115  Entry[byIndex].Clear();
116  return false;
117  }
118  // Landscape must be notified (new valid pixel clr)
120  }
121  // Add last in order list
122  Order.push_back(byIndex);
123  return true;
124 }
C4Landscape Landscape
void HandleTexMapUpdate()
void Clear()
Definition: C4Texture.cpp:46
bool Create(const char *szMaterial, const char *szTexture)
Definition: C4Texture.cpp:54
C4TexMapEntry Entry[C4M_MaxTexIndex]
Definition: C4Texture.h:76
int32_t Init()
Definition: C4Texture.cpp:292
bool fInitialized
Definition: C4Texture.h:81

References C4M_MaxTexIndex, C4TexMapEntry::Clear(), C4TexMapEntry::Create(), Entry, fInitialized, C4Landscape::HandleTexMapUpdate(), Init(), Landscape, and Order.

Referenced by GetIndex(), LoadMap(), and C4Landscape::SetTextureIndex().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ AddTexture()

bool C4TextureMap::AddTexture ( const char *  szTexture,
C4Surface sfcSurface 
)

Definition at line 126 of file C4Texture.cpp.

127 {
128  C4Texture *pTexture;
129  if (!(pTexture=new C4Texture)) return false;
130  pTexture->Name.Copy(szTexture);
131  pTexture->Surface32=sfcSurface;
132  pTexture->Next=FirstTexture;
133  FirstTexture=pTexture;
134 
135  // Compute average texture color
136  if(sfcSurface)
137  {
138  sfcSurface->Lock();
139  uint32_t avg_c[4] = { 0, 0, 0, 0 };
140  for(int32_t y = 0; y < sfcSurface->Hgt; ++y)
141  {
142  for(int32_t x = 0; x < sfcSurface->Wdt; ++x)
143  {
144  DWORD c = sfcSurface->GetPixDw(x, y, false);
145  avg_c[0] += c & 0xff;
146  avg_c[1] += (c >> 8) & 0xff;
147  avg_c[2] += (c >> 16) & 0xff;
148  avg_c[3] += (c >> 24) & 0xff;
149  }
150  }
151  sfcSurface->Unlock();
152 
153  double Size = sfcSurface->Wdt * sfcSurface->Hgt;
154  avg_c[0] = static_cast<uint32_t>(avg_c[0] / Size + 0.5);
155  avg_c[1] = static_cast<uint32_t>(avg_c[1] / Size + 0.5);
156  avg_c[2] = static_cast<uint32_t>(avg_c[2] / Size + 0.5);
157  avg_c[3] = static_cast<uint32_t>(avg_c[3] / Size + 0.5);
158  pTexture->SetAverageColor(avg_c[0] | (avg_c[1] << 8) | (avg_c[2] << 16) | (avg_c[3] << 24));
159  }
160  else
161  {
162  pTexture->SetAverageColor(0x00000000);
163  }
164 
165  return true;
166 }
uint32_t DWORD
int Wdt
Definition: C4Surface.h:65
DWORD GetPixDw(int iX, int iY, bool fApplyModulation)
Definition: C4Surface.cpp:491
bool Unlock()
Definition: C4Surface.cpp:464
bool Lock()
Definition: C4Surface.cpp:453
int Hgt
Definition: C4Surface.h:65
void SetAverageColor(uint32_t Color)
Definition: C4Texture.h:37
C4Surface * Surface32
Definition: C4Texture.h:35
C4Texture * Next
Definition: C4Texture.h:45
StdStrBuf Name
Definition: C4Texture.h:42
C4Texture * FirstTexture
Definition: C4Texture.h:78
void Copy()
Definition: StdBuf.h:467

References StdStrBuf::Copy(), FirstTexture, C4Surface::GetPixDw(), C4Surface::Hgt, C4Surface::Lock(), C4Texture::Name, C4Texture::Next, C4Texture::SetAverageColor(), C4Texture::Surface32, C4Surface::Unlock(), and C4Surface::Wdt.

Referenced by LoadTextures().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CheckTexture()

bool C4TextureMap::CheckTexture ( const char *  szTexture)

Definition at line 485 of file C4Texture.cpp.

486 {
487  C4Texture *pTexture;
488  for (pTexture=FirstTexture; pTexture; pTexture=pTexture->Next)
489  if (SEqualNoCase(pTexture->Name.getData(),szTexture))
490  return true;
491  return false;
492 }
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen)
Definition: Standard.cpp:213
const char * getData() const
Definition: StdBuf.h:442

References FirstTexture, StdStrBuf::getData(), C4Texture::Name, C4Texture::Next, and SEqualNoCase().

Referenced by C4MCOverlay::SetField().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Clear()

void C4TextureMap::Clear ( )

Definition at line 168 of file C4Texture.cpp.

169 {
170  for (int32_t i = 1; i < C4M_MaxTexIndex; i++)
171  Entry[i].Clear();
172  C4Texture *ctex,*next2;
173  for (ctex=FirstTexture; ctex; ctex=next2)
174  {
175  next2=ctex->Next;
176  delete ctex;
177  }
178  FirstTexture=nullptr;
179  fInitialized = false;
180  fEntriesAdded = false;
181  fOverloadMaterials = false;
182  fOverloadTextures = false;
183  Order.clear();
184  Order.reserve(C4M_MaxTexIndex);
185 }
bool fOverloadTextures
Definition: C4Texture.h:80
bool fEntriesAdded
Definition: C4Texture.h:83
bool fOverloadMaterials
Definition: C4Texture.h:79

References C4M_MaxTexIndex, Entry, fEntriesAdded, fInitialized, FirstTexture, fOverloadMaterials, fOverloadTextures, C4Texture::Next, and Order.

Referenced by c4_texture_map_handle_new(), C4Game::Clear(), C4Game::InitMaterialTexture(), and ~C4TextureMap().

Here is the caller graph for this function:

◆ DefaultBkgMatTex()

BYTE C4TextureMap::DefaultBkgMatTex ( BYTE  fg) const

Definition at line 504 of file C4Texture.cpp.

505 {
506  // For the given foreground index, find the default background index
507  // If fg is semisolid, this is tunnel.
508  // Otherwise it is fg itself, so that tunnel and background bricks
509  // stay the way they are.
510  int32_t iTex = PixCol2Tex(fg);
511  if (!iTex) return fg; // sky
512 
513  // Get material-texture mapping
514  const C4TexMapEntry *pTex = GetEntry(iTex);
515  // Texmap entry does not exist
516  if(!pTex || !pTex->GetMaterial()) return fg;
517 
518  if(DensitySemiSolid(pTex->GetMaterial()->Density))
519  return Mat2PixColDefault(MTunnel);
520 
521  return fg;
522 
523 }
int32_t PixCol2Tex(BYTE pixc)
Definition: C4Landscape.h:211
bool DensitySemiSolid(int32_t dens)
Definition: C4Landscape.h:201
int32_t MTunnel
Definition: C4Material.cpp:36
BYTE Mat2PixColDefault(int32_t mat)
Definition: C4Material.h:235
int32_t Density
Definition: C4Material.h:92
Definition: C4Texture.h:49
C4Material * GetMaterial() const
Definition: C4Texture.h:63
const C4TexMapEntry * GetEntry(int32_t iIndex) const
Definition: C4Texture.h:85

References C4MaterialCore::Density, DensitySemiSolid(), GetEntry(), C4TexMapEntry::GetMaterial(), Mat2PixColDefault(), MTunnel, and PixCol2Tex().

Referenced by C4Landscape::P::DefaultBkgMat(), FnParTexCol(), and C4ToolsDlg::SetIFT().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetEntry()

const C4TexMapEntry* C4TextureMap::GetEntry ( int32_t  iIndex) const
inline

Definition at line 85 of file C4Texture.h.

85 { return Inside<int32_t>(iIndex, 0, C4M_MaxTexIndex-1) ? &Entry[iIndex] : nullptr; }

References C4M_MaxTexIndex, and Entry.

Referenced by C4EditCursor::ApplyToolPicker(), C4Landscape::P::ChunkOZoom(), C4MaterialMap::CrossMapMaterials(), DefaultBkgMatTex(), C4Landscape::P::DoScan(), GetTextureName(), C4Landscape::P::Mat2Pal(), PixCol2Mat(), C4ToolsDlg::SetIFT(), C4Landscape::SetTextureIndex(), and C4MapCreator::ValidateTextureIndices().

Here is the caller graph for this function:

◆ GetIndex()

int32_t C4TextureMap::GetIndex ( const char *  szMaterial,
const char *  szTexture,
bool  fAddIfNotExist = true,
const char *  szErrorIfFailed = nullptr 
)

Definition at line 414 of file C4Texture.cpp.

415 {
416  BYTE byIndex;
417  // Find existing
418  for (byIndex = 1; byIndex < C4M_MaxTexIndex; byIndex++)
419  if (!Entry[byIndex].isNull())
420  if (SEqualNoCase(Entry[byIndex].GetMaterialName(), szMaterial))
421  if (!szTexture || SEqualNoCase(Entry[byIndex].GetTextureName(), szTexture))
422  return byIndex;
423  // Add new entry
424  if (fAddIfNotExist)
425  for (byIndex=1; byIndex<C4M_MaxTexIndex; byIndex++)
426  if (Entry[byIndex].isNull())
427  {
428  if (AddEntry(byIndex, szMaterial, szTexture))
429  {
430  fEntriesAdded=true;
431  return byIndex;
432  }
433  if (szErrorIfFailed) DebugLogF("Error getting MatTex %s-%s for %s from TextureMap: Init failed.", szMaterial, szTexture, szErrorIfFailed);
434  return 0;
435  }
436  // Else, fail
437  if (szErrorIfFailed) DebugLogF("Error getting MatTex %s-%s for %s from TextureMap: %s.", szMaterial, szTexture, szErrorIfFailed, fAddIfNotExist ? "Map is full!" : "Entry not found.");
438  return 0;
439 }
C4String * GetTextureName(int32_t texture_nr)
bool DebugLogF(const char *strMessage ...)
Definition: C4Log.cpp:290
uint8_t BYTE
bool AddEntry(BYTE byIndex, const char *szMaterial, const char *szTexture)
Definition: C4Texture.cpp:103

References AddEntry(), C4M_MaxTexIndex, DebugLogF(), Entry, fEntriesAdded, GetTextureName(), and SEqualNoCase().

Referenced by C4ToolsDlg::AssertValidBackTexture(), C4ToolsDlg::AssertValidTexture(), C4MaterialMap::CrossMapMaterials(), GetIndexMatTex(), C4Landscape::P::GetMapColorIndex(), and C4Landscape::SetTextureIndex().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetIndexMatTex()

int32_t C4TextureMap::GetIndexMatTex ( const char *  szMaterialTexture,
const char *  szDefaultTexture = nullptr,
bool  fAddIfNotExist = true,
const char *  szErrorIfFailed = nullptr 
)

Definition at line 441 of file C4Texture.cpp.

442 {
443  // split material/texture pair
444  StdStrBuf Material, Texture;
445  Material.CopyUntil(szMaterialTexture, '-');
446  Texture.Copy(SSearch(szMaterialTexture, "-"));
447  // texture not given or invalid?
448  int32_t iMatTex = 0;
449  if (Texture.getData())
450  if ((iMatTex = GetIndex(Material.getData(), Texture.getData(), fAddIfNotExist)))
451  return iMatTex;
452  if (szDefaultTexture)
453  if ((iMatTex = GetIndex(Material.getData(), szDefaultTexture, fAddIfNotExist)))
454  return iMatTex;
455  // search material
456  long iMaterial = ::MaterialMap.Get(szMaterialTexture);
457  if (!MatValid(iMaterial))
458  {
459  if (szErrorIfFailed) DebugLogF("Error getting MatTex for %s: Invalid material", szErrorIfFailed);
460  return 0;
461  }
462  // return default map entry
464 }
C4MaterialMap MaterialMap
Definition: C4Material.cpp:974
bool MatValid(int32_t mat)
Definition: C4Material.h:210
const char * SSearch(const char *szString, const char *szIndex)
Definition: Standard.cpp:369
int32_t DefaultMatTex
Definition: C4Material.h:155
C4Material * Map
Definition: C4Material.h:169
int32_t Get(const char *szMaterial)
Definition: C4Material.cpp:365
int32_t GetIndex(const char *szMaterial, const char *szTexture, bool fAddIfNotExist=true, const char *szErrorIfFailed=nullptr)
Definition: C4Texture.cpp:414
void CopyUntil(const char *szString, char cUntil)
Definition: StdBuf.h:613

References StdStrBuf::Copy(), StdStrBuf::CopyUntil(), DebugLogF(), C4Material::DefaultMatTex, C4MaterialMap::Get(), StdStrBuf::getData(), GetIndex(), C4MaterialMap::Map, MaterialMap, MatValid(), and SSearch().

Referenced by C4MapCreator::Create(), C4MaterialMap::CrossMapMaterials(), C4Landscape::DrawPolygon(), C4MCOverlay::Evaluate(), and C4ToolsDlg::SetIFT().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetTexture() [1/2]

C4Texture * C4TextureMap::GetTexture ( const char *  szTexture)

Definition at line 466 of file C4Texture.cpp.

467 {
468  C4Texture *pTexture;
469  for (pTexture=FirstTexture; pTexture; pTexture=pTexture->Next)
470  if (SEqualNoCase(pTexture->Name.getData(),szTexture))
471  return pTexture;
472  return nullptr;
473 }

References FirstTexture, StdStrBuf::getData(), C4Texture::Name, C4Texture::Next, and SEqualNoCase().

Here is the call graph for this function:

◆ GetTexture() [2/2]

const char * C4TextureMap::GetTexture ( int32_t  iIndex)

Definition at line 494 of file C4Texture.cpp.

495 {
496  C4Texture *pTexture;
497  int32_t cindex;
498  for (pTexture=FirstTexture,cindex=0; pTexture; pTexture=pTexture->Next,cindex++)
499  if (cindex==iIndex)
500  return pTexture->Name.getData();
501  return nullptr;
502 }

References FirstTexture, StdStrBuf::getData(), C4Texture::Name, and C4Texture::Next.

Referenced by C4ToolsDlg::AssertValidBackTexture(), C4ToolsDlg::AssertValidTexture(), C4Landscape::P::ChunkOZoom(), C4MaterialMap::CrossMapMaterials(), C4Landscape::DrawBox(), C4Landscape::DrawBrush(), C4Landscape::DrawLine(), C4TexMapEntry::Init(), LoadTextures(), C4ToolsDlg::SetBackTexture(), C4ToolsDlg::SetTexture(), and StoreMapPalette().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetTextureIndex()

int32_t C4TextureMap::GetTextureIndex ( const char *  pTexName)

Definition at line 475 of file C4Texture.cpp.

476 {
477  C4Texture *pTexture;
478  int32_t i=0;
479  for (pTexture=FirstTexture; pTexture; pTexture=pTexture->Next, i++)
480  if (SEqualNoCase(pTexture->Name.getData(),szName))
481  return i;
482  return -1;
483 }

References FirstTexture, StdStrBuf::getData(), C4Texture::Name, C4Texture::Next, and SEqualNoCase().

Here is the call graph for this function:

◆ HasTextures()

bool C4TextureMap::HasTextures ( C4Group hGroup)

Definition at line 398 of file C4Texture.cpp.

399 {
400  return hGroup.EntryCount(C4CFN_PNGFiles) || hGroup.EntryCount(C4CFN_BitmapFiles);
401 }
#define C4CFN_BitmapFiles
Definition: C4Components.h:174
#define C4CFN_PNGFiles
Definition: C4Components.h:173
int EntryCount(const char *wildcard=nullptr)
Definition: C4Group.cpp:2314

References C4CFN_BitmapFiles, C4CFN_PNGFiles, and C4Group::EntryCount().

Here is the call graph for this function:

◆ Init()

int32_t C4TextureMap::Init ( )

Definition at line 292 of file C4Texture.cpp.

293 {
294  int32_t iRemoved = 0;
295  // Initialize texture mappings
296  int32_t i;
297  for (i = 0; i < C4M_MaxTexIndex; i++)
298  if (!Entry[i].isNull())
299  if (!Entry[i].Init())
300  {
301  LogF("Error in TextureMap initialization at entry %d", (int) i);
302  Entry[i].Clear();
303  iRemoved++;
304  }
305  fInitialized = true;
306  return iRemoved;
307 }
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:262

References C4M_MaxTexIndex, C4TexMapEntry::Clear(), Entry, fInitialized, and LogF().

Referenced by AddEntry(), c4_texture_map_handle_new(), and C4Game::InitMaterialTexture().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadFlags()

bool C4TextureMap::LoadFlags ( C4Group hGroup,
const char *  szEntryName,
bool *  pOverloadMaterials,
bool *  pOverloadTextures 
)
static

Definition at line 187 of file C4Texture.cpp.

188 {
189  // Load the file
190  StdStrBuf TexMap;
191  if (!hGroup.LoadEntryString(szEntryName, &TexMap))
192  return false;
193  // Reset flags
194  if (pOverloadMaterials) *pOverloadMaterials = false;
195  if (pOverloadTextures) *pOverloadTextures = false;
196  // Check if there are flags in there
197  for (const char *pPos = TexMap.getData(); pPos && *pPos; pPos = SSearch(pPos + 1, "\n"))
198  {
199  // Go over newlines
200  while (*pPos == '\r' || *pPos == '\n') pPos++;
201  // Flag?
202  if (pOverloadMaterials && SEqual2(pPos, "OverloadMaterials"))
203  *pOverloadMaterials = true;
204  if (pOverloadTextures && SEqual2(pPos, "OverloadTextures"))
205  *pOverloadTextures = true;
206  }
207  // Done
208  return true;
209 }
bool SEqual2(const char *szStr1, const char *szStr2)
Definition: Standard.cpp:204
bool LoadEntryString(const char *entry_name, StdStrBuf *buffer)
Definition: C4Group.cpp:2430

References StdStrBuf::getData(), C4Group::LoadEntryString(), SEqual2(), and SSearch().

Referenced by C4Game::InitMaterialTexture().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadMap()

int32_t C4TextureMap::LoadMap ( C4Group hGroup,
const char *  szEntryName,
bool *  pOverloadMaterials,
bool *  pOverloadTextures 
)

Definition at line 211 of file C4Texture.cpp.

212 {
213  static std::regex line_terminator("\r?\n", static_cast<std::regex::flag_type>(std::regex_constants::optimize | std::regex_constants::ECMAScript));
214 
215  char *bpMap;
216  size_t map_size;
217  int32_t iTextures = 0;
218  // Load text file into memory
219  if (!hGroup.LoadEntry(szEntryName,&bpMap,&map_size,1)) return 0;
220 
221  char *begin = bpMap;
222  char *end = begin + map_size;
223 
224  size_t line = 1; // Counter for error messages
225  for (auto it = std::cregex_token_iterator(begin, end, line_terminator, -1); it != std::cregex_token_iterator(); ++it, ++line)
226  {
227  if (it->compare("OverloadMaterials") == 0)
228  {
229  fOverloadMaterials = true;
230  if (pOverloadMaterials)
231  *pOverloadMaterials = true;
232  }
233  else if (it->compare("OverloadTextures") == 0)
234  {
235  fOverloadTextures = true;
236  if (pOverloadTextures)
237  *pOverloadTextures = true;
238  }
239  else if (it->length() == 0 || it->first[0] == '#' || std::all_of(it->first, it->second, &isspace))
240  {
241  // Skip empty lines, comments, and all-whitespace lines
242  continue;
243  }
244  else
245  {
246  // This must be a texmap entry now
247  std::string value;
248 
249  // Read index
250  unsigned long index;
251  try
252  {
253  size_t separator;
254  index = std::stoul(it->str(), &separator, 10);
255  if (index >= C4M_MaxTexIndex)
256  throw std::out_of_range("Texture index out of range");
257  value.assign(it->first + separator + 1, it->second);
258  }
259  catch (std::invalid_argument &)
260  {
261  DebugLogF("TexMap line %u: Texture index is not numeric", static_cast<unsigned>(line));
262  continue;
263  }
264  catch (std::out_of_range &)
265  {
266  DebugLogF("TexMap line %u: Texture index is out of range", static_cast<unsigned>(line));
267  continue;
268  }
269 
270  // Split material/texture combination
271  std::string::const_iterator separator = std::find(value.cbegin(), value.cend(), '-');
272  if (separator == value.cend())
273  {
274  DebugLogF(R"(TexMap line %u: Texture name "%s" is invalid (missing "-"))", static_cast<unsigned>(line), value.c_str());
275  continue;
276  }
277 
278  std::string material(value.cbegin(), separator);
279  std::string texture(separator + 1, value.cend());
280 
281  if (AddEntry(index, material.c_str(), texture.c_str()))
282  ++iTextures;
283  }
284  }
285 
286  // Delete buffer, return entry count
287  delete [] bpMap;
288  fEntriesAdded=false;
289  return iTextures;
290 }
bool LoadEntry(const char *entry_name, char **buffer, size_t *size_info=nullptr, int zeros_to_append=0)
Definition: C4Group.cpp:2375

References AddEntry(), C4M_MaxTexIndex, DebugLogF(), fEntriesAdded, fOverloadMaterials, fOverloadTextures, and C4Group::LoadEntry().

Referenced by C4Game::InitMaterialTexture().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadTextures()

int32_t C4TextureMap::LoadTextures ( C4Group hGroup,
C4Group OverloadFile = nullptr 
)

Definition at line 340 of file C4Texture.cpp.

341 {
342  int32_t texnum=0;
343  // overload: load from other file
344  if (OverloadFile) texnum+=LoadTextures(*OverloadFile);
345 
346  char texname[256+1];
347  C4Surface *ctex;
348  size_t binlen;
349 
350  hGroup.ResetSearch();
351  while (hGroup.AccessNextEntry("*",&binlen,texname))
352  {
353  // check if it already exists in the map
354  const char *base_filename = GetFilenameOnly(texname);
355  if (GetTexture(base_filename)) continue;
356  // skip shape textures for now. Will be added later after all base textures have been loaded
357  if (WildcardMatch("*" C4CFN_MaterialShapeFiles, texname)) continue;
358  // create surface
359  ctex = new C4Surface();
360  if (ctex->Read(hGroup, GetExtension(texname), C4SF_MipMap))
361  {
362  SReplaceChar(texname,'.',0);
363  if (AddTexture(texname,ctex)) texnum++;
364  else delete ctex;
365  }
366  else
367  {
368  delete ctex;
369  }
370  }
371 
372  // Load texture shapes
373  hGroup.ResetSearch();
374  while (hGroup.AccessNextEntry("*" C4CFN_MaterialShapeFiles, &binlen, texname))
375  {
376  // get associated texture
377  StdStrBuf texname4shape(texname, true);
378  texname4shape.SetLength(texname4shape.getLength() - SLen(C4CFN_MaterialShapeFiles));
379  C4Texture *base_tex = GetTexture(texname4shape.getData());
380  if (!base_tex || !base_tex->Surface32)
381  {
382  LogF("ERROR: Texture shape %s not loaded because associated texture (%s) not found or invalid.", hGroup.GetFullName().getData(), texname4shape.getData());
383  continue;
384  }
385  std::unique_ptr<C4TextureShape> shape(new C4TextureShape());
386  int32_t scaler_zoom = 4;
387  if (!shape->Load(hGroup, texname, base_tex->Surface32->Wdt / scaler_zoom, base_tex->Surface32->Hgt / scaler_zoom))
388  {
389  LogF("Error loading texture shape %s.", hGroup.GetFullName().getData());
390  continue;
391  }
392  base_tex->SetMaterialShape(shape.release());
393  }
394 
395  return texnum;
396 }
#define C4CFN_MaterialShapeFiles
Definition: C4Components.h:133
const int C4SF_MipMap
Definition: C4Surface.h:50
void SReplaceChar(char *str, char fc, char tc)
Definition: Standard.cpp:354
size_t SLen(const char *sptr)
Definition: Standard.h:74
char * GetExtension(char *szFilename)
Definition: StdFile.cpp:118
bool WildcardMatch(const char *szWildcard, const char *szString)
Definition: StdFile.cpp:396
const char * GetFilenameOnly(const char *strFilename)
Definition: StdFile.cpp:57
bool AccessNextEntry(const char *wildcard, size_t *size=nullptr, char *filename=nullptr, bool start_at_filename=false)
Definition: C4Group.cpp:2140
StdStrBuf GetFullName() const
Definition: C4Group.cpp:2638
void ResetSearch(bool reload_contents=false)
Definition: C4Group.cpp:1316
bool Read(CStdStream &hGroup, const char *extension, int iFlags)
void SetMaterialShape(class C4TextureShape *s)
Definition: C4Texture.h:39
bool AddTexture(const char *szTexture, C4Surface *sfcSurface)
Definition: C4Texture.cpp:126
const char * GetTexture(int32_t iIndex)
Definition: C4Texture.cpp:494
int32_t LoadTextures(C4Group &hGroup, C4Group *OverloadFile=nullptr)
Definition: C4Texture.cpp:340

References C4Group::AccessNextEntry(), AddTexture(), C4CFN_MaterialShapeFiles, C4SF_MipMap, StdStrBuf::getData(), GetExtension(), GetFilenameOnly(), C4Group::GetFullName(), StdStrBuf::getLength(), GetTexture(), C4Surface::Hgt, LogF(), C4Surface::Read(), C4Group::ResetSearch(), StdStrBuf::SetLength(), C4Texture::SetMaterialShape(), SLen(), SReplaceChar(), C4Texture::Surface32, C4Surface::Wdt, and WildcardMatch().

Referenced by C4Game::InitMaterialTexture().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ MoveIndex()

void C4TextureMap::MoveIndex ( BYTE  byOldIndex,
BYTE  byNewIndex 
)

Definition at line 403 of file C4Texture.cpp.

404 {
405  if (byNewIndex == byOldIndex) return;
406  Entry[byNewIndex] = Entry[byOldIndex];
407  Entry[byOldIndex].Clear();
408  auto old_entry = std::find_if(Order.begin(), Order.end(),
409  [byOldIndex](const int32_t &entry) { return entry == byOldIndex; });
410  if (old_entry != Order.end()) *old_entry = byNewIndex;
411  fEntriesAdded = true;
412 }

References C4TexMapEntry::Clear(), Entry, fEntriesAdded, and Order.

Referenced by C4Landscape::SetTextureIndex().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RemoveEntry()

void C4TextureMap::RemoveEntry ( int32_t  iIndex)

Definition at line 525 of file C4Texture.cpp.

526 {
527  // remove entry from table and order vector
528  if (Inside<int32_t>(iIndex, 1, C4M_MaxTexIndex - 1))
529  {
530  Entry[iIndex].Clear();
531  auto last_entry = std::remove_if(Order.begin(), Order.end(),
532  [iIndex](const int32_t &entry) { return entry == iIndex; });
533  Order.erase(last_entry, Order.end());
534  }
535 }

References C4M_MaxTexIndex, C4TexMapEntry::Clear(), Entry, and Order.

Referenced by C4Landscape::RemoveUnusedTexMapEntries().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SaveMap()

bool C4TextureMap::SaveMap ( C4Group hGroup,
const char *  szEntryName 
)

Definition at line 309 of file C4Texture.cpp.

310 {
311  // build file in memory
312  StdStrBuf sTexMapFile;
313  // add desc
314  sTexMapFile.Append("# Automatically generated texture map\n");
315  sTexMapFile.Append("# Contains material-texture-combinations added at runtime\n");
316  // add overload-entries
317  if (fOverloadMaterials) sTexMapFile.Append("# Import materials from global file as well\nOverloadMaterials\n");
318  if (fOverloadTextures) sTexMapFile.Append("# Import textures from global file as well\nOverloadTextures\n");
319  sTexMapFile.Append("\n");
320  // add entries
321  for (auto i : Order)
322  {
323  if (!Entry[i].isNull())
324  {
325  // compose line
326  sTexMapFile.AppendFormat("%d=%s-%s\n", i, Entry[i].GetMaterialName(), Entry[i].GetTextureName());
327  }
328  }
329  // create new buffer allocated with new [], because C4Group cannot handle StdStrBuf-buffers
330  size_t iBufSize = sTexMapFile.getLength();
331  BYTE *pBuf = new BYTE[iBufSize];
332  memcpy(pBuf, sTexMapFile.getData(), iBufSize);
333  // add to group
334  bool fSuccess = !!hGroup.Add(szEntryName, pBuf, iBufSize, false, true);
335  if (!fSuccess) delete [] pBuf;
336  // done
337  return fSuccess;
338 }
bool Add(const char *filename, const char *entry_name)
Definition: C4Group.cpp:1621
void AppendFormat(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:190
void Append(const char *pnData, size_t iChars)
Definition: StdBuf.h:519
size_t getLength() const
Definition: StdBuf.h:445

References C4Group::Add(), StdStrBuf::Append(), StdStrBuf::AppendFormat(), Entry, fOverloadMaterials, fOverloadTextures, StdStrBuf::getData(), StdStrBuf::getLength(), GetTextureName(), and Order.

Referenced by C4Landscape::SaveTextures().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ StoreMapPalette()

void C4TextureMap::StoreMapPalette ( CStdPalette Palette,
C4MaterialMap rMaterials 
)

Definition at line 537 of file C4Texture.cpp.

538 {
539  // Sky color
540  Palette->Colors[0] = C4RGB(192, 196, 252);
541  // Material colors by texture map entries
542  bool fSet[C4M_MaxTexIndex];
543  ZeroMem(&fSet, sizeof (fSet));
544  int32_t i;
545  for (i = 1; i < C4M_MaxTexIndex; i++)
546  {
547  // Find material
548  DWORD dwPix;
549  auto texture = GetTexture(Entry[i].GetTextureName());
550  if (texture)
551  dwPix = texture->GetAverageColor();
552  else
553  dwPix = Entry[i].GetPattern().PatternClr(0, 0);
554  Palette->Colors[i] = dwPix;
555  fSet[i] = true;
556  }
557  // Crosscheck colors, change equal palette entries
558  for (i = 0; i < C4M_MaxTexIndex; i++) if (fSet[i])
559  for (;;)
560  {
561  // search equal entry
562  int32_t j = 0;
563  for (; j < i; j++)
564  if (fSet[j] && Palette->Colors[i] == Palette->Colors[j])
565  break;
566  // not found? ok then
567  if (j >= i) break;
568  // change randomly
569  Palette->Colors[i] = C4RGB(
570  UnsyncedRandom(2) ? GetRedValue(Palette->Colors[i]) + 3 : GetRedValue(Palette->Colors[i]) - 3,
571  UnsyncedRandom(2) ? GetGreenValue(Palette->Colors[i]) + 3 : GetGreenValue(Palette->Colors[i]) - 3,
572  UnsyncedRandom(2) ? GetBlueValue(Palette->Colors[i]) + 3 : GetBlueValue(Palette->Colors[i]) - 3);
573  }
574 }
uint32_t UnsyncedRandom()
Definition: C4Random.cpp:58
std::enable_if< std::is_pod< T >::value >::type ZeroMem(T *lpMem, size_t dwSize)
Definition: Standard.h:60
#define C4RGB(r, g, b)
Definition: StdColors.h:26
#define GetRedValue(rgb)
Definition: StdColors.h:29
#define GetGreenValue(rgb)
Definition: StdColors.h:28
#define GetBlueValue(rgb)
Definition: StdColors.h:27
DWORD PatternClr(unsigned int iX, unsigned int iY) const
Definition: C4Draw.cpp:159
const C4Pattern & GetPattern() const
Definition: C4Texture.h:64
DWORD Colors[256]
Definition: StdColors.h:186

References C4M_MaxTexIndex, C4RGB, CStdPalette::Colors, Entry, GetBlueValue, GetGreenValue, C4TexMapEntry::GetPattern(), GetRedValue, GetTexture(), GetTextureName(), C4Pattern::PatternClr(), UnsyncedRandom(), and ZeroMem().

Referenced by C4Landscape::SaveMap().

Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Function Documentation

◆ C4Landscape

friend class C4Landscape
friend

Definition at line 106 of file C4Texture.h.

Member Data Documentation

◆ Entry

C4TexMapEntry C4TextureMap::Entry[C4M_MaxTexIndex]
protected

◆ fEntriesAdded

bool C4TextureMap::fEntriesAdded {false}

◆ fInitialized

bool C4TextureMap::fInitialized {false}
protected

Definition at line 81 of file C4Texture.h.

Referenced by AddEntry(), Clear(), and Init().

◆ FirstTexture

C4Texture* C4TextureMap::FirstTexture {nullptr}
protected

Definition at line 78 of file C4Texture.h.

Referenced by AddTexture(), CheckTexture(), Clear(), GetTexture(), and GetTextureIndex().

◆ fOverloadMaterials

bool C4TextureMap::fOverloadMaterials {false}
protected

Definition at line 79 of file C4Texture.h.

Referenced by Clear(), LoadMap(), and SaveMap().

◆ fOverloadTextures

bool C4TextureMap::fOverloadTextures {false}
protected

Definition at line 80 of file C4Texture.h.

Referenced by Clear(), LoadMap(), and SaveMap().

◆ Order

std::vector<int32_t> C4TextureMap::Order
protected

The documentation for this class was generated from the following files: