diff options
author | Paul Gilbert | 2015-04-21 01:12:16 -0500 |
---|---|---|
committer | Paul Gilbert | 2015-04-21 01:12:16 -0500 |
commit | 7e1e0ed3ac7ca8b3233503476162c1ca1e79e0a8 (patch) | |
tree | 8bea14a14a553ce5df7ce1c23d945ea79407ad12 /engines/sherlock/scalpel | |
parent | 6a1b12b797c51bdc51c71db67e2df4e8de6281e0 (diff) | |
download | scummvm-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.cpp | 203 | ||||
-rw-r--r-- | engines/sherlock/scalpel/darts.h | 6 |
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); |