Skip to content

Commit 6b712cb

Browse files
dpogueHazado
andcommitted
Hacks for reading MQO data
Co-Authored-By: Edmond Mondor <[email protected]>
1 parent 4451567 commit 6b712cb

14 files changed

+98
-11
lines changed

core/PRP/Avatar/plAGAnim.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ void plAGAnim::read(hsStream* S, plResManager* mgr)
3131
fStart = S->readFloat();
3232
fEnd = S->readFloat();
3333

34+
// MQO data
35+
if (S->getVer().isMoul() && pdUnifiedTypeMap::CurrentVersion(this->ClassIndex()) >= 5) {
36+
fUnknownMQO1 = S->readFloat();
37+
fUnknownMQO2 = S->readFloat();
38+
}
39+
3440
clearApplicators();
3541
fApps.resize(S->readInt());
3642
for (size_t i=0; i<fApps.size(); i++) {
@@ -52,6 +58,12 @@ void plAGAnim::write(hsStream* S, plResManager* mgr)
5258
S->writeFloat(fStart);
5359
S->writeFloat(fEnd);
5460

61+
// MQO data
62+
if (S->getVer().isMoul() && pdUnifiedTypeMap::CurrentVersion(this->ClassIndex()) >= 5) {
63+
S->writeFloat(fUnknownMQO1);
64+
S->writeFloat(fUnknownMQO2);
65+
}
66+
5567
S->writeInt(fApps.size());
5668
for (size_t i=0; i<fApps.size(); i++) {
5769
mgr->WriteCreatable(S, fApps[i]);
@@ -70,6 +82,8 @@ void plAGAnim::IPrcWrite(pfPrcHelper* prc)
7082
prc->writeParam("Name", fName);
7183
prc->writeParam("Start", fStart);
7284
prc->writeParam("End", fEnd);
85+
prc->writeParam("UnknownMQO1", fUnknownMQO1);
86+
prc->writeParam("UnknownMQO2", fUnknownMQO2);
7387
prc->writeParam("EoaFlag", fEoaFlag);
7488
prc->endTag(true);
7589

@@ -93,6 +107,8 @@ void plAGAnim::IPrcParse(const pfPrcTag* tag, plResManager* mgr)
93107
fName = tag->getParam("Name", "");
94108
fStart = tag->getParam("Start", "0").to_float();
95109
fEnd = tag->getParam("End", "0").to_float();
110+
fUnknownMQO1 = tag->getParam("UnknownMQO1", "0").to_float();
111+
fUnknownMQO2 = tag->getParam("UnknownMQO2", "0").to_float();
96112
fEoaFlag = tag->getParam("EoaFlag", "0").to_uint();
97113
} else if (tag->getName() == "Applicators") {
98114
clearApplicators();

core/PRP/Avatar/plAGAnim.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ class HSPLASMA_EXPORT plAGAnim : public plSynchedObject
3333
protected:
3434
std::vector<plAGApplicator*> fApps;
3535
float fBlend, fStart, fEnd;
36+
float fUnknownMQO1, fUnknownMQO2;
3637
ST::string fName;
3738
unsigned char fEoaFlag;
3839

3940
public:
40-
plAGAnim() : fBlend(), fStart(), fEnd(), fEoaFlag() { }
41+
plAGAnim() : fBlend(), fStart(), fEnd(), fUnknownMQO1(), fUnknownMQO2(), fEoaFlag() { }
4142
~plAGAnim();
4243

4344
void read(hsStream* S, plResManager* mgr) HS_OVERRIDE;

core/PRP/Avatar/plMultistageBehMod.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ void plMultistageBehMod::read(hsStream* S, plResManager* mgr)
2828

2929
fFreezePhys = S->readBool();
3030
fSmartSeek = S->readBool();
31-
fReverseFBControlsOnRelease = S->readBool();
31+
32+
if (S->getVer() >= MAKE_VERSION(2, 0, 62, 12)) {
33+
fReverseFBControlsOnRelease = S->readBool();
34+
}
3235

3336
clearStages();
3437
fStages.resize(S->readInt());

core/PRP/KeyedObject/plLoadMask.cpp

+7-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@
1818

1919
void plLoadMask::read(hsStream* S)
2020
{
21-
unsigned char m = S->readByte();
22-
fQuality[0] = (m >> 4) | 0xF0;
23-
fQuality[1] = m | 0xF0;
21+
if (S->getVer() < MAKE_VERSION(2, 0, 63, 0) && S->getVer().isValid()) {
22+
S->readInt();
23+
} else {
24+
unsigned char m = S->readByte();
25+
fQuality[0] = (m >> 4) | 0xF0;
26+
fQuality[1] = m | 0xF0;
27+
}
2428
}
2529

2630
void plLoadMask::write(hsStream* S)

core/PRP/KeyedObject/plUoid.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ void plUoid::read(hsStream* S)
4949
unsigned char contents = 0;
5050
if (S->getVer() < MAKE_VERSION(2, 0, 63, 0) && S->getVer().isValid()) {
5151
contents = kHasCloneIDs;
52+
53+
if (S->getVer() > MAKE_VERSION(2, 0, 62, 0)) {
54+
contents |= kHasLoadMask;
55+
}
5256
} else {
5357
contents = S->readByte();
5458
}

core/PRP/Message/plCameraMsg.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ void plCameraMsg::read(hsStream* S, plResManager* mgr)
154154
fNewCam = mgr->readKey(S);
155155
fTriggerer = mgr->readKey(S);
156156
fConfig.read(S);
157+
158+
if (S->getVer().isMqo()) {
159+
fUnknownMQO.read(S);
160+
}
157161
}
158162

159163
void plCameraMsg::write(hsStream* S, plResManager* mgr)
@@ -166,6 +170,10 @@ void plCameraMsg::write(hsStream* S, plResManager* mgr)
166170
mgr->writeKey(S, fNewCam);
167171
mgr->writeKey(S, fTriggerer);
168172
fConfig.write(S);
173+
174+
if (S->getVer().isMqo()) {
175+
fUnknownMQO.write(S);
176+
}
169177
}
170178

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

