aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/illusions/illusions.cpp26
-rw-r--r--engines/illusions/illusions.h6
-rw-r--r--engines/illusions/module.mk2
-rw-r--r--engines/illusions/scriptman.cpp60
-rw-r--r--engines/illusions/scriptman.h20
-rw-r--r--engines/illusions/scriptopcodes.cpp86
-rw-r--r--engines/illusions/scriptopcodes.h55
-rw-r--r--engines/illusions/scriptresource.cpp31
-rw-r--r--engines/illusions/scriptresource.h1
-rw-r--r--engines/illusions/scriptthread.cpp103
-rw-r--r--engines/illusions/scriptthread.h66
-rw-r--r--engines/illusions/thread.cpp43
-rw-r--r--engines/illusions/thread.h21
13 files changed, 477 insertions, 43 deletions
diff --git a/engines/illusions/illusions.cpp b/engines/illusions/illusions.cpp
index 3ff6750718..a3ed76ee3b 100644
--- a/engines/illusions/illusions.cpp
+++ b/engines/illusions/illusions.cpp
@@ -85,35 +85,51 @@ Common::Error IllusionsEngine::run() {
_resSys->addResourceLoader(0x000D0000, new ScriptResourceLoader(this));
_resSys->addResourceLoader(0x00100000, new ActorResourceLoader(this));
_resSys->addResourceLoader(0x00110000, new BackgroundResourceLoader(this));
+
+ _scriptMan = new ScriptMan(this);
- _actorItems = new ActorItems(this);
+ _actorItems = new ActorItems(this);
_backgroundItems = new BackgroundItems(this);
_camera = new Camera(this);
- /*
+#if 0
// ActorResource test
_resSys->loadResource(0x00100006, 0, 0);
- */
+#endif
- /*
+#if 0
// BackgroundResource test
_resSys->loadResource(0x0011000B, 0, 0);
BackgroundItem *backgroundItem = _backgroundItems->debugFirst();
_system->copyRectToScreen(backgroundItem->_surfaces[0]->getPixels(), backgroundItem->_surfaces[0]->pitch,
0, 0, 640, 480);
_system->updateScreen();
- */
+#endif
+#if 1
// ScriptResource test
_resSys->loadResource(0x000D0001, 0, 0);
+
+ _scriptMan->startScriptThread(0x00020004, 0, 0, 0, 0);
+
+ while (!shouldQuit()) {
+ updateEvents();
+ _scriptMan->_threads->updateThreads();
+ }
+
+
+#endif
+#if 0
while (!shouldQuit()) {
updateEvents();
}
+#endif
delete _camera;
delete _backgroundItems;
delete _actorItems;
+ delete _scriptMan;
delete _resSys;
return Common::kNoError;
diff --git a/engines/illusions/illusions.h b/engines/illusions/illusions.h
index f283f17255..bfb7335be4 100644
--- a/engines/illusions/illusions.h
+++ b/engines/illusions/illusions.h
@@ -55,6 +55,7 @@ class BackgroundItems;
class BackgroundResource;
class Camera;
class ScriptResource;
+class ScriptMan;
class IllusionsEngine : public Engine {
protected:
@@ -74,11 +75,10 @@ public:
void updateEvents();
- ActorItems *_actorItems;
+ ScriptMan *_scriptMan;
+ ActorItems *_actorItems;
BackgroundItems *_backgroundItems;
Camera *_camera;
-
- ScriptResource *_scriptResource;
// Screen functions
Graphics::Surface *allocSurface(int16 width, int16 height);
diff --git a/engines/illusions/module.mk b/engines/illusions/module.mk
index 5ba65d7e9d..8dd462c86e 100644
--- a/engines/illusions/module.mk
+++ b/engines/illusions/module.mk
@@ -12,7 +12,9 @@ MODULE_OBJS := \
input.o \
resourcesystem.o \
scriptman.o \
+ scriptopcodes.o \
scriptresource.o \
+ scriptthread.o \
spritedecompressqueue.o \
spritedrawqueue.o \
thread.o \
diff --git a/engines/illusions/scriptman.cpp b/engines/illusions/scriptman.cpp
index 922ce605bb..25b8d2e902 100644
--- a/engines/illusions/scriptman.cpp
+++ b/engines/illusions/scriptman.cpp
@@ -22,11 +22,17 @@
#include "illusions/illusions.h"
#include "illusions/scriptman.h"
+#include "illusions/scriptthread.h"
+#include "illusions/scriptopcodes.h"
namespace Illusions {
// ActiveScenes
+ActiveScenes::ActiveScenes() {
+ clear();
+}
+
void ActiveScenes::clear() {
_stack.clear();
}
@@ -112,10 +118,14 @@ int16 ScriptStack::peek() {
// ScriptMan
ScriptMan::ScriptMan(IllusionsEngine *vm)
- : _vm(vm) {
+ : _vm(vm), _pauseCtr(0), _doScriptThreadInit(false) {
+ _threads = new ThreadList(vm);
+ _scriptOpcodes = new ScriptOpcodes(vm);
}
ScriptMan::~ScriptMan() {
+ delete _threads;
+ delete _scriptOpcodes;
}
void ScriptMan::setSceneIdThreadId(uint32 theSceneId, uint32 theThreadId) {
@@ -123,4 +133,52 @@ void ScriptMan::setSceneIdThreadId(uint32 theSceneId, uint32 theThreadId) {
_theThreadId = theThreadId;
}
+void ScriptMan::startScriptThread(uint32 threadId, uint32 callingThreadId,
+ uint32 value8, uint32 valueC, uint32 value10) {
+ debug("Starting script thread %08X", threadId);
+ byte *scriptCodeIp = _scriptResource->getThreadCode(threadId);
+ newScriptThread(threadId, callingThreadId, 0, scriptCodeIp, value8, valueC, value10);
+}
+
+void ScriptMan::startAnonScriptThread(int32 threadId, uint32 callingThreadId,
+ uint32 value8, uint32 valueC, uint32 value10) {
+ debug("Starting anonymous script thread %08X", threadId);
+ uint32 tempThreadId = newTempThreadId();
+ byte *scriptCodeIp = _scriptResource->getThreadCode(threadId);
+ scriptCodeIp = _scriptResource->getThreadCode(threadId);
+ newScriptThread(tempThreadId, callingThreadId, 0, scriptCodeIp, value8, valueC, value10);
+}
+
+uint32 ScriptMan::startTempScriptThread(byte *scriptCodeIp, uint32 callingThreadId,
+ uint32 value8, uint32 valueC, uint32 value10) {
+ debug("Starting temp script thread");
+ uint32 tempThreadId = newTempThreadId();
+ newScriptThread(tempThreadId, callingThreadId, 0, scriptCodeIp, value8, valueC, value10);
+ return tempThreadId;
+}
+
+void ScriptMan::newScriptThread(uint32 threadId, uint32 callingThreadId, uint notifyFlags,
+ byte *scriptCodeIp, uint32 value8, uint32 valueC, uint32 value10) {
+ ScriptThread *scriptThread = new ScriptThread(_vm, threadId, callingThreadId,
+ notifyFlags, scriptCodeIp, value8, valueC, value10);
+ _threads->startThread(scriptThread);
+ if (_pauseCtr > 0)
+ scriptThread->pause();
+ if (_doScriptThreadInit) {
+ int updateResult = 4;
+ while (scriptThread->_pauseCtr <= 0 && updateResult != 1 && updateResult != 2)
+ updateResult = scriptThread->update();
+ }
+}
+
+uint32 ScriptMan::newTempThreadId() {
+ uint32 threadId = _nextTempThreadId + 2 * _scriptResource->_codeCount;
+ if (threadId > 65535) {
+ _nextTempThreadId = 0;
+ threadId = 2 * _scriptResource->_codeCount;
+ }
+ ++_nextTempThreadId;
+ return 0x00020000 | threadId;
+}
+
} // End of namespace Illusions
diff --git a/engines/illusions/scriptman.h b/engines/illusions/scriptman.h
index acfd51491a..031fa19851 100644
--- a/engines/illusions/scriptman.h
+++ b/engines/illusions/scriptman.h
@@ -31,6 +31,7 @@
namespace Illusions {
class IllusionsEngine;
+class ScriptOpcodes;
struct ActiveScene {
uint32 _sceneId;
@@ -70,17 +71,34 @@ public:
ScriptMan(IllusionsEngine *vm);
~ScriptMan();
void setSceneIdThreadId(uint32 theSceneId, uint32 theThreadId);
+ void startScriptThread(uint32 threadId, uint32 callingThreadId,
+ uint32 value8, uint32 valueC, uint32 value10);
+ void startAnonScriptThread(int32 threadId, uint32 callingThreadId,
+ uint32 value8, uint32 valueC, uint32 value10);
+ uint32 startTempScriptThread(byte *scriptCodeIp, uint32 callingThreadId,
+ uint32 value8, uint32 valueC, uint32 value10);
public:
IllusionsEngine *_vm;
+ ScriptResource *_scriptResource;
+
ActiveScenes _activeScenes;
ScriptStack _stack;
+ int _pauseCtr;
+
uint32 _theSceneId;
uint32 _theThreadId;
+ bool _doScriptThreadInit;
+ uint32 _nextTempThreadId;
+ ThreadList *_threads;
+ ScriptOpcodes *_scriptOpcodes;
-
+ void newScriptThread(uint32 threadId, uint32 callingThreadId, uint notifyFlags,
+ byte *scriptCodeIp, uint32 value8, uint32 valueC, uint32 value10);
+ uint32 newTempThreadId();
+
};
} // End of namespace Illusions
diff --git a/engines/illusions/scriptopcodes.cpp b/engines/illusions/scriptopcodes.cpp
new file mode 100644
index 0000000000..ac38548faa
--- /dev/null
+++ b/engines/illusions/scriptopcodes.cpp
@@ -0,0 +1,86 @@
+/* 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 "illusions/illusions.h"
+#include "illusions/scriptopcodes.h"
+#include "illusions/scriptman.h"
+#include "illusions/scriptresource.h"
+#include "illusions/scriptthread.h"
+
+namespace Illusions {
+
+// ScriptOpcodes
+
+ScriptOpcodes::ScriptOpcodes(IllusionsEngine *vm)
+ : _vm(vm) {
+ initOpcodes();
+}
+
+ScriptOpcodes::~ScriptOpcodes() {
+ freeOpcodes();
+}
+
+void ScriptOpcodes::execOpcode(ScriptThread *scriptThread, OpCall &opCall) {
+ if (!_opcodes[opCall._op])
+ error("ScriptOpcodes::execOpcode() Unimplemented opcode %d", opCall._op);
+ debug("execOpcode(%d)", opCall._op);
+ (*_opcodes[opCall._op])(scriptThread, opCall);
+}
+
+typedef Common::Functor2Mem<ScriptThread*, OpCall&, void, ScriptOpcodes> ScriptOpcodeI;
+#define OPCODE(op, func) _opcodes[op] = new ScriptOpcodeI(this, &ScriptOpcodes::func);
+
+void ScriptOpcodes::initOpcodes() {
+ // First clear everything
+ for (uint i = 0; i < 256; ++i)
+ _opcodes[i] = 0;
+ // Register opcodes
+ OPCODE(42, opIncBlockCounter);
+ OPCODE(126, opDebug126);
+}
+
+#undef OPCODE
+
+void ScriptOpcodes::freeOpcodes() {
+ for (uint i = 0; i < 256; ++i)
+ delete _opcodes[i];
+}
+
+// Opcodes
+
+// Convenience macros
+#define ARG_SKIP(x) opCall.skip(x);
+#define ARG_INT16(name) int16 name = opCall.readSint16(); debug("ARG_INT16(" #name " = %d)", name);
+#define ARG_UINT32(name) uint32 name = opCall.readUint32(); debug("ARG_UINT32(" #name " = %d)", name);
+
+void ScriptOpcodes::opIncBlockCounter(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_INT16(index)
+ byte value = _vm->_scriptMan->_scriptResource->_blockCounters.get(index + 1);
+ if (value <= 63)
+ _vm->_scriptMan->_scriptResource->_blockCounters.set(index + 1, value);
+}
+
+void ScriptOpcodes::opDebug126(ScriptThread *scriptThread, OpCall &opCall) {
+ // NOTE Prints some debug text
+}
+
+} // End of namespace Illusions
diff --git a/engines/illusions/scriptopcodes.h b/engines/illusions/scriptopcodes.h
new file mode 100644
index 0000000000..78b68e5b59
--- /dev/null
+++ b/engines/illusions/scriptopcodes.h
@@ -0,0 +1,55 @@
+/* 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.
+ *
+ */
+
+#ifndef ILLUSIONS_SCRIPTOPCODES_H
+#define ILLUSIONS_SCRIPTOPCODES_H
+
+#include "common/func.h"
+
+namespace Illusions {
+
+class IllusionsEngine;
+class ScriptThread;
+struct OpCall;
+
+typedef Common::Functor2<ScriptThread*, OpCall&, void> ScriptOpcode;
+
+class ScriptOpcodes {
+public:
+ ScriptOpcodes(IllusionsEngine *vm);
+ ~ScriptOpcodes();
+ void execOpcode(ScriptThread *scriptThread, OpCall &opCall);
+protected:
+ IllusionsEngine *_vm;
+ ScriptOpcode *_opcodes[256];
+ void initOpcodes();
+ void freeOpcodes();
+
+ // Opcodes
+ void opIncBlockCounter(ScriptThread *scriptThread, OpCall &opCall);
+ void opDebug126(ScriptThread *scriptThread, OpCall &opCall);
+
+};
+
+} // End of namespace Illusions
+
+#endif // ILLUSIONS_SCRIPTOPCODES_H
diff --git a/engines/illusions/scriptresource.cpp b/engines/illusions/scriptresource.cpp
index 5d9b86a36e..545e79babb 100644
--- a/engines/illusions/scriptresource.cpp
+++ b/engines/illusions/scriptresource.cpp
@@ -22,20 +22,19 @@
#include "illusions/illusions.h"
#include "illusions/scriptresource.h"
+#include "illusions/scriptman.h"
namespace Illusions {
// ScriptResourceLoader
void ScriptResourceLoader::load(Resource *resource) {
- debug("ScriptResourceLoader::load() Loading script %08X from %s...", resource->_resId, resource->_filename.c_str());
+ debug(2, "ScriptResourceLoader::load() Loading script %08X from %s...", resource->_resId, resource->_filename.c_str());
ScriptResource *scriptResource = new ScriptResource();
scriptResource->load(resource->_data, resource->_dataSize);
-
-
- _vm->_scriptResource = scriptResource;
+ _vm->_scriptMan->_scriptResource = scriptResource;
}
@@ -77,11 +76,11 @@ void BlockCounters::clear() {
}
byte BlockCounters::get(uint index) {
- return _blockCounters[index] & 0x3F;
+ return _blockCounters[index - 1] & 0x3F;
}
void BlockCounters::set(uint index, byte value) {
- _blockCounters[index] = (get(index) ^ value) & 0x3F;
+ _blockCounters[index - 1] = (get(index - 1) ^ value) & 0x3F;
}
// TriggerCause
@@ -91,7 +90,7 @@ void TriggerCause::load(Common::SeekableReadStream &stream) {
_objectId2 = stream.readUint32LE();
_codeOffs = stream.readUint32LE();
- debug("TriggerCause::load() _verbId: %08X; _objectId2: %08X; _codeOffs: %08X",
+ debug(2, "TriggerCause::load() _verbId: %08X; _objectId2: %08X; _codeOffs: %08X",
_verbId, _objectId2, _codeOffs);
}
@@ -109,7 +108,7 @@ void TriggerObject::load(byte *dataStart, Common::SeekableReadStream &stream) {
_objectId = stream.readUint32LE();
_causesCount = stream.readUint16LE();
stream.skip(2); // Skip padding
- debug("TriggerObject::load() _objectId: %08X; _causesCount: %d",
+ debug(2, "TriggerObject::load() _objectId: %08X; _causesCount: %d",
_objectId, _causesCount);
_causes = new TriggerCause[_causesCount];
for (uint i = 0; i < _causesCount; ++i)
@@ -144,7 +143,7 @@ void ProgInfo::load(byte *dataStart, Common::SeekableReadStream &stream) {
stream.skip(128);
_triggerObjectsCount = stream.readUint16LE();
stream.skip(2); // Skip padding
- debug("\nProgInfo::load() _id: %d; _unk: %d; _name: [%s]",
+ debug(2, "\nProgInfo::load() _id: %d; _unk: %d; _name: [%s]",
_id, _unk, debugW2I(_name));
uint32 triggerObjectsListOffs = stream.readUint32LE();
if (_triggerObjectsCount > 0) {
@@ -177,7 +176,7 @@ void ScriptResource::load(byte *data, uint32 dataSize) {
stream.skip(4); // Skip unused
uint propertiesCount = stream.readUint16LE();
uint blockCountersCount = stream.readUint16LE();
- uint codeCount = stream.readUint16LE();
+ _codeCount = stream.readUint16LE();
_progInfosCount = stream.readUint16LE();
uint32 propertiesOffs = stream.readUint32LE();
uint32 blockCountersOffs = stream.readUint32LE();
@@ -189,9 +188,9 @@ void ScriptResource::load(byte *data, uint32 dataSize) {
// Init blockcounters
_blockCounters.init(blockCountersCount, data + blockCountersOffs);
- _codeOffsets = new uint32[codeCount];
+ _codeOffsets = new uint32[_codeCount];
stream.seek(codeTblOffs);
- for (uint i = 0; i < codeCount; ++i)
+ for (uint i = 0; i < _codeCount; ++i)
_codeOffsets[i] = stream.readUint32LE();
_progInfos = new ProgInfo[_progInfosCount];
@@ -202,15 +201,15 @@ void ScriptResource::load(byte *data, uint32 dataSize) {
_progInfos[i].load(data, stream);
}
- debug("ScriptResource::load() propertiesCount: %d; blockCountersCount: %d; codeCount: %d; _progInfosCount: %d",
- propertiesCount, blockCountersCount, codeCount, _progInfosCount);
- debug("ScriptResource::load() propertiesOffs: %08X; blockCountersOffs: %08X; codeTblOffs: %08X",
+ debug(2, "ScriptResource::load() propertiesCount: %d; blockCountersCount: %d; _codeCount: %d; _progInfosCount: %d",
+ propertiesCount, blockCountersCount, _codeCount, _progInfosCount);
+ debug(2, "ScriptResource::load() propertiesOffs: %08X; blockCountersOffs: %08X; codeTblOffs: %08X",
propertiesOffs, blockCountersOffs, codeTblOffs);
}
byte *ScriptResource::getThreadCode(uint32 threadId) {
- return _data + _codeOffsets[threadId & 0xFFFF];
+ return _data + _codeOffsets[(threadId & 0xFFFF) - 1];
}
} // End of namespace Illusions
diff --git a/engines/illusions/scriptresource.h b/engines/illusions/scriptresource.h
index 206aa4b77d..d659f43d21 100644
--- a/engines/illusions/scriptresource.h
+++ b/engines/illusions/scriptresource.h
@@ -104,6 +104,7 @@ public:
uint32 _dataSize;
Properties _properties;
BlockCounters _blockCounters;
+ uint _codeCount;
uint32 *_codeOffsets;
uint _progInfosCount;
ProgInfo *_progInfos;
diff --git a/engines/illusions/scriptthread.cpp b/engines/illusions/scriptthread.cpp
new file mode 100644
index 0000000000..a594101107
--- /dev/null
+++ b/engines/illusions/scriptthread.cpp
@@ -0,0 +1,103 @@
+/* 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 "illusions/illusions.h"
+#include "illusions/scriptthread.h"
+#include "illusions/scriptman.h"
+#include "illusions/scriptopcodes.h"
+
+namespace Illusions {
+
+// OpCall
+
+void OpCall::skip(uint size) {
+ _scriptCode += size;
+}
+
+byte OpCall::readByte() {
+ return *_scriptCode++;
+}
+
+int16 OpCall::readSint16() {
+ int16 value = READ_LE_UINT16(_scriptCode);
+ _scriptCode += 2;
+ return value;
+}
+
+uint32 OpCall::readUint32() {
+ uint32 value = READ_LE_UINT32(_scriptCode);
+ _scriptCode += 4;
+ return value;
+}
+
+// ScriptThread
+
+ScriptThread::ScriptThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThreadId, uint notifyFlags,
+ byte *scriptCodeIp, uint32 value8, uint32 valueC, uint32 value10)
+ : Thread(vm, threadId, callingThreadId, notifyFlags), _scriptCodeIp(scriptCodeIp), _value8(value8),
+ _valueC(valueC), _value10(value10), _sequenceStalled(0) {
+ _type = kTTScriptThread;
+}
+
+int ScriptThread::onUpdate() {
+ OpCall opCall;
+ opCall._result = kTSRun;
+ while (!_terminated && opCall._result == 4) {
+ opCall._op = _scriptCodeIp[0];
+ opCall._opSize = _scriptCodeIp[1] >> 1;
+ opCall._threadId = _scriptCodeIp[1] & 1 ? _threadId : 0;
+ opCall._scriptCode = _scriptCodeIp + 2;
+ opCall._deltaOfs = 0;
+ execOpcode(opCall);
+ _scriptCodeIp += opCall._opSize + opCall._deltaOfs;
+ }
+ if (_terminated)
+ opCall._result = kTSTerminate;
+ return opCall._result;
+}
+
+void ScriptThread::onSuspend() {
+ // TODO
+}
+
+void ScriptThread::onNotify() {
+ // TODO
+}
+
+void ScriptThread::onPause() {
+ // TODO
+}
+
+void ScriptThread::onResume() {
+ // TODO
+}
+
+void ScriptThread::onTerminated() {
+ // TODO
+}
+
+void ScriptThread::execOpcode(OpCall &opCall) {
+ // TODO Clean this up
+ _vm->_scriptMan->_scriptOpcodes->execOpcode(this, opCall);
+}
+
+} // End of namespace Illusions
diff --git a/engines/illusions/scriptthread.h b/engines/illusions/scriptthread.h
new file mode 100644
index 0000000000..201e598756
--- /dev/null
+++ b/engines/illusions/scriptthread.h
@@ -0,0 +1,66 @@
+/* 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.
+ *
+ */
+
+#ifndef ILLUSIONS_SCRIPTTHREAD_H
+#define ILLUSIONS_SCRIPTTHREAD_H
+
+#include "illusions/thread.h"
+
+namespace Illusions {
+
+class IllusionsEngine;
+
+struct OpCall {
+ byte _op;
+ byte _opSize;
+ uint32 _threadId;
+ int16 _deltaOfs;
+ byte *_scriptCode;
+ int _result;
+ void skip(uint size);
+ byte readByte();
+ int16 readSint16();
+ uint32 readUint32();
+};
+
+class ScriptThread : public Thread {
+public:
+ ScriptThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThreadId, uint notifyFlags,
+ byte *scriptCodeIp, uint32 value8, uint32 valueC, uint32 value10);
+ virtual int onUpdate();
+ virtual void onSuspend();
+ virtual void onNotify();
+ virtual void onPause();
+ virtual void onResume();
+ virtual void onTerminated();
+public:
+ int16 _sequenceStalled;
+ byte *_scriptCodeIp;
+ uint32 _value8;
+ uint32 _valueC;
+ uint32 _value10;
+ void execOpcode(OpCall &opCall);
+};
+
+} // End of namespace Illusions
+
+#endif // ILLUSIONS_SCRIPTTHREAD_H
diff --git a/engines/illusions/thread.cpp b/engines/illusions/thread.cpp
index 8c2f585360..0bfb82e5cd 100644
--- a/engines/illusions/thread.cpp
+++ b/engines/illusions/thread.cpp
@@ -27,8 +27,31 @@ namespace Illusions {
// Thread
-Thread::Thread(IllusionsEngine *vm)
- : _vm(vm), _pauseCtr(0), _terminated(false) {
+Thread::Thread(IllusionsEngine *vm, uint32 threadId, uint32 callingThreadId, uint notifyFlags)
+ : _vm(vm), _threadId(threadId), _callingThreadId(callingThreadId), _notifyFlags(notifyFlags),
+ _pauseCtr(0), _terminated(false) {
+}
+
+Thread::~Thread() {
+}
+
+int Thread::onUpdate() {
+ return kTSTerminate;
+}
+
+void Thread::onSuspend() {
+}
+
+void Thread::onNotify() {
+}
+
+void Thread::onPause() {
+}
+
+void Thread::onResume() {
+}
+
+void Thread::onTerminated() {
}
void Thread::pause() {
@@ -65,15 +88,15 @@ void Thread::notify() {
int Thread::update() {
// NOTE Deletion of terminated threads handled in caller
- int result = 2;
+ int status = kTSYield;
if (!_terminated && _pauseCtr <= 0) {
- result = onUpdate();
- if (result == 1)
+ status = onUpdate();
+ if (status == kTSTerminate)
terminate();
- else if (result == 3)
+ else if (status == kTSSuspend)
suspend();
}
- return result;
+ return status;
}
void Thread::terminate() {
@@ -111,9 +134,9 @@ void ThreadList::updateThreads() {
it = _threads.erase(it);
delete thread;
} else {
- int updateResult = 4;
- while (!thread->_terminated && updateResult != 1 && updateResult != 2)
- updateResult = thread->update();
+ int status = kTSRun;
+ while (!thread->_terminated && status != kTSTerminate && status != kTSYield)
+ status = thread->update();
++it;
}
}
diff --git a/engines/illusions/thread.h b/engines/illusions/thread.h
index 2a2c0f10d2..eab92aeaad 100644
--- a/engines/illusions/thread.h
+++ b/engines/illusions/thread.h
@@ -36,16 +36,23 @@ enum ThreadType {
kTTSpecialThread = 5
};
+enum ThreadStatus {
+ kTSTerminate = 1,
+ kTSYield = 2,
+ kTSSuspend = 3,
+ kTSRun = 4
+};
+
class Thread {
public:
- Thread(IllusionsEngine *vm);
+ Thread(IllusionsEngine *vm, uint32 threadId, uint32 callingThreadId, uint notifyFlags);
virtual ~Thread();
- virtual int onUpdate() = 0;
- virtual void onSuspend() = 0;
- virtual void onNotify() = 0;
- virtual void onPause() = 0;
- virtual void onResume() = 0;
- virtual void onTerminated() = 0;
+ virtual int onUpdate();
+ virtual void onSuspend();
+ virtual void onNotify();
+ virtual void onPause();
+ virtual void onResume();
+ virtual void onTerminated();
void pause();
void resume();
void suspend();