mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
MACVENTURE: Add untested script engine
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,9 @@ MODULE_OBJS := \
|
||||
gui.o \
|
||||
object.o \
|
||||
text.o \
|
||||
macventure.o \
|
||||
world.o \
|
||||
script.o \
|
||||
macventure.o
|
||||
|
||||
MODULE_DIRS += \
|
||||
engines/macventure
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user