191199
fConfig.prcWrite(prc);
200+
201+
prc->writeSimpleTag("UnknownMQO");
202+
fUnknownMQO.prcWrite(prc);
203+
prc->closeTag();
192204
}
193205

194206
void plCameraMsg::IPrcParse(const pfPrcTag* tag, plResManager* mgr)
@@ -207,6 +219,9 @@ void plCameraMsg::IPrcParse(const pfPrcTag* tag, plResManager* mgr)
207219
fTriggerer = mgr->prcParseKey(tag->getFirstChild());
208220
} else if (tag->getName() == "plCameraConfig") {
209221
fConfig.prcParse(tag);
222+
} else if (tag->getName() == "UnknownMQO") {
223+
if (tag->hasChildren())
224+
fUnknownMQO.prcParse(tag->getFirstChild());
210225
} else {
211226
plMessage::IPrcParse(tag, mgr);
212227
}

core/PRP/Message/plCameraMsg.h

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class HSPLASMA_EXPORT plCameraMsg : public plMessage
9898
plCameraConfig fConfig;
9999
bool fActivated;
100100
hsBitVector fCmd;
101+
hsVector3 fUnknownMQO;
101102

102103
public:
103104
plCameraMsg();

core/PRP/Modifier/plOneShotMod.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@ void plOneShotMod::read(hsStream* S, plResManager* mgr)
2626
fReversable = S->readBool();
2727
fSmartSeek = S->readBool();
2828

29-
if (S->getVer() > 0x02006304) { /*TODO: Verify! */
29+
if (S->getVer() > MAKE_VERSION(2, 0, 63, 4)) {
3030
fNoSeek = S->readBool();
3131
}
32+
33+
if (S->getVer().isMoul() && pdUnifiedTypeMap::CurrentVersion(this->ClassIndex()) >= 3) {
34+
fUnknownMQO = S->readBool();
35+
}
3236
}
3337

3438
void plOneShotMod::write(hsStream* S, plResManager* mgr)
@@ -41,6 +45,10 @@ void plOneShotMod::write(hsStream* S, plResManager* mgr)
4145
S->writeBool(fReversable);
4246
S->writeBool(fSmartSeek);
4347
S->writeBool(fNoSeek);
48+
49+
if (S->getVer().isMoul() && pdUnifiedTypeMap::CurrentVersion(this->ClassIndex()) >= 3) {
50+
S->writeBool(fUnknownMQO);
51+
}
4452
}
4553

