Skip to content

Commit

Permalink
Hacks for reading MQO data
Browse files Browse the repository at this point in the history
Co-Authored-By: Edmond Mondor <[email protected]>
  • Loading branch information
dpogue and Hazado committed Dec 25, 2024
1 parent 1712b06 commit 5542984
Show file tree
Hide file tree
Showing 14 changed files with 98 additions and 11 deletions.
16 changes: 16 additions & 0 deletions core/PRP/Avatar/plAGAnim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ void plAGAnim::read(hsStream* S, plResManager* mgr)
fStart = S->readFloat();
fEnd = S->readFloat();

// MQO data
if (S->getVer().isMoul() && pdUnifiedTypeMap::CurrentVersion(this->ClassIndex()) >= 5) {
fUnknownMQO1 = S->readFloat();
fUnknownMQO2 = S->readFloat();
}

clearApplicators();
fApps.resize(S->readInt());
for (size_t i=0; i<fApps.size(); i++) {
Expand All @@ -52,6 +58,12 @@ void plAGAnim::write(hsStream* S, plResManager* mgr)
S->writeFloat(fStart);
S->writeFloat(fEnd);

// MQO data
if (S->getVer().isMoul() && pdUnifiedTypeMap::CurrentVersion(this->ClassIndex()) >= 5) {
S->writeFloat(fUnknownMQO1);
S->writeFloat(fUnknownMQO2);
}

S->writeInt(fApps.size());
for (size_t i=0; i<fApps.size(); i++) {
mgr->WriteCreatable(S, fApps[i]);
Expand All @@ -70,6 +82,8 @@ void plAGAnim::IPrcWrite(pfPrcHelper* prc)
prc->writeParam("Name", fName);
prc->writeParam("Start", fStart);
prc->writeParam("End", fEnd);
prc->writeParam("UnknownMQO1", fUnknownMQO1);
prc->writeParam("UnknownMQO2", fUnknownMQO2);
prc->writeParam("EoaFlag", fEoaFlag);
prc->endTag(true);

Expand All @@ -93,6 +107,8 @@ void plAGAnim::IPrcParse(const pfPrcTag* tag, plResManager* mgr)
fName = tag->getParam("Name", "");
fStart = tag->getParam("Start", "0").to_float();
fEnd = tag->getParam("End", "0").to_float();
fUnknownMQO1 = tag->getParam("UnknownMQO1", "0").to_float();
fUnknownMQO2 = tag->getParam("UnknownMQO2", "0").to_float();
fEoaFlag = tag->getParam("EoaFlag", "0").to_uint();
} else if (tag->getName() == "Applicators") {
clearApplicators();
Expand Down
3 changes: 2 additions & 1 deletion core/PRP/Avatar/plAGAnim.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ class HSPLASMA_EXPORT plAGAnim : public plSynchedObject
protected:
std::vector<plAGApplicator*> fApps;
float fBlend, fStart, fEnd;
float fUnknownMQO1, fUnknownMQO2;
ST::string fName;
unsigned char fEoaFlag;

public:
plAGAnim() : fBlend(), fStart(), fEnd(), fEoaFlag() { }
plAGAnim() : fBlend(), fStart(), fEnd(), fUnknownMQO1(), fUnknownMQO2(), fEoaFlag() { }
~plAGAnim();

void read(hsStream* S, plResManager* mgr) HS_OVERRIDE;
Expand Down
5 changes: 4 additions & 1 deletion core/PRP/Avatar/plMultistageBehMod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ void plMultistageBehMod::read(hsStream* S, plResManager* mgr)

fFreezePhys = S->readBool();
fSmartSeek = S->readBool();
fReverseFBControlsOnRelease = S->readBool();

if (S->getVer() >= MAKE_VERSION(2, 0, 62, 12)) {
fReverseFBControlsOnRelease = S->readBool();
}

clearStages();
fStages.resize(S->readInt());
Expand Down
10 changes: 7 additions & 3 deletions core/PRP/KeyedObject/plLoadMask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@

void plLoadMask::read(hsStream* S)
{
unsigned char m = S->readByte();
fQuality[0] = (m >> 4) | 0xF0;
fQuality[1] = m | 0xF0;
if (S->getVer() < MAKE_VERSION(2, 0, 63, 0) && S->getVer().isValid()) {
S->readInt();
} else {
unsigned char m = S->readByte();
fQuality[0] = (m >> 4) | 0xF0;
fQuality[1] = m | 0xF0;
}
}

void plLoadMask::write(hsStream* S)
Expand Down
4 changes: 4 additions & 0 deletions core/PRP/KeyedObject/plUoid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ void plUoid::read(hsStream* S)
unsigned char contents = 0;
if (S->getVer() < MAKE_VERSION(2, 0, 63, 0) && S->getVer().isValid()) {
contents = kHasCloneIDs;

if (S->getVer() > MAKE_VERSION(2, 0, 62, 0)) {
contents |= kHasLoadMask;
}
} else {
contents = S->readByte();
}
Expand Down
15 changes: 15 additions & 0 deletions core/PRP/Message/plCameraMsg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ void plCameraMsg::read(hsStream* S, plResManager* mgr)
fNewCam = mgr->readKey(S);
fTriggerer = mgr->readKey(S);
fConfig.read(S);

if (S->getVer().isMqo()) {
fUnknownMQO.read(S);
}
}

void plCameraMsg::write(hsStream* S, plResManager* mgr)
Expand All @@ -166,6 +170,10 @@ void plCameraMsg::write(hsStream* S, plResManager* mgr)
mgr->writeKey(S, fNewCam);
mgr->writeKey(S, fTriggerer);
fConfig.write(S);

if (S->getVer().isMqo()) {
fUnknownMQO.write(S);
}
}

