[Scummvm-cvs-logs] scummvm master -> 92ac962718b07e9b82199d39bb5ce970717da57d

dreammaster dreammaster at scummvm.org
Fri Jun 26 02:43:16 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:
92ac962718 SHERLOCK: RT: Further split-off of Scalpel-specific code


Commit: 92ac962718b07e9b82199d39bb5ce970717da57d
    https://github.com/scummvm/scummvm/commit/92ac962718b07e9b82199d39bb5ce970717da57d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2015-06-25T20:42:02-04:00

Commit Message:
SHERLOCK: RT: Further split-off of Scalpel-specific code

Changed paths:
  A engines/sherlock/scalpel/scalpel_inventory.cpp
  A engines/sherlock/scalpel/scalpel_inventory.h
  A engines/sherlock/scalpel/scalpel_saveload.cpp
  A engines/sherlock/scalpel/scalpel_saveload.h
  A engines/sherlock/scalpel/scalpel_screen.cpp
  A engines/sherlock/scalpel/scalpel_screen.h
    engines/sherlock/inventory.cpp
    engines/sherlock/inventory.h
    engines/sherlock/module.mk
    engines/sherlock/saveload.cpp
    engines/sherlock/saveload.h
    engines/sherlock/scalpel/scalpel.h
    engines/sherlock/scalpel/scalpel_journal.cpp
    engines/sherlock/scalpel/scalpel_talk.cpp
    engines/sherlock/scalpel/scalpel_talk.h
    engines/sherlock/scalpel/scalpel_user_interface.cpp
    engines/sherlock/scalpel/settings.cpp
    engines/sherlock/screen.cpp
    engines/sherlock/screen.h
    engines/sherlock/sherlock.cpp
    engines/sherlock/talk.cpp
    engines/sherlock/talk.h
    engines/sherlock/tattoo/tattoo.h
    engines/sherlock/tattoo/tattoo_user_interface.cpp
    engines/sherlock/tattoo/widget_inventory.cpp
    engines/sherlock/tattoo/widget_inventory.h



diff --git a/engines/sherlock/inventory.cpp b/engines/sherlock/inventory.cpp
index 692b057..492ac73 100644
--- a/engines/sherlock/inventory.cpp
+++ b/engines/sherlock/inventory.cpp
@@ -22,6 +22,7 @@
 
 #include "sherlock/inventory.h"
 #include "sherlock/sherlock.h"
+#include "sherlock/scalpel/scalpel_inventory.h"
 #include "sherlock/scalpel/scalpel_user_interface.h"
 
 namespace Sherlock {
@@ -42,6 +43,13 @@ void InventoryItem::synchronize(Serializer &s) {
 
 /*----------------------------------------------------------------*/
 
+Inventory *Inventory::init(SherlockEngine *vm) {
+	if (vm->getGameID() == GType_SerratedScalpel)
+		return new Scalpel::ScalpelInventory(vm);
+	else
+		return new Inventory(vm);
+}
+
 Inventory::Inventory(SherlockEngine *vm) : Common::Array<InventoryItem>(), _vm(vm) {
 	Common::fill(&_invShapes[0], &_invShapes[MAX_VISIBLE_INVENTORY], (ImageFile *)nullptr);
 	_invGraphicsLoaded = false;
@@ -128,238 +136,6 @@ int Inventory::findInv(const Common::String &name) {
 	error("Couldn't find inventory item - %s", name.c_str());
 }
 
-void Inventory::putInv(InvSlamMode slamIt) {
-	Screen &screen = *_vm->_screen;
-	UserInterface &ui = *_vm->_ui;
-
-	// If an inventory item has disappeared (due to using it or giving it),
-	// a blank space slot may have appeared. If so, adjust the inventory
-	if (_invIndex > 0 && _invIndex > (_holdings - 6)) {
-		--_invIndex;
-		freeGraphics();
-		loadGraphics();
-	}
-
-	if (slamIt != SLAM_SECONDARY_BUFFER) {
-		screen.makePanel(Common::Rect(6, 163, 54, 197));
-		screen.makePanel(Common::Rect(58, 163, 106, 197));
-		screen.makePanel(Common::Rect(110, 163, 158, 197));
-		screen.makePanel(Common::Rect(162, 163, 210, 197));
-		screen.makePanel(Common::Rect(214, 163, 262, 197));
-		screen.makePanel(Common::Rect(266, 163, 314, 197));
-	}
-
-	// Iterate through displaying up to 6 objects at a time
-	for (int idx = _invIndex; idx < _holdings && (idx - _invIndex) < MAX_VISIBLE_INVENTORY; ++idx) {
-		int itemNum = idx - _invIndex;
-		Surface &bb = slamIt == SLAM_SECONDARY_BUFFER ? screen._backBuffer2 : screen._backBuffer1;
-		Common::Rect r(8 + itemNum * 52, 165, 51 + itemNum * 52, 194);
-
-		// Draw the background
-		if (idx == ui._selector) {
-			bb.fillRect(r, BUTTON_BACKGROUND);
-		} else if (slamIt == SLAM_SECONDARY_BUFFER) {
-			bb.fillRect(r, BUTTON_MIDDLE);
-		}
-
-		// Draw the item image
-		ImageFrame &frame = (*_invShapes[itemNum])[0];
-		bb.transBlitFrom(frame, Common::Point(6 + itemNum * 52 + ((47 - frame._width) / 2),
-			163 + ((33 - frame._height) / 2)));
-	}
-
-	if (slamIt == SLAM_DISPLAY)
-		screen.slamArea(6, 163, 308, 34);
-
-	if (slamIt != SLAM_SECONDARY_BUFFER)
-		ui.clearInfo();
-
-	if (slamIt == 0) {
-		invCommands(0);
-	} else if (slamIt == SLAM_SECONDARY_BUFFER) {
-		screen._backBuffer = &screen._backBuffer2;
-		invCommands(0);
-		screen._backBuffer = &screen._backBuffer1;
-	}
-}
-
-void Inventory::drawInventory(InvNewMode mode) {
-	FixedText &fixedText = *_vm->_fixedText;
-	Screen &screen = *_vm->_screen;
-	UserInterface &ui = *_vm->_ui;
-	InvNewMode tempMode = mode;
-
-	loadInv();
-
-	if (mode == INVENTORY_DONT_DISPLAY) {
-		screen._backBuffer = &screen._backBuffer2;
-	}
-
-	// Draw the window background
-	Surface &bb = *screen._backBuffer;
-	bb.fillRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y1 + 10), BORDER_COLOR);
-	bb.fillRect(Common::Rect(0, CONTROLS_Y1 + 10, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
-	bb.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y1 + 10,
-		SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
-	bb.fillRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 2, SHERLOCK_SCREEN_WIDTH,
-		SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
-	bb.fillRect(Common::Rect(2, CONTROLS_Y1 + 10, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT - 2),
-		INV_BACKGROUND);
-
-	// Draw the buttons
-	Common::String fixedText_Exit = fixedText.getText(kFixedText_Inventory_Exit);
-	Common::String fixedText_Look = fixedText.getText(kFixedText_Inventory_Look);
-	Common::String fixedText_Use  = fixedText.getText(kFixedText_Inventory_Use);
-	Common::String fixedText_Give = fixedText.getText(kFixedText_Inventory_Give);
-
-	screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[0][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[0][1],
-		CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[0][2] - screen.stringWidth(fixedText_Exit) / 2, fixedText_Exit);
-	screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[1][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[1][1],
-		CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[1][2] - screen.stringWidth(fixedText_Look) / 2, fixedText_Look);
-	screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[2][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[2][1],
-		CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[2][2] - screen.stringWidth(fixedText_Use) / 2, fixedText_Use);
-	screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[3][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[3][1],
-		CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[3][2] - screen.stringWidth(fixedText_Give) / 2, fixedText_Give);
-	screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[4][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[4][1],
-		CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[4][2], "^^"); // 2 arrows pointing to the left
-	screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[5][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[5][1],
-		CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[5][2], "^"); // 1 arrow pointing to the left
-	screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[6][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[6][1],
-		CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[6][2], "_"); // 1 arrow pointing to the right
-	screen.makeButton(Common::Rect(Scalpel::INVENTORY_POINTS[7][0], CONTROLS_Y1, Scalpel::INVENTORY_POINTS[7][1],
-		CONTROLS_Y1 + 10), Scalpel::INVENTORY_POINTS[7][2], "__"); // 2 arrows pointing to the right
-
-	if (tempMode == INVENTORY_DONT_DISPLAY)
-		mode = LOOK_INVENTORY_MODE;
-	_invMode = (InvMode)mode;
-
-	if (mode != PLAIN_INVENTORY) {
-		ui._oldKey = Scalpel::INVENTORY_COMMANDS[(int)mode];
-	} else {
-		ui._oldKey = -1;
-	}
-
-	invCommands(0);
-	putInv(SLAM_DONT_DISPLAY);
-
-	if (tempMode != INVENTORY_DONT_DISPLAY) {
-		if (!ui._slideWindows) {
-			screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
-		} else {
-			ui.summonWindow(false, CONTROLS_Y1);
-		}
-
-		ui._windowOpen = true;
-	} else {
-		// Reset the screen back buffer to the first buffer now that drawing is done
-		screen._backBuffer = &screen._backBuffer1;
-	}
-
-	assert(IS_SERRATED_SCALPEL);
-	((Scalpel::ScalpelUserInterface *)_vm->_ui)->_oldUse = -1;
-}
-
-void Inventory::invCommands(bool slamIt) {
-	FixedText &fixedText = *_vm->_fixedText;
-	Screen &screen = *_vm->_screen;
-	UserInterface &ui = *_vm->_ui;
-
-	Common::String fixedText_Exit = fixedText.getText(kFixedText_Inventory_Exit);
-	Common::String fixedText_Look = fixedText.getText(kFixedText_Inventory_Look);
-	Common::String fixedText_Use  = fixedText.getText(kFixedText_Inventory_Use);
-	Common::String fixedText_Give = fixedText.getText(kFixedText_Inventory_Give);
-
-	if (slamIt) {
-		screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[0][2], CONTROLS_Y1),
-			_invMode == INVMODE_EXIT ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND,
-			true, fixedText_Exit);
-		screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[1][2], CONTROLS_Y1),
-			_invMode == INVMODE_LOOK ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND,
-			true, fixedText_Look);
-		screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[2][2], CONTROLS_Y1),
-			_invMode == INVMODE_USE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
-			true, fixedText_Use);
-		screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[3][2], CONTROLS_Y1),
-			_invMode == INVMODE_GIVE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
-			true, fixedText_Give);
-		screen.print(Common::Point(Scalpel::INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1),
-			_invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
-			"^^"); // 2 arrows pointing to the left
-		screen.print(Common::Point(Scalpel::INVENTORY_POINTS[5][2], CONTROLS_Y1 + 1),
-			_invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
-			"^"); // 2 arrows pointing to the left
-		screen.print(Common::Point(Scalpel::INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1),
-			(_holdings - _invIndex <= 6) ? COMMAND_NULL : COMMAND_FOREGROUND,
-			"_"); // 1 arrow pointing to the right
-		screen.print(Common::Point(Scalpel::INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1),
-			(_holdings - _invIndex <= 6) ? COMMAND_NULL : COMMAND_FOREGROUND,
-			"__"); // 2 arrows pointing to the right
-		if (_invMode != INVMODE_LOOK)
-			ui.clearInfo();
-	} else {
-		screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[0][2], CONTROLS_Y1),
-			_invMode == INVMODE_EXIT ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
-			false, fixedText_Exit);
-		screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[1][2], CONTROLS_Y1),
-			_invMode == INVMODE_LOOK ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
-			false, fixedText_Look);
-		screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[2][2], CONTROLS_Y1),
-			_invMode == INVMODE_USE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
-			false, fixedText_Use);
-		screen.buttonPrint(Common::Point(Scalpel::INVENTORY_POINTS[3][2], CONTROLS_Y1),
-			_invMode == INVMODE_GIVE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
-			false, fixedText_Give);
-		screen.gPrint(Common::Point(Scalpel::INVENTORY_POINTS[4][2], CONTROLS_Y1),
-			_invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
-			"^^"); // 2 arrows pointing to the left
-		screen.gPrint(Common::Point(Scalpel::INVENTORY_POINTS[5][2], CONTROLS_Y1),
-			_invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
-			"^"); // 1 arrow pointing to the left
-		screen.gPrint(Common::Point(Scalpel::INVENTORY_POINTS[6][2], CONTROLS_Y1),
-			(_holdings - _invIndex < 7) ? COMMAND_NULL : COMMAND_FOREGROUND,
-			"_"); // 1 arrow pointing to the right
-		screen.gPrint(Common::Point(Scalpel::INVENTORY_POINTS[7][2], CONTROLS_Y1),
-			(_holdings - _invIndex < 7) ? COMMAND_NULL : COMMAND_FOREGROUND,
-			"__"); // 2 arrows pointing to the right
-	}
-}
-
-void Inventory::highlight(int index, byte color) {
-	Screen &screen = *_vm->_screen;
-	Surface &bb = *screen._backBuffer;
-	int slot = index - _invIndex;
-	ImageFrame &frame = (*_invShapes[slot])[0];
-
-	bb.fillRect(Common::Rect(8 + slot * 52, 165, (slot + 1) * 52, 194), color);
-	bb.transBlitFrom(frame, Common::Point(6 + slot * 52 + ((47 - frame._width) / 2),
-		163 + ((33 - frame._height) / 2)));
-	screen.slamArea(8 + slot * 52, 165, 44, 30);
-}
-
-void Inventory::refreshInv() {
-	if (IS_ROSE_TATTOO)
-		return;
-	
-	Screen &screen = *_vm->_screen;
-	Talk &talk = *_vm->_talk;
-	Scalpel::ScalpelUserInterface &ui = *(Scalpel::ScalpelUserInterface *)_vm->_ui;
-
-	ui._invLookFlag = true;
-	freeInv();
-
-	ui._infoFlag = true;
-	ui.clearInfo();
-
-	screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(0, CONTROLS_Y),
-		Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
-	ui.examine();
-
-	if (!talk._talkToAbort) {
-		screen._backBuffer2.blitFrom((*ui._controlPanel)[0], Common::Point(0, CONTROLS_Y));
-		loadInv();
-	}
-}
-
 int Inventory::putNameInInventory(const Common::String &name) {
 	Scene &scene = *_vm->_scene;
 	int matches = 0;
diff --git a/engines/sherlock/inventory.h b/engines/sherlock/inventory.h
index 019f5ed..20eb6c0 100644
--- a/engines/sherlock/inventory.h
+++ b/engines/sherlock/inventory.h
@@ -77,7 +77,7 @@ struct InventoryItem {
 };
 
 class Inventory : public Common::Array<InventoryItem> {
-private:
+protected:
 	SherlockEngine *_vm;
 	Common::StringArray _names;
 
@@ -97,6 +97,7 @@ public:
 	 */
 	void freeGraphics();
 public:
+	static Inventory *init(SherlockEngine *vm);
 	Inventory(SherlockEngine *vm);
 	~Inventory();
 
@@ -123,32 +124,6 @@ public:
 	int findInv(const Common::String &name);
 
 	/**
-	 * Display the character's inventory. The slamIt parameter specifies:
-	 */
-	void putInv(InvSlamMode slamIt);
-
-	/**
-	 * Put the game into inventory mode and open the interface window.
-	 */
-	void drawInventory(InvNewMode flag);
-
-	/**
-	 * Prints the line of inventory commands at the top of an inventory window with
-	 * the correct highlighting
-	 */
-	void invCommands(bool slamIt);
-
-	/**
-	 * Set the highlighting color of a given inventory item
-	 */
-	void highlight(int index, byte color);
-
-	/**
-	 * Support method for refreshing the display of the inventory
-	 */
-	void refreshInv();
-
-	/**
 	 * Adds a shape from the scene to the player's inventory
 	 */
 	int putNameInInventory(const Common::String &name);
diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk
index 8bbee9d..badd288 100644
--- a/engines/sherlock/module.mk
+++ b/engines/sherlock/module.mk
@@ -8,10 +8,13 @@ MODULE_OBJS = \
 	scalpel/drivers/mt32.o \
 	scalpel/tsage/logo.o \
 	scalpel/tsage/resources.o \
+	scalpel/scalpel_inventory.o \
 	scalpel/scalpel_journal.o \
 	scalpel/scalpel_map.o \
 	scalpel/scalpel_people.o \
+	scalpel/scalpel_saveload.o \
 	scalpel/scalpel_scene.o \
+	scalpel/scalpel_screen.o \
 	scalpel/scalpel_talk.o \
 	scalpel/scalpel_user_interface.o \
 	scalpel/settings.o \
diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp
index c863f8c..fae8196 100644
--- a/engines/sherlock/saveload.cpp
+++ b/engines/sherlock/saveload.cpp
@@ -23,27 +23,26 @@
 #include "sherlock/saveload.h"
 #include "sherlock/surface.h"
 #include "sherlock/sherlock.h"
+#include "sherlock/scalpel/scalpel_saveload.h"
 #include "common/system.h"
 #include "graphics/scaler.h"
 #include "graphics/thumbnail.h"
 
 namespace Sherlock {
 
-const int ENV_POINTS[6][3] = {
-	{ 41, 80, 61 },		// Exit
-	{ 81, 120, 101 },	// Load
-	{ 121, 160, 141 },	// Save
-	{ 161, 200, 181 },	// Up
-	{ 201, 240, 221 },	// Down
-	{ 241, 280, 261 }	// Quit
-};
-
-static const char *const EMPTY_SAVEGAME_SLOT = "-EMPTY-";
+const char *const EMPTY_SAVEGAME_SLOT = "-EMPTY-";
 static const char *const SAVEGAME_STR = "SHLK";
 #define SAVEGAME_STR_SIZE 4
 
 /*----------------------------------------------------------------*/
 
+SaveManager *SaveManager::init(SherlockEngine *vm, const Common::String &target) {
+	if (vm->getGameID() == GType_SerratedScalpel)
+		return new Scalpel::ScalpelSaveManager(vm, target);
+	else
+		return new SaveManager(vm, target);
+}
+
 SaveManager::SaveManager(SherlockEngine *vm, const Common::String &target) :
 		_vm(vm), _target(target) {
 	_saveThumb = nullptr;
@@ -59,54 +58,6 @@ SaveManager::~SaveManager() {
 	}
 }
 
-void SaveManager::drawInterface() {
-	Screen &screen = *_vm->_screen;
-	UserInterface &ui = *_vm->_ui;
-
-	// Create a list of savegame slots
-	createSavegameList();
-
-	screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + 10), BORDER_COLOR);
-	screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y + 10, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
-	screen._backBuffer1.fillRect(Common::Rect(318, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
-	screen._backBuffer1.fillRect(Common::Rect(0, 199, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
-	screen._backBuffer1.fillRect(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND);
-
-	screen.makeButton(Common::Rect(ENV_POINTS[0][0], CONTROLS_Y, ENV_POINTS[0][1], CONTROLS_Y + 10),
-		ENV_POINTS[0][2] - screen.stringWidth("Exit") / 2, "Exit");
-	screen.makeButton(Common::Rect(ENV_POINTS[1][0], CONTROLS_Y, ENV_POINTS[1][1], CONTROLS_Y + 10),
-		ENV_POINTS[1][2] - screen.stringWidth("Load") / 2, "Load");
-	screen.makeButton(Common::Rect(ENV_POINTS[2][0], CONTROLS_Y, ENV_POINTS[2][1], CONTROLS_Y + 10),
-		ENV_POINTS[2][2] - screen.stringWidth("Save") / 2, "Save");
-	screen.makeButton(Common::Rect(ENV_POINTS[3][0], CONTROLS_Y, ENV_POINTS[3][1], CONTROLS_Y + 10),
-		ENV_POINTS[3][2] - screen.stringWidth("Up") / 2, "Up");
-	screen.makeButton(Common::Rect(ENV_POINTS[4][0], CONTROLS_Y, ENV_POINTS[4][1], CONTROLS_Y + 10),
-		ENV_POINTS[4][2] - screen.stringWidth("Down") / 2, "Down");
-	screen.makeButton(Common::Rect(ENV_POINTS[5][0], CONTROLS_Y, ENV_POINTS[5][1], CONTROLS_Y + 10),
-		ENV_POINTS[5][2] - screen.stringWidth("Quit") / 2, "Quit");
-
-	if (!_savegameIndex)
-		screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_NULL, 0, "Up");
-
-	if (_savegameIndex == MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT)
-		screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_NULL, 0, "Down");
-
-	for (int idx = _savegameIndex; idx < _savegameIndex + ONSCREEN_FILES_COUNT; ++idx) {
-		screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10),
-			INV_FOREGROUND, "%d.", idx + 1);
-		screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10),
-			INV_FOREGROUND, "%s", _savegames[idx].c_str());
-	}
-
-	if (!ui._slideWindows) {
-		screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
-	} else {
-		ui.summonWindow();
-	}
-
-	_envMode = SAVEMODE_NONE;
-}
-
 void SaveManager::createSavegameList() {
 	Screen &screen = *_vm->_screen;
 
@@ -249,49 +200,6 @@ void SaveManager::createThumbnail() {
 	}
 }
 
