[Scummvm-cvs-logs] scummvm master -> b2e98f4f52341c049df90d3410ff05f806bf1100

dreammaster dreammaster at scummvm.org
Fri Aug 7 02:44:22 CEST 2015


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
b2e98f4f52 SHERLOCK: SS: Renamed darts.cpp to scalpel_darts.cpp


Commit: b2e98f4f52341c049df90d3410ff05f806bf1100
    https://github.com/scummvm/scummvm/commit/b2e98f4f52341c049df90d3410ff05f806bf1100
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2015-08-06T20:40:20-04:00

Commit Message:
SHERLOCK: SS: Renamed darts.cpp to scalpel_darts.cpp

Changed paths:
  A engines/sherlock/scalpel/scalpel_darts.cpp
  A engines/sherlock/scalpel/scalpel_darts.h
  R engines/sherlock/scalpel/darts.cpp
  R engines/sherlock/scalpel/darts.h
    engines/sherlock/module.mk
    engines/sherlock/scalpel/scalpel.h



diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk
index e58a2a1..9e3fde0 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 8b5d02f..0000000
--- 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 bf327b6..0000000
--- 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 d2524cc..2635c2e 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 0000000..f36de09
--- /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 0000000..483a163
--- /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






More information about the Scummvm-git-logs mailing list