void plCameraMsg::IPrcWrite(pfPrcHelper* prc)
Expand All @@ -189,6 +197,10 @@ void plCameraMsg::IPrcWrite(pfPrcHelper* prc)
prc->closeTag();

fConfig.prcWrite(prc);

prc->writeSimpleTag("UnknownMQO");
fUnknownMQO.prcWrite(prc);
prc->closeTag();
}

void plCameraMsg::IPrcParse(const pfPrcTag* tag, plResManager* mgr)
Expand All @@ -207,6 +219,9 @@ void plCameraMsg::IPrcParse(const pfPrcTag* tag, plResManager* mgr)
fTriggerer = mgr->prcParseKey(tag->getFirstChild());
} else if (tag->getName() == "plCameraConfig") {
fConfig.prcParse(tag);
} else if (tag->getName() == "UnknownMQO") {
if (tag->hasChildren())
fUnknownMQO.prcParse(tag->getFirstChild());
} else {
plMessage::IPrcParse(tag, mgr);
}
Expand Down
1 change: 1 addition & 0 deletions core/PRP/Message/plCameraMsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class HSPLASMA_EXPORT plCameraMsg : public plMessage
plCameraConfig fConfig;
bool fActivated;
hsBitVector fCmd;
hsVector3 fUnknownMQO;

public:
plCameraMsg();
Expand Down
12 changes: 11 additions & 1 deletion core/PRP/Modifier/plOneShotMod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ void plOneShotMod::read(hsStream* S, plResManager* mgr)
fReversable = S->readBool();
fSmartSeek = S->readBool();

if (S->getVer() > 0x02006304) { /*TODO: Verify! */
if (S->getVer() > MAKE_VERSION(2, 0, 63, 4)) {
fNoSeek = S->readBool();
}

if (S->getVer().isMoul() && pdUnifiedTypeMap::CurrentVersion(this->ClassIndex()) >= 3) {
fUnknownMQO = S->readBool();
}
}

void plOneShotMod::write(hsStream* S, plResManager* mgr)
Expand All @@ -41,6 +45,10 @@ void plOneShotMod::write(hsStream* S, plResManager* mgr)
S->writeBool(fReversable);
S->writeBool(fSmartSeek);
S->writeBool(fNoSeek);

