aboutsummaryrefslogtreecommitdiff
path: root/engines/illusions/bbdou
diff options
context:
space:
mode:
authorjohndoe1232014-03-26 14:04:17 +0100
committerEugene Sandulenko2018-07-20 06:43:33 +0000
commit22e898f7eb1bddc363900f4146696bf6e9d41e2f (patch)
treed45b25cf42f6b3efeec2d14cba4a880fea06d182 /engines/illusions/bbdou
parente05a7899755011f860f2b09ce6d5b4e0a15107b9 (diff)
downloadscummvm-rg350-22e898f7eb1bddc363900f4146696bf6e9d41e2f.tar.gz
scummvm-rg350-22e898f7eb1bddc363900f4146696bf6e9d41e2f.tar.bz2
scummvm-rg350-22e898f7eb1bddc363900f4146696bf6e9d41e2f.zip
ILLUSIONS: Work on interaction; work on Cause related code
Diffstat (limited to 'engines/illusions/bbdou')
-rw-r--r--engines/illusions/bbdou/bbdou_cursor.cpp28
-rw-r--r--engines/illusions/bbdou/bbdou_cursor.h1
-rw-r--r--engines/illusions/bbdou/bbdou_specialcode.cpp161
-rw-r--r--engines/illusions/bbdou/bbdou_specialcode.h27
4 files changed, 203 insertions, 14 deletions
diff --git a/engines/illusions/bbdou/bbdou_cursor.cpp b/engines/illusions/bbdou/bbdou_cursor.cpp
index 16cd82ade6..1c4af97a2c 100644
--- a/engines/illusions/bbdou/bbdou_cursor.cpp
+++ b/engines/illusions/bbdou/bbdou_cursor.cpp
@@ -72,7 +72,7 @@ void BbdouCursor::init(uint32 objectId, uint32 progResKeywordId) {
_data._item10._objectIds[1] = 0;
_data._item10._index = 0;
_data._item10._flag56 = 0;
-
+
clearCursorDataField14();
control->setActorIndexTo1();
@@ -111,8 +111,32 @@ uint32 BbdouCursor::findCursorSequenceId(uint32 objectId) {
return 0;
}
+void BbdouCursor::setStruct8bsValue(uint32 objectId, int value) {
+ // TODO Clean this up, preliminary
+ Struct8b *struct8b = 0;
+ for (uint i = 0; i < 512; ++i)
+ if (_cursorStruct8bs[i]._objectId == objectId) {
+ struct8b = &_cursorStruct8bs[i];
+ break;
+ }
+ if (!struct8b) {
+ for (uint i = 0; i < 512; ++i)
+ if (_cursorStruct8bs[i]._objectId == 0) {
+ struct8b = &_cursorStruct8bs[i];
+ break;
+ }
+ }
+ if (value != 11) {
+ struct8b->_objectId = objectId;
+ struct8b->_value = value;
+ } else if (struct8b->_objectId == objectId) {
+ struct8b->_objectId = 0;
+ struct8b->_value = 0;
+ }
+}
+
int BbdouCursor::findStruct8bsValue(uint32 objectId) {
- for (uint i = 0; i < kMaxCursorSequences; ++i)
+ for (uint i = 0; i < 512; ++i)
if (_cursorStruct8bs[i]._objectId == objectId)
return _cursorStruct8bs[i]._value;
return 11;
diff --git a/engines/illusions/bbdou/bbdou_cursor.h b/engines/illusions/bbdou/bbdou_cursor.h
index 8f02632857..bd3ba3aea3 100644
--- a/engines/illusions/bbdou/bbdou_cursor.h
+++ b/engines/illusions/bbdou/bbdou_cursor.h
@@ -92,6 +92,7 @@ public:
void disable(uint32 objectId);
void addCursorSequence(uint32 objectId, uint32 sequenceId);
uint32 findCursorSequenceId(uint32 objectId);
+ void setStruct8bsValue(uint32 objectId, int value);
int findStruct8bsValue(uint32 objectId);
void saveInfo();
void restoreInfo();
diff --git a/engines/illusions/bbdou/bbdou_specialcode.cpp b/engines/illusions/bbdou/bbdou_specialcode.cpp
index e0d29e7265..62b0a7aca1 100644
--- a/engines/illusions/bbdou/bbdou_specialcode.cpp
+++ b/engines/illusions/bbdou/bbdou_specialcode.cpp
@@ -33,6 +33,24 @@
namespace Illusions {
+CauseThread::CauseThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThreadId,
+ BbdouSpecialCode *bbdou, uint32 cursorObjectId, uint32 sceneId, uint32 verbId,
+ uint32 objectId2, uint32 objectId)
+ : Thread(vm, threadId, callingThreadId, 0), _bbdou(bbdou), _cursorObjectId(cursorObjectId),
+ _sceneId(sceneId), _verbId(verbId), _objectId2(objectId2), _objectId(objectId) {
+ _type = kTTSpecialThread;
+}
+
+void CauseThread::onNotify() {
+ _bbdou->_cursor->_data._causeThreadId1 = 0;
+ terminate();
+}
+
+void CauseThread::onTerminated() {
+ _bbdou->_cursor->_data._causeThreadId1 = 0;
+ _bbdou->_cursor->enable(_cursorObjectId);
+}
+
// BbdouSpecialCode
BbdouSpecialCode::BbdouSpecialCode(IllusionsEngine *vm)
@@ -125,7 +143,7 @@ void BbdouSpecialCode::spcSetObjectInteractMode(OpCall &opCall) {
ARG_SKIP(4);
ARG_UINT32(objectId);
ARG_INT16(value);
- // TODO Cursor_updateStruct8bs(objectId, v3);
+ _cursor->setStruct8bsValue(objectId, value);
_vm->notifyThreadId(opCall._callerThreadId);
}
@@ -176,19 +194,26 @@ Common::Point BbdouSpecialCode::getBackgroundCursorPos(Common::Point cursorPos)
return pt;
}
-bool BbdouSpecialCode::runCause(Control *control, CursorData &cursorData,
- uint32 verbId, uint32 objectId1, uint32 objectId2, int soundIndex) {
- // TODO
- return false;
-}
-
void BbdouSpecialCode::showBubble(uint32 objectId, uint32 overlappedObjectId, uint32 holdingObjectId,
Item10 *item10, uint32 progResKeywordId) {
// TODO
}
bool BbdouSpecialCode::findVerbId(Item10 *item10, uint32 currOverlappedObjectId, int always0, uint32 &outVerbId) {
- // TODO
+ if (item10->_playSound48) {
+ int verbNum = item10->_verbId & 0xFFFF;
+ int verbNumI = verbNum + 1;
+ while (1) {
+ if (verbNumI >= 32)
+ verbNumI = 0;
+ if (verbNumI++ == verbNum)
+ break;
+ if (item10->_verbActive[verbNumI] && testVerbId(verbNumI | 0x1B0000, always0, currOverlappedObjectId)) {
+ outVerbId = verbNumI | 0x1B0000;
+ return true;
+ }
+ }
+ }
return false;
}
@@ -221,21 +246,22 @@ void BbdouSpecialCode::cursorInteractControlRoutine(Control *cursorControl, uint
if (cursorData._flags & 1) {
foundOverlapped = 0;
- } else if (_vm->_scriptMan->_activeScenes.getCurrentScene() == 0x1000D) {
+ } else if (_vm->getCurrentScene() == 0x1000D) {
/* TODO foundOverlapped = artcntrlGetOverlappedObjectAccurate(cursorControl, cursorPos,
&overlappedControl, cursorData._item10._field58);*/
} else {
foundOverlapped = _vm->_controls->getOverlappedObject(cursorControl, cursorPos,
&overlappedControl, cursorData._item10._field58);
- debug("overlappedControl: %p", (void*)overlappedControl);
}
if (foundOverlapped) {
+ debug("overlappedControl: %p", (void*)overlappedControl);
if (overlappedControl->_objectId != cursorData._currOverlappedObjectId) {
if (cursorData._item10._playSound48)
playSoundEffect(4);
resetItem10(cursorControl->_objectId, &cursorData._item10);
int value = _cursor->findStruct8bsValue(overlappedControl->_objectId);
+ debug("object value: %d", value);
if (!testValueRange(value)) {
if (cursorData._mode == 3)
_cursor->restoreInfo();
@@ -346,4 +372,119 @@ bool BbdouSpecialCode::updateTrackingCursor(Control *cursorControl) {
return false;
}
+bool BbdouSpecialCode::testVerbId(uint32 verbId, uint32 holdingObjectId, uint32 overlappedObjectId) {
+ static const uint32 kVerbIdsEE[] = {0x001B0002, 0x001B0001, 0};
+ static const uint32 kVerbIdsE9[] = {0x001B0005, 0};
+ static const uint32 kVerbIdsE8[] = {0x001B0005, 0x001B0001, 0};
+ static const uint32 kVerbIdsHE[] = {0x001B0003, 0x001B0001, 0};
+ static const uint32 kVerbIdsH9[] = {0x001B0003, 0};
+ static const uint32 kVerbIdsH8[] = {0x001B0003, 0x001B0001, 0};
+
+ const uint32 *verbIds;
+ int value = _cursor->findStruct8bsValue(overlappedObjectId);
+
+ if (holdingObjectId) {
+ if (value == 9)
+ verbIds = kVerbIdsH9;
+ else if (value == 9)
+ verbIds = kVerbIdsH8;
+ else
+ verbIds = kVerbIdsHE;
+ } else {
+ if (value == 9)
+ verbIds = kVerbIdsE9;
+ else if (value == 8)
+ verbIds = kVerbIdsE8;
+ else
+ verbIds = kVerbIdsEE;
+ }
+
+ for (; *verbIds; ++verbIds)
+ if (*verbIds == verbId)
+ return true;
+ return false;
+}
+
+bool BbdouSpecialCode::getCause(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId,
+ uint32 &outVerbId, uint32 &outObjectId2, uint32 &outObjectId) {
+ bool success = false;
+ objectId2 = verbId != 0x1B0003 ? 0 : objectId2;
+ if (_vm->causeIsDeclared(sceneId, verbId, objectId2, objectId)) {
+ outVerbId = verbId;
+ outObjectId2 = objectId2;
+ outObjectId = objectId;
+ success = true;
+ } else if (objectId2 != 0 && _vm->causeIsDeclared(sceneId, 0x1B0008, 0, objectId)) {
+ outVerbId = 0x1B0008;
+ outObjectId2 = 0;
+ outObjectId = objectId;
+ success = true;
+ } else if (_vm->causeIsDeclared(sceneId, verbId, objectId2, 0x40001)) {
+ outVerbId = verbId;
+ outObjectId2 = objectId2;
+ outObjectId = 0x40001;
+ success = true;
+ } else if (objectId2 != 0 && _vm->causeIsDeclared(sceneId, 0x1B0008, 0, 0x40001)) {
+ outVerbId = 0x1B0008;
+ outObjectId2 = 0;
+ outObjectId = 0x40001;
+ success = true;
+ }
+
+ if (success) {
+ debug("getCause() -> %08X %08X %08X", outVerbId, outObjectId2, outObjectId);
+ }
+
+ return success;
+}
+
+bool BbdouSpecialCode::runCause(Control *cursorControl, CursorData &cursorData,
+ uint32 verbId, uint32 objectId2, uint32 objectId, int soundIndex) {
+ debug("runCause(%08X, %08X, %08X)", verbId, objectId2, objectId);
+ uint32 sceneId = _vm->getCurrentScene();
+ uint32 outVerbId, outObjectId2, outObjectId;
+ bool success = false;
+
+ if (getCause(_vm->getCurrentScene(), verbId, objectId2, objectId, outVerbId, outObjectId2, outObjectId)) {
+ sceneId = _vm->getCurrentScene();
+ success = true;
+ } else if (getCause(0x10003, verbId, objectId2, objectId, outVerbId, outObjectId2, outObjectId)) {
+ sceneId = 0x10003;
+ success = true;
+ }
+
+ debug("runCause() success: %d", success);
+
+ if (!success)
+ return false;
+
+
+ _cursor->hide(cursorControl->_objectId);
+
+ uint32 threadId = startCauseThread(cursorControl->_objectId, _vm->getCurrentScene(), outVerbId, outObjectId2, outObjectId);
+
+ if (cursorData._field90) {
+ _vm->_scriptMan->_threads->killThread(cursorData._causeThreadId2);
+ cursorData._field90 = 0;
+ }
+
+ if (soundIndex)
+ playSoundEffect(soundIndex);
+
+ cursorData._causeThreadId1 = _vm->causeTrigger(sceneId, outVerbId, outObjectId2, outObjectId, threadId);
+ cursorData._causeThreadId2 = cursorData._causeThreadId1;
+
+ return true;
+}
+
+uint32 BbdouSpecialCode::startCauseThread(uint32 cursorObjectId, uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId) {
+ uint32 tempThreadId = _vm->_scriptMan->newTempThreadId();
+ debug("staring cause thread %08X...", tempThreadId);
+ CauseThread *causeThread = new CauseThread(_vm, tempThreadId, 0, this,
+ cursorObjectId, sceneId, verbId, objectId2, objectId);
+ _vm->_scriptMan->_threads->startThread(causeThread);
+ causeThread->suspend();
+ return tempThreadId;
+}
+
} // End of namespace Illusions
diff --git a/engines/illusions/bbdou/bbdou_specialcode.h b/engines/illusions/bbdou/bbdou_specialcode.h
index 1dda19fa78..61f6b703da 100644
--- a/engines/illusions/bbdou/bbdou_specialcode.h
+++ b/engines/illusions/bbdou/bbdou_specialcode.h
@@ -24,6 +24,7 @@
#define ILLUSIONS_BBDOU_BBDOU_SPECIALCODE_H
#include "illusions/specialcode.h"
+#include "illusions/thread.h"
#include "common/hashmap.h"
namespace Illusions {
@@ -36,6 +37,24 @@ struct Item10;
typedef Common::Functor1<OpCall&, void> SpecialCodeFunction;
+class BbdouSpecialCode;
+
+class CauseThread : public Thread {
+public:
+ CauseThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThreadId,
+ BbdouSpecialCode *bbdou, uint32 cursorObjectId, uint32 sceneId,
+ uint32 verbId, uint32 objectId2, uint32 objectId);
+ virtual void onNotify();
+ virtual void onTerminated();
+public:
+ BbdouSpecialCode *_bbdou;
+ uint32 _cursorObjectId;
+ uint32 _sceneId;
+ uint32 _verbId;
+ uint32 _objectId2;
+ uint32 _objectId;
+};
+
class BbdouSpecialCode : public SpecialCode {
public:
BbdouSpecialCode(IllusionsEngine *vm);
@@ -63,14 +82,18 @@ protected:
bool testValueRange(int value);
void setCursorControlRoutine(uint32 objectId, int num);
Common::Point getBackgroundCursorPos(Common::Point cursorPos);
- bool runCause(Control *control, CursorData &cursorData,
- uint32 verbId, uint32 objectId1, uint32 objectId2, int soundIndex);
void showBubble(uint32 objectId, uint32 overlappedObjectId, uint32 holdingObjectId,
Item10 *item10, uint32 progResKeywordId);
bool findVerbId(Item10 *item10, uint32 currOverlappedObjectId, int always0, uint32 &outVerbId);
void cursorInteractControlRoutine(Control *cursorControl, uint32 deltaTime);
void cursorControlRoutine2(Control *cursorControl, uint32 deltaTime);
bool updateTrackingCursor(Control *cursorControl);
+ bool testVerbId(uint32 verbId, uint32 holdingObjectId, uint32 overlappedObjectId);
+ bool getCause(uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId,
+ uint32 &outVerbId, uint32 &outObjectId2, uint32 &outObjectId);
+ bool runCause(Control *cursorControl, CursorData &cursorData,
+ uint32 verbId, uint32 objectId2, uint32 objectId, int soundIndex);
+ uint32 startCauseThread(uint32 cursorObjectId, uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId);
};
} // End of namespace Illusions