diff options
author | johndoe123 | 2014-03-13 19:55:25 +0100 |
---|---|---|
committer | Eugene Sandulenko | 2018-07-20 06:43:33 +0000 |
commit | 9d35f807ecc0cbc7a98a987c02d58d795706ed1f (patch) | |
tree | d92c9e062265b56d2c2797d39f950494b83530ac | |
parent | 9696eb9a546891bf7ff601d94f7a8a2ff6730349 (diff) | |
download | scummvm-rg350-9d35f807ecc0cbc7a98a987c02d58d795706ed1f.tar.gz scummvm-rg350-9d35f807ecc0cbc7a98a987c02d58d795706ed1f.tar.bz2 scummvm-rg350-9d35f807ecc0cbc7a98a987c02d58d795706ed1f.zip |
ILLUSIONS: More work on the script system
-rw-r--r-- | engines/illusions/illusions.cpp | 26 | ||||
-rw-r--r-- | engines/illusions/illusions.h | 6 | ||||
-rw-r--r-- | engines/illusions/module.mk | 2 | ||||
-rw-r--r-- | engines/illusions/scriptman.cpp | 60 | ||||
-rw-r--r-- | engines/illusions/scriptman.h | 20 | ||||
-rw-r--r-- | engines/illusions/scriptopcodes.cpp | 86 | ||||
-rw-r--r-- | engines/illusions/scriptopcodes.h | 55 | ||||
-rw-r--r-- | engines/illusions/scriptresource.cpp | 31 | ||||
-rw-r--r-- | engines/illusions/scriptresource.h | 1 | ||||
-rw-r--r-- | engines/illusions/scriptthread.cpp | 103 | ||||
-rw-r--r-- | engines/illusions/scriptthread.h | 66 | ||||
-rw-r--r-- | engines/illusions/thread.cpp | 43 | ||||
-rw-r--r-- | engines/illusions/thread.h | 21 |
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(); |