ILLUSIONS: Fix bug which occured when trying to walk while talking

- Fix minor bugs
- Work on talk thread handling
This commit is contained in:
johndoe123 2014-04-01 11:22:58 +02:00 committed by Eugene Sandulenko
parent f2c48e3ae0
commit d77d4ed4a6
12 changed files with 58 additions and 59 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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)

View File

@ -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);

View File

@ -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() {