mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 06:08:35 +00:00
ILLUSIONS: More work on BBDOU specific code (cursor, bubble)
- Add input handling code
This commit is contained in:
parent
28cb39eb2b
commit
e05a789975
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
150
engines/illusions/bbdou/bbdou_bubble.cpp
Normal file
150
engines/illusions/bbdou/bbdou_bubble.cpp
Normal file
@ -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
|
81
engines/illusions/bbdou/bbdou_bubble.h
Normal file
81
engines/illusions/bbdou/bbdou_bubble.h
Normal file
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user