diff options
Diffstat (limited to 'engines/illusions/bbdou')
-rw-r--r-- | engines/illusions/bbdou/bbdou_bubble.cpp | 106 | ||||
-rw-r--r-- | engines/illusions/bbdou/bbdou_bubble.h | 1 | ||||
-rw-r--r-- | engines/illusions/bbdou/bbdou_specialcode.cpp | 18 | ||||
-rw-r--r-- | engines/illusions/bbdou/scriptopcodes_bbdou.cpp | 4 |
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); |