mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 13:50:13 +00:00
MTROPOLIS: Add more features required by MTI
This commit is contained in:
parent
ccfe7fae69
commit
51221b846e
@ -117,6 +117,7 @@ bool isModifier(DataObjectType type) {
|
||||
case kCursorModifierV1:
|
||||
case kGradientModifier:
|
||||
case kColorTableModifier:
|
||||
case kSoundFadeModifier:
|
||||
case kSaveAndRestoreModifier:
|
||||
case kCompoundVariableModifier:
|
||||
case kBooleanVariableModifier:
|
||||
@ -126,8 +127,8 @@ bool isModifier(DataObjectType type) {
|
||||
case kPointVariableModifier:
|
||||
case kFloatingPointVariableModifier:
|
||||
case kStringVariableModifier:
|
||||
case kObjectReferenceVariableModifierV1:
|
||||
case kPlugInModifier:
|
||||
case kSoundFadeModifier:
|
||||
case kDebris:
|
||||
return true;
|
||||
default:
|
||||
@ -1267,11 +1268,12 @@ DataReadErrorCode SetModifier::load(DataReader &reader) {
|
||||
}
|
||||
|
||||
AliasModifier::AliasModifier()
|
||||
: modifierFlags(0), sizeIncludingTag(0), aliasIndexPlusOne(0), unknown1(0), unknown2(0), lengthOfName(0), guid(0), editorLayoutPosition(Point::createDefault()) {
|
||||
: modifierFlags(0), sizeIncludingTag(0), aliasIndexPlusOne(0), unknown1(0), unknown2(0)
|
||||
, lengthOfName(0), guid(0), editorLayoutPosition(Point::createDefault()), haveGUID(false) {
|
||||
}
|
||||
|
||||
DataReadErrorCode AliasModifier::load(DataReader& reader) {
|
||||
if (_revision != 2)
|
||||
if (_revision > 2)
|
||||
return kDataReadErrorUnsupportedRevision;
|
||||
|
||||
if (!reader.readU32(modifierFlags)
|
||||
@ -1280,9 +1282,19 @@ DataReadErrorCode AliasModifier::load(DataReader& reader) {
|
||||
|| !reader.readU32(unknown1)
|
||||
|| !reader.readU32(unknown2)
|
||||
|| !reader.readU16(lengthOfName)
|
||||
|| !editorLayoutPosition.load(reader)
|
||||
|| !reader.readU32(guid)
|
||||
|| !reader.readTerminatedStr(name, lengthOfName))
|
||||
|| !editorLayoutPosition.load(reader))
|
||||
return kDataReadErrorReadFailed;
|
||||
|
||||
if (_revision >= 2) {
|
||||
haveGUID = true;
|
||||
if (!reader.readU32(guid))
|
||||
return kDataReadErrorReadFailed;
|
||||
} else {
|
||||
haveGUID = false;
|
||||
guid = 0;
|
||||
}
|
||||
|
||||
if (!reader.readTerminatedStr(name, lengthOfName))
|
||||
return kDataReadErrorReadFailed;
|
||||
|
||||
return kDataReadErrorNone;
|
||||
@ -1802,6 +1814,19 @@ DataReadErrorCode StringVariableModifier::load(DataReader &reader) {
|
||||
return kDataReadErrorNone;
|
||||
}
|
||||
|
||||
ObjectReferenceVariableModifierV1::ObjectReferenceVariableModifierV1() : unknown1(0) {
|
||||
}
|
||||
|
||||
DataReadErrorCode ObjectReferenceVariableModifierV1::load(DataReader &reader) {
|
||||
if (_revision != 1000)
|
||||
return kDataReadErrorUnsupportedRevision;
|
||||
|
||||
if (!modHeader.load(reader) || !reader.readU32(unknown1) || !setToSourcesParentWhen.load(reader))
|
||||
return kDataReadErrorReadFailed;
|
||||
|
||||
return kDataReadErrorNone;
|
||||
}
|
||||
|
||||
PlugInModifierData::~PlugInModifierData() {
|
||||
}
|
||||
|
||||
@ -2401,6 +2426,9 @@ DataReadErrorCode loadDataObject(const PlugInModifierRegistry ®istry, DataRea
|
||||
case DataObjectTypes::kStringVariableModifier:
|
||||
dataObject = new StringVariableModifier();
|
||||
break;
|
||||
case DataObjectTypes::kObjectReferenceVariableModifierV1:
|
||||
dataObject = new ObjectReferenceVariableModifierV1();
|
||||
break;
|
||||
case DataObjectTypes::kDebris:
|
||||
dataObject = new Debris();
|
||||
break;
|
||||
|
@ -137,6 +137,7 @@ enum DataObjectType {
|
||||
kPointVariableModifier = 0x326,
|
||||
kFloatingPointVariableModifier = 0x328,
|
||||
kStringVariableModifier = 0x329,
|
||||
kObjectReferenceVariableModifierV1 = 0x33e,
|
||||
kDebris = 0xfffffffe, // Deleted modifier in alias list
|
||||
kPlugInModifier = 0xffffffff,
|
||||
|
||||
@ -1058,6 +1059,8 @@ struct AliasModifier : public DataObject {
|
||||
|
||||
Common::String name;
|
||||
|
||||
bool haveGUID;
|
||||
|
||||
protected:
|
||||
DataReadErrorCode load(DataReader &reader) override;
|
||||
};
|
||||
@ -1670,6 +1673,17 @@ protected:
|
||||
DataReadErrorCode load(DataReader &reader) override;
|
||||
};
|
||||
|
||||
struct ObjectReferenceVariableModifierV1 : public DataObject {
|
||||
ObjectReferenceVariableModifierV1();
|
||||
|
||||
TypicalModifierHeader modHeader;
|
||||
uint32 unknown1;
|
||||
Event setToSourcesParentWhen;
|
||||
|
||||
protected:
|
||||
DataReadErrorCode load(DataReader &reader) override;
|
||||
};
|
||||
|
||||
struct PlugInModifierData {
|
||||
virtual ~PlugInModifierData();
|
||||
virtual DataReadErrorCode load(PlugIn &plugIn, const PlugInModifier &prefix, DataReader &reader) = 0;
|
||||
|
@ -134,6 +134,8 @@ SIModifierFactory *getModifierFactoryForDataObjectType(const Data::DataObjectTyp
|
||||
return ModifierFactory<FloatingPointVariableModifier, Data::FloatingPointVariableModifier>::getInstance();
|
||||
case Data::DataObjectTypes::kStringVariableModifier:
|
||||
return ModifierFactory<StringVariableModifier, Data::StringVariableModifier>::getInstance();
|
||||
case Data::DataObjectTypes::kObjectReferenceVariableModifierV1:
|
||||
return ModifierFactory<ObjectReferenceVariableModifierV1, Data::ObjectReferenceVariableModifierV1>::getInstance();
|
||||
|
||||
default:
|
||||
warning("No modifier factory for type %x", static_cast<int>(dataObjectType));
|
||||
|
@ -365,16 +365,33 @@ VThreadState SaveAndRestoreModifier::consumeMessage(Runtime *runtime, const Comm
|
||||
return kVThreadError;
|
||||
}
|
||||
|
||||
// There doesn't appear to be any flag for this, it just uses the file path field
|
||||
bool isPrompt = (_filePath == "Ask User");
|
||||
|
||||
if (_saveWhen.respondsTo(msg->getEvent())) {
|
||||
CompoundVarSaver saver(obj);
|
||||
if (runtime->getSaveProvider()->promptSave(&saver, runtime->getSaveScreenshotOverride().get())) {
|
||||
|
||||
bool succeeded = false;
|
||||
if (isPrompt)
|
||||
succeeded = runtime->getSaveProvider()->promptSave(&saver, runtime->getSaveScreenshotOverride().get());
|
||||
else
|
||||
succeeded = runtime->getSaveProvider()->namedSave(&saver, runtime->getSaveScreenshotOverride().get(), _fileName);
|
||||
|
||||
if (succeeded) {
|
||||
for (const Common::SharedPtr<SaveLoadHooks> &hooks : runtime->getHacks().saveLoadHooks)
|
||||
hooks->onSave(runtime, this, static_cast<Modifier *>(obj));
|
||||
}
|
||||
return kVThreadReturn;
|
||||
} else if (_restoreWhen.respondsTo(msg->getEvent())) {
|
||||
CompoundVarLoader loader(obj);
|
||||
if (runtime->getLoadProvider()->promptLoad(&loader)) {
|
||||
|
||||
bool succeeded = false;
|
||||
if (isPrompt)
|
||||
runtime->getLoadProvider()->promptLoad(&loader);
|
||||
else
|
||||
runtime->getLoadProvider()->namedLoad(&loader, _fileName);
|
||||
|
||||
if (succeeded) {
|
||||
for (const Common::SharedPtr<SaveLoadHooks> &hooks : runtime->getHacks().saveLoadHooks)
|
||||
hooks->onLoad(runtime, this, static_cast<Modifier *>(obj));
|
||||
}
|
||||
@ -2815,4 +2832,72 @@ bool StringVariableModifier::SaveLoad::loadInternal(Common::ReadStream *stream,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ObjectReferenceVariableModifierV1::load(ModifierLoaderContext &context, const Data::ObjectReferenceVariableModifierV1 &data) {
|
||||
if (!loadTypicalHeader(data.modHeader))
|
||||
return false;
|
||||
|
||||
if (!_setToSourcesParentWhen.load(data.setToSourcesParentWhen))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectReferenceVariableModifierV1::respondsToEvent(const Event &evt) const {
|
||||
return _setToSourcesParentWhen.respondsTo(evt);
|
||||
}
|
||||
|
||||
VThreadState ObjectReferenceVariableModifierV1::consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) {
|
||||
if (msg->getEvent().respondsTo(_setToSourcesParentWhen)) {
|
||||
warning("Set to source's parent is not implemented");
|
||||
}
|
||||
return kVThreadError;
|
||||
}
|
||||
|
||||
Common::SharedPtr<ModifierSaveLoad> ObjectReferenceVariableModifierV1::getSaveLoad() {
|
||||
return Common::SharedPtr<ModifierSaveLoad>(new SaveLoad(this));
|
||||
}
|
||||
|
||||
bool ObjectReferenceVariableModifierV1::varSetValue(MiniscriptThread *thread, const DynamicValue &value) {
|
||||
if (value.getType() == DynamicValueTypes::kNull)
|
||||
_value.reset();
|
||||
else if (value.getType() == DynamicValueTypes::kObject)
|
||||
_value = value.getObject().object;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ObjectReferenceVariableModifierV1::varGetValue(MiniscriptThread *thread, DynamicValue &dest) const {
|
||||
if (_value.expired())
|
||||
dest.clear();
|
||||
else
|
||||
dest.setObject(_value);
|
||||
}
|
||||
|
||||
Common::SharedPtr<Modifier> ObjectReferenceVariableModifierV1::shallowClone() const {
|
||||
return Common::SharedPtr<Modifier>(new ObjectReferenceVariableModifierV1(*this));
|
||||
}
|
||||
|
||||
const char *ObjectReferenceVariableModifierV1::getDefaultName() const {
|
||||
return "Object Reference Variable";
|
||||
}
|
||||
|
||||
ObjectReferenceVariableModifierV1::SaveLoad::SaveLoad(ObjectReferenceVariableModifierV1 *modifier) : _modifier(modifier) {
|
||||
}
|
||||
|
||||
void ObjectReferenceVariableModifierV1::SaveLoad::commitLoad() const {
|
||||
_modifier->_value = _value;
|
||||
}
|
||||
|
||||
void ObjectReferenceVariableModifierV1::SaveLoad::saveInternal(Common::WriteStream *stream) const {
|
||||
error("Saving version 1 object reference variables is not currently supported");
|
||||
}
|
||||
|
||||
bool ObjectReferenceVariableModifierV1::SaveLoad::loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace MTropolis
|
||||
|
@ -1178,6 +1178,44 @@ private:
|
||||
Common::String _value;
|
||||
};
|
||||
|
||||
class ObjectReferenceVariableModifierV1 : public VariableModifier {
|
||||
public:
|
||||
bool load(ModifierLoaderContext &context, const Data::ObjectReferenceVariableModifierV1 &data);
|
||||
|
||||
bool respondsToEvent(const Event &evt) const override;
|
||||
VThreadState consumeMessage(Runtime *runtime, const Common::SharedPtr<MessageProperties> &msg) override;
|
||||
|
||||
Common::SharedPtr<ModifierSaveLoad> getSaveLoad() override;
|
||||
|
||||
bool varSetValue(MiniscriptThread *thread, const DynamicValue &value) override;
|
||||
void varGetValue(MiniscriptThread *thread, DynamicValue &dest) const override;
|
||||
|
||||
#ifdef MTROPOLIS_DEBUG_ENABLE
|
||||
const char *debugGetTypeName() const override { return "Object Reference Variable Modifier V1"; }
|
||||
SupportStatus debugGetSupportStatus() const override { return kSupportStatusNone; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
class SaveLoad : public ModifierSaveLoad {
|
||||
public:
|
||||
explicit SaveLoad(ObjectReferenceVariableModifierV1 *modifier);
|
||||
|
||||
private:
|
||||
void commitLoad() const override;
|
||||
void saveInternal(Common::WriteStream *stream) const override;
|
||||
bool loadInternal(Common::ReadStream *stream, uint32 saveFileVersion) override;
|
||||
|
||||
ObjectReferenceVariableModifierV1 *_modifier;
|
||||
Common::WeakPtr<RuntimeObject> _value;
|
||||
};
|
||||
|
||||
Common::SharedPtr<Modifier> shallowClone() const override;
|
||||
const char *getDefaultName() const override;
|
||||
|
||||
Common::WeakPtr<RuntimeObject> _value;
|
||||
Event _setToSourcesParentWhen;
|
||||
};
|
||||
|
||||
} // End of namespace MTropolis
|
||||
|
||||
#endif
|
||||
|
@ -59,8 +59,10 @@ public:
|
||||
Common::Platform getPlatform() const;
|
||||
|
||||
bool promptSave(ISaveWriter *writer, const Graphics::Surface *screenshotOverride) override;
|
||||
bool namedSave(ISaveWriter *writer, const Graphics::Surface *screenshotOverride, const Common::String &fileName) override;
|
||||
bool autoSave(ISaveWriter *writer) override;
|
||||
bool promptLoad(ISaveReader *reader) override;
|
||||
bool namedLoad(ISaveReader *reader, const Common::String &fileName) override;
|
||||
|
||||
const Graphics::Surface *getSavegameScreenshot() const;
|
||||
|
||||
@ -75,6 +77,11 @@ protected:
|
||||
void pauseEngineIntern(bool pause) override;
|
||||
|
||||
private:
|
||||
bool save(ISaveWriter *writer, const Graphics::Surface *screenshotOverride, const Common::String &fileName, const Common::String &desc);
|
||||
bool load(ISaveReader *reader, const Common::String &fileName);
|
||||
|
||||
Common::String getUnpromptedSaveFileName(const Common::String &fileName);
|
||||
|
||||
static const uint kCurrentSaveFileVersion = 1;
|
||||
static const uint kSavegameSignature = 0x6d545356; // mTSV
|
||||
|
||||
|
@ -87,6 +87,12 @@ bool MTropolisEngine::promptSave(ISaveWriter *writer, const Graphics::Surface *s
|
||||
return true;
|
||||
|
||||
Common::String saveFileName = getSaveStateName(slot);
|
||||
|
||||
return save(writer, screenshotOverride, saveFileName, desc);
|
||||
}
|
||||
|
||||
bool MTropolisEngine::save(ISaveWriter *writer, const Graphics::Surface *screenshotOverride, const Common::String &saveFileName, const Common::String &desc) {
|
||||
|
||||
Common::SharedPtr<Common::OutSaveFile> out(_saveFileMan->openForSaving(saveFileName, false));
|
||||
|
||||
ISaveWriter *oldWriter = _saveWriter;
|
||||
@ -102,6 +108,10 @@ bool MTropolisEngine::promptSave(ISaveWriter *writer, const Graphics::Surface *s
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MTropolisEngine::namedSave(ISaveWriter *writer, const Graphics::Surface *screenshotOverride, const Common::String &fileName) {
|
||||
return save(writer, screenshotOverride, getUnpromptedSaveFileName(fileName), fileName);
|
||||
}
|
||||
|
||||
bool MTropolisEngine::promptLoad(ISaveReader *reader) {
|
||||
Common::String desc;
|
||||
int slot;
|
||||
@ -115,7 +125,16 @@ bool MTropolisEngine::promptLoad(ISaveReader *reader) {
|
||||
return true;
|
||||
|
||||
Common::String saveFileName = getSaveStateName(slot);
|
||||
|
||||
return load(reader, saveFileName);
|
||||
}
|
||||
|
||||
bool MTropolisEngine::load(ISaveReader *reader, const Common::String &saveFileName) {
|
||||
Common::SharedPtr<Common::InSaveFile> in(_saveFileMan->openForLoading(saveFileName));
|
||||
if (!in) {
|
||||
warning("An error occurred while attempting to open save file '%s'", saveFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 signature = in->readUint32BE();
|
||||
uint32 saveFileVersion = in->readUint32BE();
|
||||
@ -154,6 +173,14 @@ bool MTropolisEngine::promptLoad(ISaveReader *reader) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Common::String MTropolisEngine::getUnpromptedSaveFileName(const Common::String &fileName) {
|
||||
return _targetName + "." + toCaseInsensitive(fileName);
|
||||
}
|
||||
|
||||
bool MTropolisEngine::namedLoad(ISaveReader *reader, const Common::String &fileName) {
|
||||
return load(reader, getUnpromptedSaveFileName(fileName));
|
||||
}
|
||||
|
||||
bool MTropolisEngine::autoSave(ISaveWriter *writer) {
|
||||
ISaveWriter *oldWriter = _saveWriter;
|
||||
bool oldIsTriggeredAutosave = _isTriggeredAutosave;
|
||||
|
@ -53,10 +53,12 @@ struct ISaveReader : public IInterfaceBase {
|
||||
|
||||
struct ISaveUIProvider : public IInterfaceBase {
|
||||
virtual bool promptSave(ISaveWriter *writer, const Graphics::Surface *screenshotOverride) = 0;
|
||||
virtual bool namedSave(ISaveWriter *writer, const Graphics::Surface *screenshotOverride, const Common::String &fileName) = 0;
|
||||
};
|
||||
|
||||
struct ILoadUIProvider : public IInterfaceBase {
|
||||
virtual bool promptLoad(ISaveReader *reader) = 0;
|
||||
virtual bool namedLoad(ISaveReader *reader, const Common::String &fileName) = 0;
|
||||
};
|
||||
|
||||
struct IAutoSaveProvider : public IInterfaceBase {
|
||||
|
Loading…
Reference in New Issue
Block a user