diff options
Diffstat (limited to 'engines/sherlock/tattoo')
-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 |
9 files changed, 307 insertions, 52 deletions
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; |