aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/pregob/onceupon/stork.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob/pregob/onceupon/stork.cpp')
-rw-r--r--engines/gob/pregob/onceupon/stork.cpp234
1 files changed, 234 insertions, 0 deletions
diff --git a/engines/gob/pregob/onceupon/stork.cpp b/engines/gob/pregob/onceupon/stork.cpp
new file mode 100644
index 0000000000..3c38037d08
--- /dev/null
+++ b/engines/gob/pregob/onceupon/stork.cpp
@@ -0,0 +1,234 @@
+/* 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 "common/str.h"
+
+#include "gob/gob.h"
+#include "gob/surface.h"
+#include "gob/anifile.h"
+#include "gob/video.h"
+
+#include "gob/pregob/onceupon/stork.h"
+
+enum Animation {
+ kAnimFlyNearWithBundle = 9,
+ kAnimFlyFarWithBundle = 12,
+ kAnimFlyNearWithoutBundle = 10,
+ kAnimFlyFarWithoutBundle = 13,
+ kAnimBundleNear = 11,
+ kAnimBundleFar = 14
+};
+
+namespace Gob {
+
+namespace OnceUpon {
+
+Stork::Stork(GobEngine *vm, const ANIFile &ani) : ANIObject(ani), _shouldDrop(false) {
+ _frame = new Surface(320, 200, 1);
+ vm->_video->drawPackedSprite("cadre.cmp", *_frame);
+
+ _bundle = new ANIObject(ani);
+
+ _bundle->setVisible(false);
+ _bundle->setPause(true);
+
+ setState(kStateFlyNearWithBundle, kAnimFlyNearWithBundle, -80);
+}
+
+Stork::~Stork() {
+ delete _frame;
+
+ delete _bundle;
+}
+
+bool Stork::hasBundleLanded() const {
+ if (!_shouldDrop || !_bundle->isVisible() || _bundle->isPaused())
+ return false;
+
+ int16 x, y, width, height;
+ _bundle->getFramePosition(x, y);
+ _bundle->getFrameSize(width, height);
+
+ return (y + height) >= _bundleDrop.landY;
+}
+
+void Stork::dropBundle(const BundleDrop &drop) {
+ if (_shouldDrop)
+ return;
+
+ _shouldDrop = true;
+ _bundleDrop = drop;
+}
+
+bool Stork::draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) {
+ left = 0x7FFF;
+ top = 0x7FFF;
+ right = 0x0000;
+ bottom = 0x0000;
+
+ bool drawn = ANIObject::draw(dest, left, top, right, bottom);
+ if (drawn) {
+ // Left frame edge
+ if (left <= 15)
+ dest.blit(*_frame, left, top, MIN<int16>(15, right), bottom, left, top);
+
+ // Right frame edge
+ if (right >= 304)
+ dest.blit(*_frame, MAX<int16>(304, left), top, right, bottom, MAX<int16>(304, left), top);
+ }
+
+ int16 bLeft, bTop, bRight, bBottom;
+ if (_bundle->draw(dest, bLeft, bTop, bRight, bBottom)) {
+ // Bottom frame edge
+ if (bBottom >= 188)
+ dest.blit(*_frame, bLeft, MAX<int16>(188, bTop), bRight, bBottom, bLeft, MAX<int16>(188, bTop));
+
+ left = MIN(left , bLeft );
+ top = MIN(top , bTop );
+ right = MAX(right , bRight );
+ bottom = MAX(bottom, bBottom);
+
+ drawn = true;
+ }
+
+ return drawn;
+}
+
+bool Stork::clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) {
+ left = 0x7FFF;
+ top = 0x7FFF;
+ right = 0x0000;
+ bottom = 0x0000;
+
+ bool cleared = _bundle->clear(dest, left, top, right, bottom);
+
+ int16 sLeft, sTop, sRight, sBottom;
+ if (ANIObject::clear(dest, sLeft, sTop, sRight, sBottom)) {
+ left = MIN(left , sLeft );
+ top = MIN(top , sTop );
+ right = MAX(right , sRight );
+ bottom = MAX(bottom, sBottom);
+
+ cleared = true;
+ }
+
+ return cleared;
+}
+
+void Stork::advance() {
+ _bundle->advance();
+
+ ANIObject::advance();
+
+ int16 curX, curY, curWidth, curHeight;
+ getFramePosition(curX, curY, 0);
+ getFrameSize(curWidth, curHeight, 0);
+
+ const int16 curRight = curX + curWidth - 1;
+
+ int16 nextX, nextY, nextWidth, nextHeight;
+ getFramePosition(nextX, nextY, 1);
+ getFrameSize(nextWidth, nextHeight, 1);
+
+ const int16 nextRight = nextX + nextWidth - 1;
+
+ switch (_state) {
+ case kStateFlyNearWithBundle:
+ if (curX >= 330)
+ setState(kStateFlyFarWithBundle, kAnimFlyFarWithBundle, 330);
+
+ if ((curRight <= _bundleDrop.dropX) &&
+ (nextRight >= _bundleDrop.dropX) && _shouldDrop && !_bundleDrop.dropWhileFar)
+ dropBundle(kStateFlyNearWithoutBundle, kAnimFlyNearWithoutBundle);
+
+ break;
+
+ case kStateFlyFarWithBundle:
+ if (curX <= -80)
+ setState(kStateFlyNearWithBundle, kAnimFlyNearWithBundle, -80);
+
+ if ((curX >= _bundleDrop.dropX) &&
+ (nextX <= _bundleDrop.dropX) && _shouldDrop && _bundleDrop.dropWhileFar)
+ dropBundle(kStateFlyFarWithoutBundle, kAnimFlyFarWithoutBundle);
+
+ break;
+
+ case kStateFlyNearWithoutBundle:
+ if (curX >= 330)
+ setState(kStateFlyFarWithoutBundle, kAnimFlyFarWithoutBundle, 330);
+ break;
+
+ case kStateFlyFarWithoutBundle:
+ if (curX <= -80)
+ setState(kStateFlyNearWithoutBundle, kAnimFlyNearWithoutBundle, -80);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void Stork::dropBundle(State state, uint16 anim) {
+ setState(state, anim);
+
+ int16 x, y, width, height;
+ getFramePosition(x, y);
+ getFrameSize(width, height);
+
+ _bundle->setAnimation(_bundleDrop.anim);
+ _bundle->setPause(false);
+ _bundle->setVisible(true);
+
+ int16 bWidth, bHeight;
+ _bundle->getFrameSize(bWidth, bHeight);
+
+ // Drop position
+ x = _bundleDrop.dropX;
+ y = y + height - bHeight;
+
+ // If the stork is flying near (from left to right), drop the bundle at the right edge
+ if (!_bundleDrop.dropWhileFar)
+ x = x - bWidth;
+
+ _bundle->setPosition(x, y);
+}
+
+void Stork::setState(State state, uint16 anim) {
+ setAnimation(anim);
+ setVisible(true);
+ setPause(false);
+
+ _state = state;
+}
+
+void Stork::setState(State state, uint16 anim, int16 x) {
+ setState(state, anim);
+ setPosition();
+
+ int16 pX, pY;
+ getPosition(pX, pY);
+ setPosition( x, pY);
+}
+
+} // End of namespace OnceUpon
+
+} // End of namespace Gob