aboutsummaryrefslogtreecommitdiff
path: root/engines/illusions/bbdou
diff options
context:
space:
mode:
Diffstat (limited to 'engines/illusions/bbdou')
-rw-r--r--engines/illusions/bbdou/bbdou_bubble.cpp106
-rw-r--r--engines/illusions/bbdou/bbdou_bubble.h1
-rw-r--r--engines/illusions/bbdou/bbdou_specialcode.cpp18
-rw-r--r--engines/illusions/bbdou/scriptopcodes_bbdou.cpp4
4 files changed, 117 insertions, 12 deletions
diff --git a/engines/illusions/bbdou/bbdou_bubble.cpp b/engines/illusions/bbdou/bbdou_bubble.cpp
index d24e16e0d1..62e7959830 100644
--- a/engines/illusions/bbdou/bbdou_bubble.cpp
+++ b/engines/illusions/bbdou/bbdou_bubble.cpp
@@ -109,7 +109,7 @@ void BbdouBubble::show() {
_prevItem0 = _currItem0;
_currItem0 = 0;
- // TODO calcBubbles(_pt1, _pt2);
+ calcBubbles(_pt1, _pt2);
Control *control = _vm->_dict->getObjectControl(_prevItem0->_objectId);
control->setActorPosition(_pt2);
@@ -183,4 +183,108 @@ uint32 BbdouBubble::addItem(uint positionIndex, uint32 sequenceId) {
return 0;
}
+void BbdouBubble::calcBubbles(Common::Point &pt1, Common::Point &pt2) {
+ const int kSequenceIdsCount = 10;
+ const float kDistanceBetweenPoints = 30.0;
+ static const uint32 kSequenceIds[] = {
+ 0x00060042, 0x00060043, 0x00060044, 0x00060045, 0x00060046,
+ 0x00060047, 0x00060048, 0x00060049, 0x0006004A, 0x0006004B
+ };
+ static const int kIndexTbl[kSequenceIdsCount] = {4, 0, 8, 2, 6, 5, 1, 9, 3, 7};
+
+ int sequenceCounters[kSequenceIdsCount];
+ bool swapY;
+ int centerX, centerY;
+ float currentAngle, radius;
+
+ for (int i = 0; i < 32; ++i) {
+ Control *control = _vm->_dict->getObjectControl(_objectIds[i]);
+ control->startSequenceActor(0x00060056, 2, 0);
+ }
+
+ for (int i = 0; i < kSequenceIdsCount; ++i)
+ sequenceCounters[i] = 0;
+
+ if (pt2.y >= pt1.y) {
+ swapY = true;
+ if (pt1.x == pt2.x)
+ pt2.x = pt2.x + 20;
+ } else {
+ swapY = false;
+ if (pt1.y == pt2.y)
+ pt2.y = pt2.y + 20;
+ }
+
+ if (swapY) {
+ centerX = (pt2.x * pt2.x - (pt2.y - pt1.y) * (pt2.y - pt1.y) - pt1.x * pt1.x) / (2 * (pt2.x - pt1.x));
+ centerY = pt2.y;
+ radius = ABS(pt2.x - centerX);
+ } else {
+ centerX = pt2.x;
+ centerY = (pt2.y * pt2.y - (pt2.x - pt1.x) * (pt2.x - pt1.x) - pt1.y * pt1.y) / (2 * (pt2.y - pt1.y));
+ radius = ABS(pt2.y - centerY);
+ }
+
+ const float fullDistance = sqrt((pt2.y - pt1.y) * (pt2.y - pt1.y) + (pt2.x - pt1.x) * (pt2.x - pt1.x));
+ const float arcAngle = 2 * asin(CLIP(0.5 * fullDistance / radius, -1.0, 1.0));
+ const float arcLength = arcAngle * radius;
+ int pointsCount = (int)(arcLength / kDistanceBetweenPoints);
+ float partAngle = ABS(kDistanceBetweenPoints / radius);
+
+ for (int i = 0; i < pointsCount; ++i)
+ ++sequenceCounters[kIndexTbl[i % kSequenceIdsCount]];
+
+ if (!swapY) {
+ if (pt2.y < pt1.y) {
+ currentAngle = M_PI * 0.5;
+ } else {
+ currentAngle = M_PI * 1.5;
+ partAngle = -partAngle;
+ }
+ if (pt2.x < pt1.x)
+ partAngle = -partAngle;
+ } else {
+ if (pt2.x <= pt1.x) {
+ currentAngle = M_PI;
+ } else {
+ currentAngle = 0.0;
+ partAngle = -partAngle;
+ }
+ if (pt2.y > pt1.y)
+ partAngle = -partAngle;
+ }
+
+ int index = kSequenceIdsCount - 1;
+ float angleStep = partAngle / (float)pointsCount * 0.5;
+ float angleIncr = (float)(pointsCount / 2) * angleStep + partAngle;
+
+ if (pointsCount > 32)
+ pointsCount = 32;
+
+ for (int i = 0; i < pointsCount; ++i) {
+
+ currentAngle += angleIncr;
+ angleIncr -= angleStep;
+
+ Common::Point newPoint(
+ centerX + _vm->getRandom(8) - 2 + (int)(cos(currentAngle) * radius),
+ centerY + _vm->getRandom(8) - 2 - (int)(sin(currentAngle) * radius));
+
+ Control *control = _vm->_dict->getObjectControl(_objectIds[i]);
+
+ for (; index >= 0; --index) {
+ if (sequenceCounters[index] > 0) {
+ --sequenceCounters[index];
+ control->setActorPosition(newPoint);
+ control->startSequenceActor(kSequenceIds[index], 2, 0);
+ control->appearActor();
+ control->deactivateObject();
+ break;
+ }
+ }
+
+ }
+
+}
+
} // End of namespace Illusions
diff --git a/engines/illusions/bbdou/bbdou_bubble.h b/engines/illusions/bbdou/bbdou_bubble.h
index fcf5f51512..f42ff6ea9d 100644
--- a/engines/illusions/bbdou/bbdou_bubble.h
+++ b/engines/illusions/bbdou/bbdou_bubble.h
@@ -63,6 +63,7 @@ public:
void hide();
void setup(int16 minCount, Common::Point pt1, Common::Point pt2, uint32 progResKeywordId);
uint32 addItem(uint positionIndex, uint32 sequenceId);
+ void calcBubbles(Common::Point &pt1, Common::Point &pt2);
protected:
IllusionsEngine_BBDOU *_vm;
BbdouSpecialCode *_bbdou;
diff --git a/engines/illusions/bbdou/bbdou_specialcode.cpp b/engines/illusions/bbdou/bbdou_specialcode.cpp
index 437c9025c1..8bc09fff01 100644
--- a/engines/illusions/bbdou/bbdou_specialcode.cpp
+++ b/engines/illusions/bbdou/bbdou_specialcode.cpp
@@ -431,28 +431,28 @@ void BbdouSpecialCode::showBubble(uint32 objectId, uint32 overlappedObjectId, ui
Common::Rect collisionRect;
Control *overlappedControl, *control2, *control3;
- Common::Point pt1(320, 240), pt2, currPan;
+ Common::Point bubbleSourcePt(320, 240), bubbleDestPt, currPan;
overlappedControl = _vm->_dict->getObjectControl(overlappedObjectId);
overlappedControl->getCollisionRect(collisionRect);
currPan = _vm->_camera->getCurrentPan();
- pt2.x = CLIP((collisionRect.right + collisionRect.left) / 2, currPan.x - 274, currPan.x + 274);
- pt2.y = CLIP(collisionRect.top - (collisionRect.bottom - collisionRect.top) / 8, currPan.y - 204, currPan.y + 204);
+ bubbleDestPt.x = CLIP((collisionRect.right + collisionRect.left) / 2, currPan.x - 274, currPan.x + 274);
+ bubbleDestPt.y = CLIP(collisionRect.top - (collisionRect.bottom - collisionRect.top) / 8, currPan.y - 204, currPan.y + 204);
control2 = _vm->_dict->getObjectControl(0x4000F);
if (!control2 || (control2->_actor && control2->_actor->_frameIndex == 0))
control2 = _vm->_dict->getObjectControl(0x4000E);
if (control2 && control2->_actor && control2->_actor->_frameIndex) {
- pt1.x = control2->_actor->_surfInfo._dimensions._width / 2 + pt1.x - control2->_position.x;
- pt1.y = control2->_actor->_position.y - control2->_position.y;
- pt1.y = pt1.y >= 500 ? 500 : pt1.y + 32;
- if (ABS(pt1.x - pt2.x) < ABS(pt1.y - pt2.y) / 2)
- pt1.y += 80;
+ bubbleSourcePt.x = control2->_actor->_position.x - control2->_position.x + control2->_actor->_surfInfo._dimensions._width / 2;
+ bubbleSourcePt.y = control2->_actor->_position.y - control2->_position.y;
+ bubbleSourcePt.y = bubbleSourcePt.y >= 500 ? 500 : bubbleSourcePt.y + 32;
+ if (ABS(bubbleSourcePt.x - bubbleDestPt.x) < ABS(bubbleSourcePt.y - bubbleDestPt.y) / 2)
+ bubbleSourcePt.y += 80;
}
- _bubble->setup(1, pt1, pt2, progResKeywordId);
+ _bubble->setup(1, bubbleSourcePt, bubbleDestPt, progResKeywordId);
item10->_objectIds[0] = _bubble->addItem(0, 0x6005A);
item10->_objectIds[1] = _bubble->addItem(0, 0x6005A);
diff --git a/engines/illusions/bbdou/scriptopcodes_bbdou.cpp b/engines/illusions/bbdou/scriptopcodes_bbdou.cpp
index 1abcb69197..d887edddb5 100644
--- a/engines/illusions/bbdou/scriptopcodes_bbdou.cpp
+++ b/engines/illusions/bbdou/scriptopcodes_bbdou.cpp
@@ -288,7 +288,7 @@ void ScriptOpcodes_BBDOU::opUnloadActiveScenes(ScriptThread *scriptThread, OpCal
//uint32 dsceneId = 0x00010007, dthreadId = 0x0002000C;//Auditorium
//uint32 dsceneId = 0x0001000B, dthreadId = 0x00020010;
//uint32 dsceneId = 0x00010013, dthreadId = 0x00020018;//Therapist
-//uint32 dsceneId = 0x00010016, dthreadId = 0x0002001B;//Dorms ext
+uint32 dsceneId = 0x00010016, dthreadId = 0x0002001B;//Dorms ext
//uint32 dsceneId = 0x00010017, dthreadId = 0x0002001C;//Dorms int
//uint32 dsceneId = 0x0001000D, dthreadId = 0x00020012;//Food minigame
//uint32 dsceneId = 0x00010067, dthreadId = 0x0002022A;
@@ -296,7 +296,7 @@ void ScriptOpcodes_BBDOU::opUnloadActiveScenes(ScriptThread *scriptThread, OpCal
//uint32 dsceneId = 0x0001000B, dthreadId = 0x00020010;
//uint32 dsceneId = 0x0001001A, dthreadId = 0x0002001F;
//uint32 dsceneId = 0x00010047, dthreadId = 0x0002005F;
-uint32 dsceneId = 0x0001007D, dthreadId = 0x000203B9;
+//uint32 dsceneId = 0x0001007D, dthreadId = 0x000203B9;
void ScriptOpcodes_BBDOU::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);