mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-22 20:21:06 +00:00
MTROPOLIS: Fix enough things for Obsidian forest intro to be completable (sometimes)
This commit is contained in:
parent
9c16acd00e
commit
5ab54de82a
@ -248,11 +248,11 @@ void CachedMToon::decompressRLEFrameToImage(size_t frameIndex, Graphics::Surface
|
||||
int32 originY = frameDef.rect.top;
|
||||
|
||||
bool decompressedOK = false;
|
||||
if (_rleOptimizedFormat.bytesPerPixel == 32) {
|
||||
if (_rleOptimizedFormat.bytesPerPixel == 4) {
|
||||
decompressedOK = decompressMToonRLE<Rle32Frame, uint32, 0x80000000u, 0x80000000u>(_dataRLE32[frameIndex], surface);
|
||||
} else if (_rleOptimizedFormat.bytesPerPixel == 16) {
|
||||
} else if (_rleOptimizedFormat.bytesPerPixel == 2) {
|
||||
decompressedOK = decompressMToonRLE<Rle16Frame, uint16, 0x8000u, 0x8000u>(_dataRLE16[frameIndex], surface);
|
||||
} else if (_rleOptimizedFormat.bytesPerPixel == 8) {
|
||||
} else if (_rleOptimizedFormat.bytesPerPixel == 1) {
|
||||
decompressedOK = decompressMToonRLE<Rle8Frame, uint8, 0x80u, 0u>(_dataRLE8[frameIndex], surface);
|
||||
} else
|
||||
error("Unknown mToon encoding");
|
||||
|
32
engines/mtropolis/hacks.cpp
Normal file
32
engines/mtropolis/hacks.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mtropolis/hacks.h"
|
||||
|
||||
#include "common/system.h"
|
||||
|
||||
namespace MTropolis {
|
||||
|
||||
Hacks::Hacks() {
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
} // End of namespace MTropolis
|
39
engines/mtropolis/hacks.h
Normal file
39
engines/mtropolis/hacks.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace MTropolis {
|
||||
|
||||
struct Hacks {
|
||||
Hacks();
|
||||
|
||||
// Workaround for bug in Obsidian:
|
||||
// When opening the journal in the intro, a script checks if cGSt.cfst.binjournal is false and if so,
|
||||
// sets cGSt.cfst.binjournal to true and then sets including setting cJournalConst.aksjournpath to the
|
||||
// main journal scene path. That scene path is used to resolve the scene to go to after clicking
|
||||
// the "Continue" button on the warning that pops up.
|
||||
//
|
||||
// The problem is that cJournalConst uses a project name that doesn't match the retail data, and
|
||||
// cJournalConst is unloaded if the player leaves the journal. This causes a progression blocker if
|
||||
// the player leaves the journal without clicking Continue.
|
||||
bool ignoreMismatchedProjectNameInObjectLookups;
|
||||
};
|
||||
|
||||
} // End of namespace MTropolis
|
@ -1826,7 +1826,7 @@ VThreadState MiniscriptThread::resume(const ResumeTaskData &taskData) {
|
||||
if (instrsArray.size() == 0)
|
||||
return kVThreadReturn;
|
||||
|
||||
if (_modifier->getStaticGUID() == 0x985d1) {
|
||||
if (_modifier->getStaticGUID() == 0x48890) {
|
||||
int n = 0;
|
||||
}
|
||||
|
||||
|
@ -716,9 +716,14 @@ VThreadState TimerMessengerModifier::consumeMessage(Runtime *runtime, const Comm
|
||||
if (_scheduledEvent)
|
||||
_scheduledEvent->cancel();
|
||||
} else if (_executeWhen.respondsTo(msg->getEvent())) {
|
||||
debug(3, "Timer %x '%s' scheduled to execute in %i milliseconds", getStaticGUID(), getName().c_str(), _milliseconds);
|
||||
// 0-time events are not allowed
|
||||
uint32 realMilliseconds = _milliseconds;
|
||||
if (realMilliseconds == 0)
|
||||
realMilliseconds = 1;
|
||||
|
||||
debug(3, "Timer %x '%s' scheduled to execute in %i milliseconds", getStaticGUID(), getName().c_str(), realMilliseconds);
|
||||
if (!_scheduledEvent) {
|
||||
_scheduledEvent = runtime->getScheduler().scheduleMethod<TimerMessengerModifier, &TimerMessengerModifier::activate>(runtime->getPlayTime() + _milliseconds, this);
|
||||
_scheduledEvent = runtime->getScheduler().scheduleMethod<TimerMessengerModifier, &TimerMessengerModifier::trigger>(runtime->getPlayTime() + realMilliseconds, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -740,11 +745,14 @@ Common::SharedPtr<Modifier> TimerMessengerModifier::shallowClone() const {
|
||||
return Common::SharedPtr<Modifier>(clone);
|
||||
}
|
||||
|
||||
void TimerMessengerModifier::activate(Runtime *runtime) {
|
||||
void TimerMessengerModifier::trigger(Runtime *runtime) {
|
||||
debug(3, "Timer %x '%s' triggered", getStaticGUID(), getName().c_str());
|
||||
if (_looping)
|
||||
_scheduledEvent = runtime->getScheduler().scheduleMethod<TimerMessengerModifier, &TimerMessengerModifier::activate>(runtime->getPlayTime() + _milliseconds, this);
|
||||
else
|
||||
if (_looping) {
|
||||
uint32 realMilliseconds = _milliseconds;
|
||||
if (realMilliseconds == 0)
|
||||
realMilliseconds = 1;
|
||||
_scheduledEvent = runtime->getScheduler().scheduleMethod<TimerMessengerModifier, &TimerMessengerModifier::trigger>(runtime->getPlayTime() + realMilliseconds, this);
|
||||
} else
|
||||
_scheduledEvent.reset();
|
||||
|
||||
_sendSpec.sendFromMessenger(runtime, this);
|
||||
|
@ -384,7 +384,7 @@ public:
|
||||
private:
|
||||
Common::SharedPtr<Modifier> shallowClone() const override;
|
||||
|
||||
void activate(Runtime *runtime);
|
||||
void trigger(Runtime *runtime);
|
||||
|
||||
Event _executeWhen;
|
||||
Event _terminateWhen;
|
||||
|
@ -9,6 +9,7 @@ MODULE_OBJS = \
|
||||
detection.o \
|
||||
element_factory.o \
|
||||
elements.o \
|
||||
hacks.o \
|
||||
metaengine.o \
|
||||
miniscript.o \
|
||||
modifiers.o \
|
||||
|
@ -277,6 +277,8 @@ Common::Error MTropolisEngine::run() {
|
||||
preferredHeight = 480;
|
||||
preferredColorDepthMode = kColorDepthMode16Bit;
|
||||
|
||||
_runtime->getHacks().ignoreMismatchedProjectNameInObjectLookups = true;
|
||||
|
||||
_runtime->addVolume(0, "Installed", true);
|
||||
_runtime->addVolume(1, "OBSIDIAN1", true);
|
||||
_runtime->addVolume(2, "OBSIDIAN2", true);
|
||||
@ -314,11 +316,14 @@ Common::Error MTropolisEngine::run() {
|
||||
desc->addPlugIn(PlugIns::createObsidian());
|
||||
|
||||
_runtime->queueProject(desc);
|
||||
|
||||
} else if (_gameDescription->gameID == GID_OBSIDIAN && _gameDescription->desc.platform == Common::kPlatformMacintosh) {
|
||||
preferredWidth = 640;
|
||||
preferredHeight = 480;
|
||||
preferredColorDepthMode = kColorDepthMode16Bit;
|
||||
|
||||
_runtime->getHacks().ignoreMismatchedProjectNameInObjectLookups = true;
|
||||
|
||||
MacObsidianResources *resources = new MacObsidianResources();
|
||||
Common::SharedPtr<ProjectResources> resPtr(resources);
|
||||
|
||||
|
@ -884,7 +884,7 @@ MiniscriptInstructionOutcome MidiModifier::scriptSetNoteVelocity(MiniscriptThrea
|
||||
return kMiniscriptInstructionOutcomeContinue;
|
||||
}
|
||||
|
||||
ListVariableModifier::ListVariableModifier() : _list(new DynamicList()) {
|
||||
ListVariableModifier::ListVariableModifier() : _list(new DynamicList()), _preferredContentType(DynamicValueTypes::kInteger) {
|
||||
}
|
||||
|
||||
bool ListVariableModifier::load(const PlugInModifierLoaderContext &context, const Data::Standard::ListVariableModifier &data) {
|
||||
@ -944,6 +944,8 @@ bool ListVariableModifier::load(const PlugInModifierLoaderContext &context, cons
|
||||
}
|
||||
}
|
||||
|
||||
_preferredContentType = expectedType;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -981,6 +983,15 @@ bool ListVariableModifier::readAttributeIndexed(MiniscriptThread *thread, Dynami
|
||||
return Modifier::readAttributeIndexed(thread, result, attrib, index);
|
||||
}
|
||||
|
||||
MiniscriptInstructionOutcome ListVariableModifier::writeRefAttribute(MiniscriptThread *thread, DynamicValueWriteProxy &writeProxy, const Common::String &attrib) {
|
||||
if (attrib == "count") {
|
||||
DynamicValueWriteFuncHelper<ListVariableModifier, &ListVariableModifier::scriptSetCount>::create(this, writeProxy);
|
||||
return kMiniscriptInstructionOutcomeContinue;
|
||||
}
|
||||
|
||||
return VariableModifier::writeRefAttribute(thread, writeProxy, attrib);
|
||||
}
|
||||
|
||||
MiniscriptInstructionOutcome ListVariableModifier::writeRefAttributeIndexed(MiniscriptThread *thread, DynamicValueWriteProxy &writeProxy, const Common::String &attrib, const DynamicValue &index) {
|
||||
if (attrib == "value") {
|
||||
size_t realIndex = 0;
|
||||
@ -1055,6 +1066,33 @@ ListVariableModifier::ListVariableModifier(const ListVariableModifier &other) {
|
||||
_list = other._list->clone();
|
||||
}
|
||||
|
||||
MiniscriptInstructionOutcome ListVariableModifier::scriptSetCount(MiniscriptThread *thread, const DynamicValue &value) {
|
||||
int32 asInteger = 0;
|
||||
if (!value.roundToInt(asInteger)) {
|
||||
thread->error("Tried to set a list variable count to something other than an integer");
|
||||
return kMiniscriptInstructionOutcomeFailed;
|
||||
}
|
||||
|
||||
if (asInteger < 0) {
|
||||
thread->error("Tried to set a list variable count to a negative value");
|
||||
return kMiniscriptInstructionOutcomeFailed;
|
||||
}
|
||||
|
||||
size_t newSize = asInteger;
|
||||
if (newSize > _list->getSize()) {
|
||||
if (_list->getSize() == 0) {
|
||||
thread->error("Restoring an empty list by setting its count isn't implemented");
|
||||
return kMiniscriptInstructionOutcomeFailed;
|
||||
}
|
||||
|
||||
_list->expandToMinimumSize(newSize);
|
||||
} else if (newSize < _list->getSize()) {
|
||||
_list->truncateToSize(newSize);
|
||||
}
|
||||
|
||||
return kMiniscriptInstructionOutcomeContinue;
|
||||
}
|
||||
|
||||
Common::SharedPtr<Modifier> ListVariableModifier::shallowClone() const {
|
||||
return Common::SharedPtr<Modifier>(new ListVariableModifier(*this));
|
||||
}
|
||||
|
@ -246,9 +246,9 @@ public:
|
||||
|
||||
bool readAttribute(MiniscriptThread *thread, DynamicValue &result, const Common::String &attrib) override;
|
||||
bool readAttributeIndexed(MiniscriptThread *thread, DynamicValue &result, const Common::String &attrib, const DynamicValue &index) override;
|
||||
MiniscriptInstructionOutcome writeRefAttribute(MiniscriptThread *thread, DynamicValueWriteProxy &writeProxy, const Common::String &attrib) override;
|
||||
MiniscriptInstructionOutcome writeRefAttributeIndexed(MiniscriptThread *thread, DynamicValueWriteProxy &writeProxy, const Common::String &attrib, const DynamicValue &index) override;
|
||||
|
||||
|
||||
#ifdef MTROPOLIS_DEBUG_ENABLE
|
||||
const char *debugGetTypeName() const override { return "List Variable Modifier"; }
|
||||
SupportStatus debugGetSupportStatus() const override { return kSupportStatusDone; }
|
||||
@ -272,9 +272,12 @@ private:
|
||||
ListVariableModifier(const ListVariableModifier &other);
|
||||
ListVariableModifier &operator=(const ListVariableModifier &other);
|
||||
|
||||
MiniscriptInstructionOutcome scriptSetCount(MiniscriptThread *thread, const DynamicValue &value);
|
||||
|
||||
Common::SharedPtr<Modifier> shallowClone() const override;
|
||||
|
||||
Common::SharedPtr<DynamicList> _list;
|
||||
DynamicValueTypes::DynamicValueType _preferredContentType;
|
||||
};
|
||||
|
||||
class SysInfoModifier : public Modifier {
|
||||
|
@ -527,6 +527,9 @@ bool DynamicListContainer<void>::setAtIndex(size_t index, const DynamicValue &dy
|
||||
return true;
|
||||
}
|
||||
|
||||
void DynamicListContainer<void>::truncateToSize(size_t sz) {
|
||||
}
|
||||
|
||||
bool DynamicListContainer<void>::expandToMinimumSize(size_t sz) {
|
||||
return false;
|
||||
}
|
||||
@ -589,6 +592,11 @@ bool DynamicListContainer<VarReference>::setAtIndex(size_t index, const DynamicV
|
||||
return true;
|
||||
}
|
||||
|
||||
void DynamicListContainer<VarReference>::truncateToSize(size_t sz) {
|
||||
if (_array.size() > sz)
|
||||
_array.resize(sz);
|
||||
}
|
||||
|
||||
bool DynamicListContainer<VarReference>::expandToMinimumSize(size_t sz) {
|
||||
if (_array.size() < sz) {
|
||||
size_t prevSize = _array.size();
|
||||
@ -800,6 +808,13 @@ bool DynamicList::setAtIndex(size_t index, const DynamicValue &value) {
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicList::truncateToSize(size_t sz) {
|
||||
if (sz == 0)
|
||||
clear();
|
||||
else if (_container)
|
||||
_container->truncateToSize(sz);
|
||||
}
|
||||
|
||||
void DynamicList::expandToMinimumSize(size_t sz) {
|
||||
if (_container)
|
||||
_container->expandToMinimumSize(sz);
|
||||
@ -1669,12 +1684,40 @@ void MessengerSendSpec::resolveDestination(Runtime *runtime, Modifier *sender, C
|
||||
if (!outStructuralDest.expired())
|
||||
outStructuralDest = outStructuralDest.lock()->getParent()->getSelfReference().staticCast<Structural>();
|
||||
break;
|
||||
case kMessageDestNextElement:
|
||||
case kMessageDestPrevElement: {
|
||||
Common::WeakPtr<Structural> elementWeak;
|
||||
Common::WeakPtr<Modifier> modifier;
|
||||
resolveHierarchyStructuralDestination(runtime, sender, elementWeak, modifier, isElementFilter);
|
||||
|
||||
Common::SharedPtr<Structural> sibling;
|
||||
Common::SharedPtr<Structural> element = elementWeak.lock();
|
||||
if (element) {
|
||||
Structural *parent = element->getParent();
|
||||
if (parent) {
|
||||
const Common::Array<Common::SharedPtr<Structural> > &siblings = parent->getChildren();
|
||||
for (size_t i = 0; i < siblings.size(); i++) {
|
||||
if (siblings[i] == element) {
|
||||
if (destination == kMessageDestPrevElement) {
|
||||
if (i != 0)
|
||||
sibling = siblings[i - 1];
|
||||
} else if (destination == kMessageDestNextElement) {
|
||||
if (i != siblings.size() - 1)
|
||||
sibling = siblings[i + 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sibling)
|
||||
outStructuralDest = sibling;
|
||||
} break;
|
||||
case kMessageDestChildren:
|
||||
case kMessageDestSubsection:
|
||||
case kMessageDestSourcesParent:
|
||||
case kMessageDestBehavior:
|
||||
case kMessageDestNextElement:
|
||||
case kMessageDestPrevElement:
|
||||
case kMessageDestBehaviorsParent:
|
||||
warning("Not-yet-implemented message destination type");
|
||||
break;
|
||||
@ -4558,6 +4601,15 @@ Audio::Mixer *Runtime::getAudioMixer() const {
|
||||
return _mixer;
|
||||
}
|
||||
|
||||
Hacks &Runtime::getHacks() {
|
||||
return _hacks;
|
||||
}
|
||||
|
||||
const Hacks &Runtime::getHacks() const {
|
||||
return _hacks;
|
||||
}
|
||||
|
||||
|
||||
void Runtime::ensureMainWindowExists() {
|
||||
// Maybe there's a better spot for this
|
||||
if (_mainWindow.expired() && _project) {
|
||||
@ -5809,7 +5861,7 @@ MiniscriptInstructionOutcome VisualElement::writeRefAttribute(MiniscriptThread *
|
||||
DynamicValueWriteFuncHelper<VisualElement, &VisualElement::scriptSetDirect>::create(this, writeProxy);
|
||||
return kMiniscriptInstructionOutcomeContinue;
|
||||
} else if (attrib == "position") {
|
||||
DynamicValueWriteFuncHelper<VisualElement, &VisualElement::scriptSetPosition>::create(this, writeProxy);
|
||||
DynamicValueWriteOrRefAttribFuncHelper<VisualElement, &VisualElement::scriptSetPosition, &VisualElement::scriptWriteRefPositionAttribute>::create(this, writeProxy);
|
||||
return kMiniscriptInstructionOutcomeContinue;
|
||||
} else if (attrib == "centerposition") {
|
||||
DynamicValueWriteFuncHelper<VisualElement, &VisualElement::scriptSetCenterPosition>::create(this, writeProxy);
|
||||
@ -5908,6 +5960,32 @@ MiniscriptInstructionOutcome VisualElement::scriptSetPosition(MiniscriptThread *
|
||||
return kMiniscriptInstructionOutcomeFailed;
|
||||
}
|
||||
|
||||
MiniscriptInstructionOutcome VisualElement::scriptSetPositionX(MiniscriptThread *thread, const DynamicValue &dest) {
|
||||
int32 asInteger = 0;
|
||||
if (!dest.roundToInt(asInteger))
|
||||
return kMiniscriptInstructionOutcomeFailed;
|
||||
|
||||
int32 xDelta = asInteger - _rect.left;
|
||||
|
||||
if (xDelta != 0)
|
||||
offsetTranslate(xDelta, 0, false);
|
||||
|
||||
return kMiniscriptInstructionOutcomeContinue;
|
||||
}
|
||||
|
||||
MiniscriptInstructionOutcome VisualElement::scriptSetPositionY(MiniscriptThread *thread, const DynamicValue &dest) {
|
||||
int32 asInteger = 0;
|
||||
if (!dest.roundToInt(asInteger))
|
||||
return kMiniscriptInstructionOutcomeFailed;
|
||||
|
||||
int32 yDelta = asInteger - _rect.top;
|
||||
|
||||
if (yDelta != 0)
|
||||
offsetTranslate(0, yDelta, false);
|
||||
|
||||
return kMiniscriptInstructionOutcomeContinue;
|
||||
}
|
||||
|
||||
MiniscriptInstructionOutcome VisualElement::scriptSetCenterPosition(MiniscriptThread *thread, const DynamicValue &value) {
|
||||
if (value.getType() == DynamicValueTypes::kPoint) {
|
||||
const Point16 &destPoint = value.getPoint();
|
||||
@ -5963,6 +6041,18 @@ MiniscriptInstructionOutcome VisualElement::scriptSetLayer(MiniscriptThread *thr
|
||||
return kMiniscriptInstructionOutcomeContinue;
|
||||
}
|
||||
|
||||
MiniscriptInstructionOutcome VisualElement::scriptWriteRefPositionAttribute(MiniscriptThread *thread, DynamicValueWriteProxy &writeProxy, const Common::String &attrib) {
|
||||
if (attrib == "x") {
|
||||
DynamicValueWriteFuncHelper<VisualElement, &VisualElement::scriptSetPositionX>::create(this, writeProxy);
|
||||
return kMiniscriptInstructionOutcomeContinue;
|
||||
} else if (attrib == "y") {
|
||||
DynamicValueWriteFuncHelper<VisualElement, &VisualElement::scriptSetPositionY>::create(this, writeProxy);
|
||||
return kMiniscriptInstructionOutcomeContinue;
|
||||
}
|
||||
|
||||
return kMiniscriptInstructionOutcomeFailed;
|
||||
}
|
||||
|
||||
void VisualElement::offsetTranslate(int32 xDelta, int32 yDelta, bool cachedOriginOnly) {
|
||||
if (!cachedOriginOnly) {
|
||||
_rect.left += xDelta;
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "mtropolis/actions.h"
|
||||
#include "mtropolis/data.h"
|
||||
#include "mtropolis/debug.h"
|
||||
#include "mtropolis/hacks.h"
|
||||
#include "mtropolis/vthread.h"
|
||||
|
||||
class OSystem;
|
||||
@ -511,6 +512,7 @@ public:
|
||||
virtual ~DynamicListContainerBase();
|
||||
virtual bool setAtIndex(size_t index, const DynamicValue &dynValue) = 0;
|
||||
virtual bool getAtIndex(size_t index, DynamicValue &dynValue) const = 0;
|
||||
virtual void truncateToSize(size_t sz) = 0;
|
||||
virtual bool expandToMinimumSize(size_t sz) = 0;
|
||||
virtual void setFrom(const DynamicListContainerBase &other) = 0; // Only supports setting same type!
|
||||
virtual const void *getConstArrayPtr() const = 0;
|
||||
@ -567,6 +569,7 @@ class DynamicListContainer : public DynamicListContainerBase {
|
||||
public:
|
||||
bool setAtIndex(size_t index, const DynamicValue &dynValue) override;
|
||||
bool getAtIndex(size_t index, DynamicValue &dynValue) const override;
|
||||
void truncateToSize(size_t sz) override;
|
||||
bool expandToMinimumSize(size_t sz) override;
|
||||
void setFrom(const DynamicListContainerBase &other) override;
|
||||
const void *getConstArrayPtr() const override;
|
||||
@ -586,6 +589,7 @@ public:
|
||||
|
||||
bool setAtIndex(size_t index, const DynamicValue &dynValue) override;
|
||||
bool getAtIndex(size_t index, DynamicValue &dynValue) const override;
|
||||
void truncateToSize(size_t sz) override;
|
||||
bool expandToMinimumSize(size_t sz) override;
|
||||
void setFrom(const DynamicListContainerBase &other) override;
|
||||
const void *getConstArrayPtr() const override;
|
||||
@ -603,6 +607,7 @@ class DynamicListContainer<VarReference> : public DynamicListContainerBase {
|
||||
public:
|
||||
bool setAtIndex(size_t index, const DynamicValue &dynValue) override;
|
||||
bool getAtIndex(size_t index, DynamicValue &dynValue) const override;
|
||||
void truncateToSize(size_t sz) override;
|
||||
bool expandToMinimumSize(size_t sz) override;
|
||||
void setFrom(const DynamicListContainerBase &other) override;
|
||||
const void *getConstArrayPtr() const override;
|
||||
@ -641,6 +646,12 @@ bool DynamicListContainer<T>::setAtIndex(size_t index, const DynamicValue &dynVa
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void DynamicListContainer<T>::truncateToSize(size_t sz) {
|
||||
if (_array.size() > sz)
|
||||
_array.resize(sz);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool DynamicListContainer<T>::expandToMinimumSize(size_t sz) {
|
||||
_array.reserve(sz);
|
||||
@ -730,6 +741,7 @@ struct DynamicList {
|
||||
|
||||
bool getAtIndex(size_t index, DynamicValue &value) const;
|
||||
bool setAtIndex(size_t index, const DynamicValue &value);
|
||||
void truncateToSize(size_t sz);
|
||||
void expandToMinimumSize(size_t sz);
|
||||
size_t getSize() const;
|
||||
|
||||
@ -937,6 +949,32 @@ private:
|
||||
static DynamicValueWriteStringHelper _instance;
|
||||
};
|
||||
|
||||
template<class TClass, MiniscriptInstructionOutcome (TClass::*TWriteMethod)(MiniscriptThread *thread, const DynamicValue &dest), MiniscriptInstructionOutcome (TClass::*TRefAttribMethod)(MiniscriptThread *thread, DynamicValueWriteProxy &proxy, const Common::String &attrib)>
|
||||
struct DynamicValueWriteOrRefAttribFuncHelper : public IDynamicValueWriteInterface {
|
||||
MiniscriptInstructionOutcome write(MiniscriptThread *thread, const DynamicValue &dest, void *objectRef, uintptr ptrOrOffset) const override {
|
||||
return (static_cast<TClass *>(objectRef)->*TWriteMethod)(thread, dest);
|
||||
}
|
||||
MiniscriptInstructionOutcome refAttrib(MiniscriptThread *thread, DynamicValueWriteProxy &proxy, void *objectRef, uintptr ptrOrOffset, const Common::String &attrib) const override {
|
||||
return (static_cast<TClass *>(objectRef)->*TRefAttribMethod)(thread, proxy, attrib);
|
||||
}
|
||||
MiniscriptInstructionOutcome refAttribIndexed(MiniscriptThread *thread, DynamicValueWriteProxy &proxy, void *objectRef, uintptr ptrOrOffset, const Common::String &attrib, const DynamicValue &index) const override {
|
||||
return kMiniscriptInstructionOutcomeFailed;
|
||||
}
|
||||
|
||||
static void create(TClass *obj, DynamicValueWriteProxy &proxy) {
|
||||
proxy.pod.ptrOrOffset = 0;
|
||||
proxy.pod.objectRef = obj;
|
||||
proxy.pod.ifc = &_instance;
|
||||
}
|
||||
|
||||
private:
|
||||
static DynamicValueWriteOrRefAttribFuncHelper _instance;
|
||||
};
|
||||
|
||||
template<class TClass, MiniscriptInstructionOutcome (TClass::*TWriteMethod)(MiniscriptThread *thread, const DynamicValue &dest), MiniscriptInstructionOutcome (TClass::*TRefAttribMethod)(MiniscriptThread *thread, DynamicValueWriteProxy &proxy, const Common::String &attrib)>
|
||||
DynamicValueWriteOrRefAttribFuncHelper<TClass, TWriteMethod, TRefAttribMethod> DynamicValueWriteOrRefAttribFuncHelper<TClass, TWriteMethod, TRefAttribMethod>::_instance;
|
||||
|
||||
|
||||
template<class TClass, MiniscriptInstructionOutcome (TClass::*TWriteMethod)(MiniscriptThread *thread, const DynamicValue &dest)>
|
||||
struct DynamicValueWriteFuncHelper : public IDynamicValueWriteInterface {
|
||||
MiniscriptInstructionOutcome write(MiniscriptThread *thread, const DynamicValue &dest, void *objectRef, uintptr ptrOrOffset) const override {
|
||||
@ -1462,6 +1500,9 @@ public:
|
||||
|
||||
Audio::Mixer *getAudioMixer() const;
|
||||
|
||||
Hacks &getHacks();
|
||||
const Hacks &getHacks() const;
|
||||
|
||||
#ifdef MTROPOLIS_DEBUG_ENABLE
|
||||
void debugSetEnabled(bool enabled);
|
||||
void debugBreak();
|
||||
@ -1633,6 +1674,8 @@ private:
|
||||
uint32 _modifierOverrideCursorID;
|
||||
bool _haveModifierOverrideCursor;
|
||||
|
||||
Hacks _hacks;
|
||||
|
||||
#ifdef MTROPOLIS_DEBUG_ENABLE
|
||||
Common::SharedPtr<Debugger> _debugger;
|
||||
#endif
|
||||
@ -2166,12 +2209,16 @@ protected:
|
||||
|
||||
MiniscriptInstructionOutcome scriptSetDirect(MiniscriptThread *thread, const DynamicValue &dest);
|
||||
MiniscriptInstructionOutcome scriptSetPosition(MiniscriptThread *thread, const DynamicValue &dest);
|
||||
MiniscriptInstructionOutcome scriptSetPositionX(MiniscriptThread *thread, const DynamicValue &dest);
|
||||
MiniscriptInstructionOutcome scriptSetPositionY(MiniscriptThread *thread, const DynamicValue &dest);
|
||||
MiniscriptInstructionOutcome scriptSetCenterPosition(MiniscriptThread *thread, const DynamicValue &dest);
|
||||
MiniscriptInstructionOutcome scriptSetVisibility(MiniscriptThread *thread, const DynamicValue &result);
|
||||
MiniscriptInstructionOutcome scriptSetWidth(MiniscriptThread *thread, const DynamicValue &dest);
|
||||
MiniscriptInstructionOutcome scriptSetHeight(MiniscriptThread *thread, const DynamicValue &dest);
|
||||
MiniscriptInstructionOutcome scriptSetLayer(MiniscriptThread *thread, const DynamicValue &dest);
|
||||
|
||||
MiniscriptInstructionOutcome scriptWriteRefPositionAttribute(MiniscriptThread *thread, DynamicValueWriteProxy &writeProxy, const Common::String &attrib);
|
||||
|
||||
void offsetTranslate(int32 xDelta, int32 yDelta, bool cachedOriginOnly);
|
||||
|
||||
Point16 getCenterPosition() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user