OpenClonk
C4DefGraphics.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2004-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 // graphics used by object definitions (object and portraits)
17 
18 #include "C4Include.h"
19 #include "object/C4DefGraphics.h"
20 
21 #include "c4group/C4Components.h"
22 #include "game/C4Application.h"
23 #include "graphics/C4Draw.h"
25 #include "graphics/C4Surface.h"
26 #include "gui/C4Menu.h"
27 #include "landscape/C4Material.h"
28 #include "lib/StdMeshLoader.h"
29 #include "object/C4Def.h"
30 #include "object/C4DefList.h"
31 #include "object/C4GameObjects.h"
32 #include "object/C4MeshAnimation.h"
33 #include "object/C4Object.h"
34 #include "object/C4ObjectInfo.h"
35 #include "object/C4ObjectMenu.h"
36 #include "player/C4Player.h"
37 #include "player/C4PlayerList.h"
38 #include "player/C4RankSystem.h"
39 
40 //-------------------------------- C4DefGraphics -----------------------------------------------
41 
43 {
44  // store def
45  pDef = pOwnDef;
46  // zero fields
47  Type = TYPE_None;
48  Bmp.Bitmap = Bmp.BitmapClr = Bmp.BitmapNormal = nullptr;
49  pNext = nullptr;
51 }
52 
54 {
55  C4DefGraphics *pLast = this;
56  while (pLast->pNext) pLast = pLast->pNext;
57  return pLast;
58 }
59 
61 {
62  // zero own fields
63  switch (Type)
64  {
65  case TYPE_None:
66  break;
67  case TYPE_Bitmap:
68  if (Bmp.BitmapNormal) { delete Bmp.BitmapNormal; Bmp.BitmapNormal=nullptr; }
69  if (Bmp.BitmapClr) { delete Bmp.BitmapClr; Bmp.BitmapClr=nullptr; }
70  if (Bmp.Bitmap) { delete Bmp.Bitmap; Bmp.Bitmap=nullptr; }
71  break;
72  case TYPE_Mesh:
73  if (Mesh) { delete Mesh; Mesh = nullptr; }
74  break;
75  }
76  Type = TYPE_None;
77 
78  // delete additonal graphics
79  C4AdditionalDefGraphics *pGrp2N = pNext, *pGrp2;
80  while ((pGrp2=pGrp2N)) { pGrp2N = pGrp2->pNext; pGrp2->pNext = nullptr; delete pGrp2; }
81  pNext = nullptr; fColorBitmapAutoCreated = false;
82 }
83 
84 bool C4DefGraphics::LoadBitmap(C4Group &hGroup, const char *szFilename, const char *szOverlay, const char *szNormal, bool fColorByOwner)
85 {
86  if (!szFilename) return false;
87  Type = TYPE_Bitmap; // will be reset to TYPE_None in Clear() if loading fails
88  Bmp.Bitmap = new C4Surface();
89  if (!Bmp.Bitmap->Load(hGroup, szFilename, false, true, C4SF_MipMap))
90  {
91  Clear();
92  return false;
93  }
94 
95  // Create owner color bitmaps
96  if (fColorByOwner)
97  {
98  // Create additionmal bitmap
99  Bmp.BitmapClr=new C4Surface();
100  // if overlay-surface is present, load from that
101  if (szOverlay && Bmp.BitmapClr->Load(hGroup, szOverlay, false, false, C4SF_MipMap))
102  {
103  // set as Clr-surface, also checking size
104  if (!Bmp.BitmapClr->SetAsClrByOwnerOf(Bmp.Bitmap))
105  {
106  DebugLogF(" Gfx loading error in %s: %s (%d x %d) doesn't match overlay %s (%d x %d) - invalid file or size mismatch",
107  hGroup.GetFullName().getData(), szFilename, Bmp.Bitmap ? Bmp.Bitmap->Wdt : -1, Bmp.Bitmap ? Bmp.Bitmap->Hgt : -1,
108  szOverlay, Bmp.BitmapClr->Wdt, Bmp.BitmapClr->Hgt);
109  Clear();
110  return false;
111  }
112  }
113  else
114  {
115  // otherwise, create by all blue shades
116  if (!Bmp.BitmapClr->CreateColorByOwner(Bmp.Bitmap))
117  {
118  Clear();
119  return false;
120  }
121  }
123  }
124 
125  if (szNormal)
126  {
127  Bmp.BitmapNormal = new C4Surface();
128  if (Bmp.BitmapNormal->Load(hGroup, szNormal, false, true, C4SF_MipMap))
129  {
130  // Normal map loaded. Sanity check and link.
131  if(Bmp.BitmapNormal->Wdt != Bmp.Bitmap->Wdt ||
132  Bmp.BitmapNormal->Hgt != Bmp.Bitmap->Hgt)
133  {
134  DebugLogF(" Gfx loading error in %s: %s (%d x %d) doesn't match normal %s (%d x %d) - invalid file or size mismatch",
135  hGroup.GetFullName().getData(), szFilename, Bmp.Bitmap ? Bmp.Bitmap->Wdt : -1, Bmp.Bitmap ? Bmp.Bitmap->Hgt : -1,
136  szNormal, Bmp.BitmapNormal->Wdt, Bmp.BitmapNormal->Hgt);
137  Clear();
138  return false;
139  }
140 
141  Bmp.Bitmap->pNormalSfc = Bmp.BitmapNormal;
142  if(Bmp.BitmapClr) Bmp.BitmapClr->pNormalSfc = Bmp.BitmapNormal;
143  }
144  else
145  {
146  // No normal map
147  delete Bmp.BitmapNormal;
148  Bmp.BitmapNormal = nullptr;
149  }
150  }
151 
152  Type = TYPE_Bitmap;
153  // success
154  return true;
155 }
156 
157 bool C4DefGraphics::LoadMesh(C4Group &hGroup, const char* szFileName, StdMeshSkeletonLoader& loader)
158 {
159  char* buf = nullptr;
160  size_t size;
161 
162  try
163  {
164  if(!hGroup.LoadEntry(szFileName, &buf, &size, 1)) return false;
165 
166  if (SEqualNoCase(GetExtension(szFileName), "xml"))
167  {
168  Mesh = StdMeshLoader::LoadMeshXml(buf, size, ::MeshMaterialManager, loader, hGroup.GetName());
169  }
170  else
171  {
172  Mesh = StdMeshLoader::LoadMeshBinary(buf, size, ::MeshMaterialManager, loader, hGroup.GetName());
173  }
174  delete[] buf;
175 
176  Mesh->SetLabel(pDef->id.ToString());
177 
178  // order submeshes
179  Mesh->PostInit();
180  }
181  catch (const std::runtime_error& ex)
182  {
183  DebugLogF("Failed to load mesh in definition %s: %s", hGroup.GetName(), ex.what());
184  delete[] buf;
185  return false;
186  }
187 
188  Type = TYPE_Mesh;
189  return true;
190 }
191 
192 bool C4DefGraphics::LoadSkeleton(C4Group &hGroup, const char* szFileName, StdMeshSkeletonLoader& loader)
193 {
194  char* buf = nullptr;
195  size_t size;
196 
197  try
198  {
199  if (!hGroup.LoadEntry(szFileName, &buf, &size, 1)) return false;
200 
201  // delete skeleton from the map for reloading, or else if you delete or rename
202  // a skeleton file in the folder the old skeleton will still exist in the map
203  loader.RemoveSkeleton(hGroup.GetName(), szFileName);
204 
205  if (SEqualNoCase(GetExtension(szFileName), "xml"))
206  {
207  loader.LoadSkeletonXml(hGroup.GetName(), szFileName, buf, size);
208  }
209  else
210  {
211  loader.LoadSkeletonBinary(hGroup.GetName(), szFileName, buf, size);
212  }
213 
214  delete[] buf;
215  }
216  catch (const std::runtime_error& ex)
217  {
218  DebugLogF("Failed to load skeleton in definition %s: %s", hGroup.GetName(), ex.what());
219  delete[] buf;
220  return false;
221  }
222 
223  return true;
224 }
225 
226 bool C4DefGraphics::Load(C4Group &hGroup, StdMeshSkeletonLoader &loader, bool fColorByOwner)
227 {
228  char Filename[_MAX_PATH_LEN]; *Filename=0;
229 
230  // load skeletons
231  hGroup.ResetSearch();
232  while (hGroup.FindNextEntry("*", Filename, nullptr, !!*Filename))
233  {
234  if (!WildcardMatch(C4CFN_DefSkeleton, Filename) && !WildcardMatch(C4CFN_DefSkeletonXml, Filename)) continue;
235  LoadSkeleton(hGroup, Filename, loader);
236  }
237 
238  // Try from Mesh first
239  if (!LoadMesh(hGroup, C4CFN_DefMesh, loader))
240  if(!LoadMesh(hGroup, C4CFN_DefMeshXml, loader))
242 
243  // load additional graphics
244  C4DefGraphics *pLastGraphics = this;
245  const int32_t iOverlayWildcardPos = SCharPos('*', C4CFN_ClrByOwnerEx);
246  hGroup.ResetSearch(); *Filename=0;
247  const char* const AdditionalGraphics[] = { C4CFN_DefGraphicsEx, C4CFN_DefGraphicsExMesh, C4CFN_DefGraphicsExMeshXml, nullptr };
248  while (hGroup.FindNextEntry("*", Filename, nullptr, !!*Filename))
249  {
250  for(const char* const* szWildcard = AdditionalGraphics; *szWildcard != nullptr; ++szWildcard)
251  {
252  if(!WildcardMatch(*szWildcard, Filename)) continue;
253  // skip def graphics
254  if (SEqualNoCase(Filename, C4CFN_DefGraphics) || SEqualNoCase(Filename, C4CFN_DefMesh) || SEqualNoCase(Filename, C4CFN_DefMeshXml)) continue;
255  // skip scaled def graphics
256  if (WildcardMatch(C4CFN_DefGraphicsScaled, Filename)) continue;
257  // get name
258  char GrpName[_MAX_PATH_LEN];
259  const int32_t iWildcardPos = SCharPos('*', *szWildcard);
260  SCopy(Filename + iWildcardPos, GrpName, _MAX_PATH);
261  RemoveExtension(GrpName);
262  // remove trailing number for scaled graphics
263  int32_t extpos; int scale;
264  if ((extpos = SCharLastPos('.', GrpName)) > -1)
265  if (sscanf(GrpName+extpos+1, "%d", &scale) == 1)
266  GrpName[extpos] = '\0';
267  // clip to max length
268  GrpName[C4MaxName]=0;
269  // create new graphics
270  pLastGraphics->pNext = new C4AdditionalDefGraphics(pDef, GrpName);
271  pLastGraphics = pLastGraphics->pNext;
272  if(*szWildcard == AdditionalGraphics[0])
273  {
274  // create overlay-filename
275  char OverlayFn[_MAX_PATH_LEN];
276  if(fColorByOwner)
277  {
278  // GraphicsX.png -> OverlayX.png
279  SCopy(C4CFN_ClrByOwnerEx, OverlayFn, _MAX_PATH);
280  OverlayFn[iOverlayWildcardPos]=0;
281  SAppend(Filename + iWildcardPos, OverlayFn);
283  }
284 
285  // create normal filename
286  char NormalFn[_MAX_PATH_LEN];
287  SCopy(C4CFN_NormalMapEx, NormalFn, _MAX_PATH);
288  NormalFn[iOverlayWildcardPos]=0;
289  SAppend(Filename + iWildcardPos, NormalFn);
291 
292  // load them
293  if (!pLastGraphics->LoadBitmap(hGroup, Filename, fColorByOwner ? OverlayFn : nullptr, NormalFn, fColorByOwner))
294  return false;
295  }
296  else
297  {
298  if (!pLastGraphics->LoadMesh(hGroup, Filename, loader))
299  return false;
300  }
301  }
302  }
303  // done, success
304  return true;
305 }
306 
307 C4DefGraphics *C4DefGraphics::Get(const char *szGrpName)
308 {
309  // no group or empty string: base graphics
310  if (!szGrpName || !szGrpName[0]) return this;
311  // search additional graphics
312  for (C4AdditionalDefGraphics *pGrp = pNext; pGrp; pGrp=pGrp->pNext)
313  if (SEqualNoCase(pGrp->GetName(), szGrpName)) return pGrp;
314  // nothing found
315  return nullptr;
316 }
317 
318 void C4DefGraphics::Draw(C4Facet &cgo, DWORD iColor, C4Object *pObj, int32_t iPhaseX, int32_t iPhaseY, C4DrawTransform* trans)
319 {
320  // default: def picture rect
321  C4Rect fctPicRect = pDef->PictureRect;
322  C4Facet fctPicture;
323 
324  // if assigned: use object specific rect and graphics
325  if (pObj) if (pObj->PictureRect.Wdt) fctPicRect = pObj->PictureRect;
326 
327  // specific object color?
328  if (pObj) pObj->PrepareDrawing();
329 
330  switch(Type)
331  {
333  // Def has no graphics
334  break;
336  fctPicture.Set(GetBitmap(iColor),fctPicRect.x,fctPicRect.y,fctPicRect.Wdt,fctPicRect.Hgt);
337  fctPicture.DrawTUnscaled(cgo,true,iPhaseX,iPhaseY,trans);
338  break;
340  // TODO: Allow rendering of a mesh directly, without instance (to render pose; no animation)
341  std::unique_ptr<StdMeshInstance> dummy;
342  StdMeshInstance* instance;
343 
344  C4Value value;
345  if (pObj)
346  {
347  instance = pObj->pMeshInstance;
348  pObj->GetProperty(P_PictureTransformation, &value);
349  }
350  else
351  {
352  dummy = std::make_unique<StdMeshInstance>(*Mesh, 1.0f);
353  instance = dummy.get();
355  }
356 
357  StdMeshMatrix matrix;
358  if (C4ValueToMatrix(value, &matrix))
359  pDraw->SetMeshTransform(&matrix);
360 
361  pDraw->SetPerspective(true);
362  pDraw->RenderMesh(*instance, cgo.Surface, cgo.X,cgo.Y, cgo.Wdt, cgo.Hgt, pObj ? pObj->Color : iColor, trans);
363  pDraw->SetPerspective(false);
364  pDraw->SetMeshTransform(nullptr);
365 
366  break;
367  }
368 
369  if (pObj) pObj->FinishedDrawing();
370 
371  // draw overlays
372  if (pObj && pObj->pGfxOverlay)
373  for (C4GraphicsOverlay *pGfxOvrl = pObj->pGfxOverlay; pGfxOvrl; pGfxOvrl = pGfxOvrl->GetNext())
374  if (pGfxOvrl->IsPicture())
375  pGfxOvrl->DrawPicture(cgo, pObj, trans);
376 }
377 
378 void C4DefGraphics::DrawClr(C4Facet &cgo, bool fAspect, DWORD dwClr)
379 {
380  if (Type != TYPE_Bitmap) return; // TODO
381  // create facet and draw it
382  C4Surface *pSfc = Bmp.BitmapClr ? Bmp.BitmapClr : Bmp.Bitmap; if (!pSfc) return;
383  C4Facet fct(pSfc, 0,0,pSfc->Wdt, pSfc->Hgt);
384  fct.DrawClr(cgo, fAspect, dwClr);
385 }
386 
388 {
389  bool deserializing = pComp->isDeserializer();
390  // nothing?
391  if (!deserializing && !pDefGraphics) return;
392  // definition
393  C4ID id; if (!deserializing) id = pDefGraphics->pDef->id;
394  pComp->Value(id);
395  // go over two separators ("::"). Expect them if an id was found.
397  pComp->excCorrupt(R"(DefGraphics: expected "::")");
398  // compile name
399  StdStrBuf Name; if (!deserializing) Name = pDefGraphics->GetName();
401  // reading: search def-graphics
402  if (deserializing)
403  {
404  // search definition, throw expection if not found
405  C4Def *pDef = ::Definitions.ID2Def(id);
406  // search def-graphics
407  if (!pDef || !( pDefGraphics = pDef->Graphics.Get(Name.getData()) ))
408  pComp->excCorrupt(R"(DefGraphics: could not find graphics "%s" in %s(%s)!)", Name.getData(), id.ToString(), pDef ? pDef->GetName() : "def not found");
409  }
410 }
411 
413 {
414  // store name
415  SCopy(szName, Name, C4MaxName);
416 }
417 
418 // ---------------------------------------------------------------------------
419 // C4DefGraphicsPtrBackup: Functionality to reload def graphics at runtime
420 
422  pMeshUpdate(nullptr)
423 {
424  // assign graphics + def
425  pGraphicsPtr = pSourceGraphics;
426  pDef = pSourceGraphics->pDef;
427  // assign name
428  const char *szName = pGraphicsPtr->GetName();
429  if (szName) SCopy(szName, Name, C4MaxName); else *Name=0;
430 
431  // assign mesh update
432  if(pSourceGraphics->Type == C4DefGraphics::TYPE_Mesh)
433  pMeshUpdate = new StdMeshUpdate(*pSourceGraphics->Mesh);
434 }
435 
437 {
438  // graphics ptr still assigned? then remove dead graphics pointers from objects
440  delete pMeshUpdate;
441 }
442 
444 {
445  // Update all attached meshes that were using this mesh
446  UpdateAttachedMeshes();
447 
448  // only if graphics are assigned
449  if (pGraphicsPtr)
450  {
451  // check all objects
452  for (C4Object *pObj : Objects)
453  {
454  if (pObj && pObj->Status)
455  {
456  if (pObj->pGraphics == pGraphicsPtr)
457  {
458  // same graphics found. Update mesh graphics if any.
459  if(pMeshUpdate)
460  {
461  assert(pObj->pMeshInstance != nullptr); // object had mesh graphics, so mesh instance should be present
462  assert(&pObj->pMeshInstance->GetMesh() == &pMeshUpdate->GetOldMesh()); // mesh instance of correct type even
463 
464  // Get new mesh from reloaded graphics
465  C4DefGraphics *pGrp = pDef->Graphics.Get(Name);
466  if(pGrp && pGrp->Type == C4DefGraphics::TYPE_Mesh)
467  pMeshUpdate->Update(pObj->pMeshInstance, *pGrp->Mesh);
468  }
469 
470  // try to set new graphics
471  if (!pObj->SetGraphics(Name, pDef))
472  if (!pObj->SetGraphics(Name, pObj->Def))
473  {
474  // shouldn't happen
475  pObj->AssignRemoval(); pObj->pGraphics=nullptr;
476  }
477  }
478 
479  // remove any overlay graphics
480  for (;;)
481  {
482  C4GraphicsOverlay *pGfxOverlay;
483  for (pGfxOverlay = pObj->pGfxOverlay; pGfxOverlay; pGfxOverlay = pGfxOverlay->GetNext())
484  if (pGfxOverlay->GetGfx() == pGraphicsPtr)
485  {
486  // then remove this overlay and redo the loop, because iterator has become invalid
487  pObj->RemoveGraphicsOverlay(pGfxOverlay->GetID());
488  break;
489  }
490  // looped through w/o removal?
491  if (!pGfxOverlay) break;
492  }
493  // update menu frame decorations - may do multiple updates to the same deco if multiple menus share it...
494  C4GUI::FrameDecoration *pDeco;
495  if (pDef && pObj->Menu && (pDeco = pObj->Menu->GetFrameDecoration()))
496  if (pDeco->idSourceDef == pDef->id)
497  if (!pDeco->UpdateGfx())
498  pObj->Menu->SetFrameDeco(nullptr);
499  }
500  }
501  // done; reset field to indicate finished update
502  pGraphicsPtr = nullptr;
503  }
504 }
505 
507 {
508  // Remove all attached meshes that were using this mesh
509  UpdateAttachedMeshes();
510 
511  // only if graphics are assigned
512  if (pGraphicsPtr)
513  {
514  // check all objects
515  for (C4Object *pObj : Objects)
516  if (pObj && pObj->Status)
517  {
518  if (pObj->pGraphics == pGraphicsPtr)
519  {
520  // same graphics found. If these are mesh graphics then remove
521  // the object because the StdMesh has already been unloaded.
522  if(pObj->pMeshInstance)
523  {
524  assert(&pObj->pMeshInstance->GetMesh() == &pMeshUpdate->GetOldMesh());
525 
526  pObj->AssignRemoval();
527  delete pObj->pMeshInstance;
528  pObj->pMeshInstance = nullptr;
529  pObj->pGraphics = nullptr;
530  }
531  // sprite graphics; reset them
532  else if (!pObj->SetGraphics()) { pObj->AssignRemoval(); pObj->pGraphics=nullptr; }
533  }
534  // remove any overlay graphics
535  for (;;)
536  {
537  C4GraphicsOverlay *pGfxOverlay;
538  for (pGfxOverlay = pObj->pGfxOverlay; pGfxOverlay; pGfxOverlay = pGfxOverlay->GetNext())
539  if (pGfxOverlay->GetGfx() == pGraphicsPtr)
540  {
541  // then remove this overlay and redo the loop, because iterator has become invalid
542  pObj->RemoveGraphicsOverlay(pGfxOverlay->GetID());
543  break;
544  }
545  // looped through w/o removal?
546  if (!pGfxOverlay) break;
547  }
548  // remove menu frame decorations
549  C4GUI::FrameDecoration *pDeco;
550  if (pDef && pObj->Menu && (pDeco = pObj->Menu->GetFrameDecoration()))
551  if (pDeco->idSourceDef == pDef->id)
552  pObj->Menu->SetFrameDeco(nullptr);
553  }
554  // done; reset field to indicate finished update
555  pGraphicsPtr = nullptr;
556  }
557 }
558 
559 void C4DefGraphicsPtrBackupEntry::UpdateAttachedMeshes()
560 {
561  for (C4Object *pObj : Objects)
562  {
563  if (pObj && pObj->Status)
564  {
565  if(pObj->pMeshInstance)
566  UpdateAttachedMesh(pObj->pMeshInstance);
567  for (C4GraphicsOverlay* pGfxOverlay = pObj->pGfxOverlay; pGfxOverlay; pGfxOverlay = pGfxOverlay->GetNext())
568  if(pGfxOverlay->pMeshInstance)
569  UpdateAttachedMesh(pGfxOverlay->pMeshInstance);
570  }
571  }
572 }
573 
574 void C4DefGraphicsPtrBackupEntry::UpdateAttachedMesh(StdMeshInstance* instance)
575 {
576  // Update if instance is an owned attached mesh
577  if(pMeshUpdate &&
578  &instance->GetMesh() == &pMeshUpdate->GetOldMesh() &&
579  instance->GetAttachParent() &&
580  instance->GetAttachParent()->OwnChild)
581  {
582  C4DefGraphics *pGrp = pDef->Graphics.Get(Name); // null for failed def. reload
583  if(pGrp && pGrp->Type == C4DefGraphics::TYPE_Mesh)
584  {
585  pMeshUpdate->Update(instance, *pGrp->Mesh); // might detach from parent
586  }
587  else
588  {
589  instance->GetAttachParent()->Parent->DetachMesh(instance->GetAttachParent()->Number);
590  }
591  }
592  // Non-attached meshes and unowned attached meshes are updated in
593  // AssignUpdate or AssignRemoval, respectively, since they are
594  // contained in the object list.
595 
596  // Copy the attached mesh list before recursion because the recursive
597  // call might detach meshes, altering the list and invalidating
598  // iterators.
599  std::vector<StdMeshInstance::AttachedMesh*> attached_meshes;
600  for(StdMeshInstance::AttachedMeshIter iter = instance->AttachedMeshesBegin(); iter != instance->AttachedMeshesEnd(); ++iter)
601  attached_meshes.push_back(*iter);
602 
603  for(auto & attached_mesh : attached_meshes)
604  // TODO: Check that this mesh is still attached?
605  UpdateAttachedMesh(attached_mesh->Child);
606 }
607 
609  MeshMaterialUpdate(::MeshMaterialManager),
610  MeshAnimationUpdate(::Definitions.GetSkeletonLoader())
611 {
612 }
613 
615 {
616  if(!fApplied) AssignRemoval();
617 
618  for(auto & Entry : Entries)
619  delete Entry;
620 }
621 
623 {
624  for(C4DefGraphics* pCur = pGfx; pCur != nullptr; pCur = pCur->pNext)
625  Entries.push_back(new C4DefGraphicsPtrBackupEntry(pCur));
626 
627  // Remove all mesh materials that were loaded from this definition
628  C4Def* pDef = pGfx->pDef;
630  {
631  StdStrBuf Filename;
632  Filename.Copy(pDef->Filename);
633  Filename.Append("/"); Filename.Append(GetFilename(iter->FileName.getData()));
634 
635  if(Filename == iter->FileName)
636  iter = ::MeshMaterialManager.Remove(iter, &MeshMaterialUpdate);
637  else
638  ++iter;
639  }
640 }
641 
643 {
644  MeshMaterialUpdate.Cancel();
645 
646  // Remove gfx
647  for(auto & Entry : Entries)
648  Entry->AssignRemoval();
649 
650  fApplied = true;
651 }
652 
654 {
655  // Update mesh materials for all meshes
656  for(auto & iter : Definitions.table)
657  if(iter.second->Graphics.Type == C4DefGraphics::TYPE_Mesh)
658  MeshMaterialUpdate.Update(iter.second->Graphics.Mesh);
659 
660  // Then, update mesh references in instances, attach bones by name, and update sprite gfx
661  for(auto & Entry : Entries)
662  Entry->AssignUpdate();
663 
664  // Update mesh materials and animations for all mesh instances.
665  for (C4Object *pObj : Objects)
666  {
667  if (pObj && pObj->Status)
668  {
669  if(pObj->pMeshInstance)
670  UpdateMesh(pObj->pMeshInstance);
671  for (C4GraphicsOverlay* pGfxOverlay = pObj->pGfxOverlay; pGfxOverlay; pGfxOverlay = pGfxOverlay->GetNext())
672  if(pGfxOverlay->pMeshInstance)
673  UpdateMesh(pGfxOverlay->pMeshInstance);
674  }
675  }
676 
677  fApplied = true;
678 }
679 
680 void C4DefGraphicsPtrBackup::UpdateMesh(StdMeshInstance* instance)
681 {
682  MeshMaterialUpdate.Update(instance);
683  MeshAnimationUpdate.Update(instance);
684 
685  // Recursive for attached meshes not in object list
686  for (StdMeshInstance::AttachedMeshIter iter = instance->AttachedMeshesBegin(); iter != instance->AttachedMeshesEnd(); ++iter)
687  if ((*iter)->OwnChild)
688  UpdateMesh((*iter)->Child);
689 }
690 
691 // ---------------------------------------------------------------------------
692 // C4GraphicsOverlay: graphics overlay used to attach additional graphics to objects
693 
695 {
696  // Free mesh instance
697  delete pMeshInstance; pMeshInstance = nullptr;
698  // free any additional overlays
699  C4GraphicsOverlay *pNextOther = pNext, *pOther;
700  while ((pOther = pNextOther))
701  {
702  pNextOther = pOther->pNext;
703  pOther->pNext = nullptr;
704  delete pOther;
705  }
706 }
707 
709 {
710  // special: Nothing to update for object and pSourceGfx may be nullptr
711  // If there will ever be something to init here, UpdateFacet() will also need to be called when objects have been loaded
712  if (eMode == MODE_Object) return;
713  // otherwise, source graphics must be specified
714  if (!pSourceGfx) return;
715  C4Def *pDef = pSourceGfx->pDef;
716  assert(pDef);
717  fZoomToShape = false;
718  // Clear old mesh instance, if any
719  delete pMeshInstance; pMeshInstance = nullptr;
720  // update by mode
721  switch (eMode)
722  {
723  case MODE_None:
724  break;
725 
726  case MODE_Base: // def base graphics
728  fctBlit.Set(pSourceGfx->GetBitmap(), 0, 0, pDef->Shape.Wdt, pDef->Shape.Hgt, pDef->Shape.x+pDef->Shape.Wdt/2, pDef->Shape.y+pDef->Shape.Hgt/2);
730  pMeshInstance = new StdMeshInstance(*pSourceGfx->Mesh, 1.0f);
731  break;
732 
733  case MODE_Action: // graphics of specified action
734  {
735  // Clear old facet
736  fctBlit.Default();
737 
738  // Ensure there is actually an action set
739  if (!Action[0])
740  return;
741 
742  C4Value v;
743  pDef->GetProperty(P_ActMap, &v);
744  C4PropList *actmap = v.getPropList();
745  if (!actmap)
746  return;
747 
748  actmap->GetPropertyByS(::Strings.RegString(Action), &v);
749  C4PropList *action = v.getPropList();
750  if (!action)
751  return;
752 
754  {
756  action->GetPropertyInt(P_X), action->GetPropertyInt(P_Y),
757  action->GetPropertyInt(P_Wdt), action->GetPropertyInt(P_Hgt));
758  // FIXME: fctBlit.TargetX has to be set here
759  }
761  {
762  C4String* AnimationName = action->GetPropertyStr(P_Animation);
763  if (!AnimationName) return;
764 
765  pMeshInstance = new StdMeshInstance(*pSourceGfx->Mesh, 1.0f);
766  const StdMeshAnimation* Animation = pSourceGfx->Mesh->GetSkeleton().GetAnimationByName(AnimationName->GetData());
767  if (!Animation) return;
768 
769  pMeshInstance->PlayAnimation(*Animation, 0, nullptr, new C4ValueProviderRef<int32_t>(iPhase, ftofix(Animation->Length / action->GetPropertyInt(P_Length))), new C4ValueProviderConst(itofix(1)), true);
770  }
771 
772  break;
773  }
774  case MODE_ObjectPicture: // ingame picture of object
775  // calculated at runtime
776  break;
777 
778  case MODE_IngamePicture:
779  case MODE_Picture: // def picture
780  fZoomToShape = true;
781  // drawn at runtime
782  break;
783 
784  case MODE_ExtraGraphics: // like ColorByOwner-sfc
785  // calculated at runtime
786  break;
787 
788  case MODE_Rank:
789  // drawn at runtime
790  break;
791 
792  case MODE_Object:
793  // TODO
794  break;
795  }
796 }
797 
798 void C4GraphicsOverlay::Set(Mode aMode, C4DefGraphics *pGfx, const char *szAction, DWORD dwBMode, C4Object *pOvrlObj)
799 {
800  // set values
801  eMode = aMode;
802  pSourceGfx = pGfx;
803  if (szAction) SCopy(szAction, Action, C4MaxName); else *Action=0;
804  dwBlitMode = dwBMode;
805  OverlayObj = pOvrlObj;
806  // (keep transform)
807  // reset phase
808  iPhase = 0;
809  // update used facet
810  UpdateFacet();
811 }
812 
813 bool C4GraphicsOverlay::IsValid(const C4Object *pForObj) const
814 {
815  assert(pForObj);
817  {
818  if (!OverlayObj || !OverlayObj->Status) return false;
819  return (eMode == MODE_Rank) || !OverlayObj->HasGraphicsOverlayRecursion(pForObj);
820  }
821  else if (eMode == MODE_ExtraGraphics)
822  {
823  return !!pSourceGfx;
824  }
825  else if (pSourceGfx)
826  {
828  return true;
830  return !!fctBlit.Surface;
832  return !!pMeshInstance;
833  return false;
834  }
835  else
836  {
837  return false;
838  }
839 }
840 
842 {
843  // read ID
844  pComp->Value(iID); pComp->Separator();
845  // read def-graphics
847  pComp->Separator();
848  // read mode
849  pComp->Value(mkIntAdapt(eMode)); pComp->Separator();
850  // read action (identifier)
851  pComp->Value(mkStringAdaptMIE(Action)); pComp->Separator();
852  // read blit mode
853  pComp->Value(dwBlitMode); pComp->Separator();
854  // read phase
855  pComp->Value(iPhase); pComp->Separator();
856  // read transform
858  pComp->Value(Transform);
860  // read color-modulation
861  if (pComp->Separator())
863  else
864  // default
865  if (pComp->isDeserializer()) dwClrModulation = 0xffffff;
866  // read overlay target object
867  if (pComp->Separator())
868  pComp->Value(OverlayObj);
869  else
870  // default
871  if (pComp->isDeserializer()) OverlayObj = nullptr;
872  // update used facet according to read data
873  if (pComp->isDeserializer()) UpdateFacet();
874 }
875 
877 {
879 }
880 
881 void C4GraphicsOverlay::Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByPlayer)
882 {
883  assert(!IsPicture());
884  // note: Also called with pForObj==nullptr for editor placement preview
885  // get target pos
886  float offX, offY;
887  float newzoom;
888  if (pForObj)
889  {
890  pForObj->GetDrawPosition(cgo, offX, offY, newzoom);
891  }
892  else
893  {
894  // offset in editor mode preview
895  offX = cgo.X;
896  offY = cgo.Y;
897  newzoom = cgo.Zoom;
898  }
899  ZoomDataStackItem zdsi(newzoom);
900 
901  // special blit mode
903  {
904  assert(pForObj);
905  (OverlayObj ? static_cast<C4Object*>(OverlayObj) : pForObj)->PrepareDrawing();
906  }
907  else
908  {
911 
912  if (pMeshInstance)
914  }
915  if (eMode == MODE_Rank)
916  {
917  assert(pForObj);
918  C4TargetFacet ccgo;
919  ccgo.Set(cgo.Surface, offX+pForObj->Shape.x,offY+pForObj->Shape.y,pForObj->Shape.Wdt,pForObj->Shape.Hgt, cgo.TargetX, cgo.TargetY);
920  DrawRankSymbol(ccgo, OverlayObj);
921  }
922  // drawing specific object?
923  else if (OverlayObj)
924  {
925  assert(pForObj);
926  // TODO: Shouldn't have called PrepareDrawing/set ClrModulation here, since
927  // OverlayObj drawing will do it on its own.
928  if (eMode == MODE_ObjectPicture)
929  {
930  C4Facet fctTarget;
931  fctTarget.Set(cgo.Surface, offX+pForObj->Shape.x, offY+pForObj->Shape.y, pForObj->Shape.Wdt, pForObj->Shape.Hgt);
932 
933  OverlayObj->DrawPicture(fctTarget, false, &C4DrawTransform(Transform, fctTarget.X+float(fctTarget.Wdt)/2, fctTarget.Y+float(fctTarget.Hgt)/2));
934  }
935  else
936  {
937  // Draw specified object at target pos of this object; offset by transform.
938  OverlayObj->Draw(cgo, iByPlayer, C4Object::ODM_Overlay, offX + Transform.GetXOffset(), offY + Transform.GetYOffset());
940  }
941  }
942  else if (eMode == MODE_ExtraGraphics)
943  {
944  assert(pForObj);
945  // draw self with specified gfx
946  if (pSourceGfx)
947  {
948  C4DefGraphics *pPrevGfx = pForObj->GetGraphics();
949  C4DrawTransform *pPrevTrf = pForObj->pDrawTransform;
950  C4DrawTransform trf;
951  if (pPrevTrf)
952  {
953  trf = *pPrevTrf;
954  trf *= Transform;
955  }
956  else
957  {
958  trf = Transform;
959  }
960  pForObj->SetGraphics(pSourceGfx, true);
961  pForObj->pDrawTransform = &trf;
962  pForObj->Draw(cgo, iByPlayer, C4Object::ODM_BaseOnly);
963  pForObj->DrawTopFace(cgo, iByPlayer, C4Object::ODM_BaseOnly);
964  pForObj->SetGraphics(pPrevGfx, true);
965  pForObj->pDrawTransform = pPrevTrf;
966  }
967  }
968  else if(eMode == MODE_Picture || eMode == MODE_IngamePicture)
969  {
970  assert(pForObj);
971  float twdt, thgt;
972  if (fZoomToShape)
973  {
974  twdt = pForObj->Shape.Wdt;
975  thgt = pForObj->Shape.Hgt;
976  }
977  else
978  {
979  twdt = pSourceGfx->pDef->Shape.Wdt;
980  thgt = pSourceGfx->pDef->Shape.Hgt;
981  }
982 
983  C4TargetFacet ccgo;
984  ccgo.Set(cgo.Surface, offX-twdt/2, offY-thgt/2, twdt, thgt, cgo.TargetX, cgo.TargetY);
985  C4DrawTransform trf(Transform, offX, offY);
986 
987  // Don't set pForObj because we don't draw the picture of pForObj, but the picture of another definition on top of pForObj:
988  pSourceGfx->Draw(ccgo, pForObj->Color, nullptr, iPhase, 0, &trf);
989  }
990  else
991  {
992  // no object specified: Draw from fctBlit
993  // update by object color
994  if (fctBlit.Surface && pForObj) fctBlit.Surface->SetClr(pForObj->Color);
995 
996  if (!pMeshInstance)
997  {
998  // draw there
999  C4DrawTransform trf(Transform, offX, offY);
1000  if (fZoomToShape)
1001  {
1002  assert(pForObj);
1003  float fZoom = std::min(pForObj->Shape.Wdt / std::max(fctBlit.Wdt, 1.0f), pForObj->Shape.Hgt / std::max(fctBlit.Hgt, 1.0f));
1004  trf.ScaleAt(fZoom, fZoom, offX, offY);
1005  }
1006 
1007  fctBlit.DrawT(cgo.Surface, offX - fctBlit.Wdt/2 + fctBlit.TargetX, offY - fctBlit.Hgt/2 + fctBlit.TargetY, iPhase, 0, &trf);
1008  }
1009  else
1010  {
1011  C4Def *pDef = pSourceGfx->pDef;
1012 
1013  // draw there
1014  C4DrawTransform trf(Transform, offX, offY);
1015  if (fZoomToShape)
1016  {
1017  assert(pForObj);
1018  float fZoom = std::min((float)pForObj->Shape.Wdt / std::max(pDef->Shape.Wdt, 1), (float)pForObj->Shape.Hgt / std::max(pDef->Shape.Hgt, 1));
1019  trf.ScaleAt(fZoom, fZoom, offX, offY);
1020  }
1021 
1022  C4Value value;
1023  pDef->GetProperty(P_MeshTransformation, &value);
1024  StdMeshMatrix matrix;
1025  if (C4ValueToMatrix(value, &matrix))
1026  pDraw->SetMeshTransform(&matrix);
1027 
1028  pDraw->RenderMesh(*pMeshInstance, cgo.Surface, offX - pDef->Shape.Wdt/2.0, offY - pDef->Shape.Hgt/2.0, pDef->Shape.Wdt, pDef->Shape.Hgt, pForObj ? pForObj->Color : 0xff, &trf);
1029  pDraw->SetMeshTransform(nullptr);
1030  }
1031  }
1032 
1033  // cleanup
1035  (OverlayObj ? static_cast<C4Object*>(OverlayObj) : pForObj)->FinishedDrawing();
1036  else
1037  {
1038  pDraw->ResetBlitMode();
1040  }
1041 }
1042 
1044 {
1045  // Determine source gfx for rank
1046  if (!rank_obj || !rank_obj->Info) return;
1047  C4RankSystem *pRankSys = &::DefaultRanks;
1048  C4Facet *pRankRes=&::GraphicsResource.fctRank;
1049  int iRankCnt=::GraphicsResource.iNumRanks;
1050  C4Def *rank_def=rank_obj->Def;
1051  if (rank_def->pRankSymbols)
1052  {
1053  pRankRes=rank_def->pRankSymbols;
1054  iRankCnt=rank_def->iNumRankSymbols;
1055  }
1056  if (rank_def->pRankNames)
1057  {
1058  pRankSys = rank_def->pRankNames;
1059  iRankCnt = rank_def->pRankNames->GetBaseRankNum();
1060  }
1061  pRankSys->DrawRankSymbol(nullptr, rank_obj->Info->Rank, pRankRes, iRankCnt, false, 0, &cgo);
1062 }
1063 
1065 {
1066  assert(IsPicture());
1067 
1068  // special blit mode
1070  {
1071  if (pForObj) pForObj->PrepareDrawing();
1072  }
1073  else
1074  {
1077 
1078  if (pMeshInstance)
1080  }
1081 
1082  // the picture we are rendering is the one with trans applied, and the overlay transformation
1083  // is applied to the picture we are rendering, so apply it afterwards. Note that
1084  // C4BltTransform::operator*= does this = other * this.
1085  C4DrawTransform trf(Transform, cgo.X + cgo.Wdt/2.0f, cgo.Y + cgo.Hgt/2.0f);
1086  if(trans) trf *= *trans;
1087 
1088  // Don't set pForObj because we don't draw the picture of pForObj, but the picture of another definition on top of pForObj:
1089  pSourceGfx->Draw(cgo, pForObj->Color, nullptr, iPhase, 0, &trf);
1090 
1091  // cleanup
1093  {
1094  if (pForObj) pForObj->FinishedDrawing();
1095  }
1096  else
1097  {
1098  pDraw->ResetBlitMode();
1100  }
1101 }
1102 
1104 {
1105  // compare relevant fields
1106  // ignoring phase, because different animation state may be concatenated in graphics display
1107  return (eMode == rCmp.eMode)
1108  && (pSourceGfx == rCmp.pSourceGfx)
1109  && SEqual(Action, rCmp.Action)
1110  && (dwBlitMode == rCmp.dwBlitMode)
1111  && (dwClrModulation == rCmp.dwClrModulation)
1112  && (Transform == rCmp.Transform)
1113  && (OverlayObj == rCmp.OverlayObj);
1114 }
1115 
1117 {
1118  bool fNaming = pComp->hasNaming();
1119  if (pComp->isDeserializer())
1120  {
1121  // clear list
1122  delete [] pOverlay; pOverlay = nullptr;
1123  // read the whole list
1124  C4GraphicsOverlay *pLast = nullptr;
1125  bool fContinue;
1126  do
1127  {
1128  C4GraphicsOverlay *pNext = new C4GraphicsOverlay();
1129  try
1130  {
1131  // read an overlay
1132  pComp->Value(*pNext);
1133  }
1135  {
1136  delete e;
1137  // delete unused overlay
1138  delete pNext; pNext = nullptr;
1139  // clear up
1140  if (!pLast) pOverlay = nullptr;
1141  // done
1142  return;
1143  }
1144  // link it
1145  if (pLast)
1146  pLast->SetNext(pNext);
1147  else
1148  pOverlay = pNext;
1149  // step
1150  pLast = pNext;
1151  // continue?
1152  if (fNaming)
1153  fContinue = pComp->Separator(StdCompiler::SEP_SEP2) || pComp->Separator(StdCompiler::SEP_SEP);
1154  else
1155  pComp->Value(fContinue);
1156  }
1157  while (fContinue);
1158  }
1159  else
1160  {
1161  // write everything
1162  bool fContinue = true;
1163  for (C4GraphicsOverlay *pPos = pOverlay; pPos; pPos = pPos->GetNext())
1164  {
1165  // separate
1166  if (pPos != pOverlay)
1167  {
1168  if (fNaming)
1170  else
1171  pComp->Value(fContinue);
1172  }
1173  // write
1174  pComp->Value(*pPos);
1175  }
1176  // terminate
1177  if (!fNaming)
1178  {
1179  fContinue = false;
1180  pComp->Value(fContinue);
1181  }
1182  }
1183 }
1184 
1186 {
1187  if (Type != TYPE_Bitmap)
1188  return nullptr;
1189  if (Bmp.BitmapClr)
1190  {
1191  Bmp.BitmapClr->SetClr(dwClr);
1192  return Bmp.BitmapClr;
1193  }
1194  else
1195  return Bmp.Bitmap;
1196 }
#define C4CFN_DefMesh
Definition: C4Components.h:92
#define C4CFN_DefMeshXml
Definition: C4Components.h:93
#define C4CFN_ClrByOwnerEx
Definition: C4Components.h:103
#define C4CFN_ClrByOwner
Definition: C4Components.h:100
#define C4CFN_DefGraphicsExMeshXml
Definition: C4Components.h:97
#define C4CFN_DefGraphicsExMesh
Definition: C4Components.h:96
#define C4CFN_NormalMapEx
Definition: C4Components.h:104
#define C4CFN_DefGraphics
Definition: C4Components.h:99
#define C4CFN_DefSkeletonXml
Definition: C4Components.h:95
#define C4CFN_DefGraphicsEx
Definition: C4Components.h:102
#define C4CFN_DefGraphicsScaled
Definition: C4Components.h:106
#define C4CFN_NormalMap
Definition: C4Components.h:101
#define C4CFN_DefSkeleton
Definition: C4Components.h:94
C4Draw * pDraw
Definition: C4Draw.cpp:42
bool C4ValueToMatrix(C4Value &value, StdMeshMatrix *matrix)
C4GameObjects Objects
Definition: C4Globals.cpp:48
C4DefList Definitions
Definition: C4Globals.cpp:49
C4StringTable Strings
Definition: C4Globals.cpp:42
C4GraphicsResource GraphicsResource
const unsigned int C4MaxName
bool DebugLogF(const char *strMessage ...)
Definition: C4Log.cpp:290
C4RankSystem DefaultRanks
C4Fixed itofix(int32_t x)
Definition: C4Real.h:261
C4Fixed ftofix(float x)
Definition: C4Real.h:258
@ P_Wdt
@ P_Y
@ P_Length
@ P_Hgt
@ P_X
@ P_MeshTransformation
@ P_Animation
@ P_PictureTransformation
@ P_ActMap
#define C4GFXBLIT_PARENT
Definition: C4Surface.h:36
const int C4SF_MipMap
Definition: C4Surface.h:50
#define _MAX_PATH
#define _MAX_PATH_LEN
uint32_t DWORD
int SCharPos(char cTarget, const char *szInStr, int iIndex)
Definition: Standard.cpp:239
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen)
Definition: Standard.cpp:213
int SCharLastPos(char cTarget, const char *szInStr)
Definition: Standard.cpp:253
void SAppend(const char *szSource, char *szTarget, int iMaxL)
Definition: Standard.cpp:263
bool SEqual(const char *szStr1, const char *szStr2)
Definition: Standard.h:93
StdDefaultAdapt< T, D > mkDefaultAdapt(T &&rValue, const D &rDefault)
Definition: StdAdaptors.h:64
StdParameterAdapt< T, P > mkParAdapt(T &&rObj, P &&rPar)
Definition: StdAdaptors.h:490
StdIntAdapt< T > mkIntAdapt(T &rValue)
Definition: StdAdaptors.h:255
StdStringAdapt mkStringAdaptMIE(char(&szString)[size])
Definition: StdAdaptors.h:192
char * GetExtension(char *szFilename)
Definition: StdFile.cpp:118
bool WildcardMatch(const char *szWildcard, const char *szString)
Definition: StdFile.cpp:396
char * GetFilename(char *szPath)
Definition: StdFile.cpp:42
void EnforceExtension(char *szFilename, const char *szExtension)
Definition: StdFile.cpp:286
void RemoveExtension(char *szFilename)
Definition: StdFile.cpp:303
StdMeshMatManager MeshMaterialManager
char Name[C4MaxName+1]
Definition: C4DefGraphics.h:94
C4AdditionalDefGraphics(C4Def *pOwnDef, const char *szName)
void ScaleAt(float sx, float sy, float tx, float ty)
C4DefGraphics *& pDefGraphics
void CompileFunc(StdCompiler *pComp)
C4DefGraphics * Get(const char *szGrpName)
GraphicsType Type
Definition: C4DefGraphics.h:48
virtual const char * GetName()
Definition: C4DefGraphics.h:79
bool Load(C4Group &hGroup, StdMeshSkeletonLoader &loader, bool fColorByOwner)
bool fColorBitmapAutoCreated
Definition: C4DefGraphics.h:59
C4Surface * GetBitmap(DWORD dwClr=0)
void DrawClr(C4Facet &cgo, bool fAspect=true, DWORD dwClr=0)
bool LoadBitmap(C4Group &hGroup, const char *szFilenamePNG, const char *szOverlayPNG, const char *szNormal, bool fColorByOwner)
void Draw(C4Facet &cgo, DWORD iColor, C4Object *pObj, int32_t iPhaseX, int32_t iPhaseY, C4DrawTransform *trans)
C4DefGraphics(C4Def *pOwnDef=nullptr)
Definition: stub-handle.cpp:73
C4DefGraphics * GetLast()
C4AdditionalDefGraphics * pNext
Definition: C4DefGraphics.h:37
bool LoadMesh(C4Group &hGroup, const char *szFilename, StdMeshSkeletonLoader &loader)
bool LoadSkeleton(C4Group &hGroup, const char *szFilename, StdMeshSkeletonLoader &loader)
StdMeshUpdate * pMeshUpdate
void AssignRemoval()
~C4DefGraphicsPtrBackupEntry()
C4DefGraphicsPtrBackupEntry(C4DefGraphics *pSourceGraphics)
C4Def * pDef
C4DefGraphics * pGraphicsPtr
void AssignUpdate()
char Name[C4MaxName+1]
void Add(C4DefGraphics *pGraphics)
Definition: C4Def.h:99
char Filename[_MAX_FNAME_LEN]
Definition: C4Def.h:176
C4DefGraphics Graphics
Definition: C4Def.h:191
int32_t iNumRankSymbols
Definition: C4Def.h:190
C4FacetSurface * pRankSymbols
Definition: C4Def.h:189
C4ID id
Definition: C4Def.h:101
C4Rect PictureRect
Definition: C4Def.h:107
C4Shape Shape
Definition: C4Def.h:104
C4RankSystem * pRankNames
Definition: C4Def.h:188
Table table
Definition: C4DefList.h:33
C4Def * ID2Def(C4ID id)
void SetBlitMode(DWORD dwBlitMode)
Definition: C4Draw.h:191
bool RenderMesh(StdMeshInstance &instance, C4Surface *sfcTarget, float tx, float ty, float twdt, float thgt, DWORD dwPlayerColor, C4BltTransform *pTransform)
Definition: C4Draw.cpp:397
void DeactivateBlitModulation()
Definition: C4Draw.h:189
void SetMeshTransform(const StdMeshMatrix *Transform)
Definition: C4Draw.h:200
void ResetBlitMode()
Definition: C4Draw.h:192
void ActivateBlitModulation(DWORD dwWithClr)
Definition: C4Draw.h:188
void SetPerspective(bool fSet)
Definition: C4Draw.h:201
int32_t GetXOffset() const
Definition: C4Facet.h:109
int32_t GetYOffset() const
Definition: C4Facet.h:110
void Set(C4Surface &rSfc)
Definition: C4Facet.cpp:459
void DrawT(C4Surface *sfcTarget, float iX, float iY, int32_t iPhaseX, int32_t iPhaseY, C4DrawTransform *pTransform)
Definition: C4Facet.cpp:76
C4Surface * Surface
Definition: C4Facet.h:117
float Hgt
Definition: C4Facet.h:118
void DrawTUnscaled(C4Surface *sfcTarget, float iX, float iY, int32_t iPhaseX, int32_t iPhaseY, C4DrawTransform *pTransform)
Definition: C4Facet.cpp:115
void DrawClr(C4Facet &cgo, bool fAspect=true, DWORD dwClr=0)
Definition: C4Facet.cpp:213
float Wdt
Definition: C4Facet.h:118
float Y
Definition: C4Facet.h:118
float X
Definition: C4Facet.h:118
void SetNext(C4GraphicsOverlay *paNext)
bool IsValid(const C4Object *pForObj) const
void DrawPicture(C4Facet &cgo, C4Object *pForObj, C4DrawTransform *trans)
void DrawRankSymbol(C4Facet &cgo, C4Object *rank_obj)
int32_t GetID() const
C4ObjectPtr OverlayObj
C4GraphicsOverlay * pNext
C4GraphicsOverlay * GetNext() const
C4DrawTransform Transform
char Action[C4MaxName+1]
C4TargetFacet fctBlit
void Set(Mode aMode, C4DefGraphics *pGfx, const char *szAction, DWORD dwBMode, C4Object *pOvrlObj)
StdMeshInstance * pMeshInstance
void Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByPlayer)
C4DefGraphics * pSourceGfx
bool operator==(const C4GraphicsOverlay &rCmp) const
C4DefGraphics * GetGfx() const
void CompileFunc(StdCompiler *pComp)
uint32_t dwClrModulation
void CompileFunc(StdCompiler *pComp)
C4GraphicsOverlay *& pOverlay
bool FindNextEntry(const char *wildcard, StdStrBuf *filename=nullptr, size_t *size=nullptr, bool start_at_filename=false)
Definition: C4Group.cpp:2217
const char * GetName() const
Definition: C4Group.cpp:2309
StdStrBuf GetFullName() const
Definition: C4Group.cpp:2638
bool LoadEntry(const char *entry_name, char **buffer, size_t *size_info=nullptr, int zeros_to_append=0)
Definition: C4Group.cpp:2375
void ResetSearch(bool reload_contents=false)
Definition: C4Group.cpp:1316
Definition: C4Id.h:26
const char * ToString() const
Definition: C4Id.h:56
C4ObjectInfo * Info
Definition: C4Object.h:143
bool GetDrawPosition(const C4TargetFacet &cgo, float &resultx, float &resulty, float &resultzoom) const
bool SetGraphics(const char *szGraphicsName=nullptr, C4Def *pSourceDef=nullptr)
class C4GraphicsOverlay * pGfxOverlay
Definition: C4Object.h:169
C4Rect PictureRect
Definition: C4Object.h:150
void DrawPicture(C4Facet &cgo, bool fSelected=false, C4DrawTransform *transform=nullptr)
C4DrawTransform * pDrawTransform
Definition: C4Object.h:135
void DrawTopFace(C4TargetFacet &cgo, int32_t iByPlayer=-1, DrawMode eDrawMode=ODM_Normal, float offX=0, float offY=0)
void PrepareDrawing() const
bool HasGraphicsOverlayRecursion(const C4Object *pCheckObj) const
StdMeshInstance * pMeshInstance
Definition: C4Object.h:154
void Draw(C4TargetFacet &cgo, int32_t iByPlayer=-1, DrawMode eDrawMode=ODM_Normal, float offX=0, float offY=0)
@ ODM_Overlay
Definition: C4Object.h:215
@ ODM_BaseOnly
Definition: C4Object.h:215
void FinishedDrawing() const
C4Def * Def
Definition: C4Object.h:141
uint32_t Color
Definition: C4Object.h:118
C4Shape Shape
Definition: C4Object.h:146
C4DefGraphics * GetGraphics() const
Definition: C4Object.h:339
void DenumeratePointers()
Definition: C4ObjectPtr.cpp:49
int32_t GetPropertyInt(C4PropertyName k, int32_t default_val=0) const
Definition: C4PropList.cpp:855
int32_t Status
Definition: C4PropList.h:173
virtual bool GetPropertyByS(const C4String *k, C4Value *pResult) const
Definition: C4PropList.cpp:726
C4String * GetPropertyStr(C4PropertyName k) const
Definition: C4PropList.cpp:744
bool GetProperty(C4PropertyName k, C4Value *pResult) const
Definition: C4PropList.h:105
const char * GetName() const override
Definition: C4PropList.cpp:243
int32_t GetBaseRankNum() const
Definition: C4RankSystem.h:52
static bool DrawRankSymbol(C4FacetSurface *fctSymbol, int32_t iRank, C4Facet *pfctRankSymbols, int32_t iRankSymbolCount, bool fOwnSurface, int32_t iXOff=0, C4Facet *cgoDrawDirect=nullptr)
Definition: C4Rect.h:28
int32_t y
Definition: C4Rect.h:30
int32_t Hgt
Definition: C4Rect.h:30
int32_t Wdt
Definition: C4Rect.h:30
int32_t x
Definition: C4Rect.h:30
StdStrBuf GetData() const
Definition: C4StringTable.h:50
C4String * RegString(StdStrBuf String)
int Wdt
Definition: C4Surface.h:65
void SetClr(DWORD toClr)
Definition: C4Surface.h:132
int Hgt
Definition: C4Surface.h:65
float TargetY
Definition: C4Facet.h:165
float TargetX
Definition: C4Facet.h:165
float Zoom
Definition: C4Facet.h:165
void Default()
Definition: C4Facet.h:179
void Set(const C4Facet &cpy)
Definition: C4Facet.h:182
C4PropList * getPropList() const
Definition: C4Value.h:116
virtual bool Separator(Sep eSep=SEP_SEP)
Definition: StdCompiler.h:119
void excCorrupt(const char *szMessage,...)
Definition: StdCompiler.h:249
void Value(const T &rStruct)
Definition: StdCompiler.h:161
virtual bool isDeserializer()
Definition: StdCompiler.h:53
virtual bool hasNaming()
Definition: StdCompiler.h:58
float Length
Definition: StdMesh.h:98
void Update(StdMeshInstance *instance) const
StdMeshInstance * Parent
Definition: StdMesh.h:510
AttachedMesh * GetAttachParent() const
Definition: StdMesh.h:586
bool DetachMesh(unsigned int number)
Definition: StdMesh.cpp:1395
AttachedMeshIter AttachedMeshesBegin() const
Definition: StdMesh.h:584
AnimationNode * PlayAnimation(const StdStrBuf &animation_name, int slot, AnimationNode *sibling, ValueProvider *position, ValueProvider *weight, bool stop_previous_animation)
Definition: StdMesh.cpp:1167
void SetFaceOrderingForClrModulation(uint32_t clrmod)
Definition: StdMesh.cpp:1135
const StdMesh & GetMesh() const
Definition: StdMesh.h:622
AttachedMeshIter AttachedMeshesEnd() const
Definition: StdMesh.h:585
AttachedMeshList::const_iterator AttachedMeshIter
Definition: StdMesh.h:544
static StdMesh * LoadMeshXml(const char *sourcefile, size_t size, const StdMeshMatManager &mat_mgr, StdMeshSkeletonLoader &loader, const char *filename=nullptr)
static StdMesh * LoadMeshBinary(const char *sourcefile, size_t size, const StdMeshMatManager &mat_mgr, StdMeshSkeletonLoader &loader, const char *filename=nullptr)
void Remove(const StdStrBuf &name, class StdMeshMaterialUpdate *update)
void Update(StdMesh *mesh) const
void LoadSkeletonBinary(const char *groupname, const char *filename, const char *sourcefile, size_t size)
void LoadSkeletonXml(const char *groupname, const char *filename, const char *sourcefile, size_t size)
void RemoveSkeleton(const StdCopyStrBuf &filepath)
void Update(StdMeshInstance *instance, const StdMesh &new_mesh) const
const StdMesh & GetOldMesh() const
Definition: StdMeshUpdate.h:56
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