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