Move C4DefList class into from C4Def.cpp/h to new C4DefList.cpp/h

floating-point
Günther Brammer 2011-03-03 17:10:22 +01:00
parent ed86af5f29
commit e250312c26
32 changed files with 659 additions and 588 deletions

View File

@ -229,6 +229,8 @@ set(OC_CLONK_SOURCES
src/game/object/C4Def.cpp
src/game/object/C4DefGraphics.cpp
src/game/object/C4DefGraphics.h
src/game/object/C4DefList.cpp
src/game/object/C4DefList.h
src/game/object/C4Def.h
src/game/object/C4GameObjects.cpp
src/game/object/C4GameObjects.h

View File

@ -247,6 +247,8 @@ src/game/object/C4Command.h \
src/game/object/C4Def.cpp \
src/game/object/C4DefGraphics.cpp \
src/game/object/C4DefGraphics.h \
src/game/object/C4DefList.cpp \
src/game/object/C4DefList.h \
src/game/object/C4Def.h \
src/game/object/C4GameObjects.cpp \
src/game/object/C4GameObjects.h \

View File

@ -30,6 +30,7 @@
#include <C4Include.h>
#include <C4Game.h>
#include <C4DefList.h>
#include <C4Effects.h>
#include <C4FileMonitor.h>
#include <C4GameSave.h>

View File

@ -24,7 +24,7 @@
#include "C4FullScreen.h"
#include "C4MouseControl.h"
#include "C4GameObjects.h"
#include "C4Def.h"
#include <C4DefList.h>
#include "C4Game.h"
#include "C4Network2.h"

View File

@ -24,6 +24,7 @@
#include "C4Log.h"
#include "C4Components.h"
#include "C4Def.h"
#include <C4DefList.h>
#include <C4Game.h>
#include <C4GameObjects.h>
#include <C4Network2.h>

View File

@ -22,6 +22,7 @@
#include "C4Include.h"
#include "C4PlayerControl.h"
#include <C4DefList.h>
#include "C4LangStringTable.h"
#include "C4Player.h"
#include "C4PlayerList.h"

View File

@ -28,6 +28,7 @@
#include <C4Include.h>
#include <C4Command.h>
#include <C4DefList.h>
#include <C4Object.h>
#include <C4ObjectCom.h>
#include <C4ObjectInfo.h>

View File

@ -27,23 +27,14 @@
#include <C4Include.h>
#include <C4Def.h>
#include <C4Version.h>
#include <C4GameVersion.h>
#include <C4FileMonitor.h>
#include <C4Log.h>
#include <C4Components.h>
#include <C4Config.h>
#include <C4RankSystem.h>
#include <C4Game.h>
#include <C4GameObjects.h>
#include <C4FileMonitor.h>
#include <C4Language.h>
#include <C4Object.h>
#include "C4Network2Res.h"
#include <C4Material.h>
#include <C4RankSystem.h>
#include <C4SoundSystem.h>
//--------------------------------- C4DefCore ----------------------------------------------
void C4Def::DefaultDefCore()
{
rC4XVer[0]=rC4XVer[1]=rC4XVer[2]=rC4XVer[3]=0;
@ -651,470 +642,6 @@ void C4Def::Synchronize()
{
}
//--------------------------------- C4DefList ----------------------------------------------
C4DefList::C4DefList()
{
Default();
}
C4DefList::~C4DefList()
{
Clear();
}
int32_t C4DefList::Load(C4Group &hGroup, DWORD dwLoadWhat,
const char *szLanguage,
C4SoundSystem *pSoundSystem,
bool fOverload,
bool fSearchMessage, int32_t iMinProgress, int32_t iMaxProgress, bool fLoadSysGroups)
{
int32_t iResult=0;
C4Def *nDef;
char szEntryname[_MAX_FNAME+1];
C4Group hChild;
bool fPrimaryDef=false;
bool fThisSearchMessage=false;
// This search message
if (fSearchMessage)
if (SEqualNoCase(GetExtension(hGroup.GetName()),"c4d")
|| SEqualNoCase(GetExtension(hGroup.GetName()),"c4s")
|| SEqualNoCase(GetExtension(hGroup.GetName()),"c4f"))
{
fThisSearchMessage=true;
fSearchMessage=false;
}
if (fThisSearchMessage) { LogF("%s...",GetFilename(hGroup.GetName())); }
// Load primary definition
if ((nDef=new C4Def))
{
if ( nDef->Load(hGroup,dwLoadWhat,szLanguage,pSoundSystem) && Add(nDef,fOverload) )
{ iResult++; fPrimaryDef=true; }
else
{ delete nDef; }
}
// Load sub definitions
int i = 0;
hGroup.ResetSearch();
while (hGroup.FindNextEntry(C4CFN_DefFiles,szEntryname))
if (hChild.OpenAsChild(&hGroup,szEntryname))
{
// Hack: Assume that there are sixteen sub definitions to avoid unnecessary I/O
int iSubMinProgress = Min<int32_t>(iMaxProgress, iMinProgress + ((iMaxProgress - iMinProgress) * i) / 16);
int iSubMaxProgress = Min<int32_t>(iMaxProgress, iMinProgress + ((iMaxProgress - iMinProgress) * (i + 1)) / 16);
++i;
iResult += Load(hChild,dwLoadWhat,szLanguage,pSoundSystem,fOverload,fSearchMessage,iSubMinProgress,iSubMaxProgress);
hChild.Close();
}
// load additional system scripts for def groups only
if (!fPrimaryDef && fLoadSysGroups) Game.LoadAdditionalSystemGroup(hGroup);
if (fThisSearchMessage) { LogF(LoadResStr("IDS_PRC_DEFSLOADED"),iResult); }
// progress (could go down one level of recursion...)
if (iMinProgress != iMaxProgress) Game.SetInitProgress(float(iMaxProgress));
return iResult;
}
int32_t C4DefList::LoadFolderLocal( const char *szPath,
DWORD dwLoadWhat, const char *szLanguage,
C4SoundSystem *pSoundSystem,
bool fOverload, char *sStoreName, int32_t iMinProgress, int32_t iMaxProgress)
{
int32_t iResult = 0;
// Scan path for folder names
int32_t cnt,iBackslash,iDefs;
char szFoldername[_MAX_PATH+1];
for (cnt=0; (iBackslash=SCharPos('\\',szPath,cnt)) > -1; cnt++)
{
SCopy(szPath,szFoldername,iBackslash);
// Load from parent folder
if (SEqualNoCase(GetExtension(szFoldername),"c4f"))
if ((iDefs=Load(szFoldername,dwLoadWhat,szLanguage,pSoundSystem,fOverload)))
{
iResult+=iDefs;
// Add any folder containing defs to store list
if (sStoreName) { SNewSegment(sStoreName); SAppend(szFoldername,sStoreName); }
}
}
// progress (could go down one level of recursion...)
if (iMinProgress != iMaxProgress) Game.SetInitProgress(float(iMaxProgress));
return iResult;
}
int32_t C4DefList::Load(const char *szSearch,
DWORD dwLoadWhat, const char *szLanguage,
C4SoundSystem *pSoundSystem,
bool fOverload, int32_t iMinProgress, int32_t iMaxProgress)
{
int32_t iResult=0;
// Empty
if (!szSearch[0]) return iResult;
// Segments
char szSegment[_MAX_PATH+1]; int32_t iGroupCount;
if ((iGroupCount=SCharCount(';',szSearch)))
{
++iGroupCount; int32_t iPrg=iMaxProgress-iMinProgress;
for (int32_t cseg=0; SCopySegment(szSearch,cseg,szSegment,';',_MAX_PATH); cseg++)
iResult += Load(szSegment,dwLoadWhat,szLanguage,pSoundSystem,fOverload,
iMinProgress+iPrg*cseg/iGroupCount, iMinProgress+iPrg*(cseg+1)/iGroupCount);
return iResult;
}
// Wildcard items
if (SCharCount('*',szSearch))
{
#ifdef _WIN32
struct _finddata_t fdt; int32_t fdthnd;
if ((fdthnd=_findfirst(szSearch,&fdt))<0) return false;
do
{
iResult += Load(fdt.name,dwLoadWhat,szLanguage,pSoundSystem,fOverload);
}
while (_findnext(fdthnd,&fdt)==0);
_findclose(fdthnd);
// progress
if (iMinProgress != iMaxProgress) Game.SetInitProgress(float(iMaxProgress));
#else
fputs("FIXME: C4DefList::Load\n", stderr);
#endif
return iResult;
}
// File specified with creation (currently not used)
char szCreation[25+1];
int32_t iCreation=0;
if (SCopyEnclosed(szSearch,'(',')',szCreation,25))
{
// Scan creation
SClearFrontBack(szCreation);
sscanf(szCreation,"%i",&iCreation);
// Extract filename
SCopyUntil(szSearch,szSegment,'(',_MAX_PATH);
SClearFrontBack(szSegment);
szSearch = szSegment;
}
// Load from specified file
C4Group hGroup;
if (!Reloc.Open(hGroup, szSearch))
{
// Specified file not found (failure)
LogFatal(FormatString(LoadResStr("IDS_PRC_DEFNOTFOUND"),szSearch).getData());
LoadFailure=true;
return iResult;
}
iResult += Load(hGroup,dwLoadWhat,szLanguage,pSoundSystem,fOverload,true,iMinProgress,iMaxProgress);
hGroup.Close();
// progress (could go down one level of recursion...)
if (iMinProgress != iMaxProgress) Game.SetInitProgress(float(iMaxProgress));
return iResult;
}
bool C4DefList::Add(C4Def *pDef, bool fOverload)
{
if (!pDef) return false;
// Check old def to overload
C4Def *pLastDef = ID2Def(pDef->id);
if (pLastDef && !fOverload) return false;
// Log overloaded def
if (Config.Graphics.VerboseObjectLoading>=1)
if (pLastDef)
{
LogF(LoadResStr("IDS_PRC_DEFOVERLOAD"),pDef->GetName(),pLastDef->id.ToString());
if (Config.Graphics.VerboseObjectLoading >= 2)
{
LogF(" Old def at %s",pLastDef->Filename);
LogF(" Overload by %s",pDef->Filename);
}
}
// Remove old def
Remove(pDef->id);
// Add new def
pDef->Next=FirstDef;
FirstDef=pDef;
return true;
}
bool C4DefList::Remove(C4ID id)
{
C4Def *cdef,*prev;
for (cdef=FirstDef,prev=NULL; cdef; prev=cdef,cdef=cdef->Next)
if (cdef->id==id)
{
if (prev) prev->Next=cdef->Next;
else FirstDef=cdef->Next;
delete cdef;
return true;
}
return false;
}
void C4DefList::Remove(C4Def *def)
{
C4Def *cdef,*prev;
for (cdef=FirstDef,prev=NULL; cdef; prev=cdef,cdef=cdef->Next)
if (cdef==def)
{
if (prev) prev->Next=cdef->Next;
else FirstDef=cdef->Next;
delete cdef;
return;
}
}
void C4DefList::Clear()
{
C4Def *cdef,*next;
for (cdef=FirstDef; cdef; cdef=next)
{
next=cdef->Next;
delete cdef;
}
FirstDef=NULL;
// clear quick access table
table.clear();
}
C4Def* C4DefList::ID2Def(C4ID id)
{
if (id==C4ID::None) return NULL;
if (table.empty())
{
// table not yet built: search list
C4Def *cdef;
for (cdef=FirstDef; cdef; cdef=cdef->Next)
if (cdef->id==id) return cdef;
}
else
{
Table::const_iterator it = table.find(id);
if (it != table.end())
return it->second;
}
// none found
return NULL;
}
int32_t C4DefList::GetIndex(C4ID id)
{
C4Def *cdef;
int32_t cindex;
for (cdef=FirstDef,cindex=0; cdef; cdef=cdef->Next,cindex++)
if (cdef->id==id) return cindex;
return -1;
}
int32_t C4DefList::GetDefCount(DWORD dwCategory)
{
C4Def *cdef; int32_t ccount=0;
for (cdef=FirstDef; cdef; cdef=cdef->Next)
if (cdef->Category & dwCategory)
ccount++;
return ccount;
}
C4Def* C4DefList::GetDef(int32_t iIndex, DWORD dwCategory)
{
C4Def *pDef; int32_t iCurrentIndex;
if (iIndex<0) return NULL;
for (pDef=FirstDef,iCurrentIndex=-1; pDef; pDef=pDef->Next)
if (pDef->Category & dwCategory)
{
iCurrentIndex++;
if (iCurrentIndex==iIndex) return pDef;
}
return NULL;
}
C4Def *C4DefList::GetByPath(const char *szPath)
{
// search defs
const char *szDefPath;
for (C4Def *pDef = FirstDef; pDef; pDef = pDef->Next)
if ((szDefPath = Config.AtRelativePath(pDef->Filename)))
if (SEqual2NoCase(szPath, szDefPath))
{
// the definition itself?
if (!szPath[SLen(szDefPath)])
return pDef;
// or a component?
else if (szPath[SLen(szDefPath)] == '\\')
if (!strchr(szPath + SLen(szDefPath) + 1, '\\'))
return pDef;
}
// not found
return NULL;
}
int32_t C4DefList::RemoveTemporary()
{
C4Def *cdef,*prev,*next;
int32_t removed=0;
for (cdef=FirstDef,prev=NULL; cdef; cdef=next)
{
next=cdef->Next;
if (cdef->Temporary)
{
if (prev) prev->Next=next;
else FirstDef=next;
delete cdef;
removed++;
}
else
prev=cdef;
}
// rebuild quick access table
BuildTable();
return removed;
}
int32_t C4DefList::CheckEngineVersion(int32_t ver1, int32_t ver2, int32_t ver3, int32_t ver4)
{
int32_t rcount=0;
C4Def *cdef,*prev,*next;
for (cdef=FirstDef,prev=NULL; cdef; cdef=next)
{
next=cdef->Next;
if (CompareVersion(cdef->rC4XVer[0],cdef->rC4XVer[1],cdef->rC4XVer[2],cdef->rC4XVer[3],ver1,ver2,ver3,ver4) > 0)
{
if (prev) prev->Next=cdef->Next;
else FirstDef=cdef->Next;
delete cdef;
rcount++;
}
else prev=cdef;
}
return rcount;
}
int32_t C4DefList::CheckRequireDef()
{
int32_t rcount=0, rcount2;
C4Def *cdef,*prev,*next;
do
{
rcount2 = rcount;
for (cdef=FirstDef,prev=NULL; cdef; cdef=next)
{
next=cdef->Next;
for (int32_t i = 0; i < cdef->RequireDef.GetNumberOfIDs(); i++)
if (GetIndex(cdef->RequireDef.GetID(i)) < 0)
{
(prev ? prev->Next : FirstDef) = cdef->Next;
delete cdef;
rcount++;
}
}
}
while (rcount != rcount2);
return rcount;
}
void C4DefList::Draw(C4ID id, C4Facet &cgo, bool fSelected, int32_t iColor)
{
C4Def *cdef = ID2Def(id);
if (cdef) cdef->Draw(cgo,fSelected,iColor);
}
void C4DefList::Default()
{
FirstDef=NULL;
LoadFailure=false;
table.clear();
}
// Load scenario specified or all selected plus scenario & folder local
int32_t C4DefList::LoadForScenario(const char *szScenario,
const char *szSelection,
DWORD dwLoadWhat, const char *szLanguage,
C4SoundSystem *pSoundSystem, bool fOverload,
int32_t iMinProgress, int32_t iMaxProgress)
{
int32_t iDefs=0;
StdStrBuf sSpecified;
// User selected modules
sSpecified.Copy(szSelection);
// Open scenario file & load core
C4Group hScenario;
C4Scenario C4S;
if ( !hScenario.Open(szScenario)
|| !C4S.Load(hScenario) )
return 0;
// Scenario definition specifications (override user selection)
if (!C4S.Definitions.AllowUserChange)
C4S.Definitions.GetModules(&sSpecified);
// Load specified
iDefs += Load(sSpecified.getData(),dwLoadWhat,szLanguage,pSoundSystem,fOverload);
if (iMinProgress != iMaxProgress) Game.SetInitProgress(float(iMaxProgress+iMinProgress)/2);
// Load folder local
iDefs += LoadFolderLocal(szScenario,dwLoadWhat,szLanguage,pSoundSystem,fOverload);
if (iMinProgress != iMaxProgress) Game.SetInitProgress(float(iMaxProgress*3+iMinProgress)/4);
// Load local
iDefs += Load(hScenario,dwLoadWhat,szLanguage,pSoundSystem,fOverload);
// build quick access table
BuildTable();
// progress
if (iMinProgress != iMaxProgress) Game.SetInitProgress(float(iMaxProgress));
// Done
return iDefs;
}
bool C4DefList::Reload(C4Def *pDef, DWORD dwLoadWhat, const char *szLanguage, C4SoundSystem *pSoundSystem)
{
// Safety
if (!pDef) return false;
// backup graphics names and pointers
// GfxBackup-dtor will ensure that upon loading-failure all graphics are reset to default
C4DefGraphicsPtrBackup GfxBackup(&pDef->Graphics);
// Clear def
pDef->Clear(); // Assume filename is being kept
// Reload def
C4Group hGroup;
if (!hGroup.Open(pDef->Filename)) return false;
if (!pDef->Load( hGroup, dwLoadWhat, szLanguage, pSoundSystem )) return false;
hGroup.Close();
// rebuild quick access table
BuildTable();
// update script engine - this will also do include callbacks and Freeze() this
::ScriptEngine.ReLink(this);
// restore graphics
GfxBackup.AssignUpdate(&pDef->Graphics);
// Success
return true;
}
bool C4Def::LoadPortraits(C4Group &hGroup)
{
// reset any previous portraits
@ -1261,48 +788,3 @@ C4PropList *C4Def::GetActionByName(C4String *actname)
if (!Action.getPropList()) return false;
return Action.getPropList();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// C4DefList
bool C4DefList::GetFontImage(const char *szImageTag, CFacet &rOutImgFacet)
{
// extended: images by game
C4FacetSurface fctOut;
if (!Game.DrawTextSpecImage(fctOut, szImageTag)) return false;
if (fctOut.Surface == &fctOut.GetFace()) return false; // cannot use facets that are drawn on the fly right now...
rOutImgFacet.Set(fctOut.Surface, fctOut.X, fctOut.Y, fctOut.Wdt, fctOut.Hgt);
// done, found
return true;
}
void C4DefList::Synchronize()
{
for (Table::iterator it = table.begin(); it != table.end(); ++it)
it->second->Synchronize();
}
void C4DefList::ResetIncludeDependencies()
{
for (Table::iterator it = table.begin(); it != table.end(); ++it)
it->second->ResetIncludeDependencies();
}
void C4DefList::CallEveryDefinition()
{
for (Table::iterator it = table.begin(); it != table.end(); ++it)
{
C4AulParSet Pars(C4VPropList(it->second));
it->second->Script.Call(PSF_Definition, 0, &Pars, true);
it->second->Freeze();
}
}
void C4DefList::BuildTable()
{
table.clear();
for (C4Def *def = FirstDef; def; def = def->Next)
table.insert(std::make_pair(def->id, def));
}

View File

@ -43,9 +43,7 @@
#include <functional>
#include <set>
const int32_t C4D_None = 0,
C4D_All = ~C4D_None,
const int32_t
C4D_StaticBack = 1<<0,
C4D_Structure = 1<<1,
C4D_Vehicle = 1<<2,
@ -249,66 +247,4 @@ public:
C4PropList *GetActionByName(C4String *actname);
};
class C4DefList
: public CStdFont::CustomImages
{
public:
C4DefList();
virtual ~C4DefList();
public:
bool LoadFailure;
typedef std::map<C4ID, C4Def*> Table;
Table table;
protected:
C4Def *FirstDef;
public:
void Default();
void Clear();
int32_t Load(C4Group &hGroup,
DWORD dwLoadWhat, const char *szLanguage,
C4SoundSystem *pSoundSystem = NULL,
bool fOverload = false,
bool fSearchMessage = false, int32_t iMinProgress=0, int32_t iMaxProgress=0, bool fLoadSysGroups = true);
int32_t Load(const char *szSearch,
DWORD dwLoadWhat, const char *szLanguage,
C4SoundSystem *pSoundSystem = NULL,
bool fOverload = false, int32_t iMinProgress=0, int32_t iMaxProgress=0);
int32_t LoadFolderLocal(const char *szPath,
DWORD dwLoadWhat, const char *szLanguage,
C4SoundSystem *pSoundSystem = NULL,
bool fOverload = false, char *szStoreName=NULL, int32_t iMinProgress=0, int32_t iMaxProgress=0);
int32_t LoadForScenario(const char *szScenario,
const char *szSpecified,
DWORD dwLoadWhat, const char *szLanguage,
C4SoundSystem *pSoundSystem = NULL,
bool fOverload = false, int32_t iMinProgress=0, int32_t iMaxProgress=0);
C4Def *ID2Def(C4ID id);
C4Def *GetDef(int32_t Index, DWORD dwCategory = C4D_All);
C4Def *GetByPath(const char *szPath);
int32_t GetDefCount(DWORD dwCategory = C4D_All);
int32_t GetIndex(C4ID id);
int32_t RemoveTemporary();
int32_t CheckEngineVersion(int32_t ver1, int32_t ver2, int32_t ver3, int32_t ver4);
int32_t CheckRequireDef();
void Draw(C4ID id, C4Facet &cgo, bool fSelected, int32_t iColor);
void Remove(C4Def *def);
bool Remove(C4ID id);
bool Reload(C4Def *pDef, DWORD dwLoadWhat, const char *szLanguage, C4SoundSystem *pSoundSystem = NULL);
bool Add(C4Def *ndef, bool fOverload);
void BuildTable();
void ResetIncludeDependencies(); // resets all pointers into foreign definitions caused by include chains
void CallEveryDefinition();
void Synchronize();
// callback from font renderer: get ID image
virtual bool GetFontImage(const char *szImageTag, CFacet &rOutImgFacet);
};
extern C4DefList Definitions;
inline C4Def *C4Id2Def(C4ID id)
{
return ::Definitions.ID2Def(id);
}
#endif

View File

@ -27,6 +27,7 @@
#include <C4Include.h>
#include <C4DefGraphics.h>
#include <C4DefList.h>
#include <C4Object.h>
#include <C4ObjectInfo.h>
#include <C4Config.h>

View File

@ -0,0 +1,532 @@
/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 1998-2000 Matthes Bender
* Copyright (c) 2001, 2003-2007 Sven Eberhardt
* Copyright (c) 2004-2005, 2007 Peter Wortmann
* Copyright (c) 2009, 2011 Günther Brammer
* Copyright (c) 2010 Benjamin Herr
* Copyright (c) 2010 Nicolas Hake
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de
*
* Portions might be copyrighted by other authors who have contributed
* to OpenClonk.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* See isc_license.txt for full license and disclaimer.
*
* "Clonk" is a registered trademark of Matthes Bender.
* See clonk_trademark_license.txt for full license.
*/
/* Object definition */
#include <C4Include.h>
#include <C4DefList.h>
#include <C4Config.h>
#include <C4Def.h>
#include <C4FileMonitor.h>
#include <C4GameVersion.h>
#include <C4Language.h>
C4DefList::C4DefList()
{
Default();
}
C4DefList::~C4DefList()
{
Clear();
}
int32_t C4DefList::Load(C4Group &hGroup, DWORD dwLoadWhat,
const char *szLanguage,
C4SoundSystem *pSoundSystem,
bool fOverload,
bool fSearchMessage, int32_t iMinProgress, int32_t iMaxProgress, bool fLoadSysGroups)
{
int32_t iResult=0;
C4Def *nDef;
char szEntryname[_MAX_FNAME+1];
C4Group hChild;
bool fPrimaryDef=false;
bool fThisSearchMessage=false;
// This search message
if (fSearchMessage)
if (SEqualNoCase(GetExtension(hGroup.GetName()),"c4d")
|| SEqualNoCase(GetExtension(hGroup.GetName()),"c4s")
|| SEqualNoCase(GetExtension(hGroup.GetName()),"c4f"))
{
fThisSearchMessage=true;
fSearchMessage=false;
}
if (fThisSearchMessage) { LogF("%s...",GetFilename(hGroup.GetName())); }
// Load primary definition
if ((nDef=new C4Def))
{
if ( nDef->Load(hGroup,dwLoadWhat,szLanguage,pSoundSystem) && Add(nDef,fOverload) )
{ iResult++; fPrimaryDef=true; }
else
{ delete nDef; }
}
// Load sub definitions
int i = 0;
hGroup.ResetSearch();
while (hGroup.FindNextEntry(C4CFN_DefFiles,szEntryname))
if (hChild.OpenAsChild(&hGroup,szEntryname))
{
// Hack: Assume that there are sixteen sub definitions to avoid unnecessary I/O
int iSubMinProgress = Min<int32_t>(iMaxProgress, iMinProgress + ((iMaxProgress - iMinProgress) * i) / 16);
int iSubMaxProgress = Min<int32_t>(iMaxProgress, iMinProgress + ((iMaxProgress - iMinProgress) * (i + 1)) / 16);
++i;
iResult += Load(hChild,dwLoadWhat,szLanguage,pSoundSystem,fOverload,fSearchMessage,iSubMinProgress,iSubMaxProgress);
hChild.Close();
}
// load additional system scripts for def groups only
if (!fPrimaryDef && fLoadSysGroups) Game.LoadAdditionalSystemGroup(hGroup);
if (fThisSearchMessage) { LogF(LoadResStr("IDS_PRC_DEFSLOADED"),iResult); }
// progress (could go down one level of recursion...)
if (iMinProgress != iMaxProgress) Game.SetInitProgress(float(iMaxProgress));
return iResult;
}
int32_t C4DefList::LoadFolderLocal( const char *szPath,
DWORD dwLoadWhat, const char *szLanguage,
C4SoundSystem *pSoundSystem,
bool fOverload, char *sStoreName, int32_t iMinProgress, int32_t iMaxProgress)
{
int32_t iResult = 0;
// Scan path for folder names
int32_t cnt,iBackslash,iDefs;
char szFoldername[_MAX_PATH+1];
for (cnt=0; (iBackslash=SCharPos('\\',szPath,cnt)) > -1; cnt++)
{
SCopy(szPath,szFoldername,iBackslash);
// Load from parent folder
if (SEqualNoCase(GetExtension(szFoldername),"c4f"))
if ((iDefs=Load(szFoldername,dwLoadWhat,szLanguage,pSoundSystem,fOverload)))
{
iResult+=iDefs;
// Add any folder containing defs to store list
if (sStoreName) { SNewSegment(sStoreName); SAppend(szFoldername,sStoreName); }
}
}
// progress (could go down one level of recursion...)
if (iMinProgress != iMaxProgress) Game.SetInitProgress(float(iMaxProgress));
return iResult;
}
int32_t C4DefList::Load(const char *szSearch,
DWORD dwLoadWhat, const char *szLanguage,
C4SoundSystem *pSoundSystem,
bool fOverload, int32_t iMinProgress, int32_t iMaxProgress)
{
int32_t iResult=0;
// Empty
if (!szSearch[0]) return iResult;
// Segments
char szSegment[_MAX_PATH+1]; int32_t iGroupCount;
if ((iGroupCount=SCharCount(';',szSearch)))
{
++iGroupCount; int32_t iPrg=iMaxProgress-iMinProgress;
for (int32_t cseg=0; SCopySegment(szSearch,cseg,szSegment,';',_MAX_PATH); cseg++)
iResult += Load(szSegment,dwLoadWhat,szLanguage,pSoundSystem,fOverload,
iMinProgress+iPrg*cseg/iGroupCount, iMinProgress+iPrg*(cseg+1)/iGroupCount);
return iResult;
}
// Wildcard items
if (SCharCount('*',szSearch))
{
#ifdef _WIN32
struct _finddata_t fdt; int32_t fdthnd;
if ((fdthnd=_findfirst(szSearch,&fdt))<0) return false;
do
{
iResult += Load(fdt.name,dwLoadWhat,szLanguage,pSoundSystem,fOverload);
}
while (_findnext(fdthnd,&fdt)==0);
_findclose(fdthnd);
// progress
if (iMinProgress != iMaxProgress) Game.SetInitProgress(float(iMaxProgress));
#else
fputs("FIXME: C4DefList::Load\n", stderr);
#endif
return iResult;
}
// File specified with creation (currently not used)
char szCreation[25+1];
int32_t iCreation=0;
if (SCopyEnclosed(szSearch,'(',')',szCreation,25))
{
// Scan creation
SClearFrontBack(szCreation);
sscanf(szCreation,"%i",&iCreation);
// Extract filename
SCopyUntil(szSearch,szSegment,'(',_MAX_PATH);
SClearFrontBack(szSegment);
szSearch = szSegment;
}
// Load from specified file
C4Group hGroup;
if (!Reloc.Open(hGroup, szSearch))
{
// Specified file not found (failure)
LogFatal(FormatString(LoadResStr("IDS_PRC_DEFNOTFOUND"),szSearch).getData());
LoadFailure=true;
return iResult;
}
iResult += Load(hGroup,dwLoadWhat,szLanguage,pSoundSystem,fOverload,true,iMinProgress,iMaxProgress);
hGroup.Close();
// progress (could go down one level of recursion...)
if (iMinProgress != iMaxProgress) Game.SetInitProgress(float(iMaxProgress));
return iResult;
}
bool C4DefList::Add(C4Def *pDef, bool fOverload)
{
if (!pDef) return false;
// Check old def to overload
C4Def *pLastDef = ID2Def(pDef->id);
if (pLastDef && !fOverload) return false;
// Log overloaded def
if (Config.Graphics.VerboseObjectLoading>=1)
if (pLastDef)
{
LogF(LoadResStr("IDS_PRC_DEFOVERLOAD"),pDef->GetName(),pLastDef->id.ToString());
if (Config.Graphics.VerboseObjectLoading >= 2)
{
LogF(" Old def at %s",pLastDef->Filename);
LogF(" Overload by %s",pDef->Filename);
}
}
// Remove old def
Remove(pDef->id);
// Add new def
pDef->Next=FirstDef;
FirstDef=pDef;
return true;
}
bool C4DefList::Remove(C4ID id)
{
C4Def *cdef,*prev;
for (cdef=FirstDef,prev=NULL; cdef; prev=cdef,cdef=cdef->Next)
if (cdef->id==id)
{
if (prev) prev->Next=cdef->Next;
else FirstDef=cdef->Next;
delete cdef;
return true;
}
return false;
}
void C4DefList::Remove(C4Def *def)
{
C4Def *cdef,*prev;
for (cdef=FirstDef,prev=NULL; cdef; prev=cdef,cdef=cdef->Next)
if (cdef==def)
{
if (prev) prev->Next=cdef->Next;
else FirstDef=cdef->Next;
delete cdef;
return;
}
}
void C4DefList::Clear()
{
C4Def *cdef,*next;
for (cdef=FirstDef; cdef; cdef=next)
{
next=cdef->Next;
delete cdef;
}
FirstDef=NULL;
// clear quick access table
table.clear();
}
C4Def* C4DefList::ID2Def(C4ID id)
{
if (id==C4ID::None) return NULL;
if (table.empty())
{
// table not yet built: search list
C4Def *cdef;
for (cdef=FirstDef; cdef; cdef=cdef->Next)
if (cdef->id==id) return cdef;
}
else
{
Table::const_iterator it = table.find(id);
if (it != table.end())
return it->second;
}
// none found
return NULL;
}
int32_t C4DefList::GetIndex(C4ID id)
{
C4Def *cdef;
int32_t cindex;
for (cdef=FirstDef,cindex=0; cdef; cdef=cdef->Next,cindex++)
if (cdef->id==id) return cindex;
return -1;
}
int32_t C4DefList::GetDefCount(DWORD dwCategory)
{
C4Def *cdef; int32_t ccount=0;
for (cdef=FirstDef; cdef; cdef=cdef->Next)
if (cdef->Category & dwCategory)
ccount++;
return ccount;
}
C4Def* C4DefList::GetDef(int32_t iIndex, DWORD dwCategory)
{
C4Def *pDef; int32_t iCurrentIndex;
if (iIndex<0) return NULL;
for (pDef=FirstDef,iCurrentIndex=-1; pDef; pDef=pDef->Next)
if (pDef->Category & dwCategory)
{
iCurrentIndex++;
if (iCurrentIndex==iIndex) return pDef;
}
return NULL;
}
C4Def *C4DefList::GetByPath(const char *szPath)
{
// search defs
const char *szDefPath;
for (C4Def *pDef = FirstDef; pDef; pDef = pDef->Next)
if ((szDefPath = Config.AtRelativePath(pDef->Filename)))
if (SEqual2NoCase(szPath, szDefPath))
{
// the definition itself?
if (!szPath[SLen(szDefPath)])
return pDef;
// or a component?
else if (szPath[SLen(szDefPath)] == '\\')
if (!strchr(szPath + SLen(szDefPath) + 1, '\\'))
return pDef;
}
// not found
return NULL;
}
int32_t C4DefList::RemoveTemporary()
{
C4Def *cdef,*prev,*next;
int32_t removed=0;
for (cdef=FirstDef,prev=NULL; cdef; cdef=next)
{
next=cdef->Next;
if (cdef->Temporary)
{
if (prev) prev->Next=next;
else FirstDef=next;
delete cdef;
removed++;
}
else
prev=cdef;
}
// rebuild quick access table
BuildTable();
return removed;
}
int32_t C4DefList::CheckEngineVersion(int32_t ver1, int32_t ver2, int32_t ver3, int32_t ver4)
{
int32_t rcount=0;
C4Def *cdef,*prev,*next;
for (cdef=FirstDef,prev=NULL; cdef; cdef=next)
{
next=cdef->Next;
if (CompareVersion(cdef->rC4XVer[0],cdef->rC4XVer[1],cdef->rC4XVer[2],cdef->rC4XVer[3],ver1,ver2,ver3,ver4) > 0)
{
if (prev) prev->Next=cdef->Next;
else FirstDef=cdef->Next;
delete cdef;
rcount++;
}
else prev=cdef;
}
return rcount;
}
int32_t C4DefList::CheckRequireDef()
{
int32_t rcount=0, rcount2;
C4Def *cdef,*prev,*next;
do
{
rcount2 = rcount;
for (cdef=FirstDef,prev=NULL; cdef; cdef=next)
{
next=cdef->Next;
for (int32_t i = 0; i < cdef->RequireDef.GetNumberOfIDs(); i++)
if (GetIndex(cdef->RequireDef.GetID(i)) < 0)
{
(prev ? prev->Next : FirstDef) = cdef->Next;
delete cdef;
rcount++;
}
}
}
while (rcount != rcount2);
return rcount;
}
void C4DefList::Draw(C4ID id, C4Facet &cgo, bool fSelected, int32_t iColor)
{
C4Def *cdef = ID2Def(id);
if (cdef) cdef->Draw(cgo,fSelected,iColor);
}
void C4DefList::Default()
{
FirstDef=NULL;
LoadFailure=false;
table.clear();
}
// Load scenario specified or all selected plus scenario & folder local
int32_t C4DefList::LoadForScenario(const char *szScenario,
const char *szSelection,
DWORD dwLoadWhat, const char *szLanguage,
C4SoundSystem *pSoundSystem, bool fOverload,
int32_t iMinProgress, int32_t iMaxProgress)
{
int32_t iDefs=0;
StdStrBuf sSpecified;
// User selected modules
sSpecified.Copy(szSelection);
// Open scenario file & load core
C4Group hScenario;
C4Scenario C4S;
if ( !hScenario.Open(szScenario)
|| !C4S.Load(hScenario) )
return 0;
// Scenario definition specifications (override user selection)
if (!C4S.Definitions.AllowUserChange)
C4S.Definitions.GetModules(&sSpecified);
// Load specified
iDefs += Load(sSpecified.getData(),dwLoadWhat,szLanguage,pSoundSystem,fOverload);
if (iMinProgress != iMaxProgress) Game.SetInitProgress(float(iMaxProgress+iMinProgress)/2);
// Load folder local
iDefs += LoadFolderLocal(szScenario,dwLoadWhat,szLanguage,pSoundSystem,fOverload);
if (iMinProgress != iMaxProgress) Game.SetInitProgress(float(iMaxProgress*3+iMinProgress)/4);
// Load local
iDefs += Load(hScenario,dwLoadWhat,szLanguage,pSoundSystem,fOverload);
// build quick access table
BuildTable();
// progress
if (iMinProgress != iMaxProgress) Game.SetInitProgress(float(iMaxProgress));
// Done
return iDefs;
}
bool C4DefList::Reload(C4Def *pDef, DWORD dwLoadWhat, const char *szLanguage, C4SoundSystem *pSoundSystem)
{
// Safety
if (!pDef) return false;
// backup graphics names and pointers
// GfxBackup-dtor will ensure that upon loading-failure all graphics are reset to default
C4DefGraphicsPtrBackup GfxBackup(&pDef->Graphics);
// Clear def
pDef->Clear(); // Assume filename is being kept
// Reload def
C4Group hGroup;
if (!hGroup.Open(pDef->Filename)) return false;
if (!pDef->Load( hGroup, dwLoadWhat, szLanguage, pSoundSystem )) return false;
hGroup.Close();
// rebuild quick access table
BuildTable();
// update script engine - this will also do include callbacks and Freeze() this
::ScriptEngine.ReLink(this);
// restore graphics
GfxBackup.AssignUpdate(&pDef->Graphics);
// Success
return true;
}
bool C4DefList::GetFontImage(const char *szImageTag, CFacet &rOutImgFacet)
{
// extended: images by game
C4FacetSurface fctOut;
if (!Game.DrawTextSpecImage(fctOut, szImageTag)) return false;
if (fctOut.Surface == &fctOut.GetFace()) return false; // cannot use facets that are drawn on the fly right now...
rOutImgFacet.Set(fctOut.Surface, fctOut.X, fctOut.Y, fctOut.Wdt, fctOut.Hgt);
// done, found
return true;
}
void C4DefList::Synchronize()
{
for (Table::iterator it = table.begin(); it != table.end(); ++it)
it->second->Synchronize();
}
void C4DefList::ResetIncludeDependencies()
{
for (Table::iterator it = table.begin(); it != table.end(); ++it)
it->second->ResetIncludeDependencies();
}
void C4DefList::CallEveryDefinition()
{
for (Table::iterator it = table.begin(); it != table.end(); ++it)
{
C4AulParSet Pars(C4VPropList(it->second));
it->second->Script.Call(PSF_Definition, 0, &Pars, true);
it->second->Freeze();
}
}
void C4DefList::BuildTable()
{
table.clear();
for (C4Def *def = FirstDef; def; def = def->Next)
table.insert(std::make_pair(def->id, def));
}

View File

@ -0,0 +1,92 @@
/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 1998-2000 Matthes Bender
* Copyright (c) 2005 Sven Eberhardt
* Copyright (c) 2009, 2011 Günther Brammer
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de
*
* Portions might be copyrighted by other authors who have contributed
* to OpenClonk.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* See isc_license.txt for full license and disclaimer.
*
* "Clonk" is a registered trademark of Matthes Bender.
* See clonk_trademark_license.txt for full license.
*/
/* Object definition */
#ifndef INC_C4DefList
#define INC_C4DefList
const int32_t C4D_None = 0,
C4D_All = ~C4D_None;
class C4DefList
: public CStdFont::CustomImages
{
public:
C4DefList();
virtual ~C4DefList();
public:
bool LoadFailure;
typedef std::map<C4ID, C4Def*> Table;
Table table;
protected:
C4Def *FirstDef;
public:
void Default();
void Clear();
int32_t Load(C4Group &hGroup,
DWORD dwLoadWhat, const char *szLanguage,
C4SoundSystem *pSoundSystem = NULL,
bool fOverload = false,
bool fSearchMessage = false, int32_t iMinProgress=0, int32_t iMaxProgress=0, bool fLoadSysGroups = true);
int32_t Load(const char *szSearch,
DWORD dwLoadWhat, const char *szLanguage,
C4SoundSystem *pSoundSystem = NULL,
bool fOverload = false, int32_t iMinProgress=0, int32_t iMaxProgress=0);
int32_t LoadFolderLocal(const char *szPath,
DWORD dwLoadWhat, const char *szLanguage,
C4SoundSystem *pSoundSystem = NULL,
bool fOverload = false, char *szStoreName=NULL, int32_t iMinProgress=0, int32_t iMaxProgress=0);
int32_t LoadForScenario(const char *szScenario,
const char *szSpecified,
DWORD dwLoadWhat, const char *szLanguage,
C4SoundSystem *pSoundSystem = NULL,
bool fOverload = false, int32_t iMinProgress=0, int32_t iMaxProgress=0);
C4Def *ID2Def(C4ID id);
C4Def *GetDef(int32_t Index, DWORD dwCategory = C4D_All);
C4Def *GetByPath(const char *szPath);
int32_t GetDefCount(DWORD dwCategory = C4D_All);
int32_t GetIndex(C4ID id);
int32_t RemoveTemporary();
int32_t CheckEngineVersion(int32_t ver1, int32_t ver2, int32_t ver3, int32_t ver4);
int32_t CheckRequireDef();
void Draw(C4ID id, C4Facet &cgo, bool fSelected, int32_t iColor);
void Remove(C4Def *def);
bool Remove(C4ID id);
bool Reload(C4Def *pDef, DWORD dwLoadWhat, const char *szLanguage, C4SoundSystem *pSoundSystem = NULL);
bool Add(C4Def *ndef, bool fOverload);
void BuildTable();
void ResetIncludeDependencies(); // resets all pointers into foreign definitions caused by include chains
void CallEveryDefinition();
void Synchronize();
// callback from font renderer: get ID image
virtual bool GetFontImage(const char *szImageTag, CFacet &rOutImgFacet);
};
extern C4DefList Definitions;
inline C4Def *C4Id2Def(C4ID id)
{
return ::Definitions.ID2Def(id);
}
#endif

View File

@ -25,6 +25,7 @@
#include <C4IDList.h>
#include <C4Def.h>
#include <C4DefList.h>
#include <C4Application.h>
#include <C4GraphicsResource.h>

View File

@ -25,6 +25,7 @@
#include <C4InfoCore.h>
#include <C4Def.h>
#include <C4DefList.h>
#include <C4Random.h>
#include <C4RankSystem.h>
#include <C4Group.h>

View File

@ -30,6 +30,7 @@
#include <C4Include.h>
#include <C4Object.h>
#include <C4DefList.h>
#include <C4Effects.h>
#include <C4ObjectInfo.h>
#include <C4Physics.h>

View File

@ -26,6 +26,7 @@
#include <C4Include.h>
#include <C4ObjectInfo.h>
#include <C4DefList.h>
#include <C4Random.h>
#include <C4Components.h>
#include <C4Game.h>

View File

@ -24,6 +24,7 @@
#include <C4Include.h>
#include <C4ObjectInfoList.h>
#include <C4DefList.h>
#include <C4ObjectInfo.h>
#include <C4Components.h>
#include <C4Game.h>

View File

@ -27,6 +27,7 @@
#include <C4Include.h>
#include <C4ObjectList.h>
#include <C4DefList.h>
#include <C4Object.h>
#include <C4Application.h>
#include <C4Region.h>

View File

@ -27,6 +27,7 @@
#include <C4Aul.h>
#include <C4AulDefFunc.h>
#include <C4Command.h>
#include <C4DefList.h>
#include <C4GameMessage.h>
#include <C4GraphicsResource.h>
#include <C4Material.h>

View File

@ -29,6 +29,7 @@
#include <C4Player.h>
#include <C4Application.h>
#include <C4DefList.h>
#include <C4Object.h>
#include <C4ObjectInfo.h>
#include <C4Command.h>

View File

@ -27,6 +27,7 @@
#include <C4Include.h>
#include <C4Effects.h>
#include <C4DefList.h>
#include <C4Object.h>
#include <C4Random.h>
#include <C4Log.h>

View File

@ -22,6 +22,7 @@
#include <C4Include.h>
#include <C4FindObject.h>
#include <C4DefList.h>
#include <C4Object.h>
#include <C4Game.h>
#include <C4Random.h>

View File

@ -35,6 +35,7 @@
#include <C4AulDefFunc.h>
#include <C4AulExec.h>
#include <C4Command.h>
#include <C4DefList.h>
#include <C4Console.h>
#include <C4Game.h>
#include <C4GameObjects.h>

View File

@ -26,6 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <C4GameOverDlg.h>
#include <C4Def.h>
#include <C4DefList.h>
#include <C4Game.h>
#include <C4FullScreen.h>
#include <C4Player.h>

View File

@ -27,6 +27,7 @@
#include <C4Include.h>
#include <C4Gui.h>
#include <C4DefList.h>
#include <C4FullScreen.h>
#include <C4LoaderScreen.h>
#include <C4Application.h>

View File

@ -25,6 +25,7 @@
#include <C4Include.h>
#include <C4MainMenu.h>
#include <C4DefList.h>
#include <C4FullScreen.h>
#include <C4Viewport.h>
#include <C4Player.h>

View File

@ -24,6 +24,7 @@
#include <C4Include.h>
#include <C4Menu.h>
#include <C4DefList.h>
#include <C4Object.h>
#include <C4FullScreen.h>
#include <C4ObjectCom.h>

View File

@ -26,6 +26,7 @@
#include <C4Include.h>
#include <C4MouseControl.h>
#include <C4DefList.h>
#include <C4Viewport.h>
#include <C4Object.h>
#include <C4Command.h>

View File

@ -25,6 +25,7 @@
#include <C4Include.h>
#include <C4GraphicsResource.h>
#include <C4DefList.h>
#include <C4Log.h>
#include <C4Game.h>
#include <C4GraphicsSystem.h>

View File

@ -23,6 +23,7 @@
#include <C4Object.h>
#include <C4Effects.h>
#include <C4DefList.h>
typedef int32_t t_int;
typedef bool t_bool;

View File

@ -23,6 +23,7 @@
#include <C4Aul.h>
#include <C4Def.h>
#include <C4DefList.h>
#include <C4Material.h>
#include <C4Game.h>
#include <C4GameObjects.h>

View File

@ -22,9 +22,10 @@
#include <C4Include.h>
#include <C4Value.h>
#include <C4DefList.h>
#include <C4StringTable.h>
#include <C4ValueArray.h>
#include <C4Game.h>
#include <C4GameObjects.h>
#include <C4Object.h>