From 9d348f46ad1a7729661867564d4e8ed254244710 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 27 Jan 2012 14:27:16 +0100 Subject: GOB: Add a controlable Oko to Geisha's Diving minigame Still missing: - Air, constantly decreasing, fill up with breathing - Health, decreases by collision with evil fish - Death, when health == 0 - Picking up pearls --- engines/gob/minigames/geisha/diving.cpp | 42 ++++++++++-- engines/gob/minigames/geisha/diving.h | 5 +- engines/gob/minigames/geisha/oko.cpp | 117 ++++++++++++++++++++++++++++++++ engines/gob/minigames/geisha/oko.h | 66 ++++++++++++++++++ engines/gob/module.mk | 1 + 5 files changed, 226 insertions(+), 5 deletions(-) create mode 100644 engines/gob/minigames/geisha/oko.cpp create mode 100644 engines/gob/minigames/geisha/oko.h diff --git a/engines/gob/minigames/geisha/diving.cpp b/engines/gob/minigames/geisha/diving.cpp index 556d54e516..1f5c025f2d 100644 --- a/engines/gob/minigames/geisha/diving.cpp +++ b/engines/gob/minigames/geisha/diving.cpp @@ -31,6 +31,7 @@ #include "gob/sound/sound.h" #include "gob/minigames/geisha/evilfish.h" +#include "gob/minigames/geisha/oko.h" #include "gob/minigames/geisha/diving.h" namespace Gob { @@ -55,10 +56,26 @@ const Diving::PlantLevel Diving::kPlantLevels[] = { Diving::Diving(GobEngine *vm) : _vm(vm), _background(0), - _objects(0), _gui(0), _oko(0), _lungs(0), _heart(0), + _objects(0), _gui(0), _okoAnim(0), _lungs(0), _heart(0), _blackPearl(0), _whitePearlCount(0), _blackPearlCount(0) { _blackPearl = new Surface(11, 8, 1); + + for (uint i = 0; i < kEvilFishCount; i++) + _evilFish[i].evilFish = 0; + + for (uint i = 0; i < kDecorFishCount; i++) + _decorFish[i].decorFish = 0; + + for (uint i = 0; i < kPlantCount; i++) + _plant[i].plant = 0; + + for (uint i = 0; i < kMaxShotCount; i++) + _shot[i] = 0; + + _pearl.pearl = 0; + + _oko = 0; } Diving::~Diving() { @@ -103,6 +120,11 @@ bool Diving::play(uint16 playerCount, bool hasPearlLocation) { if (mouseButtons == kMouseButtonsLeft) shoot(mouseX, mouseY); + if (key == kKeyDown) + _oko->sink(); + else if (key == kKeyUp) + _oko->raise(); + if ((_whitePearlCount >= 20) || (_blackPearlCount >= 2)) break; } @@ -115,7 +137,7 @@ void Diving::init() { _background = new DECFile(_vm, "tperle.dec" , 320, 200); _objects = new ANIFile(_vm, "tperle.ani" , 320); _gui = new ANIFile(_vm, "tperlcpt.ani", 320); - _oko = new ANIFile(_vm, "tplonge.ani" , 320); + _okoAnim = new ANIFile(_vm, "tplonge.ani" , 320); _water = new ANIObject(*_objects); _lungs = new ANIObject(*_gui); @@ -179,6 +201,8 @@ void Diving::init() { _shot[i]->setMode(ANIObject::kModeOnce); } + _oko = new Oko(*_okoAnim); + Surface tmp(320, 103, 1); _vm->_video->drawPackedSprite("tperlobj.cmp", tmp); @@ -199,6 +223,7 @@ void Diving::init() { _anims.push_back(_evilFish[i].evilFish); for (int i = kPlantCount - 1; i >= 0; i--) _anims.push_back(_plant[i].plant); + _anims.push_back(_oko); _anims.push_back(_lungs); _anims.push_back(_heart); @@ -248,11 +273,14 @@ void Diving::deinit() { delete _pearl.pearl; _pearl.pearl = 0; + delete _oko; + _oko = 0; + delete _heart; delete _lungs; delete _water; - delete _oko; + delete _okoAnim; delete _gui; delete _objects; delete _background; @@ -261,7 +289,7 @@ void Diving::deinit() { _heart = 0; _lungs = 0; - _oko = 0; + _okoAnim = 0; _gui = 0; _objects = 0; _background = 0; @@ -426,6 +454,9 @@ void Diving::updateDecorFish() { } void Diving::updatePlants() { + if (_oko->getState() == Oko::kStateBreathe) + return; + for (uint i = 0; i < kPlantCount; i++) { ManagedPlant &plant = _plant[i]; @@ -461,6 +492,9 @@ void Diving::updatePearl() { if (!_pearl.pearl->isVisible()) return; + if (_oko->getState() == Oko::kStateBreathe) + return; + // Move the pearl int16 x, y, width, height; _pearl.pearl->getPosition(x, y); diff --git a/engines/gob/minigames/geisha/diving.h b/engines/gob/minigames/geisha/diving.h index ee2f8d8451..eeee4df07c 100644 --- a/engines/gob/minigames/geisha/diving.h +++ b/engines/gob/minigames/geisha/diving.h @@ -40,6 +40,7 @@ class ANIObject; namespace Geisha { class EvilFish; +class Oko; /** Geisha's "Diving" minigame. */ class Diving { @@ -107,7 +108,7 @@ private: DECFile *_background; ANIFile *_objects; ANIFile *_gui; - ANIFile *_oko; + ANIFile *_okoAnim; ANIObject *_water; ANIObject *_lungs; @@ -118,6 +119,8 @@ private: ManagedPlant _plant[kPlantCount]; ManagedPearl _pearl; + Oko *_oko; + ANIObject *_shot[kMaxShotCount]; Common::List _activeShots; diff --git a/engines/gob/minigames/geisha/oko.cpp b/engines/gob/minigames/geisha/oko.cpp new file mode 100644 index 0000000000..24a6c8053e --- /dev/null +++ b/engines/gob/minigames/geisha/oko.cpp @@ -0,0 +1,117 @@ +/* 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 "gob/minigames/geisha/oko.h" + +namespace Gob { + +namespace Geisha { + +enum kOkoAnimation { + kOkoAnimationEnter = 0, + kOkoAnimationSwim = 1, + kOkoAnimationSink = 8, + kOkoAnimationRaise = 7, + kOkoAnimationBreathe = 2 +}; + +static const int16 kOkoPositionX = 110; + +static const uint kLevelCount = 3; +static const int16 kLevelPositionX[kLevelCount] = { 44, 84, 124 }; + + +Oko::Oko(const ANIFile &ani) : ANIObject(ani), _state(kStateEnter), _level(0) { + setAnimation(kOkoAnimationEnter); + setVisible(true); +} + +Oko::~Oko() { +} + +void Oko::advance() { + bool wasLastFrame = lastFrame(); + + ANIObject::advance(); + + switch (_state) { + case kStateEnter: + if (wasLastFrame) { + setAnimation(kOkoAnimationSwim); + setPosition(kOkoPositionX, kLevelPositionX[_level]); + _state = kStateSwim; + } + break; + + case kStateSink: + case kStateRaise: + case kStateBreathe: + if (wasLastFrame) { + setAnimation(kOkoAnimationSwim); + setPosition(kOkoPositionX, kLevelPositionX[_level]); + _state = kStateSwim; + } + break; + + default: + break; + } +} + +void Oko::sink() { + if (_state != kStateSwim) + return; + + if (_level >= (kLevelCount - 1)) + return; + + setAnimation(kOkoAnimationSink); + setPosition(kOkoPositionX, kLevelPositionX[_level]); + _state = kStateSink; + + _level++; +} + +void Oko::raise() { + if (_state != kStateSwim) + return; + + if (_level == 0) { + setAnimation(kOkoAnimationBreathe); + _state = kStateBreathe; + return; + } + + setAnimation(kOkoAnimationRaise); + setPosition(kOkoPositionX, kLevelPositionX[_level]); + _state = kStateSink; + + _level--; +} + +Oko::State Oko::getState() const { + return _state; +} + +} // End of namespace Geisha + +} // End of namespace Gob diff --git a/engines/gob/minigames/geisha/oko.h b/engines/gob/minigames/geisha/oko.h new file mode 100644 index 0000000000..7e56315c9c --- /dev/null +++ b/engines/gob/minigames/geisha/oko.h @@ -0,0 +1,66 @@ +/* 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. + * + */ + +#ifndef GOB_MINIGAMES_GEISHA_OKO_H +#define GOB_MINIGAMES_GEISHA_OKO_H + +#include "gob/aniobject.h" + +namespace Gob { + +namespace Geisha { + +/** Oko, the person you control, in Geisha's "Diving" minigame. */ +class Oko : public ANIObject { +public: + enum State { + kStateEnter, + kStateSwim, + kStateSink, + kStateRaise, + kStateBreathe + }; + + Oko(const ANIFile &ani); + ~Oko(); + + /** Advance the animation to the next frame. */ + void advance(); + + /** Oko should sink a level. */ + void sink(); + /** Oko should raise a level. */ + void raise(); + + State getState() const; + +private: + State _state; + + uint8 _level; +}; + +} // End of namespace Geisha + +} // End of namespace Gob + +#endif // GOB_MINIGAMES_GEISHA_OKO_H diff --git a/engines/gob/module.mk b/engines/gob/module.mk index bf040c5428..6adf99f669 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -74,6 +74,7 @@ MODULE_OBJS := \ demos/scnplayer.o \ demos/batplayer.o \ minigames/geisha/evilfish.o \ + minigames/geisha/oko.o \ minigames/geisha/diving.o \ minigames/geisha/penetration.o \ save/savefile.o \ -- cgit v1.2.3