MACVENTURE: Add untested script engine

This commit is contained in:
Borja Lorente
2016-08-14 18:28:47 +02:00
parent e8725ae068
commit 9b052d0a97
6 changed files with 254 additions and 29 deletions
+3 -3
View File
@@ -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;
}
+2 -1
View File
@@ -5,8 +5,9 @@ MODULE_OBJS := \
gui.o \
object.o \
text.o \
macventure.o \
world.o \
script.o \
macventure.o
MODULE_DIRS += \
engines/macventure
+174
View File
@@ -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
+53 -24
View File
@@ -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
+20
View File
@@ -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;
+2 -1
View File
@@ -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();