diff options
-rw-r--r-- | engines/sherlock/tattoo/tattoo_darts.cpp | 225 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_darts.h | 46 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_fixed_text.cpp | 8 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_fixed_text.h | 8 |
4 files changed, 284 insertions, 3 deletions
diff --git a/engines/sherlock/tattoo/tattoo_darts.cpp b/engines/sherlock/tattoo/tattoo_darts.cpp index 05113da958..77f6b59211 100644 --- a/engines/sherlock/tattoo/tattoo_darts.cpp +++ b/engines/sherlock/tattoo/tattoo_darts.cpp @@ -21,12 +21,31 @@ */ #include "sherlock/tattoo/tattoo_darts.h" +#include "sherlock/tattoo/tattoo_fixed_text.h" #include "sherlock/tattoo/tattoo.h" namespace Sherlock { namespace Tattoo { +enum { + DART_COLOR_FORE = 5, + PLAYER_COLOR = 11, +}; + +const int STATUS_INFO_X = 430; +const int STATUS_INFO_Y = 50; +const int STATUS_INFO_WIDTH = 205; +const int STATUS_INFO_HEIGHT = 330; +const int STATUS2_INFO_X = 510; +const int STATUS2_X_ADD = STATUS2_INFO_X - STATUS_INFO_X; +const int DART_BAR_VX = 10; +const int DART_HEIGHT_Y = 121; +const int DART_BAR_SIZE = 150; +const int DARTBOARD_LEFT = 73; +const int DARTBOARD_WIDTH = 257; +const int DARTBOARD_HEIGHT = 256; + Darts::Darts(SherlockEngine *vm) : _vm(vm) { _gameType = GAME_301; _hand1 = _hand2 = nullptr; @@ -38,11 +57,28 @@ Darts::Darts(SherlockEngine *vm) : _vm(vm) { Common::fill(&_cricketScore[1][0], &_cricketScore[1][7], 0); _score1 = _score2 = 0; _roundNum = 0; + _roundScore = 0; _level = 0; + _oldDartButtons = false; + _handX = 0; } void Darts::playDarts(GameType gameType) { + Screen &screen = *_vm->_screen; + int oldFontType = screen.fontNumber(); + int playerNum = 0; + int roundStart, score; + + screen.setFont(7); + _spacing = screen.fontHeight() + 2; + + while (!_vm->shouldQuit()) { + roundStart = score = (playerNum == 0) ? _score1 : _score2; + showNames(playerNum); + showStatus(playerNum); + _roundScore = 0; + } } void Darts::initDarts() { @@ -88,7 +124,7 @@ void Darts::initDarts() { } } - _opponent = "Jock"; + _opponent = FIXED(Jock); } void Darts::loadDarts() { @@ -126,6 +162,193 @@ void Darts::closeDarts() { delete _hand2; } +void Darts::showNames(int playerNum) { + Screen &screen = *_vm->_screen; + byte color; + + color = playerNum == 0 ? PLAYER_COLOR : DART_COLOR_FORE; + screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y), 0, "%s", FIXED(Holmes)); + screen._backBuffer1.fillRect(Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + _spacing + 1, + STATUS_INFO_X + 50, STATUS_INFO_Y + _spacing + 3), color); + screen.fillRect(Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + _spacing + 1, + STATUS_INFO_X + 50, STATUS_INFO_Y + _spacing + 3), color); + + color = playerNum == 1 ? PLAYER_COLOR : DART_COLOR_FORE; + screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y), 0, "%s", _opponent.c_str()); + screen._backBuffer1.fillRect(Common::Rect(STATUS2_INFO_X, STATUS_INFO_Y + _spacing + 1, + STATUS2_INFO_X + 50, STATUS_INFO_Y + _spacing + 3), color); + screen.fillRect(Common::Rect(STATUS2_INFO_X, STATUS_INFO_Y + _spacing + 1, + STATUS2_INFO_X + 50, STATUS_INFO_Y + _spacing + 3), color); + + screen._backBuffer2.blitFrom(screen._backBuffer1); +} + +void Darts::showStatus(int playerNum) { + Screen &screen = *_vm->_screen; + byte color; + const char *const CRICKET_SCORE_NAME[7] = { "20", "19", "18", "17", "16", "15", FIXED(Bull) }; + + screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10), + Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, STATUS_INFO_X + STATUS_INFO_WIDTH, + STATUS_INFO_Y + STATUS_INFO_HEIGHT - 10)); + + color = (playerNum == 0) ? PLAYER_COLOR : DART_COLOR_FORE; + screen.print(Common::Point(STATUS_INFO_X + 30, STATUS_INFO_Y + _spacing + 4), 0, "%d", _score1); + + color = (playerNum == 1) ? PLAYER_COLOR : DART_COLOR_FORE; + screen.print(Common::Point(STATUS2_INFO_X + 30, STATUS_INFO_Y + _spacing + 4), 0, "%d", _score2); + + int temp = (_gameType == GAME_CRICKET) ? STATUS_INFO_Y + 10 * _spacing + 5 : STATUS_INFO_Y + 55; + screen.print(Common::Point(STATUS_INFO_X, temp), 0, "%s: %d", FIXED(Round), _roundNum); + + if (_gameType == GAME_301) { + screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 75), 0, "%s: %d", FIXED(TurnTotal), _roundScore); + } else { + // Show cricket scores + for (int x = 0; x < 7; ++x) { + screen.print(Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 40 + x * _spacing), 0, "%s:", CRICKET_SCORE_NAME[x]); + + for (int y = 0; y < 2; ++y) { + color = (playerNum == y) ? PLAYER_COLOR : DART_COLOR_FORE; + + switch (CRICKET_SCORE_NAME[y][x]) { + case 1: + screen.print(Common::Point(STATUS_INFO_X + 38 + y*STATUS2_X_ADD, STATUS_INFO_Y + 40 + x * _spacing), 0, "/"); + break; + case 2: + screen.print(Common::Point(STATUS_INFO_X + 38 + y*STATUS2_X_ADD, STATUS_INFO_Y + 40 + x * _spacing), 0, "X"); + break; + case 3: + screen.print(Common::Point(STATUS_INFO_X + 38 + y * STATUS2_X_ADD - 1, STATUS_INFO_Y + 40 + x * _spacing), 0, "X"); + screen.print(Common::Point(STATUS_INFO_X + 37 + y * STATUS2_X_ADD, STATUS_INFO_Y + 40 + x * _spacing), 0, "O"); + break; + default: + break; + } + } + } + } + + screen.blitFrom(screen._backBuffer1, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10), + Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, STATUS_INFO_X + STATUS_INFO_WIDTH, + STATUS_INFO_Y + STATUS_INFO_HEIGHT - 10)); +} + +void Darts::erasePowerBars() { + Screen &screen = *_vm->_screen; + + // Erase the old power bars and replace them with empty ones + screen.fillRect(Common::Rect(DART_BAR_VX, DART_HEIGHT_Y, DART_BAR_VX + 9, DART_HEIGHT_Y + DART_BAR_SIZE), 0); + screen._backBuffer1.transBlitFrom((*_dartGraphics)[0], Common::Point(DART_BAR_VX - 1, DART_HEIGHT_Y - 1)); + screen.slamArea(DART_BAR_VX - 1, DART_HEIGHT_Y - 1, 10, DART_BAR_SIZE + 2); +} + +bool Darts::dartHit() { + Events &events = *_vm->_events; + events.pollEventsAndWait(); + + // Keyboard check + if (events.kbHit()) { + events.clearEvents(); + return true; + } + + bool result = events._pressed && !_oldDartButtons; + _oldDartButtons = events._pressed; + return result; +} + +int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, int orientation) { + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + int x = 0; + + events.clearEvents(); + events.delay(100); + + while (!_vm->shouldQuit()) { + if (x >= DART_BAR_SIZE) + break; + + if ((goToPower - 1) == x) + break; + else if (goToPower == 0) { + if (dartHit()) + break; + } + + screen._backBuffer1.fillRect(Common::Rect(pt.x, pt.y + DART_BAR_SIZE - 1 - x, + pt.x + 8, pt.y + DART_BAR_SIZE - 2 - x), color); + screen._backBuffer1.transBlitFrom((*_dartGraphics)[0], Common::Point(pt.x - 1, pt.y - 1)); + screen.slamArea(pt.x, pt.y + DART_BAR_SIZE - 1 - x, 8, 2); + + if (!(x % 8)) + events.wait(1); + + x += 1; + } + + return MIN(x * 100 / DART_BAR_SIZE, 100); +} + +int Darts::drawHand(int goToPower, int computer) { + Events &events = *_vm->_events; + Screen &screen = *_vm->_screen; + const int HAND_OFFSET[2] = { 72, 44 }; + ImageFile *hands; + int hand; + + goToPower = (goToPower * DARTBOARD_WIDTH) / 150; + + if (!computer) { + hand = 0; + hands = _hand1; + } else { + hand = 1; + hands = _hand2; + } + + _handSize.x = (*hands)[0]._offset.x + (*hands)[0]._width; + _handSize.y = (*hands)[0]._offset.y + (*hands)[0]._height; + + // Clear keyboard buffer + events.clearEvents(); + events.delay(100); + + Common::Point pt(DARTBOARD_LEFT - HAND_OFFSET[hand], SHERLOCK_SCREEN_HEIGHT - _handSize.y); + int x = 0; + + while (!_vm->shouldQuit()) { + if (x >= DARTBOARD_WIDTH) + break; + + if ((goToPower - 1) == x) + break; + else if (goToPower == 0) { + if (dartHit()) + break; + } + + screen._backBuffer1.transBlitFrom((*hands)[0], pt); + screen.slamArea(pt.x - 1, pt.y, _handSize.x + 1, _handSize.y); + screen.restoreBackground(Common::Rect(pt.x, pt.y, pt.x + _handSize.x, pt.y + _handSize.y)); + + if (!(x % 8)) + events.wait(1); + + ++x; + ++pt.x; + } + + _handX = pt.x - 1; + + return MIN(x * 100 / DARTBOARD_WIDTH, 100); +} + +Common::Point Darts::convertFromScreenToScoreCoords(const Common::Point &pt) const { + return Common::Point(CLIP((int)pt.x, 0, DARTBOARD_WIDTH), CLIP((int)pt.y, 0, DARTBOARD_HEIGHT)); +} + } // End of namespace Tattoo } // End of namespace Sherlock diff --git a/engines/sherlock/tattoo/tattoo_darts.h b/engines/sherlock/tattoo/tattoo_darts.h index 762eb35c83..679a41547c 100644 --- a/engines/sherlock/tattoo/tattoo_darts.h +++ b/engines/sherlock/tattoo/tattoo_darts.h @@ -47,9 +47,14 @@ private: int _cricketScore[2][7]; int _score1, _score2; int _roundNum; + int _roundScore; int _level; int _compPlay; Common::String _opponent; + int _spacing; + bool _oldDartButtons; + int _handX; + Common::Point _handSize; /** * Initialize game variables @@ -65,6 +70,47 @@ private: * Free loaded dart images */ void closeDarts(); + + /** + * Show the player names + */ + void showNames(int playerNum); + + /** + * Show the current scores + */ + void showStatus(int playerNum); + + /** + * Erases the power bars + */ + void erasePowerBars(); + + /** + * Returns true if a mouse button or key is pressed + */ + bool dartHit(); + + /** + * Shows a power bar and increments it until a key or mouse button is pressed. If the bar + * reaches the end, it will also end. The reached power bar number is returned. + * @param pt Bar position + * @param color draw color + * @param goToPower If provided, input is ignored, and the bar is increased up to the specified level + * @param orientation 0=Horizontal, 1=Vertical + */ + int doPowerBar(const Common::Point &pt, byte color, int goToPower, int orientation); + + /** + * This is similar to doPowerBar, except it draws the player's hand moving across the + * bottom of the screen to indicate the positioning of the darts + */ + int drawHand(int goToPower, int computer); + + /** + * Converts a passed co-ordinates from screen co-ordinates to an offset within the dartboard + */ + Common::Point convertFromScreenToScoreCoords(const Common::Point &pt) const; public: Darts(SherlockEngine *vm); diff --git a/engines/sherlock/tattoo/tattoo_fixed_text.cpp b/engines/sherlock/tattoo/tattoo_fixed_text.cpp index 4ee9e5eb34..568b59f2de 100644 --- a/engines/sherlock/tattoo/tattoo_fixed_text.cpp +++ b/engines/sherlock/tattoo/tattoo_fixed_text.cpp @@ -64,7 +64,13 @@ static const char *const FIXED_TEXT_ENGLISH[] = { "Abort Search", "Search Backwards", "Search Forwards", - "Text Not Found !" + "Text Not Found !", + + "Holmes", + "Jock", + "Bull", + "Round", + "Turn Total" }; TattooFixedText::TattooFixedText(SherlockEngine *vm) : FixedText(vm) { diff --git a/engines/sherlock/tattoo/tattoo_fixed_text.h b/engines/sherlock/tattoo/tattoo_fixed_text.h index 117888d8e6..facb51721c 100644 --- a/engines/sherlock/tattoo/tattoo_fixed_text.h +++ b/engines/sherlock/tattoo/tattoo_fixed_text.h @@ -64,7 +64,13 @@ enum FixedTextId { kFixedText_AbortSearch, kFixedText_SearchBackwards, kFixedText_SearchForwards, - kFixedText_TextNotFound + kFixedText_TextNotFound, + + kFixedText_Holmes, + kFixedText_Jock, + kFixedText_Bull, + kFixedText_Round, + kFixedText_TurnTotal }; class TattooFixedText: public FixedText { |