mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-03 17:33:05 +00:00
ILLUSIONS: Fix bug which occured when trying to walk while talking
- Fix minor bugs - Work on talk thread handling
This commit is contained in:
parent
f2c48e3ae0
commit
d77d4ed4a6
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -229,9 +229,10 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user