-int SaveManager::getHighlightedButton() const {
-	Common::Point pt = _vm->_events->mousePos();
-
-	for (int idx = 0; idx < 6; ++idx) {
-		if (pt.x > ENV_POINTS[idx][0] && pt.x < ENV_POINTS[idx][1] && pt.y > CONTROLS_Y
-				&& pt.y < (CONTROLS_Y + 10))
-			return idx;
-	}
-
-	return -1;
-}
-
-void SaveManager::highlightButtons(int btnIndex) {
-	Screen &screen = *_vm->_screen;
-	byte color = (btnIndex == 0) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND;
-
-	screen.buttonPrint(Common::Point(ENV_POINTS[0][2], CONTROLS_Y), color, 1, "Exit");
-
-	if ((btnIndex == 1) || ((_envMode == SAVEMODE_LOAD) && (btnIndex != 2)))
-		screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Load");
-	else
-		screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Load");
-
-	if ((btnIndex == 2) || ((_envMode == SAVEMODE_SAVE) && (btnIndex != 1)))
-		screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Save");
-	else
-		screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Save");
-
-	if (btnIndex == 3 && _savegameIndex)
-		screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Up");
-	else
-		if (_savegameIndex)
-			screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Up");
-
-	if ((btnIndex == 4) && (_savegameIndex < MAX_SAVEGAME_SLOTS - 5))
-		screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Down");
-	else if (_savegameIndex < (MAX_SAVEGAME_SLOTS - 5))
-		screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Down");
-
-	color = (btnIndex == 5) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND;
-	screen.buttonPrint(Common::Point(ENV_POINTS[5][2], CONTROLS_Y), color, 1, "Quit");
-}
-
 void SaveManager::loadGame(int slot) {
 	Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(
 		generateSaveName(slot));
@@ -363,129 +271,6 @@ void SaveManager::synchronize(Serializer &s) {
 	_justLoaded = true;
 }
 
-bool SaveManager::checkGameOnScreen(int slot) {
-	Screen &screen = *_vm->_screen;
-
-	// Check if it's already on-screen
-	if (slot != -1 && (slot < _savegameIndex || slot >= (_savegameIndex + ONSCREEN_FILES_COUNT))) {
-		_savegameIndex = slot;
-
-		screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2,
-			SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND);
-
-		for (int idx = _savegameIndex; idx < (_savegameIndex + 5); ++idx) {
-			screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10),
-				INV_FOREGROUND, "%d.", idx + 1);
-			screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10),
-				INV_FOREGROUND, "%s", _savegames[idx].c_str());
-		}
-
-		screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, 318, SHERLOCK_SCREEN_HEIGHT));
-
-		byte color = !_savegameIndex ? COMMAND_NULL : COMMAND_FOREGROUND;
-		screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), color, 1, "Up");
-
-		color = (_savegameIndex == (MAX_SAVEGAME_SLOTS - 5)) ? COMMAND_NULL : COMMAND_FOREGROUND;
-		screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, 1, "Down");
-
-		return true;
-	}
-
-	return false;
-}
-
-bool SaveManager::promptForDescription(int slot) {
-	Events &events = *_vm->_events;
-	Scene &scene = *_vm->_scene;
-	Screen &screen = *_vm->_screen;
-	Talk &talk = *_vm->_talk;
-	int xp, yp;
-	bool flag = false;
-
-	screen.buttonPrint(Common::Point(ENV_POINTS[0][2], CONTROLS_Y), COMMAND_NULL, true, "Exit");
-	screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_NULL, true, "Load");
-	screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_NULL, true, "Save");
-	screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_NULL, true, "Up");
-	screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_NULL, true, "Down");
-	screen.buttonPrint(Common::Point(ENV_POINTS[5][2], CONTROLS_Y), COMMAND_NULL, true, "Quit");
-
-	Common::String saveName = _savegames[slot];
-	if (isSlotEmpty(slot)) {
-		// It's an empty slot, so start off with an empty save name
-		saveName = "";
-
-		yp = CONTROLS_Y + 12 + (slot - _savegameIndex) * 10;
-		screen.vgaBar(Common::Rect(24, yp, 85, yp + 9), INV_BACKGROUND);
-	}
-
-	screen.print(Common::Point(6, CONTROLS_Y + 12 + (slot - _savegameIndex) * 10), TALK_FOREGROUND, "%d.", slot + 1);
-	screen.print(Common::Point(24, CONTROLS_Y + 12 + (slot - _savegameIndex) * 10), TALK_FOREGROUND, "%s", saveName.c_str());
-	xp = 24 + screen.stringWidth(saveName);
-	yp = CONTROLS_Y + 12 + (slot - _savegameIndex) * 10;
-
-	int done = 0;
-	do {
-		while (!_vm->shouldQuit() && !events.kbHit()) {
-			scene.doBgAnim();
-
-			if (talk._talkToAbort)
-				return false;
-
-			// Allow event processing
-			events.pollEventsAndWait();
-			events.setButtonState();
-
-			flag = !flag;
-			if (flag)
-				screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND);
-			else
-				screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND);
-		}
-		if (_vm->shouldQuit())
-			return false;
-
-		// Get the next keypress
-		Common::KeyState keyState = events.getKey();
-
-		if (keyState.keycode == Common::KEYCODE_BACKSPACE && saveName.size() > 0) {
-			// Delete character of save name
-			screen.vgaBar(Common::Rect(xp - screen.charWidth(saveName.lastChar()), yp - 1,
-				xp + 8, yp + 9), INV_BACKGROUND);
-			xp -= screen.charWidth(saveName.lastChar());
-			screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND);
-			saveName.deleteLastChar();
-		
-		} else if (keyState.keycode == Common::KEYCODE_RETURN && saveName.compareToIgnoreCase(EMPTY_SAVEGAME_SLOT)) {
-			done = 1;
-
-		} else if (keyState.keycode == Common::KEYCODE_ESCAPE) {
-			screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND);
-			done = -1;
-		
-		} else if (keyState.ascii >= ' ' && keyState.ascii <= 'z' && saveName.size() < 50
-				&& (xp + screen.charWidth(keyState.ascii)) < 308) {
-			char c = (char)keyState.ascii;
-
-			screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND);
-			screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", c);
-			xp += screen.charWidth(c);
-			screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND);
-			saveName += c;
-		}
-	} while (!done);
-
-	if (done == 1) {
-		// Enter key perssed
-		_savegames[slot] = saveName;
-	} else {
-		done = 0;
-		_envMode = SAVEMODE_NONE;
-		highlightButtons(-1);
-	}
-
-	return done == 1;
-}
-
 bool SaveManager::isSlotEmpty(int slot) const {
 	return _savegames[slot].equalsIgnoreCase(EMPTY_SAVEGAME_SLOT);
 }
diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h
index 49ccc50..e485cfc 100644
--- a/engines/sherlock/saveload.h
+++ b/engines/sherlock/saveload.h
@@ -42,7 +42,7 @@ enum {
 
 enum SaveMode { SAVEMODE_NONE = 0, SAVEMODE_LOAD = 1, SAVEMODE_SAVE = 2 };
 
-extern const int ENV_POINTS[6][3];
+extern const char *const EMPTY_SAVEGAME_SLOT;
 
 struct SherlockSavegameHeader {
 	uint8 _version;
@@ -70,7 +70,7 @@ public:
 };
 
 class SaveManager {
-private:
+protected:
 	SherlockEngine *_vm;
 	Common::String _target;
 	Graphics::Surface *_saveThumb;
@@ -90,15 +90,11 @@ public:
 	SaveMode _envMode;
 	bool _justLoaded;
 public:
+	static SaveManager *init(SherlockEngine *vm, const Common::String &target);
 	SaveManager(SherlockEngine *vm, const Common::String &target);
 	~SaveManager();
 
 	/**
-	 * Shows the in-game dialog interface for loading and saving games
-	 */
-	void drawInterface();
-
-	/**
 	 * Creates a thumbnail for the current on-screen contents
 	 */
 	void createThumbnail();
@@ -145,16 +141,6 @@ public:
 	void saveGame(int slot, const Common::String &name);
 
 	/**
-	 * Make sure that the selected savegame is on-screen
-	 */
-	bool checkGameOnScreen(int slot);
-
-	/**
-	 * Prompts the user to enter a description in a given slot
-	 */
-	bool promptForDescription(int slot);
-
-	/**
 	 * Returns true if the given save slot is empty
 	 */
 	bool isSlotEmpty(int slot) const;
diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h
index 8a10094..0747e7d 100644
--- a/engines/sherlock/scalpel/scalpel.h
+++ b/engines/sherlock/scalpel/scalpel.h
@@ -30,6 +30,11 @@ namespace Sherlock {
 
 namespace Scalpel {
 
+enum {
+	COMMAND_HIGHLIGHTED = 10,
+	COMMAND_NULL		= 248
+};
+
 class ScalpelEngine : public SherlockEngine {
 private:
 	Darts *_darts;
diff --git a/engines/sherlock/scalpel/scalpel_inventory.cpp b/engines/sherlock/scalpel/scalpel_inventory.cpp
new file mode 100644
index 0000000..bf12a16
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_inventory.cpp
@@ -0,0 +1,271 @@
+/* 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_inventory.h"
+#include "sherlock/scalpel/scalpel_screen.h"
+#include "sherlock/scalpel/scalpel_user_interface.h"
+#include "sherlock/scalpel/scalpel.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+ScalpelInventory::ScalpelInventory(SherlockEngine *vm) : Inventory(vm) {
+}
+
+ScalpelInventory::~ScalpelInventory() {
+}
+
+void ScalpelInventory::drawInventory(InvNewMode mode) {
+	FixedText &fixedText = *_vm->_fixedText;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+	UserInterface &ui = *_vm->_ui;
+	InvNewMode tempMode = mode;
+
+	loadInv();
+
+	if (mode == INVENTORY_DONT_DISPLAY) {
+		screen._backBuffer = &screen._backBuffer2;
+	}
+
+	// Draw the window background
+	Surface &bb = *screen._backBuffer;
+	bb.fillRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y1 + 10), BORDER_COLOR);
+	bb.fillRect(Common::Rect(0, CONTROLS_Y1 + 10, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+	bb.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y1 + 10,
+		SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+	bb.fillRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 2, SHERLOCK_SCREEN_WIDTH,
+		SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+	bb.fillRect(Common::Rect(2, CONTROLS_Y1 + 10, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT - 2),
+		INV_BACKGROUND);
+
+	// Draw the buttons
+	Common::String fixedText_Exit = fixedText.getText(kFixedText_Inventory_Exit);
+	Common::String fixedText_Look = fixedText.getText(kFixedText_Inventory_Look);
+	Common::String fixedText_Use  = fixedText.getText(kFixedText_Inventory_Use);
+	Common::String fixedText_Give = fixedText.getText(kFixedText_Inventory_Give);
+
+	screen.makeButton(Common::Rect(INVENTORY_POINTS[0][0], CONTROLS_Y1, INVENTORY_POINTS[0][1],
+		CONTROLS_Y1 + 10), INVENTORY_POINTS[0][2] - screen.stringWidth(fixedText_Exit) / 2, fixedText_Exit);
+	screen.makeButton(Common::Rect(INVENTORY_POINTS[1][0], CONTROLS_Y1, INVENTORY_POINTS[1][1],
+		CONTROLS_Y1 + 10), INVENTORY_POINTS[1][2] - screen.stringWidth(fixedText_Look) / 2, fixedText_Look);
+	screen.makeButton(Common::Rect(INVENTORY_POINTS[2][0], CONTROLS_Y1, INVENTORY_POINTS[2][1],
+		CONTROLS_Y1 + 10), INVENTORY_POINTS[2][2] - screen.stringWidth(fixedText_Use) / 2, fixedText_Use);
+	screen.makeButton(Common::Rect(INVENTORY_POINTS[3][0], CONTROLS_Y1, INVENTORY_POINTS[3][1],
+		CONTROLS_Y1 + 10), INVENTORY_POINTS[3][2] - screen.stringWidth(fixedText_Give) / 2, fixedText_Give);
+	screen.makeButton(Common::Rect(INVENTORY_POINTS[4][0], CONTROLS_Y1, INVENTORY_POINTS[4][1],
+		CONTROLS_Y1 + 10), INVENTORY_POINTS[4][2], "^^"); // 2 arrows pointing to the left
+	screen.makeButton(Common::Rect(INVENTORY_POINTS[5][0], CONTROLS_Y1, INVENTORY_POINTS[5][1],
+		CONTROLS_Y1 + 10), INVENTORY_POINTS[5][2], "^"); // 1 arrow pointing to the left
+	screen.makeButton(Common::Rect(INVENTORY_POINTS[6][0], CONTROLS_Y1, INVENTORY_POINTS[6][1],
+		CONTROLS_Y1 + 10), INVENTORY_POINTS[6][2], "_"); // 1 arrow pointing to the right
+	screen.makeButton(Common::Rect(INVENTORY_POINTS[7][0], CONTROLS_Y1, INVENTORY_POINTS[7][1],
+		CONTROLS_Y1 + 10), INVENTORY_POINTS[7][2], "__"); // 2 arrows pointing to the right
+
+	if (tempMode == INVENTORY_DONT_DISPLAY)
+		mode = LOOK_INVENTORY_MODE;
+	_invMode = (InvMode)mode;
+
+	if (mode != PLAIN_INVENTORY) {
+		ui._oldKey = INVENTORY_COMMANDS[(int)mode];
+	} else {
+		ui._oldKey = -1;
+	}
+
+	invCommands(0);
+	putInv(SLAM_DONT_DISPLAY);
+
+	if (tempMode != INVENTORY_DONT_DISPLAY) {
+		if (!ui._slideWindows) {
+			screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+		} else {
+			ui.summonWindow(false, CONTROLS_Y1);
+		}
+
+		ui._windowOpen = true;
+	} else {
+		// Reset the screen back buffer to the first buffer now that drawing is done
+		screen._backBuffer = &screen._backBuffer1;
+	}
+
+	assert(IS_SERRATED_SCALPEL);
+	((ScalpelUserInterface *)_vm->_ui)->_oldUse = -1;
+}
+
+void ScalpelInventory::invCommands(bool slamIt) {
+	FixedText &fixedText = *_vm->_fixedText;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+	UserInterface &ui = *_vm->_ui;
+
+	Common::String fixedText_Exit = fixedText.getText(kFixedText_Inventory_Exit);
+	Common::String fixedText_Look = fixedText.getText(kFixedText_Inventory_Look);
+	Common::String fixedText_Use  = fixedText.getText(kFixedText_Inventory_Use);
+	Common::String fixedText_Give = fixedText.getText(kFixedText_Inventory_Give);
+
+	if (slamIt) {
+		screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1),
+			_invMode == INVMODE_EXIT ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND,
+			true, fixedText_Exit);
+		screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1),
+			_invMode == INVMODE_LOOK ? COMMAND_HIGHLIGHTED :COMMAND_FOREGROUND,
+			true, fixedText_Look);
+		screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1),
+			_invMode == INVMODE_USE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+			true, fixedText_Use);
+		screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1),
+			_invMode == INVMODE_GIVE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+			true, fixedText_Give);
+		screen.print(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1 + 1),
+			_invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
+			"^^"); // 2 arrows pointing to the left
+		screen.print(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1 + 1),
+			_invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
+			"^"); // 2 arrows pointing to the left
+		screen.print(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1 + 1),
+			(_holdings - _invIndex <= 6) ? COMMAND_NULL : COMMAND_FOREGROUND,
+			"_"); // 1 arrow pointing to the right
+		screen.print(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1 + 1),
+			(_holdings - _invIndex <= 6) ? COMMAND_NULL : COMMAND_FOREGROUND,
+			"__"); // 2 arrows pointing to the right
+		if (_invMode != INVMODE_LOOK)
+			ui.clearInfo();
+	} else {
+		screen.buttonPrint(Common::Point(INVENTORY_POINTS[0][2], CONTROLS_Y1),
+			_invMode == INVMODE_EXIT ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+			false, fixedText_Exit);
+		screen.buttonPrint(Common::Point(INVENTORY_POINTS[1][2], CONTROLS_Y1),
+			_invMode == INVMODE_LOOK ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+			false, fixedText_Look);
+		screen.buttonPrint(Common::Point(INVENTORY_POINTS[2][2], CONTROLS_Y1),
+			_invMode == INVMODE_USE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+			false, fixedText_Use);
+		screen.buttonPrint(Common::Point(INVENTORY_POINTS[3][2], CONTROLS_Y1),
+			_invMode == INVMODE_GIVE ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND,
+			false, fixedText_Give);
+		screen.gPrint(Common::Point(INVENTORY_POINTS[4][2], CONTROLS_Y1),
+			_invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
+			"^^"); // 2 arrows pointing to the left
+		screen.gPrint(Common::Point(INVENTORY_POINTS[5][2], CONTROLS_Y1),
+			_invIndex == 0 ? COMMAND_NULL : COMMAND_FOREGROUND,
+			"^"); // 1 arrow pointing to the left
+		screen.gPrint(Common::Point(INVENTORY_POINTS[6][2], CONTROLS_Y1),
+			(_holdings - _invIndex < 7) ? COMMAND_NULL : COMMAND_FOREGROUND,
+			"_"); // 1 arrow pointing to the right
+		screen.gPrint(Common::Point(INVENTORY_POINTS[7][2], CONTROLS_Y1),
+			(_holdings - _invIndex < 7) ? COMMAND_NULL : COMMAND_FOREGROUND,
+			"__"); // 2 arrows pointing to the right
+	}
+}
+
+void ScalpelInventory::highlight(int index, byte color) {
+	Screen &screen = *_vm->_screen;
+	Surface &bb = *screen._backBuffer;
+	int slot = index - _invIndex;
+	ImageFrame &frame = (*_invShapes[slot])[0];
+
+	bb.fillRect(Common::Rect(8 + slot * 52, 165, (slot + 1) * 52, 194), color);
+	bb.transBlitFrom(frame, Common::Point(6 + slot * 52 + ((47 - frame._width) / 2),
+		163 + ((33 - frame._height) / 2)));
+	screen.slamArea(8 + slot * 52, 165, 44, 30);
+}
+
+void ScalpelInventory::refreshInv() {
+	Screen &screen = *_vm->_screen;
+	Talk &talk = *_vm->_talk;
+	ScalpelUserInterface &ui = *(ScalpelUserInterface *)_vm->_ui;
+
+	ui._invLookFlag = true;
+	freeInv();
+
+	ui._infoFlag = true;
+	ui.clearInfo();
+
+	screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(0, CONTROLS_Y),
+		Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+	ui.examine();
+
+	if (!talk._talkToAbort) {
+		screen._backBuffer2.blitFrom((*ui._controlPanel)[0], Common::Point(0, CONTROLS_Y));
+		loadInv();
+	}
+}
+
+void ScalpelInventory::putInv(InvSlamMode slamIt) {
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+	UserInterface &ui = *_vm->_ui;
+
+	// If an inventory item has disappeared (due to using it or giving it),
+	// a blank space slot may have appeared. If so, adjust the inventory
+	if (_invIndex > 0 && _invIndex > (_holdings - 6)) {
+		--_invIndex;
+		freeGraphics();
+		loadGraphics();
+	}
+
+	if (slamIt != SLAM_SECONDARY_BUFFER) {
+		screen.makePanel(Common::Rect(6, 163, 54, 197));
+		screen.makePanel(Common::Rect(58, 163, 106, 197));
+		screen.makePanel(Common::Rect(110, 163, 158, 197));
+		screen.makePanel(Common::Rect(162, 163, 210, 197));
+		screen.makePanel(Common::Rect(214, 163, 262, 197));
+		screen.makePanel(Common::Rect(266, 163, 314, 197));
+	}
+
+	// Iterate through displaying up to 6 objects at a time
+	for (int idx = _invIndex; idx < _holdings && (idx - _invIndex) < MAX_VISIBLE_INVENTORY; ++idx) {
+		int itemNum = idx - _invIndex;
+		Surface &bb = slamIt == SLAM_SECONDARY_BUFFER ? screen._backBuffer2 : screen._backBuffer1;
+		Common::Rect r(8 + itemNum * 52, 165, 51 + itemNum * 52, 194);
+
+		// Draw the background
+		if (idx == ui._selector) {
+			bb.fillRect(r, BUTTON_BACKGROUND);
+		}
+		else if (slamIt == SLAM_SECONDARY_BUFFER) {
+			bb.fillRect(r, BUTTON_MIDDLE);
+		}
+
+		// Draw the item image
+		ImageFrame &frame = (*_invShapes[itemNum])[0];
+		bb.transBlitFrom(frame, Common::Point(6 + itemNum * 52 + ((47 - frame._width) / 2),
+			163 + ((33 - frame._height) / 2)));
+	}
+
+	if (slamIt == SLAM_DISPLAY)
+		screen.slamArea(6, 163, 308, 34);
+
+	if (slamIt != SLAM_SECONDARY_BUFFER)
+		ui.clearInfo();
+
+	if (slamIt == 0) {
+		invCommands(0);
+	}
+	else if (slamIt == SLAM_SECONDARY_BUFFER) {
+		screen._backBuffer = &screen._backBuffer2;
+		invCommands(0);
+		screen._backBuffer = &screen._backBuffer1;
+	}
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_inventory.h b/engines/sherlock/scalpel/scalpel_inventory.h
new file mode 100644
index 0000000..953e024
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_inventory.h
@@ -0,0 +1,68 @@
+/* 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_INVENTORY_H
+#define SHERLOCK_SCALPEL_INVENTORY_H
+
+#include "sherlock/inventory.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+class ScalpelInventory : public Inventory {
+public:
+	ScalpelInventory(SherlockEngine *vm);
+	~ScalpelInventory();
+
+	/**
+	 * Put the game into inventory mode and open the interface window.
+	 */
+	void drawInventory(InvNewMode flag);
+
+	/**
+	 * Prints the line of inventory commands at the top of an inventory window with
+	 * the correct highlighting
+	 */
+	void invCommands(bool slamIt);
+
+	/**
+	 * Set the highlighting color of a given inventory item
+	 */
+	void highlight(int index, byte color);
+
+	/**
+	 * Support method for refreshing the display of the inventory
+	 */
+	void refreshInv();
+
+	/**
+	 * Display the character's inventory. The slamIt parameter specifies:
+	 */
+	void putInv(InvSlamMode slamIt);
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/scalpel_journal.cpp b/engines/sherlock/scalpel/scalpel_journal.cpp
index 12ebe6f..8bb74e9 100644
--- a/engines/sherlock/scalpel/scalpel_journal.cpp
+++ b/engines/sherlock/scalpel/scalpel_journal.cpp
@@ -23,6 +23,8 @@
 #include "sherlock/journal.h"
 #include "sherlock/sherlock.h"
 #include "sherlock/scalpel/scalpel_journal.h"
+#include "sherlock/scalpel/scalpel_screen.h"
+#include "sherlock/scalpel/scalpel.h"
 #include "sherlock/tattoo/tattoo_journal.h"
 
 namespace Sherlock {
@@ -147,7 +149,7 @@ void ScalpelJournal::loadLocations() {
 void ScalpelJournal::drawFrame() {
 	FixedText &fixedText = *_vm->_fixedText;
 	Resources &res = *_vm->_res;
-	Screen &screen = *_vm->_screen;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
 	byte palette[PALETTE_SIZE];
 
 	// Load in the journal background
@@ -211,7 +213,7 @@ void ScalpelJournal::drawFrame() {
 }
 
 void ScalpelJournal::drawInterface() {
-	Screen &screen = *_vm->_screen;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
 
 	drawFrame();
 
@@ -229,7 +231,7 @@ void ScalpelJournal::drawInterface() {
 
 void ScalpelJournal::doArrows() {
 	FixedText &fixedText = *_vm->_fixedText;
-	Screen &screen = *_vm->_screen;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
 	byte color;
 
 	Common::String fixedText_Back10         = fixedText.getText(kFixedText_Journal_Back10);
@@ -301,7 +303,7 @@ JournalButton ScalpelJournal::getHighlightedButton(const Common::Point &pt) {
 bool ScalpelJournal::handleEvents(int key) {
 	Events    &events    = *_vm->_events;
 	FixedText &fixedText = *_vm->_fixedText;
-	Screen    &screen    = *_vm->_screen;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
 	bool doneFlag = false;
 
 	Common::Point pt = events.mousePos();
@@ -484,7 +486,7 @@ int ScalpelJournal::getSearchString(bool printError) {
 
 	Events    &events    = *_vm->_events;
 	FixedText &fixedText = *_vm->_fixedText;
-	Screen    &screen    = *_vm->_screen;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
 	Talk &talk = *_vm->_talk;
 	int xp;
 	int yp = 174;
diff --git a/engines/sherlock/scalpel/scalpel_saveload.cpp b/engines/sherlock/scalpel/scalpel_saveload.cpp
new file mode 100644
index 0000000..01ba149
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_saveload.cpp
@@ -0,0 +1,261 @@
+/* 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_saveload.h"
+#include "sherlock/scalpel/scalpel_screen.h"
+#include "sherlock/scalpel/scalpel.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+const int ENV_POINTS[6][3] = {
+	{ 41, 80, 61 },		// Exit
+	{ 81, 120, 101 },	// Load
+	{ 121, 160, 141 },	// Save
+	{ 161, 200, 181 },	// Up
+	{ 201, 240, 221 },	// Down
+	{ 241, 280, 261 }	// Quit
+};
+
+/*----------------------------------------------------------------*/
+
+ScalpelSaveManager::ScalpelSaveManager(SherlockEngine *vm, const Common::String &target) : SaveManager(vm, target) {
+}
+
+void ScalpelSaveManager::drawInterface() {
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+	UserInterface &ui = *_vm->_ui;
+
+	// Create a list of savegame slots
+	createSavegameList();
+
+	screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + 10), BORDER_COLOR);
+	screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y + 10, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+	screen._backBuffer1.fillRect(Common::Rect(318, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+	screen._backBuffer1.fillRect(Common::Rect(0, 199, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+	screen._backBuffer1.fillRect(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND);
+
+	screen.makeButton(Common::Rect(ENV_POINTS[0][0], CONTROLS_Y, ENV_POINTS[0][1], CONTROLS_Y + 10),
+		ENV_POINTS[0][2] - screen.stringWidth("Exit") / 2, "Exit");
+	screen.makeButton(Common::Rect(ENV_POINTS[1][0], CONTROLS_Y, ENV_POINTS[1][1], CONTROLS_Y + 10),
+		ENV_POINTS[1][2] - screen.stringWidth("Load") / 2, "Load");
+	screen.makeButton(Common::Rect(ENV_POINTS[2][0], CONTROLS_Y, ENV_POINTS[2][1], CONTROLS_Y + 10),
+		ENV_POINTS[2][2] - screen.stringWidth("Save") / 2, "Save");
+	screen.makeButton(Common::Rect(ENV_POINTS[3][0], CONTROLS_Y, ENV_POINTS[3][1], CONTROLS_Y + 10),
+		ENV_POINTS[3][2] - screen.stringWidth("Up") / 2, "Up");
+	screen.makeButton(Common::Rect(ENV_POINTS[4][0], CONTROLS_Y, ENV_POINTS[4][1], CONTROLS_Y + 10),
+		ENV_POINTS[4][2] - screen.stringWidth("Down") / 2, "Down");
+	screen.makeButton(Common::Rect(ENV_POINTS[5][0], CONTROLS_Y, ENV_POINTS[5][1], CONTROLS_Y + 10),
+		ENV_POINTS[5][2] - screen.stringWidth("Quit") / 2, "Quit");
+
+	if (!_savegameIndex)
+		screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_NULL, 0, "Up");
+
+	if (_savegameIndex == MAX_SAVEGAME_SLOTS - ONSCREEN_FILES_COUNT)
+		screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_NULL, 0, "Down");
+
+	for (int idx = _savegameIndex; idx < _savegameIndex + ONSCREEN_FILES_COUNT; ++idx) {
+		screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10),
+			INV_FOREGROUND, "%d.", idx + 1);
+		screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10),
+			INV_FOREGROUND, "%s", _savegames[idx].c_str());
+	}
+
+	if (!ui._slideWindows) {
+		screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+	} else {
+		ui.summonWindow();
+	}
+
+	_envMode = SAVEMODE_NONE;
+}
+
+int ScalpelSaveManager::getHighlightedButton() const {
+	Common::Point pt = _vm->_events->mousePos();
+
+	for (int idx = 0; idx < 6; ++idx) {
+		if (pt.x > ENV_POINTS[idx][0] && pt.x < ENV_POINTS[idx][1] && pt.y > CONTROLS_Y
+				&& pt.y < (CONTROLS_Y + 10))
+			return idx;
+	}
+
+	return -1;
+}
+
+void ScalpelSaveManager::highlightButtons(int btnIndex) {
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+	byte color = (btnIndex == 0) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND;
+
+	screen.buttonPrint(Common::Point(ENV_POINTS[0][2], CONTROLS_Y), color, 1, "Exit");
+
+	if ((btnIndex == 1) || ((_envMode == SAVEMODE_LOAD) && (btnIndex != 2)))
+		screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Load");
+	else
+		screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Load");
+
+	if ((btnIndex == 2) || ((_envMode == SAVEMODE_SAVE) && (btnIndex != 1)))
+		screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Save");
+	else
+		screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Save");
+
+	if (btnIndex == 3 && _savegameIndex)
+		screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Up");
+	else
+		if (_savegameIndex)
+			screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Up");
+
+	if ((btnIndex == 4) && (_savegameIndex < MAX_SAVEGAME_SLOTS - 5))
+		screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "Down");
+	else if (_savegameIndex < (MAX_SAVEGAME_SLOTS - 5))
+		screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_FOREGROUND, true, "Down");
+
+	color = (btnIndex == 5) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND;
+	screen.buttonPrint(Common::Point(ENV_POINTS[5][2], CONTROLS_Y), color, 1, "Quit");
+}
+
+bool ScalpelSaveManager::checkGameOnScreen(int slot) {
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+
+	// Check if it's already on-screen
+	if (slot != -1 && (slot < _savegameIndex || slot >= (_savegameIndex + ONSCREEN_FILES_COUNT))) {
+		_savegameIndex = slot;
+
+		screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2,
+			SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND);
+
+		for (int idx = _savegameIndex; idx < (_savegameIndex + 5); ++idx) {
+			screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10),
+				INV_FOREGROUND, "%d.", idx + 1);
+			screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - _savegameIndex) * 10),
+				INV_FOREGROUND, "%s", _savegames[idx].c_str());
+		}
+
+		screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, 318, SHERLOCK_SCREEN_HEIGHT));
+
+		byte color = !_savegameIndex ? COMMAND_NULL : COMMAND_FOREGROUND;
+		screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), color, 1, "Up");
+
+		color = (_savegameIndex == (MAX_SAVEGAME_SLOTS - 5)) ? COMMAND_NULL : COMMAND_FOREGROUND;
+		screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, 1, "Down");
+
+		return true;
+	}
+
+	return false;
+}
+
+bool ScalpelSaveManager::promptForDescription(int slot) {
+	Events &events = *_vm->_events;
+	Scene &scene = *_vm->_scene;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+	Talk &talk = *_vm->_talk;
+	int xp, yp;
+	bool flag = false;
+
+	screen.buttonPrint(Common::Point(ENV_POINTS[0][2], CONTROLS_Y), COMMAND_NULL, true, "Exit");
+	screen.buttonPrint(Common::Point(ENV_POINTS[1][2], CONTROLS_Y), COMMAND_NULL, true, "Load");
+	screen.buttonPrint(Common::Point(ENV_POINTS[2][2], CONTROLS_Y), COMMAND_NULL, true, "Save");
+	screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), COMMAND_NULL, true, "Up");
+	screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_NULL, true, "Down");
+	screen.buttonPrint(Common::Point(ENV_POINTS[5][2], CONTROLS_Y), COMMAND_NULL, true, "Quit");
+
+	Common::String saveName = _savegames[slot];
+	if (isSlotEmpty(slot)) {
+		// It's an empty slot, so start off with an empty save name
+		saveName = "";
+
+		yp = CONTROLS_Y + 12 + (slot - _savegameIndex) * 10;
+		screen.vgaBar(Common::Rect(24, yp, 85, yp + 9), INV_BACKGROUND);
+	}
+
+	screen.print(Common::Point(6, CONTROLS_Y + 12 + (slot - _savegameIndex) * 10), TALK_FOREGROUND, "%d.", slot + 1);
+	screen.print(Common::Point(24, CONTROLS_Y + 12 + (slot - _savegameIndex) * 10), TALK_FOREGROUND, "%s", saveName.c_str());
+	xp = 24 + screen.stringWidth(saveName);
+	yp = CONTROLS_Y + 12 + (slot - _savegameIndex) * 10;
+
+	int done = 0;
+	do {
+		while (!_vm->shouldQuit() && !events.kbHit()) {
+			scene.doBgAnim();
+
+			if (talk._talkToAbort)
+				return false;
+
+			// Allow event processing
+			events.pollEventsAndWait();
+			events.setButtonState();
+
+			flag = !flag;
+			if (flag)
+				screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND);
+			else
+				screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND);
+		}
+		if (_vm->shouldQuit())
+			return false;
+
+		// Get the next keypress
+		Common::KeyState keyState = events.getKey();
+
+		if (keyState.keycode == Common::KEYCODE_BACKSPACE && saveName.size() > 0) {
+			// Delete character of save name
+			screen.vgaBar(Common::Rect(xp - screen.charWidth(saveName.lastChar()), yp - 1,
+				xp + 8, yp + 9), INV_BACKGROUND);
+			xp -= screen.charWidth(saveName.lastChar());
+			screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND);
+			saveName.deleteLastChar();
+		
+		} else if (keyState.keycode == Common::KEYCODE_RETURN && saveName.compareToIgnoreCase(EMPTY_SAVEGAME_SLOT)) {
+			done = 1;
+
+		} else if (keyState.keycode == Common::KEYCODE_ESCAPE) {
+			screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND);
+			done = -1;
+		
+		} else if (keyState.ascii >= ' ' && keyState.ascii <= 'z' && saveName.size() < 50
+				&& (xp + screen.charWidth(keyState.ascii)) < 308) {
+			char c = (char)keyState.ascii;
+
+			screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_BACKGROUND);
+			screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", c);
+			xp += screen.charWidth(c);
+			screen.vgaBar(Common::Rect(xp, yp - 1, xp + 8, yp + 9), INV_FOREGROUND);
+			saveName += c;
+		}
+	} while (!done);
+
+	if (done == 1) {
+		// Enter key perssed
+		_savegames[slot] = saveName;
+	} else {
+		done = 0;
+		_envMode = SAVEMODE_NONE;
+		highlightButtons(-1);
+	}
+
+	return done == 1;
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_saveload.h b/engines/sherlock/scalpel/scalpel_saveload.h
new file mode 100644
index 0000000..db4fa1a
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_saveload.h
@@ -0,0 +1,69 @@
+/* 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_SAVELOAD_H
+#define SHERLOCK_SCALPEL_SAVELOAD_H
+
+#include "sherlock/saveload.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+extern const int ENV_POINTS[6][3];
+
+class ScalpelSaveManager: public SaveManager {
+public:
+	ScalpelSaveManager(SherlockEngine *vm, const Common::String &target);
+	virtual ~ScalpelSaveManager() {}
+
+	/**
+	 * Shows the in-game dialog interface for loading and saving games
+	 */
+	void drawInterface();
+
+	/**
+	 * Return the index of the button the mouse is over, if any
+	 */
+	int getHighlightedButton() const;
+
+	/**
+	 * Handle highlighting buttons
+	 */
+	void highlightButtons(int btnIndex);
+
+	/**
+	 * Make sure that the selected savegame is on-screen
+	 */
+	bool checkGameOnScreen(int slot);
+
+	/**
+	 * Prompts the user to enter a description in a given slot
+	 */
+	bool promptForDescription(int slot);
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/scalpel_screen.cpp b/engines/sherlock/scalpel/scalpel_screen.cpp
new file mode 100644
index 0000000..2096dab
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_screen.cpp
@@ -0,0 +1,93 @@
+/* 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_screen.h"
+#include "sherlock/scalpel/scalpel.h"
+
+namespace Sherlock {
+
+namespace Scalpel {
+
+ScalpelScreen::ScalpelScreen(SherlockEngine *vm) : Screen(vm) {
+}
+
+void ScalpelScreen::makeButton(const Common::Rect &bounds, int textX,
+		const Common::String &str) {
+
+	Surface &bb = *_backBuffer;
+	bb.fillRect(Common::Rect(bounds.left, bounds.top, bounds.right, bounds.top + 1), BUTTON_TOP);
+	bb.fillRect(Common::Rect(bounds.left, bounds.top, bounds.left + 1, bounds.bottom), BUTTON_TOP);
+	bb.fillRect(Common::Rect(bounds.right - 1, bounds.top, bounds.right, bounds.bottom), BUTTON_BOTTOM);
+	bb.fillRect(Common::Rect(bounds.left + 1, bounds.bottom - 1, bounds.right, bounds.bottom), BUTTON_BOTTOM);
+	bb.fillRect(Common::Rect(bounds.left + 1, bounds.top + 1, bounds.right - 1, bounds.bottom - 1), BUTTON_MIDDLE);
+
+	gPrint(Common::Point(textX, bounds.top), COMMAND_HIGHLIGHTED, "%c", str[0]);
+	gPrint(Common::Point(textX + charWidth(str[0]), bounds.top),
+		COMMAND_FOREGROUND, "%s", str.c_str() + 1);
+}
+
+void ScalpelScreen::buttonPrint(const Common::Point &pt, byte color, bool slamIt,
+		const Common::String &str) {
+	int xStart = pt.x - stringWidth(str) / 2;
+
+	if (color == COMMAND_FOREGROUND) {
+		// First character needs to be highlighted
+		if (slamIt) {
+			print(Common::Point(xStart, pt.y + 1), COMMAND_HIGHLIGHTED, "%c", str[0]);
+			print(Common::Point(xStart + charWidth(str[0]), pt.y + 1),
+				COMMAND_FOREGROUND, "%s", str.c_str() + 1);
+		} else {
+			gPrint(Common::Point(xStart, pt.y), COMMAND_HIGHLIGHTED, "%c", str[0]);
+			gPrint(Common::Point(xStart + charWidth(str[0]), pt.y),
+				COMMAND_FOREGROUND, "%s", str.c_str() + 1);
+		}
+	} else if (slamIt) {
+		print(Common::Point(xStart, pt.y + 1), color, "%s", str.c_str());
+	} else {
+		gPrint(Common::Point(xStart, pt.y), color, "%s", str.c_str());
+	}
+}
+
+void ScalpelScreen::makePanel(const Common::Rect &r) {
+	_backBuffer->fillRect(r, BUTTON_MIDDLE);
+	_backBuffer->hLine(r.left, r.top, r.right - 2, BUTTON_TOP);
+	_backBuffer->hLine(r.left + 1, r.top + 1, r.right - 3, BUTTON_TOP);
+	_backBuffer->vLine(r.left, r.top, r.bottom - 1, BUTTON_TOP);
+	_backBuffer->vLine(r.left + 1, r.top + 1, r.bottom - 2, BUTTON_TOP);
+
+	_backBuffer->vLine(r.right - 1, r.top, r.bottom - 1, BUTTON_BOTTOM);
+	_backBuffer->vLine(r.right - 2, r.top + 1, r.bottom - 2, BUTTON_BOTTOM);
+	_backBuffer->hLine(r.left, r.bottom - 1, r.right - 1, BUTTON_BOTTOM);
+	_backBuffer->hLine(r.left + 1, r.bottom - 2, r.right - 1, BUTTON_BOTTOM);
+}
+
+void ScalpelScreen::makeField(const Common::Rect &r) {
+	_backBuffer->fillRect(r, BUTTON_MIDDLE);
+	_backBuffer->hLine(r.left, r.top, r.right - 1, BUTTON_BOTTOM);
+	_backBuffer->hLine(r.left + 1, r.bottom - 1, r.right - 1, BUTTON_TOP);
+	_backBuffer->vLine(r.left, r.top + 1, r.bottom - 1, BUTTON_BOTTOM);
+	_backBuffer->vLine(r.right - 1, r.top + 1, r.bottom - 2, BUTTON_TOP);
+}
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_screen.h b/engines/sherlock/scalpel/scalpel_screen.h
new file mode 100644
index 0000000..472fe9e
--- /dev/null
+++ b/engines/sherlock/scalpel/scalpel_screen.h
@@ -0,0 +1,66 @@
+/* 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_SCREEN_H
+#define SHERLOCK_SCALPEL_SCREEN_H
+
+#include "sherlock/screen.h"
+
+namespace Sherlock {
+
+class SherlockEngine;
+
+namespace Scalpel {
+
+class ScalpelScreen : public Screen {
+public:
+	ScalpelScreen(SherlockEngine *vm);
+	virtual ~ScalpelScreen() {}
+
+	/**
+	 * Draws a button for use in the inventory, talk, and examine dialogs.
+	 */
+	void makeButton(const Common::Rect &bounds, int textX, const Common::String &str);
+
+	/**
+	 * Prints an interface command with the first letter highlighted to indicate
+	 * what keyboard shortcut is associated with it
+	 */
+	void buttonPrint(const Common::Point &pt, byte color, bool slamIt, const Common::String &str);
+
+	/**
+	 * Draw a panel in the back buffer with a raised area effect around the edges
+	 */
+	void makePanel(const Common::Rect &r);
+
+	/**
+	 * Draw a field in the back buffer with a raised area effect around the edges,
+	 * suitable for text input.
+	 */
+	void makeField(const Common::Rect &r);
+};
+
+} // End of namespace Scalpel
+
+} // End of namespace Sherlock
+
+#endif
diff --git a/engines/sherlock/scalpel/scalpel_talk.cpp b/engines/sherlock/scalpel/scalpel_talk.cpp
index 5a2427c..33d0e4a 100644
--- a/engines/sherlock/scalpel/scalpel_talk.cpp
+++ b/engines/sherlock/scalpel/scalpel_talk.cpp
@@ -24,8 +24,9 @@
 #include "sherlock/scalpel/scalpel_map.h"
 #include "sherlock/scalpel/scalpel_people.h"
 #include "sherlock/scalpel/scalpel_scene.h"
