diff options
author | johndoe123 | 2014-03-25 19:57:21 +0100 |
---|---|---|
committer | Eugene Sandulenko | 2018-07-20 06:43:33 +0000 |
commit | e05a7899755011f860f2b09ce6d5b4e0a15107b9 (patch) | |
tree | b16815bcf51d3b776e63563d04f9997cb4a4567f | |
parent | 28cb39eb2b48d8c6e80e35ef6e26e02cc209fc0f (diff) | |
download | scummvm-rg350-e05a7899755011f860f2b09ce6d5b4e0a15107b9.tar.gz scummvm-rg350-e05a7899755011f860f2b09ce6d5b4e0a15107b9.tar.bz2 scummvm-rg350-e05a7899755011f860f2b09ce6d5b4e0a15107b9.zip |
ILLUSIONS: More work on BBDOU specific code (cursor, bubble)
- Add input handling code
-rw-r--r-- | engines/illusions/actor.cpp | 91 | ||||
-rw-r--r-- | engines/illusions/actor.h | 7 | ||||
-rw-r--r-- | engines/illusions/bbdou/bbdou_bubble.cpp | 150 | ||||
-rw-r--r-- | engines/illusions/bbdou/bbdou_bubble.h | 81 | ||||
-rw-r--r-- | engines/illusions/bbdou/bbdou_cursor.cpp | 167 | ||||
-rw-r--r-- | engines/illusions/bbdou/bbdou_cursor.h | 77 | ||||
-rw-r--r-- | engines/illusions/bbdou/bbdou_specialcode.cpp | 304 | ||||
-rw-r--r-- | engines/illusions/bbdou/bbdou_specialcode.h | 33 | ||||
-rw-r--r-- | engines/illusions/illusions.cpp | 23 | ||||
-rw-r--r-- | engines/illusions/input.cpp | 86 | ||||
-rw-r--r-- | engines/illusions/input.h | 24 | ||||
-rw-r--r-- | engines/illusions/module.mk | 1 | ||||
-rw-r--r-- | engines/illusions/scriptopcodes.cpp | 5 |
13 files changed, 1011 insertions, 38 deletions
diff --git a/engines/illusions/actor.cpp b/engines/illusions/actor.cpp index b813ff0cc9..fbc5958ecc 100644 --- a/engines/illusions/actor.cpp +++ b/engines/illusions/actor.cpp @@ -95,7 +95,7 @@ Actor::Actor(IllusionsEngine *vm) _pathCtrY = 0; _controlRoutine = 0; - setControlRoutine(new Common::Functor2Mem<Control*, uint32, void, Controls>(_vm->_controls, &Controls::actorControlRouine)); + setControlRoutine(new Common::Functor2Mem<Control*, uint32, void, Controls>(_vm->_controls, &Controls::actorControlRoutine)); #if 0 // TODO _field2 = 0; @@ -283,7 +283,7 @@ void Control::activateObject() { } void Control::deactivateObject() { - _flags |= ~1; + _flags &= ~1; if (_actor) { for (uint i = 0; i < kSubObjectsCount; ++i) if (_actor->_subobjects[i]) { @@ -377,11 +377,11 @@ int Control::getPriority() { int16 positionY, priority, priority1; if (_actor) { if (_actor->_parentObjectId && (_actor->_flags & 0x40)) { - uint32 objectId2 = getSubActorParent(); - Control *control2 = _vm->_dict->getObjectControl(objectId2); - objectId = control2->_objectId; - priority = control2->_priority; - positionY = control2->_actor->_position.y; + uint32 parentObjectId = getSubActorParent(); + Control *parentControl = _vm->_dict->getObjectControl(parentObjectId); + objectId = parentControl->_objectId; + priority = parentControl->_priority; + positionY = parentControl->_actor->_position.y; priority1 = _priority; } else { objectId = _objectId; @@ -475,6 +475,24 @@ void Control::getCollisionRectAccurate(Common::Rect &collisionRect) { } +void Control::getCollisionRect(Common::Rect &collisionRect) { + collisionRect = Common::Rect(_unkPt.x, _unkPt.y, _pt.x, _pt.y); + if (_actor) { + if (_actor->_scale != 100) { + // scaledValue = value * scale div 100 + collisionRect.left = collisionRect.left * _actor->_scale / 100; + collisionRect.top = collisionRect.top * _actor->_scale / 100; + collisionRect.right = collisionRect.right * _actor->_scale / 100; + collisionRect.bottom = collisionRect.bottom * _actor->_scale / 100; + } + collisionRect.translate(_actor->_position.x, _actor->_position.y); + } + if (_flags & 8) { + Common::Point screenOffs = _vm->_camera->getScreenOffset(); + collisionRect.translate(screenOffs.x, screenOffs.y); + } +} + void Control::setActorUsePan(int usePan) { if (usePan == 1) _flags &= ~8; @@ -602,6 +620,14 @@ void Control::sequenceActor() { } +void Control::setActorIndexTo1() { + _actor->_actorIndex = 1; +} + +void Control::setActorIndexTo2() { + _actor->_actorIndex = 2; +} + void Control::startSequenceActorIntern(uint32 sequenceId, int value, byte *entryTblPtr, uint32 notifyThreadId) { stopActor(); @@ -618,10 +644,18 @@ void Control::startSequenceActorIntern(uint32 sequenceId, int value, byte *entry _actor->_path40 = 0; Sequence *sequence = _vm->_dict->findSequence(sequenceId); + //debug("sequence: %p", (void*)sequence); _actor->_seqCodeIp = sequence->_sequenceCode; _actor->_frames = _vm->_actorItems->findSequenceFrames(sequence); + /* + for (int i = 0; i < 64; ++i) { + debugN("%02X ", sequence->_sequenceCode[i]); + } + debug("."); + */ + _actor->_seqCodeValue3 = 0; _actor->_seqCodeValue1 = 0; _actor->_seqCodeValue2 = value == 1 ? 350 : 600; @@ -815,7 +849,48 @@ void Controls::unpauseControlsByTag(uint32 tag) { } } -void Controls::actorControlRouine(Control *control, uint32 deltaTime) { +bool Controls::getOverlappedObject(Control *control, Common::Point pt, Control **outOverlappedControl, int minPriority) { + Control *foundControl = 0; + int foundPriority = 0; + // TODO minPriority = artcntrlGetPriorityFromBase(minPriority); + + for (ItemsIterator it = _controls.begin(); it != _controls.end(); ++it) { + Control *testControl = *it; + if (testControl != control && testControl->_pauseCtr == 0 && + (testControl->_flags & 1) && !(testControl->_flags & 0x10) && + (!testControl->_actor || (testControl->_actor->_flags & 1))) { + Common::Rect collisionRect; + testControl->getCollisionRect(collisionRect); + debug("collisionRect(%d, %d, %d, %d)", collisionRect.left, collisionRect.top, collisionRect.right, collisionRect.bottom); + debug("pt(%d, %d)", pt.x, pt.y); + if (!collisionRect.isEmpty() && collisionRect.contains(pt)) { + int testPriority = testControl->getPriority(); + debug("testPriority: %d; minPriority: %d", testPriority, minPriority); + if ((!foundControl || foundPriority < testPriority) && + testPriority >= minPriority) { + debug("overlapped() %08X; pauseCtr: %d; flags: %04X", + testControl->_objectId, testControl->_pauseCtr, testControl->_flags); + foundControl = testControl; + foundPriority = testPriority; + } + } + } + } + + debug("OVERLAPPED DONE\n"); + + if (foundControl) { + if (foundControl->_actor && foundControl->_actor->_parentObjectId && (foundControl->_actor->_flags & 0x40)) { + uint32 parentObjectId = foundControl->getSubActorParent(); + foundControl = _vm->_dict->getObjectControl(parentObjectId); + } + *outOverlappedControl = foundControl; + } + + return foundControl != 0; +} + +void Controls::actorControlRoutine(Control *control, uint32 deltaTime) { Actor *actor = control->_actor; diff --git a/engines/illusions/actor.h b/engines/illusions/actor.h index fe5564e0a7..9ddfc9cf16 100644 --- a/engines/illusions/actor.h +++ b/engines/illusions/actor.h @@ -134,7 +134,6 @@ public: int _pathCtrY; int _path40; - }; class Control { @@ -162,6 +161,7 @@ public: Common::Point calcPosition(Common::Point posDelta); uint32 getSubActorParent(); void getCollisionRectAccurate(Common::Rect &collisionRect); + void getCollisionRect(Common::Rect &collisionRect); void setActorUsePan(int usePan); void setActorFrameIndex(int16 frameIndex); void stopActor(); @@ -169,6 +169,8 @@ public: void stopSequenceActor(); void startTalkActor(uint32 sequenceId, byte *entryTblPtr, uint32 threadId); void sequenceActor(); + void setActorIndexTo1(); + void setActorIndexTo2(); public: IllusionsEngine *_vm; uint _flags; @@ -201,7 +203,8 @@ public: void destroyControlsByTag(uint32 tag); void pauseControlsByTag(uint32 tag); void unpauseControlsByTag(uint32 tag); - void actorControlRouine(Control *control, uint32 deltaTime); + bool getOverlappedObject(Control *control, Common::Point pt, Control **outOverlappedControl, int minPriority); + void actorControlRoutine(Control *control, uint32 deltaTime); public: typedef Common::List<Control*> Items; typedef Items::iterator ItemsIterator; diff --git a/engines/illusions/bbdou/bbdou_bubble.cpp b/engines/illusions/bbdou/bbdou_bubble.cpp new file mode 100644 index 0000000000..3256bc404d --- /dev/null +++ b/engines/illusions/bbdou/bbdou_bubble.cpp @@ -0,0 +1,150 @@ +/* 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/bbdou/bbdou_bubble.h" +#include "illusions/actor.h" +#include "illusions/camera.h" +#include "illusions/dictionary.h" +#include "illusions/input.h" + +namespace Illusions { + +BbdouBubble::BbdouBubble(IllusionsEngine *vm, BbdouSpecialCode *bbdou) + : _vm(vm), _bbdou(bbdou) { +} + +BbdouBubble::~BbdouBubble() { +} + +void BbdouBubble::init() { + + static const uint32 kObjectIds3[] = { + 0x0004003B, 0x0004003C, 0x0004003D, 0x0004003E, + 0x0004003F, 0x00040040, 0x00040041, 0x00040042, + 0x00040043, 0x00040044, 0x00040045, 0x00040046, + 0x00040047, 0x00040048, 0x00040049, 0x0004004A, + 0x0004004B, 0x0004004C, 0x0004004D, 0x0004004E, + 0x0004004F, 0x00040050, 0x00040051, 0x00040052, + 0x00040053, 0x00040054, 0x00040055, 0x00040056, + 0x00040057, 0x00040058, 0x00040059, 0x0004005A + }; + + static const uint32 kObjectIds2[] = { + 0x0004001B, 0x0004001C, 0x0004001D, 0x0004001E, + 0x0004001F, 0x00040020, 0x00040021, 0x00040022, + 0x00040023, 0x00040024, 0x00040025, 0x00040026, + 0x00040027, 0x00040028, 0x00040029, 0x0004002A, + 0x0004002B, 0x0004002C, 0x0004002D, 0x0004002E, + 0x0004002F, 0x00040030, 0x00040031, 0x00040032, + 0x00040033, 0x00040034, 0x00040035, 0x00040036, + 0x00040037, 0x00040038, 0x00040039, 0x0004003A + }; + + _field1414 = 0x4005B; + _field1418 = 0x4005C; + + for (uint i = 0; i < 32; ++i) + _objectIds[i] = kObjectIds3[i]; + + for (uint i = 0; i < 32; ++i) { + _items[i]._objectId = kObjectIds2[i]; + _items[i]._enabled = 0; + _items[i]._position.x = 0; + _items[i]._position.y = 0; + _items[i]._sequenceId = 0; + } + + _currItem0 = 0; + _prevItem0 = 0; + _someItem0 = 0; + _pt1.x = 0; + _pt1.y = 0; + _pt2.x = 0; + _pt2.y = 0; + +} + +void BbdouBubble::addItem0(uint32 sequenceId1, uint32 sequenceId2, uint32 progResKeywordId, + uint32 namedPointId, int16 count, uint32 *namedPointIds) { + Item0 item0; + item0._sequenceId1 = sequenceId1; + item0._sequenceId2 = sequenceId2; + item0._progResKeywordId = progResKeywordId; + item0._baseNamedPointId = namedPointId; + item0._count = count; + for (int16 i = 0; i < count; ++i) + item0._namedPointIds[i] = FROM_LE_32(namedPointIds[i]); + item0._objectId = 0; + item0._pt.x = 0; + item0._pt.y = 0; + _item0s.push_back(item0); +} + +void BbdouBubble::show() { + + if (_prevItem0) { + hide(); + } + + _prevItem0 = _currItem0; + _currItem0 = 0; + + // TODO calcBubbles(_pt1, _pt2); + + Control *control = _vm->_dict->getObjectControl(_prevItem0->_objectId); + control->setActorPosition(_pt2); + control->startSequenceActor(0x60057, 2, 0); + control->startSequenceActor(_prevItem0->_sequenceId1, 2, 0); + control->appearActor(); + control->deactivateObject(); + + for (uint i = 0; i < 32; ++i) { + if (_items[i]._enabled == 1) { + Control *subControl = _vm->_dict->getObjectControl(_items[i]._objectId); + subControl->setActorPosition(_items[i]._position); + subControl->startSequenceActor(_items[i]._sequenceId, 2, 0); + } + } + +} + +void BbdouBubble::hide() { + _someItem0 = _prevItem0; + _prevItem0 = 0; + if (_someItem0) { + Control *control = _vm->_dict->getObjectControl(_someItem0->_objectId); + control->startSequenceActor(_someItem0->_sequenceId2, 2, 0); + for (uint i = 0; i < 32; ++i) { + Control *subControl = _vm->_dict->getObjectControl(_objectIds[i]); + subControl->stopActor(); + subControl->disappearActor(); + } + for (uint i = 0; i < 32; ++i) { + Control *subControl = _vm->_dict->getObjectControl(_items[i]._objectId); + subControl->stopActor(); + subControl->disappearActor(); + } + } +} + +} // End of namespace Illusions diff --git a/engines/illusions/bbdou/bbdou_bubble.h b/engines/illusions/bbdou/bbdou_bubble.h new file mode 100644 index 0000000000..9064acd08c --- /dev/null +++ b/engines/illusions/bbdou/bbdou_bubble.h @@ -0,0 +1,81 @@ +/* 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_BBDOU_BBDOU_BUBBLE_H +#define ILLUSIONS_BBDOU_BBDOU_BUBBLE_H + +#include "illusions/specialcode.h" +#include "common/rect.h" + +namespace Illusions { + +class IllusionsEngine; +class BbdouSpecialCode; +class Control; + +struct Item0 { + uint32 _sequenceId1; + uint32 _sequenceId2; + int16 _count; + uint32 _progResKeywordId; + uint32 _baseNamedPointId; + uint32 _namedPointIds[32]; + uint32 _objectId; + Common::Point _pt; + Item0() : _count(0) {} +}; + +struct Item141C { + uint32 _objectId; + int16 _enabled; + Common::Point _position; + int16 _fieldA; + uint32 _sequenceId; +}; + +class BbdouBubble { +public: + BbdouBubble(IllusionsEngine *vm, BbdouSpecialCode *bbdou); + ~BbdouBubble(); + void init(); + void addItem0(uint32 sequenceId1, uint32 sequenceId2, uint32 progResKeywordId, + uint32 namedPointId, int16 count, uint32 *namedPointIds); + void show(); + void hide(); +protected: + IllusionsEngine *_vm; + BbdouSpecialCode *_bbdou; + Common::Array<Item0> _item0s; + Item0 *_currItem0; + Item0 *_prevItem0; + Item0 *_someItem0; + uint32 _objectIds[32]; + Common::Point _pt1; + Common::Point _pt2; + int _field1414; + int _field1418; + Item141C _items[32]; +}; + +} // End of namespace Illusions + +#endif // ILLUSIONS_BBDOU_BBDOU_BUBBLE_H diff --git a/engines/illusions/bbdou/bbdou_cursor.cpp b/engines/illusions/bbdou/bbdou_cursor.cpp index 9c0bcc8170..16cd82ade6 100644 --- a/engines/illusions/bbdou/bbdou_cursor.cpp +++ b/engines/illusions/bbdou/bbdou_cursor.cpp @@ -23,17 +23,178 @@ #include "illusions/illusions.h" #include "illusions/bbdou/bbdou_cursor.h" #include "illusions/actor.h" +#include "illusions/camera.h" +#include "illusions/dictionary.h" +#include "illusions/input.h" namespace Illusions { -BbdouCursor::BbdouCursor(IllusionsEngine *vm) - : _vm(vm) { +// NOTE It's assumed there's only one game cursor object +// The original stores the _data inside the actor, here it's inside the Cursor class. + +BbdouCursor::BbdouCursor(IllusionsEngine *vm, BbdouSpecialCode *bbdou) + : _vm(vm), _bbdou(bbdou) { } BbdouCursor::~BbdouCursor() { } -void BbdouCursor::init() { +void BbdouCursor::init(uint32 objectId, uint32 progResKeywordId) { + + Common::Point pos = _vm->_camera->getCurrentPan(); + _vm->_controls->placeActor(0x50001, pos, 0x6000C, objectId, 0); + + Control *control = _vm->_dict->getObjectControl(objectId); + //control->_actor->setControlRoutine(new Common::Functor2Mem<Control*, uint32, void, BbdouCursor>(this, &BbdouCursor::actorControlRoutine1)); + control->_flags |= 8; + + _data._mode = 1; + _data._mode2 = 0; + _data._verbId1 = 0x1B0000; + _data._progResKeywordId = progResKeywordId; + _data._currOverlappedObjectId = 0; + _data._overlappedObjectId = 0; + _data._sequenceId = 0x6000F; + _data._holdingObjectId = 0; + _data._holdingObjectId2 = 0; + _data._visibleCtr = 0; + _data._causeThreadId1 = 0; + _data._causeThreadId2 = 0; + _data._field90 = 0; + _data._flags = 0; + _data._item10._field58 = 1; + _data._sequenceId98 = 0; + _data._idleCtr = 0; + _data._item10._verbId = 0x1B0000; + _data._item10._field0 = 1; + _data._item10._playSound48 = 0; + _data._item10._objectIds[0] = 0; + _data._item10._objectIds[1] = 0; + _data._item10._index = 0; + _data._item10._flag56 = 0; + + clearCursorDataField14(); + + control->setActorIndexTo1(); + +} + +void BbdouCursor::enable(uint32 objectId) { + ++_data._visibleCtr; + if (_data._visibleCtr == 1) { + Control *control = _vm->_dict->getObjectControl(objectId); + show(control); + _vm->_camera->pushCameraMode(); + _vm->_camera->panEdgeFollow(objectId, 360); + _data._idleCtr = 0; + } + _vm->_input->discardButtons(0xFFFF); +} + +void BbdouCursor::disable(uint32 objectId) { + hide(objectId); +} + +void BbdouCursor::addCursorSequence(uint32 objectId, uint32 sequenceId) { + for (uint i = 0; i < kMaxCursorSequences; ++i) + if (_cursorSequences[i]._objectId == 0) { + _cursorSequences[i]._objectId = objectId; + _cursorSequences[i]._sequenceId = sequenceId; + break; + } +} + +uint32 BbdouCursor::findCursorSequenceId(uint32 objectId) { + for (uint i = 0; i < kMaxCursorSequences; ++i) + if (_cursorSequences[i]._objectId == objectId) + return _cursorSequences[i]._sequenceId; + return 0; +} + +int BbdouCursor::findStruct8bsValue(uint32 objectId) { + for (uint i = 0; i < kMaxCursorSequences; ++i) + if (_cursorStruct8bs[i]._objectId == objectId) + return _cursorStruct8bs[i]._value; + return 11; +} + +void BbdouCursor::saveInfo() { + _data._mode2 = _data._mode; + _data._sequenceId2 = _data._sequenceId; + _data._holdingObjectId2 = _data._holdingObjectId; +} + +void BbdouCursor::restoreInfo() { + _data._mode = _data._mode2; + _data._holdingObjectId = _data._holdingObjectId2; + _data._sequenceId = _data._sequenceId2; + _data._mode2 = 0; + _data._holdingObjectId2 = 0; + _data._sequenceId2 = 0; +} + +void BbdouCursor::restoreAfterTrackingCursor() { + _data._holdingObjectId = _data._holdingObjectId2; + if (_data._holdingObjectId2) { + _data._mode = 2; + _data._sequenceId = findCursorSequenceId(_data._holdingObjectId2); + } else { + _data._mode = 1; + _data._sequenceId = 0x6000F; + } + _data._mode2 = 0; + _data._sequenceId2 = 0; + _data._holdingObjectId2 = 0; + _data._sequenceId98 = 0; +} + +uint32 BbdouCursor::getSequenceId1(int sequenceIndex) { + switch (sequenceIndex) { + case 2: + return 0x60010; + case 3: + return 0x60011; + case 4: + return 0x60012; + case 5: + return 0x60013; + case 6: + return 0x60015; + case 7: + return 0x60014; + default: + return 0; + } +} + +void BbdouCursor::clearCursorDataField14() { + for (uint i = 0; i < 32; ++i) + _data._item10._verbActive[i] = 0; + if (_data._item10._field0 == 1) { + _data._item10._verbActive[1] = 1; + _data._item10._verbActive[2] = 1; + _data._item10._verbActive[3] = 1; + _data._item10._verbActive[5] = 1; + } else if (_data._item10._field0 == 3) { + _data._item10._verbActive[1] = 1; + _data._item10._verbActive[2] = 1; + } +} + +void BbdouCursor::show(Control *control) { + control->startSequenceActor(_data._sequenceId, 2, 0); + control->appearActor(); +} + +void BbdouCursor::hide(uint32 objectId) { + --_data._visibleCtr; + if (_data._visibleCtr == 0) { + Control *control = _vm->_dict->getObjectControl(objectId); + control->startSequenceActor(0x60029, 2, 0); + // TODO item10_sub_10005040(objectId, &cursorData->item10); + _vm->_camera->popCameraMode(); + } + _vm->_input->discardButtons(0xFFFF); } } // End of namespace Illusions diff --git a/engines/illusions/bbdou/bbdou_cursor.h b/engines/illusions/bbdou/bbdou_cursor.h index df3ed82f1a..8f02632857 100644 --- a/engines/illusions/bbdou/bbdou_cursor.h +++ b/engines/illusions/bbdou/bbdou_cursor.h @@ -28,14 +28,85 @@ namespace Illusions { class IllusionsEngine; +class BbdouSpecialCode; +class Control; +struct Item10; + +struct Item10 { + int _field0; + int16 _verbActive[32]; + uint32 _verbId; + int16 _playSound48; + //field_4A dw + uint32 _objectIds[2]; + int16 _index; + int16 _flag56; + int _field58; +}; + +struct CursorData { + int _mode; + int _mode2; + uint32 _verbId1; + uint32 _progResKeywordId; + Item10 _item10; + uint32 _currOverlappedObjectId; + uint32 _overlappedObjectId; + uint32 _sequenceId; + uint32 _sequenceId2; + uint32 _holdingObjectId; + uint32 _holdingObjectId2; + int _visibleCtr; + //field_86 dw + uint32 _causeThreadId1; + uint32 _causeThreadId2; + int16 _field90; + //field_92 dw + uint _flags; + uint32 _sequenceId98; + int16 _idleCtr; + //field_9E db + //field_9F db +}; + +struct CursorSequence { + uint32 _objectId; + uint32 _sequenceId; + CursorSequence() : _objectId(0), _sequenceId(0) {} +}; + +struct Struct8b { + uint32 _objectId; + int _value; + Struct8b() : _objectId(0), _value(0) {} +}; + +const uint kMaxCursorSequences = 100; class BbdouCursor { public: - BbdouCursor(IllusionsEngine *vm); + BbdouCursor(IllusionsEngine *vm, BbdouSpecialCode *bbdou); ~BbdouCursor(); - void init(); -protected: + void init(uint32 objectId, uint32 progResKeywordId); + void enable(uint32 objectId); + void disable(uint32 objectId); + void addCursorSequence(uint32 objectId, uint32 sequenceId); + uint32 findCursorSequenceId(uint32 objectId); + int findStruct8bsValue(uint32 objectId); + void saveInfo(); + void restoreInfo(); + void restoreAfterTrackingCursor(); + uint32 getSequenceId1(int sequenceIndex); +public: IllusionsEngine *_vm; + BbdouSpecialCode *_bbdou; + Control *_control; + CursorData _data; + CursorSequence _cursorSequences[kMaxCursorSequences]; + Struct8b _cursorStruct8bs[512]; + void clearCursorDataField14(); + void show(Control *control); + void hide(uint32 objectId); }; } // End of namespace Illusions diff --git a/engines/illusions/bbdou/bbdou_specialcode.cpp b/engines/illusions/bbdou/bbdou_specialcode.cpp index 028fdb54a8..e0d29e7265 100644 --- a/engines/illusions/bbdou/bbdou_specialcode.cpp +++ b/engines/illusions/bbdou/bbdou_specialcode.cpp @@ -22,7 +22,13 @@ #include "illusions/illusions.h" #include "illusions/bbdou/bbdou_specialcode.h" +#include "illusions/bbdou/bbdou_bubble.h" #include "illusions/bbdou/bbdou_cursor.h" +#include "illusions/actor.h" +#include "illusions/camera.h" +#include "illusions/dictionary.h" +#include "illusions/input.h" +#include "illusions/scriptman.h" #include "illusions/scriptopcodes.h" namespace Illusions { @@ -31,15 +37,313 @@ namespace Illusions { BbdouSpecialCode::BbdouSpecialCode(IllusionsEngine *vm) : SpecialCode(vm) { + _bubble = new BbdouBubble(_vm, this); + _cursor = new BbdouCursor(_vm, this); } BbdouSpecialCode::~BbdouSpecialCode() { + delete _cursor; + delete _bubble; } +typedef Common::Functor1Mem<OpCall&, void, BbdouSpecialCode> SpecialCodeFunctionI; +#define SPECIAL(id, func) _map[id] = new SpecialCodeFunctionI(this, &BbdouSpecialCode::func); + void BbdouSpecialCode::init() { + // TODO + SPECIAL(0x00160006, spcInitCursor); + SPECIAL(0x00160008, spcEnableCursor); + SPECIAL(0x00160009, spcDisableCursor); + SPECIAL(0x0016000A, spcAddCursorSequence); + SPECIAL(0x00160013, spcInitBubble); + SPECIAL(0x00160014, spcSetupBubble); + SPECIAL(0x00160015, spcSetObjectInteractMode); } void BbdouSpecialCode::run(uint32 specialCodeId, OpCall &opCall) { + MapIterator it = _map.find(specialCodeId); + if (it != _map.end()) { + (*(*it)._value)(opCall); + } else { + debug("BbdouSpecialCode::run() Unimplemented special code %08X", specialCodeId); + _vm->notifyThreadId(opCall._callerThreadId); + } +} + +// Special codes + +// Convenience macros +#define ARG_SKIP(x) opCall.skip(x); +#define ARG_INT16(name) int16 name = opCall.readSint16(); debug("ARG_INT16(" #name " = %d)", name); +#define ARG_UINT32(name) uint32 name = opCall.readUint32(); debug("ARG_UINT32(" #name " = %08X)", name); + +void BbdouSpecialCode::spcInitCursor(OpCall &opCall) { + ARG_UINT32(objectId); + ARG_UINT32(progResKeywordId); + _cursor->init(objectId, progResKeywordId); + setCursorControlRoutine(objectId, 0); + _vm->notifyThreadId(opCall._callerThreadId); +} + +void BbdouSpecialCode::spcEnableCursor(OpCall &opCall) { + ARG_UINT32(objectId); + _cursor->enable(objectId); + _vm->notifyThreadId(opCall._callerThreadId); +} + +void BbdouSpecialCode::spcDisableCursor(OpCall &opCall) { + ARG_UINT32(objectId); + _cursor->disable(objectId); + _vm->notifyThreadId(opCall._callerThreadId); +} + +void BbdouSpecialCode::spcAddCursorSequence(OpCall &opCall) { + ARG_SKIP(4); + ARG_UINT32(objectId); + ARG_UINT32(sequenceId); + _cursor->addCursorSequence(objectId, sequenceId); + _vm->notifyThreadId(opCall._callerThreadId); +} + +void BbdouSpecialCode::spcInitBubble(OpCall &opCall) { + _bubble->init(); + _vm->notifyThreadId(opCall._callerThreadId); +} + +void BbdouSpecialCode::spcSetupBubble(OpCall &opCall) { + ARG_UINT32(sequenceId1); + ARG_UINT32(sequenceId2); + ARG_UINT32(progResKeywordId); + ARG_UINT32(namedPointId); + ARG_INT16(count); + _bubble->addItem0(sequenceId1, sequenceId2, progResKeywordId, namedPointId, + count, (uint32*)opCall._code); + _vm->notifyThreadId(opCall._callerThreadId); +} + +void BbdouSpecialCode::spcSetObjectInteractMode(OpCall &opCall) { + ARG_SKIP(4); + ARG_UINT32(objectId); + ARG_INT16(value); + // TODO Cursor_updateStruct8bs(objectId, v3); + _vm->notifyThreadId(opCall._callerThreadId); +} + +void BbdouSpecialCode::playSoundEffect(int soundIndex) { + static const uint32 kSoundEffectIds[] = { + 0, 1, + 0x900C1, 2, + 0, 3, + 0x900C0, 4, + 0x900C2, 5, + 0, 6 + }; + uint32 soundEffectId = kSoundEffectIds[2 * soundIndex]; + if (soundEffectId) { + // TODO _vm->startSound(soundEffectId, 255, 0); + } +} + +void BbdouSpecialCode::resetItem10(uint32 objectId, Item10 *item10) { + if (item10->_playSound48 == 1) { + _bubble->hide(); + item10->_verbId = 0x1B0000; + item10->_playSound48 = 0; + item10->_objectIds[0] = 0; + item10->_objectIds[1] = 0; + } + _vm->_input->discardButtons(0xFFFF); +} + +bool BbdouSpecialCode::testValueRange(int value) { + return value >= 2 && value <= 7; +} + +void BbdouSpecialCode::setCursorControlRoutine(uint32 objectId, int num) { + Control *control = _vm->_dict->getObjectControl(objectId); + if (num == 0) + control->_actor->setControlRoutine( + new Common::Functor2Mem<Control*, uint32, void, BbdouSpecialCode>(this, &BbdouSpecialCode::cursorInteractControlRoutine)); + else + control->_actor->setControlRoutine( + new Common::Functor2Mem<Control*, uint32, void, BbdouSpecialCode>(this, &BbdouSpecialCode::cursorControlRoutine2)); +} + +Common::Point BbdouSpecialCode::getBackgroundCursorPos(Common::Point cursorPos) { + Common::Point pt = _vm->_camera->getScreenOffset(); + pt.x += cursorPos.x; + pt.y += cursorPos.y; + 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 + return false; +} + +void BbdouSpecialCode::cursorInteractControlRoutine(Control *cursorControl, uint32 deltaTime) { + Actor *actor = cursorControl->_actor; + CursorData &cursorData = _cursor->_data; + + if (cursorData._visibleCtr > 0) { + + Common::Point cursorPos = _vm->_input->getCursorPosition(); + + if (cursorPos == actor->_position) { + cursorData._idleCtr += deltaTime; + if (cursorData._idleCtr > 3600) + cursorData._idleCtr = 0; + } else { + actor->_position.x = cursorPos.x; + actor->_position.y = cursorPos.y; + cursorData._idleCtr = 0; + } + + if (updateTrackingCursor(cursorControl)) + cursorData._flags |= 1; + else + cursorData._flags &= ~1; + + cursorPos = getBackgroundCursorPos(cursorPos); + bool foundOverlapped = false; + Control *overlappedControl = 0; + + if (cursorData._flags & 1) { + foundOverlapped = 0; + } else if (_vm->_scriptMan->_activeScenes.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) { + if (overlappedControl->_objectId != cursorData._currOverlappedObjectId) { + if (cursorData._item10._playSound48) + playSoundEffect(4); + resetItem10(cursorControl->_objectId, &cursorData._item10); + int value = _cursor->findStruct8bsValue(overlappedControl->_objectId); + if (!testValueRange(value)) { + if (cursorData._mode == 3) + _cursor->restoreInfo(); + _cursor->show(cursorControl); + cursorControl->setActorIndexTo2(); + if (cursorData._overlappedObjectId != overlappedControl->_objectId) { + cursorData._overlappedObjectId = overlappedControl->_objectId; + runCause(cursorControl, cursorData, 0x1B0009, 0, overlappedControl->_objectId, 0); + } + if (value == 10) { + if (cursorData._holdingObjectId) { + cursorData._item10._verbId = 0x1B0003; + cursorData._currOverlappedObjectId = overlappedControl->_objectId; + } + else { + cursorData._item10._verbId = 0x1B0002; + cursorData._currOverlappedObjectId = overlappedControl->_objectId; + } + } else { + playSoundEffect(3); + showBubble(cursorControl->_objectId, overlappedControl->_objectId, + cursorData._holdingObjectId, &cursorData._item10, + cursorData._progResKeywordId); + cursorData._currOverlappedObjectId = overlappedControl->_objectId; + } + } else { + if (cursorData._mode != 3) { + _cursor->saveInfo(); + cursorData._mode = 3; + cursorData._item10._verbId = 0x1B0006; + cursorData._holdingObjectId = 0; + } + cursorData._sequenceId = _cursor->getSequenceId1(value); + _cursor->show(cursorControl); + cursorData._currOverlappedObjectId = overlappedControl->_objectId; + } + } + } else { + if (cursorData._overlappedObjectId) { + runCause(cursorControl, cursorData, 0x1B0009, 0, 0x40003, 0); + cursorData._overlappedObjectId = 0; + } + if (cursorData._currOverlappedObjectId || cursorData._mode == 3) { + if (cursorData._mode == 3) + _cursor->restoreInfo(); + _cursor->show(cursorControl); + cursorControl->setActorIndexTo1(); + if (cursorData._item10._playSound48) + playSoundEffect(4); + resetItem10(cursorControl->_objectId, &cursorData._item10); + } + cursorData._currOverlappedObjectId = 0; + } + } + + actor->_seqCodeValue1 = 100 * deltaTime; + + if (cursorData._visibleCtr <= 0) { + if (cursorData._currOverlappedObjectId || cursorData._mode == 3 || cursorData._mode == 4) { + if (cursorData._mode == 3) { + _cursor->restoreInfo(); + } else if (cursorData._mode == 4) { + _cursor->restoreAfterTrackingCursor(); + } + cursorControl->setActorIndexTo1(); + } + cursorData._currOverlappedObjectId = 0; + } else if (cursorData._currOverlappedObjectId) { + if (_vm->_input->pollButton(1)) { + cursorData._idleCtr = 0; + if (runCause(cursorControl, cursorData, cursorData._item10._verbId, cursorData._holdingObjectId, cursorData._currOverlappedObjectId, 1)) { + resetItem10(cursorControl->_objectId, &cursorData._item10); + cursorData._currOverlappedObjectId = 0; + cursorControl->setActorIndexTo1(); + } + } else if (_vm->_input->pollButton(2)) { + uint32 verbId; + cursorData._idleCtr = 0; + if (cursorData._holdingObjectId) { + runCause(cursorControl, cursorData, 0x1B000B, 0, 0x40003, 0); + cursorData._currOverlappedObjectId = 0; + } else if (findVerbId(&cursorData._item10, cursorData._currOverlappedObjectId, 0, verbId) && + runCause(cursorControl, cursorData, verbId, cursorData._holdingObjectId, cursorData._currOverlappedObjectId, 1)) { + resetItem10(cursorControl->_objectId, &cursorData._item10); + cursorData._currOverlappedObjectId = 0; + cursorControl->setActorIndexTo1(); + } + } + } else { + if (_vm->_input->pollButton(1)) { + cursorData._idleCtr = 0; + runCause(cursorControl, cursorData, 0x1B0002, 0, 0x40003, 0); + } else if (_vm->_input->pollButton(4)) { + cursorData._idleCtr = 0; + if (cursorData._item10._field58 <= 1) + runCause(cursorControl, cursorData, cursorData._holdingObjectId != 0 ? 0x1B000B : 0x1B0004, 0, 0x40003, 0); + } + } + +} + +void BbdouSpecialCode::cursorControlRoutine2(Control *cursorControl, uint32 deltaTime) { + // TODO +} + +bool BbdouSpecialCode::updateTrackingCursor(Control *cursorControl) { + // TODO + return false; } } // End of namespace Illusions diff --git a/engines/illusions/bbdou/bbdou_specialcode.h b/engines/illusions/bbdou/bbdou_specialcode.h index 98aef581be..1dda19fa78 100644 --- a/engines/illusions/bbdou/bbdou_specialcode.h +++ b/engines/illusions/bbdou/bbdou_specialcode.h @@ -24,11 +24,17 @@ #define ILLUSIONS_BBDOU_BBDOU_SPECIALCODE_H #include "illusions/specialcode.h" +#include "common/hashmap.h" namespace Illusions { class IllusionsEngine; +class BbdouBubble; class BbdouCursor; +struct CursorData; +struct Item10; + +typedef Common::Functor1<OpCall&, void> SpecialCodeFunction; class BbdouSpecialCode : public SpecialCode { public: @@ -37,7 +43,34 @@ public: virtual void init(); virtual void run(uint32 specialCodeId, OpCall &opCall); public: + typedef Common::HashMap<uint32, SpecialCodeFunction*> Map; + typedef Map::iterator MapIterator; + Map _map; BbdouCursor *_cursor; + BbdouBubble *_bubble; + // Special code interface functions + void spcInitCursor(OpCall &opCall); + void spcEnableCursor(OpCall &opCall); + void spcDisableCursor(OpCall &opCall); + void spcAddCursorSequence(OpCall &opCall); + void spcInitBubble(OpCall &opCall); + void spcSetupBubble(OpCall &opCall); + void spcSetObjectInteractMode(OpCall &opCall); +protected: + // Internal functions + void playSoundEffect(int soundIndex); + void resetItem10(uint32 objectId, Item10 *item10); + 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); }; } // End of namespace Illusions diff --git a/engines/illusions/illusions.cpp b/engines/illusions/illusions.cpp index a59c568c8b..cf40801fff 100644 --- a/engines/illusions/illusions.cpp +++ b/engines/illusions/illusions.cpp @@ -213,23 +213,9 @@ bool IllusionsEngine::hasFeature(EngineFeature f) const { void IllusionsEngine::updateEvents() { Common::Event event; - while (_eventMan->pollEvent(event)) { + _input->processEvent(event); switch (event.type) { - case Common::EVENT_KEYDOWN: - break; - case Common::EVENT_KEYUP: - break; - case Common::EVENT_MOUSEMOVE: - break; - case Common::EVENT_LBUTTONDOWN: - break; - case Common::EVENT_LBUTTONUP: - break; - case Common::EVENT_RBUTTONDOWN: - break; - case Common::EVENT_RBUTTONUP: - break; case Common::EVENT_QUIT: quitGame(); break; @@ -240,7 +226,9 @@ void IllusionsEngine::updateEvents() { } Common::Point *IllusionsEngine::getObjectActorPositionPtr(uint32 objectId) { - // TODO Dummy, to be replaced later + Control *control = _dict->getObjectControl(objectId); + if (control && control->_actor) + return &control->_actor->_position; return 0; } @@ -296,6 +284,7 @@ int IllusionsEngine::updateGraphics() { Common::Point panPoint(0, 0); uint32 currTime = getCurrentTime(); + _camera->update(currTime); // TODO Move to BackgroundItems class @@ -312,7 +301,7 @@ int IllusionsEngine::updateGraphics() { panPoint = backgroundItem->_panPoints[i]; } } - + // TODO Move to Controls class for (Controls::ItemsIterator it = _controls->_controls.begin(); it != _controls->_controls.end(); ++it) { Control *control = *it; diff --git a/engines/illusions/input.cpp b/engines/illusions/input.cpp index fd922eca0d..b9ae53abd1 100644 --- a/engines/illusions/input.cpp +++ b/engines/illusions/input.cpp @@ -27,18 +27,45 @@ namespace Illusions { Input::Input() { _buttonStates = 0; _newButtons = 0; - // TODO? _buttonsDown = 0; - // TODO? _unk6 = 0; + _buttonsDown = 0; + _newKeys = 0; _enabledButtons = 0xFFFF; _cursorPos.x = 0; _cursorPos.y = 0; _prevCursorPos.x = 0; _prevCursorPos.y = 0; // TODO Not sure if this is still needed newTimer(40, 0, 0, Input_onTimer); + initKeys(); } void Input::processEvent(Common::Event event) { // TODO + switch (event.type) { + case Common::EVENT_KEYDOWN: + handleKey(event.kbd.keycode, MOUSE_NONE, true); + break; + case Common::EVENT_KEYUP: + handleKey(event.kbd.keycode, MOUSE_NONE, false); + break; + case Common::EVENT_MOUSEMOVE: + _cursorPos.x = event.mouse.x; + _cursorPos.y = event.mouse.y; + break; + case Common::EVENT_LBUTTONDOWN: + handleMouseButton(MOUSE_BUTTON0, true); + break; + case Common::EVENT_LBUTTONUP: + handleMouseButton(MOUSE_BUTTON0, false); + break; + case Common::EVENT_RBUTTONDOWN: + handleMouseButton(MOUSE_BUTTON1, true); + break; + case Common::EVENT_RBUTTONUP: + handleMouseButton(MOUSE_BUTTON1, false); + break; + default: + break; + } } bool Input::pollButton(uint buttons) { @@ -90,4 +117,59 @@ Common::Point Input::getCursorDelta() { return deltaPos; } +void Input::initKeys() { + // NOTE Skipped debugging keys of the original engine, not sure if used + addKeyMapping(Common::KEYCODE_INVALID, MOUSE_BUTTON0, 0x01); + addKeyMapping(Common::KEYCODE_RETURN, MOUSE_NONE, 0x01); + addKeyMapping(Common::KEYCODE_TAB, MOUSE_NONE, 0x04); + addKeyMapping(Common::KEYCODE_INVALID, MOUSE_BUTTON1, 0x04); + addKeyMapping(Common::KEYCODE_ESCAPE, MOUSE_NONE, 0x08); + addKeyMapping(Common::KEYCODE_SPACE, MOUSE_NONE, 0x10); + addKeyMapping(Common::KEYCODE_F1, MOUSE_NONE, 0x20); + addKeyMapping(Common::KEYCODE_UP, MOUSE_NONE, 0x40); + addKeyMapping(Common::KEYCODE_DOWN, MOUSE_NONE, 0x80); + addKeyMapping(Common::KEYCODE_INVALID, MOUSE_BUTTON1, 0x80); +} + +void Input::addKeyMapping(Common::KeyCode key, int mouseButton, uint bitMask) { + KeyMapping keyMapping; + keyMapping._key = key; + keyMapping._mouseButton = mouseButton; + keyMapping._bitMask = bitMask; + keyMapping._down = false; + _keyMap.push_back(keyMapping); +} + +void Input::handleKey(Common::KeyCode key, int mouseButton, bool down) { + for (KeyMap::iterator it = _keyMap.begin(); it != _keyMap.end(); ++it) { + KeyMapping &keyMapping = *it; + if ((keyMapping._key != Common::KEYCODE_INVALID && keyMapping._key == key) || + (keyMapping._mouseButton != MOUSE_NONE && keyMapping._mouseButton == mouseButton)) { + if (down && !keyMapping._down) { + _newKeys |= keyMapping._bitMask; + keyMapping._down = true; + } else if (!down) + keyMapping._down = false; + } + } + uint prevButtonStates = _buttonStates; + + debug("_newKeys = %08X", _newKeys); + + _buttonStates |= _newKeys; + _newKeys = 0; + _newButtons = ~prevButtonStates & _buttonStates; + + debug("_buttonStates = %08X", _buttonStates); + +} + +void Input::handleMouseButton(int mouseButton, bool down) { + if (down) + _buttonsDown |= mouseButton; + else + _buttonsDown &= ~mouseButton; + handleKey(Common::KEYCODE_INVALID, mouseButton, down); +} + } // End of namespace Illusions diff --git a/engines/illusions/input.h b/engines/illusions/input.h index 700d9ed644..f3c9654d37 100644 --- a/engines/illusions/input.h +++ b/engines/illusions/input.h @@ -23,11 +23,26 @@ #ifndef ILLUSIONS_INPUT_H #define ILLUSIONS_INPUT_H +#include "common/array.h" #include "common/events.h" +#include "common/keyboard.h" #include "common/rect.h" namespace Illusions { +enum { + MOUSE_NONE = 0, + MOUSE_BUTTON0 = 1, + MOUSE_BUTTON1 = 2 +}; + +struct KeyMapping { + Common::KeyCode _key; + int _mouseButton; + uint _bitMask; + bool _down; +}; + class Input { public: Input(); @@ -43,9 +58,16 @@ public: void setCursorPosition(Common::Point mousePos); Common::Point getCursorDelta(); protected: - uint _buttonStates, _newButtons; + typedef Common::Array<KeyMapping> KeyMap; + uint _buttonStates, _newButtons, _buttonsDown; uint _enabledButtons; + uint _newKeys; Common::Point _cursorPos, _prevCursorPos; + KeyMap _keyMap; + void initKeys(); + void addKeyMapping(Common::KeyCode key, int mouseButton, uint bitMask); + void handleKey(Common::KeyCode key, int mouseButton, bool down); + void handleMouseButton(int mouseButton, bool down); }; } // End of namespace Illusions diff --git a/engines/illusions/module.mk b/engines/illusions/module.mk index 77f089ad03..762bd4c935 100644 --- a/engines/illusions/module.mk +++ b/engines/illusions/module.mk @@ -5,6 +5,7 @@ MODULE_OBJS := \ actor.o \ actorresource.o \ backgroundresource.o \ + bbdou/bbdou_bubble.o \ bbdou/bbdou_cursor.o \ bbdou/bbdou_specialcode.o \ camera.o \ diff --git a/engines/illusions/scriptopcodes.cpp b/engines/illusions/scriptopcodes.cpp index a191effb17..8abfa8b63b 100644 --- a/engines/illusions/scriptopcodes.cpp +++ b/engines/illusions/scriptopcodes.cpp @@ -29,6 +29,7 @@ #include "illusions/scriptman.h" #include "illusions/scriptresource.h" #include "illusions/scriptthread.h" +#include "illusions/specialcode.h" namespace Illusions { @@ -559,11 +560,11 @@ void ScriptOpcodes::opRunSpecialCode(ScriptThread *scriptThread, OpCall &opCall) ARG_SKIP(2); ARG_UINT32(specialCodeId); _vm->_scriptMan->_callerThreadId = opCall._callerThreadId; - // TODO _vm->runSpecialCode(specialCodeId, opCall._code + 8, opCall._threadId); + _vm->_specialCode->run(specialCodeId, opCall); _vm->_scriptMan->_callerThreadId = 0; //DEBUG Resume calling thread, later done by the special code - _vm->notifyThreadId(opCall._callerThreadId); + //_vm->notifyThreadId(opCall._callerThreadId); } |