if (S->getVer().isMoul() && pdUnifiedTypeMap::CurrentVersion(this->ClassIndex()) >= 3) {
S->writeBool(fUnknownMQO);
}
}

void plOneShotMod::IPrcWrite(pfPrcHelper* prc)
Expand All @@ -54,6 +62,7 @@ void plOneShotMod::IPrcWrite(pfPrcHelper* prc)
prc->writeParam("Reversable", fReversable);
prc->writeParam("SmartSeek", fSmartSeek);
prc->writeParam("NoSeek", fNoSeek);
prc->writeParam("UnknownMQO", fUnknownMQO);
prc->endTag(true);
}

Expand All @@ -66,6 +75,7 @@ void plOneShotMod::IPrcParse(const pfPrcTag* tag, plResManager* mgr)
fReversable = tag->getParam("Reversable", "false").to_bool();
fSmartSeek = tag->getParam("SmartSeek", "false").to_bool();
fNoSeek = tag->getParam("NoSeek", "true").to_bool();
fUnknownMQO = tag->getParam("UnknownMQO", "false").to_bool();
} else {
plMultiModifier::IPrcParse(tag, mgr);
}
Expand Down
4 changes: 2 additions & 2 deletions core/PRP/Modifier/plOneShotMod.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ class HSPLASMA_EXPORT plOneShotMod : public plMultiModifier

protected:
ST::string fAnimName;
bool fDrivable, fReversable, fSmartSeek, fNoSeek;
bool fDrivable, fReversable, fSmartSeek, fNoSeek, fUnknownMQO;
float fSeekDuration;

public:
plOneShotMod()
: fDrivable(), fReversable(), fSmartSeek(), fNoSeek(true),
fSeekDuration() { }
fUnknownMQO(), fSeekDuration() { }

void read(hsStream* S, plResManager* mgr) HS_OVERRIDE;
void write(hsStream* S, plResManager* mgr) HS_OVERRIDE;
Expand Down
4 changes: 4 additions & 0 deletions core/PRP/Physics/plGenericPhysical.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ void plGenericPhysical::read(hsStream* S, plResManager* mgr)
{
plSynchedObject::read(S, mgr);

if (S->getVer() < MAKE_VERSION(2, 0, 63, 0)) {
return;
}

if (S->getVer().isUniversal())
fInternalType = (PhysType)S->readInt();
else if (S->getVer().isNewPlasma())
Expand Down
19 changes: 19 additions & 0 deletions core/PRP/plPageInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,25 @@ void plPageInfo::read(hsStream* S)
pdUnifiedTypeMap::ClassVersion(type, S->getVer()), ver);
}
}

// We have a slight problem with MQO data, because it is effectively
// indistinguishable from MOUL data. Most classes correctly use the
// type map to indicate when they have been updated, with the exception
// of plMessages embedded within ResponderModifiers. We have no way of
// knowing when there is extra data to read in those messages, and
// failing to read it correctly will corrupt the stream and probably
// crash.
//
// Since there is a finite set of MQO files, we're going to hackily
// check what Age we're reading here and compare the Age name and
// sequence prefix against known MQO Ages, and then set our stream
// version to pvMqo (which isn't actually accurate, but we need *some*
// way to track this when reading)
if ((fAge == "Courtyard" && fLocation.getSeqPrefix() == 3)
|| (fAge == "Forest" && fLocation.getSeqPrefix() == 5)
|| (fAge == "PortalWell" && fLocation.getSeqPrefix() == 1)) {
S->setVer(PlasmaVer::pvMqo);
}
}

