OpenClonk
C4Texture.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Textures used by the landscape */
19 
20 #include "C4Include.h"
21 #include "landscape/C4Texture.h"
22 
23 #include "c4group/C4Components.h"
24 #include "c4group/C4Group.h"
25 #include "landscape/C4Landscape.h"
26 #include "lib/C4Random.h"
27 #include "lib/StdColors.h"
28 
30 {
31  Surface32=nullptr;
32  AvgColor = 0x00000000;
33  Next=nullptr;
34 }
35 
37 {
38  delete Surface32;
39 }
40 
42  : iMaterialIndex(MNone)
43 {
44 }
45 
47 {
48  Material.Clear(); Texture.Clear();
49  iMaterialIndex = MNone;
50  pMaterial = nullptr;
51  MatPattern.Clear();
52 }
53 
54 bool C4TexMapEntry::Create(const char *szMaterial, const char *szTexture)
55 {
56  // Clear previous data
57  Clear();
58  // Save names
59  Material = szMaterial; Texture = szTexture;
60  return true;
61 }
62 
64 {
65  // Find material
66  iMaterialIndex = ::MaterialMap.Get(Material.getData());
67  if (!MatValid(iMaterialIndex))
68  {
69  DebugLogF("Error initializing material %s-%s: Invalid material!", Material.getData(), Texture.getData());
70  return false;
71  }
72  pMaterial = &::MaterialMap.Map[iMaterialIndex];
73  // Find texture
74  StdStrBuf FirstTexture;
75  FirstTexture.CopyUntil(Texture.getData(), '-');
76  C4Texture * sfcTexture = ::TextureMap.GetTexture(FirstTexture.getData());
77  if (!sfcTexture)
78  {
79  DebugLogF("Error initializing material %s-%s: Invalid texture!", Material.getData(), FirstTexture.getData());
80  Clear();
81  return false;
82  }
83  // Get overlay properties
84  int32_t iOverlayType=pMaterial->OverlayType;
85  int32_t iZoom=0;
86  if (iOverlayType & C4MatOv_Exact) iZoom=1;
87  if (iOverlayType & C4MatOv_HugeZoom) iZoom=4;
88  // Create pattern
89  MatPattern.Set(sfcTexture->Surface32, iZoom);
90  return true;
91 }
92 
94 {
95  Order.reserve(C4M_MaxTexIndex);
96 }
97 
99 {
100  Clear();
101 }
102 
103 bool C4TextureMap::AddEntry(BYTE byIndex, const char *szMaterial, const char *szTexture)
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 }
125 
126 bool C4TextureMap::AddTexture(const char *szTexture, C4Surface * sfcSurface)
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 }
167 
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 }
186 
187 bool C4TextureMap::LoadFlags(C4Group &hGroup, const char *szEntryName, bool *pOverloadMaterials, bool *pOverloadTextures)
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 }
210 
211 int32_t C4TextureMap::LoadMap(C4Group &hGroup, const char *szEntryName, bool *pOverloadMaterials, bool *pOverloadTextures)
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 }
291 
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 }
308 
309 bool C4TextureMap::SaveMap(C4Group &hGroup, const char *szEntryName)
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 }
339 
340 int32_t C4TextureMap::LoadTextures(C4Group &hGroup, C4Group* OverloadFile)
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 }
397 
399 {
400  return hGroup.EntryCount(C4CFN_PNGFiles) || hGroup.EntryCount(C4CFN_BitmapFiles);
401 }
402 
403 void C4TextureMap::MoveIndex(BYTE byOldIndex, BYTE byNewIndex)
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 }
413 
414 int32_t C4TextureMap::GetIndex(const char *szMaterial, const char *szTexture, bool fAddIfNotExist, const char *szErrorIfFailed)
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 }
440 
441 int32_t C4TextureMap::GetIndexMatTex(const char *szMaterialTexture, const char *szDefaultTexture, bool fAddIfNotExist, const char *szErrorIfFailed)
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 }
465 
466 C4Texture * C4TextureMap::GetTexture(const char *szTexture)
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 }
474 
475 int32_t C4TextureMap::GetTextureIndex(const char *szName)
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 }
484 
485 bool C4TextureMap::CheckTexture(const char *szTexture)
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 }
493 
494 const char* C4TextureMap::GetTexture(int32_t iIndex)
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 }
503 
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 }
524 
525 void C4TextureMap::RemoveEntry(int32_t iIndex)
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 }
536 
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 }
575 
#define C4CFN_BitmapFiles
Definition: C4Components.h:174
#define C4CFN_PNGFiles
Definition: C4Components.h:173
#define C4CFN_MaterialShapeFiles
Definition: C4Components.h:133
const int32_t MNone
Definition: C4Constants.h:177
const int C4M_MaxTexIndex
Definition: C4Constants.h:51
C4String * GetTextureName(int32_t texture_nr)
C4Landscape Landscape
int32_t PixCol2Tex(BYTE pixc)
Definition: C4Landscape.h:211
bool DensitySemiSolid(int32_t dens)
Definition: C4Landscape.h:201
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:262
bool DebugLogF(const char *strMessage ...)
Definition: C4Log.cpp:290
int32_t MTunnel
Definition: C4Material.cpp:36
C4MaterialMap MaterialMap
Definition: C4Material.cpp:974
bool MatValid(int32_t mat)
Definition: C4Material.h:210
BYTE Mat2PixColDefault(int32_t mat)
Definition: C4Material.h:235
#define C4MatOv_HugeZoom
Definition: C4Material.h:32
#define C4MatOv_Exact
Definition: C4Material.h:30
uint32_t UnsyncedRandom()
Definition: C4Random.cpp:58
const int C4SF_MipMap
Definition: C4Surface.h:50
C4TextureMap TextureMap
Definition: C4Texture.cpp:576
uint8_t BYTE
uint32_t DWORD
void SReplaceChar(char *str, char fc, char tc)
Definition: Standard.cpp:354
const char * SSearch(const char *szString, const char *szIndex)
Definition: Standard.cpp:369
bool SEqual2(const char *szStr1, const char *szStr2)
Definition: Standard.cpp:204
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen)
Definition: Standard.cpp:213
std::enable_if< std::is_pod< T >::value >::type ZeroMem(T *lpMem, size_t dwSize)
Definition: Standard.h:60
size_t SLen(const char *sptr)
Definition: Standard.h:74
#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
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
int EntryCount(const char *wildcard=nullptr)
Definition: C4Group.cpp:2314
StdStrBuf GetFullName() const
Definition: C4Group.cpp:2638
bool Add(const char *filename, const char *entry_name)
Definition: C4Group.cpp:1621
bool LoadEntry(const char *entry_name, char **buffer, size_t *size_info=nullptr, int zeros_to_append=0)
Definition: C4Group.cpp:2375
bool LoadEntryString(const char *entry_name, StdStrBuf *buffer)
Definition: C4Group.cpp:2430
void ResetSearch(bool reload_contents=false)
Definition: C4Group.cpp:1316
void HandleTexMapUpdate()
int32_t Density
Definition: C4Material.h:92
int32_t OverlayType
Definition: C4Material.h:115
int32_t DefaultMatTex
Definition: C4Material.h:155
C4Material * Map
Definition: C4Material.h:169
int32_t Get(const char *szMaterial)
Definition: C4Material.cpp:365
DWORD PatternClr(unsigned int iX, unsigned int iY) const
Definition: C4Draw.cpp:159
bool Set(class C4Surface *sfcSource, int iZoom=0)
Definition: C4Draw.cpp:114
void Clear()
Definition: C4Draw.cpp:146
int Wdt
Definition: C4Surface.h:65
DWORD GetPixDw(int iX, int iY, bool fApplyModulation)
Definition: C4Surface.cpp:491
bool Read(CStdStream &hGroup, const char *extension, int iFlags)
bool Unlock()
Definition: C4Surface.cpp:464
bool Lock()
Definition: C4Surface.cpp:453
int Hgt
Definition: C4Surface.h:65
Definition: C4Texture.h:49
const C4Pattern & GetPattern() const
Definition: C4Texture.h:64
bool Init()
Definition: C4Texture.cpp:63
C4Material * GetMaterial() const
Definition: C4Texture.h:63
C4TexMapEntry()
Definition: C4Texture.cpp:41
void Clear()
Definition: C4Texture.cpp:46
bool Create(const char *szMaterial, const char *szTexture)
Definition: C4Texture.cpp:54
uint32_t AvgColor
Definition: C4Texture.h:43
void SetAverageColor(uint32_t Color)
Definition: C4Texture.h:37
void SetMaterialShape(class C4TextureShape *s)
Definition: C4Texture.h:39
C4Surface * Surface32
Definition: C4Texture.h:35
C4Texture * Next
Definition: C4Texture.h:45
StdStrBuf Name
Definition: C4Texture.h:42
C4TexMapEntry Entry[C4M_MaxTexIndex]
Definition: C4Texture.h:76
bool CheckTexture(const char *szTexture)
Definition: C4Texture.cpp:485
int32_t GetIndex(const char *szMaterial, const char *szTexture, bool fAddIfNotExist=true, const char *szErrorIfFailed=nullptr)
Definition: C4Texture.cpp:414
C4Texture * FirstTexture
Definition: C4Texture.h:78
int32_t GetIndexMatTex(const char *szMaterialTexture, const char *szDefaultTexture=nullptr, bool fAddIfNotExist=true, const char *szErrorIfFailed=nullptr)
Definition: C4Texture.cpp:441
bool fOverloadTextures
Definition: C4Texture.h:80
bool AddTexture(const char *szTexture, C4Surface *sfcSurface)
Definition: C4Texture.cpp:126
bool SaveMap(C4Group &hGroup, const char *szEntryName)
Definition: C4Texture.cpp:309
bool HasTextures(C4Group &hGroup)
Definition: C4Texture.cpp:398
bool fEntriesAdded
Definition: C4Texture.h:83
BYTE DefaultBkgMatTex(BYTE fg) const
Definition: C4Texture.cpp:504
static bool LoadFlags(C4Group &hGroup, const char *szEntryName, bool *pOverloadMaterials, bool *pOverloadTextures)
Definition: C4Texture.cpp:187
int32_t Init()
Definition: C4Texture.cpp:292
int32_t GetTextureIndex(const char *pTexName)
Definition: C4Texture.cpp:475
const char * GetTexture(int32_t iIndex)
Definition: C4Texture.cpp:494
void Clear()
Definition: C4Texture.cpp:168
int32_t LoadMap(C4Group &hGroup, const char *szEntryName, bool *pOverloadMaterials, bool *pOverloadTextures)
Definition: C4Texture.cpp:211
bool fInitialized
Definition: C4Texture.h:81
void StoreMapPalette(CStdPalette *, C4MaterialMap &rMaterials)
Definition: C4Texture.cpp:537
void MoveIndex(BYTE byOldIndex, BYTE byNewIndex)
Definition: C4Texture.cpp:403
const C4TexMapEntry * GetEntry(int32_t iIndex) const
Definition: C4Texture.h:85
std::vector< int32_t > Order
Definition: C4Texture.h:77
int32_t LoadTextures(C4Group &hGroup, C4Group *OverloadFile=nullptr)
Definition: C4Texture.cpp:340
bool fOverloadMaterials
Definition: C4Texture.h:79
bool AddEntry(BYTE byIndex, const char *szMaterial, const char *szTexture)
Definition: C4Texture.cpp:103
void RemoveEntry(int32_t iIndex)
Definition: C4Texture.cpp:525
void SetLength(size_t iLength)
Definition: StdBuf.h:509
void AppendFormat(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:190
void CopyUntil(const char *szString, char cUntil)
Definition: StdBuf.h:613
const char * getData() const
Definition: StdBuf.h:442
void Copy()
Definition: StdBuf.h:467
void Append(const char *pnData, size_t iChars)
Definition: StdBuf.h:519
void Clear()
Definition: StdBuf.h:466
size_t getLength() const
Definition: StdBuf.h:445
DWORD Colors[256]
Definition: StdColors.h:186