mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 12:11:25 +00:00
Fix A_ChangeModel serialization
I overlooked this part on my first A_ChangeModel fix
This commit is contained in:
parent
631eb5847b
commit
ce479e09ff
10 changed files with 95 additions and 76 deletions
|
@ -294,6 +294,21 @@ bool FSerializer::BeginObject(const char *name)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
bool FSerializer::HasKey(const char* name)
|
||||||
|
{
|
||||||
|
if (isReading())
|
||||||
|
{
|
||||||
|
return r->FindKey(name) != nullptr;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
bool FSerializer::HasObject(const char* name)
|
bool FSerializer::HasObject(const char* name)
|
||||||
{
|
{
|
||||||
if (isReading())
|
if (isReading())
|
||||||
|
|
|
@ -91,6 +91,7 @@ public:
|
||||||
void ReadObjects(bool hubtravel);
|
void ReadObjects(bool hubtravel);
|
||||||
bool BeginObject(const char *name);
|
bool BeginObject(const char *name);
|
||||||
void EndObject();
|
void EndObject();
|
||||||
|
bool HasKey(const char* name);
|
||||||
bool HasObject(const char* name);
|
bool HasObject(const char* name);
|
||||||
bool BeginArray(const char *name);
|
bool BeginArray(const char *name);
|
||||||
void EndArray();
|
void EndArray();
|
||||||
|
@ -245,6 +246,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FSoundID &sid, FSoundI
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, FString &sid, FString *def);
|
FSerializer &Serialize(FSerializer &arc, const char *key, FString &sid, FString *def);
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &sid, NumericValue *def);
|
FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &sid, NumericValue *def);
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, struct ModelOverride &mo, struct ModelOverride *def);
|
FSerializer &Serialize(FSerializer &arc, const char *key, struct ModelOverride &mo, struct ModelOverride *def);
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, struct AnimModelOverride &mo, struct AnimModelOverride *def);
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, struct AnimOverride &ao, struct AnimOverride *def);
|
FSerializer &Serialize(FSerializer &arc, const char *key, struct AnimOverride &ao, struct AnimOverride *def);
|
||||||
FSerializer& Serialize(FSerializer& arc, const char* key, FTranslationID& value, FTranslationID* defval);
|
FSerializer& Serialize(FSerializer& arc, const char* key, FTranslationID& value, FTranslationID* defval);
|
||||||
|
|
||||||
|
@ -259,6 +261,16 @@ FSerializer &Serialize(FSerializer &arc, const char *key, T *&value, T **)
|
||||||
return arc;
|
return arc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class A, class B>
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, std::pair<A, B> &value, std::pair<A, B> *def)
|
||||||
|
{
|
||||||
|
arc.BeginObject(key);
|
||||||
|
Serialize(arc, "first", value.first, def ? &def->first : nullptr);
|
||||||
|
Serialize(arc, "second", value.second, def ? &def->second : nullptr);
|
||||||
|
arc.EndObject();
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
template<class T, class TT>
|
template<class T, class TT>
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, TArray<T, TT> &value, TArray<T, TT> *def)
|
FSerializer &Serialize(FSerializer &arc, const char *key, TArray<T, TT> &value, TArray<T, TT> *def)
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,8 +43,6 @@
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
#include "modelrenderer.h"
|
#include "modelrenderer.h"
|
||||||
|
|
||||||
|
|
||||||
TArray<FString> savedModelFiles;
|
|
||||||
TDeletingArray<FModel*> Models;
|
TDeletingArray<FModel*> Models;
|
||||||
TArray<FSpriteModelFrame> SpriteModelFrames;
|
TArray<FSpriteModelFrame> SpriteModelFrames;
|
||||||
TMap<void*, FSpriteModelFrame> BaseSpriteModelFrames;
|
TMap<void*, FSpriteModelFrame> BaseSpriteModelFrames;
|
||||||
|
@ -160,7 +158,7 @@ unsigned FindModel(const char * path, const char * modelfile, bool silent)
|
||||||
|
|
||||||
for(unsigned i = 0; i< Models.Size(); i++)
|
for(unsigned i = 0; i< Models.Size(); i++)
|
||||||
{
|
{
|
||||||
if (!Models[i]->mFileName.CompareNoCase(fullname)) return i;
|
if (Models[i]->mFileName.CompareNoCase(fullname) == 0) return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto len = fileSystem.FileLength(lump);
|
auto len = fileSystem.FileLength(lump);
|
||||||
|
@ -236,6 +234,7 @@ unsigned FindModel(const char * path, const char * modelfile, bool silent)
|
||||||
}
|
}
|
||||||
// The vertex buffer cannot be initialized here because this gets called before OpenGL is initialized
|
// The vertex buffer cannot be initialized here because this gets called before OpenGL is initialized
|
||||||
model->mFileName = fullname;
|
model->mFileName = fullname;
|
||||||
|
model->mFilePath = {path, modelfile};
|
||||||
return Models.Push(model);
|
return Models.Push(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ struct FSpriteModelFrame;
|
||||||
|
|
||||||
FTextureID LoadSkin(const char* path, const char* fn);
|
FTextureID LoadSkin(const char* path, const char* fn);
|
||||||
void FlushModels();
|
void FlushModels();
|
||||||
extern TArray<FString> savedModelFiles;
|
|
||||||
extern TDeletingArray<FModel*> Models;
|
extern TDeletingArray<FModel*> Models;
|
||||||
extern TArray<FSpriteModelFrame> SpriteModelFrames;
|
extern TArray<FSpriteModelFrame> SpriteModelFrames;
|
||||||
extern TMap<void*, FSpriteModelFrame> BaseSpriteModelFrames;
|
extern TMap<void*, FSpriteModelFrame> BaseSpriteModelFrames;
|
||||||
|
@ -76,6 +76,7 @@ enum EFrameError
|
||||||
class FModel
|
class FModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FModel();
|
FModel();
|
||||||
virtual ~FModel();
|
virtual ~FModel();
|
||||||
|
|
||||||
|
@ -100,7 +101,9 @@ public:
|
||||||
void DestroyVertexBuffer();
|
void DestroyVertexBuffer();
|
||||||
|
|
||||||
bool hasSurfaces = false;
|
bool hasSurfaces = false;
|
||||||
|
|
||||||
FString mFileName;
|
FString mFileName;
|
||||||
|
std::pair<FString, FString> mFilePath;
|
||||||
|
|
||||||
FSpriteModelFrame *baseFrame;
|
FSpriteModelFrame *baseFrame;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -2148,14 +2148,6 @@ void G_DoLoadGame ()
|
||||||
|
|
||||||
BackupSaveName = savename;
|
BackupSaveName = savename;
|
||||||
|
|
||||||
//Push any added models from A_ChangeModel
|
|
||||||
for (auto& smf : savedModelFiles)
|
|
||||||
{
|
|
||||||
FString modelFilePath = smf.Left(smf.LastIndexOf("/")+1);
|
|
||||||
FString modelFileName = smf.Right(smf.Len() - smf.Left(smf.LastIndexOf("/") + 1).Len());
|
|
||||||
FindModel(modelFilePath.GetChars(), modelFileName.GetChars());
|
|
||||||
}
|
|
||||||
|
|
||||||
// At this point, the GC threshold is likely a lot higher than the
|
// At this point, the GC threshold is likely a lot higher than the
|
||||||
// amount of memory in use, so bring it down now by starting a
|
// amount of memory in use, so bring it down now by starting a
|
||||||
// collection.
|
// collection.
|
||||||
|
|
|
@ -1013,8 +1013,7 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
|
||||||
("scrolls", Scrolls)
|
("scrolls", Scrolls)
|
||||||
("automap", automap)
|
("automap", automap)
|
||||||
("interpolator", interpolator)
|
("interpolator", interpolator)
|
||||||
("frozenstate", frozenstate)
|
("frozenstate", frozenstate);
|
||||||
("savedModelFiles", savedModelFiles);
|
|
||||||
|
|
||||||
|
|
||||||
// Hub transitions must keep the current total time
|
// Hub transitions must keep the current total time
|
||||||
|
|
|
@ -719,6 +719,16 @@ struct ModelOverride
|
||||||
TArray<FTextureID> surfaceSkinIDs;
|
TArray<FTextureID> surfaceSkinIDs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AnimModelOverride
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
|
||||||
|
AnimModelOverride() = default;
|
||||||
|
|
||||||
|
AnimModelOverride(int i) : id(i) {}
|
||||||
|
operator int() { return id; }
|
||||||
|
};
|
||||||
|
|
||||||
enum EModelDataFlags
|
enum EModelDataFlags
|
||||||
{
|
{
|
||||||
MODELDATA_HADMODEL = 1 << 0,
|
MODELDATA_HADMODEL = 1 << 0,
|
||||||
|
@ -729,14 +739,14 @@ class DActorModelData : public DObject
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(DActorModelData, DObject);
|
DECLARE_CLASS(DActorModelData, DObject);
|
||||||
public:
|
public:
|
||||||
PClass * modelDef;
|
PClass * modelDef;
|
||||||
TArray<ModelOverride> models;
|
TArray<ModelOverride> models;
|
||||||
TArray<FTextureID> skinIDs;
|
TArray<FTextureID> skinIDs;
|
||||||
TArray<int> animationIDs;
|
TArray<AnimModelOverride> animationIDs;
|
||||||
TArray<int> modelFrameGenerators;
|
TArray<int> modelFrameGenerators;
|
||||||
int flags;
|
int flags;
|
||||||
int overrideFlagsSet;
|
int overrideFlagsSet;
|
||||||
int overrideFlagsClear;
|
int overrideFlagsClear;
|
||||||
|
|
||||||
AnimOverride curAnim;
|
AnimOverride curAnim;
|
||||||
AnimOverride prevAnim; // used for interpolation when switching anims
|
AnimOverride prevAnim; // used for interpolation when switching anims
|
||||||
|
|
|
@ -5438,57 +5438,6 @@ void ChangeModelNative(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//[SM] - We need to serialize file paths and model names so that they are pushed on loading save files. Likewise, let's not include models that were already parsed when initialized.
|
|
||||||
if (queryModel >= 0)
|
|
||||||
{
|
|
||||||
FString fullName;
|
|
||||||
fullName.Format("%s%s", modelpath.GetChars(), model.GetChars());
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
for (auto &m : savedModelFiles)
|
|
||||||
{
|
|
||||||
if(m.CompareNoCase(fullName) == 0)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!found) for (auto &m : Models)
|
|
||||||
{
|
|
||||||
if (m->mFileName.CompareNoCase(fullName) == 0)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!found) savedModelFiles.Push(fullName);
|
|
||||||
}
|
|
||||||
//Same for animations
|
|
||||||
if (queryAnimation >= 0)
|
|
||||||
{
|
|
||||||
FString fullName;
|
|
||||||
fullName.Format("%s%s", animationpath.GetChars(), animation.GetChars());
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
for (auto &m : savedModelFiles)
|
|
||||||
{
|
|
||||||
if(m.CompareNoCase(fullName) == 0)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!found) for (auto &m : Models)
|
|
||||||
{
|
|
||||||
if (m->mFileName.CompareNoCase(fullName) == 0)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!found) savedModelFiles.Push(fullName);
|
|
||||||
}
|
|
||||||
|
|
||||||
CleanupModelData(mobj);
|
CleanupModelData(mobj);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -101,6 +101,7 @@
|
||||||
#include "fragglescript/t_fs.h"
|
#include "fragglescript/t_fs.h"
|
||||||
#include "shadowinlines.h"
|
#include "shadowinlines.h"
|
||||||
#include "d_net.h"
|
#include "d_net.h"
|
||||||
|
#include "model.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -1387,18 +1388,57 @@ bool AActor::Massacre ()
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void SerializeModelID(FSerializer &arc, const char *key, int &id)
|
||||||
|
{ // TODO: make it a proper serializable type (FModelID) instead of an int
|
||||||
|
if(arc.isWriting())
|
||||||
|
{
|
||||||
|
if(id >= 0)
|
||||||
|
{
|
||||||
|
arc(key, Models[id]->mFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(arc.HasKey(key))
|
||||||
|
{
|
||||||
|
std::pair<FString, FString> modelFile;
|
||||||
|
arc(key, modelFile);
|
||||||
|
|
||||||
|
id = FindModel(modelFile.first.GetChars(), modelFile.second.GetChars(), true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
id = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, ModelOverride &mo, ModelOverride *def)
|
FSerializer &Serialize(FSerializer &arc, const char *key, ModelOverride &mo, ModelOverride *def)
|
||||||
{
|
{
|
||||||
arc.BeginObject(key);
|
arc.BeginObject(key);
|
||||||
arc("modelID", mo.modelID);
|
SerializeModelID(arc, "model", mo.modelID);
|
||||||
arc("surfaceSkinIDs", mo.surfaceSkinIDs);
|
arc("surfaceSkinIDs", mo.surfaceSkinIDs);
|
||||||
arc.EndObject();
|
arc.EndObject();
|
||||||
return arc;
|
return arc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, AnimModelOverride &amo, AnimModelOverride *def)
|
||||||
|
{
|
||||||
|
int ok = arc.BeginObject(key);
|
||||||
|
if(arc.isReading() && !ok)
|
||||||
|
{
|
||||||
|
amo.id = -1;
|
||||||
|
}
|
||||||
|
else if(ok)
|
||||||
|
{
|
||||||
|
SerializeModelID(arc, "model", amo.id);
|
||||||
|
arc.EndObject();
|
||||||
|
}
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, struct AnimOverride &ao, struct AnimOverride *def)
|
FSerializer &Serialize(FSerializer &arc, const char *key, struct AnimOverride &ao, struct AnimOverride *def)
|
||||||
{
|
{
|
||||||
//TODO
|
|
||||||
arc.BeginObject(key);
|
arc.BeginObject(key);
|
||||||
arc("firstFrame", ao.firstFrame);
|
arc("firstFrame", ao.firstFrame);
|
||||||
arc("lastFrame", ao.lastFrame);
|
arc("lastFrame", ao.lastFrame);
|
||||||
|
|
|
@ -506,7 +506,7 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
|
||||||
skinid = smf->skinIDs[i];
|
skinid = smf->skinIDs[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modelid >= 0)
|
if (modelid >= 0 && modelid < Models.size())
|
||||||
{
|
{
|
||||||
FModel * mdl = Models[modelid];
|
FModel * mdl = Models[modelid];
|
||||||
auto tex = skinid.isValid() ? TexMan.GetGameTexture(skinid, true) : nullptr;
|
auto tex = skinid.isValid() ? TexMan.GetGameTexture(skinid, true) : nullptr;
|
||||||
|
|
Loading…
Reference in a new issue