From faf7b31ff802786ded2bd177da6503e98fca3ebf Mon Sep 17 00:00:00 2001 From: johndoe123 Date: Tue, 2 Dec 2014 13:27:49 +0100 Subject: ILLUSIONS: Move thread-related files into threads subdirectory --- engines/illusions/threads/abortablethread.cpp | 69 +++++ engines/illusions/threads/abortablethread.h | 50 ++++ engines/illusions/threads/causethread_duckman.cpp | 58 ++++ engines/illusions/threads/causethread_duckman.h | 45 +++ engines/illusions/threads/scriptthread.cpp | 71 +++++ engines/illusions/threads/scriptthread.h | 50 ++++ engines/illusions/threads/talkthread.cpp | 329 ++++++++++++++++++++++ engines/illusions/threads/talkthread.h | 83 ++++++ engines/illusions/threads/talkthread_duckman.cpp | 311 ++++++++++++++++++++ engines/illusions/threads/talkthread_duckman.h | 87 ++++++ engines/illusions/threads/timerthread.cpp | 80 ++++++ engines/illusions/threads/timerthread.h | 50 ++++ 12 files changed, 1283 insertions(+) create mode 100644 engines/illusions/threads/abortablethread.cpp create mode 100644 engines/illusions/threads/abortablethread.h create mode 100644 engines/illusions/threads/causethread_duckman.cpp create mode 100644 engines/illusions/threads/causethread_duckman.h create mode 100644 engines/illusions/threads/scriptthread.cpp create mode 100644 engines/illusions/threads/scriptthread.h create mode 100644 engines/illusions/threads/talkthread.cpp create mode 100644 engines/illusions/threads/talkthread.h create mode 100644 engines/illusions/threads/talkthread_duckman.cpp create mode 100644 engines/illusions/threads/talkthread_duckman.h create mode 100644 engines/illusions/threads/timerthread.cpp create mode 100644 engines/illusions/threads/timerthread.h (limited to 'engines/illusions/threads') diff --git a/engines/illusions/threads/abortablethread.cpp b/engines/illusions/threads/abortablethread.cpp new file mode 100644 index 0000000000..348bc9c49a --- /dev/null +++ b/engines/illusions/threads/abortablethread.cpp @@ -0,0 +1,69 @@ +/* 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/threads/abortablethread.h" +#include "illusions/input.h" +#include "illusions/time.h" + +namespace Illusions { + +// AbortableThread + +AbortableThread::AbortableThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThreadId, uint notifyFlags, + uint32 scriptThreadId, byte *scriptCodeIp) + : Thread(vm, threadId, callingThreadId, notifyFlags), _scriptThreadId(scriptThreadId), + _scriptCodeIp(scriptCodeIp), _status(1) { + _type = kTTAbortableThread; + _tag = _vm->getCurrentScene(); + _vm->_input->discardButtons(8); +} + +int AbortableThread::onUpdate() { + if (_status != 1 || _pauseCtr < 0) + return kTSTerminate; + if (_vm->_input->pollButton(8)) { + _vm->_threads->killThread(_scriptThreadId); + ++_pauseCtr; + _vm->startTempScriptThread(_scriptCodeIp, _threadId, 0, 0, 0); + _status = 2; + return kTSSuspend; + } + return kTSYield; +} + +void AbortableThread::onSuspend() { +} + +void AbortableThread::onNotify() { +} + +void AbortableThread::onPause() { +} + +void AbortableThread::onResume() { +} + +void AbortableThread::onTerminated() { +} + +} // End of namespace Illusions diff --git a/engines/illusions/threads/abortablethread.h b/engines/illusions/threads/abortablethread.h new file mode 100644 index 0000000000..8fc2a47fce --- /dev/null +++ b/engines/illusions/threads/abortablethread.h @@ -0,0 +1,50 @@ +/* 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_ABORTABLETHREAD_H +#define ILLUSIONS_ABORTABLETHREAD_H + +#include "illusions/thread.h" + +namespace Illusions { + +class IllusionsEngine; + +class AbortableThread : public Thread { +public: + AbortableThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThreadId, uint notifyFlags, + uint32 scriptThreadId, byte *scriptCodeIp); + virtual int onUpdate(); + virtual void onSuspend(); + virtual void onNotify(); + virtual void onPause(); + virtual void onResume(); + virtual void onTerminated(); +public: + int _status; + byte *_scriptCodeIp; + uint32 _scriptThreadId; +}; + +} // End of namespace Illusions + +#endif // ILLUSIONS_ABORTABLETHREAD_H diff --git a/engines/illusions/threads/causethread_duckman.cpp b/engines/illusions/threads/causethread_duckman.cpp new file mode 100644 index 0000000000..091b85c78d --- /dev/null +++ b/engines/illusions/threads/causethread_duckman.cpp @@ -0,0 +1,58 @@ +/* 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_duckman.h" +#include "illusions/threads/causethread_duckman.h" +#include "illusions/actor.h" +#include "illusions/input.h" + +namespace Illusions { + +// CauseThread_Duckman + +CauseThread_Duckman::CauseThread_Duckman(IllusionsEngine_Duckman *vm, uint32 threadId, uint32 callingThreadId, uint notifyFlags, + uint32 triggerThreadId) + : Thread(vm, threadId, callingThreadId, notifyFlags), _vm(vm), _triggerThreadId(triggerThreadId), _flag(false) { + _type = kTTCauseThread; + _tag = _vm->getCurrentScene(); +} + +int CauseThread_Duckman::onUpdate() { + if (_flag) { + if (_vm->getCurrentScene() == _tag) { + Control *cursorCursor = _vm->getObjectControl(0x40004); + cursorCursor->appearActor(); + _vm->_input->discardButtons(1); + } + return kTSTerminate; + } else { + _tag = _vm->getCurrentScene(); + Control *cursorCursor = _vm->getObjectControl(0x40004); + cursorCursor->disappearActor(); + _vm->_input->discardButtons(1); + _vm->startScriptThread(_triggerThreadId, _threadId); + _flag = true; + return kTSSuspend; + } +} + +} // End of namespace Illusions diff --git a/engines/illusions/threads/causethread_duckman.h b/engines/illusions/threads/causethread_duckman.h new file mode 100644 index 0000000000..97bf00e7cb --- /dev/null +++ b/engines/illusions/threads/causethread_duckman.h @@ -0,0 +1,45 @@ +/* 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_CAUSETHREAD_DUCKMAN_H +#define ILLUSIONS_CAUSETHREAD_DUCKMAN_H + +#include "illusions/thread.h" + +namespace Illusions { + +class IllusionsEngine_Duckman; + +class CauseThread_Duckman : public Thread { +public: + CauseThread_Duckman(IllusionsEngine_Duckman *vm, uint32 threadId, uint32 callingThreadId, uint notifyFlags, + uint32 triggerThreadId); + virtual int onUpdate(); +public: + IllusionsEngine_Duckman *_vm; + bool _flag; + uint32 _triggerThreadId; +}; + +} // End of namespace Illusions + +#endif // ILLUSIONS_CAUSETHREAD_DUCKMAN_H diff --git a/engines/illusions/threads/scriptthread.cpp b/engines/illusions/threads/scriptthread.cpp new file mode 100644 index 0000000000..f8bbae9cb4 --- /dev/null +++ b/engines/illusions/threads/scriptthread.cpp @@ -0,0 +1,71 @@ +/* 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/threads/scriptthread.h" +#include "illusions/scriptopcodes.h" + +namespace Illusions { + +// 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; + _tag = _vm->getCurrentScene(); +} + +int ScriptThread::onUpdate() { + OpCall opCall; + opCall._result = kTSRun; + opCall._callerThreadId = _threadId; + while (!_terminated && opCall._result == kTSRun) { + loadOpcode(opCall); + execOpcode(opCall); + _scriptCodeIp += opCall._deltaOfs; + } + if (_terminated) + opCall._result = kTSTerminate; + return opCall._result; +} + +void ScriptThread::loadOpcode(OpCall &opCall) { + if (_vm->getGameId() == kGameIdDuckman) { + opCall._op = _scriptCodeIp[0] & 0x7F; + opCall._opSize = _scriptCodeIp[1]; + opCall._threadId = _scriptCodeIp[0] & 0x80 ? _threadId : 0; + } else { + opCall._op = _scriptCodeIp[0]; + opCall._opSize = _scriptCodeIp[1] >> 1; + opCall._threadId = _scriptCodeIp[1] & 1 ? _threadId : 0; + } + opCall._code = _scriptCodeIp + 2; + opCall._deltaOfs = opCall._opSize; +} + +void ScriptThread::execOpcode(OpCall &opCall) { + _vm->_scriptOpcodes->execOpcode(this, opCall); +} + +} // End of namespace Illusions diff --git a/engines/illusions/threads/scriptthread.h b/engines/illusions/threads/scriptthread.h new file mode 100644 index 0000000000..0306c4f1cd --- /dev/null +++ b/engines/illusions/threads/scriptthread.h @@ -0,0 +1,50 @@ +/* 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; + +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(); +public: + int16 _sequenceStalled; + byte *_scriptCodeIp; + uint32 _value8; + uint32 _valueC; + uint32 _value10; + void loadOpcode(OpCall &opCall); + void execOpcode(OpCall &opCall); +}; + +} // End of namespace Illusions + +#endif // ILLUSIONS_SCRIPTTHREAD_H diff --git a/engines/illusions/threads/talkthread.cpp b/engines/illusions/threads/talkthread.cpp new file mode 100644 index 0000000000..3a4d286f66 --- /dev/null +++ b/engines/illusions/threads/talkthread.cpp @@ -0,0 +1,329 @@ +/* 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/threads/talkthread.h" +#include "illusions/actor.h" +#include "illusions/dictionary.h" +#include "illusions/input.h" +#include "illusions/sound.h" +#include "illusions/talkresource.h" +#include "illusions/time.h" + +namespace Illusions { + +// TalkThread + +TalkThread::TalkThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThreadId, uint notifyFlags, + int16 duration, uint32 objectId, uint32 talkId, uint32 sequenceId1, uint32 sequenceId2, + uint32 namedPointId) + : Thread(vm, threadId, callingThreadId, notifyFlags), _objectId(objectId), _talkId(talkId), + _sequenceId1(0), _sequenceId2(0) { + _type = kTTTalkThread; + + if (sequenceId1 && _vm->_dict->getObjectControl(objectId)) { + _sequenceId1 = sequenceId1; + _sequenceId2 = sequenceId2; + } + + if (!callingThreadId) + _sequenceId2 = 0; + + _namedPointId = namedPointId; + + if (duration) + _status = 1; + else if (_vm->checkActiveTalkThreads()) + _status = 2; + else + _status = 3; + + _flags = 0x0E; + + _durationMult = _vm->clipTextDuration(_vm->_fieldE); + _textDuration = _durationMult; + _defDurationMult = _vm->clipTextDuration(240); + _textStartTime = 0; + _textEndTime = 0; + _textDurationElapsed = 0; + _entryText = 0; + _currEntryText = 0; + _voiceDurationElapsed = 0; + _voiceDuration = duration; + _voiceStartTime = getCurrentTime(); + _voiceEndTime = _voiceStartTime + duration; + _entryTblPtr = 0; + + if (callingThreadId) { + Thread *callingThread = _vm->_threads->findThread(callingThreadId); + if (callingThread) + _tag = callingThread->_tag; + } + + //debug("New talk thread: %08X %08X", _threadId, _talkId); +} + +int TalkThread::onUpdate() { + + TalkEntry *talkEntry; + + switch (_status) { + + case 1: + if (isTimerExpired(_voiceStartTime, _voiceEndTime)) { + if (_vm->checkActiveTalkThreads()) + _status = 2; + else + _status = 3; + } + return kTSYield; + + case 2: + if (_vm->checkActiveTalkThreads()) + return kTSYield; + _status = 3; + // Fallthrough to status 3 + + case 3: + talkEntry = getTalkResourceEntry(_talkId); + _flags = 0; + _currEntryText = 0; + _entryText = talkEntry->_text; + _entryTblPtr = talkEntry->_tblPtr; + if (_sequenceId1) { + // TODO _field30 = v6; + _pauseCtr = 0; + } else { + // TODO _field30 = 0; + _flags |= 2; + _flags |= 1; + } + if (_vm->isSoundActive()) { + if (!_vm->_soundMan->cueVoice((char*)talkEntry->_voiceName) && !_durationMult) + _durationMult = _defDurationMult; + } else { + _flags |= 4; + if (_durationMult == 0) + _durationMult = _defDurationMult; + } + if (_objectId == 0 || _durationMult == 0) + _flags |= 8; + _status = 4; + // Fallthrough to status 4 + + case 4: + if (!(_flags & 4) && !_vm->_soundMan->isVoiceCued()) + return kTSYield; + _status = 5; + // Fallthrough to status 5 + + case 5: + if (!(_flags & 8)) + refreshText(); + if (!(_flags & 2)) { + Control *control = _vm->_dict->getObjectControl(_objectId); + control->startTalkActor(_sequenceId1, _entryTblPtr, _threadId); + } + if (!(_flags & 4)) { + int16 panX = 0; + if (_namedPointId) { + // TODO pt.x = (unsigned int)artcntrlGetNamedPointPosition((Point)_namedPointId); + // TODO panX = convertPanXCoord(pt.x); + } + _vm->_soundMan->startVoice(255, panX); + } + _vm->_input->discardButtons(0x10); + _status = 6; + return kTSYield; + + case 6: + if (!(_flags & 4) && !_vm->_soundMan->isVoicePlaying()) + _flags |= 4; + if (!(_flags & 8) && isTimerExpired(_textStartTime, _textEndTime)) { + // TODO _vm->removeText(); + if (_entryText && *_entryText) { + refreshText(); + _vm->_input->discardButtons(0x10); + } else { + _flags |= 8; + } + } + if ((_flags & 4) && (_flags & 8)) { + if (_sequenceId2) { + Control *control = _vm->_dict->getObjectControl(_objectId); + control->startSequenceActor(_sequenceId2, 2, 0); + } + if (_sequenceId1) { + Control *control = _vm->_dict->getObjectControl(_objectId); + control->clearNotifyThreadId2(); + } + _flags |= 2; + } + if (_objectId && _vm->_input->pollButton(0x10)) { + if (!(_flags & 8)) { + // TODO _vm->removeText(); + if (_entryText && *_entryText) + refreshText(); + else + _flags |= 8; + } + if (_flags & 8) { + if (!(_flags & 4)) { + _vm->_soundMan->stopVoice(); + _flags |= 4; + } + if (!(_flags & 2)) { + if (_sequenceId2) { + Control *control = _vm->_dict->getObjectControl(_objectId); + control->startSequenceActor(_sequenceId2, 2, 0); + } + if (_sequenceId1) { + Control *control = _vm->_dict->getObjectControl(_objectId); + control->clearNotifyThreadId2(); + } + _flags |= 2; + } + } + } + if ((_flags & 8) && (_flags & 2) && (_flags & 4)) { + _vm->_input->discardButtons(0x10); + _status = 7; + return kTSTerminate; + } + return kTSYield; + + case 7: + if (!(_flags & 2)) { + if (_sequenceId2) { + Control *control = _vm->_dict->getObjectControl(_objectId); + control->startSequenceActor(_sequenceId2, 2, 0); + } + if (_sequenceId1) { + Control *control = _vm->_dict->getObjectControl(_objectId); + control->clearNotifyThreadId2(); + } + _flags |= 2; + } + if (!(_flags & 8)) { + // TODO _vm->removeText(); + _flags |= 8; + } + if (!(_flags & 4)) { + _vm->_soundMan->stopVoice(); + _flags |= 4; + } + return kTSTerminate; + + } + + return kTSTerminate; + +} + +void TalkThread::onSuspend() { +} + +void TalkThread::onNotify() { +} + +void TalkThread::onPause() { +} + +void TalkThread::onResume() { +} + +void TalkThread::onTerminated() { +} + +void TalkThread::onKill() { + _callingThreadId = 0; + sendMessage(kMsgClearSequenceId1, 0); + sendMessage(kMsgClearSequenceId2, 0); +} + +uint32 TalkThread::sendMessage(int msgNum, uint32 msgValue) { + // TODO + switch (msgNum) { + case kMsgQueryTalkThreadActive: + if (_status != 1 && _status != 2) + return 1; + break; + case kMsgClearSequenceId1: + _sequenceId1 = 0; + _flags |= 3; + // TODO _field30 = 0; + break; + case kMsgClearSequenceId2: + _sequenceId2 = 0; + break; + } + return 0; +} + +void TalkThread::refreshText() { + _currEntryText = _entryText; + int charCount = insertText(); + uint32 duration = _durationMult; + if (charCount < 80) { + duration = _durationMult * charCount / 80; + if (duration < 25 * _durationMult / 100) + duration = 25 * _durationMult / 100; + if (duration < 60) + duration = 60; + } + _textDuration = duration; + _textStartTime = getCurrentTime(); + _textEndTime = _textStartTime + _textDuration; +} + +static char *debugW2I(byte *wstr) { + static char buf[65]; + char *p = buf; + while (*wstr != 0) { + *p++ = *wstr; + wstr += 2; + } + *p = 0; + return buf; +} + +int TalkThread::insertText() { + int charCount = 100; + + debug("%08X %08X [%s]", _threadId, _talkId, debugW2I(_currEntryText)); + _entryText = 0; + + // TODO _vm->getDimensions1(&dimensions); + // TODO _vm->insertText(_currEntryText, _vm->_currFontId, dimensions, 0, 2, 0, 0, 0, 0, 0, 0, &outTextPtr); + // TODO _vm->charCount = (char *)outTextPtr - (char *)text; + // TODO _entryText = outTextPtr; + // TODO _vm->getPoint1(&pt); + // TODO _vm->updateTextInfoPosition(pt); + return charCount >> 1; +} + +TalkEntry *TalkThread::getTalkResourceEntry(uint32 talkId) { + TalkEntry *talkEntry = _vm->_dict->findTalkEntry(talkId); + return talkEntry; +} + +} // End of namespace Illusions diff --git a/engines/illusions/threads/talkthread.h b/engines/illusions/threads/talkthread.h new file mode 100644 index 0000000000..ada593b571 --- /dev/null +++ b/engines/illusions/threads/talkthread.h @@ -0,0 +1,83 @@ +/* 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_TALKTHREAD_H +#define ILLUSIONS_TALKTHREAD_H + +#include "illusions/thread.h" + +namespace Illusions { + +class IllusionsEngine; +struct TalkEntry; + +enum { + kMsgQueryTalkThreadActive = 0, + kMsgClearSequenceId1 = 1, + kMsgClearSequenceId2 = 2 +}; + +class TalkThread : public Thread { +public: + TalkThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThreadId, uint notifyFlags, + int16 duration, uint32 objectId, uint32 talkId, uint32 sequenceId1, uint32 sequenceId2, + uint32 namedPointId); + virtual int onUpdate(); + virtual void onSuspend(); + virtual void onNotify(); + virtual void onPause(); + virtual void onResume(); + virtual void onTerminated(); + virtual void onKill(); + virtual uint32 sendMessage(int msgNum, uint32 msgValue); +public: + //field0 dw + int _status; + uint _flags; + uint32 _textStartTime; + uint32 _textEndTime; + uint32 _textDuration; + uint32 _defDurationMult; + uint32 _textDurationElapsed; + uint32 _durationMult; + //field12 dw + uint32 _objectId; + uint32 _talkId; + uint32 _sequenceId1; + uint32 _sequenceId2; + byte *_entryTblPtr; + byte *_entryText; + byte *_currEntryText; + //field30 dd + uint32 _namedPointId; + uint32 _voiceStartTime; + uint32 _voiceEndTime; + uint32 _voiceDuration; + uint32 _voiceDurationElapsed; + void refreshText(); + int insertText(); + TalkEntry *getTalkResourceEntry(uint32 talkId); +}; + +} // End of namespace Illusions + +#endif // ILLUSIONS_TALKTHREAD_H diff --git a/engines/illusions/threads/talkthread_duckman.cpp b/engines/illusions/threads/talkthread_duckman.cpp new file mode 100644 index 0000000000..67c394cd75 --- /dev/null +++ b/engines/illusions/threads/talkthread_duckman.cpp @@ -0,0 +1,311 @@ +/* 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_duckman.h" +#include "illusions/threads/talkthread_duckman.h" +#include "illusions/actor.h" +#include "illusions/dictionary.h" +#include "illusions/input.h" +#include "illusions/screentext.h" +#include "illusions/sound.h" +#include "illusions/talkresource.h" +#include "illusions/time.h" + +namespace Illusions { + +// TalkThread_Duckman + +TalkThread_Duckman::TalkThread_Duckman(IllusionsEngine_Duckman *vm, uint32 threadId, uint32 callingThreadId, uint notifyFlags, + uint32 objectId, uint32 talkId, uint32 sequenceId1, uint32 sequenceId2) + : Thread(vm, threadId, callingThreadId, notifyFlags), _vm(vm), _objectId(objectId), _talkId(talkId) { + _type = kTTTalkThread; + + if ((sequenceId1 & 0xFFFF0000) == 0x60000) { + _sequenceId1 = sequenceId1; + _sequenceId2 = sequenceId2; + _namedPointId1 = 0; + _namedPointId2 = 0; + } else { + _sequenceId1 = 0; + _sequenceId2 = 0; + _namedPointId1 = sequenceId1; + _namedPointId2 = sequenceId2; + } + + if (_vm->checkActiveTalkThreads()) + _status = 1; + else + _status = 2; + + _durationMult = _vm->clipTextDuration(_vm->_fieldE); + _textDuration = _durationMult; + _defDurationMult = _vm->clipTextDuration(240); + + _tag = _vm->getCurrentScene(); + +} + +int TalkThread_Duckman::onUpdate() { + + TalkEntry *talkEntry; + + switch (_status) { + + case 1: + if (_vm->checkActiveTalkThreads()) + return kTSYield; + _status = 3; + // Fallthrough to status 2 + + case 2: + talkEntry = getTalkResourceEntry(_talkId); + _flags = 0; + _currEntryText = 0; + _entryText = talkEntry->_text; + _entryTblPtr = talkEntry->_tblPtr; + if (_sequenceId1) { + _pauseCtrPtr = &_pauseCtr; + _pauseCtr = 0; + } else { + _pauseCtrPtr = 0; + _flags |= 2; + _flags |= 1; + } + if (_vm->isSoundActive()) { + if (!_vm->_soundMan->cueVoice((char*)talkEntry->_voiceName) && !_durationMult) + _durationMult = _defDurationMult; + } else { + _flags |= 4; + if (_durationMult == 0) + _durationMult = _defDurationMult; + } + if (_objectId == 0 || _durationMult == 0) + _flags |= 8; + _status = 3; + // Fallthrough to status 3 + + case 3: + if (!(_flags & 4) && !_vm->_soundMan->isVoiceCued()) + return kTSYield; + _status = 4; + // Fallthrough to status 4 + + case 4: + if (!(_flags & 8) ) { + uint32 actorTypeId = _vm->getObjectActorTypeId(_objectId); + getActorTypeColor(actorTypeId, _color); + refreshText(); + } + if (!(_flags & 2)) { + Control *control = _vm->_dict->getObjectControl(_objectId); + control->startTalkActor(_sequenceId1, _entryTblPtr, _threadId); + } + if (!(_flags & 4)) { + int16 panX = 0; + if (_flags & 1) { + if (_namedPointId2) { + panX = _vm->getNamedPointPosition(_namedPointId2).x; + panX = _vm->convertPanXCoord(panX); + } + } else { + Control *control = _vm->_dict->getObjectControl(_objectId); + panX = control->getActorPosition().x; + panX = _vm->convertPanXCoord(panX); + } + _vm->_soundMan->startVoice(255, panX); + } + _vm->_input->discardButtons(0x20); + _status = 5; + return kTSYield; + + case 5: + if (!(_flags & 4) && !_vm->_soundMan->isVoicePlaying()) + _flags |= 4; + if (!(_flags & 8) && isTimerExpired(_textStartTime, _textEndTime)) { + _vm->_screenText->removeText(); + if (_entryText && *_entryText) { + refreshText(); + _vm->_input->discardButtons(0x20); + } else { + _flags |= 8; + } + } + if (!(_flags & 2)) { + if (*_pauseCtrPtr < 0) { + ++(*_pauseCtrPtr); + Control *control = _vm->_dict->getObjectControl(_objectId); + control->startSequenceActor(_sequenceId2, 2, 0); + _flags |= 2; + } + } + if (_objectId && _vm->_input->pollButton(0x20)) { + if (!(_flags & 8)) { + _vm->_screenText->removeText(); + if (_entryText && *_entryText) + refreshText(); + else + _flags |= 8; + } + if (_flags & 8) { + if (!(_flags & 4)) { + _vm->_soundMan->stopVoice(); + _flags |= 4; + } + if (!(_flags & 2)) { + Control *control = _vm->_dict->getObjectControl(_objectId); + control->clearNotifyThreadId1(); + control->startSequenceActor(_sequenceId2, 2, 0); + _flags |= 2; + } + } + } + if ((_flags & 8) && (_flags & 2) && (_flags & 4)) { + _vm->_input->discardButtons(0x20); + return kTSTerminate; + } + return kTSYield; + + case 6: + if (!(_flags & 2)) { + Control *control = _vm->_dict->getObjectControl(_objectId); + if (*_pauseCtrPtr >= 0) { + control->clearNotifyThreadId1(); + } else { + ++(*_pauseCtrPtr); + } + control->startSequenceActor(_sequenceId2, 2, 0); + _flags |= 2; + } + return kTSTerminate; + + } + + return kTSTerminate; + +} + +void TalkThread_Duckman::onSuspend() { +} + +void TalkThread_Duckman::onNotify() { +} + +void TalkThread_Duckman::onPause() { +} + +void TalkThread_Duckman::onResume() { +} + +void TalkThread_Duckman::onTerminated() { + if (_status == 5) { + if (!(_flags & 4)) + _vm->_soundMan->stopVoice(); + if (!(_flags & 8)) { + _vm->_screenText->removeText(); + } + if (!(_flags & 2)) { + Control *control = _vm->_dict->getObjectControl(_objectId); + if (control) { + control->clearNotifyThreadId1(); + control->startSequenceActor(_sequenceId2, 2, 0); + } + } + } +} + +void TalkThread_Duckman::onKill() { + _callingThreadId = 0; + sendMessage(kMsgClearSequenceId1, 0); + sendMessage(kMsgClearSequenceId2, 0); +} + +uint32 TalkThread_Duckman::sendMessage(int msgNum, uint32 msgValue) { + switch (msgNum) { + case kMsgQueryTalkThreadActive: + if (_status != 1) + return 1; + break; + case kMsgClearSequenceId1: + _sequenceId1 = 0; + _flags |= 3; + // TODO _pauseCtrPtr = 0; + break; + case kMsgClearSequenceId2: + _sequenceId2 = 0; + break; + } + return 0; +} + +void TalkThread_Duckman::refreshText() { + _currEntryText = _entryText; + int charCount = insertText(); + uint32 duration = _durationMult; + if (charCount < 80) { + duration = _durationMult * charCount / 80; + if (duration < 25 * _durationMult / 100) + duration = 25 * _durationMult / 100; + if (duration < 60) + duration = 60; + } + _textDuration = duration; + _textStartTime = getCurrentTime(); + _textEndTime = _textStartTime + _textDuration; +} + +static char *debugW2I(byte *wstr) { + static char buf[65]; + char *p = buf; + while (*wstr != 0) { + *p++ = *wstr; + wstr += 2; + } + *p = 0; + return buf; +} + +int TalkThread_Duckman::insertText() { + debug("%08X %08X [%s]", _threadId, _talkId, debugW2I(_currEntryText)); + WidthHeight dimensions; + _vm->getDefaultTextDimensions(dimensions); + uint16 *outTextPtr; + _vm->_screenText->insertText((uint16*)_currEntryText, 0x120001, dimensions, + Common::Point(0, 0), 2, 0, 0, _color.r, _color.r, _color.r, outTextPtr); + _entryText = (byte*)outTextPtr; + Common::Point pt; + _vm->getDefaultTextPosition(pt); + _vm->_screenText->updateTextInfoPosition(pt); + int charCount = (_entryText - _currEntryText) / 2; + return charCount; +} + +TalkEntry *TalkThread_Duckman::getTalkResourceEntry(uint32 talkId) { + TalkEntry *talkEntry = _vm->_dict->findTalkEntry(talkId); + return talkEntry; +} + +void TalkThread_Duckman::getActorTypeColor(uint32 actorTypeId, RGB &color) { + ActorType *actorType = _vm->_dict->findActorType(actorTypeId); + color = actorType->_color; +} + +} // End of namespace Illusions diff --git a/engines/illusions/threads/talkthread_duckman.h b/engines/illusions/threads/talkthread_duckman.h new file mode 100644 index 0000000000..b729ad2d8f --- /dev/null +++ b/engines/illusions/threads/talkthread_duckman.h @@ -0,0 +1,87 @@ +/* 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_TALKTHREAD_DUCKMAN_H +#define ILLUSIONS_TALKTHREAD_DUCKMAN_H + +#include "illusions/thread.h" + +namespace Illusions { + +class IllusionsEngine_Duckman; +struct TalkEntry; + +enum { + kMsgQueryTalkThreadActive = 0, + kMsgClearSequenceId1 = 1, + kMsgClearSequenceId2 = 2 +}; + +class TalkThread_Duckman : public Thread { +public: + TalkThread_Duckman(IllusionsEngine_Duckman *vm, uint32 threadId, uint32 callingThreadId, uint notifyFlags, + uint32 objectId, uint32 talkId, uint32 sequenceId1, uint32 sequenceId2); + virtual int onUpdate(); + virtual void onSuspend(); + virtual void onNotify(); + virtual void onPause(); + virtual void onResume(); + virtual void onTerminated(); + virtual void onKill(); + virtual uint32 sendMessage(int msgNum, uint32 msgValue); +public: + IllusionsEngine_Duckman *_vm; + //field0 dw + int _status; + uint _flags; + uint32 _textStartTime; + uint32 _textEndTime; + uint32 _textDuration; + uint32 _defDurationMult; + uint32 _textDurationElapsed; + uint32 _durationMult; + //field12 dw + uint32 _objectId; + uint32 _talkId; + uint32 _sequenceId1; + uint32 _sequenceId2; + uint32 _namedPointId1; + uint32 _namedPointId2; + byte *_entryTblPtr; + byte *_entryText; + byte *_currEntryText; + //field30 dd + uint32 _voiceStartTime; + uint32 _voiceEndTime; + uint32 _voiceDuration; + uint32 _voiceDurationElapsed; + int *_pauseCtrPtr; + RGB _color; + void refreshText(); + int insertText(); + TalkEntry *getTalkResourceEntry(uint32 talkId); + void getActorTypeColor(uint32 actorTypeId, RGB &color); +}; + +} // End of namespace Illusions + +#endif // ILLUSIONS_TALKTHREAD_H diff --git a/engines/illusions/threads/timerthread.cpp b/engines/illusions/threads/timerthread.cpp new file mode 100644 index 0000000000..714c719bc9 --- /dev/null +++ b/engines/illusions/threads/timerthread.cpp @@ -0,0 +1,80 @@ +/* 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/threads/timerthread.h" +#include "illusions/input.h" +#include "illusions/time.h" + +namespace Illusions { + +// TimerThread + +TimerThread::TimerThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThreadId, uint notifyFlags, + uint32 duration, bool isAbortable) + : Thread(vm, threadId, callingThreadId, notifyFlags), _duration(duration), _isAbortable(isAbortable) { + _type = kTTTimerThread; + _startTime = getCurrentTime(); + _endTime = _startTime + _duration; + + if (callingThreadId) { + Thread *callingThread = _vm->_threads->findThread(callingThreadId); + if (callingThread) + _tag = callingThread->_tag; + } + +} + +int TimerThread::onUpdate() { + if (isTimerExpired(_startTime, _endTime) || + (_isAbortable && _vm->_input->pollButton(8))) + return kTSTerminate; + return kTSYield; +} + +void TimerThread::onSuspend() { + _durationElapsed = getDurationElapsed(_startTime, _endTime); +} + +void TimerThread::onNotify() { + uint32 currTime = getCurrentTime(); + _startTime = currTime; + if (_duration <= _durationElapsed) + _endTime = currTime; + else + _endTime = currTime + _duration - _durationElapsed; + _durationElapsed = 0; +} + +void TimerThread::onPause() { + onSuspend(); +} + +void TimerThread::onResume() { + onNotify(); +} + +void TimerThread::onTerminated() { + // Empty +} + +} // End of namespace Illusions diff --git a/engines/illusions/threads/timerthread.h b/engines/illusions/threads/timerthread.h new file mode 100644 index 0000000000..d283dc40ba --- /dev/null +++ b/engines/illusions/threads/timerthread.h @@ -0,0 +1,50 @@ +/* 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_TIMERTHREAD_H +#define ILLUSIONS_TIMERTHREAD_H + +#include "illusions/thread.h" + +namespace Illusions { + +class IllusionsEngine; + +class TimerThread : public Thread { +public: + TimerThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThreadId, uint notifyFlags, + uint32 duration, bool isAbortable); + virtual int onUpdate(); + virtual void onSuspend(); + virtual void onNotify(); + virtual void onPause(); + virtual void onResume(); + virtual void onTerminated(); +public: + uint32 _startTime, _endTime; + uint32 _duration, _durationElapsed; + bool _isAbortable; +}; + +} // End of namespace Illusions + +#endif // ILLUSIONS_TIMERTHREAD_H -- cgit v1.2.3