+#include "sherlock/scalpel/scalpel_screen.h"
 #include "sherlock/scalpel/scalpel_user_interface.h"
-#include "sherlock/sherlock.h"
+#include "sherlock/scalpel/scalpel.h"
 #include "sherlock/screen.h"
 #include "sherlock/scalpel/3do/movie_decoder.h"
 
@@ -173,7 +174,7 @@ ScalpelTalk::ScalpelTalk(SherlockEngine *vm) : Talk(vm) {
 void ScalpelTalk::talkInterface(const byte *&str) {
 	FixedText &fixedText = *_vm->_fixedText;
 	People &people = *_vm->_people;
-	Screen &screen = *_vm->_screen;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
 	UserInterface &ui = *_vm->_ui;
 
 	// If the window isn't yet open, draw the window before printing starts
@@ -504,7 +505,7 @@ OpcodeReturn ScalpelTalk::cmdSfxCommand(const byte *&str) {
 OpcodeReturn ScalpelTalk::cmdSummonWindow(const byte *&str) {
 	Events       &events = *_vm->_events;
 	FixedText &fixedText = *_vm->_fixedText;
-	Screen       &screen = *_vm->_screen;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
 
 	drawInterface();
 	events._pressed = events._released = false;
@@ -597,6 +598,240 @@ void ScalpelTalk::talk3DOMovieTrigger(int subIndex) {
 	_vm->_screen->makeAllDirty();
 }
 
+void ScalpelTalk::drawInterface() {
+	FixedText &fixedText = *_vm->_fixedText;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+	Surface &bb = *screen._backBuffer;
+
+	bb.fillRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y1 + 10), BORDER_COLOR);
+	bb.fillRect(Common::Rect(0, CONTROLS_Y + 10, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+	bb.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 10,
+		SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+	bb.fillRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 1, SHERLOCK_SCREEN_WIDTH - 2,
+		SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
+	bb.fillRect(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2,
+		SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND);
+
+	if (_talkTo != -1) {
+		Common::String fixedText_Exit = fixedText.getText(kFixedText_Window_Exit);
+		Common::String fixedText_Up   = fixedText.getText(kFixedText_Window_Up);
+		Common::String fixedText_Down = fixedText.getText(kFixedText_Window_Down);
+
+		screen.makeButton(Common::Rect(99, CONTROLS_Y, 139, CONTROLS_Y + 10),
+			119 - screen.stringWidth(fixedText_Exit) / 2, fixedText_Exit);
+		screen.makeButton(Common::Rect(140, CONTROLS_Y, 180, CONTROLS_Y + 10),
+			159 - screen.stringWidth(fixedText_Up) / 2, fixedText_Up);
+		screen.makeButton(Common::Rect(181, CONTROLS_Y, 221, CONTROLS_Y + 10),
+			200 - screen.stringWidth(fixedText_Down) / 2, fixedText_Down);
+	} else {
+		int strWidth = screen.stringWidth(Scalpel::PRESS_KEY_TO_CONTINUE);
+		screen.makeButton(Common::Rect(46, CONTROLS_Y, 273, CONTROLS_Y + 10),
+			160 - strWidth / 2, Scalpel::PRESS_KEY_TO_CONTINUE);
+		screen.gPrint(Common::Point(160 - strWidth / 2, CONTROLS_Y), COMMAND_FOREGROUND, "P");
+	}
+}
+
+bool ScalpelTalk::displayTalk(bool slamIt) {
+	FixedText &fixedText = *_vm->_fixedText;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+	int yp = CONTROLS_Y + 14;
+	int lineY = -1;
+	_moreTalkDown = _moreTalkUp = false;
+
+	for (uint idx = 0; idx < _statements.size(); ++idx) {
+		_statements[idx]._talkPos.top = _statements[idx]._talkPos.bottom = -1;
+	}
+
+	if (_talkIndex) {
+		for (int idx = 0; idx < _talkIndex && !_moreTalkUp; ++idx) {
+			if (_statements[idx]._talkMap != -1)
+				_moreTalkUp = true;
+		}
+	}
+
+	// Display the up arrow and enable Up button if the first option is scrolled off-screen
+	Common::String fixedText_Up   = fixedText.getText(kFixedText_Window_Up);
+	Common::String fixedText_Down = fixedText.getText(kFixedText_Window_Down);
+	if (_moreTalkUp) {
+		if (slamIt) {
+			screen.print(Common::Point(5, CONTROLS_Y + 13), INV_FOREGROUND, "~");
+			screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_FOREGROUND, true, fixedText_Up);
+		} else {
+			screen.gPrint(Common::Point(5, CONTROLS_Y + 12), INV_FOREGROUND, "~");
+			screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_FOREGROUND, false, fixedText_Up);
+		}
+	} else {
+		if (slamIt) {
+			screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, true, fixedText_Up);
+			screen.vgaBar(Common::Rect(5, CONTROLS_Y + 11, 15, CONTROLS_Y + 22), INV_BACKGROUND);
+		} else {
+			screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, false, fixedText_Up);
+			screen._backBuffer1.fillRect(Common::Rect(5, CONTROLS_Y + 11,
+				15, CONTROLS_Y + 22), INV_BACKGROUND);
+		}
+	}
+
+	// Loop through the statements
+	bool done = false;
+	for (uint idx = _talkIndex; idx < _statements.size() && !done; ++idx) {
+		Statement &statement = _statements[idx];
+
+		if (statement._talkMap != -1) {
+			bool flag = _talkHistory[_converseNum][idx];
+			lineY = talkLine(idx, statement._talkMap, flag ? TALK_NULL : INV_FOREGROUND,
+				yp, slamIt);
+
+			if (lineY != -1) {
+				statement._talkPos.top = yp;
+				yp = lineY;
+				statement._talkPos.bottom = yp;
+
+				if (yp == SHERLOCK_SCREEN_HEIGHT)
+					done = true;
+			} else {
+				done = true;
+			}
+		}
+	}
+
+	// Display the down arrow and enable down button if there are more statements available down off-screen
+	if (lineY == -1 || lineY == SHERLOCK_SCREEN_HEIGHT) {
+		_moreTalkDown = true;
+
+		if (slamIt) {
+			screen.print(Common::Point(5, 190), INV_FOREGROUND, "|");
+			screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, true, fixedText_Down);
+		} else {
+			screen.gPrint(Common::Point(5, 189), INV_FOREGROUND, "|");
+			screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, false, fixedText_Down);
+		}
+	} else {
+		if (slamIt) {
+			screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, true, fixedText_Down);
+			screen.vgaBar(Common::Rect(5, 189, 16, 199), INV_BACKGROUND);
+		} else {
+			screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, false, fixedText_Down);
+			screen._backBuffer1.fillRect(Common::Rect(5, 189, 16, 199), INV_BACKGROUND);
+		}
+	}
+
+	return done;
+}
+
+int ScalpelTalk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt) {
+	Screen &screen = *_vm->_screen;
+	int idx = lineNum;
+	Common::String msg, number;
+	bool numberFlag = false;
+
+	// Get the statement to display as well as optional number prefix
+	if (idx < SPEAKER_REMOVE) {
+		number = Common::String::format("%d.", stateNum + 1);
+		numberFlag = true;
+	} else {
+		idx -= SPEAKER_REMOVE;
+	}
+	msg = _statements[idx]._statement;
+
+	// Handle potentially multiple lines needed to display entire statement
+	const char *lineStartP = msg.c_str();
+	int maxWidth = 298 - (numberFlag ? 18 : 0);
+	for (;;) {
+		// Get as much of the statement as possible will fit on the
+		Common::String sLine;
+		const char *lineEndP = lineStartP;
+		int width = 0;
+		do {
+			width += screen.charWidth(*lineEndP);
+		} while (*++lineEndP && width < maxWidth);
+
+		// Check if we need to wrap the line
+		if (width >= maxWidth) {
+			// Work backwards to the prior word's end
+			while (*--lineEndP != ' ')
+				;
+
+			sLine = Common::String(lineStartP, lineEndP++);
+		} else {
+			// Can display remainder of the statement on the current line
+			sLine = Common::String(lineStartP);
+		}
+
+
+		if (lineY <= (SHERLOCK_SCREEN_HEIGHT - 10)) {
+			// Need to directly display on-screen?
+			if (slamIt) {
+				// See if a numer prefix is needed or not
+				if (numberFlag) {
+					// Are we drawing the first line?
+					if (lineStartP == msg.c_str()) {
+						// We are, so print the number and then the text
+						screen.print(Common::Point(16, lineY), color, "%s", number.c_str());
+					}
+
+					// Draw the line with an indent
+					screen.print(Common::Point(30, lineY), color, "%s", sLine.c_str());
+				} else {
+					screen.print(Common::Point(16, lineY), color, "%s", sLine.c_str());
+				}
+			} else {
+				if (numberFlag) {
+					if (lineStartP == msg.c_str()) {
+						screen.gPrint(Common::Point(16, lineY - 1), color, "%s", number.c_str());
+					}
+
+					screen.gPrint(Common::Point(30, lineY - 1), color, "%s", sLine.c_str());
+				} else {
+					screen.gPrint(Common::Point(16, lineY - 1), color, "%s", sLine.c_str());
+				}
+			}
+
+			// Move to next line, if any
+			lineY += 9;
+			lineStartP = lineEndP;
+
+			if (!*lineEndP)
+				break;
+		} else {
+			// We're close to the bottom of the screen, so stop display
+			lineY = -1;
+			break;
+		}
+	}
+
+	if (lineY == -1 && lineStartP != msg.c_str())
+		lineY = SHERLOCK_SCREEN_HEIGHT;
+
+	// Return the Y position of the next line to follow this one
+	return lineY;
+}
+
+void ScalpelTalk::showTalk() {
+	FixedText &fixedText = *_vm->_fixedText;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
+	ScalpelUserInterface &ui = *(ScalpelUserInterface *)_vm->_ui;
+	Common::String fixedText_Exit = fixedText.getText(kFixedText_Window_Exit);
+	byte color = ui._endKeyActive ? COMMAND_FOREGROUND : COMMAND_NULL;
+
+	// If the window is already open, simply draw. Otherwise, do it
+	// to the back buffer and then summon the window
+	if (ui._windowOpen) {
+		screen.buttonPrint(Common::Point(119, CONTROLS_Y), color, true, fixedText_Exit);
+	} else {
+		screen.buttonPrint(Common::Point(119, CONTROLS_Y), color, false, fixedText_Exit);
+
+		if (!ui._slideWindows) {
+			screen.slamRect(Common::Rect(0, CONTROLS_Y,
+				SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
+		} else {
+			ui.summonWindow();
+		}
+
+		ui._windowOpen = true;
+	}
+
+}
+
 } // End of namespace Scalpel
 
 } // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_talk.h b/engines/sherlock/scalpel/scalpel_talk.h
index 2f8e412..01e7c05 100644
--- a/engines/sherlock/scalpel/scalpel_talk.h
+++ b/engines/sherlock/scalpel/scalpel_talk.h
@@ -68,9 +68,29 @@ protected:
 	 */
 	virtual void talk3DOMovieTrigger(int subIndex);
 
+	/**
+	 * Show the talk display
+	 */
+	virtual void showTalk();
 public:
 	ScalpelTalk(SherlockEngine *vm);
 	virtual ~ScalpelTalk() {}
+
+	/**
+	 * Draws the interface for conversation display
+	 */
+	void drawInterface();
+
+	/**
+	 * Display a list of statements in a window at the bottom of the screen that the
+	 * player can select from.
+	 */
+	bool displayTalk(bool slamIt);
+
+	/**
+	 * Prints a single conversation option in the interface window
+	 */
+	int talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt);
 };
 
 } // End of namespace Scalpel
diff --git a/engines/sherlock/scalpel/scalpel_user_interface.cpp b/engines/sherlock/scalpel/scalpel_user_interface.cpp
index f85c95e..9a07a40 100644
--- a/engines/sherlock/scalpel/scalpel_user_interface.cpp
+++ b/engines/sherlock/scalpel/scalpel_user_interface.cpp
@@ -21,9 +21,13 @@
  */
 
 #include "sherlock/scalpel/scalpel_user_interface.h"
+#include "sherlock/scalpel/scalpel_inventory.h"
 #include "sherlock/scalpel/scalpel_journal.h"
 #include "sherlock/scalpel/scalpel_people.h"
+#include "sherlock/scalpel/scalpel_saveload.h"
+#include "sherlock/scalpel/scalpel_screen.h"
 #include "sherlock/scalpel/settings.h"
+#include "sherlock/scalpel/scalpel.h"
 #include "sherlock/sherlock.h"
 
 namespace Sherlock {
@@ -666,9 +670,9 @@ void ScalpelUserInterface::lookInv() {
 
 void ScalpelUserInterface::doEnvControl() {
 	Events &events = *_vm->_events;
-	SaveManager &saves = *_vm->_saves;
+	ScalpelSaveManager &saves = *(ScalpelSaveManager *)_vm->_saves;
 	Scene &scene = *_vm->_scene;
-	Screen &screen = *_vm->_screen;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
 	Talk &talk = *_vm->_talk;
 	Common::Point mousePos = events.mousePos();
 	static const char ENV_COMMANDS[7] = "ELSUDQ";
@@ -969,9 +973,9 @@ void ScalpelUserInterface::doEnvControl() {
 void ScalpelUserInterface::doInvControl() {
 	Events &events = *_vm->_events;
 	FixedText &fixedText = *_vm->_fixedText;
-	Inventory &inv = *_vm->_inventory;
+	ScalpelInventory &inv = *(ScalpelInventory *)_vm->_inventory;
 	Scene &scene = *_vm->_scene;
-	Screen &screen = *_vm->_screen;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
 	Talk &talk = *_vm->_talk;
 	int colors[8];
 	Common::Point mousePos = events.mousePos();
@@ -1197,7 +1201,7 @@ void ScalpelUserInterface::doInvControl() {
 
 void ScalpelUserInterface::doLookControl() {
 	Events &events = *_vm->_events;
-	Inventory &inv = *_vm->_inventory;
+	ScalpelInventory &inv = *(ScalpelInventory *)_vm->_inventory;
 	Screen &screen = *_vm->_screen;
 
 	_key = _oldKey = -1;
@@ -1259,8 +1263,8 @@ void ScalpelUserInterface::doLookControl() {
 
 void ScalpelUserInterface::doMainControl() {
 	Events &events = *_vm->_events;
-	Inventory &inv = *_vm->_inventory;
-	SaveManager &saves = *_vm->_saves;
+	ScalpelInventory &inv = *(ScalpelInventory *)_vm->_inventory;
+	ScalpelSaveManager &saves = *(ScalpelSaveManager *)_vm->_saves;
 	Common::Point pt = events.mousePos();
 
 	if ((events._pressed || events._released) && pt.y > CONTROLS_Y) {
@@ -1476,7 +1480,7 @@ void ScalpelUserInterface::doTalkControl() {
 	FixedText &fixedText = *_vm->_fixedText;
 	ScalpelJournal &journal = *(ScalpelJournal *)_vm->_journal;
 	ScalpelPeople &people = *(ScalpelPeople *)_vm->_people;
-	Screen &screen = *_vm->_screen;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
 	Sound &sound = *_vm->_sound;
 	Talk &talk = *_vm->_talk;
 	Common::Point mousePos = events.mousePos();
@@ -1781,8 +1785,8 @@ void ScalpelUserInterface::journalControl() {
 
 void ScalpelUserInterface::printObjectDesc(const Common::String &str, bool firstTime) {
 	Events &events = *_vm->_events;
-	Inventory &inv = *_vm->_inventory;
-	Screen &screen = *_vm->_screen;
+	ScalpelInventory &inv = *(ScalpelInventory *)_vm->_inventory;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
 	Talk &talk = *_vm->_talk;
 
 	if (str.hasPrefix("_")) {
diff --git a/engines/sherlock/scalpel/settings.cpp b/engines/sherlock/scalpel/settings.cpp
index aa8033d..f6769a4 100644
--- a/engines/sherlock/scalpel/settings.cpp
+++ b/engines/sherlock/scalpel/settings.cpp
@@ -22,7 +22,9 @@
 
 #include "sherlock/sherlock.h"
 #include "sherlock/scalpel/settings.h"
+#include "sherlock/scalpel/scalpel_screen.h"
 #include "sherlock/scalpel/scalpel_user_interface.h"
+#include "sherlock/scalpel/scalpel.h"
 
 namespace Sherlock {
 
@@ -56,7 +58,7 @@ static const char *const SETUP_NAMES[12] = {
 
 void Settings::drawInteface(bool flag) {
 	People &people = *_vm->_people;
-	Screen &screen = *_vm->_screen;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
 	Sound &sound = *_vm->_sound;
 	Music &music = *_vm->_music;
 	UserInterface &ui = *_vm->_ui;
@@ -138,7 +140,7 @@ void Settings::drawInteface(bool flag) {
 int Settings::drawButtons(const Common::Point &pt, int _key) {
 	Events &events = *_vm->_events;
 	People &people = *_vm->_people;
-	Screen &screen = *_vm->_screen;
+	ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
 	Music &music = *_vm->_music;
 	Sound &sound = *_vm->_sound;
 	UserInterface &ui = *_vm->_ui;
diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp
index fdc10fd..4c6e0ef 100644
--- a/engines/sherlock/screen.cpp
+++ b/engines/sherlock/screen.cpp
@@ -22,12 +22,20 @@
 
 #include "sherlock/screen.h"
 #include "sherlock/sherlock.h"
+#include "sherlock/scalpel/scalpel_screen.h"
 #include "common/system.h"
 #include "common/util.h"
 #include "graphics/palette.h"
 
 namespace Sherlock {
 
+Screen *Screen::init(SherlockEngine *vm) {
+	if (vm->getGameID() == GType_SerratedScalpel)
+		return new Scalpel::ScalpelScreen(vm);
+	else
+		return new Screen(vm);
+}
+
 Screen::Screen(SherlockEngine *vm) : Surface(g_system->getWidth(), g_system->getHeight()), _vm(vm),
 		_backBuffer1(g_system->getWidth(), g_system->getHeight()),
 		_backBuffer2(g_system->getWidth(), g_system->getHeight()),
@@ -486,64 +494,6 @@ void Screen::vgaBar(const Common::Rect &r, int color) {
 	slamRect(r);
 }
 
-void Screen::makeButton(const Common::Rect &bounds, int textX,
-		const Common::String &str) {
-
-	Surface &bb = *_backBuffer;
-	bb.fillRect(Common::Rect(bounds.left, bounds.top, bounds.right, bounds.top + 1), BUTTON_TOP);
-	bb.fillRect(Common::Rect(bounds.left, bounds.top, bounds.left + 1, bounds.bottom), BUTTON_TOP);
-	bb.fillRect(Common::Rect(bounds.right - 1, bounds.top, bounds.right, bounds.bottom), BUTTON_BOTTOM);
-	bb.fillRect(Common::Rect(bounds.left + 1, bounds.bottom - 1, bounds.right, bounds.bottom), BUTTON_BOTTOM);
-	bb.fillRect(Common::Rect(bounds.left + 1, bounds.top + 1, bounds.right - 1, bounds.bottom - 1), BUTTON_MIDDLE);
-
-	gPrint(Common::Point(textX, bounds.top), COMMAND_HIGHLIGHTED, "%c", str[0]);
-	gPrint(Common::Point(textX + charWidth(str[0]), bounds.top),
-		COMMAND_FOREGROUND, "%s", str.c_str() + 1);
-}
-
-void Screen::buttonPrint(const Common::Point &pt, byte color, bool slamIt,
-		const Common::String &str) {
-	int xStart = pt.x - stringWidth(str) / 2;
-
-	if (color == COMMAND_FOREGROUND) {
-		// First character needs to be highlighted
-		if (slamIt) {
-			print(Common::Point(xStart, pt.y + 1), COMMAND_HIGHLIGHTED, "%c", str[0]);
-			print(Common::Point(xStart + charWidth(str[0]), pt.y + 1),
-				COMMAND_FOREGROUND, "%s", str.c_str() + 1);
-		} else {
-			gPrint(Common::Point(xStart, pt.y), COMMAND_HIGHLIGHTED, "%c", str[0]);
-			gPrint(Common::Point(xStart + charWidth(str[0]), pt.y),
-				COMMAND_FOREGROUND, "%s", str.c_str() + 1);
-		}
-	} else if (slamIt) {
-		print(Common::Point(xStart, pt.y + 1), color, "%s", str.c_str());
-	} else {
-		gPrint(Common::Point(xStart, pt.y), color, "%s", str.c_str());
-	}
-}
-
-void Screen::makePanel(const Common::Rect &r) {
-	_backBuffer->fillRect(r, BUTTON_MIDDLE);
-	_backBuffer->hLine(r.left, r.top, r.right - 2, BUTTON_TOP);
-	_backBuffer->hLine(r.left + 1, r.top + 1, r.right - 3, BUTTON_TOP);
-	_backBuffer->vLine(r.left, r.top, r.bottom - 1, BUTTON_TOP);
-	_backBuffer->vLine(r.left + 1, r.top + 1, r.bottom - 2, BUTTON_TOP);
-
-	_backBuffer->vLine(r.right - 1, r.top, r.bottom - 1, BUTTON_BOTTOM);
-	_backBuffer->vLine(r.right - 2, r.top + 1, r.bottom - 2, BUTTON_BOTTOM);
-	_backBuffer->hLine(r.left, r.bottom - 1, r.right - 1, BUTTON_BOTTOM);
-	_backBuffer->hLine(r.left + 1, r.bottom - 2, r.right - 1, BUTTON_BOTTOM);
-}
-
-void Screen::makeField(const Common::Rect &r) {
-	_backBuffer->fillRect(r, BUTTON_MIDDLE);
-	_backBuffer->hLine(r.left, r.top, r.right - 1, BUTTON_BOTTOM);
-	_backBuffer->hLine(r.left + 1, r.bottom - 1, r.right - 1, BUTTON_TOP);
-	_backBuffer->vLine(r.left, r.top + 1, r.bottom - 1, BUTTON_BOTTOM);
-	_backBuffer->vLine(r.right - 1, r.top + 1, r.bottom - 2, BUTTON_TOP);
-}
-
 void Screen::setDisplayBounds(const Common::Rect &r) {
 	assert(r.left == 0 && r.top == 0);
 	_sceneSurface.setPixels(_backBuffer1.getPixels(), r.width(), r.height(), _backBuffer1.getPixelFormat());
diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h
index a4b1a83..b67361e 100644
--- a/engines/sherlock/screen.h
+++ b/engines/sherlock/screen.h
@@ -44,10 +44,8 @@ enum {
 	BORDER_COLOR		= 237,
 	INV_FOREGROUND		= 14,
 	INV_BACKGROUND		= 1,
-	COMMAND_HIGHLIGHTED	= 10,
 	COMMAND_FOREGROUND	= 15,
 	COMMAND_BACKGROUND	= 4,
-	COMMAND_NULL		= 248,
 	BUTTON_TOP			= 233,
 	BUTTON_MIDDLE		= 244,
 	BUTTON_BOTTOM		= 248,
@@ -94,6 +92,7 @@ public:
 	byte _tMap[PALETTE_SIZE];
 	bool _flushScreen;
 public:
+	static Screen *init(SherlockEngine *vm);
 	Screen(SherlockEngine *vm);
 	virtual ~Screen();
 
@@ -210,28 +209,6 @@ public:
 	void vgaBar(const Common::Rect &r, int color);
 
 	/**
-	 * Draws a button for use in the inventory, talk, and examine dialogs.
-	 */
-	void makeButton(const Common::Rect &bounds, int textX, const Common::String &str);
-
-	/**
-	 * Prints an interface command with the first letter highlighted to indicate
-	 * what keyboard shortcut is associated with it
-	 */
-	void buttonPrint(const Common::Point &pt, byte color, bool slamIt, const Common::String &str);
-
-	/**
-	 * Draw a panel in the back buffer with a raised area effect around the edges
-	 */
-	void makePanel(const Common::Rect &r);
-
-	/**
-	 * Draw a field in the back buffer with a raised area effect around the edges,
-	 * suitable for text input.
-	 */
-	void makeField(const Common::Rect &r);
-
-	/**
 	 * Sets the active back buffer pointer to a restricted sub-area of the first back buffer
 	 */
 	void setDisplayBounds(const Common::Rect &r);
diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp
index aac6986..f491023 100644
--- a/engines/sherlock/sherlock.cpp
+++ b/engines/sherlock/sherlock.cpp
@@ -96,14 +96,14 @@ void SherlockEngine::initialize() {
 	_debugger = new Debugger(this);
 	_events = new Events(this);
 	_fixedText = new FixedText(this);
-	_inventory = new Inventory(this);
+	_inventory = Inventory::init(this);
 	_map = Map::init(this);
 	_music = new Music(this, _mixer);
 	_journal = Journal::init(this);
 	_people = People::init(this);
-	_saves = new SaveManager(this, _targetName);
+	_saves = SaveManager::init(this, _targetName);
 	_scene = Scene::init(this);
-	_screen = new Screen(this);
+	_screen = Screen::init(this);
 	_sound = new Sound(this, _mixer);
 	_talk = Talk::init(this);
 	_ui = UserInterface::init(this);
diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp
index 050d319..1195ba0 100644
--- a/engines/sherlock/talk.cpp
+++ b/engines/sherlock/talk.cpp
@@ -23,9 +23,11 @@
 #include "sherlock/talk.h"
 #include "sherlock/sherlock.h"
 #include "sherlock/screen.h"
+#include "sherlock/scalpel/scalpel.h"
 #include "sherlock/scalpel/scalpel_people.h"
 #include "sherlock/scalpel/scalpel_talk.h"
 #include "sherlock/scalpel/scalpel_user_interface.h"
+#include "sherlock/tattoo/tattoo.h"
 #include "sherlock/tattoo/tattoo_people.h"
 #include "sherlock/tattoo/tattoo_talk.h"
 
@@ -133,7 +135,6 @@ Talk::Talk(SherlockEngine *vm) : _vm(vm) {
 
 void Talk::talkTo(const Common::String &filename) {
 	Events &events = *_vm->_events;
-	FixedText &fixedText = *_vm->_fixedText;
 	Inventory &inv = *_vm->_inventory;
 	Journal &journal = *_vm->_journal;
 	People &people = *_vm->_people;
@@ -389,25 +390,7 @@ void Talk::talkTo(const Common::String &filename) {
 						displayTalk(true);
 					}
 
-					byte color = ui._endKeyActive ? COMMAND_FOREGROUND : COMMAND_NULL;
-
-					// If the window is already open, simply draw. Otherwise, do it
-					// to the back buffer and then summon the window
-					Common::String fixedText_Exit = fixedText.getText(kFixedText_Window_Exit);
-					if (ui._windowOpen) {
-						screen.buttonPrint(Common::Point(119, CONTROLS_Y), color, true, fixedText_Exit);
-					} else {
-						screen.buttonPrint(Common::Point(119, CONTROLS_Y), color, false, fixedText_Exit);
-
-						if (!ui._slideWindows) {
-							screen.slamRect(Common::Rect(0, CONTROLS_Y,
-								SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
-						} else {
-							ui.summonWindow();
-						}
-
-						ui._windowOpen = true;
-					}
+					showTalk();
 
 					// Break out of loop now that we're waiting for player input
 					events.setCursor(ARROW);
@@ -635,214 +618,6 @@ void Talk::setTalkMap() {
 	}
 }
 
-void Talk::drawInterface() {
-	FixedText &fixedText = *_vm->_fixedText;
-	Screen &screen = *_vm->_screen;
-	Surface &bb = *screen._backBuffer;
-
-	bb.fillRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y1 + 10), BORDER_COLOR);
-	bb.fillRect(Common::Rect(0, CONTROLS_Y + 10, 2, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
-	bb.fillRect(Common::Rect(SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 10,
-		SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
-	bb.fillRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 1, SHERLOCK_SCREEN_WIDTH - 2,
-		SHERLOCK_SCREEN_HEIGHT), BORDER_COLOR);
-	bb.fillRect(Common::Rect(2, CONTROLS_Y + 10, SHERLOCK_SCREEN_WIDTH - 2,
-		SHERLOCK_SCREEN_HEIGHT - 2), INV_BACKGROUND);
-
-	if (_talkTo != -1) {
-		Common::String fixedText_Exit = fixedText.getText(kFixedText_Window_Exit);
-		Common::String fixedText_Up   = fixedText.getText(kFixedText_Window_Up);
-		Common::String fixedText_Down = fixedText.getText(kFixedText_Window_Down);
-
-		screen.makeButton(Common::Rect(99, CONTROLS_Y, 139, CONTROLS_Y + 10),
-			119 - screen.stringWidth(fixedText_Exit) / 2, fixedText_Exit);
-		screen.makeButton(Common::Rect(140, CONTROLS_Y, 180, CONTROLS_Y + 10),
-			159 - screen.stringWidth(fixedText_Up) / 2, fixedText_Up);
-		screen.makeButton(Common::Rect(181, CONTROLS_Y, 221, CONTROLS_Y + 10),
-			200 - screen.stringWidth(fixedText_Down) / 2, fixedText_Down);
-	} else {
-		int strWidth = screen.stringWidth(Scalpel::PRESS_KEY_TO_CONTINUE);
-		screen.makeButton(Common::Rect(46, CONTROLS_Y, 273, CONTROLS_Y + 10),
-			160 - strWidth / 2, Scalpel::PRESS_KEY_TO_CONTINUE);
-		screen.gPrint(Common::Point(160 - strWidth / 2, CONTROLS_Y), COMMAND_FOREGROUND, "P");
-	}
-}
-
-bool Talk::displayTalk(bool slamIt) {
-	FixedText &fixedText = *_vm->_fixedText;
-	Screen &screen = *_vm->_screen;
-	int yp = CONTROLS_Y + 14;
-	int lineY = -1;
-	_moreTalkDown = _moreTalkUp = false;
-
-	for (uint idx = 0; idx < _statements.size(); ++idx) {
-		_statements[idx]._talkPos.top = _statements[idx]._talkPos.bottom = -1;
-	}
-
-	if (_talkIndex) {
-		for (int idx = 0; idx < _talkIndex && !_moreTalkUp; ++idx) {
-			if (_statements[idx]._talkMap != -1)
-				_moreTalkUp = true;
-		}
-	}
-
-	// Display the up arrow and enable Up button if the first option is scrolled off-screen
-	Common::String fixedText_Up   = fixedText.getText(kFixedText_Window_Up);
-	Common::String fixedText_Down = fixedText.getText(kFixedText_Window_Down);
-	if (_moreTalkUp) {
-		if (slamIt) {
-			screen.print(Common::Point(5, CONTROLS_Y + 13), INV_FOREGROUND, "~");
-			screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_FOREGROUND, true, fixedText_Up);
-		} else {
-			screen.gPrint(Common::Point(5, CONTROLS_Y + 12), INV_FOREGROUND, "~");
-			screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_FOREGROUND, false, fixedText_Up);
-		}
-	} else {
-		if (slamIt) {
-			screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, true, fixedText_Up);
-			screen.vgaBar(Common::Rect(5, CONTROLS_Y + 11, 15, CONTROLS_Y + 22), INV_BACKGROUND);
-		} else {
-			screen.buttonPrint(Common::Point(159, CONTROLS_Y), COMMAND_NULL, false, fixedText_Up);
-			screen._backBuffer1.fillRect(Common::Rect(5, CONTROLS_Y + 11,
-				15, CONTROLS_Y + 22), INV_BACKGROUND);
-		}
-	}
-
-	// Loop through the statements
-	bool done = false;
-	for (uint idx = _talkIndex; idx < _statements.size() && !done; ++idx) {
-		Statement &statement = _statements[idx];
-
-		if (statement._talkMap != -1) {
-			bool flag = _talkHistory[_converseNum][idx];
-			lineY = talkLine(idx, statement._talkMap, flag ? TALK_NULL : INV_FOREGROUND,
-				yp, slamIt);
-
-			if (lineY != -1) {
-				statement._talkPos.top = yp;
-				yp = lineY;
-				statement._talkPos.bottom = yp;
-
-				if (yp == SHERLOCK_SCREEN_HEIGHT)
-					done = true;
-			} else {
-				done = true;
-			}
-		}
-	}
-
-	// Display the down arrow and enable down button if there are more statements available down off-screen
-	if (lineY == -1 || lineY == SHERLOCK_SCREEN_HEIGHT) {
-		_moreTalkDown = true;
-
-		if (slamIt) {
-			screen.print(Common::Point(5, 190), INV_FOREGROUND, "|");
-			screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, true, fixedText_Down);
-		} else {
-			screen.gPrint(Common::Point(5, 189), INV_FOREGROUND, "|");
-			screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_FOREGROUND, false, fixedText_Down);
-		}
-	} else {
-		if (slamIt) {
-			screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, true, fixedText_Down);
-			screen.vgaBar(Common::Rect(5, 189, 16, 199), INV_BACKGROUND);
-		} else {
-			screen.buttonPrint(Common::Point(200, CONTROLS_Y), COMMAND_NULL, false, fixedText_Down);
-			screen._backBuffer1.fillRect(Common::Rect(5, 189, 16, 199), INV_BACKGROUND);
-		}
-	}
-
-	return done;
-}
-
-int Talk::talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt) {
-	Screen &screen = *_vm->_screen;
-	int idx = lineNum;
-	Common::String msg, number;
-	bool numberFlag = false;
-
-	// Get the statement to display as well as optional number prefix
-	if (idx < SPEAKER_REMOVE) {
-		number = Common::String::format("%d.", stateNum + 1);
-		numberFlag = true;
-	} else {
-		idx -= SPEAKER_REMOVE;
-	}
-	msg = _statements[idx]._statement;
-
-	// Handle potentially multiple lines needed to display entire statement
-	const char *lineStartP = msg.c_str();
-	int maxWidth = 298 - (numberFlag ? 18 : 0);
-	for (;;) {
-		// Get as much of the statement as possible will fit on the
-		Common::String sLine;
-		const char *lineEndP = lineStartP;
-		int width = 0;
-		do {
-			width += screen.charWidth(*lineEndP);
-		} while (*++lineEndP && width < maxWidth);
-
-		// Check if we need to wrap the line
-		if (width >= maxWidth) {
-			// Work backwards to the prior word's end
-			while (*--lineEndP != ' ')
-				;
-
-			sLine = Common::String(lineStartP, lineEndP++);
-		} else {
-			// Can display remainder of the statement on the current line
-			sLine = Common::String(lineStartP);
-		}
-
-
-		if (lineY <= (SHERLOCK_SCREEN_HEIGHT - 10)) {
-			// Need to directly display on-screen?
-			if (slamIt) {
-				// See if a numer prefix is needed or not
-				if (numberFlag) {
-					// Are we drawing the first line?
-					if (lineStartP == msg.c_str()) {
-						// We are, so print the number and then the text
-						screen.print(Common::Point(16, lineY), color, "%s", number.c_str());
-					}
-
-					// Draw the line with an indent
-					screen.print(Common::Point(30, lineY), color, "%s", sLine.c_str());
-				} else {
-					screen.print(Common::Point(16, lineY), color, "%s", sLine.c_str());
-				}
-			} else {
-				if (numberFlag) {
-					if (lineStartP == msg.c_str()) {
-						screen.gPrint(Common::Point(16, lineY - 1), color, "%s", number.c_str());
-					}
-
-					screen.gPrint(Common::Point(30, lineY - 1), color, "%s", sLine.c_str());
-				} else {
-					screen.gPrint(Common::Point(16, lineY - 1), color, "%s", sLine.c_str());
-				}
-			}
-
-			// Move to next line, if any
-			lineY += 9;
-			lineStartP = lineEndP;
-
-			if (!*lineEndP)
-				break;
-		} else {
-			// We're close to the bottom of the screen, so stop display
-			lineY = -1;
-			break;
-		}
-	}
-
-	if (lineY == -1 && lineStartP != msg.c_str())
-		lineY = SHERLOCK_SCREEN_HEIGHT;
-
-	// Return the Y position of the next line to follow this one
-	return lineY;
-}
-
 void Talk::clearSequences() {
 	_sequenceStack.clear();
 }
diff --git a/engines/sherlock/talk.h b/engines/sherlock/talk.h
index 62a839e..ef11551 100644
--- a/engines/sherlock/talk.h
+++ b/engines/sherlock/talk.h
@@ -186,17 +186,6 @@ private:
 	void setTalkMap();
 
 	/**
-	 * Display a list of statements in a window at the bottom of the screen that the
-	 * player can select from.
-	 */
-	bool displayTalk(bool slamIt);
-
-	/**
-	 * Prints a single conversation option in the interface window
-	 */
-	int talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt);
-
-	/**
 	 * Parses a reply for control codes and display text. The found text is printed within
 	 * the text window, handles delays, animations, and animating portraits.
 	 */
@@ -207,7 +196,6 @@ private:
 	 * the amount of text that's been displayed
 	 */
 	int waitForMore(int delay);
-
 protected:
 	SherlockEngine *_vm;
 	OpcodeMethod *_opcodeTable;
@@ -273,7 +261,11 @@ protected:
 	 * Trigger to play a 3DO talk dialog movie
 	 */
 	virtual void talk3DOMovieTrigger(int subIndex) {};
-
+	
+	/**
+	 * Show the talk display
+	 */
+	virtual void showTalk() {}
 public:
 	TalkSequence _talkSequenceStack[TALK_SEQUENCE_STACK_SIZE];
 	Common::Array<Statement> _statements;
@@ -286,7 +278,6 @@ public:
 	bool _moreTalkUp, _moreTalkDown;
 	int _converseNum;
 	const byte *_opcodes;
-
 public:
 	static Talk *init(SherlockEngine *vm);
 	virtual ~Talk() {}
@@ -320,11 +311,6 @@ public:
 	void freeTalkVars();
 
 	/**
-	 * Draws the interface for conversation display
-	 */
-	void drawInterface();
-
-	/**
 	 * Opens the talk file 'talk.tlk' and searches the index for the specified
 	 * conversation. If found, the data for that conversation is loaded
 	 */
@@ -372,6 +358,22 @@ public:
 	 * Synchronize the data for a savegame
 	 */
 	void synchronize(Serializer &s);
+
+	/**
+	 * Draws the interface for conversation display
+	 */
+	virtual void drawInterface() {}
+
+	/**
+	 * Display a list of statements in a window at the bottom of the screen that the
+	 * player can select from.
+	 */
+	virtual bool displayTalk(bool slamIt) { return false; }
+
+	/**
+	 * Prints a single conversation option in the interface window
+	 */
+	virtual int talkLine(int lineNum, int stateNum, byte color, int lineY, bool slamIt) { return 0; }
 };
 
 } // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo.h b/engines/sherlock/tattoo/tattoo.h
index 9ef2e0a..aa07d85 100644
--- a/engines/sherlock/tattoo/tattoo.h
+++ b/engines/sherlock/tattoo/tattoo.h
@@ -33,7 +33,10 @@ enum {
 	INFO_TOP			= 185,
 	INFO_MIDDLE			= 186,
 	INFO_BOTTOM			= 188,
-	MENU_BACKGROUND		= 225
+	MENU_BACKGROUND		= 225,
+	COMMAND_HIGHLIGHTED	= 254,
+	COMMAND_NULL		= 193
+
 };
 
 class TattooEngine : public SherlockEngine {
diff --git a/engines/sherlock/tattoo/tattoo_user_interface.cpp b/engines/sherlock/tattoo/tattoo_user_interface.cpp
index e3df27d..ade9861 100644
--- a/engines/sherlock/tattoo/tattoo_user_interface.cpp
+++ b/engines/sherlock/tattoo/tattoo_user_interface.cpp
@@ -587,7 +587,6 @@ void TattooUserInterface::freeMenu() {
 
 void TattooUserInterface::putMessage(const char *formatStr, ...) {
 	Events &events = *_vm->_events;
-	Screen &screen = *_vm->_screen;
 	Common::Point mousePos = events.mousePos();
 
 	// Create the string to display
diff --git a/engines/sherlock/tattoo/widget_inventory.cpp b/engines/sherlock/tattoo/widget_inventory.cpp
index ac30fe3..fe6fa09 100644
--- a/engines/sherlock/tattoo/widget_inventory.cpp
+++ b/engines/sherlock/tattoo/widget_inventory.cpp
@@ -31,7 +31,6 @@ namespace Tattoo {
 
 #define INVENTORY_XSIZE 70			// Width of the box that surrounds inventory items
 #define INVENTORY_YSIZE 70			// Height of the box that surrounds inventory items
-#define NUM_INVENTORY_SHOWN 8		// Number of Inventory Items Shown
 #define MAX_INV_COMMANDS 10			// Maximum elements in dialog
 
 // TODO: Refactor into FixedText
diff --git a/engines/sherlock/tattoo/widget_inventory.h b/engines/sherlock/tattoo/widget_inventory.h
index b3e914c..4193077 100644
--- a/engines/sherlock/tattoo/widget_inventory.h
+++ b/engines/sherlock/tattoo/widget_inventory.h
@@ -33,6 +33,8 @@ class SherlockEngine;
 
 namespace Tattoo {
 
+#define NUM_INVENTORY_SHOWN 8		// Number of Inventory Items Shown
+
 class WidgetInventory: public WidgetBase {
 private:
 	int _invVerbMode;






More information about the Scummvm-git-logs mailing list