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 /engines/illusions/bbdou | |
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
Diffstat (limited to 'engines/illusions/bbdou')
-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 |
6 files changed, 806 insertions, 6 deletions
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 |