aboutsummaryrefslogtreecommitdiff
path: root/engines/gob
diff options
context:
space:
mode:
authorSven Hesse2011-09-12 18:00:22 +0200
committerSven Hesse2011-09-14 18:54:28 +0200
commit5caf4ac4003180bcbf897d6bfa1812eba8d5e76c (patch)
tree626dc716bf4f4438e3b1d5721c7b829372c5eeda /engines/gob
parente21b1af568fd255da8b2a1d45b42b9d9cb170eb4 (diff)
downloadscummvm-rg350-5caf4ac4003180bcbf897d6bfa1812eba8d5e76c.tar.gz
scummvm-rg350-5caf4ac4003180bcbf897d6bfa1812eba8d5e76c.tar.bz2
scummvm-rg350-5caf4ac4003180bcbf897d6bfa1812eba8d5e76c.zip
GOB: Implement the fish shooting part of the Diving minigame
Diffstat (limited to 'engines/gob')
-rw-r--r--engines/gob/minigames/geisha/diving.cpp167
-rw-r--r--engines/gob/minigames/geisha/diving.h26
-rw-r--r--engines/gob/minigames/geisha/evilfish.h4
3 files changed, 166 insertions, 31 deletions
diff --git a/engines/gob/minigames/geisha/diving.cpp b/engines/gob/minigames/geisha/diving.cpp
index f0eae3219c..355edd7f88 100644
--- a/engines/gob/minigames/geisha/diving.cpp
+++ b/engines/gob/minigames/geisha/diving.cpp
@@ -57,37 +57,12 @@ bool Diving::play(uint16 playerCount, bool hasPearlLocation) {
_vm->_draw->blitInvalidated();
_vm->_video->retrace();
- EvilFish shark(*_objects, 320, 0, 14, 8, 9, 3);
+ while (!_vm->shouldQuit()) {
+ evilFishEnter();
- Common::List<ANIObject *> objects;
+ checkShots();
- objects.push_back(_water);
- objects.push_back(&shark);
- objects.push_back(_lungs);
- objects.push_back(_heart);
-
- shark.enter(EvilFish::kDirectionLeft, 90);
-
- while (!_vm->_util->keyPressed() && !_vm->shouldQuit()) {
- int16 left, top, right, bottom;
-
- // Clear the previous animation frames
- for (Common::List<ANIObject *>::iterator o = objects.reverse_begin();
- o != objects.end(); --o) {
-
- (*o)->clear(*_vm->_draw->_backSurface, left, top, right, bottom);
- _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
- }
-
- // Draw the current animation frames
- for (Common::List<ANIObject *>::iterator o = objects.begin();
- o != objects.end(); ++o) {
-
- (*o)->draw(*_vm->_draw->_backSurface, left, top, right, bottom);
- _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
-
- (*o)->advance();
- }
+ updateAnims();
_vm->_draw->animateCursor(1);
@@ -96,6 +71,16 @@ bool Diving::play(uint16 playerCount, bool hasPearlLocation) {
_vm->_util->waitEndFrame();
_vm->_util->processInput();
+ int16 mouseX, mouseY;
+ MouseButtons mouseButtons;
+
+ int16 key = checkInput(mouseX, mouseY, mouseButtons);
+ if (key == kKeyEscape)
+ break;
+
+ if (mouseButtons == kMouseButtonsLeft)
+ shoot(mouseX, mouseY);
+
if ((_whitePearlCount >= 20) || (_blackPearlCount >= 2))
break;
}
@@ -128,6 +113,17 @@ void Diving::init() {
_heart->setVisible(true);
_heart->setPause(true);
+ _evilFish[0] = new EvilFish(*_objects, 320, 0, 14, 8, 9, 3); // Shark
+ _evilFish[1] = new EvilFish(*_objects, 320, 15, 1, 12, 13, 3); // Moray
+ _evilFish[2] = new EvilFish(*_objects, 320, 16, 2, 10, 11, 3); // Ray
+
+ for (uint i = 0; i < kMaxShotCount; i++) {
+ _shot[i] = new ANIObject(*_objects);
+
+ _shot[i]->setAnimation(17);
+ _shot[i]->setMode(ANIObject::kModeOnce);
+ }
+
Surface tmp(320, 103, 1);
_vm->_video->drawPackedSprite("tperlobj.cmp", tmp);
@@ -135,12 +131,38 @@ void Diving::init() {
_blackPearl->blit(tmp, 282, 80, 292, 87, 0, 0);
_blackPearlCount = 0;
+
+ _currentShot = 0;
+
+ _anims.push_back(_water);
+ for (uint i = 0; i < kMaxShotCount; i++)
+ _anims.push_back(_shot[i]);
+ for (uint i = 0; i < kEvilFishCount; i++)
+ _anims.push_back(_evilFish[i]);
+ _anims.push_back(_lungs);
+ _anims.push_back(_heart);
}
void Diving::deinit() {
_vm->_draw->_cursorHotspotX = -1;
_vm->_draw->_cursorHotspotY = -1;
+ _anims.clear();
+
+ _activeShots.clear();
+
+ for (uint i = 0; i < kMaxShotCount; i++) {
+ delete _shot[i];
+
+ _shot[i] = 0;
+ }
+
+ for (uint i = 0; i < kEvilFishCount; i++) {
+ delete _evilFish[i];
+
+ _evilFish[i] = 0;
+ }
+
delete _heart;
delete _lungs;
delete _water;
@@ -192,6 +214,17 @@ void Diving::initCursor() {
_vm->_draw->_cursorHotspotY = 8;
}
+void Diving::evilFishEnter() {
+ for (uint i = 0; i < kEvilFishCount; i++) {
+ EvilFish &fish = *_evilFish[i];
+
+ if (fish.isVisible())
+ continue;
+
+ fish.enter((EvilFish::Direction)_vm->_util->getRandom(2), 90 + i * 20);
+ }
+}
+
void Diving::foundBlackPearl() {
_blackPearlCount++;
@@ -215,6 +248,82 @@ void Diving::foundWhitePearl() {
_vm->_draw->dirtiedRect(_vm->_draw->_backSurface, x, 177, x + 3, 180);
}
+void Diving::updateAnims() {
+ int16 left, top, right, bottom;
+
+ // Clear the previous animation frames
+ for (Common::List<ANIObject *>::iterator a = _anims.reverse_begin();
+ a != _anims.end(); --a) {
+
+ (*a)->clear(*_vm->_draw->_backSurface, left, top, right, bottom);
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
+ }
+
+ // Draw the current animation frames
+ for (Common::List<ANIObject *>::iterator a = _anims.begin();
+ a != _anims.end(); ++a) {
+
+ (*a)->draw(*_vm->_draw->_backSurface, left, top, right, bottom);
+ _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom);
+
+ (*a)->advance();
+ }
+}
+
+int16 Diving::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons) {
+ _vm->_util->getMouseState(&mouseX, &mouseY, &mouseButtons);
+
+ return _vm->_util->checkKey();
+}
+
+void Diving::shoot(int16 mouseX, int16 mouseY) {
+ // Outside the playable area?
+ if (mouseY > 157)
+ return;
+
+ // Too many shots still active?
+ if (_activeShots.size() >= kMaxShotCount)
+ return;
+
+ ANIObject &shot = *_shot[_currentShot];
+
+ shot.rewind();
+ shot.setVisible(true);
+ shot.setPause(false);
+ shot.setPosition(mouseX - 8, mouseY - 8);
+
+ _activeShots.push_back(_currentShot);
+
+ _currentShot = (_currentShot + 1) % kMaxShotCount;
+}
+
+void Diving::checkShots() {
+ Common::List<int>::iterator activeShot = _activeShots.begin();
+
+ while (activeShot != _activeShots.end()) {
+ ANIObject &shot = *_shot[*activeShot];
+
+ if (shot.lastFrame()) {
+ int16 x, y;
+
+ shot.getPosition(x, y);
+
+ for (uint i = 0; i < kEvilFishCount; i++) {
+ EvilFish &evilFish = *_evilFish[i];
+
+ if (evilFish.isIn(x + 8, y + 8)) {
+ evilFish.die();
+
+ break;
+ }
+ }
+
+ activeShot = _activeShots.erase(activeShot);
+ } else
+ ++activeShot;
+ }
+}
+
} // End of namespace Geisha
} // End of namespace Gob
diff --git a/engines/gob/minigames/geisha/diving.h b/engines/gob/minigames/geisha/diving.h
index 023ac919a7..dd0773a9c4 100644
--- a/engines/gob/minigames/geisha/diving.h
+++ b/engines/gob/minigames/geisha/diving.h
@@ -33,8 +33,12 @@ class DECFile;
class ANIFile;
class ANIObject;
+enum MouseButtons;
+
namespace Geisha {
+class EvilFish;
+
/** Geisha's "Diving" minigame. */
class Diving {
public:
@@ -44,6 +48,9 @@ public:
bool play(uint16 playerCount, bool hasPearlLocation);
private:
+ static const uint kEvilFishCount = 3;
+ static const uint kMaxShotCount = 10;
+
GobEngine *_vm;
DECFile *_background;
@@ -55,19 +62,38 @@ private:
ANIObject *_lungs;
ANIObject *_heart;
+ EvilFish *_evilFish[kEvilFishCount];
+
+ ANIObject *_shot[kMaxShotCount];
+
+ Common::List<int> _activeShots;
+
+ Common::List<ANIObject *> _anims;
+
Surface *_blackPearl;
uint8 _whitePearlCount;
uint8 _blackPearlCount;
+ uint8 _currentShot;
+
void init();
void deinit();
void initScreen();
void initCursor();
+ void evilFishEnter();
+
void foundBlackPearl();
void foundWhitePearl();
+
+ void updateAnims();
+
+ int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons);
+
+ void shoot(int16 mouseX, int16 mouseY);
+ void checkShots();
};
} // End of namespace Geisha
diff --git a/engines/gob/minigames/geisha/evilfish.h b/engines/gob/minigames/geisha/evilfish.h
index 9144cefb4b..1801ad9b16 100644
--- a/engines/gob/minigames/geisha/evilfish.h
+++ b/engines/gob/minigames/geisha/evilfish.h
@@ -33,8 +33,8 @@ namespace Geisha {
class EvilFish : public ANIObject {
public:
enum Direction {
- kDirectionLeft,
- kDirectionRight
+ kDirectionLeft = 0,
+ kDirectionRight = 1
};
EvilFish(const ANIFile &ani, uint16 screenWidth,