diff options
Diffstat (limited to 'engines/sherlock')
-rw-r--r-- | engines/sherlock/saveload.cpp | 2 | ||||
-rw-r--r-- | engines/sherlock/scalpel/scalpel_scene.cpp | 21 | ||||
-rw-r--r-- | engines/sherlock/scalpel/scalpel_scene.h | 6 | ||||
-rw-r--r-- | engines/sherlock/scene.cpp | 42 | ||||
-rw-r--r-- | engines/sherlock/scene.h | 12 | ||||
-rw-r--r-- | engines/sherlock/sherlock.h | 1 | ||||
-rw-r--r-- | engines/sherlock/talk.cpp | 10 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_journal.cpp | 6 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_scene.cpp | 64 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_scene.h | 5 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_talk.cpp | 2 | ||||
-rw-r--r-- | engines/sherlock/tattoo/tattoo_user_interface.cpp | 6 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_base.cpp | 23 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_files.cpp | 243 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_files.h | 5 | ||||
-rw-r--r-- | engines/sherlock/tattoo/widget_talk.cpp | 5 |
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; |