diff options
-rw-r--r-- | engines/macventure/macventure.cpp | 6 | ||||
-rw-r--r-- | engines/macventure/module.mk | 3 | ||||
-rw-r--r-- | engines/macventure/script.cpp | 174 | ||||
-rw-r--r-- | engines/macventure/script.h | 77 | ||||
-rw-r--r-- | engines/macventure/world.cpp | 20 | ||||
-rw-r--r-- | engines/macventure/world.h | 3 |
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(); |