4654
void plOneShotMod::IPrcWrite(pfPrcHelper* prc)
@@ -54,6 +62,7 @@ void plOneShotMod::IPrcWrite(pfPrcHelper* prc)
5462
prc->writeParam("Reversable", fReversable);
5563
prc->writeParam("SmartSeek", fSmartSeek);
5664
prc->writeParam("NoSeek", fNoSeek);
65+
prc->writeParam("UnknownMQO", fUnknownMQO);
5766
prc->endTag(true);
5867
}
5968

@@ -66,6 +75,7 @@ void plOneShotMod::IPrcParse(const pfPrcTag* tag, plResManager* mgr)
6675
fReversable = tag->getParam("Reversable", "false").to_bool();
6776
fSmartSeek = tag->getParam("SmartSeek", "false").to_bool();
6877
fNoSeek = tag->getParam("NoSeek", "true").to_bool();
78+
fUnknownMQO = tag->getParam("UnknownMQO", "false").to_bool();
6979
} else {
7080
plMultiModifier::IPrcParse(tag, mgr);
7181
}

core/PRP/Modifier/plOneShotMod.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ class HSPLASMA_EXPORT plOneShotMod : public plMultiModifier
2525

2626
protected:
2727
ST::string fAnimName;
28-
bool fDrivable, fReversable, fSmartSeek, fNoSeek;
28+
bool fDrivable, fReversable, fSmartSeek, fNoSeek, fUnknownMQO;
2929
float fSeekDuration;
3030

3131
public:
3232
plOneShotMod()
3333
: fDrivable(), fReversable(), fSmartSeek(), fNoSeek(true),
34-
fSeekDuration() { }
34+
fUnknownMQO(), fSeekDuration() { }
3535

3636
void read(hsStream* S, plResManager* mgr) HS_OVERRIDE;
3737
void write(hsStream* S, plResManager* mgr) HS_OVERRIDE;

core/PRP/Physics/plGenericPhysical.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ void plGenericPhysical::read(hsStream* S, plResManager* mgr)
9999
{
100100
plSynchedObject::read(S, mgr);
101101

102+
if (S->getVer() < MAKE_VERSION(2, 0, 63, 0)) {
103+
return;
104+
}
105+
102106
if (S->getVer().isUniversal())
103107
fInternalType = (PhysType)S->readInt();
104108
else if (S->getVer().isNewPlasma())

core/PRP/plPageInfo.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,25 @@ void plPageInfo::read(hsStream* S)
133133
pdUnifiedTypeMap::ClassVersion(type, S->getVer()), ver);
134134
}
135135
}
136+
137+
// We have a slight problem with MQO data, because it is effectively
138+
// indistinguishable from MOUL data. Most classes correctly use the
139+
// type map to indicate when they have been updated, with the exception
140+
// of plMessages embedded within ResponderModifiers. We have no way of
141+
// knowing when there is extra data to read in those messages, and
142+
// failing to read it correctly will corrupt the stream and probably
143+
// crash.
144+
//
145+
// Since there is a finite set of MQO files, we're going to hackily
146+
// check what Age we're reading here and compare the Age name and
147+
// sequence prefix against known MQO Ages, and then set our stream
148+
// version to pvMqo (which isn't actually accurate, but we need *some*
149+
// way to track this when reading)
150+
if ((fAge == "Courtyard" && fLocation.getSeqPrefix() == 3)
151+
|| (fAge == "Forest" && fLocation.getSeqPrefix() == 5)
152+
|| (fAge == "PortalWell" && fLocation.getSeqPrefix() == 1)) {
153+
S->setVer(PlasmaVer::pvMqo);
154+
}
136155
}
137156

