From 31860163709b12a38856fc017a217eb5e32610a7 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 21 Apr 2015 18:25:06 -0500 Subject: SHERLOCK: Implemented save game dialog event handling --- engines/sherlock/detection.cpp | 23 ++- engines/sherlock/saveload.cpp | 185 +++++++++++++++++++- engines/sherlock/saveload.h | 23 ++- engines/sherlock/sherlock.cpp | 3 + engines/sherlock/sherlock.h | 2 + engines/sherlock/user_interface.cpp | 325 ++++++++++++++++++++++++++++++++++-- engines/sherlock/user_interface.h | 3 +- 7 files changed, 540 insertions(+), 24 deletions(-) (limited to 'engines/sherlock') diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index 7d9db96e77..bb66cee7df 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -24,6 +24,7 @@ #include "sherlock/saveload.h" #include "sherlock/scalpel/scalpel.h" #include "sherlock/tattoo/tattoo.h" +#include "common/system.h" #include "engines/advancedDetector.h" namespace Sherlock { @@ -105,13 +106,33 @@ SaveStateList SherlockMetaEngine::listSaves(const char *target) const { } int SherlockMetaEngine::getMaximumSaveSlot() const { - return NUM_SAVEGAME_SLOTS; + return MAX_SAVEGAME_SLOTS; } void SherlockMetaEngine::removeSaveState(const char *target, int slot) const { + Common::String filename = Common::String::format("%s.%03d", target, slot); + g_system->getSavefileManager()->removeSavefile(filename); } SaveStateDescriptor SherlockMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + Common::String filename = Common::String::format("%s.%03d", target, slot); + Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename); + + if (f) { + Sherlock::SherlockSavegameHeader header; + Sherlock::SaveManager::readSavegameHeader(f, header); + delete f; + + // Create the return descriptor + SaveStateDescriptor desc(slot, header._saveName); + desc.setThumbnail(header._thumbnail); + desc.setSaveDate(header._year, header._month, header._day); + desc.setSaveTime(header._hour, header._minute); + desc.setPlayTime(header._totalFrames * GAME_FRAME_TIME); + + return desc; + } + return SaveStateDescriptor(); } diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 54995e056a..78c86c836e 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -29,9 +29,21 @@ 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 +}; + +/*----------------------------------------------------------------*/ + SaveManager::SaveManager(SherlockEngine *vm, const Common::String &target) : _vm(vm), _target(target) { _saveThumb = nullptr; + _envMode = SAVEMODE_NONE; } SaveManager::~SaveManager() { @@ -44,23 +56,80 @@ SaveManager::~SaveManager() { /** * Shows the in-game dialog interface for loading and saving games */ -void SaveManager::show() { +void SaveManager::drawInterface() { + Screen &screen = *_vm->_screen; + UserInterface &ui = *_vm->_ui; + + // Create a list of savegame slots createSavegameList(); - // TODO + 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 - 5) + screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), COMMAND_NULL, 0, "Down"); + + 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]); + } + + if (!ui._windowStyle) { + screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); + } else { + ui.summonWindow(); + } + + _envMode = SAVEMODE_NONE; } /** * Build up a savegame list, with empty slots given an explicit Empty message */ void SaveManager::createSavegameList() { + Screen &screen = *_vm->_screen; + _savegames.clear(); - for (int idx = 0; idx < NUM_SAVEGAME_SLOTS; ++idx) + for (int idx = 0; idx < MAX_SAVEGAME_SLOTS; ++idx) _savegames.push_back("-EMPTY"); SaveStateList saveList = getSavegameList(_target); for (uint idx = 0; idx < saveList.size(); ++idx) _savegames[saveList[idx].getSaveSlot()] = saveList[idx].getDescription(); + + // Ensure the names will fit on the screen + for (uint idx = 0; idx < _savegames.size(); ++idx) { + int width = screen.stringWidth(_savegames[idx]) + 24; + if (width > 308) { + // It won't fit in, so remove characters until it does + do { + width -= screen.charWidth(_savegames[idx].lastChar()); + _savegames[idx].deleteLastChar(); + } while (width > 300); + } + } } /** @@ -81,7 +150,7 @@ SaveStateList SaveManager::getSavegameList(const Common::String &target) { const char *ext = strrchr(file->c_str(), '.'); int slot = ext ? atoi(ext + 1) : -1; - if (slot >= 0 && slot < NUM_SAVEGAME_SLOTS) { + if (slot >= 0 && slot < MAX_SAVEGAME_SLOTS) { Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); if (in) { @@ -101,6 +170,9 @@ SaveStateList SaveManager::getSavegameList(const Common::String &target) { const char *const SAVEGAME_STR = "SHLK"; #define SAVEGAME_STR_SIZE 4 +/** + * Read in the header information for a savegame + */ bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header) { char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; header._thumbnail = nullptr; @@ -135,6 +207,9 @@ bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHea return true; } +/** + * Write out the header information for a savegame + */ void SaveManager::writeSavegameHeader(Common::OutSaveFile *out, SherlockSavegameHeader &header) { // Write out a savegame header out->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1); @@ -180,4 +255,106 @@ void SaveManager::createThumbnail() { ::createThumbnail(_saveThumb, (const byte *)_vm->_screen->getPixels(), SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT, thumbPalette); } +/** + * Return the index of the button the mouse is over, if any + */ +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; +} + +/** + * Handle highlighting buttons + */ +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 == 1) && (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 == 2) && (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"); +} + +/** + * Load the game in the specified slot + */ +void SaveManager::loadGame(int slot) { + // TODO +} + +/** + * Save the game in the specified slot with the given name + */ +void SaveManager::saveGame(int slot, const Common::String &name) { + // TODO +} + +/** + * Make sure that the selected savegame is on-screen + */ +bool SaveManager::checkGameOnScreen(int slot) { + Screen &screen = *_vm->_screen; + + // Check if it's already on-screen + if (slot != -1 && (slot < _savegameIndex || slot >= (_savegameIndex + 5))) { + _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::getFilename(int slot) { + // TODO + return false; +} + } // End of namespace Sherlock diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h index a0f1da4041..20ce4e6067 100644 --- a/engines/sherlock/saveload.h +++ b/engines/sherlock/saveload.h @@ -31,9 +31,13 @@ namespace Sherlock { -#define NUM_SAVEGAME_SLOTS 99 +#define MAX_SAVEGAME_SLOTS 99 #define SHERLOCK_SAVEGAME_VERSION 1 +enum SaveMode { SAVEMODE_NONE = 0, SAVEMODE_LOAD = 1, SAVEMODE_SAVE = 2 }; + +extern const int ENV_POINTS[6][3]; + struct SherlockSavegameHeader { uint8 _version; Common::String _saveName; @@ -49,15 +53,18 @@ class SaveManager { private: SherlockEngine *_vm; Common::String _target; - Common::StringArray _savegames; Graphics::Surface *_saveThumb; void createSavegameList(); +public: + Common::StringArray _savegames; + int _savegameIndex; + SaveMode _envMode; public: SaveManager(SherlockEngine *vm, const Common::String &target); ~SaveManager(); - void show(); + void drawInterface(); void createThumbnail(); @@ -67,6 +74,16 @@ public: static bool readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header); + int getHighlightedButton() const; + + void highlightButtons(int btnIndex); + + void loadGame(int slot); + void saveGame(int slot, const Common::String &name); + + bool checkGameOnScreen(int slot); + + bool getFilename(int slot); }; } // End of namespace Sherlock diff --git a/engines/sherlock/sherlock.cpp b/engines/sherlock/sherlock.cpp index 632e388642..d0744c4775 100644 --- a/engines/sherlock/sherlock.cpp +++ b/engines/sherlock/sherlock.cpp @@ -38,6 +38,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam _map = nullptr; _people = nullptr; _res = nullptr; + _saves = nullptr; _scene = nullptr; _screen = nullptr; _sound = nullptr; @@ -58,6 +59,7 @@ SherlockEngine::~SherlockEngine() { delete _journal; delete _map; delete _people; + delete _saves; delete _scene; delete _screen; delete _sound; @@ -83,6 +85,7 @@ void SherlockEngine::initialize() { _map = new Map(this); _journal = new Journal(this); _people = new People(this); + _saves = new SaveManager(this, _targetName); _scene = new Scene(this); _screen = new Screen(this); _sound = new Sound(this); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index 67c7a2864d..20afb6f0e3 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -39,6 +39,7 @@ #include "sherlock/map.h" #include "sherlock/people.h" #include "sherlock/resources.h" +#include "sherlock/saveload.h" #include "sherlock/scene.h" #include "sherlock/screen.h" #include "sherlock/sound.h" @@ -89,6 +90,7 @@ public: Map *_map; People *_people; Resources *_res; + SaveManager *_saves; Scene *_scene; Screen *_screen; Sound *_sound; diff --git a/engines/sherlock/user_interface.cpp b/engines/sherlock/user_interface.cpp index 3ab705e26c..c8cd300b5e 100644 --- a/engines/sherlock/user_interface.cpp +++ b/engines/sherlock/user_interface.cpp @@ -65,15 +65,15 @@ const int SETUP_POINTS[12][4] = { { 219, 176, 316, 268 }, // Fade Style { 103, 176, 217, 160 }, // Window Open Style { 4, 176, 101, 53 }, // Portraits Toggle - { 219, 187, 316, 268 } // Key Pad Accel. Toggle + { 219, 187, 316, 268 } // _key Pad Accel. Toggle }; const char COMMANDS[13] = "LMTPOCIUGJFS"; const char INVENTORY_COMMANDS[9] = { "ELUG-+,." }; -const char *const PRESS_KEY_FOR_MORE = "Press any Key for More."; -const char *const PRESS_KEY_TO_CONTINUE = "Press any Key to Continue."; +const char *const PRESS_KEY_FOR_MORE = "Press any _key for More."; +const char *const PRESS_KEY_TO_CONTINUE = "Press any _key to Continue."; const char *const MOPEN[] = { "This cannot be opened", "It is already open", "It is locked", "Wait for Watson", " ", "." @@ -164,7 +164,7 @@ void Settings::drawInteface(bool flag) { tempStr = Common::String::format("Portraits %s", SETUP_STRS0[people._portraitsOn]); screen.makeButton(Common::Rect(SETUP_POINTS[10][0], SETUP_POINTS[10][1], SETUP_POINTS[10][2], SETUP_POINTS[10][1] + 10), SETUP_POINTS[10][3] - screen.stringWidth(tempStr) / 2, tempStr); - tempStr = Common::String::format("Key Pad %s", _vm->_keyPadSpeed ? "Fast" : "Slow"); + tempStr = Common::String::format("_key Pad %s", _vm->_keyPadSpeed ? "Fast" : "Slow"); screen.makeButton(Common::Rect(SETUP_POINTS[11][0], SETUP_POINTS[11][1], SETUP_POINTS[11][2], SETUP_POINTS[11][1] + 10), SETUP_POINTS[11][3] - screen.stringWidth(tempStr) / 2, tempStr); @@ -183,7 +183,7 @@ void Settings::drawInteface(bool flag) { } } -int Settings::drawButtons(const Common::Point &pt, int key) { +int Settings::drawButtons(const Common::Point &pt, int _key) { Events &events = *_vm->_events; People &people = *_vm->_people; Screen &screen = *_vm->_screen; @@ -196,7 +196,7 @@ int Settings::drawButtons(const Common::Point &pt, int key) { for (int idx = 0; idx < 12; ++idx) { if ((pt.x > SETUP_POINTS[idx][0] && pt.x < SETUP_POINTS[idx][2] && pt.y > SETUP_POINTS[idx][1] && pt.y < (SETUP_POINTS[idx][1] + 10) && (events._released || events._released)) - || (key == SETUP_NAMES[idx][0])) { + || (_key == SETUP_NAMES[idx][0])) { found = idx; color = COMMAND_HIGHLIGHTED; } else { @@ -238,7 +238,7 @@ int Settings::drawButtons(const Common::Point &pt, int key) { screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; case 11: - tempStr = Common::String::format("Key Pad %s", SETUP_STRS4[_vm->_keyPadSpeed]); + tempStr = Common::String::format("_key Pad %s", SETUP_STRS4[_vm->_keyPadSpeed]); screen.buttonPrint(Common::Point(SETUP_POINTS[idx][3], SETUP_POINTS[idx][1]), color, true, tempStr); break; default: @@ -328,7 +328,7 @@ void UserInterface::handleInput() { _keycode = Common::KEYCODE_INVALID; // Check kbd and set the mouse released flag if Enter or space is pressed. - // Otherwise, the pressed key is stored for later use + // Otherwise, the pressed _key is stored for later use if (events.kbHit()) { Common::KeyState keyState = events.getKey(); @@ -890,7 +890,304 @@ void UserInterface::lookInv() { * Handles input when the file list window is being displayed */ void UserInterface::doEnvControl() { - // TODO + Events &events = *_vm->_events; + SaveManager &saves = *_vm->_saves; + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Talk &talk = *_vm->_talk; + Common::Point mousePos = events.mousePos(); + static const char ENV_COMMANDS[7] = "ELSUDQ"; + byte color; + + _key = _oldKey = -1; + _keyboardInput = false; + int found = saves.getHighlightedButton(); + + if (events._pressed || events._released) + { + events.clearKeyboard(); + + // Check for a filename entry being highlighted + int found1 = 0; + if ((events._pressed || events._released) && mousePos.y > (CONTROLS_Y + 10)) + { + for (_selector = 0; (_selector < 5) && !found1; ++_selector) + if (mousePos.y > (CONTROLS_Y + 11 + _selector * 10) && mousePos.y < (CONTROLS_Y + 21 + _selector * 10)) + found1 = 1; + + if (_selector + saves._savegameIndex - 1 < MAX_SAVEGAME_SLOTS + (saves._envMode != 1)) + _selector = _selector + saves._savegameIndex - 1; + else + _selector = -1; + + if (!found1) + _selector = -1; + } + + // Handle selecting buttons, if any + saves.highlightButtons(found); + + if (found == 0 || found == 5) + saves._envMode = SAVEMODE_NONE; + } + + if (_keycode) { + _key = toupper(_keycode); + + // Escape _key will close the dialog + if (_key == Common::KEYCODE_ESCAPE) + _key = 'E'; + + if (_key == 'E' || _key == 'L' || _key == 'S' || _key == 'U' || _key == 'D' || _key == 'Q') { + const char *chP = strchr(ENV_COMMANDS, _key); + int btnIndex = !chP ? -1 : chP - ENV_COMMANDS; + saves.highlightButtons(btnIndex); + _keyboardInput = true; + + if (_key == 'E' || _key == 'Q') { + saves._envMode = SAVEMODE_NONE; + } else if (_key >= '1' && _key <= '9') { + _keyboardInput = true; + _selector = _key - '1'; + if (_selector >= MAX_SAVEGAME_SLOTS + (saves._envMode == 1 ? 0 : 1)) + _selector = -1; + + if (saves.checkGameOnScreen(_selector)) + _oldSelector = _selector; + } else { + _selector = -1; + } + } + } + + if (_selector != _oldSelector) { + if (_oldSelector != -1 && _oldSelector >= saves._savegameIndex && _oldSelector < (saves._savegameIndex + 5)) { + screen.print(Common::Point(6, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), + INV_FOREGROUND, 0, "%d.", _oldSelector + 1); + screen.print(Common::Point(24, CONTROLS_Y + 12 + (_oldSelector - saves._savegameIndex) * 10), + INV_FOREGROUND, 0, "%s", saves._savegames[_oldSelector]); + } + + if (_selector != -1) { + screen.print(Common::Point(6, CONTROLS_Y + 12 + (_selector - saves._savegameIndex) * 10), + TALK_FOREGROUND, 0, "%d.", _selector + 1); + screen.print(Common::Point(24, CONTROLS_Y + 12 + (_selector - saves._savegameIndex) * 10), + TALK_FOREGROUND, 0, "%s", saves._savegames[_selector]); + } + + _oldSelector = _selector; + } + + if (events._released || _keyboardInput) { + if ((found == 0 && events._released) || _key == 'E') { + banishWindow(); + _windowBounds.top = CONTROLS_Y1; + + events._pressed = events._released = _keyboardInput = false; + _keycode = Common::KEYCODE_INVALID; + } else if ((found == 1 && events._released) || _key == 'L') { + saves._envMode = SAVEMODE_LOAD; + if (_selector != -1) { + saves.loadGame(_selector + 1); + } + } else if ((found == 2 && events._released) || _key == 'S') { + saves._envMode = SAVEMODE_SAVE; + if (_selector != -1) { + if (saves.checkGameOnScreen(_selector)) + _oldSelector = _selector; + + if (saves.getFilename(_selector)) { + saves.saveGame(_selector + 1, saves._savegames[_selector]); + + banishWindow(1); + _windowBounds.top = CONTROLS_Y1; + _key = _oldKey = -1; + _keycode = Common::KEYCODE_INVALID; + _keyboardInput = false; + } else { + if (!talk._talkToAbort) { + screen._backBuffer1.fillRect(Common::Rect(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, + SHERLOCK_SCREEN_WIDTH - 2, CONTROLS_Y + 20 + (_selector - saves._savegameIndex) * 10), INV_BACKGROUND); + screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND, + "%d.", _selector + 1); + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), INV_FOREGROUND, + "%s", saves._savegames[_selector]); + + screen.slamArea(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, 311, 10); + _selector = _oldSelector = -1; + } + } + } + } else if (((found == 3 && events._released) || _key == 'U') && saves._savegameIndex) { + bool moreKeys; + do { + saves._savegameIndex--; + screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, + SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); + + for (int idx = saves._savegameIndex; idx < (saves._savegameIndex + 5); ++idx) { + color = INV_FOREGROUND; + if (idx == _selector && idx >= saves._savegameIndex && idx < (saves._savegameIndex + 5)) + color = TALK_FOREGROUND; + + screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%d.", idx + 1); + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, "%s", saves._savegames[idx]); + } + + screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT)); + + color = !saves._savegameIndex ? COMMAND_NULL : COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), color, true, "Up"); + color = (saves._savegameIndex == MAX_SAVEGAME_SLOTS - 5) ? COMMAND_NULL : COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, true, "Down"); + + // Check for there are more pending U keys pressed + moreKeys = false; + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + + _key = toupper(keyState.keycode); + moreKeys = _key == 'U'; + } + } while ((saves._savegameIndex) && moreKeys); + } else if (((found == 4 && events._released) || _key == 'D') && saves._savegameIndex < (MAX_SAVEGAME_SLOTS - 5)) { + bool moreKeys; + do { + saves._savegameIndex++; + screen._backBuffer1.fillRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, + SHERLOCK_SCREEN_HEIGHT - 1), INV_BACKGROUND); + + for (int idx = saves._savegameIndex; idx < (saves._savegameIndex + 5); ++idx) { + if (idx == _selector && idx >= saves._savegameIndex && idx < (saves._savegameIndex + 5)) + color = TALK_FOREGROUND; + else + color = INV_FOREGROUND; + + screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, + "%d.", idx + 1); + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (idx - saves._savegameIndex) * 10), color, + "%s", saves._savegames[idx]); + } + + screen.slamRect(Common::Rect(3, CONTROLS_Y + 11, SHERLOCK_SCREEN_WIDTH - 2, SHERLOCK_SCREEN_HEIGHT)); + + color = (!saves._savegameIndex) ? COMMAND_NULL : COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(ENV_POINTS[3][2], CONTROLS_Y), color, true, "Up"); + + color = (saves._savegameIndex == MAX_SAVEGAME_SLOTS - 5) ? COMMAND_NULL : COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(ENV_POINTS[4][2], CONTROLS_Y), color, true, "Down"); + + // Check for there are more pending D keys pressed + moreKeys = false; + if (events.kbHit()) { + Common::KeyState keyState; + _key = toupper(keyState.keycode); + + moreKeys = _key == 'D'; + } + } while (saves._savegameIndex < (MAX_SAVEGAME_SLOTS - 5) && moreKeys); + } else if ((found == 5 && events._released) || _key == 'Q') { + clearWindow(); + screen.print(Common::Point(0, CONTROLS_Y + 20), INV_FOREGROUND, "Are you sure you wish to Quit ?"); + screen.vgaBar(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + 10), BORDER_COLOR); + + screen.makeButton(Common::Rect(112, CONTROLS_Y, 150, CONTROLS_Y + 10), 136 - screen.stringWidth("Yes") / 2, "Yes"); + screen.makeButton(Common::Rect(161, CONTROLS_Y, 209, CONTROLS_Y + 10), 184 - screen.stringWidth("No") / 2, "No"); + screen.slamArea(112, CONTROLS_Y, 97, 10); + + do { + scene.doBgAnim(); + + if (talk._talkToAbort) + return; + + events.pollEventsAndWait(); + events.setButtonState(); + if (events.kbHit()) { + Common::KeyState keyState = events.getKey(); + _key = toupper(keyState.keycode); + + if (_key == 'X' && (keyState.flags & Common::KBD_ALT) != 0) { + _vm->quitGame(); + events.pollEvents(); + return; + } + + if (_key == Common::KEYCODE_ESCAPE) + _key = 'N'; + + if (_key == Common::KEYCODE_RETURN || _key == Common::KEYCODE_SPACE) { + events._pressed = false; + events._released = true; + events._oldButtons = 0; + _keycode = Common::KEYCODE_INVALID; + } + } + + if (events._pressed || events._released) { + if (mousePos.x > 112 && mousePos.x < 159 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9)) + color = COMMAND_HIGHLIGHTED; + else + color = COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(136, CONTROLS_Y), color, true, "Yes"); + + if (mousePos.x > 161 && mousePos.x < 208 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9)) + color = COMMAND_HIGHLIGHTED; + else + color = COMMAND_FOREGROUND; + screen.buttonPrint(Common::Point(184, CONTROLS_Y), color, true, "No"); + } + + if (mousePos.x > 112 && mousePos.x < 159 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9) && events._released) + _key = 'Y'; + + if (mousePos.x > 161 && mousePos.x < 208 && mousePos.y > CONTROLS_Y && mousePos.y < (CONTROLS_Y + 9) && events._released) + _key = 'N'; + } while (!_vm->shouldQuit() && _key != 'Y' && _key != 'N'); + + if (_key == 'Y') { + _vm->quitGame(); + events.pollEvents(); + return; + } else { + screen.buttonPrint(Common::Point(184, CONTROLS_Y), COMMAND_HIGHLIGHTED, true, "No"); + banishWindow(1); + _windowBounds.top = CONTROLS_Y1; + _key = -1; + } + } else { + if (_selector != -1) { + // Are we already in Load mode? + if (saves._envMode == SAVEMODE_LOAD) { + saves.loadGame(_selector + 1); + } else if (saves._envMode == SAVEMODE_SAVE || _selector == MAX_SAVEGAME_SLOTS) { + // We're alreaady in save mode, or pointed to an empty save slot + if (saves.checkGameOnScreen(_selector)) + _oldSelector = _selector; + + if (saves.getFilename(_selector)) { + saves.saveGame(_selector + 1, saves._savegames[_selector]); + banishWindow(); + _windowBounds.top = CONTROLS_Y1; + _key = _oldKey = -1; + _keycode = Common::KEYCODE_INVALID; + _keyboardInput = false; + } else { + if (!talk._talkToAbort) { + screen._backBuffer1.fillRect(Common::Rect(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, + 317, CONTROLS_Y + 20 + (_selector - saves._savegameIndex) * 10), INV_BACKGROUND); + screen.gPrint(Common::Point(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), + INV_FOREGROUND, 0, "%d.", _selector + 1); + screen.gPrint(Common::Point(24, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10), + INV_FOREGROUND, 0, "%s", saves._savegames[_selector]); + screen.slamArea(6, CONTROLS_Y + 11 + (_selector - saves._savegameIndex) * 10, 311, 10); + _selector = _oldSelector = -1; + } + } + } + } + } + } } /** @@ -1199,6 +1496,7 @@ void UserInterface::doLookControl() { void UserInterface::doMainControl() { Events &events = *_vm->_events; Inventory &inv = *_vm->_inventory; + SaveManager &saves = *_vm->_saves; Common::Point pt = events.mousePos(); if ((events._pressed || events._released) && pt.y > CONTROLS_Y) { @@ -1302,7 +1600,10 @@ void UserInterface::doMainControl() { case 'F': pushButton(10); _menuMode = FILES_MODE; - environment(); + saves.drawInterface(); + + _selector = _oldSelector = -1; + _windowOpen = true; break; case 'S': pushButton(11); @@ -1699,10 +2000,6 @@ void UserInterface::journalControl() { // TODO } -void UserInterface::environment() { - // TODO -} - /** * Handles input when the settings window is being shown */ diff --git a/engines/sherlock/user_interface.h b/engines/sherlock/user_interface.h index 211287c372..12470357e5 100644 --- a/engines/sherlock/user_interface.h +++ b/engines/sherlock/user_interface.h @@ -99,7 +99,6 @@ private: bool _lookScriptFlag; Common::Rect _windowBounds; Common::String _descStr; - int _windowStyle; int _find; int _oldUse; private: @@ -124,7 +123,6 @@ private: void doTalkControl(); void journalControl(); - void environment(); void doControls(); void checkUseAction(const UseType *use, const Common::String &invName, const char *const messages[], @@ -138,6 +136,7 @@ public: bool _endKeyActive; int _invLookFlag; int _temp1; + int _windowStyle; public: UserInterface(SherlockEngine *vm); ~UserInterface(); -- cgit v1.2.3