diff options
Diffstat (limited to 'engines/gob/pregob/onceupon/stork.cpp')
| -rw-r--r-- | engines/gob/pregob/onceupon/stork.cpp | 234 | 
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  | 