138157
plDebug::Debug("* Loading: {} ({})\n"

core/ResManager/pdUnifiedTypeMap.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -2187,6 +2187,7 @@ short pdUnifiedTypeMap::PlasmaToMapped(short typeIdx, PlasmaVer ver)
21872187
case PlasmaVer::pvPots:
21882188
return fPotSP2MTable[typeIdx];
21892189
case PlasmaVer::pvMoul:
2190+
case PlasmaVer::pvMqo:
21902191
return fLiveP2MTable[typeIdx];
21912192
case PlasmaVer::pvEoa:
21922193
return fEoaP2MTable[typeIdx];
@@ -2214,6 +2215,7 @@ short pdUnifiedTypeMap::MappedToPlasma(short typeIdx, PlasmaVer ver)
22142215
case PlasmaVer::pvPots:
22152216
return fPotSM2PTable[typeIdx];
22162217
case PlasmaVer::pvMoul:
2218+
case PlasmaVer::pvMqo:
22172219
return fLiveM2PTable[typeIdx];
22182220
case PlasmaVer::pvEoa:
22192221
return fEoaM2PTable[typeIdx];
@@ -2233,6 +2235,7 @@ short pdUnifiedTypeMap::ClassVersion(short typeIdx, PlasmaVer ver)
22332235

22342236
switch (ver) {
22352237
case PlasmaVer::pvMoul:
2238+
case PlasmaVer::pvMqo:
22362239
return fLiveVerTable[PlasmaToMapped(typeIdx, ver)];
22372240
case PlasmaVer::pvEoa:
22382241
return fEoaVerTable[PlasmaToMapped(typeIdx, ver)];
@@ -2259,6 +2262,7 @@ void pdUnifiedTypeMap::SetCurrentVersionBase(PlasmaVer ver)
22592262

22602263
switch (ver) {
22612264
case PlasmaVer::pvMoul:
2265+
case PlasmaVer::pvMqo:
22622266
base = fLiveVerTable;
22632267
break;
22642268
case PlasmaVer::pvEoa:

core/Util/PlasmaVersions.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ const char* PlasmaVer::GetVersionName(PlasmaVer ver)
2424
case pvPots:
2525
return "PotS/CC";
2626
case pvMoul:
27-
return "MOUL/MQO";
27+
return "MOUL";
28+
case pvMqo:
29+
return "MQO";
2830
case pvEoa:
2931
return "Myst V/Crowthistle";
3032
case pvHex:
@@ -49,6 +51,8 @@ PlasmaVer PlasmaVer::GetSafestVersion(PlasmaVer ver)
4951
return pvPots;
5052
else if (ver <= pvMoul)
5153
return pvMoul;
54+
else if (ver == pvMqo)
55+
return pvMqo;
5256
else if (ver == pvEoa)
5357
return pvEoa;
5458
else if (ver == pvHex)

core/Util/PlasmaVersions.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class HSPLASMA_EXPORT PlasmaVer
8585
pvPrime = MAKE_VERSION(2, 0, 63, 11),
8686
pvPots = MAKE_VERSION(2, 0, 63, 12),
8787
pvMoul = MAKE_VERSION(2, 0, 70, 0),
88+
pvMqo = MAKE_VERSION(2, 0, 70, 1),
8889
pvEoa = MAKE_VERSION(2, 1, 6, 10),
8990
pvHex = MAKE_VERSION(3, 0, 0, 0),
9091
pvUniversal = -1,
@@ -115,7 +116,8 @@ class HSPLASMA_EXPORT PlasmaVer
115116

116117
bool isPrime() const { return fVersion == pvPrime; }
117118
bool isPots() const { return fVersion == pvPots; }
118-
bool isMoul() const { return fVersion == pvMoul; }
119+
bool isMoul() const { return fVersion == pvMoul || fVersion == pvMqo; }
120+
bool isMqo() const { return fVersion == pvMqo; }
119121
bool isEoa() const { return fVersion == pvEoa; }
120122
bool isHexIsle() const { return fVersion == pvHex; }
121123

@@ -127,7 +129,7 @@ class HSPLASMA_EXPORT PlasmaVer
127129
bool isSafeVer() const
128130
{
129131
return fVersion == pvPrime || fVersion == pvPots || fVersion == pvMoul
130-
|| fVersion == pvEoa || fVersion == pvHex;
132+
|| fVersion == pvMqo || fVersion == pvEoa || fVersion == pvHex;
131133
}
132134

133135
static const char* GetVersionName(PlasmaVer ver);

0 commit comments

Comments
 (0)