aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/macventure/macventure.cpp6
-rw-r--r--engines/macventure/module.mk3
-rw-r--r--engines/macventure/script.cpp174
-rw-r--r--engines/macventure/script.h77
-rw-r--r--engines/macventure/world.cpp20
-rw-r--r--engines/macventure/world.h3
6 files changed, 254 insertions, 29 deletions
diff --git a/engines/macventure/macventure.cpp b/engines/macventure/macventure.cpp
index 75f2c33711..78884cf1bf 100644
--- a/engines/macventure/macventure.cpp
+++ b/engines/macventure/macventure.cpp
@@ -92,7 +92,7 @@ Common::Error MacVentureEngine::run() {
// Big class instantiation
_gui = new Gui(this, _resourceManager);
_world = new World(this, _resourceManager);
- _scriptEngine = new ScriptEngine();
+ _scriptEngine = new ScriptEngine(_world);
_paused = false;
_halted = true;
@@ -233,7 +233,7 @@ bool MacVenture::MacVentureEngine::runScriptEngine() {
debug(4, "MAIN: Running script engine");
if (_haltedAtEnd) {
_haltedAtEnd = false;
- if (_scriptEngine->resume()) {
+ if (_scriptEngine->resume(false)) {
_haltedAtEnd = true;
return true;
}
@@ -242,7 +242,7 @@ bool MacVenture::MacVentureEngine::runScriptEngine() {
if (_haltedInSelection) {
_haltedInSelection = false;
- if (_scriptEngine->resume()) {
+ if (_scriptEngine->resume(false)) {
_haltedInSelection = true;
return true;
}
diff --git a/engines/macventure/module.mk b/engines/macventure/module.mk
index 47e0c702e4..c0dc818d96 100644
--- a/engines/macventure/module.mk
+++ b/engines/macventure/module.mk
@@ -5,8 +5,9 @@ MODULE_OBJS := \
gui.o \
object.o \
text.o \
- macventure.o \
world.o \
+ script.o \
+ macventure.o
MODULE_DIRS += \
engines/macventure
diff --git a/engines/macventure/script.cpp b/engines/macventure/script.cpp
new file mode 100644
index 0000000000..7e594f5a11
--- /dev/null
+++ b/engines/macventure/script.cpp
@@ -0,0 +1,174 @@
+/* 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 2
+* 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, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#include "macventure/macventure.h"
+#include "macventure/script.h"
+#include "macventure/world.h"
+#include "macventure/container.h"
+
+namespace MacVenture {
+
+ScriptEngine::ScriptEngine(World * world) {
+ _world = world;
+ _scripts = new Container("Shadowgate II/Shadow Filter");
+}
+
+ScriptEngine::~ScriptEngine() {
+ if (_scripts)
+ delete _scripts;
+}
+
+bool ScriptEngine::runControl(ControlAction action, ObjID source, ObjID destination, Common::Point delta) {
+ //debug(7, "SCRIPT: Running control %d from obj %d into obj %d, at delta (%d, %d)",
+ // action, source, destination, delta.x, delta.y);
+
+ EngineFrame frame;
+ frame.action = action;
+ frame.src = source;
+ frame.dest = destination;
+ frame.x = delta.x;
+ frame.y = delta.y;
+ frame.haltedInSaves = false;
+ frame.haltedInFirst = false;
+ frame.haltedInFamily = false;
+ _frames.push_back(frame);
+ debug(7, "SCRIPT: Stored frame %d, action: %d src: %d dest: %d point: (%d, %d)",
+ _frames.size() - 1, frame.action, frame.src, frame.dest, frame.x, frame.y);
+
+ return resume(true);
+}
+
+bool ScriptEngine::resume(bool execAll) {
+ debug(7, "SCRIPT: Resume");
+ while (_frames.size()) {
+ bool fail = execFrame(execAll);
+ if (fail) return true;
+ }
+ return false;
+}
+
+void ScriptEngine::reset() {
+ _frames.clear();
+}
+
+bool ScriptEngine::execFrame(bool execAll) {
+ bool doFirst = execAll;
+ bool doFamily = false;
+ bool fail;
+
+ EngineFrame *frame = &_frames.front();
+
+ // Do first dispatch script (script 0)
+ if (frame->haltedInFirst || doFirst) { // We were stuck or it's the first time
+ frame->haltedInFirst = false;
+ if (doFirst) { fail = loadScript(frame, 0); }
+ else { fail = resumeFunc(frame); }
+ if (fail) {
+ frame->haltedInFirst = true;
+ return true;
+ }
+ doFamily = true;
+ frame->familyIdx = 0;
+ }
+
+ // Do scripts in the family of player (ObjID 1)
+ if (frame->haltedInFamily || doFamily) { // We have to do the family or we were stuck here
+ frame->haltedInFamily = false;
+ Common::Array<ObjID> family = _world->getFamily(_world->getObjAttr(1, kAttrParentObject), false);
+ uint32 i = frame->familyIdx;
+ for (; i < family.size(); i++) {
+ if (doFamily) { fail = loadScript(frame, family[i]); }
+ else { fail = resumeFunc(frame); }
+ if (fail) { // We are stuck, so we don't shift the frame
+ frame->haltedInFamily = true;
+ frame->familyIdx = i;
+ return true;
+ }
+ doFamily = true;
+ }
+ }
+
+ //Handle saves
+ /*
+
+ uint highest;
+ uint high;
+ if (frame->haltedInSaves) {
+ frame->haltedInSaves = false;
+ }
+
+
+ do {
+ highest = 0;
+ for (uint i = 0; i < frame->haltedInSaves.size)
+ }
+ */
+
+ _frames.remove_at(0);
+ return false;
+}
+
+bool ScriptEngine::loadScript(EngineFrame * frame, uint32 scriptID) {
+ frame->scripts.push_back(ScriptAsset(scriptID, _scripts));
+ return false;
+}
+
+bool ScriptEngine::resumeFunc(EngineFrame * frame) {
+ bool fail = runFunc();
+ if (fail) return fail;
+ frame->scripts.remove_at(0);
+ if (frame->scripts.size())
+ return resumeFunc(frame);
+ return false;
+}
+
+bool ScriptEngine::runFunc() {
+ debug(7, "SCRIPT: I'm running the function");
+ return false;
+}
+
+ScriptAsset::ScriptAsset(ObjID id, Container * container) {
+ _id = id;
+ _container = container;
+ _ip = 0x0;
+}
+
+void ScriptAsset::reset() {
+ _ip = 0x0;
+}
+
+uint8 ScriptAsset::fecth() {
+ uint8 ins = _instructions[_ip];
+ _ip++;
+ return ins;
+}
+
+void ScriptAsset::loadInstructions() {
+ uint32 amount = _container->getItemByteSize(_id);
+ Common::SeekableReadStream *res = _container->getItem(_id);
+ for (uint i = 0; i < amount; i++) {
+ _instructions.push_back(res->readByte());
+ }
+ debug(7, "SCRIPT: Load %d instructions for script %d", amount, _id);
+}
+
+} // End of namespace MacVenture \ No newline at end of file
diff --git a/engines/macventure/script.h b/engines/macventure/script.h
index 9814c01ad4..d66a867eca 100644
--- a/engines/macventure/script.h
+++ b/engines/macventure/script.h
@@ -23,10 +23,13 @@
#ifndef MACVENTURE_SCRIPT_H
#define MACVENTURE_SCRIPT_H
-#include "macventure/macventure.h"
#include "macventure/container.h"
+#include "macventure/world.h"
namespace MacVenture {
+
+class Container;
+class World;
enum ControlAction {
kNoCommand = 0,
@@ -51,42 +54,68 @@ typedef uint32 ObjID;
class ScriptAsset {
public:
- ScriptAsset(ObjID id, Container *container, MacVentureEngine *engine) {
- _id = id;
- _container = container;
- _engine = engine;
- }
- ~ScriptAsset() {
+ ScriptAsset(ObjID id, Container *container);
+ ~ScriptAsset() {}
- }
+ void reset();
+ uint8 fecth();
- void execute() {
- debug("SCRIPT: Executing script %x ", _id);
- }
+private:
+
+ void loadInstructions();
private:
ObjID _id;
Container *_container;
- MacVentureEngine *_engine;
+
+ Common::Array<uint8> _instructions;
+ uint32 _ip; // Instruction pointer
+};
+
+struct EngineState {
+ uint8 stack[0x80];
+ uint8 sp;
+
+ EngineState() {
+ sp = 0x80;
+ }
+};
+
+struct EngineFrame {
+ ControlAction action;
+ ObjID src;
+ ObjID dest;
+ int x;
+ int y;
+ EngineState state;
+ Common::Array<ScriptAsset> scripts;
+ uint32 familyIdx;
+
+ bool haltedInFirst;
+ bool haltedInFamily;
+ bool haltedInSaves;
};
class ScriptEngine {
public:
- ScriptEngine() {}
- ~ScriptEngine() {}
+ ScriptEngine(World *world);
+ ~ScriptEngine();
- bool runControl(ControlAction action, ObjID source, ObjID destination, Common::Point delta) {
- debug(7, "SCRIPT: Running control %d from obj %d into obj %d, at delta (%d, %d)",
- action, source, destination, delta.x, delta.y);
-
- return false;
- }
+public:
+ bool runControl(ControlAction action, ObjID source, ObjID destination, Common::Point delta);
+ bool resume(bool execAll);
+ void reset();
- bool resume() {
- debug(7, "SCRIPT: Resume");
+private:
+ bool execFrame(bool execAll);
+ bool loadScript(EngineFrame * frame, uint32 scriptID);
+ bool resumeFunc(EngineFrame * frame);
+ bool runFunc();
- return false;
- }
+private:
+ World *_world;
+ Common::Array<EngineFrame> _frames;
+ Container *_scripts;
};
} // End of namespace MacVenture
diff --git a/engines/macventure/world.cpp b/engines/macventure/world.cpp
index feb8c0b7be..2cd50ff82a 100644
--- a/engines/macventure/world.cpp
+++ b/engines/macventure/world.cpp
@@ -1,4 +1,5 @@
#include "macventure/world.h"
+#include "macventure/macventure.h"
#include "common/file.h"
@@ -82,6 +83,25 @@ bool MacVenture::World::isObjActive(ObjID obj) {
return false;
}
+Common::Array<ObjID> World::getFamily(ObjID objID, bool recursive) {
+ Common::Array<ObjID> res;
+ res.push_back(objID);
+ res.push_back(getChildren(objID, recursive));
+ return res;
+}
+
+Common::Array<ObjID> World::getChildren(ObjID objID, bool recursive) {
+ Common::Array<ObjID> res;
+ ObjID child = _relations[objID * 2];
+ while (child) {
+ res.push_back(child);
+ if (!recursive)
+ res.push_back(getChildren(child, false));
+ child = _relations[child * 2 + 1];
+ }
+ return Common::Array<ObjID>();
+}
+
bool World::loadStartGameFileName() {
Common::SeekableReadStream *res;
diff --git a/engines/macventure/world.h b/engines/macventure/world.h
index 58e9fc5ce5..3893aca445 100644
--- a/engines/macventure/world.h
+++ b/engines/macventure/world.h
@@ -23,7 +23,6 @@
#ifndef MACVENTURE_WORLD_H
#define MACVENTURE_WORLD_H
-#include "macventure/macventure.h"
#include "macventure/container.h"
#include "macventure/text.h"
@@ -92,6 +91,8 @@ public:
uint32 getObjAttr(ObjID objID, uint32 attrID);
void setObjAttr(ObjID objID, uint32 attrID, Attribute value);
bool isObjActive(ObjID obj);
+ Common::Array<ObjID> getFamily(ObjID objID, bool recursive);
+ Common::Array<ObjID> getChildren(ObjID objID, bool recursive);
private:
bool loadStartGameFileName();