plDebug::Debug("* Loading: {} ({})\n"
Expand Down
4 changes: 4 additions & 0 deletions core/ResManager/pdUnifiedTypeMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2187,6 +2187,7 @@ short pdUnifiedTypeMap::PlasmaToMapped(short typeIdx, PlasmaVer ver)
case PlasmaVer::pvPots:
return fPotSP2MTable[typeIdx];
case PlasmaVer::pvMoul:
case PlasmaVer::pvMqo:
return fLiveP2MTable[typeIdx];
case PlasmaVer::pvEoa:
return fEoaP2MTable[typeIdx];
Expand Down Expand Up @@ -2214,6 +2215,7 @@ short pdUnifiedTypeMap::MappedToPlasma(short typeIdx, PlasmaVer ver)
case PlasmaVer::pvPots:
return fPotSM2PTable[typeIdx];
case PlasmaVer::pvMoul:
case PlasmaVer::pvMqo:
return fLiveM2PTable[typeIdx];
case PlasmaVer::pvEoa:
return fEoaM2PTable[typeIdx];
Expand All @@ -2233,6 +2235,7 @@ short pdUnifiedTypeMap::ClassVersion(short typeIdx, PlasmaVer ver)

switch (ver) {
case PlasmaVer::pvMoul:
case PlasmaVer::pvMqo:
return fLiveVerTable[PlasmaToMapped(typeIdx, ver)];
case PlasmaVer::pvEoa:
return fEoaVerTable[PlasmaToMapped(typeIdx, ver)];
Expand All @@ -2259,6 +2262,7 @@ void pdUnifiedTypeMap::SetCurrentVersionBase(PlasmaVer ver)

switch (ver) {
case PlasmaVer::pvMoul:
case PlasmaVer::pvMqo:
base = fLiveVerTable;
break;
case PlasmaVer::pvEoa:
Expand Down
6 changes: 5 additions & 1 deletion core/Util/PlasmaVersions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ const char* PlasmaVer::GetVersionName(PlasmaVer ver)
case pvPots:
return "PotS/CC";
case pvMoul:
return "MOUL/MQO";
return "MOUL";
case pvMqo:
return "MQO";
case pvEoa:
return "Myst V/Crowthistle";
case pvHex:
Expand All @@ -49,6 +51,8 @@ PlasmaVer PlasmaVer::GetSafestVersion(PlasmaVer ver)
return pvPots;
else if (ver <= pvMoul)
return pvMoul;
else if (ver == pvMqo)
return pvMqo;
else if (ver == pvEoa)
return pvEoa;
else if (ver == pvHex)
Expand Down
6 changes: 4 additions & 2 deletions core/Util/PlasmaVersions.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class HSPLASMA_EXPORT PlasmaVer
pvPrime = MAKE_VERSION(2, 0, 63, 11),
pvPots = MAKE_VERSION(2, 0, 63, 12),
pvMoul = MAKE_VERSION(2, 0, 70, 0),
pvMqo = MAKE_VERSION(2, 0, 70, 1),
pvEoa = MAKE_VERSION(2, 1, 6, 10),
pvHex = MAKE_VERSION(3, 0, 0, 0),
pvUniversal = -1,
Expand Down Expand Up @@ -115,7 +116,8 @@ class HSPLASMA_EXPORT PlasmaVer

bool isPrime() const { return fVersion == pvPrime; }
bool isPots() const { return fVersion == pvPots; }
bool isMoul() const { return fVersion == pvMoul; }
bool isMoul() const { return fVersion == pvMoul || fVersion == pvMqo; }
bool isMqo() const { return fVersion == pvMqo; }
bool isEoa() const { return fVersion == pvEoa; }
bool isHexIsle() const { return fVersion == pvHex; }

Expand All @@ -127,7 +129,7 @@ class HSPLASMA_EXPORT PlasmaVer
bool isSafeVer() const
{
return fVersion == pvPrime || fVersion == pvPots || fVersion == pvMoul
|| fVersion == pvEoa || fVersion == pvHex;
|| fVersion == pvMqo || fVersion == pvEoa || fVersion == pvHex;
}

static const char* GetVersionName(PlasmaVer ver);
Expand Down

0 comments on commit 5542984

Please sign in to comment.