From b3c8173bd46ddc831344848723598846bd5c41e8 Mon Sep 17 00:00:00 2001 From: athrxx Date: Mon, 14 Nov 2011 19:57:23 +0100 Subject: [PATCH] KYRA: (EOB) - extend save/load dialogue to support 990 slots --- engines/kyra/gui.cpp | 40 ++++++++--------- engines/kyra/gui.h | 8 ++-- engines/kyra/gui_eob.cpp | 84 ++++++++++++++++++++++++++++------- engines/kyra/gui_eob.h | 1 + engines/kyra/gui_hof.cpp | 2 +- engines/kyra/gui_lok.cpp | 4 +- engines/kyra/gui_lol.cpp | 6 +-- engines/kyra/gui_mr.cpp | 2 +- engines/kyra/gui_v2.cpp | 4 +- engines/kyra/saveload_eob.cpp | 4 ++ engines/kyra/text_eob.cpp | 4 +- 11 files changed, 109 insertions(+), 50 deletions(-) diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp index d03fa23d5ab6..9c0adf159bc4 100644 --- a/engines/kyra/gui.cpp +++ b/engines/kyra/gui.cpp @@ -32,7 +32,7 @@ namespace Kyra { GUI::GUI(KyraEngine_v1 *kyra) : _vm(kyra), _screen(kyra->screen()) { - _savegameListUpdateNeeded = false; + _saveSlotsListUpdateNeeded = true; _savegameListSize = 0; _savegameList = 0; } @@ -46,7 +46,7 @@ GUI::~GUI() { } } -void GUI::updateSaveList(bool excludeQuickSaves) { +void GUI::updateSaveFileList(bool excludeQuickSaves) { Common::String pattern = _vm->_targetName + ".???"; Common::StringArray saveFileList = _vm->_saveFileMan->listSavefiles(pattern); _saveSlots.clear(); @@ -93,11 +93,11 @@ int GUI::getNextSavegameSlot() { return 0; } -void GUI::updateSavegameList() { - if (!_savegameListUpdateNeeded) +void GUI::updateSaveSlotsList() { + if (!_saveSlotsListUpdateNeeded) return; - _savegameListUpdateNeeded = false; + _saveSlotsListUpdateNeeded = false; if (_savegameList) { for (int i = 0; i < _savegameListSize; i++) @@ -105,31 +105,31 @@ void GUI::updateSavegameList() { delete[] _savegameList; } - updateSaveList(true); - _savegameListSize = _saveSlots.size(); + updateSaveFileList(true); + int numSaves = _savegameListSize = _saveSlots.size(); + bool allowEmptySlots = (_vm->game() == GI_EOB1 || _vm->game() == GI_EOB2); if (_savegameListSize) { - if (_vm->game() == GI_EOB1 || _vm->game() == GI_EOB2) { - Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Less()); - _savegameListSize = _saveSlots.back() + 1; - } else { - Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Greater()); - } + if (allowEmptySlots) + _savegameListSize = 990; KyraEngine_v1::SaveHeader header; Common::InSaveFile *in; - _savegameList = new char *[_savegameListSize]; + _savegameList = new char*[_savegameListSize]; + memset(_savegameList, 0, _savegameListSize * sizeof(char*)); - for (int i = 0; i < _savegameListSize; i++) { - in = _vm->openSaveForReading(_vm->getSavegameFilename(i), header); + for (int i = 0; i < numSaves; i++) { + in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i]), header); + char **listEntry = &_savegameList[allowEmptySlots? _saveSlots[i] : i]; if (in) { - _savegameList[i] = new char[header.description.size() + 1]; - Common::strlcpy(_savegameList[i], header.description.c_str(), header.description.size() + 1); - Util::convertISOToDOS(_savegameList[i]); + *listEntry = new char[header.description.size() + 1]; + Common::strlcpy(*listEntry, header.description.c_str(), header.description.size() + 1); + Util::convertISOToDOS(*listEntry); delete in; } else { - _savegameList[i] = 0; + *listEntry = 0; + error("GUI::updateSavegameList(): Unexpected missing save file for slot: %d.", _saveSlots[i]); } } diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h index efca84548275..4991707744f9 100644 --- a/engines/kyra/gui.h +++ b/engines/kyra/gui.h @@ -108,6 +108,8 @@ class GUI { // utilities for thumbnail creation virtual void createScreenThumbnail(Graphics::Surface &dst) = 0; + void notifyUpdateSaveSlotsList() { _saveSlotsListUpdateNeeded = true; } + protected: KyraEngine_v1 *_vm; Screen *_screen; @@ -116,16 +118,16 @@ class GUI { // Since ScummVM's savegame indices aren't, we re-index them. // The integers stored in _saveSlots are ScummVM savegame indices. Common::Array _saveSlots; - void updateSaveList(bool excludeQuickSaves = false); + void updateSaveFileList(bool excludeQuickSaves = false); int getNextSavegameSlot(); - void updateSavegameList(); + void updateSaveSlotsList(); virtual void sortSaveSlots(); uint32 _lastScreenUpdate; char **_savegameList; int _savegameListSize; - bool _savegameListUpdateNeeded; + bool _saveSlotsListUpdateNeeded; Common::KeyState _keyPressed; }; diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp index fcd66c923b2c..7778feba8e75 100644 --- a/engines/kyra/gui_eob.cpp +++ b/engines/kyra/gui_eob.cpp @@ -1609,7 +1609,9 @@ int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8 _flagsMouseRight = (_vm->_mouseClick == 2) ? 2 : 4; _vm->_mouseClick = 0; - if (in >= 199 && in <= 202) { + if (mouseWheel) { + return 204 + mouseWheel; + } else if (in >= 199 && in <= 202) { buttonReleaseFlag = (inputFlags & 0x800) ? 3 : 1; if (in < 201) _flagsMouseLeft = buttonReleaseFlag; @@ -2318,7 +2320,6 @@ bool GUI_Eob::runLoadMenu(int x, int y) { int xo = dm->sx; int yo = dm->sy; bool result = false; - _savegameListUpdateNeeded = true; _screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h); @@ -2629,7 +2630,6 @@ bool GUI_Eob::runSaveMenu(int x, int y) { int xo = dm->sx; int yo = dm->sy; bool result = false; - _savegameListUpdateNeeded = true; _screen->modifyScreenDim(11, dm->sx + (x >> 3), dm->sy + y, dm->w, dm->h); @@ -2667,12 +2667,11 @@ bool GUI_Eob::runSaveMenu(int x, int y) { Common::Error err = _vm->saveGameStateIntern(_savegameOffset + slot, _saveSlotStringsTemp[slot], &thumb); thumb.free(); - if (err.getCode() == Common::kNoError) { - _savegameListUpdateNeeded = true; + if (err.getCode() == Common::kNoError) result = true; - } else { + else messageDialogue(11, 15, 6); - } + runLoop = false; } } @@ -2687,14 +2686,11 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) { _saveSlotX = _saveSlotY = 0; _screen->setCurPage(2); - updateSavegameList(); - setupSaveMenuSlots(); + updateSaveSlotsList(); + _savegameOffset = 0; drawMenuButtonBox(0, 0, 176, 144, false, false); _screen->printShadedText(_vm->_saveLoadStrings[2 + id], 52, 5, 15, 0); - - for (int i = 0; i < 7; i++) - drawSaveSlotButton(i, 1, 15); _screen->copyRegion(0, 0, x, y, 176, 144, 2, 0, Screen::CR_NO_P_CHECK); _screen->setCurPage(0); @@ -2703,6 +2699,7 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) { _saveSlotX = x; _saveSlotY = y; int lastHighlight = -1; + int lastOffset = -1; int newHighlight = 0; int slot = -1; @@ -2712,12 +2709,47 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) { if (inputFlag == _vm->_keyMap[Common::KEYCODE_SPACE] || inputFlag == _vm->_keyMap[Common::KEYCODE_RETURN]) { runLoop = false; + } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_ESCAPE]) { + newHighlight = 6; + runLoop = false; } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_DOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP2]) { - if (++newHighlight > 6) - newHighlight = 0; + if (++newHighlight > 5) { + newHighlight = 5; + if (++_savegameOffset > 984) + _savegameOffset = 984; + else + lastOffset = -1; + } } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_UP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP8]) { - if (--newHighlight < 0) - newHighlight = 6; + if (--newHighlight < 0) { + newHighlight = 0; + if (--_savegameOffset < 0) + _savegameOffset = 0; + else + lastOffset = -1; + } + } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_PAGEDOWN] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP1]) { + _savegameOffset += 6; + if (_savegameOffset > 984) + _savegameOffset = 984; + else + lastOffset = -1; + } else if (inputFlag == _vm->_keyMap[Common::KEYCODE_PAGEUP] || inputFlag == _vm->_keyMap[Common::KEYCODE_KP7]) { + _savegameOffset -= 6; + if (_savegameOffset < 0) + _savegameOffset = 0; + else + lastOffset = -1; + } else if (inputFlag == 205) { + if (++_savegameOffset > 984) + _savegameOffset = 984; + else + lastOffset = -1; + } else if (inputFlag == 203) { + if (--_savegameOffset < 0) + _savegameOffset = 0; + else + lastOffset = -1; } else { slot = getHighlightSlot(); if (slot != -1) { @@ -2727,9 +2759,25 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) { } } + if (lastOffset != _savegameOffset) { + lastHighlight = -1; + setupSaveMenuSlots(); + for (int i = 0; i < 7; i++) + drawSaveSlotButton(i, 1, 15); + lastOffset = _savegameOffset; + } + if (lastHighlight != newHighlight) { drawSaveSlotButton(lastHighlight, 0, 15); drawSaveSlotButton(newHighlight, 0, 6); + + // Display highlighted slot index in the bottom left corner to avoid people getting lost with the 990 save slots + _screen->setFont(Screen::FID_6_FNT); + _screen->fillRect(_saveSlotX + 5, _saveSlotY + 135, _saveSlotX + 46, _saveSlotY + 140, _vm->_bkgColor_1); + int sli = (newHighlight == 6) ? _savegameOffset : (_savegameOffset + newHighlight); + _screen->printText(Common::String::format("%03d/989", sli).c_str(), _saveSlotX + 5, _saveSlotY + 135, _vm->_color2_1, _vm->_bkgColor_1); + _screen->setFont(Screen::FID_8_FNT); + _screen->updateScreen(); lastHighlight = newHighlight; } @@ -3966,6 +4014,10 @@ int GUI_Eob::getHighlightSlot() { return res; } +void GUI_Eob::sortSaveSlots() { + Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Less()); +} + void GUI_Eob::restParty_updateRestTime(int hours, bool init) { Screen::FontId of = _screen->setFont(Screen::FID_8_FNT); int od = _screen->curDimIndex(); diff --git a/engines/kyra/gui_eob.h b/engines/kyra/gui_eob.h index af3d3d2e4864..30fd4ccc383b 100644 --- a/engines/kyra/gui_eob.h +++ b/engines/kyra/gui_eob.h @@ -102,6 +102,7 @@ class GUI_Eob : public GUI { void setupSaveMenuSlots(); int getHighlightSlot(); + void sortSaveSlots(); void restParty_updateRestTime(int hours, bool init); diff --git a/engines/kyra/gui_hof.cpp b/engines/kyra/gui_hof.cpp index a1e0ce66bf8e..8d968ec58c7f 100644 --- a/engines/kyra/gui_hof.cpp +++ b/engines/kyra/gui_hof.cpp @@ -1148,7 +1148,7 @@ int GUI_HoF::sliderHandler(Button *caller) { } int GUI_HoF::loadMenu(Button *caller) { - updateSaveList(); + updateSaveFileList(); if (!_vm->_menuDirectlyToLoad) { updateMenuButton(caller); diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp index 6e0d108435c7..e66b3cec51f9 100644 --- a/engines/kyra/gui_lok.cpp +++ b/engines/kyra/gui_lok.cpp @@ -596,7 +596,7 @@ void GUI_LoK::setupSavegames(Menu &menu, int num) { } int GUI_LoK::saveGameMenu(Button *button) { - updateSaveList(); + updateSaveFileList(); updateMenuButton(button); _menu[2].item[5].enabled = true; @@ -636,7 +636,7 @@ int GUI_LoK::saveGameMenu(Button *button) { } int GUI_LoK::loadGameMenu(Button *button) { - updateSaveList(); + updateSaveFileList(); if (_vm->_menuDirectlyToLoad) { _menu[2].item[5].enabled = false; diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp index ac3d16be6748..6a8e6e13b70b 100644 --- a/engines/kyra/gui_lol.cpp +++ b/engines/kyra/gui_lol.cpp @@ -2222,13 +2222,13 @@ int GUI_LoL::runMenu(Menu &menu) { // Instead, the respevtive struct entry is used to determine whether // a menu has scroll buttons or slider bars. uint8 hasSpecialButtons = 0; - _savegameListUpdateNeeded = true; + _saveSlotsListUpdateNeeded = true; while (_displayMenu) { _vm->_mouseX = _vm->_mouseY = 0; if (_currentMenu == &_loadMenu || _currentMenu == &_saveMenu || _currentMenu == &_deleteMenu) { - updateSavegameList(); + updateSaveSlotsList(); setupSaveMenuSlots(*_currentMenu, 4); } @@ -2837,7 +2837,7 @@ int GUI_LoL::clickedChoiceMenu(Button *button) { _vm->_saveFileMan->renameSavefile(oldName, newName); } _newMenu = &_mainMenu; - _savegameListUpdateNeeded = true; + _saveSlotsListUpdateNeeded = true; } } else if (button->arg == _choiceMenu.item[1].itemId) { _newMenu = &_mainMenu; diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp index 82082961e9ac..b8bf8f43e2e4 100644 --- a/engines/kyra/gui_mr.cpp +++ b/engines/kyra/gui_mr.cpp @@ -1277,7 +1277,7 @@ int GUI_MR::optionsButton(Button *button) { } int GUI_MR::loadMenu(Button *caller) { - updateSaveList(); + updateSaveFileList(); if (!_vm->_menuDirectlyToLoad) { updateMenuButton(caller); diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp index a1d74fded9db..27b329c25ad6 100644 --- a/engines/kyra/gui_v2.cpp +++ b/engines/kyra/gui_v2.cpp @@ -594,7 +594,7 @@ int GUI_v2::cancelLoadMenu(Button *caller) { } int GUI_v2::saveMenu(Button *caller) { - updateSaveList(); + updateSaveFileList(); updateMenuButton(caller); @@ -690,7 +690,7 @@ int GUI_v2::cancelSaveMenu(Button *caller) { } int GUI_v2::deleteMenu(Button *caller) { - updateSaveList(); + updateSaveFileList(); updateMenuButton(caller); if (_saveSlots.size() < 2) { diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp index 24a10133d09b..847f30428816 100644 --- a/engines/kyra/saveload_eob.cpp +++ b/engines/kyra/saveload_eob.cpp @@ -391,6 +391,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) { _loading = false; _screen->fadeFromBlack(20); + removeInputTop(); return Common::kNoError; } @@ -589,6 +590,9 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName, } delete out; + + _gui->notifyUpdateSaveSlotsList(); + return Common::kNoError; } diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp index 3641681f4b11..318147c679d7 100644 --- a/engines/kyra/text_eob.cpp +++ b/engines/kyra/text_eob.cpp @@ -573,7 +573,7 @@ void TextDisplayer_Eob::textPageBreak() { int inputFlag = vm()->checkInput(0, false) & 0xFF; vm()->removeInputTop(); - while (!inputFlag) { + while (!inputFlag && !_vm->shouldQuit()) { vm()->update(); if (vm()->speechEnabled()) { @@ -603,7 +603,7 @@ void TextDisplayer_Eob::textPageBreak() { if (target) loop = false; } - } while (loop); + } while (loop && !_vm->shouldQuit()); if (vm()->gameFlags().use16ColorMode) screen()->fillRect(x + 8, y, x + 57, y + 9, _textDimData[screen()->curDimIndex()].color2);