aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjohndoe1232014-04-12 18:46:53 +0200
committerEugene Sandulenko2018-07-20 06:43:33 +0000
commit998744608f27802526b085ebe94215719ef9f28d (patch)
tree164599985e3c1f0893d002624eabd6c4fe1f47e5
parent36c7ec4d344e13223ba630bd66baaf492870ce68 (diff)
downloadscummvm-rg350-998744608f27802526b085ebe94215719ef9f28d.tar.gz
scummvm-rg350-998744608f27802526b085ebe94215719ef9f28d.tar.bz2
scummvm-rg350-998744608f27802526b085ebe94215719ef9f28d.zip
ILLUSIONS: More work on Duckman
- Implement dialogs - Change Camera class for Duckman
-rw-r--r--engines/illusions/actor.cpp100
-rw-r--r--engines/illusions/actor.h13
-rw-r--r--engines/illusions/backgroundresource.cpp21
-rw-r--r--engines/illusions/backgroundresource.h1
-rw-r--r--engines/illusions/camera.cpp138
-rw-r--r--engines/illusions/camera.h13
-rw-r--r--engines/illusions/fontresource.cpp6
-rw-r--r--engines/illusions/illusions.h2
-rw-r--r--engines/illusions/illusions_bbdou.cpp15
-rw-r--r--engines/illusions/illusions_bbdou.h2
-rw-r--r--engines/illusions/illusions_duckman.cpp190
-rw-r--r--engines/illusions/illusions_duckman.h24
-rw-r--r--engines/illusions/input.cpp1
-rw-r--r--engines/illusions/screen.cpp5
-rw-r--r--engines/illusions/screentext.cpp2
-rw-r--r--engines/illusions/scriptopcodes_duckman.cpp156
-rw-r--r--engines/illusions/scriptopcodes_duckman.h18
-rw-r--r--engines/illusions/scriptresource.cpp39
-rw-r--r--engines/illusions/scriptresource.h6
-rw-r--r--engines/illusions/sequenceopcodes.cpp12
-rw-r--r--engines/illusions/sequenceopcodes.h2
-rw-r--r--engines/illusions/talkthread_duckman.cpp3
22 files changed, 617 insertions, 152 deletions
diff --git a/engines/illusions/actor.cpp b/engines/illusions/actor.cpp
index f3677e4726..a67f5b92a9 100644
--- a/engines/illusions/actor.cpp
+++ b/engines/illusions/actor.cpp
@@ -616,7 +616,7 @@ void Control::sequenceActor() {
while (_actor->_seqCodeValue3 <= 0 && !sequenceFinished) {
bool breakInner = false;
while (!breakInner) {
- debug(1, "SEQ[%08X] op: %08X", _actor->_sequenceId, _actor->_seqCodeIp[0]);
+ debug(1, "[%08X] SEQ[%08X] op: %08X", _objectId, _actor->_sequenceId, _actor->_seqCodeIp[0]);
opCall._op = _actor->_seqCodeIp[0] & 0x7F;
opCall._opSize = _actor->_seqCodeIp[1];
opCall._code = _actor->_seqCodeIp + 2;
@@ -652,6 +652,10 @@ void Control::sequenceActor() {
}
+void Control::setActorIndex(int actorIndex) {
+ _actor->_actorIndex = actorIndex;
+}
+
void Control::setActorIndexTo1() {
_actor->_actorIndex = 1;
}
@@ -762,12 +766,23 @@ PointArray *Control::createPath(Common::Point destPt) {
void Control::updateActorMovement(uint32 deltaTime) {
// TODO This needs some cleanup
+ // TODO Move while loop to caller
static const int16 kAngleTbl[] = {60, 0, 120, 0, 60, 0, 120, 0};
+ bool again = false;
while (1) {
- bool again = false;
+ if (!again && _vm->testMainActorFastWalk(this)) {
+ again = true;
+ disappearActor();
+ _actor->_flags |= 0x8000;
+ _actor->_seqCodeIp = 0;
+ deltaTime = 2;
+ }
+
+ if (_vm->testMainActorCollision(this))
+ break;
/* TODO
if (controla->objectId == GameScript_getField0() && again == const0 && Input_pollButton__(0x10u)) {
@@ -912,7 +927,6 @@ void Control::refreshSequenceCode() {
}
void Control::startSequenceActorIntern(uint32 sequenceId, int value, byte *entryTblPtr, uint32 notifyThreadId) {
-
stopActor();
_actor->_flags &= ~0x80;
@@ -964,7 +978,8 @@ void Control::startSequenceActorIntern(uint32 sequenceId, int value, byte *entry
}
}
- sequenceActor();
+ if (_vm->getGameId() == kGameIdBBDOU)
+ sequenceActor();
}
@@ -1123,10 +1138,33 @@ void Controls::placeSubActor(uint32 objectId, int linkIndex, uint32 actorTypeId,
subActor->_linkIndex = linkIndex;
}
+void Controls::placeDialogItem(uint16 objectNum, uint32 actorTypeId, uint32 sequenceId, Common::Point placePt, int16 choiceJumpOffs) {
+ Control *control = newControl();
+ Actor *actor = newActor();
+ ActorType *actorType = _vm->_dict->findActorType(actorTypeId);
+ control->_flags = 0xC;
+ control->_priority = actorType->_priority;
+ control->_objectId = objectNum | 0x40000;
+ control->readPointsConfig(actorType->_pointsConfig);
+ control->_actorTypeId = actorTypeId;
+ control->_actor = actor;
+ actor->setControlRoutine(new Common::Functor2Mem<Control*, uint32, void, Controls>(this, &Controls::dialogItemControlRoutine));
+ actor->_choiceJumpOffs = choiceJumpOffs;
+ actor->createSurface(actorType->_surfInfo);
+ actor->_position = placePt;
+ actor->_position2 = placePt;
+ actor->_scale = actorType->_scale;
+ actor->_color = actorType->_color;
+ _controls.push_back(control);
+ control->appearActor();
+ control->startSequenceActor(sequenceId, 2, 0);
+ control->setActorIndex(1);
+}
+
void Controls::destroyControls() {
ItemsIterator it = _controls.begin();
while (it != _controls.end()) {
- destroyControl(*it);
+ destroyControlInternal(*it);
it = _controls.erase(it);
}
}
@@ -1135,7 +1173,7 @@ void Controls::destroyActiveControls() {
ItemsIterator it = _controls.begin();
while (it != _controls.end()) {
if ((*it)->_pauseCtr <= 0) {
- destroyControl(*it);
+ destroyControlInternal(*it);
it = _controls.erase(it);
} else
++it;
@@ -1146,13 +1184,24 @@ void Controls::destroyControlsByTag(uint32 tag) {
ItemsIterator it = _controls.begin();
while (it != _controls.end()) {
if ((*it)->_tag == tag) {
- destroyControl(*it);
+ destroyControlInternal(*it);
it = _controls.erase(it);
} else
++it;
}
}
+void Controls::destroyDialogItems() {
+ ItemsIterator it = _controls.begin();
+ while (it != _controls.end()) {
+ if (((*it)->_pauseCtr == 0) && ((*it)->_flags & 4)) {
+ destroyControlInternal(*it);
+ it = _controls.erase(it);
+ } else
+ ++it;
+ }
+}
+
void Controls::threadIsDead(uint32 threadId) {
for (ItemsIterator it = _controls.begin(); it != _controls.end(); ++it) {
Control *control = *it;
@@ -1238,6 +1287,28 @@ bool Controls::getOverlappedObject(Control *control, Common::Point pt, Control *
return foundControl != 0;
}
+bool Controls::getDialogItemAtPos(Control *control, Common::Point pt, Control **outOverlappedControl) {
+ Control *foundControl = 0;
+ for (ItemsIterator it = _controls.begin(); it != _controls.end(); ++it) {
+ Control *testControl = *it;
+ if (testControl != control && testControl->_pauseCtr == 0 &&
+ (testControl->_flags & 1) && (testControl->_flags & 4)) {
+ Common::Rect collisionRect;
+ testControl->getCollisionRect(collisionRect);
+ if (!collisionRect.isEmpty() && collisionRect.contains(pt) &&
+ (!foundControl || foundControl->_priority < testControl->_priority))
+ foundControl = testControl;
+ }
+ }
+ *outOverlappedControl = foundControl;
+ return foundControl != 0;
+}
+
+void Controls::destroyControl(Control *control) {
+ _controls.remove(control);
+ destroyControlInternal(control);
+}
+
bool Controls::findNamedPoint(uint32 namedPointId, Common::Point &pt) {
for (ItemsIterator it = _controls.begin(); it != _controls.end(); ++it) {
Control *control = *it;
@@ -1277,6 +1348,12 @@ void Controls::actorControlRoutine(Control *control, uint32 deltaTime) {
}
+void Controls::dialogItemControlRoutine(Control *control, uint32 deltaTime) {
+ Actor *actor = control->_actor;
+ if (actor->_pauseCtr <= 0)
+ actor->_seqCodeValue1 = 100 * deltaTime;
+}
+
Actor *Controls::newActor() {
return new Actor(_vm);
}
@@ -1296,14 +1373,14 @@ uint32 Controls::newTempObjectId() {
return nextTempObjectId2 | 0x40000;
}
-void Controls::destroyControl(Control *control) {
+void Controls::destroyControlInternal(Control *control) {
- if (control->_pauseCtr <= 0)
+ if (!(control->_flags & 4) && control->_pauseCtr <= 0)
_vm->_dict->setObjectControl(control->_objectId, 0);
- if (control->_objectId == 0x40004 && control->_pauseCtr <= 0)
+ if (!(control->_flags & 4) && control->_objectId == 0x40004 && control->_pauseCtr <= 0)
_vm->setCursorControl(0);
-
+
if (control->_actor) {
if (control->_actor->_pathNode && (control->_actor->_flags & 0x400))
delete control->_actor->_pathNode;
@@ -1316,6 +1393,7 @@ void Controls::destroyControl(Control *control) {
delete control->_actor;
control->_actor = 0;
}
+
delete control;
}
diff --git a/engines/illusions/actor.h b/engines/illusions/actor.h
index d1740ebb36..cce5a41e9f 100644
--- a/engines/illusions/actor.h
+++ b/engines/illusions/actor.h
@@ -146,7 +146,10 @@ public:
PointArray *_pathNode;
uint _pathPoints;
uint32 _walkCallerThreadId1;
-
+
+ RGB _color;
+ int16 _choiceJumpOffs;
+
};
class Control {
@@ -182,6 +185,7 @@ public:
void stopSequenceActor();
void startTalkActor(uint32 sequenceId, byte *entryTblPtr, uint32 threadId);
void sequenceActor();
+ void setActorIndex(int actorIndex);
void setActorIndexTo1();
void setActorIndexTo2();
void startSubSequence(int linkIndex, uint32 sequenceId);
@@ -220,17 +224,22 @@ public:
void placeSequenceLessActor(uint32 objectId, Common::Point placePt, WidthHeight dimensions, int16 priority);
void placeActorLessObject(uint32 objectId, Common::Point feetPt, Common::Point pt, int16 priority, uint flags);
void placeSubActor(uint32 objectId, int linkIndex, uint32 actorTypeId, uint32 sequenceId);
+ void placeDialogItem(uint16 objectNum, uint32 actorTypeId, uint32 sequenceId, Common::Point placePt, int16 choiceJumpOffs);
void destroyControls();
void destroyActiveControls();
void destroyControlsByTag(uint32 tag);
+ void destroyDialogItems();
void threadIsDead(uint32 threadId);
void pauseControls();
void unpauseControls();
void pauseControlsByTag(uint32 tag);
void unpauseControlsByTag(uint32 tag);
bool getOverlappedObject(Control *control, Common::Point pt, Control **outOverlappedControl, int minPriority);
+ bool getDialogItemAtPos(Control *control, Common::Point pt, Control **outOverlappedControl);
+ void destroyControl(Control *control);
bool findNamedPoint(uint32 namedPointId, Common::Point &pt);
void actorControlRoutine(Control *control, uint32 deltaTime);
+ void dialogItemControlRoutine(Control *control, uint32 deltaTime);
public:
typedef Common::List<Control*> Items;
typedef Items::iterator ItemsIterator;
@@ -241,7 +250,7 @@ public:
Actor *newActor();
Control *newControl();
uint32 newTempObjectId();
- void destroyControl(Control *control);
+ void destroyControlInternal(Control *control);
};
} // End of namespace Illusions
diff --git a/engines/illusions/backgroundresource.cpp b/engines/illusions/backgroundresource.cpp
index 2841971d89..301694370d 100644
--- a/engines/illusions/backgroundresource.cpp
+++ b/engines/illusions/backgroundresource.cpp
@@ -404,25 +404,6 @@ void BackgroundItem::unpause() {
}
}
-void BackgroundItem::refreshPan(WidthHeight &dimensions) {
- Common::Point screenOffs = _vm->_camera->getScreenOffset();
- int x = dimensions._width - 640;
- int y = dimensions._height - 480;
- for (uint i = 0; i < _bgRes->_bgInfosCount; ++i) {
- const BgInfo &bgInfo = _bgRes->_bgInfos[i];
- if (bgInfo._flags & 1) {
- _panPoints[i] = screenOffs;
- } else {
- Common::Point newOffs(0, 0);
- if (x > 0 && bgInfo._surfInfo._dimensions._width - 640 > 0)
- newOffs.x = screenOffs.x * (bgInfo._surfInfo._dimensions._width - 640) / x;
- if (y > 0 && bgInfo._surfInfo._dimensions._height - 480 > 0)
- newOffs.y = screenOffs.y * (bgInfo._surfInfo._dimensions._height - 480) / y;
- _panPoints[i] = newOffs;
- }
- }
-}
-
// BackgroundItems
BackgroundItems::BackgroundItems(IllusionsEngine *vm)
@@ -486,7 +467,7 @@ void BackgroundItems::refreshPan() {
BackgroundItem *backgroundItem = findActiveBackground();
if (backgroundItem) {
WidthHeight dimensions = getMasterBgDimensions();
- backgroundItem->refreshPan(dimensions);
+ _vm->_camera->refreshPan(backgroundItem, dimensions);
}
}
diff --git a/engines/illusions/backgroundresource.h b/engines/illusions/backgroundresource.h
index 75c867acbd..ca6a372660 100644
--- a/engines/illusions/backgroundresource.h
+++ b/engines/illusions/backgroundresource.h
@@ -159,7 +159,6 @@ public:
void drawTiles(Graphics::Surface *surface, TileMap &tileMap, byte *tilePixels);
void pause();
void unpause();
- void refreshPan(WidthHeight &dimensions);
public:
IllusionsEngine *_vm;
uint32 _tag;
diff --git a/engines/illusions/camera.cpp b/engines/illusions/camera.cpp
index b9d934284f..92783a198b 100644
--- a/engines/illusions/camera.cpp
+++ b/engines/illusions/camera.cpp
@@ -30,26 +30,27 @@ namespace Illusions {
Camera::Camera(IllusionsEngine *vm)
: _vm(vm) {
+ init();
_activeState._cameraMode = 6;
_activeState._paused = false;
_activeState._panStartTime = getCurrentTime();
_activeState._panSpeed = 1;
- _activeState._bounds._topLeft.x = 320;
- _activeState._bounds._topLeft.y = 240;
- _activeState._bounds._bottomRight.x = 320;
- _activeState._bounds._bottomRight.y = 240;
- _activeState._currPan.x = 320;
- _activeState._currPan.y = 240;
- _activeState._panXShl = 320 << 16;
- _activeState._panYShl = 240 << 16;
- _activeState._panTargetPoint.x = 320;
+ _activeState._bounds._topLeft.x = _screenMidX;
+ _activeState._bounds._topLeft.y = _screenMidY;
+ _activeState._bounds._bottomRight.x = _screenMidX;
+ _activeState._bounds._bottomRight.y = _screenMidY;
+ _activeState._currPan.x = _screenMidX;
+ _activeState._currPan.y = _screenMidY;
+ _activeState._panXShl = _screenMidX << 16;
+ _activeState._panYShl = _screenMidY << 16;
+ _activeState._panTargetPoint.x = _screenMidX;
_activeState._panTargetPoint.y = 240;
_activeState._panToPositionPtr = 0;
_activeState._panNotifyId = 0;
_activeState._trackingLimits.x = 0;
_activeState._trackingLimits.y = 0;
- _activeState._centerPt.x = 320;
- _activeState._centerPt.y = 240;
+ _activeState._centerPt.x = _screenMidX;
+ _activeState._centerPt.y = _screenMidY;
_activeState._pointFlags = 0;
}
@@ -62,10 +63,10 @@ void Camera::set(Common::Point &panPoint, WidthHeight &dimensions) {
_activeState._paused = false;
_activeState._panStartTime = getCurrentTime();
_activeState._panSpeed = 1;
- _activeState._bounds._topLeft.x = 320;
- _activeState._bounds._topLeft.y = 240;
- _activeState._bounds._bottomRight.x = MAX(0, dimensions._width - 640) + 320;
- _activeState._bounds._bottomRight.y = MAX(0, dimensions._height - 480) + 240;
+ _activeState._bounds._topLeft.x = _screenMidX;
+ _activeState._bounds._topLeft.y = _screenMidY;
+ _activeState._bounds._bottomRight.x = MAX(0, dimensions._width - _screenWidth) + _screenMidX;
+ _activeState._bounds._bottomRight.y = MAX(0, dimensions._height - _screenHeight) + _screenMidY;
_activeState._panTargetPoint = panPoint;
clipPanTargetPoint();
_activeState._currPan = _activeState._panTargetPoint;
@@ -78,21 +79,26 @@ void Camera::set(Common::Point &panPoint, WidthHeight &dimensions) {
_activeState._trackingLimits.x = 0;
_activeState._trackingLimits.y = 0;
_activeState._pointFlags = 0;
- _activeState._centerPt.x = 320;
- _activeState._centerPt.y = 240;
+ _activeState._centerPt.x = _screenMidX;
+ _activeState._centerPt.y = _screenMidY;
}
void Camera::panCenterObject(uint32 objectId, int16 panSpeed) {
Common::Point *actorPosition = _vm->getObjectActorPositionPtr(objectId);
- _activeState._cameraMode = 1;
+ if (_vm->getGameId() == kGameIdDuckman && objectId == 0x40004) {
+ _activeState._cameraMode = 2;
+ _activeState._trackingLimits.x = 156;
+ _activeState._trackingLimits.y = 96;
+ } else if (_vm->getGameId() == kGameIdBBDOU) {
+ _activeState._cameraMode = 1;
+ _activeState._trackingLimits = _centerObjectTrackingLimits;
+ }
_activeState._panSpeed = panSpeed;
- _activeState._trackingLimits.x = 8;
- _activeState._trackingLimits.y = 8;
_activeState._pointFlags = 0;
- _activeState._panToPositionPtr = actorPosition;
_activeState._panObjectId = objectId;
- _activeState._panTargetPoint = *actorPosition;
_activeState._panNotifyId = 0;
+ _activeState._panToPositionPtr = actorPosition;
+ _activeState._panTargetPoint = *actorPosition;
clipPanTargetPoint();
_activeState._panStartTime = getCurrentTime();
recalcPan(_activeState._panStartTime);
@@ -102,10 +108,9 @@ void Camera::panTrackObject(uint32 objectId) {
Common::Point *actorPosition = _vm->getObjectActorPositionPtr(objectId);
_activeState._cameraMode = 3;
_activeState._panObjectId = objectId;
- _activeState._trackingLimits.x = 160;
- _activeState._trackingLimits.y = 120;
+ _activeState._trackingLimits = _trackObjectTrackingLimits;
+ _activeState._panSpeed = _trackObjectTrackingLimitsPanSpeed;
_activeState._pointFlags = 0;
- _activeState._panSpeed = 710;
_activeState._panToPositionPtr = actorPosition;
_activeState._panNotifyId = 0;
_activeState._panTargetPoint = *actorPosition;
@@ -286,10 +291,10 @@ void Camera::setBounds(Common::Point minPt, Common::Point maxPt) {
void Camera::setBoundsToDimensions(WidthHeight &dimensions) {
// NOTE For the caller dimensions = artdispGetMasterBGDimensions();
- _activeState._bounds._topLeft.x = 320;
- _activeState._bounds._topLeft.y = 240;
- _activeState._bounds._bottomRight.x = MAX(0, dimensions._width - 640) + 320;
- _activeState._bounds._bottomRight.y = MAX(0, dimensions._height - 480) + 240;
+ _activeState._bounds._topLeft.x = _screenMidX;
+ _activeState._bounds._topLeft.y = _screenMidY;
+ _activeState._bounds._bottomRight.x = MAX(0, dimensions._width - _screenWidth) + _screenMidX;
+ _activeState._bounds._bottomRight.y = MAX(0, dimensions._height - _screenHeight) + _screenMidY;
clipPanTargetPoint();
}
@@ -299,8 +304,8 @@ Common::Point Camera::getCurrentPan() {
Common::Point Camera::getScreenOffset() {
Common::Point screenOffs = getCurrentPan();
- screenOffs.x -= 320;
- screenOffs.y -= 240;
+ screenOffs.x -= _screenMidX;
+ screenOffs.y -= _screenMidY;
return screenOffs;
}
@@ -331,10 +336,29 @@ void Camera::getActiveState(CameraState &state) {
state = _activeState;
}
+void Camera::refreshPan(BackgroundItem *backgroundItem, WidthHeight &dimensions) {
+ Common::Point screenOffs = getScreenOffset();
+ int x = dimensions._width - _screenWidth;
+ int y = dimensions._height - _screenHeight;
+ for (uint i = 0; i < backgroundItem->_bgRes->_bgInfosCount; ++i) {
+ const BgInfo &bgInfo = backgroundItem->_bgRes->_bgInfos[i];
+ if (bgInfo._flags & 1) {
+ backgroundItem->_panPoints[i] = screenOffs;
+ } else {
+ Common::Point newOffs(0, 0);
+ if (x > 0 && bgInfo._surfInfo._dimensions._width - _screenWidth > 0)
+ newOffs.x = screenOffs.x * (bgInfo._surfInfo._dimensions._width - _screenWidth) / x;
+ if (y > 0 && bgInfo._surfInfo._dimensions._height - _screenHeight > 0)
+ newOffs.y = screenOffs.y * (bgInfo._surfInfo._dimensions._height - _screenHeight) / y;
+ backgroundItem->_panPoints[i] = newOffs;
+ }
+ }
+}
+
void Camera::updateMode1(uint32 currTime) {
Common::Point ptOffs = getPtOffset(*_activeState._panToPositionPtr);
- int deltaX = ptOffs.x - _activeState._currPan.x + 320 - _activeState._centerPt.x;
- int deltaY = ptOffs.y - _activeState._currPan.y + 240 - _activeState._centerPt.y;
+ int deltaX = ptOffs.x - _activeState._currPan.x + _screenMidX - _activeState._centerPt.x;
+ int deltaY = ptOffs.y - _activeState._currPan.y + _screenMidY - _activeState._centerPt.y;
int deltaXAbs = ABS(deltaX);
int deltaYAbs = ABS(deltaY);
@@ -359,14 +383,15 @@ void Camera::updateMode1(uint32 currTime) {
}
void Camera::updateMode2(uint32 currTime) {
+ // TOOD CHECKME Bigger differences in Duckman
Common::Point panToPosition = *_activeState._panToPositionPtr;
uint pointFlags = 0;
WRect rect;
- rect._topLeft.x = 320 - _activeState._trackingLimits.x;
- rect._topLeft.y = 240 - _activeState._trackingLimits.y;
- rect._bottomRight.x = 320 + _activeState._trackingLimits.x;
- rect._bottomRight.y = 240 + _activeState._trackingLimits.y;
+ rect._topLeft.x = _screenMidX - _activeState._trackingLimits.x;
+ rect._topLeft.y = _screenMidY - _activeState._trackingLimits.y;
+ rect._bottomRight.x = _screenMidX + _activeState._trackingLimits.x;
+ rect._bottomRight.y = _screenMidY + _activeState._trackingLimits.y;
if (calcPointFlags(panToPosition, rect, pointFlags)) {
if (pointFlags != _activeState._pointFlags) {
@@ -441,8 +466,8 @@ bool Camera::isPanFinished() {
}
Common::Point Camera::getPtOffset(Common::Point pt) {
- pt.x = pt.x - _activeState._centerPt.x + 320;
- pt.y = pt.y - _activeState._centerPt.y + 240;
+ pt.x = pt.x - _activeState._centerPt.x + _screenMidX;
+ pt.y = pt.y - _activeState._centerPt.y + _screenMidY;
return pt;
}
@@ -497,4 +522,39 @@ void Camera::clipPanTargetPoint() {
_activeState._bounds._topLeft.y, _activeState._bounds._bottomRight.y);
}
+void Camera::init() {
+ switch (_vm->getGameId()) {
+ case kGameIdDuckman:
+ initDuckman();
+ break;
+ case kGameIdBBDOU:
+ initBBDOU();
+ break;
+ }
+}
+
+void Camera::initDuckman() {
+ _centerObjectTrackingLimits.x = 4;
+ _centerObjectTrackingLimits.y = 4;
+ _screenWidth = 320;
+ _screenHeight = 200;
+ _screenMidX = 160;
+ _screenMidY = 100;
+ _trackObjectTrackingLimits.x = 80;
+ _trackObjectTrackingLimits.y = 50;
+ _trackObjectTrackingLimitsPanSpeed = 353;
+}
+
+void Camera::initBBDOU() {
+ _centerObjectTrackingLimits.x = 8;
+ _centerObjectTrackingLimits.y = 8;
+ _screenWidth = 640;
+ _screenHeight = 480;
+ _screenMidX = 320;
+ _screenMidY = 240;
+ _trackObjectTrackingLimits.x = 160;
+ _trackObjectTrackingLimits.y = 120;
+ _trackObjectTrackingLimitsPanSpeed = 710;
+}
+
} // End of namespace Illusions
diff --git a/engines/illusions/camera.h b/engines/illusions/camera.h
index 9fa12c4ebc..85d308df5f 100644
--- a/engines/illusions/camera.h
+++ b/engines/illusions/camera.h
@@ -29,6 +29,8 @@
namespace Illusions {
+class BackgroundItem;
+
struct CameraState {
int _cameraMode;
//field_2 dw
@@ -85,10 +87,18 @@ public:
bool isAtPanLimit(int limitNum);
void setActiveState(CameraState &state);
void getActiveState(CameraState &state);
+ void refreshPan(BackgroundItem *backgroundItem, WidthHeight &dimensions);
protected:
IllusionsEngine *_vm;
CameraState _activeState;
Common::FixedStack<CameraModeStackItem, 8> _stack;
+
+ int16 _screenWidth, _screenHeight;
+ int16 _screenMidX, _screenMidY;
+ Common::Point _centerObjectTrackingLimits;
+ Common::Point _trackObjectTrackingLimits;
+ int16 _trackObjectTrackingLimitsPanSpeed;
+
void updateMode1(uint32 currTime);
void updateMode2(uint32 currTime);
void updateMode3(uint32 currTime);
@@ -98,6 +108,9 @@ protected:
void recalcPan(uint32 currTime);
bool calcPointFlags(Common::Point &pt, WRect &rect, uint &outFlags);
void clipPanTargetPoint();
+ void init();
+ void initDuckman();
+ void initBBDOU();
};
} // End of namespace Illusions
diff --git a/engines/illusions/fontresource.cpp b/engines/illusions/fontresource.cpp
index adfb135da5..9f7a075895 100644
--- a/engines/illusions/fontresource.cpp
+++ b/engines/illusions/fontresource.cpp
@@ -62,7 +62,7 @@ void CharInfo::load(byte *dataStart, Common::SeekableReadStream &stream) {
_field_2 = stream.readUint16LE();
uint32 pixelsOffs = stream.readUint32LE();
_pixels = dataStart + pixelsOffs;
- debug("CharInfo::load() _width: %d; _field_2: %d; pixelsOffs: %08X",
+ debug(2, "CharInfo::load() _width: %d; _field_2: %d; pixelsOffs: %08X",
_width, _field_2, pixelsOffs);
}
@@ -78,7 +78,7 @@ void CharRange::load(byte *dataStart, Common::SeekableReadStream &stream) {
stream.seek(charInfosOffs + i * 8);
_charInfos[i].load(dataStart, stream);
}
- debug("CharRange::load() _firstChar: %d; _lastChar: %d; charInfosOffs: %08X",
+ debug(2, "CharRange::load() _firstChar: %d; _lastChar: %d; charInfosOffs: %08X",
_firstChar, _lastChar, charInfosOffs);
}
@@ -116,7 +116,7 @@ void FontResource::load(Resource *resource) {
stream.seek(charRangesOffs + i * 8);
_charRanges[i].load(data, stream);
}
- debug("FontResource::load() _charHeight: %d; _field_6: %d; _colorIndex: %d; _lineIncr: %d; _widthC: %d; _charRangesCount: %d",
+ debug(2, "FontResource::load() _charHeight: %d; _field_6: %d; _colorIndex: %d; _lineIncr: %d; _widthC: %d; _charRangesCount: %d",
_charHeight, _field_6, _colorIndex, _lineIncr, _widthC, _charRangesCount);
}
diff --git a/engines/illusions/illusions.h b/engines/illusions/illusions.h
index 3bfa8765cd..63fb3f6d3e 100644
--- a/engines/illusions/illusions.h
+++ b/engines/illusions/illusions.h
@@ -158,6 +158,8 @@ public:
virtual void loadSpecialCode(uint32 resId) = 0;
virtual void unloadSpecialCode(uint32 resId) = 0;
virtual void notifyThreadId(uint32 &threadId) = 0;
+ virtual bool testMainActorFastWalk(Control *control) = 0;
+ virtual bool testMainActorCollision(Control *control) = 0;
virtual Control *getObjectControl(uint32 objectId) = 0;
virtual Common::Point getNamedPointPosition(uint32 namedPointId) = 0;
virtual uint32 getPriorityFromBase(int16 priority) = 0;
diff --git a/engines/illusions/illusions_bbdou.cpp b/engines/illusions/illusions_bbdou.cpp
index d5e9713817..931db5c2ee 100644
--- a/engines/illusions/illusions_bbdou.cpp
+++ b/engines/illusions/illusions_bbdou.cpp
@@ -32,6 +32,7 @@
#include "illusions/input.h"
#include "illusions/resourcesystem.h"
#include "illusions/screen.h"
+#include "illusions/screentext.h"
#include "illusions/scriptopcodes_bbdou.h"
#include "illusions/scriptresource.h"
#include "illusions/scriptman.h"
@@ -201,6 +202,7 @@ Common::Error IllusionsEngine_BBDOU::run() {
_resSys->addResourceLoader(0x00170000, new SpecialCodeLoader(this));
_screen = new Screen(this, 640, 480, 16);
+ _screenText = new ScreenText(this);
_input = new Input();
_scriptMan = new ScriptMan(this);
_actorItems = new ActorItems(this);
@@ -221,7 +223,6 @@ Common::Error IllusionsEngine_BBDOU::run() {
_lastUpdateTime = 0;
_pauseCtr = 0;
- _doScriptThreadInit = false;
_field8 = 1;
_fieldA = 0;
_fieldE = 240;
@@ -231,6 +232,8 @@ Common::Error IllusionsEngine_BBDOU::run() {
setDefaultTextCoords();
_resSys->loadResource(0x000D0001, 0, 0);
+
+ _doScriptThreadInit = false;
startScriptThread(0x00020004, 0, 0, 0, 0);
_doScriptThreadInit = true;
@@ -258,6 +261,7 @@ Common::Error IllusionsEngine_BBDOU::run() {
delete _actorItems;
delete _scriptMan;
delete _input;
+ delete _screenText;
delete _screen;
delete _resSys;
delete _dict;
@@ -329,6 +333,15 @@ void IllusionsEngine_BBDOU::notifyThreadId(uint32 &threadId) {
}
}
+bool IllusionsEngine_BBDOU::testMainActorFastWalk(Control *control) {
+ return false;
+}
+
+bool IllusionsEngine_BBDOU::testMainActorCollision(Control *control) {
+ // Not used in BBDOU
+ return false;
+}
+
Control *IllusionsEngine_BBDOU::getObjectControl(uint32 objectId) {
return _dict->getObjectControl(objectId);
}
diff --git a/engines/illusions/illusions_bbdou.h b/engines/illusions/illusions_bbdou.h
index 05aea8a863..addd06cac4 100644
--- a/engines/illusions/illusions_bbdou.h
+++ b/engines/illusions/illusions_bbdou.h
@@ -113,6 +113,8 @@ public:
void loadSpecialCode(uint32 resId);
void unloadSpecialCode(uint32 resId);
void notifyThreadId(uint32 &threadId);
+ bool testMainActorFastWalk(Control *control);
+ bool testMainActorCollision(Control *control);
Control *getObjectControl(uint32 objectId);
Common::Point getNamedPointPosition(uint32 namedPointId);
uint32 getPriorityFromBase(int16 priority);
diff --git a/engines/illusions/illusions_duckman.cpp b/engines/illusions/illusions_duckman.cpp
index 0cd27e8a29..252483f4ad 100644
--- a/engines/illusions/illusions_duckman.cpp
+++ b/engines/illusions/illusions_duckman.cpp
@@ -121,10 +121,10 @@ Common::Error IllusionsEngine_Duckman::run() {
_globalSceneId = 0x00010003;
- initSpecialCode();
- setDefaultTextCoords();
+ initSpecialCode();
+ setDefaultTextCoords();
initCursor();
- initActiveScenes();
+ initActiveScenes();
_resSys->loadResource(0x120001, 0x00010001, 0);
_resSys->loadResource(0x120002, 0x00010001, 0);
@@ -203,6 +203,17 @@ void IllusionsEngine_Duckman::notifyThreadId(uint32 &threadId) {
}
}
+bool IllusionsEngine_Duckman::testMainActorFastWalk(Control *control) {
+ return
+ control->_objectId == _scriptResource->getMainActorObjectId() &&
+ _input->pollButton(0x20);
+}
+
+bool IllusionsEngine_Duckman::testMainActorCollision(Control *control) {
+ // TODO
+ return false;
+}
+
Control *IllusionsEngine_Duckman::getObjectControl(uint32 objectId) {
return _dict->getObjectControl(objectId);
}
@@ -213,11 +224,11 @@ Common::Point IllusionsEngine_Duckman::getNamedPointPosition(uint32 namedPointId
if (_backgroundItems->findActiveBackgroundNamedPoint(namedPointId, pt)) {
return pt;
} else if (namedPointId - 0x00070001 > 209) {
- if (_controls->findNamedPoint(namedPointId, pt)) {
- return pt;
- } else {
- return currPan;
- }
+ if (_controls->findNamedPoint(namedPointId, pt)) {
+ return pt;
+ } else {
+ return currPan;
+ }
} else {
// TODO
//debug("getNamedPointPosition(%08X) UNKNOWN", namedPointId);
@@ -271,8 +282,8 @@ void IllusionsEngine_Duckman::placeCursorControl(Control *control, uint32 sequen
_cursor._field14[8] = false;
_cursor._op113_choiceOfsPtr = 0;
_cursor._notifyThreadId30 = 0;
- _cursor._op113_objectNumCtr = 0;
- _cursor._overlappedObjectNum = 0;
+ _cursor._dialogItemsCount = 0;
+ _cursor._overlappedObjectId = 0;
_cursor._field40 = 0;
control->_flags |= 8;
setCursorActorIndex(_cursor._actorIndex, 1, 0);
@@ -320,8 +331,8 @@ void IllusionsEngine_Duckman::initCursor() {
_cursor._field14[12] = false;
_cursor._op113_choiceOfsPtr = 0;
_cursor._notifyThreadId30 = 0;
- _cursor._op113_objectNumCtr = 0;
- _cursor._overlappedObjectNum = 0;
+ _cursor._dialogItemsCount = 0;
+ _cursor._overlappedObjectId = 0;
_cursor._field40 = 0;
}
@@ -342,7 +353,6 @@ void IllusionsEngine_Duckman::setCursorActorIndex(int actorIndex, int a, int b)
{{21, 22}, { 0, 0}}
};
_cursor._control->_actor->_actorIndex = kCursorMap[actorIndex - 1][b][a - 1];
- debug("_cursor._control->_actor->_actorIndex: %d", _cursor._control->_actor->_actorIndex);
}
void IllusionsEngine_Duckman::enableCursorVerb(int verbNum) {
@@ -381,6 +391,31 @@ void IllusionsEngine_Duckman::setCursorHandMode(int mode) {
setCursorActorIndex(_cursor._actorIndex, 1, 0);
}
+void IllusionsEngine_Duckman::startCursorHoldingObject(uint32 objectId, uint32 sequenceId) {
+ _cursor._objectId = objectId;
+ _cursor._sequenceId2 = sequenceId;
+ _cursor._actorIndex = 7;
+ _cursor._savedActorIndex = 7;
+ _cursor._field14[_cursor._actorIndex - 1] = true;
+ _cursor._control->startSequenceActor(sequenceId, 2, 0);
+ setCursorActorIndex(_cursor._actorIndex, 1, 0);
+ _cursor._currOverlappedControl = 0;
+}
+
+void IllusionsEngine_Duckman::stopCursorHoldingObject() {
+ _cursor._field14[6] = false;
+ _cursor._objectId = 0;
+ _cursor._sequenceId2 = 0;
+ if (_cursor._actorIndex == 7) {
+ _cursor._actorIndex = getCursorActorIndex();
+ _cursor._control->startSequenceActor(_cursor._sequenceId1, 2, 0);
+ if (_cursor._currOverlappedControl)
+ setCursorActorIndex(_cursor._actorIndex, 2, 0);
+ else
+ setCursorActorIndex(_cursor._actorIndex, 1, 0);
+ }
+}
+
void IllusionsEngine_Duckman::cursorControlRoutine(Control *control, uint32 deltaTime) {
control->_actor->_seqCodeValue1 = 100 * deltaTime;
if (control->_actor->_flags & 1) {
@@ -389,7 +424,7 @@ void IllusionsEngine_Duckman::cursorControlRoutine(Control *control, uint32 delt
updateGameState2();
break;
case 3:
- // TODO updateGameState3(cursorControl);
+ updateDialogState();
break;
case 4:
// TODO ShellMgr_update(cursorControl);
@@ -689,7 +724,6 @@ void IllusionsEngine_Duckman::updateGameState2() {
} else if (_input->pollButton(2)) {
if (_cursor._actorIndex != 3 && _cursor._actorIndex != 10 && _cursor._actorIndex != 11 && _cursor._actorIndex != 12 && _cursor._actorIndex != 13) {
int newActorIndex = getCursorActorIndex();
- debug("newActorIndex = %d", newActorIndex);
if (newActorIndex != _cursor._actorIndex) {
_cursor._actorIndex = newActorIndex;
if (_cursor._currOverlappedControl)
@@ -701,9 +735,9 @@ void IllusionsEngine_Duckman::updateGameState2() {
}
} else if (_input->pollButton(8)) {
if (_cursor._field14[0] == 1) {
- runTriggerCause(1, 0, _scriptResource->getField6C());
+ runTriggerCause(1, 0, _scriptResource->getMainActorObjectId());
} else if (_cursor._field14[1] == 1) {
- runTriggerCause(2, 0, _scriptResource->getField6C());
+ runTriggerCause(2, 0, _scriptResource->getMainActorObjectId());
}
}
@@ -737,16 +771,16 @@ uint32 IllusionsEngine_Duckman::runTriggerCause(uint32 verbId, uint32 objectId2,
bool flag = false;
if (_scriptResource->_properties.get(0x000E003C)) {
- if (verbId == 7 && objectId == 0x40003 ) {
+ if (verbId == 7 && objectId == 0x40003) {
playSoundEffect(7);
flag = true;
- } else if (objectId == 0x40003 ) {
+ } else if (objectId == 0x40003) {
playSoundEffect(14);
flag = true;
- } else if (verbId == 3 ) {
+ } else if (verbId == 3) {
playSoundEffect(16);
flag = true;
- } else if (verbId == 2 ) {
+ } else if (verbId == 2) {
flag = true;
}
}
@@ -754,9 +788,9 @@ uint32 IllusionsEngine_Duckman::runTriggerCause(uint32 verbId, uint32 objectId2,
if (!flag) {
if (objectId == 0x40003) {
playSoundEffect(14);
- } else if ((verbId == 1 || verbId == 2) && _scriptResource->getField6C() == objectId) {
+ } else if ((verbId == 1 || verbId == 2) && _scriptResource->getMainActorObjectId() == objectId) {
playSoundEffect(15);
- } else if (verbId == 7 && _scriptResource->getField6C() == objectId) {
+ } else if (verbId == 7 && _scriptResource->getMainActorObjectId() == objectId) {
playSoundEffect(15);
} else if (verbId == 1) {
playSoundEffect(1);
@@ -780,6 +814,116 @@ uint32 IllusionsEngine_Duckman::runTriggerCause(uint32 verbId, uint32 objectId2,
return tempThreadId;
}
+void IllusionsEngine_Duckman::addDialogItem(int16 choiceJumpOffs, uint32 sequenceId) {
+ DialogItem dialogItem;
+ dialogItem._choiceJumpOffs = choiceJumpOffs;
+ dialogItem._sequenceId = sequenceId;
+ _dialogItems.push_back(dialogItem);
+}
+
+void IllusionsEngine_Duckman::startDialog(int16 *choiceOfsPtr, uint32 actorTypeId, uint32 callerThreadId) {
+ static const uint32 kDialogSequenceIds[] = {
+ 0,
+ 0x6049C, 0x6049C, 0x6047A, 0x6049D,
+ 0x60479, 0x6049E, 0x6049F, 0x60468
+ };
+ if (_dialogItems.size() == 1) {
+ *choiceOfsPtr = _dialogItems[0]._choiceJumpOffs;
+ notifyThreadId(callerThreadId);
+ } else {
+ if (!_cursor._control) {
+ Common::Point pos = getNamedPointPosition(0x70001);
+ _controls->placeActor(0x50001, pos, 0x60001, 0x40004, 0);
+ _cursor._control = _dict->getObjectControl(0x40004);
+ }
+ _cursor._control->appearActor();
+ setCursorActorIndex(6, 1, 0);
+
+ _cursor._gameState = 3;
+ _cursor._notifyThreadId30 = callerThreadId;
+ _cursor._dialogItemsCount = 0;
+ _cursor._overlappedObjectId = 0;
+ _cursor._op113_choiceOfsPtr = choiceOfsPtr;
+ _cursor._currOverlappedControl = 0;
+
+ /* TODO?
+ if (!_input->getCursorMouseMode())
+ _input->setMousePos((Point)0xBC0014);
+ */
+
+ _cursor._dialogItemsCount = _dialogItems.size();
+ Common::Point placePt(20, 188);
+
+ for (uint i = 1; i <= _dialogItems.size(); ++i) {
+ DialogItem &dialogItem = _dialogItems[_dialogItems.size() - i];
+ _controls->placeDialogItem(i + 1, actorTypeId, dialogItem._sequenceId, placePt, dialogItem._choiceJumpOffs);
+ placePt.x += 40;
+ }
+
+ Common::Point placePt2 = getNamedPointPosition(0x700C3);
+ _controls->placeActor(0x5006E, placePt2, kDialogSequenceIds[_dialogItems.size()], 0x40148, 0);
+ Control *control = _dict->getObjectControl(0x40148);
+ control->_flags |= 8;
+ playSoundEffect(8);
+ }
+
+ _dialogItems.clear();
+
+}
+
+void IllusionsEngine_Duckman::updateDialogState() {
+ Common::Point mousePos = _input->getCursorPosition();
+ // TODO Handle keyboard input
+ _cursor._control->_actor->_position = mousePos;
+ mousePos = convertMousePos(mousePos);
+
+ Control *currOverlappedControl = _cursor._currOverlappedControl;
+ Control *newOverlappedControl;
+
+ if (_controls->getDialogItemAtPos(_cursor._control, mousePos, &newOverlappedControl)) {
+ if (currOverlappedControl != newOverlappedControl) {
+ newOverlappedControl->setActorIndex(2);
+ newOverlappedControl->startSequenceActor(newOverlappedControl->_actor->_sequenceId, 2, 0);
+ if (currOverlappedControl) {
+ currOverlappedControl->setActorIndex(1);
+ currOverlappedControl->startSequenceActor(currOverlappedControl->_actor->_sequenceId, 2, 0);
+ }
+ playSoundEffect(10);
+ startCursorSequence();
+ setCursorActorIndex(6, 2, 0);
+ _cursor._currOverlappedControl = newOverlappedControl;
+ _cursor._overlappedObjectId = newOverlappedControl->_objectId;
+ }
+ } else if (currOverlappedControl) {
+ currOverlappedControl->setActorIndex(1);
+ currOverlappedControl->startSequenceActor(currOverlappedControl->_actor->_sequenceId, 2, 0);
+ playSoundEffect(10);
+ _cursor._currOverlappedControl = 0;
+ _cursor._overlappedObjectId = 0;
+ startCursorSequence();
+ setCursorActorIndex(6, 1, 0);
+ }
+
+ if (_input->pollButton(1)) {
+ if (_cursor._currOverlappedControl) {
+ playSoundEffect(9);
+ *_cursor._op113_choiceOfsPtr = _cursor._currOverlappedControl->_actor->_choiceJumpOffs;
+ _controls->destroyDialogItems();
+ Control *control = _dict->getObjectControl(0x40148);
+ _controls->destroyControl(control);
+ debug("_cursor._notifyThreadId30: %08X", _cursor._notifyThreadId30);
+ notifyThreadId(_cursor._notifyThreadId30);
+ _cursor._notifyThreadId30 = 0;
+ _cursor._gameState = 2;
+ _cursor._dialogItemsCount = 0;
+ _cursor._overlappedObjectId = 0;
+ _cursor._op113_choiceOfsPtr = 0;
+ _cursor._control->disappearActor();
+ }
+ }
+
+}
+
// Special code
typedef Common::Functor1Mem<OpCall&, void, IllusionsEngine_Duckman> SpecialCodeFunctionDM;
diff --git a/engines/illusions/illusions_duckman.h b/engines/illusions/illusions_duckman.h
index 375407fe09..7213e21fda 100644
--- a/engines/illusions/illusions_duckman.h
+++ b/engines/illusions/illusions_duckman.h
@@ -45,12 +45,17 @@ struct Cursor_Duckman {
uint32 _sequenceId2;
uint32 _notifyThreadId30;
int16 *_op113_choiceOfsPtr;
- int _op113_objectNumCtr;
- uint _overlappedObjectNum;
+ int _dialogItemsCount;
+ uint32 _overlappedObjectId;
uint32 _field3C;
uint32 _field40;
};
+struct DialogItem {
+ int16 _choiceJumpOffs;
+ uint32 _sequenceId;
+};
+
struct OpCall;
typedef Common::Functor1<OpCall&, void> SpecialCodeFunction;
@@ -81,14 +86,17 @@ public:
uint32 _activeScenes[6];
Cursor_Duckman _cursor;
+ Common::Array<DialogItem> _dialogItems;
- SpecialCodeMap _specialCodeMap;
+ SpecialCodeMap _specialCodeMap;
void setDefaultTextCoords();
void loadSpecialCode(uint32 resId);
void unloadSpecialCode(uint32 resId);
void notifyThreadId(uint32 &threadId);
+ bool testMainActorFastWalk(Control *control);
+ bool testMainActorCollision(Control *control);
Control *getObjectControl(uint32 objectId);
Common::Point getNamedPointPosition(uint32 namedPointId);
uint32 getPriorityFromBase(int16 priority);
@@ -106,6 +114,8 @@ public:
void enableCursorVerb(int verbNum);
void disableCursorVerb(int verbNum);
void setCursorHandMode(int mode);
+ void startCursorHoldingObject(uint32 objectId, uint32 sequenceId);
+ void stopCursorHoldingObject();
void cursorControlRoutine(Control *control, uint32 deltaTime);
void startScriptThreadSimple(uint32 threadId, uint32 callingThreadId);
@@ -122,9 +132,9 @@ public:
uint32 newTimerThread(uint32 duration, uint32 callingThreadId, bool isAbortable);
uint32 newTempThreadId();
- void initActiveScenes();
+ void initActiveScenes();
void pushActiveScene(uint32 sceneId);
- void popActiveScene();
+ void popActiveScene();
bool loadScene(uint32 sceneId);
bool enterScene(uint32 sceneId, uint32 threadId);
void exitScene();
@@ -148,6 +158,10 @@ public:
bool getTriggerCause(uint32 verbId, uint32 objectId2, uint32 objectId, uint32 &outThreadId);
uint32 runTriggerCause(uint32 verbId, uint32 objectId2, uint32 objectId);
+ void addDialogItem(int16 choiceJumpOffs, uint32 sequenceId);
+ void startDialog(int16 *choiceOfsPtr, uint32 actorTypeId, uint32 callerThreadId);
+ void updateDialogState();
+
// Special code
void initSpecialCode();
void runSpecialCode(uint32 specialCodeId, OpCall &opCall);
diff --git a/engines/illusions/input.cpp b/engines/illusions/input.cpp
index 1a174b1be2..53b3291a59 100644
--- a/engines/illusions/input.cpp
+++ b/engines/illusions/input.cpp
@@ -119,6 +119,7 @@ Common::Point Input::getCursorDelta() {
void Input::initKeys() {
// NOTE Skipped debugging keys of the original engine, not sure if used
+ // TODO Move this to the engine class and tidy up methods (one for mouse buttons, one for keys)
addKeyMapping(Common::KEYCODE_INVALID, MOUSE_BUTTON0, 0x01);
addKeyMapping(Common::KEYCODE_RETURN, MOUSE_NONE, 0x01);
addKeyMapping(Common::KEYCODE_INVALID, MOUSE_BUTTON1, 0x02);
diff --git a/engines/illusions/screen.cpp b/engines/illusions/screen.cpp
index f4b6982ab8..57989e738f 100644
--- a/engines/illusions/screen.cpp
+++ b/engines/illusions/screen.cpp
@@ -93,7 +93,7 @@ bool SpriteDrawQueue::draw(SpriteDrawQueueItem *item) {
return true;
_screen->drawSurface(dstRect, item->_surface, srcRect, item->_scale, item->_flags);
-
+
if (item->_drawFlags)
*item->_drawFlags &= ~4;
@@ -441,14 +441,11 @@ void Screen::decompressSprite8(SpriteDecompressQueueItem *item) {
}
void Screen::drawSurface8(Common::Rect &dstRect, Graphics::Surface *surface, Common::Rect &srcRect, int16 scale, uint32 flags) {
- drawSurface81(dstRect.left, dstRect.top, surface, srcRect);
- /*
if (scale == 100) {
drawSurface81(dstRect.left, dstRect.top, surface, srcRect);
} else {
drawSurface82(dstRect, surface, srcRect);
}
- */
}
void Screen::drawSurface81(int16 destX, int16 destY, Graphics::Surface *surface, Common::Rect &srcRect) {
diff --git a/engines/illusions/screentext.cpp b/engines/illusions/screentext.cpp
index 684ab5a426..60fc9011d3 100644
--- a/engines/illusions/screentext.cpp
+++ b/engines/illusions/screentext.cpp
@@ -110,7 +110,7 @@ bool ScreenText::insertText(uint16 *text, uint32 fontId, WidthHeight dimensions,
bool done = refreshScreenText(font, screenText->_info._dimensions, screenText->_info._offsPt,
text, screenText->_info._flags, screenText->_info._color2, screenText->_info._color1,
outTextPtr);
- _vm->_screen->setPaletteEntry(font->getColorIndex(), screenText->_info._colorR, screenText->_info._colorG, screenText->_info._colorB);
+ //_vm->_screen->setPaletteEntry(font->getColorIndex(), screenText->_info._colorR, screenText->_info._colorG, screenText->_info._colorB);
uint16 *textPart = screenText->_text;
while (text != outTextPtr)
diff --git a/engines/illusions/scriptopcodes_duckman.cpp b/engines/illusions/scriptopcodes_duckman.cpp
index f7e96765be..63cdf65573 100644
--- a/engines/illusions/scriptopcodes_duckman.cpp
+++ b/engines/illusions/scriptopcodes_duckman.cpp
@@ -71,7 +71,9 @@ void ScriptOpcodes_Duckman::initOpcodes() {
OPCODE(23, opExitModalScene);
OPCODE(24, opEnterScene24);
OPCODE(25, opLeaveScene24);
+ OPCODE(33, opPanTrackObject);
OPCODE(34, opPanToObject);
+ OPCODE(36, opPanToPoint);
OPCODE(38, opStartFade);
OPCODE(39, opSetDisplay);
OPCODE(40, opSetCameraBounds);
@@ -80,6 +82,7 @@ void ScriptOpcodes_Duckman::initOpcodes() {
OPCODE(50, opFaceActor);
OPCODE(51, opFaceActorToObject);
OPCODE(52, opStartSequenceActor);
+ OPCODE(53, opStartSequenceActorAtPosition);
OPCODE(54, opStartMoveActor);
OPCODE(55, opStartMoveActorToObject);
OPCODE(56, opStartTalkThread);
@@ -88,6 +91,8 @@ void ScriptOpcodes_Duckman::initOpcodes() {
OPCODE(59, opActivateObject);
OPCODE(60, opDeactivateObject);
OPCODE(61, opSetDefaultSequence);
+ OPCODE(64, opStopCursorHoldingObject);
+ OPCODE(65, opStartCursorHoldingObject);
OPCODE(66, opPlayVideo);
OPCODE(69, opRunSpecialCode);
OPCODE(72, opStartSound);
@@ -101,13 +106,23 @@ void ScriptOpcodes_Duckman::initOpcodes() {
OPCODE(87, opDeactivateButton);
OPCODE(88, opActivateButton);
OPCODE(96, opIncBlockCounter);
+ OPCODE(97, opClearBlockCounter);
OPCODE(104, opJumpIf);
+ OPCODE(105, opIsPrevSceneId);
OPCODE(106, opNot);
OPCODE(107, opAnd);
OPCODE(108, opOr);
OPCODE(109, opGetProperty);
OPCODE(110, opCompareBlockCounter);
+ OPCODE(112, opAddDialogItem);
+ OPCODE(113, opStartDialog);
+ OPCODE(114, opJumpToDialogChoice);
+ OPCODE(115, opSetBlockCounter115);
+ OPCODE(116, opSetBlockCounter116);
+ OPCODE(117, opSetBlockCounter117);
+ OPCODE(118, opSetBlockCounter118);
OPCODE(126, opDebug126);
+ OPCODE(127, opDebug127);
#if 0
// Register opcodes
OPCODE(8, opStartTempScriptThread);
@@ -118,9 +133,7 @@ void ScriptOpcodes_Duckman::initOpcodes() {
OPCODE(31, opExitCloseUpScene);
OPCODE(32, opPanCenterObject);
OPCODE(35, opPanToNamedPoint);
- OPCODE(36, opPanToPoint);
OPCODE(37, opPanStop);
- OPCODE(43, opClearBlockCounter);
OPCODE(53, opSetActorToNamedPoint);
OPCODE(63, opSetSelectSfx);
OPCODE(64, opSetMoveSfx);
@@ -129,7 +142,6 @@ void ScriptOpcodes_Duckman::initOpcodes() {
OPCODE(67, opSetAdjustDnSfx);
OPCODE(78, opStackPushRandom);
OPCODE(79, opIfLte);
- OPCODE(104, opIsPrevSceneId);
OPCODE(105, opIsCurrentSceneId);
OPCODE(106, opIsActiveSceneId);
OPCODE(146, opStackPop);
@@ -232,9 +244,14 @@ void ScriptOpcodes_Duckman::opEnterScene18(ScriptThread *scriptThread, OpCall &o
}
//static uint dsceneId = 0, dthreadId = 0;
-static uint dsceneId = 0x00010008, dthreadId = 0x00020029;//Beginning in Jac
+//static uint dsceneId = 0x00010008, dthreadId = 0x00020029;//Beginning in Jac
//static uint dsceneId = 0x00010012, dthreadId = 0x0002009D;//Paramount
//static uint dsceneId = 0x00010039, dthreadId = 0x00020089;//Map
+//static uint dsceneId = 0x00010033, dthreadId = 0x000201A4;//Chinese
+//static uint dsceneId = 0x00010020, dthreadId = 0x00020112;//Xmas
+//static uint dsceneId = 0x00010039, dthreadId = 0x00020089;//Pizza
+//static uint dsceneId = 0x0001002D, dthreadId = 0x00020141;
+static uint dsceneId = 0x0001004B, dthreadId = 0x0002029B;
void ScriptOpcodes_Duckman::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
@@ -242,6 +259,8 @@ void ScriptOpcodes_Duckman::opChangeScene(ScriptThread *scriptThread, OpCall &op
ARG_UINT32(threadId);
_vm->_input->discardButtons(0xFFFF);
+ debug("changeScene(%08X, %08X)", sceneId, threadId);
+
//DEBUG
if (dsceneId) {
sceneId = dsceneId;
@@ -273,10 +292,10 @@ void ScriptOpcodes_Duckman::opExitModalScene(ScriptThread *scriptThread, OpCall
// TODO _vm->startScriptThread2(0x10002, 0x20001, 0);
opCall._result = kTSTerminate;
} else {
- _vm->dumpCurrSceneFiles(_vm->getCurrentScene(), opCall._callerThreadId);
- _vm->exitScene();
- _vm->leavePause(_vm->getCurrentScene(), opCall._callerThreadId);
- _vm->_talkItems->unpauseByTag(_vm->getCurrentScene());
+ _vm->dumpCurrSceneFiles(_vm->getCurrentScene(), opCall._callerThreadId);
+ _vm->exitScene();
+ _vm->leavePause(_vm->getCurrentScene(), opCall._callerThreadId);
+ _vm->_talkItems->unpauseByTag(_vm->getCurrentScene());
}
}
@@ -295,6 +314,12 @@ void ScriptOpcodes_Duckman::opLeaveScene24(ScriptThread *scriptThread, OpCall &o
_vm->leavePause(_vm->getCurrentScene(), opCall._callerThreadId);
}
+void ScriptOpcodes_Duckman::opPanTrackObject(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_SKIP(2);
+ ARG_UINT32(objectId);
+ _vm->_camera->panTrackObject(objectId);
+}
+
void ScriptOpcodes_Duckman::opPanToObject(ScriptThread *scriptThread, OpCall &opCall) {
ARG_INT16(speed);
ARG_UINT32(objectId);
@@ -303,6 +328,13 @@ void ScriptOpcodes_Duckman::opPanToObject(ScriptThread *scriptThread, OpCall &op
_vm->_camera->panToPoint(pos, speed, opCall._threadId);
}
+void ScriptOpcodes_Duckman::opPanToPoint(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_INT16(speed);
+ ARG_INT16(x);
+ ARG_INT16(y);
+ _vm->_camera->panToPoint(Common::Point(x, y), speed, opCall._threadId);
+}
+
void ScriptOpcodes_Duckman::opStartFade(ScriptThread *scriptThread, OpCall &opCall) {
ARG_INT16(arg1);
ARG_INT16(arg2);
@@ -321,6 +353,7 @@ void ScriptOpcodes_Duckman::opSetDisplay(ScriptThread *scriptThread, OpCall &opC
}
void ScriptOpcodes_Duckman::opSetCameraBounds(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_SKIP(2);
ARG_INT16(x1);
ARG_INT16(y1);
ARG_INT16(x2);
@@ -353,8 +386,8 @@ void ScriptOpcodes_Duckman::opFaceActor(ScriptThread *scriptThread, OpCall &opCa
void ScriptOpcodes_Duckman::opFaceActorToObject(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
- ARG_UINT32(objectId1);
ARG_UINT32(objectId2);
+ ARG_UINT32(objectId1);
Control *control1 = _vm->_dict->getObjectControl(objectId1);
Control *control2 = _vm->_dict->getObjectControl(objectId2);
Common::Point pos1 = control1->getActorPosition();
@@ -373,6 +406,17 @@ void ScriptOpcodes_Duckman::opStartSequenceActor(ScriptThread *scriptThread, OpC
control->startSequenceActor(sequenceId, 2, opCall._threadId);
}
+void ScriptOpcodes_Duckman::opStartSequenceActorAtPosition(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_SKIP(2);
+ ARG_UINT32(objectId);
+ ARG_UINT32(sequenceId);
+ ARG_UINT32(namedPointId);
+ Common::Point pos = _vm->getNamedPointPosition(namedPointId);
+ Control *control = _vm->_dict->getObjectControl(objectId);
+ control->setActorPosition(pos);
+ control->startSequenceActor(sequenceId, 2, opCall._threadId);
+}
+
void ScriptOpcodes_Duckman::opStartMoveActor(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(objectId);
@@ -456,6 +500,22 @@ void ScriptOpcodes_Duckman::opSetDefaultSequence(ScriptThread *scriptThread, OpC
control->_actor->_defaultSequences.set(sequenceId, defaultSequenceId);
}
+void ScriptOpcodes_Duckman::opStopCursorHoldingObject(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_INT16(flags);
+ _vm->stopCursorHoldingObject();
+ if (!(flags & 1))
+ _vm->playSoundEffect(7);
+}
+
+void ScriptOpcodes_Duckman::opStartCursorHoldingObject(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_INT16(flags);
+ ARG_UINT32(objectId);
+ ARG_UINT32(sequenceId);
+ _vm->startCursorHoldingObject(objectId, sequenceId);
+ if (!(flags & 1))
+ _vm->playSoundEffect(6);
+}
+
void ScriptOpcodes_Duckman::opPlayVideo(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(objectId);
@@ -550,6 +610,11 @@ void ScriptOpcodes_Duckman::opIncBlockCounter(ScriptThread *scriptThread, OpCall
_vm->_scriptResource->_blockCounters.set(index, value);
}
+void ScriptOpcodes_Duckman::opClearBlockCounter(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_INT16(index);
+ _vm->_scriptResource->_blockCounters.set(index, 0);
+}
+
void ScriptOpcodes_Duckman::opJumpIf(ScriptThread *scriptThread, OpCall &opCall) {
ARG_INT16(jumpOffs);
int16 value = _vm->_stack->pop();
@@ -557,6 +622,12 @@ void ScriptOpcodes_Duckman::opJumpIf(ScriptThread *scriptThread, OpCall &opCall)
opCall._deltaOfs += jumpOffs;
}
+void ScriptOpcodes_Duckman::opIsPrevSceneId(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_SKIP(2);
+ ARG_UINT32(sceneId);
+ _vm->_stack->push(_vm->_prevSceneId == sceneId ? 1 : 0);
+}
+
void ScriptOpcodes_Duckman::opNot(ScriptThread *scriptThread, OpCall &opCall) {
int16 value = _vm->_stack->pop();
_vm->_stack->push(value != 0 ? 0 : 1);
@@ -610,9 +681,56 @@ void ScriptOpcodes_Duckman::opCompareBlockCounter(ScriptThread *scriptThread, Op
_vm->_stack->push(compareResult ? 1 : 0);
}
+void ScriptOpcodes_Duckman::opAddDialogItem(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_SKIP(2);
+ ARG_INT16(index);
+ ARG_INT16(choiceJumpOffs);
+ ARG_UINT32(sequenceId);
+ if (index && (_vm->_scriptResource->_blockCounters.getC0(index) & 0x40))
+ _vm->addDialogItem(choiceJumpOffs, sequenceId);
+}
+
+void ScriptOpcodes_Duckman::opStartDialog(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_SKIP(2);
+ ARG_UINT32(actorTypeId);
+ _vm->startDialog(&_vm->_menuChoiceOfs, actorTypeId, opCall._callerThreadId);
+}
+
+void ScriptOpcodes_Duckman::opJumpToDialogChoice(ScriptThread *scriptThread, OpCall &opCall) {
+ opCall._deltaOfs += _vm->_menuChoiceOfs;
+}
+
+void ScriptOpcodes_Duckman::opSetBlockCounter115(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_INT16(index);
+ if (_vm->_scriptResource->_blockCounters.getC0(index) & 0x80)
+ _vm->_scriptResource->_blockCounters.set(index, 0);
+ _vm->_scriptResource->_blockCounters.setC0(index, 0x40);
+}
+
+void ScriptOpcodes_Duckman::opSetBlockCounter116(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_INT16(index);
+ if (!(_vm->_scriptResource->_blockCounters.getC0(index) & 0x80))
+ _vm->_scriptResource->_blockCounters.setC0(index, 0x40);
+}
+
+void ScriptOpcodes_Duckman::opSetBlockCounter117(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_INT16(index);
+ _vm->_scriptResource->_blockCounters.setC0(index, 0);
+}
+
+void ScriptOpcodes_Duckman::opSetBlockCounter118(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_INT16(index);
+ _vm->_scriptResource->_blockCounters.setC0(index, 0x40);
+}
+
void ScriptOpcodes_Duckman::opDebug126(ScriptThread *scriptThread, OpCall &opCall) {
// NOTE Prints some debug text
- debug(1, "[DBG] %s", (char*)opCall._code);
+ debug(1, "[DBG126] %s", (char*)opCall._code);
+}
+
+void ScriptOpcodes_Duckman::opDebug127(ScriptThread *scriptThread, OpCall &opCall) {
+ // NOTE Prints some debug text
+ debug(1, "[DBG127] %s", (char*)opCall._code);
}
#if 0
@@ -674,22 +792,10 @@ void ScriptOpcodes_Duckman::opPanToNamedPoint(ScriptThread *scriptThread, OpCall
_vm->_camera->panToPoint(pos, speed, opCall._threadId);
}
-void ScriptOpcodes_Duckman::opPanToPoint(ScriptThread *scriptThread, OpCall &opCall) {
- ARG_INT16(speed);
- ARG_INT16(x);
- ARG_INT16(y);
- _vm->_camera->panToPoint(Common::Point(x, y), speed, opCall._threadId);
-}
-
void ScriptOpcodes_Duckman::opPanStop(ScriptThread *scriptThread, OpCall &opCall) {
_vm->_camera->stopPan();
}
-void ScriptOpcodes_Duckman::opClearBlockCounter(ScriptThread *scriptThread, OpCall &opCall) {
- ARG_INT16(index);
- _vm->_scriptResource->_blockCounters.set(index, 0);
-}
-
void ScriptOpcodes_Duckman::opSetActorToNamedPoint(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(objectId);
@@ -744,12 +850,6 @@ void ScriptOpcodes_Duckman::opIfLte(ScriptThread *scriptThread, OpCall &opCall)
opCall._deltaOfs += elseJumpOffs;
}
-void ScriptOpcodes_Duckman::opIsPrevSceneId(ScriptThread *scriptThread, OpCall &opCall) {
- ARG_SKIP(2);
- ARG_UINT32(sceneId);
- _vm->_stack->push(_vm->_prevSceneId == sceneId ? 1 : 0);
-}
-
void ScriptOpcodes_Duckman::opIsCurrentSceneId(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(sceneId);
diff --git a/engines/illusions/scriptopcodes_duckman.h b/engines/illusions/scriptopcodes_duckman.h
index 2a30c584f3..124564eaa1 100644
--- a/engines/illusions/scriptopcodes_duckman.h
+++ b/engines/illusions/scriptopcodes_duckman.h
@@ -58,7 +58,9 @@ protected:
void opExitModalScene(ScriptThread *scriptThread, OpCall &opCall);
void opEnterScene24(ScriptThread *scriptThread, OpCall &opCall);
void opLeaveScene24(ScriptThread *scriptThread, OpCall &opCall);
+ void opPanTrackObject(ScriptThread *scriptThread, OpCall &opCall);
void opPanToObject(ScriptThread *scriptThread, OpCall &opCall);
+ void opPanToPoint(ScriptThread *scriptThread, OpCall &opCall);
void opStartFade(ScriptThread *scriptThread, OpCall &opCall);
void opSetDisplay(ScriptThread *scriptThread, OpCall &opCall);
void opSetCameraBounds(ScriptThread *scriptThread, OpCall &opCall);
@@ -67,6 +69,7 @@ protected:
void opFaceActor(ScriptThread *scriptThread, OpCall &opCall);
void opFaceActorToObject(ScriptThread *scriptThread, OpCall &opCall);
void opStartSequenceActor(ScriptThread *scriptThread, OpCall &opCall);
+ void opStartSequenceActorAtPosition(ScriptThread *scriptThread, OpCall &opCall);
void opStartMoveActor(ScriptThread *scriptThread, OpCall &opCall);
void opStartMoveActorToObject(ScriptThread *scriptThread, OpCall &opCall);
void opStartTalkThread(ScriptThread *scriptThread, OpCall &opCall);
@@ -75,6 +78,8 @@ protected:
void opActivateObject(ScriptThread *scriptThread, OpCall &opCall);
void opDeactivateObject(ScriptThread *scriptThread, OpCall &opCall);
void opSetDefaultSequence(ScriptThread *scriptThread, OpCall &opCall);
+ void opStopCursorHoldingObject(ScriptThread *scriptThread, OpCall &opCall);
+ void opStartCursorHoldingObject(ScriptThread *scriptThread, OpCall &opCall);
void opPlayVideo(ScriptThread *scriptThread, OpCall &opCall);
void opRunSpecialCode(ScriptThread *scriptThread, OpCall &opCall);
void opStartSound(ScriptThread *scriptThread, OpCall &opCall);
@@ -88,13 +93,23 @@ protected:
void opDeactivateButton(ScriptThread *scriptThread, OpCall &opCall);
void opActivateButton(ScriptThread *scriptThread, OpCall &opCall);
void opIncBlockCounter(ScriptThread *scriptThread, OpCall &opCall);
+ void opClearBlockCounter(ScriptThread *scriptThread, OpCall &opCall);
void opJumpIf(ScriptThread *scriptThread, OpCall &opCall);
+ void opIsPrevSceneId(ScriptThread *scriptThread, OpCall &opCall);
void opNot(ScriptThread *scriptThread, OpCall &opCall);
void opAnd(ScriptThread *scriptThread, OpCall &opCall);
void opOr(ScriptThread *scriptThread, OpCall &opCall);
void opGetProperty(ScriptThread *scriptThread, OpCall &opCall);
void opCompareBlockCounter(ScriptThread *scriptThread, OpCall &opCall);
+ void opAddDialogItem(ScriptThread *scriptThread, OpCall &opCall);
+ void opStartDialog(ScriptThread *scriptThread, OpCall &opCall);
+ void opJumpToDialogChoice(ScriptThread *scriptThread, OpCall &opCall);
+ void opSetBlockCounter115(ScriptThread *scriptThread, OpCall &opCall);
+ void opSetBlockCounter116(ScriptThread *scriptThread, OpCall &opCall);
+ void opSetBlockCounter117(ScriptThread *scriptThread, OpCall &opCall);
+ void opSetBlockCounter118(ScriptThread *scriptThread, OpCall &opCall);
void opDebug126(ScriptThread *scriptThread, OpCall &opCall);
+ void opDebug127(ScriptThread *scriptThread, OpCall &opCall);
#if 0
void opStartTempScriptThread(ScriptThread *scriptThread, OpCall &opCall);
@@ -105,9 +120,7 @@ protected:
void opExitCloseUpScene(ScriptThread *scriptThread, OpCall &opCall);
void opPanCenterObject(ScriptThread *scriptThread, OpCall &opCall);
void opPanToNamedPoint(ScriptThread *scriptThread, OpCall &opCall);
- void opPanToPoint(ScriptThread *scriptThread, OpCall &opCall);
void opPanStop(ScriptThread *scriptThread, OpCall &opCall);
- void opClearBlockCounter(ScriptThread *scriptThread, OpCall &opCall);
void opSetActorToNamedPoint(ScriptThread *scriptThread, OpCall &opCall);
void opSetSelectSfx(ScriptThread *scriptThread, OpCall &opCall);
void opSetMoveSfx(ScriptThread *scriptThread, OpCall &opCall);
@@ -116,7 +129,6 @@ protected:
void opSetAdjustDnSfx(ScriptThread *scriptThread, OpCall &opCall);
void opStackPushRandom(ScriptThread *scriptThread, OpCall &opCall);
void opIfLte(ScriptThread *scriptThread, OpCall &opCall);
- void opIsPrevSceneId(ScriptThread *scriptThread, OpCall &opCall);
void opIsCurrentSceneId(ScriptThread *scriptThread, OpCall &opCall);
void opIsActiveSceneId(ScriptThread *scriptThread, OpCall &opCall);
void opStackPop(ScriptThread *scriptThread, OpCall &opCall);
diff --git a/engines/illusions/scriptresource.cpp b/engines/illusions/scriptresource.cpp
index 90658ca165..2054d4dede 100644
--- a/engines/illusions/scriptresource.cpp
+++ b/engines/illusions/scriptresource.cpp
@@ -113,6 +113,17 @@ void BlockCounters::set(uint index, byte value) {
_blockCounters[index - 1] ^= (_blockCounters[index - 1] ^ value) & 0x3F;
}
+byte BlockCounters::getC0(uint index) {
+ return _blockCounters[index - 1] & 0xC0;
+}
+
+void BlockCounters::setC0(uint index, byte value) {
+ byte oldValue = _blockCounters[index - 1] & 0x3F;
+ if (value & 0x80)
+ value = value & 0xBF;
+ _blockCounters[index - 1] = oldValue | (value & 0xC0);
+}
+
// TriggerCause
void TriggerCause::load(Common::SeekableReadStream &stream) {
@@ -146,11 +157,20 @@ void TriggerObject::load(byte *dataStart, Common::SeekableReadStream &stream) {
}
bool TriggerObject::findTriggerCause(uint32 verbId, uint32 objectId2, uint32 &codeOffs) {
- for (uint i = 0; i < _causesCount; ++i)
- if (_causes[i]._verbId == verbId && _causes[i]._objectId2 == objectId2) {
- codeOffs = _causes[i]._codeOffs;
- return true;
- }
+ if ((verbId & 0xFFFF0000) == 0) {
+ for (uint i = 0; i < _causesCount; ++i)
+ if ((verbId == 7 && ((_causes[i]._verbId == 7 && _causes[i]._objectId2 == objectId2) || _causes[i]._verbId == 8)) ||
+ verbId == _causes[i]._verbId) {
+ codeOffs = _causes[i]._codeOffs;
+ return true;
+ }
+ } else {
+ for (uint i = 0; i < _causesCount; ++i)
+ if (_causes[i]._verbId == verbId && _causes[i]._objectId2 == objectId2) {
+ codeOffs = _causes[i]._codeOffs;
+ return true;
+ }
+ }
return false;
}
@@ -311,8 +331,13 @@ void ScriptResource::load(Resource *resource) {
}
}
- stream.seek(0x6C);
- _field6C = stream.readUint32LE();
+ if (resource->_gameId == kGameIdDuckman) {
+ stream.seek(0x6C);
+ _mainActorObjectId = stream.readUint32LE();
+ } else if (resource->_gameId == kGameIdBBDOU) {
+ stream.seek(0);
+ _mainActorObjectId = stream.readUint32LE();
+ }
if (resource->_gameId == kGameIdDuckman)
fixupProgInfosDuckman();
diff --git a/engines/illusions/scriptresource.h b/engines/illusions/scriptresource.h
index 6452c7c4c5..35c3ed02c8 100644
--- a/engines/illusions/scriptresource.h
+++ b/engines/illusions/scriptresource.h
@@ -61,6 +61,8 @@ public:
void clear();
byte get(uint index);
void set(uint index, byte value);
+ byte getC0(uint index);
+ void setC0(uint index, byte value);
public:
uint _count;
byte *_blockCounters;
@@ -114,7 +116,7 @@ public:
byte *getCode(uint32 codeOffs);
ProgInfo *getProgInfo(uint32 index);
uint32 getObjectActorTypeId(uint32 objectId);
- uint32 getField6C() const { return _field6C; }
+ uint32 getMainActorObjectId() const { return _mainActorObjectId; }
public:
byte *_data;
uint32 _dataSize;
@@ -128,7 +130,7 @@ public:
uint32 _soundIds[27];
uint _objectMapCount;
uint32 *_objectMap;
- uint32 _field6C;
+ uint32 _mainActorObjectId;
void fixupProgInfosDuckman();
};
diff --git a/engines/illusions/sequenceopcodes.cpp b/engines/illusions/sequenceopcodes.cpp
index e00bb23722..83476ff629 100644
--- a/engines/illusions/sequenceopcodes.cpp
+++ b/engines/illusions/sequenceopcodes.cpp
@@ -75,9 +75,11 @@ void SequenceOpcodes::initOpcodes() {
OPCODE(18, opAppearForeignActor);
OPCODE(19, opDisappearForeignActor);
OPCODE(21, opMoveDelta);
+ OPCODE(25, opFaceActor);
OPCODE(28, opNotifyThreadId1);
OPCODE(29, opSetPathCtrY);
OPCODE(33, opSetPathWalkPoints);
+ OPCODE(34, opDisableAutoScale);
OPCODE(35, opSetScale);
OPCODE(36, opSetScaleLayer);
OPCODE(37, opDeactivatePathWalkRects);
@@ -253,6 +255,11 @@ void SequenceOpcodes::opMoveDelta(Control *control, OpCall &opCall) {
control->_actor->_position.y += deltaY;
}
+void SequenceOpcodes::opFaceActor(Control *control, OpCall &opCall) {
+ ARG_INT16(facing);
+ control->_actor->_facing = facing;
+}
+
void SequenceOpcodes::opNotifyThreadId1(Control *control, OpCall &opCall) {
_vm->notifyThreadId(control->_actor->_notifyThreadId1);
}
@@ -269,6 +276,11 @@ void SequenceOpcodes::opSetPathWalkPoints(Control *control, OpCall &opCall) {
// TODO control->_actor->_pathWalkPoints = bgRes->getPathWalkPoints(pathWalkPointsIndex - 1);
}
+void SequenceOpcodes::opDisableAutoScale(Control *control, OpCall &opCall) {
+ // Keep current scale but don't autoscale
+ control->_actor->_flags &= ~4;
+}
+
void SequenceOpcodes::opSetScale(Control *control, OpCall &opCall) {
ARG_INT16(scale);
control->_actor->_flags &= ~4;
diff --git a/engines/illusions/sequenceopcodes.h b/engines/illusions/sequenceopcodes.h
index 3aab3a8328..db15658356 100644
--- a/engines/illusions/sequenceopcodes.h
+++ b/engines/illusions/sequenceopcodes.h
@@ -64,9 +64,11 @@ protected:
void opAppearForeignActor(Control *control, OpCall &opCall);
void opDisappearForeignActor(Control *control, OpCall &opCall);
void opMoveDelta(Control *control, OpCall &opCall);
+ void opFaceActor(Control *control, OpCall &opCall);
void opNotifyThreadId1(Control *control, OpCall &opCall);
void opSetPathCtrY(Control *control, OpCall &opCall);
void opSetPathWalkPoints(Control *control, OpCall &opCall);
+ void opDisableAutoScale(Control *control, OpCall &opCall);
void opSetScale(Control *control, OpCall &opCall);
void opSetScaleLayer(Control *control, OpCall &opCall);
void opDeactivatePathWalkRects(Control *control, OpCall &opCall);
diff --git a/engines/illusions/talkthread_duckman.cpp b/engines/illusions/talkthread_duckman.cpp
index fe666a3a29..8c290718d8 100644
--- a/engines/illusions/talkthread_duckman.cpp
+++ b/engines/illusions/talkthread_duckman.cpp
@@ -240,10 +240,9 @@ void TalkThread_Duckman::onKill() {
}
uint32 TalkThread_Duckman::sendMessage(int msgNum, uint32 msgValue) {
- // TODO
switch (msgNum) {
case kMsgQueryTalkThreadActive:
- if (_status != 1 && _status != 2)
+ if (_status != 1)
return 1;
break;
case kMsgClearSequenceId1: