aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sherlock')
-rw-r--r--engines/sherlock/saveload.cpp2
-rw-r--r--engines/sherlock/scalpel/scalpel_scene.cpp21
-rw-r--r--engines/sherlock/scalpel/scalpel_scene.h6
-rw-r--r--engines/sherlock/scene.cpp42
-rw-r--r--engines/sherlock/scene.h12
-rw-r--r--engines/sherlock/sherlock.h1
-rw-r--r--engines/sherlock/talk.cpp10
-rw-r--r--engines/sherlock/tattoo/tattoo_journal.cpp6
-rw-r--r--engines/sherlock/tattoo/tattoo_scene.cpp64
-rw-r--r--engines/sherlock/tattoo/tattoo_scene.h5
-rw-r--r--engines/sherlock/tattoo/tattoo_talk.cpp2
-rw-r--r--engines/sherlock/tattoo/tattoo_user_interface.cpp6
-rw-r--r--engines/sherlock/tattoo/widget_base.cpp23
-rw-r--r--engines/sherlock/tattoo/widget_files.cpp243
-rw-r--r--engines/sherlock/tattoo/widget_files.h5
-rw-r--r--engines/sherlock/tattoo/widget_talk.cpp5
16 files changed, 360 insertions, 93 deletions
diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp
index 0ae437fbf3..ce6f32dcde 100644
--- a/engines/sherlock/saveload.cpp
+++ b/engines/sherlock/saveload.cpp
@@ -268,7 +268,7 @@ void SaveManager::synchronize(Serializer &s) {
if (screen.fontNumber() != oldFont)
journal.resetPosition();
- _justLoaded = true;
+ _justLoaded = s.isLoading();
}
bool SaveManager::isSlotEmpty(int slot) const {
diff --git a/engines/sherlock/scalpel/scalpel_scene.cpp b/engines/sherlock/scalpel/scalpel_scene.cpp
index 9c36e84969..2f60cebefe 100644
--- a/engines/sherlock/scalpel/scalpel_scene.cpp
+++ b/engines/sherlock/scalpel/scalpel_scene.cpp
@@ -727,6 +727,27 @@ int ScalpelScene::closestZone(const Common::Point &pt) {
return zone;
}
+int ScalpelScene::findBgShape(const Common::Point &pt) {
+ if (!_doBgAnimDone)
+ // New frame hasn't been drawn yet
+ return -1;
+
+ for (int idx = (int)_bgShapes.size() - 1; idx >= 0; --idx) {
+ Object &o = _bgShapes[idx];
+ if (o._type != INVALID && o._type != NO_SHAPE && o._type != HIDDEN
+ && o._aType <= PERSON) {
+ if (o.getNewBounds().contains(pt))
+ return idx;
+ }
+ else if (o._type == NO_SHAPE) {
+ if (o.getNoShapeBounds().contains(pt))
+ return idx;
+ }
+ }
+
+ return -1;
+}
+
} // End of namespace Scalpel
} // End of namespace Sherlock
diff --git a/engines/sherlock/scalpel/scalpel_scene.h b/engines/sherlock/scalpel/scalpel_scene.h
index 62dd1c7a92..8fe3b66b38 100644
--- a/engines/sherlock/scalpel/scalpel_scene.h
+++ b/engines/sherlock/scalpel/scalpel_scene.h
@@ -89,6 +89,12 @@ public:
* A negative playRate can also be specified to play the animation in reverse
*/
virtual int startCAnim(int cAnimNum, int playRate = 1);
+
+ /**
+ * Attempts to find a background shape within the passed bounds. If found,
+ * it will return the shape number, or -1 on failure.
+ */
+ virtual int findBgShape(const Common::Point &pt);
};
} // End of namespace Scalpel
diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp
index 8669d4c092..c571f27b0c 100644
--- a/engines/sherlock/scene.cpp
+++ b/engines/sherlock/scene.cpp
@@ -207,11 +207,12 @@ Scene *Scene::init(SherlockEngine *vm) {
Scene::Scene(SherlockEngine *vm): _vm(vm) {
_sceneStats = new bool *[SCENES_COUNT];
- _sceneStats[0] = new bool[SCENES_COUNT * 65];
- Common::fill(&_sceneStats[0][0], &_sceneStats[0][SCENES_COUNT * 65], false);
+ _sceneStats[0] = new bool[SCENES_COUNT * (MAX_BGSHAPES + 1)];
+ Common::fill(&_sceneStats[0][0], &_sceneStats[0][SCENES_COUNT * (MAX_BGSHAPES + 1)], false);
for (int idx = 1; idx < SCENES_COUNT; ++idx) {
- _sceneStats[idx] = _sceneStats[idx - 1] + 65;
+ _sceneStats[idx] = _sceneStats[idx - 1] + (MAX_BGSHAPES + 1);
}
+
_currentScene = -1;
_goToScene = -1;
_loadingSavedGame = false;
@@ -244,9 +245,6 @@ void Scene::selectScene() {
ui._windowOpen = ui._infoFlag = false;
ui._menuMode = STD_MODE;
- // Free any previous scene
- freeScene();
-
// Load the scene
Common::String sceneFile = Common::String::format("res%02d", _goToScene);
// _rrmName gets set during loadScene()
@@ -1050,11 +1048,11 @@ void Scene::loadSceneSounds() {
}
void Scene::checkSceneStatus() {
- if (_sceneStats[_currentScene][64]) {
- for (uint idx = 0; idx < 64; ++idx) {
+ if (_sceneStats[_currentScene][MAX_BGSHAPES]) {
+ for (int idx = 0; idx < MAX_BGSHAPES; ++idx) {
bool flag = _sceneStats[_currentScene][idx];
- if (idx < _bgShapes.size()) {
+ if (idx < (int)_bgShapes.size()) {
Object &obj = _bgShapes[idx];
if (flag) {
@@ -1076,7 +1074,7 @@ void Scene::checkSceneStatus() {
void Scene::saveSceneStatus() {
// Flag any objects for the scene that have been altered
- int count = MIN((int)_bgShapes.size(), 64);
+ int count = MIN((int)_bgShapes.size(), MAX_BGSHAPES);
for (int idx = 0; idx < count; ++idx) {
Object &obj = _bgShapes[idx];
_sceneStats[_currentScene][idx] = obj._type == HIDDEN || obj._type == REMOVE
@@ -1084,7 +1082,7 @@ void Scene::saveSceneStatus() {
}
// Flag scene as having been visited
- _sceneStats[_currentScene][64] = true;
+ _sceneStats[_currentScene][MAX_BGSHAPES] = true;
}
void Scene::checkSceneFlags(bool flag) {
@@ -1340,26 +1338,6 @@ Exit *Scene::checkForExit(const Common::Rect &r) {
return nullptr;
}
-int Scene::findBgShape(const Common::Point &pt) {
- if (!_doBgAnimDone)
- // New frame hasn't been drawn yet
- return -1;
-
- for (int idx = (int)_bgShapes.size() - 1; idx >= 0; --idx) {
- Object &o = _bgShapes[idx];
- if (o._type != INVALID && o._type != NO_SHAPE && o._type != HIDDEN
- && o._aType <= PERSON) {
- if (o.getNewBounds().contains(pt))
- return idx;
- } else if (o._type == NO_SHAPE) {
- if (o.getNoShapeBounds().contains(pt))
- return idx;
- }
- }
-
- return -1;
-}
-
int Scene::checkForZones(const Common::Point &pt, int zoneType) {
int matches = 0;
@@ -1400,7 +1378,7 @@ void Scene::synchronize(Serializer &s) {
}
for (int sceneNum = 0; sceneNum < SCENES_COUNT; ++sceneNum) {
- for (int flag = 0; flag < 65; ++flag) {
+ for (int flag = 0; flag <= MAX_BGSHAPES; ++flag) {
s.syncAsByte(_sceneStats[sceneNum][flag]);
}
}
diff --git a/engines/sherlock/scene.h b/engines/sherlock/scene.h
index 0fbda38fe8..42bee4f127 100644
--- a/engines/sherlock/scene.h
+++ b/engines/sherlock/scene.h
@@ -247,11 +247,6 @@ public:
void selectScene();
/**
- * Fres all the graphics and other dynamically allocated data for the scene
- */
- void freeScene();
-
- /**
* Check the scene's objects against the game flags. If false is passed,
* it means the scene has just been loaded. A value of true means that the scene
* is in use (ie. not just loaded)
@@ -281,6 +276,11 @@ public:
int whichZone(const Common::Point &pt);
/**
+ * Fres all the graphics and other dynamically allocated data for the scene
+ */
+ virtual void freeScene();
+
+ /**
* Returns the index of the closest zone to a given point.
*/
virtual int closestZone(const Common::Point &pt) = 0;
@@ -289,7 +289,7 @@ public:
* Attempts to find a background shape within the passed bounds. If found,
* it will return the shape number, or -1 on failure.
*/
- virtual int findBgShape(const Common::Point &pt);
+ virtual int findBgShape(const Common::Point &pt) = 0;
/**
* Synchronize the data for a savegame
diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h
index 5f888f8c3d..ab2c8be6b6 100644
--- a/engines/sherlock/sherlock.h
+++ b/engines/sherlock/sherlock.h
@@ -68,6 +68,7 @@ enum GameType {
#define SHERLOCK_SCENE_WIDTH _vm->_screen->_backBuffer1.w()
#define SHERLOCK_SCENE_HEIGHT (IS_SERRATED_SCALPEL ? 138 : 480)
#define SCENES_COUNT (IS_SERRATED_SCALPEL ? 63 : 101)
+#define MAX_BGSHAPES (IS_SERRATED_SCALPEL ? 64 : 150)
#define COL_INFO_FOREGROUND (IS_SERRATED_SCALPEL ? (byte)Scalpel::INFO_FOREGROUND : (byte)Tattoo::INFO_FOREGROUND)
#define COL_PEN_COLOR (IS_SERRATED_SCALPEL ? (byte)Scalpel::PEN_COLOR : (byte)Tattoo::PEN_COLOR)
diff --git a/engines/sherlock/talk.cpp b/engines/sherlock/talk.cpp
index a1a003d751..d259182a70 100644
--- a/engines/sherlock/talk.cpp
+++ b/engines/sherlock/talk.cpp
@@ -403,8 +403,14 @@ void Talk::talkTo(const Common::String &filename) {
if (!ui._lookScriptFlag) {
ui.drawInterface(2);
- ui._menuMode = STD_MODE;
- ui._windowBounds.top = CONTROLS_Y1;
+
+ if (IS_SERRATED_SCALPEL) {
+ ui._menuMode = STD_MODE;
+ ui._windowBounds.top = CONTROLS_Y1;
+ } else {
+ ui._menuMode = static_cast<Tattoo::TattooScene *>(_vm->_scene)->_labTableScene ?
+ LAB_MODE : STD_MODE;
+ }
ui.banishWindow();
}
diff --git a/engines/sherlock/tattoo/tattoo_journal.cpp b/engines/sherlock/tattoo/tattoo_journal.cpp
index 6df5ee7458..6c33971357 100644
--- a/engines/sherlock/tattoo/tattoo_journal.cpp
+++ b/engines/sherlock/tattoo/tattoo_journal.cpp
@@ -49,6 +49,9 @@ void TattooJournal::show() {
Screen &screen = *_vm->_screen;
TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
byte palette[PALETTE_SIZE];
+
+ Common::Point oldScroll = screen._currentScroll;
+ screen._currentScroll = Common::Point(0, 0);
// Load journal images
_journalImages = new ImageFile("journal.vgs");
@@ -95,6 +98,9 @@ void TattooJournal::show() {
// Free the images
delete _journalImages;
+
+ // Reset back to whatever scroll was active for the screen
+ screen._currentScroll = oldScroll;
}
void TattooJournal::handleKeyboardEvents() {
diff --git a/engines/sherlock/tattoo/tattoo_scene.cpp b/engines/sherlock/tattoo/tattoo_scene.cpp
index e40b4d6a9c..1ecc997f42 100644
--- a/engines/sherlock/tattoo/tattoo_scene.cpp
+++ b/engines/sherlock/tattoo/tattoo_scene.cpp
@@ -292,6 +292,15 @@ void TattooScene::checkBgShapes() {
}
}
+void TattooScene::freeScene() {
+ TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ Scene::freeScene();
+
+ delete ui._mask;
+ delete ui._mask1;
+ ui._mask = ui._mask1 = nullptr;
+}
+
void TattooScene::doBgAnimCheckCursor() {
Events &events = *_vm->_events;
TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
@@ -724,46 +733,47 @@ void TattooScene::setNPCPath(int npc) {
int TattooScene::findBgShape(const Common::Point &pt) {
People &people = *_vm->_people;
+ UserInterface &ui = *_vm->_ui;
if (!_doBgAnimDone)
// New frame hasn't been drawn yet
return -1;
- int result = Scene::findBgShape(pt);
- if (result == -1) {
- if (_labTableScene) {
- // Check for SOLID objects in the lab scene
- for (int idx = (int)_bgShapes.size() - 1; idx >= 0; --idx) {
- Object &o = _bgShapes[idx];
- if (o._type != INVALID && o._type != NO_SHAPE && o._type != HIDDEN && o._aType == SOLID) {
- if (o.getNewBounds().contains(pt))
- return idx;
- }
- }
+
+ for (int idx = (int)_bgShapes.size() - 1; idx >= 0; --idx) {
+ Object &o = _bgShapes[idx];
+
+ if (o._type != INVALID && o._type != NO_SHAPE && o._type != HIDDEN &&
+ (o._aType <= PERSON || (ui._menuMode == LAB_MODE && o._aType == SOLID))) {
+ if (o.getNewBounds().contains(pt))
+ return idx;
+ } else if (o._type == NO_SHAPE) {
+ if (o.getNoShapeBounds().contains(pt))
+ return idx;
}
+ }
- // No shape found, so check whether a character is highlighted
- for (int idx = 1; idx < MAX_CHARACTERS && result == -1; ++idx) {
- Person &person = people[idx];
+ // If no shape found, so check whether a character is highlighted
+ for (int idx = 1; idx < MAX_CHARACTERS; ++idx) {
+ Person &person = people[idx];
- if (person._type == CHARACTER) {
- int scaleVal = getScaleVal(person._position);
- Common::Rect charRect;
+ if (person._type == CHARACTER) {
+ int scaleVal = getScaleVal(person._position);
+ Common::Rect charRect;
- if (scaleVal == SCALE_THRESHOLD)
- charRect = Common::Rect(person.frameWidth(), person.frameHeight());
- else
- charRect = Common::Rect(person._imageFrame->sDrawXSize(scaleVal), person._imageFrame->sDrawYSize(scaleVal));
- charRect.moveTo(person._position.x / FIXED_INT_MULTIPLIER, person._position.y / FIXED_INT_MULTIPLIER
- - charRect.height());
+ if (scaleVal == SCALE_THRESHOLD)
+ charRect = Common::Rect(person.frameWidth(), person.frameHeight());
+ else
+ charRect = Common::Rect(person._imageFrame->sDrawXSize(scaleVal), person._imageFrame->sDrawYSize(scaleVal));
+ charRect.moveTo(person._position.x / FIXED_INT_MULTIPLIER, person._position.y / FIXED_INT_MULTIPLIER
+ - charRect.height());
- if (charRect.contains(pt))
- result = 1000 + idx;
- }
+ if (charRect.contains(pt))
+ return 1000 + idx;
}
}
- return result;
+ return -1;
}
void TattooScene::synchronize(Serializer &s) {
diff --git a/engines/sherlock/tattoo/tattoo_scene.h b/engines/sherlock/tattoo/tattoo_scene.h
index b75f7e70eb..ade4b00a38 100644
--- a/engines/sherlock/tattoo/tattoo_scene.h
+++ b/engines/sherlock/tattoo/tattoo_scene.h
@@ -118,6 +118,11 @@ public:
int getScaleVal(const Point32 &pt);
/**
+ * Fres all the graphics and other dynamically allocated data for the scene
+ */
+ virtual void freeScene();
+
+ /**
* Draw all objects and characters.
*/
virtual void doBgAnim();
diff --git a/engines/sherlock/tattoo/tattoo_talk.cpp b/engines/sherlock/tattoo/tattoo_talk.cpp
index dbeeaf8918..8303fd42ad 100644
--- a/engines/sherlock/tattoo/tattoo_talk.cpp
+++ b/engines/sherlock/tattoo/tattoo_talk.cpp
@@ -193,7 +193,7 @@ void TattooTalk::talkInterface(const byte *&str) {
}
// Display the text window
-// ui.banishWindow();
+ ui.banishWindow();
ui._textWidget.load(Common::String((const char *)s, (const char *)str), _speaker);
ui._textWidget.summonWindow();
_wait = true;
diff --git a/engines/sherlock/tattoo/tattoo_user_interface.cpp b/engines/sherlock/tattoo/tattoo_user_interface.cpp
index 6c40323b0d..d8faa3e0ae 100644
--- a/engines/sherlock/tattoo/tattoo_user_interface.cpp
+++ b/engines/sherlock/tattoo/tattoo_user_interface.cpp
@@ -65,6 +65,8 @@ TattooUserInterface::TattooUserInterface(SherlockEngine *vm): UserInterface(vm),
TattooUserInterface::~TattooUserInterface() {
delete _interfaceImages;
+ delete _mask;
+ delete _mask1;
}
void TattooUserInterface::initScrollVars() {
@@ -388,13 +390,13 @@ void TattooUserInterface::doStandardControl() {
switch (_keyState.keycode) {
case Common::KEYCODE_F5:
// Save game
- freeMenu();
+ events.warpMouse();
saveGame();
return;
case Common::KEYCODE_F7:
// Load game
- freeMenu();
+ events.warpMouse();
loadGame();
return;
diff --git a/engines/sherlock/tattoo/widget_base.cpp b/engines/sherlock/tattoo/widget_base.cpp
index e0b903916b..539d4a2f02 100644
--- a/engines/sherlock/tattoo/widget_base.cpp
+++ b/engines/sherlock/tattoo/widget_base.cpp
@@ -59,11 +59,13 @@ void WidgetBase::banishWindow() {
}
void WidgetBase::close() {
+ Events &events = *_vm->_events;
TattooScene &scene = *(TattooScene *)_vm->_scene;
TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
banishWindow();
ui._menuMode = scene._labTableScene ? LAB_MODE : STD_MODE;
+ events.clearEvents();
}
bool WidgetBase::active() const {
@@ -175,8 +177,8 @@ void WidgetBase::restrictToScreen() {
_bounds.moveTo(screen._currentScroll.x, _bounds.top);
if (_bounds.top < 0)
_bounds.moveTo(_bounds.left, 0);
- if (_bounds.right > screen._backBuffer1.w())
- _bounds.moveTo(screen._backBuffer1.w() - _bounds.width(), _bounds.top);
+ if (_bounds.right > (screen._currentScroll.x + SHERLOCK_SCREEN_WIDTH))
+ _bounds.moveTo(screen._currentScroll.x + SHERLOCK_SCREEN_WIDTH - _bounds.width(), _bounds.top);
if (_bounds.bottom > screen._backBuffer1.h())
_bounds.moveTo(_bounds.left, screen._backBuffer1.h() - _bounds.height());
}
@@ -330,21 +332,8 @@ void WidgetBase::handleScrolling(int &scrollIndex, int pageSize, int max) {
yp = CLIP(yp, r.top + BUTTON_SIZE + 3, r.bottom - BUTTON_SIZE - 3);
// Calculate the line number that corresponds to the position that the mouse is on the scrollbar
- int lineNum = (yp - _bounds.top - BUTTON_SIZE - 3) * 100 / (_bounds.height() - BUTTON_SIZE * 2 - 6)
- * max / 100 - 3;
-
- // If the new position would place part of the text outsidethe text window, adjust it so it doesn't
- if (lineNum < 0)
- lineNum = 0;
- else if (lineNum + pageSize > max) {
- lineNum = max - pageSize;
-
- // Make sure it's not below zero now
- if (lineNum < 0)
- lineNum = 0;
- }
-
- scrollIndex = lineNum;
+ int lineNum = (yp - r.top - BUTTON_SIZE - 3) * (max - pageSize) / (r.height() - BUTTON_SIZE * 2 - 6);
+ scrollIndex = CLIP(lineNum, 0, max - pageSize);
}
// Get the current frame so we can check the scroll timer against it
diff --git a/engines/sherlock/tattoo/widget_files.cpp b/engines/sherlock/tattoo/widget_files.cpp
index 4a0c0495e0..1743bcd09e 100644
--- a/engines/sherlock/tattoo/widget_files.cpp
+++ b/engines/sherlock/tattoo/widget_files.cpp
@@ -150,7 +150,7 @@ void WidgetFiles::render(FilesRenderMode mode) {
color = INFO_TOP;
if (mode == RENDER_NAMES_AND_SCROLLBAR)
- _surface.fillRect(Common::Rect(4, yp, _surface.w() - BUTTON_SIZE - 9, yp + _surface.fontHeight() - 1), TRANSPARENCY);
+ _surface.fillRect(Common::Rect(4, yp, _surface.w() - BUTTON_SIZE - 9, yp + _surface.fontHeight()), TRANSPARENCY);
Common::String numStr = Common::String::format("%d.", idx + 1);
_surface.writeString(numStr, Common::Point(_surface.widestChar(), yp), color);
@@ -166,8 +166,11 @@ void WidgetFiles::render(FilesRenderMode mode) {
}
void WidgetFiles::handleEvents() {
- //Events &events = *_vm->_events;
+ Events &events = *_vm->_events;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
+ Common::Point mousePos = events.mousePos();
+ Common::KeyState keyState = ui._keyState;
// Handle scrollbar events
ScrollHighlight oldHighlight = ui._scrollHighlight;
@@ -176,11 +179,243 @@ void WidgetFiles::handleEvents() {
int oldScrollIndex = _savegameIndex;
handleScrolling(_savegameIndex, FILES_LINES_COUNT, _savegames.size());
+ // See if the mouse is pointing at any filenames in the window
+ if (Common::Rect(_bounds.left, _bounds.top + _surface.fontHeight() + 14,
+ _bounds.right - BUTTON_SIZE - 5, _bounds.bottom - 5).contains(mousePos)) {
+ _selector = (mousePos.y - _bounds.top - _surface.fontHeight() - 14) / (_surface.fontHeight() + 1) +
+ _savegameIndex;
+ } else {
+ _selector = -1;
+ }
+
+ // Check for the Tab key
+ if (keyState.keycode == Common::KEYCODE_TAB) {
+ // If the mouse is not over any of the filenames, move the mouse so that it points to the first one
+ if (_selector == -1) {
+ events.warpMouse(Common::Point(_bounds.right - BUTTON_SIZE - 20,
+ _bounds.top + _surface.fontHeight() * 2 + 8));
+ } else {
+ // See if we're doing Tab or Shift Tab
+ if (keyState.flags & Common::KBD_SHIFT) {
+ // We're doing Shift Tab
+ if (_selector == _savegameIndex)
+ _selector = _savegameIndex + 4;
+ else
+ --_selector;
+ } else {
+ // We're doing Tab
+ ++_selector;
+ if (_selector >= _savegameIndex + 5)
+ _selector = _savegameIndex;
+ }
+
+ events.warpMouse(Common::Point(mousePos.x, _bounds.top + _surface.fontHeight() * 2
+ + 8 + (_selector - _savegameIndex) * (_surface.fontHeight() + 1)));
+ }
+ }
+
// Only redraw the window if the the scrollbar position has changed
- if (ui._scrollHighlight != oldHighlight || oldScrollIndex != _savegameIndex)
+ if (ui._scrollHighlight != oldHighlight || oldScrollIndex != _savegameIndex || _selector != _oldSelector)
render(RENDER_NAMES_AND_SCROLLBAR);
+ _oldSelector = _selector;
+
+ if (events._firstPress && !_bounds.contains(mousePos))
+ _outsideMenu = true;
+
+ if (events._released || events._rightReleased || keyState.keycode == Common::KEYCODE_ESCAPE) {
+ ui._scrollHighlight = SH_NONE;
+
+ if (_outsideMenu && !_bounds.contains(mousePos)) {
+ close();
+ } else {
+ _outsideMenu = false;
+
+ if (_selector != -1) {
+ if (_fileMode = SAVEMODE_LOAD) {
+ // We're in Load Mode
+ _vm->loadGameState(_selector);
+ } else if (_fileMode == SAVEMODE_SAVE) {
+ // We're in Save Mode
+ if (getFilename())
+ _vm->saveGameState(_selector, _savegames[_selector]);
+ close();
+ }
+ }
+ }
+ }
+}
+
+bool WidgetFiles::getFilename() {
+ Events &events = *_vm->_events;
+ TattooScene &scene = *(TattooScene *)_vm->_scene;
+ Talk &talk = *_vm->_talk;
+ int index = 0;
+ int done = 0;
+ bool flag = false;
+ int width;
+ int cursorColor = 192;
+ byte color, textColor;
+ bool insert = true;
+
+ assert(_selector != -1);
+ Common::Point pt(_surface.stringWidth("00.") + _surface.widestChar() + 5,
+ _surface.fontHeight() + 14 + (_selector - _savegameIndex) * (_surface.fontHeight() + 1));
+
+ Common::String str = Common::String::format("%d.", _selector + 1);
+ _surface.writeString(str, Common::Point(_surface.widestChar(), pt.y), COMMAND_HIGHLIGHTED);
+
+ Common::String saveFile = _savegames[_selector];
+ Common::String filename = _savegames[_selector];
+ _savegames[_selector] = "";
+
+ if (isSlotEmpty(_selector)) {
+ index = 0;
+ _surface.fillRect(Common::Rect(pt.x, pt.y, _bounds.right - BUTTON_SIZE - 9, pt.y + _surface.fontHeight() - 1), TRANSPARENCY);
+ } else {
+ index = saveFile.size();
+ _surface.writeString(saveFile, pt, COMMAND_HIGHLIGHTED);
+ pt.x = _surface.stringWidth("00.") + _surface.stringWidth(saveFile) + _surface.widestChar() + 5;
+
+ //filename[index] = 32;
+ }
+
+ do {
+ scene.doBgAnim();
+
+ if (talk._talkToAbort)
+ return false;
+
+ if (filename[index]) {
+ str = Common::String::format("%c", filename[index]);
+ width = _surface.charWidth(filename[index]);
+ } else {
+ width = 7;
+ }
+
+ while (!events.kbHit()) {
+ events.pollEventsAndWait();
+ events.setButtonState();
+
+ scene.doBgAnim();
+
+ if (talk._talkToAbort)
+ return false;
+
+ flag = !flag;
+ if (flag) {
+ textColor = 236;
+ color = cursorColor;
+ } else {
+ textColor = COMMAND_HIGHLIGHTED;
+ color = TRANSPARENCY;
+ }
+
+ _surface.fillRect(Common::Rect(pt.x, pt.y, pt.x + width, pt.y + _surface.fontHeight()), color);
+ if (filename[index])
+ _surface.writeString(str, pt, textColor);
+
+ if (_vm->shouldQuit())
+ return false;
+ }
+
+ Common::KeyState keyState = events.getKey();
+ if (keyState.keycode == Common::KEYCODE_BACKSPACE && index > 0) {
+ pt.x -= _surface.charWidth(filename[index - 1]);
+
+ if (insert) {
+ filename.deleteChar(index);
+ } else {
+ filename.setChar(' ', index - 1);
+ }
+
+ --index;
+ _surface.fillRect(Common::Rect(pt.x, pt.y, _surface.w() - BUTTON_SIZE - 9, pt.y + _surface.fontHeight() - 1), TRANSPARENCY);
+ _surface.writeString(filename.c_str() + index, pt, COMMAND_HIGHLIGHTED);
+
+ } else if ((keyState.keycode == Common::KEYCODE_LEFT && index > 0)
+ || (keyState.keycode == Common::KEYCODE_RIGHT && index < 49 && pt.x < (_bounds.right - BUTTON_SIZE - 20))
+ || (keyState.keycode == Common::KEYCODE_HOME && index > 0)
+ || (keyState.keycode == Common::KEYCODE_END)) {
+ _surface.fillRect(Common::Rect(pt.x, pt.y, pt.x + width, pt.y + _surface.fontHeight()), TRANSPARENCY);
+ if (filename[index])
+ _surface.writeString(str, pt, COMMAND_HIGHLIGHTED);
+
+ switch (keyState.keycode) {
+ case Common::KEYCODE_LEFT:
+ pt.x -= _surface.charWidth(filename[index - 1]);
+ --index;
+ break;
+
+ case Common::KEYCODE_RIGHT:
+ pt.x += _surface.charWidth(filename[index]);
+ ++index;
+ break;
+
+ case Common::KEYCODE_HOME:
+ pt.x = _surface.stringWidth("00.") + _surface.widestChar() + 5;
+ index = 0;
+ break;
+
+ case Common::KEYCODE_END:
+ pt.x = _surface.stringWidth("00.") + _surface.stringWidth(filename) + _surface.widestChar() + 5;
+ index = filename.size();
+
+ while (filename[index - 1] == ' ' && index > 0) {
+ pt.x -= _surface.charWidth(filename[index - 1]);
+ --index;
+ }
+ break;
+ }
+ } else if (keyState.keycode == Common::KEYCODE_INSERT) {
+ insert = !insert;
+ if (insert)
+ cursorColor = 192;
+ else
+ cursorColor = 200;
+
+ } else if (keyState.keycode == Common::KEYCODE_DELETE) {
+ filename.deleteChar(index);
+
+ _surface.fillRect(Common::Rect(pt.x, pt.y, _bounds.right - BUTTON_SIZE - 9, pt.y + _surface.fontHeight() - 1), TRANSPARENCY);
+ _surface.writeString(filename + index, pt, COMMAND_HIGHLIGHTED);
+
+ } else if (keyState.keycode == Common::KEYCODE_RETURN) {
+ done = 1;
+
+ } else if (keyState.keycode == Common::KEYCODE_ESCAPE) {
+ filename = saveFile;
+ _selector = -1;
+ render(RENDER_NAMES_AND_SCROLLBAR);
+ done = -1;
+ }
+
+ if ((keyState.keycode >= ' ') && ((keyState.keycode <= 168) || (keyState.keycode == 225)) && (index < 50)) {
+ if (pt.x + _surface.charWidth(keyState.keycode) < _surface.w() - BUTTON_SIZE - 20) {
+ if (insert) {
+ int temp = strlen(filename.c_str() + index) - 1;
+ if (temp)
+ filename.deleteChar(index);
+ }
+
+ filename.insertChar(keyState.ascii, index);
+ _surface.fillRect(Common::Rect(pt.x, pt.y, _bounds.width() - BUTTON_SIZE - 9,
+ pt.y + _surface.fontHeight() - 1), TRANSPARENCY);
+ _surface.writeString(filename.c_str() + index, pt, COMMAND_HIGHLIGHTED);
+ pt.x += _surface.charWidth(keyState.keycode);
+ ++index;
+ }
+ }
+ } while (!done && !_vm->shouldQuit());
+
+ scene.doBgAnim();
+
+ if (talk._talkToAbort)
+ return false;
+
+ if (done == 1)
+ _savegames[_selector] = saveFile;
- // TODO
+ return done == 1;
}
Common::Rect WidgetFiles::getScrollBarBounds() const {
diff --git a/engines/sherlock/tattoo/widget_files.h b/engines/sherlock/tattoo/widget_files.h
index e861206d4b..94a029d18d 100644
--- a/engines/sherlock/tattoo/widget_files.h
+++ b/engines/sherlock/tattoo/widget_files.h
@@ -57,6 +57,11 @@ private:
void showScummVMRestoreDialog();
/**
+ * Prompt the user for a savegame name in the currently selected slot
+ */
+ bool getFilename();
+
+ /**
* Return the area of a widget that the scrollbar will be drawn in
*/
virtual Common::Rect getScrollBarBounds() const;
diff --git a/engines/sherlock/tattoo/widget_talk.cpp b/engines/sherlock/tattoo/widget_talk.cpp
index bc2f8339d2..d33da658ab 100644
--- a/engines/sherlock/tattoo/widget_talk.cpp
+++ b/engines/sherlock/tattoo/widget_talk.cpp
@@ -128,7 +128,7 @@ void WidgetTalk::handleEvents() {
// Only redraw the window if the the scrollbar position has changed
if (ui._scrollHighlight != oldHighlight || oldScrollIndex != _talkScrollIndex)
- render(HL_SCROLLBAR_ONLY);
+ render(HL_NO_HIGHLIGHTING);
// Flag if they started pressing outside of the window
if (events._firstPress && !_bounds.contains(mousePos))
@@ -385,6 +385,9 @@ void WidgetTalk::render(Highlight highlightMode) {
for (uint idx = _talkScrollIndex; idx < _statementLines.size() && yp < (_bounds.height() - _surface.fontHeight()); ++idx) {
if (highlightMode == HL_NO_HIGHLIGHTING || _statementLines[idx]._num == _selector ||
_statementLines[idx]._num == _oldSelector) {
+ // Erase the line contents
+ _surface.fillRect(Common::Rect(3, yp, _surface.w() - BUTTON_SIZE - 3, yp + _surface.fontHeight()), TRANSPARENCY);
+
// Different coloring based on whether the option has been previously chosen or not
color = (!talk._talkHistory[talk._converseNum][_statementLines[idx]._num]) ?
INFO_TOP : INFO_BOTTOM;