diff options
| -rw-r--r-- | engines/gob/pregob/onceupon/onceupon.cpp | 103 | ||||
| -rw-r--r-- | engines/gob/pregob/onceupon/onceupon.h | 10 | ||||
| -rw-r--r-- | engines/gob/pregob/pregob.cpp | 62 | ||||
| -rw-r--r-- | engines/gob/pregob/pregob.h | 37 | 
4 files changed, 176 insertions, 36 deletions
| diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index fb9629566c..aed1b45e02 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -264,14 +264,6 @@ void OnceUpon::setGameCursor() {  	setCursor(cursor, 105, 0, 120, 15, 0, 0);  } -void OnceUpon::setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const { -	ani.setAnimation(state); -	ani.setMode(once ? ANIObject::kModeOnce : ANIObject::kModeContinuous); -	ani.setPause(pause); -	ani.setVisible(true); -	ani.setPosition(); -} -  void OnceUpon::drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom,                                int16 x, int16 y) const { @@ -374,6 +366,18 @@ Common::String OnceUpon::fixString(const Common::String &str) const {  	return str;  } +enum ClownAnimation { +	kClownAnimationStand = 0, +	kClownAnimationCheer = 1, +	kClownAnimationCry   = 2 +}; + +const PreGob::AnimProperties OnceUpon::kClownAnimations[] = { +	{ 1, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, +	{ 0, 0, ANIObject::kModeOnce      , true, false, false, 0, 0}, +	{ 6, 0, ANIObject::kModeOnce      , true, false, false, 0, 0} +}; +  enum CopyProtectionState {  	kCPStateSetup,     // Set up the screen  	kCPStateWaitUser,  // Waiting for the user to pick a shape @@ -392,8 +396,10 @@ bool OnceUpon::doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20  	_vm->_video->drawPackedSprite("grille2.cmp", sprites[1]);  	// Load the clown animation -	ANIFile   ani  (_vm, "grille.ani", 320); -	ANIObject clown(ani); +	ANIFile ani  (_vm, "grille.ani", 320); +	ANIList anims; + +	loadAnims(anims, ani, 1, &kClownAnimations[kClownAnimationStand]);  	// Set the copy protection cursor  	setCursor(sprites[1], 5, 110, 20, 134, 3, 0); @@ -406,20 +412,20 @@ bool OnceUpon::doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20  	bool  hasCorrect  = false;  	while (!_vm->shouldQuit() && (state != kCPStateFinish)) { -		clearAnim(clown); +		clearAnim(anims);  		// Set up the screen  		if (state == kCPStateSetup) {  			animalShape = cpSetup(colors, shapes, obfuscate, sprites); -			setAnimState(clown, kClownAnimationClownStand, false, false); +			setAnim(*anims[0], kClownAnimations[kClownAnimationStand]);  			state = kCPStateWaitUser;  		} -		drawAnim(clown); +		drawAnim(anims);  		// If we're waiting for the clown and he finished, evaluate if we're finished -		if (!clown.isVisible() && (state == kCPStateWaitClown)) +		if (!anims[0]->isVisible() && (state == kCPStateWaitClown))  			state = (hasCorrect || (--triesLeft == 0)) ? kCPStateFinish : kCPStateSetup;  		showCursor(); @@ -443,12 +449,14 @@ bool OnceUpon::doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20  				hasCorrect  = guessedShape == animalShape;  				animalShape = -1; -				setAnimState(clown, hasCorrect ? kClownAnimationClownCheer : kClownAnimationClownCry, true, false); +				setAnim(*anims[0], kClownAnimations[hasCorrect ? kClownAnimationCheer : kClownAnimationCry]);  				state = kCPStateWaitClown;  			}  		}  	} +	freeAnims(anims); +  	fadeOut();  	hideCursor();  	clearScreen(); @@ -625,6 +633,10 @@ void OnceUpon::showQuote() {  	fadeOut();  } +const PreGob::AnimProperties OnceUpon::kTitleAnimation = { +	8, 0, ANIObject::kModeContinuous, true, false, false, 0, 0 +}; +  void OnceUpon::showTitle() {  	// Show the Once Upon A Time title animation  	// NOTE: This is currently only a mock-up. The real animation is in "ville.seq". @@ -639,15 +651,15 @@ void OnceUpon::showTitle() {  	_vm->_video->drawPackedSprite("ville.cmp", *_vm->_draw->_backSurface);  	_vm->_draw->forceBlit(); -	ANIFile   ani  (_vm, "pres.ani", 320); -	ANIObject title(ani); +	ANIFile ani  (_vm, "pres.ani", 320); +	ANIList anims; -	setAnimState(title, 8, false, false); +	loadAnims(anims, ani, 1, &kTitleAnimation);  	playTitleMusic();  	while (!_vm->shouldQuit()) { -		redrawAnim(title); +		redrawAnim(anims);  		fadeIn(); @@ -657,6 +669,8 @@ void OnceUpon::showTitle() {  			break;  	} +	freeAnims(anims); +  	fadeOut();  	stopTitleMusic();  } @@ -1349,9 +1363,58 @@ bool OnceUpon::sectionChapter7() {  	return true;  } +const PreGob::AnimProperties OnceUpon::kSectionEndAnimations[] = { +	{ 0, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, +	{ 6, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, +	{ 9, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, +	{11, 0, ANIObject::kModeContinuous, true, false, false, 0, 0} +}; +  bool OnceUpon::sectionEnd() { -	warning("OnceUpon::sectionEnd(): TODO"); +	fadeOut(); +	setGamePalette(9); + +	_vm->_video->drawPackedSprite("cadre.cmp", *_vm->_draw->_backSurface); + +	Surface endBackground(320, 200, 1); +	_vm->_video->drawPackedSprite("fin.cmp", endBackground); + +	_vm->_draw->_backSurface->blit(endBackground, 0, 0, 288, 137, 16, 50); + +	ANIFile ani(_vm, "fin.ani", 320); +	ANIList anims; + +	loadAnims(anims, ani, ARRAYSIZE(kSectionEndAnimations), kSectionEndAnimations); +	drawAnim(anims); + +	_vm->_draw->forceBlit(); + +	MenuAction action = kMenuActionNone; +	while (!_vm->shouldQuit() && (action == kMenuActionNone)) { +		redrawAnim(anims); + +		fadeIn(); + +		endFrame(true); + +		int16 mouseX, mouseY; +		MouseButtons mouseButtons; + +		int16 key = checkInput(mouseX, mouseY, mouseButtons); +		if ((key != 0) && (key != kKeyEscape)) +			// Any key pressed => Quit +			action = kMenuActionQuit; + +		action = doIngameMenu(key, mouseButtons); +	} + +	freeAnims(anims); + +	// Restart requested +	if (action == kMenuActionRestart) +		return false; +	// Last scene. Even if we didn't explicitly request a quit, the game ends here  	_quit = true;  	return false;  } diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 0cae369758..caaf155d06 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -149,19 +149,23 @@ private:  	/** All general game sounds we know about. */  	static const char *kSound[kSoundMAX]; + +	static const AnimProperties kClownAnimations[]; +	static const AnimProperties kTitleAnimation; +	static const AnimProperties kSectionEndAnimations[]; + +  	/** Function pointer type for a section handler. */  	typedef bool (OnceUpon::*SectionFunc)();  	/** Section handler function. */  	static const SectionFunc kSectionFuncs[kSectionCount]; +  	// -- General helpers --  	void setGamePalette(uint palette); ///< Set a game palette.  	void setGameCursor();              ///< Set the default game cursor. -	/** Set the state of an ANIObject. */ -	void setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const; -  	/** Draw this sprite in a fancy, animated line-by-line way. */  	void drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom,  	                    int16 x, int16 y) const; diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index 675958035d..4ee5430de7 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -251,24 +251,70 @@ bool PreGob::hasInput() {  	return checkInput(mouseX, mouseY, mouseButtons) || (mouseButtons != kMouseButtonsNone);  } -void PreGob::clearAnim(ANIObject &ani) { +void PreGob::clearAnim(ANIObject &anim) {  	int16 left, top, right, bottom; -	if (ani.clear(*_vm->_draw->_backSurface, left, top, right, bottom)) +	if (anim.clear(*_vm->_draw->_backSurface, left, top, right, bottom))  		_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);  } -void PreGob::drawAnim(ANIObject &ani) { +void PreGob::drawAnim(ANIObject &anim) {  	int16 left, top, right, bottom; -	if (ani.draw(*_vm->_draw->_backSurface, left, top, right, bottom)) +	if (anim.draw(*_vm->_draw->_backSurface, left, top, right, bottom))  		_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); -	ani.advance(); +	anim.advance();  } -void PreGob::redrawAnim(ANIObject &ani) { -	clearAnim(ani); -	drawAnim(ani); +void PreGob::redrawAnim(ANIObject &anim) { +	clearAnim(anim); +	drawAnim(anim); +} + +void PreGob::clearAnim(const ANIList &anims) { +	for (int i = (anims.size() - 1); i >= 0; i--) +		clearAnim(*anims[i]); +} + +void PreGob::drawAnim(const ANIList &anims) { +	for (ANIList::const_iterator a = anims.begin(); a != anims.end(); ++a) +		drawAnim(**a); +} + +void PreGob::redrawAnim(const ANIList &anims) { +	clearAnim(anims); +	drawAnim(anims); +} + +void PreGob::loadAnims(ANIList &anims, ANIFile &ani, uint count, const AnimProperties *props) const { +	freeAnims(anims); + +	anims.resize(count); +	for (uint i = 0; i < count; i++) { +		anims[i] = new ANIObject(ani); + +		setAnim(*anims[i], props[i]); +	} +} + +void PreGob::freeAnims(ANIList &anims) const { +	for (ANIList::iterator a = anims.begin(); a != anims.end(); ++a) +		delete *a; + +	anims.clear(); +} + +void PreGob::setAnim(ANIObject &anim, const AnimProperties &props) const { +	anim.setAnimation(props.animation); +	anim.setFrame(props.frame); +	anim.setMode(props.mode); +	anim.setPause(props.paused); +	anim.setVisible(props.visible); + +	if (props.hasPosition) +		anim.setPosition(props.x, props.y); +	else +		anim.setPosition();  }  Common::String PreGob::getLocFile(const Common::String &file) const { diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index e62a59042b..f1728036ab 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -27,6 +27,7 @@  #include "common/array.h"  #include "gob/util.h" +#include "gob/aniobject.h"  #include "gob/sound/sounddesc.h" @@ -37,8 +38,6 @@ namespace Gob {  class GobEngine;  class Surface; -class ANIObject; -  class PreGob {  public:  	PreGob(GobEngine *vm); @@ -46,7 +45,23 @@ public:  	virtual void run() = 0; +	struct AnimProperties { +		uint16 animation; +		uint16 frame; + +		ANIObject::Mode mode; + +		bool visible; +		bool paused; + +		bool hasPosition; +		int16 x; +		int16 y; +	}; +  protected: +	typedef Common::Array<ANIObject *> ANIList; +  	static const char  kLanguageSuffixShort[5];  	static const char *kLanguageSuffixLong [5]; @@ -88,11 +103,23 @@ protected:  	bool isCursorVisible() const;  	/** Remove an animation from the screen. */ -	void clearAnim(ANIObject &ani); +	void clearAnim(ANIObject &anim);  	/** Draw an animation to the screen, advancing it. */ -	void drawAnim(ANIObject &ani); +	void drawAnim(ANIObject &anim);  	/** Clear and draw an animation to the screen, advancing it. */ -	void redrawAnim(ANIObject &ani); +	void redrawAnim(ANIObject &anim); + +	/** Remove animations from the screen. */ +	void clearAnim(const ANIList &anims); +	/** Draw animations to the screen, advancing them. */ +	void drawAnim(const ANIList &anims); +	/** Clear and draw animations to the screen, advancing them. */ +	void redrawAnim(const ANIList &anims); + +	void loadAnims(ANIList &anims, ANIFile &ani, uint count, const AnimProperties *props) const; +	void freeAnims(ANIList &anims) const; + +	void setAnim(ANIObject &anim, const AnimProperties &props) const;  	/** Wait for the frame to end, handling screen updates and optionally update input. */  	void endFrame(bool doInput); | 
