aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock/scalpel
diff options
context:
space:
mode:
authorPaul Gilbert2015-04-21 01:12:16 -0500
committerPaul Gilbert2015-04-21 01:12:16 -0500
commit7e1e0ed3ac7ca8b3233503476162c1ca1e79e0a8 (patch)
tree8bea14a14a553ce5df7ce1c23d945ea79407ad12 /engines/sherlock/scalpel
parent6a1b12b797c51bdc51c71db67e2df4e8de6281e0 (diff)
downloadscummvm-rg350-7e1e0ed3ac7ca8b3233503476162c1ca1e79e0a8.tar.gz
scummvm-rg350-7e1e0ed3ac7ca8b3233503476162c1ca1e79e0a8.tar.bz2
scummvm-rg350-7e1e0ed3ac7ca8b3233503476162c1ca1e79e0a8.zip
SHERLOCK: More darts game logic
Diffstat (limited to 'engines/sherlock/scalpel')
-rw-r--r--engines/sherlock/scalpel/darts.cpp203
-rw-r--r--engines/sherlock/scalpel/darts.h6
2 files changed, 193 insertions, 16 deletions
diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp
index c975cb1086..c3f2c478d7 100644
--- a/engines/sherlock/scalpel/darts.cpp
+++ b/engines/sherlock/scalpel/darts.cpp
@@ -67,6 +67,7 @@ Darts::Darts(ScalpelEngine *vm) : _vm(vm) {
* Main method for playing darts game
*/
void Darts::playDarts() {
+ Events &events = *_vm->_events;
Screen &screen = *_vm->_screen;
int score, roundStartScore;
int playerNumber = 0;
@@ -79,6 +80,7 @@ void Darts::playDarts() {
loadDarts();
initDarts();
+ bool done = false;
do {
roundStartScore = score = playerNumber == 0 ? _dartScore1 : _dartScore2;
@@ -99,13 +101,81 @@ void Darts::playDarts() {
score -= lastDart;
_roundScore += lastDart;
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1),
+ Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y), DART_COL_FORE, "Dart # %d", idx + 1);
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 10), DART_COL_FORE, "Scored %d points", lastDart);
+
+ if (score != 0 && playerNumber == 0)
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 30), DART_COL_FORE, "Press a key");
+
+ if (score == 0) {
+ // Some-one has won
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 20), PLAYER_COLOR, "GAME OVER!");
+
+ if (playerNumber == 0) {
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 30), PLAYER_COLOR, "Holmes Wins!");
+ if (_level < 4)
+ setFlagsForDarts(318 + _level);
+ } else {
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 30), PLAYER_COLOR, "%s Wins!", _opponent.c_str());
+ }
+
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 4), DART_COL_FORE, "Press a key");
+
+ idx = 10;
+ done = true;
+ } else if (score < 0) {
+ screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 20), PLAYER_COLOR, "BUSTED!");
+
+ idx = 10;
+ score = roundStartScore;
+ }
+
+ if (playerNumber == 0)
+ _dartScore1 = score;
+ else
+ _dartScore2 = score;
+
+ showStatus(playerNumber);
+ events.clearKeyboard();
+ if ((playerNumber == 0 && _computerPlayer == 1) || _computerPlayer == 0 || done) {
+ int dartKey;
+ while (!(dartKey = dartHit()) && !_vm->shouldQuit())
+ events.delay(10);
+
+ if (dartKey == Common::KEYCODE_ESCAPE) {
+ idx = 10;
+ done = true;
+ }
+ } else {
+ events.wait(20);
+ }
+
+ screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1),
+ Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
}
- // todo
- } while (!_vm->shouldQuit());
+ playerNumber ^= 1;
+ if (!playerNumber)
+ ++_roundNumber;
+
+ done |= _vm->shouldQuit();
- // TODO
+ if (!done) {
+ screen._backBuffer2.blitFrom((*_dartImages)[1], Common::Point(0, 0));
+ screen._backBuffer1.blitFrom(screen._backBuffer2);
+ screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
+ }
+ } while (!done);
+
+ closeDarts();
+ screen.fadeToBlack();
+
+ // Restore font
+ screen.setFont(oldFont);
}
/**
@@ -145,6 +215,14 @@ void Darts::initDarts() {
}
/**
+ * Frees the images used by the dart game
+ */
+void Darts::closeDarts() {
+ delete _dartImages;
+ _dartImages = nullptr;
+}
+
+/**
* Show the player names
*/
void Darts::showNames(int playerNum) {
@@ -236,8 +314,8 @@ int Darts::throwDart(int dartNum, int computer) {
if (computer)
targetNum = getComputerDartDest(computer - 1);
- width = doPowerBar(Common::Point(DARTBARHX, DARTHORIZY), DART_BAR_FORE, targetNum.x, 0);
- height = 101 - doPowerBar(Common::Point(DARTBARVX, DARTHEIGHTY), DART_BAR_FORE, targetNum.y, 0);
+ width = doPowerBar(Common::Point(DARTBARHX, DARTHORIZY), DART_BAR_FORE, targetNum.x, false);
+ height = 101 - doPowerBar(Common::Point(DARTBARVX, DARTHEIGHTY), DART_BAR_FORE, targetNum.y, true);
// For human players, slight y adjustment
if (computer == 0)
@@ -263,7 +341,43 @@ int Darts::throwDart(int dartNum, int computer) {
* Draw a dart moving towards the board
*/
void Darts::drawDartThrow(const Common::Point &pt) {
- // TODO
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ Common::Point pos(pt.x, pt.y + 2);
+ Common::Rect oldDrawBounds;
+ int delta = 9;
+
+ for (int idx = 5; idx < 24; ++idx) {
+ Graphics::Surface &frame = (*_dartImages)[idx]._frame;
+
+ // Adjust draw position for animating dart
+ if (idx < 14)
+ pos.y -= delta--;
+ else if (idx == 14)
+ delta = 1;
+ else
+ pos.y += delta++;
+
+ // Draw the dart
+ Common::Point drawPos(pos.x - frame.w / 2, pos.y - frame.h);
+ screen._backBuffer1.transBlitFrom(frame, drawPos);
+ screen.slamArea(drawPos.x, drawPos.y, frame.w, frame.h);
+
+ // Handle erasing old dart
+ if (!oldDrawBounds.isEmpty())
+ screen.slamRect(oldDrawBounds);
+
+ oldDrawBounds = Common::Rect(drawPos.x, drawPos.y, drawPos.x + frame.w, drawPos.y + frame.h);
+ if (idx != 23)
+ screen._backBuffer1.blitFrom(screen._backBuffer2, drawPos, oldDrawBounds);
+
+ events.wait(2);
+ }
+
+ // Draw dart in final "stuck to board" form
+ screen._backBuffer1.transBlitFrom((*_dartImages)[23], Common::Point(oldDrawBounds.left, oldDrawBounds.top));
+ screen._backBuffer2.transBlitFrom((*_dartImages)[23], Common::Point(oldDrawBounds.left, oldDrawBounds.top));
+ screen.slamRect(oldDrawBounds);
}
/**
@@ -285,32 +399,86 @@ void Darts::erasePowerBars() {
* increment to that power level ignoring all keyboard input (ie. for computer throws).
* Otherwise, it will increment until either a key/mouse button is pressed, or it reaches the end
*/
-int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, int orientation) {
- // TODO
- return 0;
+int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical) {
+ Events &events = *_vm->_events;
+ Screen &screen = *_vm->_screen;
+ Sound &sound = *_vm->_sound;
+ bool done;
+ int idx = 0;
+
+ events.clearEvents();
+ if (sound._musicOn)
+ sound.waitTimerRoland(10);
+ else
+ events.delay(100);
+
+ // Display loop
+ do {
+ done = _vm->shouldQuit() || idx >= DARTBARSIZE;
+
+ if (idx == (goToPower - 1))
+ // Reached target power for a computer player
+ done = true;
+ else if (goToPower == 0) {
+ // Check for pres
+ if (dartHit())
+ done = true;
+ }
+
+ if (isVertical) {
+ screen._backBuffer1.hLine(pt.x, pt.y + DARTBARSIZE - 1 - idx, pt.x + 8, color);
+ screen._backBuffer1.transBlitFrom((*_dartImages)[4], Common::Point(pt.x - 1, pt.y - 1));
+ screen.slamArea(pt.x, pt.y + DARTBARSIZE - 1 - idx, 8, 2);
+ } else {
+ screen._backBuffer1.vLine(pt.x + idx, pt.y, pt.y + 8, color);
+ screen._backBuffer1.transBlitFrom((*_dartImages)[3], Common::Point(pt.x - 1, pt.y - 1));
+ screen.slamArea(pt.x + idx, pt.y, 1, 8);
+ }
+
+ if (sound._musicOn) {
+ if (!(idx % 3))
+ sound.waitTimerRoland(1);
+ } else {
+ if (!(idx % 8))
+ events.wait(1);
+ }
+
+ ++idx;
+ } while (!done);
+
+ return MIN(idx * 100 / DARTBARSIZE, 100);
}
/**
* Returns true if a mouse button or key is pressed.
*/
-bool Darts::dartHit() {
+int Darts::dartHit() {
Events &events = *_vm->_events;
if (events.kbHit()) {
+ Common::KeyState keyState = events.getKey();
+
events.clearKeyboard();
- return true;
+ return keyState.keycode;
}
events.setButtonState();
- return events._pressed && !_oldDartButtons;
+ return events._pressed && !_oldDartButtons ? 1 : 0;
}
/**
* Return the score of the given location on the dart-board
*/
int Darts::dartScore(const Common::Point &pt) {
- // TODO
- return 0;
+ Common::Point pos(pt.x - 37, pt.y - 33);
+
+ if (pos.x < 0 || pos.y < 0 || pos.x >= 147 || pt.y >= 132)
+ // Not on the board
+ return 0;
+
+ // On board, so get the score from the pixel at that position
+ int score = *(const byte *)(*_dartImages)[2]._frame.getBasePtr(pos.x, pos.y);
+ return score;
}
/**
@@ -415,6 +583,13 @@ bool Darts::findNumberOnBoard(int aim, Common::Point &pt) {
return done;
}
+/**
+ * Set a global flag to 0 or 1 depending on whether the passed flag is negative or positive.
+ * @remarks We don't use the global setFlags method because we don't want to check scene flags
+ */
+void Darts::setFlagsForDarts(int flagNum) {
+ _vm->_flags[ABS(flagNum)] = flagNum >= 0;
+}
} // End of namespace Scalpel
diff --git a/engines/sherlock/scalpel/darts.h b/engines/sherlock/scalpel/darts.h
index 2fbdc3d7e2..a6c8cdba6d 100644
--- a/engines/sherlock/scalpel/darts.h
+++ b/engines/sherlock/scalpel/darts.h
@@ -46,6 +46,7 @@ private:
void loadDarts();
void initDarts();
+ void closeDarts();
void showNames(int playerNum);
void showStatus(int playerNum);
@@ -54,15 +55,16 @@ private:
void drawDartThrow(const Common::Point &pt);
void erasePowerBars();
- int doPowerBar(const Common::Point &pt, byte color, int goToPower, int orientation);
+ int doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical);
- bool dartHit();
+ int dartHit();
int dartScore(const Common::Point &pt);
Common::Point getComputerDartDest(int playerNum);
bool findNumberOnBoard(int aim, Common::Point &pt);
+ void setFlagsForDarts(int flagNum);
public:
Darts(ScalpelEngine *vm);