737 lines
19 KiB
C++
737 lines
19 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Copyright 2020 Google
|
|
*
|
|
*/
|
|
#include "hadesch/hadesch.h"
|
|
#include "hadesch/video.h"
|
|
#include "common/util.h"
|
|
|
|
namespace Hadesch {
|
|
|
|
enum {
|
|
kBackgroundZ = 10000,
|
|
kScrollZ = 9900,
|
|
kScrollBarZ = 9000,
|
|
kThumbnailZ = 5000,
|
|
kArrowsZ = 2900,
|
|
kThumbZ = 2800,
|
|
kButtonZ = 2000,
|
|
kTitleZ = 2000
|
|
};
|
|
|
|
static const struct {
|
|
const char *image;
|
|
const char *hotname;
|
|
} buttons[] = {
|
|
{"return", "returntogame"},
|
|
{"credits", "credits"},
|
|
{"quit", "quitgame"},
|
|
{"new", "new"},
|
|
{"savegame", "savegame"},
|
|
{"restoregame", "restoregame"},
|
|
{"cancel", "cancel"},
|
|
{"save", "save"},
|
|
{"delete", "delete"},
|
|
{"yes", "yes"},
|
|
{"no", "no"},
|
|
{"ok", "ok"}
|
|
};
|
|
|
|
static const char *saveDescs[] = {
|
|
"",
|
|
"%s in intro scene",
|
|
"%s on mount olympus",
|
|
"%s in wall of fame",
|
|
"%s on Seriphos",
|
|
"%s in Athena temple",
|
|
"%s on Medusa Isle",
|
|
"%s in Medusa fight",
|
|
"%s on Argo",
|
|
"%s in Troy",
|
|
"%s in Catacombs",
|
|
"%s in Priam's Castle",
|
|
"%s in Trojan horse puzzle",
|
|
"%s on Crete",
|
|
"%s in Minos' Palace",
|
|
"%s in Daedalus' Room",
|
|
"%s in Minotaur puzzle",
|
|
"%s on Volcano top",
|
|
"%s near river Styx",
|
|
"%s in Hades' throne room",
|
|
"%s in ferryman puzzle",
|
|
"%s in monster puzzle",
|
|
"%s in Hades' Challenge",
|
|
"%s in credits scene",
|
|
""
|
|
};
|
|
|
|
class OptionsHandler : public Handler {
|
|
public:
|
|
enum AlertType {
|
|
kAlertSaveBeforeLoad,
|
|
kAlertSaveBeforeExit,
|
|
kAlertSaveBeforeNew,
|
|
kDeleteFromLoad,
|
|
kDeleteFromSave,
|
|
kDeleteUser
|
|
};
|
|
enum SaveMenuVariant {
|
|
kSaveFromMainMenu,
|
|
kSaveBeforeLoad,
|
|
kSaveBeforeExit,
|
|
kSaveBeforeNew
|
|
};
|
|
OptionsHandler() {
|
|
_savesLoaded = false;
|
|
_showPos = 0;
|
|
_selectedSave = -1;
|
|
_isLast = false;
|
|
}
|
|
void handleClick(const Common::String &hotname) override {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
|
|
if (hotname == "returntogame") {
|
|
g_vm->exitOptions();
|
|
return;
|
|
}
|
|
if (hotname == "credits") {
|
|
g_vm->enterOptionsCredits();
|
|
return;
|
|
}
|
|
|
|
if (hotname == "savegame") {
|
|
g_vm->resetOptionsRoom();
|
|
saveMenu(kSaveFromMainMenu);
|
|
return;
|
|
}
|
|
|
|
if (hotname == "restoregame") {
|
|
g_vm->resetOptionsRoom();
|
|
if (gameInProgress())
|
|
alertMenu(kAlertSaveBeforeLoad);
|
|
else
|
|
loadMenuUser();
|
|
return;
|
|
}
|
|
|
|
if (hotname == "cancel") {
|
|
switch (_currentMenu) {
|
|
case kLoadSlotMenu:
|
|
g_vm->resetOptionsRoom();
|
|
loadMenuUser();
|
|
break;
|
|
case kSaveMenu:
|
|
case kLoadUserMenu:
|
|
if (gameInProgress()) {
|
|
g_vm->resetOptionsRoom();
|
|
gameMenu();
|
|
} else {
|
|
g_vm->exitOptions();
|
|
}
|
|
break;
|
|
// No cancel in game menu
|
|
case kGameMenu:
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (hotname == "save" && _currentMenu == kSaveMenu) {
|
|
performSave();
|
|
return;
|
|
}
|
|
|
|
if (hotname.matchString("nameslot#")) {
|
|
_selectedSave = _showPos + hotname.substr(8).asUint64();
|
|
renderUserNames();
|
|
return;
|
|
}
|
|
|
|
if (hotname.matchString("saveslot#")) {
|
|
_selectedSave = _showPos + hotname.substr(8).asUint64();
|
|
renderSaveSlots();
|
|
return;
|
|
}
|
|
|
|
if (hotname.matchString("restoreslot#")) {
|
|
_selectedSave = _showPos + hotname.substr(11).asUint64();
|
|
renderLoadSlots();
|
|
return;
|
|
}
|
|
|
|
if (hotname == "arrowup" && _currentMenu == kLoadSlotMenu) {
|
|
if (_showPos < 6)
|
|
_showPos = 0;
|
|
else
|
|
_showPos -= 6;
|
|
renderLoadSlots();
|
|
return;
|
|
}
|
|
|
|
if (hotname == "arrowdown" && _currentMenu == kLoadSlotMenu) {
|
|
if (_showPos + 6 < (int) _userNames.size())
|
|
_showPos += 6;
|
|
renderLoadSlots();
|
|
return;
|
|
}
|
|
|
|
if (hotname == "arrowup" && _currentMenu == kLoadUserMenu) {
|
|
if (_showPos < 6)
|
|
_showPos = 0;
|
|
else
|
|
_showPos -= 6;
|
|
renderUserNames();
|
|
return;
|
|
}
|
|
|
|
if (hotname == "arrowdown" && _currentMenu == kLoadUserMenu) {
|
|
if (_showPos + 6 < (int) _userNames.size())
|
|
_showPos += 6;
|
|
renderUserNames();
|
|
return;
|
|
}
|
|
|
|
if (hotname == "arrowup" && _currentMenu == kSaveMenu) {
|
|
if (_showPos < 3)
|
|
_showPos = 0;
|
|
else
|
|
_showPos -= 3;
|
|
renderSaveSlots();
|
|
return;
|
|
}
|
|
|
|
if (hotname == "arrowdown" && _currentMenu == kSaveMenu) {
|
|
if (_showPos + 3 < (int) _filteredSaves.size())
|
|
_showPos += 3;
|
|
renderSaveSlots();
|
|
return;
|
|
}
|
|
|
|
if (hotname == "no") {
|
|
switch (_alertType) {
|
|
case kAlertSaveBeforeLoad:
|
|
case kDeleteUser:
|
|
g_vm->resetOptionsRoom();
|
|
loadMenuUser();
|
|
break;
|
|
case kAlertSaveBeforeExit:
|
|
g_vm->quit();
|
|
break;
|
|
case kAlertSaveBeforeNew:
|
|
g_vm->newGame();
|
|
g_vm->exitOptions();
|
|
break;
|
|
case kDeleteFromLoad:
|
|
g_vm->resetOptionsRoom();
|
|
loadMenuSlot();
|
|
break;
|
|
case kDeleteFromSave:
|
|
g_vm->resetOptionsRoom();
|
|
saveMenu(_saveVariant);
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (hotname == "yes") {
|
|
switch (_alertType) {
|
|
case kAlertSaveBeforeLoad:
|
|
g_vm->resetOptionsRoom();
|
|
saveMenu(kSaveBeforeLoad);
|
|
break;
|
|
case kAlertSaveBeforeExit:
|
|
g_vm->resetOptionsRoom();
|
|
saveMenu(kSaveBeforeExit);
|
|
break;
|
|
case kAlertSaveBeforeNew:
|
|
g_vm->resetOptionsRoom();
|
|
saveMenu(kSaveBeforeNew);
|
|
break;
|
|
case kDeleteFromLoad:
|
|
g_vm->deleteSave(_filteredSaves[_selectedSave]._slot);
|
|
_savesLoaded = false; // Invalidate cache
|
|
g_vm->resetOptionsRoom();
|
|
loadMenuSlot();
|
|
break;
|
|
case kDeleteFromSave:
|
|
g_vm->deleteSave(_filteredSaves[_selectedSave]._slot);
|
|
_savesLoaded = false; // Invalidate cache
|
|
g_vm->resetOptionsRoom();
|
|
saveMenu(_saveVariant);
|
|
break;
|
|
case kDeleteUser: {
|
|
Common::U32String username = _userNames[_selectedSave];
|
|
for (unsigned i = 0; i < _saves.size(); i++)
|
|
if (_saves[i]._heroName == username)
|
|
g_vm->deleteSave(_saves[i]._slot);
|
|
_savesLoaded = false; // Invalidate cache
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (hotname == "ok" && _currentMenu == kLoadUserMenu) {
|
|
g_vm->resetOptionsRoom();
|
|
_chosenName = _userNames[_selectedSave];
|
|
loadMenuSlot();
|
|
return;
|
|
}
|
|
|
|
if (hotname == "restore") {
|
|
int slot = _filteredSaves[_selectedSave]._slot;
|
|
g_vm->loadGameState(slot);
|
|
g_vm->exitOptions();
|
|
return;
|
|
}
|
|
|
|
|
|
if (hotname == "quitgame") {
|
|
g_vm->resetOptionsRoom();
|
|
if (gameInProgress())
|
|
alertMenu(kAlertSaveBeforeExit);
|
|
else
|
|
g_vm->quit();
|
|
return;
|
|
}
|
|
|
|
if (hotname == "new") {
|
|
g_vm->resetOptionsRoom();
|
|
if (gameInProgress())
|
|
alertMenu(kAlertSaveBeforeNew);
|
|
else
|
|
g_vm->newGame();
|
|
return;
|
|
}
|
|
|
|
if (hotname == "delete" && _currentMenu == kLoadUserMenu) {
|
|
g_vm->resetOptionsRoom();
|
|
alertMenu(kDeleteUser);
|
|
return;
|
|
}
|
|
|
|
if (hotname == "delete" && _currentMenu == kLoadSlotMenu) {
|
|
g_vm->resetOptionsRoom();
|
|
alertMenu(kDeleteFromLoad);
|
|
return;
|
|
}
|
|
|
|
if (hotname == "delete" && _currentMenu == kSaveMenu) {
|
|
g_vm->resetOptionsRoom();
|
|
alertMenu(kDeleteFromSave);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void handleMouseOver(const Common::String &hotname) override {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
for (unsigned i = 0; i < ARRAYSIZE(buttons); i++)
|
|
if (hotname == buttons[i].hotname) {
|
|
room->selectFrame(buttons[i].image, kButtonZ, 1);
|
|
return;
|
|
}
|
|
if (hotname == "arrowup" && _showPos > 0) {
|
|
room->selectFrame("arrows", kArrowsZ, 1);
|
|
return;
|
|
}
|
|
|
|
if (hotname == "arrowdown" && !_isLast) {
|
|
room->selectFrame("arrows", kArrowsZ, 2);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void handleMouseOut(const Common::String &hotname) override {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
for (unsigned i = 0; i < ARRAYSIZE(buttons); i++)
|
|
if (hotname == buttons[i].hotname) {
|
|
room->selectFrame(buttons[i].image, kButtonZ, 0);
|
|
return;
|
|
}
|
|
|
|
if (hotname == "arrowup" || hotname == "arrowdown") {
|
|
room->selectFrame("arrows", kArrowsZ, 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void handleKeypress(uint32 ucode) override {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
if (_currentMenu == kSaveMenu) {
|
|
if (ucode == '\n' || ucode == '\r') {
|
|
performSave();
|
|
return;
|
|
}
|
|
|
|
if (ucode == '\b' && _typedSlotName.size() > 0) {
|
|
_typedSlotName.deleteLastChar();
|
|
room->playSFX("keyclick");
|
|
renderSaveName();
|
|
return;
|
|
}
|
|
|
|
if (ucode == '\0' || ucode < ' ')
|
|
return;
|
|
|
|
if (_typedSlotName.size() < 11) {
|
|
_typedSlotName += ucode;
|
|
room->playSFX("keyclick");
|
|
renderSaveName();
|
|
}
|
|
}
|
|
}
|
|
|
|
void handleEvent(int eventId) override {
|
|
}
|
|
|
|
~OptionsHandler() override {}
|
|
|
|
void prepareRoom() override {
|
|
Persistent *persistent = g_vm->getPersistent();
|
|
if (persistent->_currentRoomId == kOlympusRoom)
|
|
loadMenuUser();
|
|
else
|
|
gameMenu();
|
|
}
|
|
|
|
private:
|
|
void performSave() {
|
|
int slot = g_vm->firstAvailableSlot();
|
|
Persistent *persistent = g_vm->getPersistent();
|
|
Common::String heroNameUTF8 = persistent->_heroName.encode(Common::kUtf8);
|
|
// UTF-8
|
|
Common::String descPos = Common::String::format(
|
|
saveDescs[persistent->_currentRoomId],
|
|
heroNameUTF8.c_str());
|
|
// UTF-8
|
|
Common::String desc = _typedSlotName.empty() ? descPos
|
|
: _typedSlotName + " (" + descPos + ")";
|
|
|
|
persistent->_slotDescription = _typedSlotName;
|
|
Common::Error res = g_vm->saveGameState(slot, desc);
|
|
debug("%d, %s->[%d, %s]", slot, desc.c_str(), res.getCode(), res.getDesc().c_str());
|
|
_savesLoaded = false; // Invalidate cache
|
|
switch (_saveVariant) {
|
|
case kSaveFromMainMenu:
|
|
g_vm->exitOptions();
|
|
break;
|
|
case kSaveBeforeLoad:
|
|
g_vm->resetOptionsRoom();
|
|
loadMenuUser();
|
|
break;
|
|
case kSaveBeforeExit:
|
|
g_vm->quit();
|
|
break;
|
|
case kSaveBeforeNew:
|
|
g_vm->newGame();
|
|
g_vm->exitOptions();
|
|
break;
|
|
}
|
|
}
|
|
void renderSaveName() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
// One character more to handle possible backspace clicks.
|
|
room->hideString("smallascii", _typedSlotName.size() + 1);
|
|
room->renderString("smallascii", _typedSlotName, Common::Point(150, 266), 4000);
|
|
}
|
|
|
|
void gameMenu() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
_currentMenu = kGameMenu;
|
|
room->loadHotZones("OPGame.HOT");
|
|
room->addStaticLayer("black", kBackgroundZ);
|
|
room->disableHeroBelt();
|
|
room->selectFrame("gamemenu", kScrollBarZ, 0);
|
|
room->selectFrame("return", kButtonZ, 0);
|
|
room->selectFrame("credits", kButtonZ, 0);
|
|
room->selectFrame("quit", kButtonZ, 0);
|
|
room->selectFrame("new", kButtonZ, 0);
|
|
room->selectFrame("savegame", kButtonZ, 0);
|
|
if (g_vm->hasAnySaves())
|
|
room->selectFrame("restoregame", kButtonZ, 0);
|
|
else
|
|
room->disableHotzone("restoregame");
|
|
}
|
|
|
|
bool gameInProgress() {
|
|
Persistent *persistent = g_vm->getPersistent();
|
|
return persistent->_currentRoomId != kOlympusRoom && persistent->_currentRoomId != kIntroRoom;
|
|
}
|
|
|
|
void loadMenuUser() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
Common::HashMap<Common::U32String, bool> userset;
|
|
|
|
loadSaves();
|
|
_currentMenu = kLoadUserMenu;
|
|
_userNames.clear();
|
|
for (unsigned i = 0; i < _saves.size(); i++)
|
|
if (!userset[_saves[i]._heroName]) {
|
|
userset[_saves[i]._heroName] = true;
|
|
_userNames.push_back(_saves[i]._heroName);
|
|
}
|
|
Common::sort(_userNames.begin(), _userNames.end());
|
|
|
|
room->loadHotZones("OPRest1.HOT");
|
|
room->addStaticLayer("black", kBackgroundZ);
|
|
room->disableHeroBelt();
|
|
room->selectFrame("scroll", kScrollZ, 0);
|
|
room->selectFrame("restorescroll", kScrollBarZ, 0);
|
|
|
|
room->selectFrame("cancel", kButtonZ, 0);
|
|
room->selectFrame("delete", kButtonZ, 0);
|
|
room->selectFrame("ok", kButtonZ, 0);
|
|
room->selectFrame("choosename", kTitleZ, 0);
|
|
if (_userNames.size() > 6)
|
|
room->selectFrame("arrows", kArrowsZ, 0);
|
|
else {
|
|
room->disableHotzone("arrowup");
|
|
room->disableHotzone("arrowdown");
|
|
}
|
|
_showPos = 0;
|
|
_selectedSave = -1;
|
|
renderUserNames();
|
|
}
|
|
|
|
void renderUserNames() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
bool selectedIsShown = false;
|
|
for (int i = 0; i < 6 && _showPos + i < (int) _userNames.size(); i++) {
|
|
Common::U32String name = _userNames[_showPos + i];
|
|
if (name == "")
|
|
name = "No name";
|
|
room->renderString("largeascii", name,
|
|
Common::Point(150, 134 + 36 * i), 4000, 0,
|
|
Common::String::format("username%d", i));
|
|
if (_showPos + i == _selectedSave) {
|
|
selectedIsShown = true;
|
|
room->selectFrame("thumb", kThumbZ, 0, Common::Point(109, 134 + 36 * i));
|
|
}
|
|
}
|
|
|
|
for (unsigned i = 0; i < 6; i++) {
|
|
room->setHotzoneEnabled(Common::String::format("nameslot%d", i), _showPos + i < _userNames.size());
|
|
}
|
|
|
|
_isLast = _showPos + 3 >= (int) _userNames.size();
|
|
|
|
room->setHotzoneEnabled("delete", selectedIsShown);
|
|
room->setHotzoneEnabled("ok", selectedIsShown);
|
|
room->setHotzoneEnabled("arrowdown", !_isLast);
|
|
room->setHotzoneEnabled("arrowup", _showPos > 0);
|
|
}
|
|
|
|
void loadMenuSlot() {
|
|
loadSaves();
|
|
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
|
|
loadFilteredSaves(_chosenName);
|
|
|
|
_currentMenu = kLoadSlotMenu;
|
|
room->loadHotZones("OPRest2.HOT");
|
|
room->addStaticLayer("black", kBackgroundZ);
|
|
room->disableHeroBelt();
|
|
room->selectFrame("scroll", kScrollZ, 0);
|
|
room->selectFrame("restore2scroll", kScrollBarZ, 0);
|
|
room->renderStringCentered("largeascii", _chosenName, Common::Point(320, 77), 4000);
|
|
if (_filteredSaves.size() > 6)
|
|
room->selectFrame("arrows", kArrowsZ, 0);
|
|
else {
|
|
room->disableHotzone("arrowup");
|
|
room->disableHotzone("arrowdown");
|
|
}
|
|
|
|
room->selectFrame("cancel", kButtonZ, 0);
|
|
room->selectFrame("restore", kButtonZ, 0);
|
|
room->selectFrame("delete", kButtonZ, 0);
|
|
room->disableHotzone("delete");
|
|
_selectedSave = -1;
|
|
_showPos = 0;
|
|
|
|
renderLoadSlots();
|
|
}
|
|
|
|
void alertMenu(AlertType alertType) {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
room->loadHotZones("OPAlert.HOT");
|
|
room->addStaticLayer("black", kBackgroundZ);
|
|
room->disableHeroBelt();
|
|
// Original uses other Z values but it generates the same
|
|
// resulting image and we can keep button code consistent
|
|
room->selectFrame("alert", 4000, 0);
|
|
switch (alertType) {
|
|
case kAlertSaveBeforeLoad:
|
|
case kAlertSaveBeforeExit:
|
|
case kAlertSaveBeforeNew:
|
|
room->selectFrame("exit", 3800, 0);
|
|
break;
|
|
case kDeleteFromLoad:
|
|
case kDeleteFromSave:
|
|
room->selectFrame("deletegame", 3800, 0);
|
|
break;
|
|
case kDeleteUser:
|
|
room->selectFrame("deletename", 3800, 0);
|
|
break;
|
|
}
|
|
room->selectFrame("yes", kButtonZ, 0);
|
|
room->selectFrame("no", kButtonZ, 0);
|
|
_alertType = alertType;
|
|
}
|
|
|
|
void saveMenu(SaveMenuVariant saveVariant) {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
Persistent *persistent = g_vm->getPersistent();
|
|
|
|
loadFilteredSaves(persistent->_heroName);
|
|
|
|
_currentMenu = kSaveMenu;
|
|
_saveVariant = saveVariant;
|
|
room->loadHotZones("OPSave.HOT");
|
|
room->addStaticLayer("black", kBackgroundZ);
|
|
room->disableHeroBelt();
|
|
room->selectFrame("scroll", kScrollZ, 0);
|
|
room->selectFrame("savescroll", kScrollBarZ, 0);
|
|
room->renderStringCentered("largeascii", persistent->_heroName, Common::Point(320, 77), 4000);
|
|
if (_filteredSaves.size() > 3)
|
|
room->selectFrame("arrows", kArrowsZ, 0);
|
|
else {
|
|
room->disableHotzone("arrowup");
|
|
room->disableHotzone("arrowdown");
|
|
}
|
|
|
|
room->selectFrame("cancel", kButtonZ, 0);
|
|
room->selectFrame("save", kButtonZ, 0);
|
|
room->selectFrame("delete", kButtonZ, 0);
|
|
room->disableHotzone("delete");
|
|
_selectedSave = -1;
|
|
_showPos = 0;
|
|
|
|
_typedSlotName = "";
|
|
|
|
room->selectFrame("saveas", kTitleZ, 0);
|
|
room->selectFrame(LayerId("thumbnails", 0, "save"), 5000,
|
|
persistent->_currentRoomId - 1, Common::Point(184, 204));
|
|
renderSaveSlots();
|
|
}
|
|
|
|
void renderSaveSlots() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
bool selectedIsShown = false;
|
|
for (int i = 0; i < 3; i++) {
|
|
Common::Point base = Common::Point(310, 128+76*i);
|
|
bool isValid = _showPos + i < (int)_filteredSaves.size();
|
|
room->hideString("smallascii", 30, Common::String::format("saveslots%d", i));
|
|
room->setHotzoneEnabled(Common::String::format("saveslot%d", i), isValid);
|
|
if (isValid) {
|
|
room->selectFrame(LayerId("thumbnails", i, "right"), 5000,
|
|
_filteredSaves[_showPos + i]._room - 1, base + Common::Point(31, 0));
|
|
room->renderString("smallascii", _filteredSaves[_showPos + i]._slotName,
|
|
base + Common::Point(31, 62), 5000,
|
|
0, Common::String::format("saveslots%d", i));
|
|
if (_showPos + i == _selectedSave) {
|
|
// TODO: original uses 300 - thumbWidth, I ust hardcode thumbWidth
|
|
room->selectFrame("thumb", kThumbZ, 0, base - Common::Point(31+10, 0));
|
|
selectedIsShown = true;
|
|
}
|
|
} else {
|
|
room->stopAnim(LayerId("thumbnails", i, "right"));
|
|
}
|
|
}
|
|
|
|
_isLast = _showPos + 3 >= (int) _filteredSaves.size();
|
|
|
|
room->setHotzoneEnabled("delete", selectedIsShown);
|
|
room->setHotzoneEnabled("arrowdown", !_isLast);
|
|
room->setHotzoneEnabled("arrowup", _showPos > 0);
|
|
}
|
|
|
|
void renderLoadSlots() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
bool selectedIsShown = false;
|
|
for (int i = 0; i < 6; i++) {
|
|
bool isValid = _showPos + i < (int) _filteredSaves.size();
|
|
room->hideString("smallascii", 30, Common::String::format("loadslots%d", i));
|
|
room->setHotzoneEnabled(Common::String::format("restoreslot%d", i), isValid);
|
|
if (isValid) {
|
|
Common::Point base = Common::Point(153 + 157 * (i % 2), 128 + 76 * (i / 2));
|
|
room->selectFrame(LayerId("thumbnails", i, "right"), 5000,
|
|
_filteredSaves[_showPos + i]._room - 1, base + Common::Point(31, 0));
|
|
room->renderString("smallascii", _filteredSaves[_showPos + i]._slotName,
|
|
base + Common::Point(31, 62), 5000,
|
|
0, Common::String::format("loadslots%d", i));
|
|
if (_showPos + i == _selectedSave) {
|
|
// TODO: original uses 300 - thumbWidth, I ust hardcode thumbWidth
|
|
room->selectFrame("thumb", kThumbZ, 0, base);
|
|
selectedIsShown = true;
|
|
}
|
|
} else {
|
|
room->stopAnim(LayerId("thumbnails", i, "right"));
|
|
}
|
|
}
|
|
|
|
_isLast = _showPos + 6 >= (int) _filteredSaves.size();
|
|
|
|
room->setHotzoneEnabled("arrowdown", !_isLast);
|
|
room->setHotzoneEnabled("arrowup", _showPos > 0);
|
|
room->setHotzoneEnabled("restore", selectedIsShown);
|
|
room->setHotzoneEnabled("delete", selectedIsShown);
|
|
}
|
|
|
|
void loadSaves() {
|
|
if (_savesLoaded)
|
|
return;
|
|
_saves = g_vm->getHadeschSavesList();
|
|
}
|
|
|
|
void loadFilteredSaves(const Common::U32String &heroname) {
|
|
loadSaves();
|
|
_filteredSaves.clear();
|
|
for (unsigned i = 0; i < _saves.size(); i++)
|
|
if (_saves[i]._heroName == heroname)
|
|
_filteredSaves.push_back(_saves[i]);
|
|
}
|
|
|
|
enum {
|
|
kGameMenu,
|
|
kSaveMenu,
|
|
kLoadUserMenu,
|
|
kLoadSlotMenu
|
|
} _currentMenu;
|
|
SaveMenuVariant _saveVariant;
|
|
AlertType _alertType;
|
|
|
|
Common::Array<HadeschSaveDescriptor> _saves;
|
|
Common::Array<HadeschSaveDescriptor> _filteredSaves;
|
|
Common::Array<Common::U32String> _userNames;
|
|
Common::U32String _chosenName;
|
|
Common::U32String _typedSlotName;
|
|
int _showPos;
|
|
int _selectedSave;
|
|
bool _savesLoaded;
|
|
bool _isLast;
|
|
};
|
|
|
|
Common::SharedPtr<Hadesch::Handler> makeOptionsHandler() {
|
|
return Common::SharedPtr<Hadesch::Handler>(new OptionsHandler());
|
|
}
|
|
|
|
}
|