From b2e98f4f52341c049df90d3410ff05f806bf1100 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 6 Aug 2015 20:40:20 -0400 Subject: SHERLOCK: SS: Renamed darts.cpp to scalpel_darts.cpp --- engines/sherlock/module.mk | 2 +- engines/sherlock/scalpel/darts.cpp | 553 ----------------------------- engines/sherlock/scalpel/darts.h | 130 ------- engines/sherlock/scalpel/scalpel.h | 2 +- engines/sherlock/scalpel/scalpel_darts.cpp | 553 +++++++++++++++++++++++++++++ engines/sherlock/scalpel/scalpel_darts.h | 130 +++++++ 6 files changed, 685 insertions(+), 685 deletions(-) delete mode 100644 engines/sherlock/scalpel/darts.cpp delete mode 100644 engines/sherlock/scalpel/darts.h create mode 100644 engines/sherlock/scalpel/scalpel_darts.cpp create mode 100644 engines/sherlock/scalpel/scalpel_darts.h (limited to 'engines') diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index e58a2a1e81..9e3fde0e78 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -1,13 +1,13 @@ MODULE := engines/sherlock MODULE_OBJS = \ - scalpel/darts.o \ scalpel/scalpel.o \ scalpel/3do/movie_decoder.o \ scalpel/drivers/adlib.o \ scalpel/drivers/mt32.o \ scalpel/tsage/logo.o \ scalpel/tsage/resources.o \ + scalpel/scalpel_darts.o \ scalpel/scalpel_debugger.o \ scalpel/scalpel_fixed_text.o \ scalpel/scalpel_inventory.o \ diff --git a/engines/sherlock/scalpel/darts.cpp b/engines/sherlock/scalpel/darts.cpp deleted file mode 100644 index 8b5d02fb9c..0000000000 --- a/engines/sherlock/scalpel/darts.cpp +++ /dev/null @@ -1,553 +0,0 @@ -/* 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 "sherlock/scalpel/darts.h" -#include "sherlock/scalpel/scalpel.h" - -namespace Sherlock { - -namespace Scalpel { - -enum { - STATUS_INFO_X = 218, - STATUS_INFO_Y = 53, - DART_INFO_X = 218, - DART_INFO_Y = 103, - DARTBARHX = 35, - DARTHORIZY = 190, - DARTBARVX = 1, - DARTHEIGHTY = 25, - DARTBARSIZE = 150, - DART_BAR_FORE = 8 -}; - -enum { - DART_COL_FORE = 5, - PLAYER_COLOR = 11 -}; -#define OPPONENTS_COUNT 4 - -const char *const OPPONENT_NAMES[OPPONENTS_COUNT] = { - "Skipper", "Willy", "Micky", "Tom" -}; - -/*----------------------------------------------------------------*/ - -Darts::Darts(ScalpelEngine *vm) : _vm(vm) { - _dartImages = nullptr; - _level = 0; - _computerPlayer = 1; - _playerDartMode = false; - _dartScore1 = _dartScore2 = 0; - _roundNumber = 0; - _playerDartMode = false; - _roundScore = 0; - _oldDartButtons = false; -} - -void Darts::playDarts() { - Events &events = *_vm->_events; - Screen &screen = *_vm->_screen; - int playerNumber = 0; - int lastDart; - - // Change the font - int oldFont = screen.fontNumber(); - screen.setFont(2); - - loadDarts(); - initDarts(); - - bool done = false; - do { - int score, roundStartScore; - roundStartScore = score = playerNumber == 0 ? _dartScore1 : _dartScore2; - - // Show player details - showNames(playerNumber); - showStatus(playerNumber); - _roundScore = 0; - - if (_vm->shouldQuit()) - return; - - for (int idx = 0; idx < 3; ++idx) { - // Throw a single dart - if (_computerPlayer == 1) - lastDart = throwDart(idx + 1, playerNumber * 2); - else if (_computerPlayer == 2) - lastDart = throwDart(idx + 1, playerNumber + 1); - else - lastDart = throwDart(idx + 1, 0); - - 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 < OPPONENTS_COUNT) - _vm->setFlagsDirect(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); - } - - playerNumber ^= 1; - if (!playerNumber) - ++_roundNumber; - - done |= _vm->shouldQuit(); - - if (!done) { - screen._backBuffer2.blitFrom((*_dartImages)[0], 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); -} - -void Darts::loadDarts() { - Screen &screen = *_vm->_screen; - - _dartImages = new ImageFile("darts.vgs"); - screen.setPalette(_dartImages->_palette); - - screen._backBuffer1.blitFrom((*_dartImages)[0], Common::Point(0, 0)); - screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); -} - -void Darts::initDarts() { - _dartScore1 = _dartScore2 = 301; - _roundNumber = 1; - - if (_level == 9) { - // No computer players - _computerPlayer = 0; - _level = 0; - } else if (_level == 8) { - _level = _vm->getRandomNumber(3); - _computerPlayer = 2; - } else { - // Check flags for opponents - for (int idx = 0; idx < OPPONENTS_COUNT; ++idx) { - if (_vm->readFlags(314 + idx)) - _level = idx; - } - } - - _opponent = OPPONENT_NAMES[_level]; -} - -void Darts::closeDarts() { - delete _dartImages; - _dartImages = nullptr; -} - -void Darts::showNames(int playerNum) { - Screen &screen = *_vm->_screen; - byte color = playerNum == 0 ? PLAYER_COLOR : DART_COL_FORE; - - // Print Holmes first - if (playerNum == 0) - screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y), PLAYER_COLOR + 3, "Holmes"); - else - screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y), color, "Holmes"); - - screen._backBuffer1.fillRect(Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, - STATUS_INFO_X + 31, STATUS_INFO_Y + 12), color); - screen.slamArea(STATUS_INFO_X, STATUS_INFO_Y + 10, 31, 12); - - // Second player - color = playerNum == 1 ? PLAYER_COLOR : DART_COL_FORE; - - if (playerNum != 0) - screen.print(Common::Point(STATUS_INFO_X + 50, STATUS_INFO_Y), PLAYER_COLOR + 3, - "%s", _opponent.c_str()); - else - screen.print(Common::Point(STATUS_INFO_X + 50, STATUS_INFO_Y), color, - "%s", _opponent.c_str()); - - screen._backBuffer1.fillRect(Common::Rect(STATUS_INFO_X + 50, STATUS_INFO_Y + 10, - STATUS_INFO_X + 81, STATUS_INFO_Y + 12), color); - screen.slamArea(STATUS_INFO_X + 50, STATUS_INFO_Y + 10, 81, 12); - - // Make a copy of the back buffer to the secondary one - screen._backBuffer2.blitFrom(screen._backBuffer1); -} - -void Darts::showStatus(int playerNum) { - Screen &screen = *_vm->_screen; - byte color; - - // Copy scoring screen from secondary back buffer. This will erase any previously displayed status/score info - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10), - Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, SHERLOCK_SCREEN_WIDTH, STATUS_INFO_Y + 48)); - - color = (playerNum == 0) ? PLAYER_COLOR : DART_COL_FORE; - screen.print(Common::Point(STATUS_INFO_X + 6, STATUS_INFO_Y + 13), color, "%d", _dartScore1); - - color = (playerNum == 1) ? PLAYER_COLOR : DART_COL_FORE; - screen.print(Common::Point(STATUS_INFO_X + 56, STATUS_INFO_Y + 13), color, "%d", _dartScore2); - screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 25), PLAYER_COLOR, "Round: %d", _roundNumber); - screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 35), PLAYER_COLOR, "Turn Total: %d", _roundScore); - screen.slamRect(Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, SHERLOCK_SCREEN_WIDTH, STATUS_INFO_Y + 48)); -} - -int Darts::throwDart(int dartNum, int computer) { - Events &events = *_vm->_events; - Screen &screen = *_vm->_screen; - Common::Point targetNum; - int width, height; - - events.clearKeyboard(); - - erasePowerBars(); - screen.print(Common::Point(DART_INFO_X, DART_INFO_Y), DART_COL_FORE, "Dart # %d", dartNum); - - if (!computer) { - screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 10), DART_COL_FORE, "Hit a key"); - screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 18), DART_COL_FORE, "to start"); - } - - if (!computer) { - while (!_vm->shouldQuit() && !dartHit()) - ; - } else { - events.delay(10); - } - - if (_vm->shouldQuit()) - return 0; - - 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.slamRect(Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); - - // If it's a computer player, choose a dart destination - if (computer) - targetNum = getComputerDartDest(computer - 1); - - 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) - height += 2; - - // Copy the bars to the secondary back buffer so that they remain fixed at their selected values - // whilst the dart is being animated at being thrown at the board - screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DARTBARHX - 1, DARTHORIZY - 1), - Common::Rect(DARTBARHX - 1, DARTHORIZY - 1, DARTBARHX + DARTBARSIZE + 3, DARTHORIZY + 10)); - screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1), - Common::Rect(DARTBARVX - 1, DARTHEIGHTY - 1, DARTBARVX + 11, DARTHEIGHTY + DARTBARSIZE + 3)); - - // Convert height and width to relative range of -50 to 50, where 0,0 is the exact centre of the board - height -= 50; - width -= 50; - - Common::Point dartPos(111 + width * 2, 99 + height * 2); - drawDartThrow(dartPos); - - return dartScore(dartPos); -} - -void Darts::drawDartThrow(const Common::Point &pt) { - 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 = 4; idx < 23; ++idx) { - ImageFrame &frame = (*_dartImages)[idx]; - - // Adjust draw position for animating dart - if (idx < 13) - pos.y -= delta--; - else if (idx == 13) - delta = 1; - else - pos.y += delta++; - - // Draw the dart - Common::Point drawPos(pos.x - frame._width / 2, pos.y - frame._height); - screen._backBuffer1.transBlitFrom(frame, drawPos); - screen.slamArea(drawPos.x, drawPos.y, frame._width, frame._height); - - // Handle erasing old dart frame area - if (!oldDrawBounds.isEmpty()) - screen.slamRect(oldDrawBounds); - - oldDrawBounds = Common::Rect(drawPos.x, drawPos.y, drawPos.x + frame._width, drawPos.y + frame._height); - screen._backBuffer1.blitFrom(screen._backBuffer2, drawPos, oldDrawBounds); - - events.wait(2); - } - - // Draw dart in final "stuck to board" form - screen._backBuffer1.transBlitFrom((*_dartImages)[22], Common::Point(oldDrawBounds.left, oldDrawBounds.top)); - screen._backBuffer2.transBlitFrom((*_dartImages)[22], Common::Point(oldDrawBounds.left, oldDrawBounds.top)); - screen.slamRect(oldDrawBounds); -} - -void Darts::erasePowerBars() { - Screen &screen = *_vm->_screen; - - screen._backBuffer1.fillRect(Common::Rect(DARTBARHX, DARTHORIZY, DARTBARHX + DARTBARSIZE, DARTHORIZY + 10), BLACK); - screen._backBuffer1.fillRect(Common::Rect(DARTBARVX, DARTHEIGHTY, DARTBARVX + 10, DARTHEIGHTY + DARTBARSIZE), BLACK); - screen._backBuffer1.transBlitFrom((*_dartImages)[2], Common::Point(DARTBARHX - 1, DARTHORIZY - 1)); - screen._backBuffer1.transBlitFrom((*_dartImages)[3], Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1)); - screen.slamArea(DARTBARHX - 1, DARTHORIZY - 1, DARTBARSIZE + 3, 11); - screen.slamArea(DARTBARVX - 1, DARTHEIGHTY - 1, 11, DARTBARSIZE + 3); -} - -int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical) { - Events &events = *_vm->_events; - Screen &screen = *_vm->_screen; - Music &music = *_vm->_music; - bool done; - int idx = 0; - - events.clearEvents(); - if (music._musicOn) - music.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)[3], 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)[2], Common::Point(pt.x - 1, pt.y - 1)); - screen.slamArea(pt.x + idx, pt.y, 1, 8); - } - - if (music._musicOn) { - if (!(idx % 3)) - music.waitTimerRoland(1); - } else if (!(idx % 8)) - events.wait(1); - - ++idx; - } while (!done); - - return MIN(idx * 100 / DARTBARSIZE, 100); -} - -int Darts::dartHit() { - Events &events = *_vm->_events; - - // Process pending events - events.pollEventsAndWait(); - - if (events.kbHit()) { - // Key was pressed, so return it - Common::KeyState keyState = events.getKey(); - return keyState.keycode; - } - - _oldDartButtons = events._pressed; - events.setButtonState(); - - // Only return true if the mouse button is newly pressed - return (events._pressed && !_oldDartButtons) ? 1 : 0; -} - -int Darts::dartScore(const Common::Point &pt) { - Common::Point pos(pt.x - 37, pt.y - 33); - Graphics::Surface &scoreImg = (*_dartImages)[1]._frame; - - if (pos.x < 0 || pos.y < 0 || pos.x >= scoreImg.w || pos.y >= scoreImg.h) - // Not on the board - return 0; - - // On board, so get the score from the pixel at that position - int score = *(const byte *)scoreImg.getBasePtr(pos.x, pos.y); - return score; -} - -Common::Point Darts::getComputerDartDest(int playerNum) { - Common::Point target; - int score = playerNum == 0 ? _dartScore1 : _dartScore2; - - if (score > 50) { - // Aim for the bullseye - target.x = target.y = 76; - - if (_level <= 1 && _vm->getRandomNumber(1) == 1) { - // Introduce margin of error - target.x += _vm->getRandomNumber(21) - 10; - target.y += _vm->getRandomNumber(21) - 10; - } - } else { - int aim = score; - - bool done; - Common::Point pt; - do { - done = findNumberOnBoard(aim, pt); - --aim; - } while (!done); - - target.x = 75 + ((target.x - 75) * 20 / 27); - target.y = 75 + ((target.y - 75) * 2 / 3); - } - - // Pick a level of accuracy. The higher the level, the more accurate their throw will be - int accuracy = _vm->getRandomNumber(10) + _level * 2; - - if (accuracy <= 2) { - target.x += _vm->getRandomNumber(71) - 35; - target.y += _vm->getRandomNumber(71) - 35; - } else if (accuracy <= 4) { - target.x += _vm->getRandomNumber(51) - 25; - target.y += _vm->getRandomNumber(51) - 25; - } else if (accuracy <= 6) { - target.x += _vm->getRandomNumber(31) - 15; - target.y += _vm->getRandomNumber(31) - 15; - } else if (accuracy <= 8) { - target.x += _vm->getRandomNumber(21) - 10; - target.y += _vm->getRandomNumber(21) - 10; - } else if (accuracy <= 10) { - target.x += _vm->getRandomNumber(11) - 5; - target.y += _vm->getRandomNumber(11) - 5; - } - - if (target.x < 1) - target.x = 1; - if (target.y < 1) - target.y = 1; - - return target; -} - -bool Darts::findNumberOnBoard(int aim, Common::Point &pt) { - ImageFrame &board = (*_dartImages)[1]; - - // Scan board image for the special "center" pixels - bool done = false; - for (int yp = 0; yp < 132 && !done; ++yp) { - const byte *srcP = (const byte *)board._frame.getBasePtr(0, yp); - for (int xp = 0; xp < 147 && !done; ++xp, ++srcP) { - int score = *srcP; - - // Check for match - if (score == aim) { - done = true; - - // Aim at non-double/triple numbers where possible - if (aim < 21) { - pt.x = xp + 5; - pt.y = yp + 5; - - score = *(const byte *)board._frame.getBasePtr(xp + 10, yp + 10); - if (score != aim) - // Not aiming at non-double/triple number yet - done = false; - } else { - // Aiming at a double or triple - pt.x = xp + 3; - pt.y = yp + 3; - } - } - } - } - - if (aim == 3) - pt.x += 15; - pt.y = 132 - pt.y; - - return done; -} - -} // End of namespace Scalpel - -} // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/darts.h b/engines/sherlock/scalpel/darts.h deleted file mode 100644 index bf327b61a2..0000000000 --- a/engines/sherlock/scalpel/darts.h +++ /dev/null @@ -1,130 +0,0 @@ -/* 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 SHERLOCK_DARTS_H -#define SHERLOCK_DARTS_H - -#include "sherlock/image_file.h" - -namespace Sherlock { - -namespace Scalpel { - -class ScalpelEngine; - -class Darts { -private: - ScalpelEngine *_vm; - ImageFile *_dartImages; - int _dartScore1, _dartScore2; - int _roundNumber; - int _level; - int _computerPlayer; - Common::String _opponent; - bool _playerDartMode; - int _roundScore; - bool _oldDartButtons; - - /** - * Load the graphics needed for the dart game - */ - void loadDarts(); - - /** - * Initializes the variables needed for the dart game - */ - void initDarts(); - - /** - * Frees the images used by the dart game - */ - void closeDarts(); - - /** - * Show the names of the people playing, Holmes and his opponent - */ - void showNames(int playerNum); - - /** - * Show the player score and game status - */ - void showStatus(int playerNum); - - /** - * Throws a single dart. - * @param dartNum Dart number - * @param computer 0 = Player, 1 = 1st player computer, 2 = 2nd player computer - * @returns Score for what dart hit - */ - int throwDart(int dartNum, int computer); - - /** - * Draw a dart moving towards the board - */ - void drawDartThrow(const Common::Point &pt); - - /** - * Erases the power bars - */ - void erasePowerBars(); - - /** - * Show a gradually incrementing incrementing power that bar. If goToPower is provided, it will - * 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 doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical); - - /** - * Returns true if a mouse button or key is pressed. - */ - int dartHit(); - - /** - * Return the score of the given location on the dart-board - */ - int dartScore(const Common::Point &pt); - - /** - * Calculates where a computer player is trying to throw their dart, and choose the actual - * point that was hit with some margin of error - */ - Common::Point getComputerDartDest(int playerNum); - - /** - * Returns the center position for the area of the dartboard with a given number - */ - bool findNumberOnBoard(int aim, Common::Point &pt); -public: - Darts(ScalpelEngine *vm); - - /** - * Main method for playing darts game - */ - void playDarts(); -}; - -} // End of namespace Scalpel - -} // End of namespace Sherlock - -#endif diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index d2524ccbc7..2635c2ee51 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -24,7 +24,7 @@ #define SHERLOCK_SCALPEL_H #include "sherlock/sherlock.h" -#include "sherlock/scalpel/darts.h" +#include "sherlock/scalpel/scalpel_darts.h" namespace Sherlock { diff --git a/engines/sherlock/scalpel/scalpel_darts.cpp b/engines/sherlock/scalpel/scalpel_darts.cpp new file mode 100644 index 0000000000..f36de0915a --- /dev/null +++ b/engines/sherlock/scalpel/scalpel_darts.cpp @@ -0,0 +1,553 @@ +/* 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 "sherlock/scalpel/scalpel_darts.h" +#include "sherlock/scalpel/scalpel.h" + +namespace Sherlock { + +namespace Scalpel { + +enum { + STATUS_INFO_X = 218, + STATUS_INFO_Y = 53, + DART_INFO_X = 218, + DART_INFO_Y = 103, + DARTBARHX = 35, + DARTHORIZY = 190, + DARTBARVX = 1, + DARTHEIGHTY = 25, + DARTBARSIZE = 150, + DART_BAR_FORE = 8 +}; + +enum { + DART_COL_FORE = 5, + PLAYER_COLOR = 11 +}; +#define OPPONENTS_COUNT 4 + +const char *const OPPONENT_NAMES[OPPONENTS_COUNT] = { + "Skipper", "Willy", "Micky", "Tom" +}; + +/*----------------------------------------------------------------*/ + +Darts::Darts(ScalpelEngine *vm) : _vm(vm) { + _dartImages = nullptr; + _level = 0; + _computerPlayer = 1; + _playerDartMode = false; + _dartScore1 = _dartScore2 = 0; + _roundNumber = 0; + _playerDartMode = false; + _roundScore = 0; + _oldDartButtons = false; +} + +void Darts::playDarts() { + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + int playerNumber = 0; + int lastDart; + + // Change the font + int oldFont = screen.fontNumber(); + screen.setFont(2); + + loadDarts(); + initDarts(); + + bool done = false; + do { + int score, roundStartScore; + roundStartScore = score = playerNumber == 0 ? _dartScore1 : _dartScore2; + + // Show player details + showNames(playerNumber); + showStatus(playerNumber); + _roundScore = 0; + + if (_vm->shouldQuit()) + return; + + for (int idx = 0; idx < 3; ++idx) { + // Throw a single dart + if (_computerPlayer == 1) + lastDart = throwDart(idx + 1, playerNumber * 2); + else if (_computerPlayer == 2) + lastDart = throwDart(idx + 1, playerNumber + 1); + else + lastDart = throwDart(idx + 1, 0); + + 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 < OPPONENTS_COUNT) + _vm->setFlagsDirect(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); + } + + playerNumber ^= 1; + if (!playerNumber) + ++_roundNumber; + + done |= _vm->shouldQuit(); + + if (!done) { + screen._backBuffer2.blitFrom((*_dartImages)[0], 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); +} + +void Darts::loadDarts() { + Screen &screen = *_vm->_screen; + + _dartImages = new ImageFile("darts.vgs"); + screen.setPalette(_dartImages->_palette); + + screen._backBuffer1.blitFrom((*_dartImages)[0], Common::Point(0, 0)); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); +} + +void Darts::initDarts() { + _dartScore1 = _dartScore2 = 301; + _roundNumber = 1; + + if (_level == 9) { + // No computer players + _computerPlayer = 0; + _level = 0; + } else if (_level == 8) { + _level = _vm->getRandomNumber(3); + _computerPlayer = 2; + } else { + // Check flags for opponents + for (int idx = 0; idx < OPPONENTS_COUNT; ++idx) { + if (_vm->readFlags(314 + idx)) + _level = idx; + } + } + + _opponent = OPPONENT_NAMES[_level]; +} + +void Darts::closeDarts() { + delete _dartImages; + _dartImages = nullptr; +} + +void Darts::showNames(int playerNum) { + Screen &screen = *_vm->_screen; + byte color = playerNum == 0 ? PLAYER_COLOR : DART_COL_FORE; + + // Print Holmes first + if (playerNum == 0) + screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y), PLAYER_COLOR + 3, "Holmes"); + else + screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y), color, "Holmes"); + + screen._backBuffer1.fillRect(Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, + STATUS_INFO_X + 31, STATUS_INFO_Y + 12), color); + screen.slamArea(STATUS_INFO_X, STATUS_INFO_Y + 10, 31, 12); + + // Second player + color = playerNum == 1 ? PLAYER_COLOR : DART_COL_FORE; + + if (playerNum != 0) + screen.print(Common::Point(STATUS_INFO_X + 50, STATUS_INFO_Y), PLAYER_COLOR + 3, + "%s", _opponent.c_str()); + else + screen.print(Common::Point(STATUS_INFO_X + 50, STATUS_INFO_Y), color, + "%s", _opponent.c_str()); + + screen._backBuffer1.fillRect(Common::Rect(STATUS_INFO_X + 50, STATUS_INFO_Y + 10, + STATUS_INFO_X + 81, STATUS_INFO_Y + 12), color); + screen.slamArea(STATUS_INFO_X + 50, STATUS_INFO_Y + 10, 81, 12); + + // Make a copy of the back buffer to the secondary one + screen._backBuffer2.blitFrom(screen._backBuffer1); +} + +void Darts::showStatus(int playerNum) { + Screen &screen = *_vm->_screen; + byte color; + + // Copy scoring screen from secondary back buffer. This will erase any previously displayed status/score info + screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10), + Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, SHERLOCK_SCREEN_WIDTH, STATUS_INFO_Y + 48)); + + color = (playerNum == 0) ? PLAYER_COLOR : DART_COL_FORE; + screen.print(Common::Point(STATUS_INFO_X + 6, STATUS_INFO_Y + 13), color, "%d", _dartScore1); + + color = (playerNum == 1) ? PLAYER_COLOR : DART_COL_FORE; + screen.print(Common::Point(STATUS_INFO_X + 56, STATUS_INFO_Y + 13), color, "%d", _dartScore2); + screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 25), PLAYER_COLOR, "Round: %d", _roundNumber); + screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 35), PLAYER_COLOR, "Turn Total: %d", _roundScore); + screen.slamRect(Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, SHERLOCK_SCREEN_WIDTH, STATUS_INFO_Y + 48)); +} + +int Darts::throwDart(int dartNum, int computer) { + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + Common::Point targetNum; + int width, height; + + events.clearKeyboard(); + + erasePowerBars(); + screen.print(Common::Point(DART_INFO_X, DART_INFO_Y), DART_COL_FORE, "Dart # %d", dartNum); + + if (!computer) { + screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 10), DART_COL_FORE, "Hit a key"); + screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 18), DART_COL_FORE, "to start"); + } + + if (!computer) { + while (!_vm->shouldQuit() && !dartHit()) + ; + } else { + events.delay(10); + } + + if (_vm->shouldQuit()) + return 0; + + 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.slamRect(Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + + // If it's a computer player, choose a dart destination + if (computer) + targetNum = getComputerDartDest(computer - 1); + + 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) + height += 2; + + // Copy the bars to the secondary back buffer so that they remain fixed at their selected values + // whilst the dart is being animated at being thrown at the board + screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DARTBARHX - 1, DARTHORIZY - 1), + Common::Rect(DARTBARHX - 1, DARTHORIZY - 1, DARTBARHX + DARTBARSIZE + 3, DARTHORIZY + 10)); + screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1), + Common::Rect(DARTBARVX - 1, DARTHEIGHTY - 1, DARTBARVX + 11, DARTHEIGHTY + DARTBARSIZE + 3)); + + // Convert height and width to relative range of -50 to 50, where 0,0 is the exact centre of the board + height -= 50; + width -= 50; + + Common::Point dartPos(111 + width * 2, 99 + height * 2); + drawDartThrow(dartPos); + + return dartScore(dartPos); +} + +void Darts::drawDartThrow(const Common::Point &pt) { + 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 = 4; idx < 23; ++idx) { + ImageFrame &frame = (*_dartImages)[idx]; + + // Adjust draw position for animating dart + if (idx < 13) + pos.y -= delta--; + else if (idx == 13) + delta = 1; + else + pos.y += delta++; + + // Draw the dart + Common::Point drawPos(pos.x - frame._width / 2, pos.y - frame._height); + screen._backBuffer1.transBlitFrom(frame, drawPos); + screen.slamArea(drawPos.x, drawPos.y, frame._width, frame._height); + + // Handle erasing old dart frame area + if (!oldDrawBounds.isEmpty()) + screen.slamRect(oldDrawBounds); + + oldDrawBounds = Common::Rect(drawPos.x, drawPos.y, drawPos.x + frame._width, drawPos.y + frame._height); + screen._backBuffer1.blitFrom(screen._backBuffer2, drawPos, oldDrawBounds); + + events.wait(2); + } + + // Draw dart in final "stuck to board" form + screen._backBuffer1.transBlitFrom((*_dartImages)[22], Common::Point(oldDrawBounds.left, oldDrawBounds.top)); + screen._backBuffer2.transBlitFrom((*_dartImages)[22], Common::Point(oldDrawBounds.left, oldDrawBounds.top)); + screen.slamRect(oldDrawBounds); +} + +void Darts::erasePowerBars() { + Screen &screen = *_vm->_screen; + + screen._backBuffer1.fillRect(Common::Rect(DARTBARHX, DARTHORIZY, DARTBARHX + DARTBARSIZE, DARTHORIZY + 10), BLACK); + screen._backBuffer1.fillRect(Common::Rect(DARTBARVX, DARTHEIGHTY, DARTBARVX + 10, DARTHEIGHTY + DARTBARSIZE), BLACK); + screen._backBuffer1.transBlitFrom((*_dartImages)[2], Common::Point(DARTBARHX - 1, DARTHORIZY - 1)); + screen._backBuffer1.transBlitFrom((*_dartImages)[3], Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1)); + screen.slamArea(DARTBARHX - 1, DARTHORIZY - 1, DARTBARSIZE + 3, 11); + screen.slamArea(DARTBARVX - 1, DARTHEIGHTY - 1, 11, DARTBARSIZE + 3); +} + +int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical) { + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + Music &music = *_vm->_music; + bool done; + int idx = 0; + + events.clearEvents(); + if (music._musicOn) + music.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)[3], 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)[2], Common::Point(pt.x - 1, pt.y - 1)); + screen.slamArea(pt.x + idx, pt.y, 1, 8); + } + + if (music._musicOn) { + if (!(idx % 3)) + music.waitTimerRoland(1); + } else if (!(idx % 8)) + events.wait(1); + + ++idx; + } while (!done); + + return MIN(idx * 100 / DARTBARSIZE, 100); +} + +int Darts::dartHit() { + Events &events = *_vm->_events; + + // Process pending events + events.pollEventsAndWait(); + + if (events.kbHit()) { + // Key was pressed, so return it + Common::KeyState keyState = events.getKey(); + return keyState.keycode; + } + + _oldDartButtons = events._pressed; + events.setButtonState(); + + // Only return true if the mouse button is newly pressed + return (events._pressed && !_oldDartButtons) ? 1 : 0; +} + +int Darts::dartScore(const Common::Point &pt) { + Common::Point pos(pt.x - 37, pt.y - 33); + Graphics::Surface &scoreImg = (*_dartImages)[1]._frame; + + if (pos.x < 0 || pos.y < 0 || pos.x >= scoreImg.w || pos.y >= scoreImg.h) + // Not on the board + return 0; + + // On board, so get the score from the pixel at that position + int score = *(const byte *)scoreImg.getBasePtr(pos.x, pos.y); + return score; +} + +Common::Point Darts::getComputerDartDest(int playerNum) { + Common::Point target; + int score = playerNum == 0 ? _dartScore1 : _dartScore2; + + if (score > 50) { + // Aim for the bullseye + target.x = target.y = 76; + + if (_level <= 1 && _vm->getRandomNumber(1) == 1) { + // Introduce margin of error + target.x += _vm->getRandomNumber(21) - 10; + target.y += _vm->getRandomNumber(21) - 10; + } + } else { + int aim = score; + + bool done; + Common::Point pt; + do { + done = findNumberOnBoard(aim, pt); + --aim; + } while (!done); + + target.x = 75 + ((target.x - 75) * 20 / 27); + target.y = 75 + ((target.y - 75) * 2 / 3); + } + + // Pick a level of accuracy. The higher the level, the more accurate their throw will be + int accuracy = _vm->getRandomNumber(10) + _level * 2; + + if (accuracy <= 2) { + target.x += _vm->getRandomNumber(71) - 35; + target.y += _vm->getRandomNumber(71) - 35; + } else if (accuracy <= 4) { + target.x += _vm->getRandomNumber(51) - 25; + target.y += _vm->getRandomNumber(51) - 25; + } else if (accuracy <= 6) { + target.x += _vm->getRandomNumber(31) - 15; + target.y += _vm->getRandomNumber(31) - 15; + } else if (accuracy <= 8) { + target.x += _vm->getRandomNumber(21) - 10; + target.y += _vm->getRandomNumber(21) - 10; + } else if (accuracy <= 10) { + target.x += _vm->getRandomNumber(11) - 5; + target.y += _vm->getRandomNumber(11) - 5; + } + + if (target.x < 1) + target.x = 1; + if (target.y < 1) + target.y = 1; + + return target; +} + +bool Darts::findNumberOnBoard(int aim, Common::Point &pt) { + ImageFrame &board = (*_dartImages)[1]; + + // Scan board image for the special "center" pixels + bool done = false; + for (int yp = 0; yp < 132 && !done; ++yp) { + const byte *srcP = (const byte *)board._frame.getBasePtr(0, yp); + for (int xp = 0; xp < 147 && !done; ++xp, ++srcP) { + int score = *srcP; + + // Check for match + if (score == aim) { + done = true; + + // Aim at non-double/triple numbers where possible + if (aim < 21) { + pt.x = xp + 5; + pt.y = yp + 5; + + score = *(const byte *)board._frame.getBasePtr(xp + 10, yp + 10); + if (score != aim) + // Not aiming at non-double/triple number yet + done = false; + } else { + // Aiming at a double or triple + pt.x = xp + 3; + pt.y = yp + 3; + } + } + } + } + + if (aim == 3) + pt.x += 15; + pt.y = 132 - pt.y; + + return done; +} + +} // End of namespace Scalpel + +} // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel_darts.h b/engines/sherlock/scalpel/scalpel_darts.h new file mode 100644 index 0000000000..483a163510 --- /dev/null +++ b/engines/sherlock/scalpel/scalpel_darts.h @@ -0,0 +1,130 @@ +/* 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 SHERLOCK_SCALPEL_DARTS_H +#define SHERLOCK_SCALPEL_DARTS_H + +#include "sherlock/image_file.h" + +namespace Sherlock { + +namespace Scalpel { + +class ScalpelEngine; + +class Darts { +private: + ScalpelEngine *_vm; + ImageFile *_dartImages; + int _dartScore1, _dartScore2; + int _roundNumber; + int _level; + int _computerPlayer; + Common::String _opponent; + bool _playerDartMode; + int _roundScore; + bool _oldDartButtons; + + /** + * Load the graphics needed for the dart game + */ + void loadDarts(); + + /** + * Initializes the variables needed for the dart game + */ + void initDarts(); + + /** + * Frees the images used by the dart game + */ + void closeDarts(); + + /** + * Show the names of the people playing, Holmes and his opponent + */ + void showNames(int playerNum); + + /** + * Show the player score and game status + */ + void showStatus(int playerNum); + + /** + * Throws a single dart. + * @param dartNum Dart number + * @param computer 0 = Player, 1 = 1st player computer, 2 = 2nd player computer + * @returns Score for what dart hit + */ + int throwDart(int dartNum, int computer); + + /** + * Draw a dart moving towards the board + */ + void drawDartThrow(const Common::Point &pt); + + /** + * Erases the power bars + */ + void erasePowerBars(); + + /** + * Show a gradually incrementing incrementing power that bar. If goToPower is provided, it will + * 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 doPowerBar(const Common::Point &pt, byte color, int goToPower, bool isVertical); + + /** + * Returns true if a mouse button or key is pressed. + */ + int dartHit(); + + /** + * Return the score of the given location on the dart-board + */ + int dartScore(const Common::Point &pt); + + /** + * Calculates where a computer player is trying to throw their dart, and choose the actual + * point that was hit with some margin of error + */ + Common::Point getComputerDartDest(int playerNum); + + /** + * Returns the center position for the area of the dartboard with a given number + */ + bool findNumberOnBoard(int aim, Common::Point &pt); +public: + Darts(ScalpelEngine *vm); + + /** + * Main method for playing darts game + */ + void playDarts(); +}; + +} // End of namespace Scalpel + +} // End of namespace Sherlock + +#endif -- cgit v1.2.3