From d77d4ed4a61d79ffc75bb9dbdab01157da387a13 Mon Sep 17 00:00:00 2001 From: johndoe123 Date: Tue, 1 Apr 2014 11:22:58 +0200 Subject: ILLUSIONS: Fix bug which occured when trying to walk while talking - Fix minor bugs - Work on talk thread handling --- engines/illusions/actor.cpp | 29 +++++++++++++++++++++-------- engines/illusions/actor.h | 1 + engines/illusions/illusions.cpp | 3 ++- engines/illusions/scriptman.cpp | 4 ++-- engines/illusions/scriptopcodes.cpp | 16 ++++++++-------- engines/illusions/scriptthread.cpp | 25 ------------------------- engines/illusions/scriptthread.h | 5 ----- engines/illusions/sequenceopcodes.cpp | 6 +++--- engines/illusions/specialcode.cpp | 2 -- engines/illusions/thread.cpp | 16 ++++++++++++---- engines/illusions/thread.h | 1 + engines/illusions/timerthread.cpp | 9 ++++++++- 12 files changed, 58 insertions(+), 59 deletions(-) diff --git a/engines/illusions/actor.cpp b/engines/illusions/actor.cpp index 2973a92f73..42f16ca951 100644 --- a/engines/illusions/actor.cpp +++ b/engines/illusions/actor.cpp @@ -540,8 +540,8 @@ void Control::stopActor() { _actor->_pathPointIndex = 0; _actor->_walkCallerThreadId1 = 0; } - _vm->notifyThreadId(_actor->_notifyThreadId1); _vm->notifyThreadId(_actor->_notifyId3C); + _vm->notifyThreadId(_actor->_notifyThreadId1); } void Control::startSequenceActor(uint32 sequenceId, int value, uint32 notifyThreadId) { @@ -569,7 +569,7 @@ void Control::startTalkActor(uint32 sequenceId, byte *entryTblPtr, uint32 thread if (_actor->_linkIndex2) { Control *subControl = _vm->_dict->getObjectControl(_actor->_subobjects[_actor->_linkIndex2 - 1]); if (subControl->_actor->_flags & 1) { - if (subControl->_actor->_pathNode) { + if (_actor->_pathNode) { doSeq = false; subControl->_actor->_notifyThreadId2 = threadId; subControl->_actor->_entryTblPtr = entryTblPtr; @@ -597,7 +597,7 @@ void Control::sequenceActor() { while (_actor->_seqCodeValue3 <= 0 && !sequenceFinished) { bool breakInner = false; while (!breakInner) { - debug(1, "SEQ op: %08X", _actor->_seqCodeIp[0]); + debug(1, "SEQ[%08X] op: %08X", _actor->_sequenceId, _actor->_seqCodeIp[0]); opCall._op = _actor->_seqCodeIp[0] & 0x7F; opCall._opSize = _actor->_seqCodeIp[1]; opCall._code = _actor->_seqCodeIp + 2; @@ -666,8 +666,9 @@ void Control::startSubSequence(int linkIndex, uint32 sequenceId) { void Control::stopSubSequence(int linkIndex) { Control *linkedControl = _vm->_dict->getObjectControl(_actor->_subobjects[linkIndex - 1]); Actor *linkedActor = linkedControl->_actor; - uint32 notifySequenceId2 = _actor->_notifyThreadId2; + uint32 notifyThreadId2 = _actor->_notifyThreadId2; _actor->_linkIndex2 = linkIndex; +//TODO BUGGY! if (_actor->_entryTblPtr) { linkedActor->_flags |= 0x80; linkedActor->_entryTblPtr = _actor->_entryTblPtr; @@ -679,13 +680,14 @@ void Control::stopSubSequence(int linkIndex) { _actor->_notifyThreadId1 = 0; _actor->_notifyThreadId2 = 0; } - if (notifySequenceId2) { - Thread *talkThread = _vm->_scriptMan->_threads->findThread(notifySequenceId2); + if (notifyThreadId2) { + Thread *talkThread = _vm->_scriptMan->_threads->findThread(notifyThreadId2); talkThread->sendMessage(kMsgClearSequenceId2, 0); } } void Control::startMoveActor(uint32 sequenceId, Common::Point destPt, uint32 callerThreadId1, uint32 callerThreadId2) { + PointArray *pathNode; ActorType *actorType = _vm->_dict->findActorType(_actorTypeId); @@ -895,7 +897,7 @@ void Control::refreshSequenceCode() { void Control::startSequenceActorIntern(uint32 sequenceId, int value, byte *entryTblPtr, uint32 notifyThreadId) { stopActor(); - + _actor->_flags &= ~0x80; _actor->_flags &= ~0x0400; _actor->_flags |= 0x0100; @@ -925,7 +927,7 @@ void Control::startSequenceActorIntern(uint32 sequenceId, int value, byte *entry } sequenceActor(); - + } void Control::execSequenceOpcode(OpCall &opCall) { @@ -1095,6 +1097,17 @@ void Controls::destroyControlsByTag(uint32 tag) { } } +void Controls::threadIsDead(uint32 threadId) { + for (ItemsIterator it = _controls.begin(); it != _controls.end(); ++it) { + Control *control = *it; + if (control->_actor && + (control->_actor->_notifyThreadId1 == threadId || control->_actor->_notifyId3C == threadId)) { + control->_actor->_notifyThreadId1 = 0; + control->_actor->_notifyId3C = 0; + } + } +} + void Controls::pauseControlsByTag(uint32 tag) { for (ItemsIterator it = _controls.begin(); it != _controls.end(); ++it) { Control *control = *it; diff --git a/engines/illusions/actor.h b/engines/illusions/actor.h index 4dd8ba50f4..4c937efbf9 100644 --- a/engines/illusions/actor.h +++ b/engines/illusions/actor.h @@ -221,6 +221,7 @@ public: void placeActorLessObject(uint32 objectId, Common::Point feetPt, Common::Point pt, int16 priority, uint flags); void placeSubActor(uint32 objectId, int linkIndex, uint32 actorTypeId, uint32 sequenceId); void destroyControlsByTag(uint32 tag); + void threadIsDead(uint32 threadId); void pauseControlsByTag(uint32 tag); void unpauseControlsByTag(uint32 tag); bool getOverlappedObject(Control *control, Common::Point pt, Control **outOverlappedControl, int minPriority); diff --git a/engines/illusions/illusions.cpp b/engines/illusions/illusions.cpp index 4748634e1c..684314e2cb 100644 --- a/engines/illusions/illusions.cpp +++ b/engines/illusions/illusions.cpp @@ -229,8 +229,9 @@ int IllusionsEngine::updateSequences() { // TODO Move to Controls class for (Controls::ItemsIterator it = _controls->_controls.begin(); it != _controls->_controls.end(); ++it) { Control *control = *it; - if (control->_pauseCtr == 0 && control->_actor && control->_actor->_seqCodeIp) + if (control->_pauseCtr == 0 && control->_actor && control->_actor->_seqCodeIp) { control->sequenceActor(); + } } return 1; } diff --git a/engines/illusions/scriptman.cpp b/engines/illusions/scriptman.cpp index 8a59d70a1e..c438def393 100644 --- a/engines/illusions/scriptman.cpp +++ b/engines/illusions/scriptman.cpp @@ -245,7 +245,7 @@ uint32 ScriptMan::startTalkThread(int16 duration, uint32 objectId, uint32 talkId uint32 sequenceId2, uint32 namedPointId, uint32 callingThreadId) { debug(2, "Starting talk thread"); uint32 tempThreadId = newTempThreadId(); - // TODO endTalkThreadsNoNotify(); + _threads->endTalkThreadsNoNotify(); TalkThread *talkThread = new TalkThread(_vm, tempThreadId, callingThreadId, 0, duration, objectId, talkId, sequenceId1, sequenceId2, namedPointId); _threads->startThread(talkThread); @@ -353,7 +353,7 @@ void ScriptMan::newScriptThread(uint32 threadId, uint32 callingThreadId, uint no if (_pauseCtr > 0) scriptThread->pause(); if (_doScriptThreadInit) { - int updateResult = 4; + int updateResult = kTSRun; while (scriptThread->_pauseCtr <= 0 && updateResult != kTSTerminate && updateResult != kTSYield) updateResult = scriptThread->update(); } diff --git a/engines/illusions/scriptopcodes.cpp b/engines/illusions/scriptopcodes.cpp index 00f57956dc..0a96f9c587 100644 --- a/engines/illusions/scriptopcodes.cpp +++ b/engines/illusions/scriptopcodes.cpp @@ -215,7 +215,7 @@ void ScriptOpcodes::opStartTimerThread(ScriptThread *scriptThread, OpCall &opCal if (maxDuration) duration += _vm->getRandom(maxDuration); -duration = 5;//DEBUG Speeds up things +duration = 1;//DEBUG Speeds up things if (isAbortable) _vm->_scriptMan->startAbortableTimerThread(duration, opCall._threadId); @@ -262,10 +262,11 @@ void ScriptOpcodes::opEnterScene(ScriptThread *scriptThread, OpCall &opCall) { } //DEBUG Scenes -uint32 dsceneId = 0x00010031, dthreadId = 0x00020036;//MAP +//uint32 dsceneId = 0x00010031, dthreadId = 0x00020036;//MAP //uint32 dsceneId = 0x00010028, dthreadId = 0x000202A1; //uint32 dsceneId = 0x00010007, dthreadId = 0x0002000C;//Auditorium //uint32 dsceneId = 0x0001000B, dthreadId = 0x00020010; +uint32 dsceneId = 0x00010013, dthreadId = 0x00020018;// void ScriptOpcodes::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) { ARG_SKIP(2); @@ -442,11 +443,7 @@ void ScriptOpcodes::opStartTalkThread(ScriptThread *scriptThread, OpCall &opCall ARG_UINT32(sequenceId1); ARG_UINT32(sequenceId2); ARG_UINT32(namedPointId); - // NOTE Skipped checking for stalled sequence, not sure if needed - _vm->_scriptMan->startTalkThread(duration, objectId, talkId, sequenceId1, sequenceId2, namedPointId, opCall._callerThreadId); - - //DEBUG Resume calling thread, later done after talking is finished - //_vm->notifyThreadId(opCall._threadId); + _vm->_scriptMan->startTalkThread(duration, objectId, talkId, sequenceId1, sequenceId2, namedPointId, opCall._threadId); } void ScriptOpcodes::opAppearActor(ScriptThread *scriptThread, OpCall &opCall) { @@ -618,16 +615,19 @@ void ScriptOpcodes::opJumpIf(ScriptThread *scriptThread, OpCall &opCall) { } void ScriptOpcodes::opIsPrevSceneId(ScriptThread *scriptThread, OpCall &opCall) { + ARG_SKIP(2); ARG_UINT32(sceneId); _vm->_scriptMan->_stack.push(_vm->_scriptMan->_prevSceneId == sceneId ? 1 : 0); } void ScriptOpcodes::opIsCurrentSceneId(ScriptThread *scriptThread, OpCall &opCall) { + ARG_SKIP(2); ARG_UINT32(sceneId); _vm->_scriptMan->_stack.push(_vm->getCurrentScene() == sceneId ? 1 : 0); } void ScriptOpcodes::opIsActiveSceneId(ScriptThread *scriptThread, OpCall &opCall) { + ARG_SKIP(2); ARG_UINT32(sceneId); _vm->_scriptMan->_stack.push(_vm->_scriptMan->_activeScenes.isSceneActive(sceneId) ? 1 : 0); } @@ -698,7 +698,7 @@ void ScriptOpcodes::opPlayVideo(ScriptThread *scriptThread, OpCall &opCall) { // TODO _vm->playVideo(videoId, objectId, value, opCall._threadId); //DEBUG Resume calling thread, later done by the video player - _vm->notifyThreadId(opCall._threadId); + _vm->notifyThreadId(opCall._callerThreadId); } diff --git a/engines/illusions/scriptthread.cpp b/engines/illusions/scriptthread.cpp index 69835d94a6..6f6d3a0709 100644 --- a/engines/illusions/scriptthread.cpp +++ b/engines/illusions/scriptthread.cpp @@ -55,31 +55,6 @@ int ScriptThread::onUpdate() { return opCall._result; } -void ScriptThread::onSuspend() { - // TODO - debug(1, "ScriptThread::onSuspend()"); -} - -void ScriptThread::onNotify() { - // TODO - debug(1, "ScriptThread::onNotify()"); -} - -void ScriptThread::onPause() { - // TODO - debug(1, "ScriptThread::onPause()"); -} - -void ScriptThread::onResume() { - // TODO - debug(1, "ScriptThread::onResume()"); -} - -void ScriptThread::onTerminated() { - // TODO - debug(1, "ScriptThread::onTerminated()"); -} - void ScriptThread::execOpcode(OpCall &opCall) { // TODO Clean this up _vm->_scriptMan->_scriptOpcodes->execOpcode(this, opCall); diff --git a/engines/illusions/scriptthread.h b/engines/illusions/scriptthread.h index f0d122bc70..cb82b6c614 100644 --- a/engines/illusions/scriptthread.h +++ b/engines/illusions/scriptthread.h @@ -35,11 +35,6 @@ 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; diff --git a/engines/illusions/sequenceopcodes.cpp b/engines/illusions/sequenceopcodes.cpp index 23d1781902..cab0fbecf3 100644 --- a/engines/illusions/sequenceopcodes.cpp +++ b/engines/illusions/sequenceopcodes.cpp @@ -119,7 +119,7 @@ void SequenceOpcodes::opSetFrameIndex(Control *control, OpCall &opCall) { control->_actor->_flags &= ~0x0100; if (control->_actor->_flags & 0x8000) { control->appearActor(); - control->_actor->_flags &= ~0x800; + control->_actor->_flags &= ~0x8000; } control->_actor->_newFrameIndex = frameIndex; } @@ -146,7 +146,7 @@ void SequenceOpcodes::opIncFrameDelay(Control *control, OpCall &opCall) { void SequenceOpcodes::opSetRandomFrameDelay(Control *control, OpCall &opCall) { ARG_INT16(minFrameDelay); ARG_INT16(maxFrameDelay); - control->_actor->_seqCodeValue3 += 0;//DEBUG minFrameDelay + _vm->getRandom(maxFrameDelay); + control->_actor->_seqCodeValue3 += minFrameDelay + _vm->getRandom(maxFrameDelay); opCall._result = 2; } @@ -172,7 +172,7 @@ void SequenceOpcodes::opGotoSequence(Control *control, OpCall &opCall) { ARG_UINT32(nextSequenceId); uint32 notifyThreadId1 = control->_actor->_notifyThreadId1; control->clearNotifyThreadId1(); - if (false/*TODO control->_actor->_pathNode*/) { + if (control->_actor->_pathNode) { control->startSequenceActor(nextSequenceId, 1, notifyThreadId1); } else { control->startSequenceActor(nextSequenceId, 2, notifyThreadId1); diff --git a/engines/illusions/specialcode.cpp b/engines/illusions/specialcode.cpp index 7ac49a2dfe..a412462d26 100644 --- a/engines/illusions/specialcode.cpp +++ b/engines/illusions/specialcode.cpp @@ -30,14 +30,12 @@ namespace Illusions { void SpecialCodeLoader::load(Resource *resource) { debug("SpecialCodeLoader::load() Loading special code %08X...", resource->_resId); - // TODO _vm->_specialCode = new BbdouSpecialCode(_vm); _vm->_specialCode->init(); } void SpecialCodeLoader::unload(Resource *resource) { debug("SpecialCodeLoader::unload() Unloading special code %08X...", resource->_resId); - // TODO delete _vm->_specialCode; _vm->_specialCode = 0; } diff --git a/engines/illusions/thread.cpp b/engines/illusions/thread.cpp index 38e69007c0..980a8afc4b 100644 --- a/engines/illusions/thread.cpp +++ b/engines/illusions/thread.cpp @@ -22,6 +22,7 @@ #include "illusions/illusions.h" #include "illusions/thread.h" +#include "illusions/actor.h" namespace Illusions { @@ -55,7 +56,7 @@ void Thread::onTerminated() { } void Thread::onKill() { - // TODO artmgrThreadIsDead(thread->threadId); + _vm->_controls->threadIsDead(_threadId); terminate(); } @@ -110,11 +111,11 @@ int Thread::update() { void Thread::terminate() { if (!_terminated) { - if (!(_notifyFlags & 1)) + if (!(_notifyFlags & 1)) { _vm->notifyThreadId(_callingThreadId); + } _callingThreadId = 0; onTerminated(); - // TODO _vm->removeThread(_threadId, this); _terminated = true; } } @@ -128,7 +129,6 @@ ThreadList::ThreadList(IllusionsEngine *vm) void ThreadList::startThread(Thread *thread) { // TODO tag has to be set by the Thread class scrmgrGetCurrentScene(); _threads.push_back(thread); - // TODO _vm->addThread(thread->_threadId, thread); } void ThreadList::updateThreads() { @@ -246,6 +246,14 @@ void ThreadList::endTalkThreads() { } } +void ThreadList::endTalkThreadsNoNotify() { + for (Iterator it = _threads.begin(); it != _threads.end(); ++it) { + Thread *thread = *it; + if (thread->_type == kTTTalkThread && thread->_callingThreadId == 0) + thread->terminate(); + } +} + void ThreadList::killThread(uint32 threadId) { if (!threadId) diff --git a/engines/illusions/thread.h b/engines/illusions/thread.h index 2cd3cc2a98..ea4868d936 100644 --- a/engines/illusions/thread.h +++ b/engines/illusions/thread.h @@ -92,6 +92,7 @@ public: void pauseThreads(uint32 threadId); void resumeThreads(uint32 threadId); void endTalkThreads(); + void endTalkThreadsNoNotify(); void killThread(uint32 threadId); void setThreadSceneId(uint32 threadId, uint32 sceneId); uint32 getThreadSceneId(uint32 threadId); diff --git a/engines/illusions/timerthread.cpp b/engines/illusions/timerthread.cpp index 42dde6dc17..bf9c32fbdb 100644 --- a/engines/illusions/timerthread.cpp +++ b/engines/illusions/timerthread.cpp @@ -23,6 +23,7 @@ #include "illusions/illusions.h" #include "illusions/timerthread.h" #include "illusions/input.h" +#include "illusions/scriptman.h" #include "illusions/time.h" namespace Illusions { @@ -35,7 +36,13 @@ TimerThread::TimerThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThr _type = kTTTimerThread; _startTime = getCurrentTime(); _endTime = _startTime + _duration; - // TODO _tag = *(_DWORD *)(krndictGetIDValue(callingThreadId) + 20); + + if (callingThreadId) { + Thread *callingThread = _vm->_scriptMan->_threads->findThread(callingThreadId); + if (callingThread) + _tag = callingThread->_tag; + } + } int TimerThread::onUpdate() { -- cgit v1.2.3