mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-19 08:25:35 +00:00
HPL1: use standard naming scheme for saves
This commit is contained in:
parent
fa822ef0c2
commit
630623c997
@ -195,22 +195,23 @@ bool cSerializeClass::SaveToFile(iSerializable *apData, const tWString &asFile,
|
||||
|
||||
glTabs = 0;
|
||||
// FIXME: string types
|
||||
Common::String filename(cString::To8Char(asFile).c_str());
|
||||
Common::String saveDesc(cString::To8Char(asFile).c_str());
|
||||
Common::String filename(Hpl1::g_engine->createSaveFile(saveDesc));
|
||||
TiXmlDocument pXmlDoc;
|
||||
// Create root
|
||||
TiXmlElement XmlRoot(asRoot.c_str());
|
||||
TiXmlElement *pRootElem = static_cast<TiXmlElement *>(pXmlDoc.InsertEndChild(XmlRoot));
|
||||
Common::ScopedPtr<Common::OutSaveFile> savefile(g_engine->getSaveFileManager()->openForSaving(filename));
|
||||
if (!savefile) {
|
||||
Hpl1::logError(Hpl1::kDebugSaves, "could't open file %s for saving\n", asFile.c_str());
|
||||
Hpl1::logError(Hpl1::kDebugSaves, "could't open file %s for saving\n", filename.c_str());
|
||||
return false;
|
||||
}
|
||||
SaveToElement(apData, "", pRootElem);
|
||||
if (!pXmlDoc.SaveFile(*savefile)) {
|
||||
Hpl1::logError(Hpl1::kDebugSaves, "couldn't save to file '%s'\n", asFile.c_str());
|
||||
Hpl1::logError(Hpl1::kDebugSaves, "couldn't save to file '%s'\n", filename.c_str());
|
||||
return false;
|
||||
}
|
||||
g_engine->getMetaEngine()->appendExtendedSave(savefile.get(), g_engine->getTotalPlayTime(), "", filename.contains("auto"));
|
||||
g_engine->getMetaEngine()->appendExtendedSave(savefile.get(), g_engine->getTotalPlayTime(), saveDesc, filename.contains("auto"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -279,15 +280,15 @@ bool cSerializeClass::LoadFromFile(iSerializable *apData, const tWString &asFile
|
||||
// Load document
|
||||
TiXmlDocument pXmlDoc;
|
||||
// FIXME: string types
|
||||
Common::String filename(cString::To8Char(asFile).c_str());
|
||||
Common::String filename(Hpl1::g_engine->mapInternalSaveToFile(cString::To8Char(asFile).c_str()));
|
||||
Common::ScopedPtr<Common::InSaveFile> saveFile(g_engine->getSaveFileManager()->openForLoading(filename));
|
||||
if (!saveFile) {
|
||||
Hpl1::logError(Hpl1::kDebugSaves | Hpl1::kDebugResourceLoading, "save file %s could not be opened\n", filename.c_str());
|
||||
return false;
|
||||
}
|
||||
ExtendedSavegameHeader header;
|
||||
if (MetaEngine::readSavegameHeader(saveFile.get(), &header)) {
|
||||
Hpl1::logError(Hpl1::kDebugResourceLoading | Hpl1::kDebugSaves, "couldn't load heaer from save file %s\n", filename.c_str());
|
||||
if (!MetaEngine::readSavegameHeader(saveFile.get(), &header)) {
|
||||
Hpl1::logError(Hpl1::kDebugResourceLoading | Hpl1::kDebugSaves, "couldn't load header from save file %s\n", filename.c_str());
|
||||
return false;
|
||||
}
|
||||
g_engine->setTotalPlayTime(header.playtime);
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "graphics/palette.h"
|
||||
#include "hpl1/console.h"
|
||||
#include "hpl1/detection.h"
|
||||
#include "hpl1/debug.h"
|
||||
|
||||
extern int hplMain(const hpl::tString &asCommandLine);
|
||||
|
||||
@ -54,11 +55,58 @@ Common::String Hpl1Engine::getGameId() const {
|
||||
return _gameDescription->gameId;
|
||||
}
|
||||
|
||||
static void initSaves(const char *target, Common::BitArray &slots, Common::HashMap<Common::String, int> &savemap) {
|
||||
slots.set_size(g_engine->getMetaEngine()->getMaximumSaveSlot());
|
||||
SaveStateList saves = g_engine->getMetaEngine()->listSaves(target);
|
||||
for (auto &s : saves) {
|
||||
savemap.setVal(s.getDescription(), s.getSaveSlot());
|
||||
slots.set(s.getSaveSlot());
|
||||
}
|
||||
}
|
||||
|
||||
Common::Error Hpl1Engine::run() {
|
||||
initSaves(_targetName.c_str(), _saveSlots, _internalSaves);
|
||||
hplMain("");
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
static int freeSaveSlot(Common::BitArray &slots, const int size) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (!slots.get(i))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Common::String Hpl1Engine::createSaveFile(const Common::String &internalName) {
|
||||
const int freeSlot = freeSaveSlot(_saveSlots, getMetaEngine()->getMaximumSaveSlot());
|
||||
if (freeSlot == -1) {
|
||||
warning("game out of save slots");
|
||||
return "";
|
||||
}
|
||||
_saveSlots.set(freeSlot);
|
||||
_internalSaves.setVal(internalName, freeSlot);
|
||||
return getSaveStateName(freeSlot);
|
||||
}
|
||||
|
||||
Common::String Hpl1Engine::mapInternalSaveToFile(const Common::String &internalName) {
|
||||
const int slot = _internalSaves.getValOrDefault(internalName, -1);
|
||||
if (slot == -1) {
|
||||
logError(Hpl1::kDebugLevelError, "trying to map invalid save name: %s\n", internalName.c_str());
|
||||
return "";
|
||||
}
|
||||
return getSaveStateName(slot);
|
||||
}
|
||||
|
||||
Common::StringArray Hpl1Engine::listInternalSaves(const Common::String &pattern) {
|
||||
Common::StringArray saves;
|
||||
for(auto &kv : _internalSaves) {
|
||||
if (kv._key.matchString(pattern))
|
||||
saves.push_back(kv._key);
|
||||
}
|
||||
return saves;
|
||||
}
|
||||
|
||||
Common::Error Hpl1Engine::syncGame(Common::Serializer &s) {
|
||||
// The Serializer has methods isLoading() and isSaving()
|
||||
// if you need to specific steps; for example setting
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "engines/engine.h"
|
||||
#include "engines/savestate.h"
|
||||
#include "graphics/screen.h"
|
||||
#include "common/bitarray.h"
|
||||
|
||||
#include "hpl1/detection.h"
|
||||
|
||||
@ -44,6 +45,8 @@ class Hpl1Engine : public Engine {
|
||||
private:
|
||||
const ADGameDescription *_gameDescription;
|
||||
Common::RandomSource _randomSource;
|
||||
Common::HashMap<Common::String, int> _internalSaves;
|
||||
Common::BitArray _saveSlots;
|
||||
|
||||
protected:
|
||||
// Engine APIs
|
||||
@ -84,6 +87,12 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
Common::String createSaveFile(const Common::String &internalName);
|
||||
|
||||
Common::String mapInternalSaveToFile(const Common::String &internalName);
|
||||
|
||||
Common::StringArray listInternalSaves(const Common::String &pattern);
|
||||
|
||||
/**
|
||||
* Uses a serializer to allow implementing savegame
|
||||
* loading and saving using a single method
|
||||
|
@ -59,26 +59,6 @@ void Hpl1MetaEngine::getSavegameThumbnail(Graphics::Surface &thumbnail) {
|
||||
scaledScreen->free();
|
||||
}
|
||||
|
||||
static Common::U32String formatSave(const Common::String &filename) {
|
||||
const int begin = filename.findFirstOf('.') + 1;
|
||||
const int len = filename.findLastOf('_') - begin;
|
||||
Common::String name = filename.substr(begin, len);
|
||||
Common::replace(name.begin(), name.end(), '.', ':');
|
||||
Common::replace(name.begin(), name.end(), '_', ' ');
|
||||
return name;
|
||||
}
|
||||
|
||||
SaveStateList Hpl1MetaEngine::listSaves(const char *target) const {
|
||||
SaveStateList saveList;
|
||||
Common::StringArray filenames = g_system->getSavefileManager()->listSavefiles("hpl1-po-????.*");
|
||||
int i = 0;
|
||||
for (auto &save : filenames) {
|
||||
if (!save.contains("favourite"))
|
||||
saveList.push_back(SaveStateDescriptor(this, ++i, formatSave(save)));
|
||||
}
|
||||
return saveList;
|
||||
}
|
||||
|
||||
Common::Action *createKeyBoardAction(const char *id, const Common::U32String &desc, const char *defaultMap, const Common::KeyState &key) {
|
||||
Common::Action *act = new Common::Action(id, desc);
|
||||
act->setKeyEvent(key);
|
||||
|
@ -37,8 +37,6 @@ public:
|
||||
*/
|
||||
bool hasFeature(MetaEngineFeature f) const override;
|
||||
|
||||
SaveStateList listSaves(const char *target) const override;
|
||||
|
||||
void getSavegameThumbnail(Graphics::Surface &thumbnail) override;
|
||||
|
||||
Common::Array<Common::Keymap *> initKeymaps(const char *target) const override;
|
||||
|
@ -104,7 +104,7 @@ void cDeathMenuButton::OnMouseOver(bool abOver) {
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cDeathMenuButton_Continue::OnMouseDown() {
|
||||
tWString save = mpInit->mpSaveHandler->GetLatest(_W("hpl1-po-????.*.sav"));
|
||||
tWString save = mpInit->mpSaveHandler->GetLatest(_W("????:*"));
|
||||
if (save != _W(""))
|
||||
mpInit->mpSaveHandler->LoadGameFromFile(save);
|
||||
}
|
||||
@ -301,7 +301,7 @@ void cDeathMenu::SetActive(bool abX) {
|
||||
STLDeleteAll(mlstButtons);
|
||||
|
||||
// Continue
|
||||
tWString latestSave = mpInit->mpSaveHandler->GetLatest(_W("hpl1-po-????.*.sav"));
|
||||
tWString latestSave = mpInit->mpSaveHandler->GetLatest(_W("????:*"));
|
||||
if (latestSave != _W("")) {
|
||||
mlstButtons.push_back(hplNew(cDeathMenuButton_Continue, (mpInit, cVector2f(400, 290), kTranslate("DeathMenu", "Continue"))));
|
||||
}
|
||||
|
@ -634,7 +634,7 @@ void cMainMenuWidget_Continue::OnMouseDown(eMButton aButton) {
|
||||
|
||||
mpInit->mpMainMenu->SetActive(false);
|
||||
|
||||
tWString latestSave = mpInit->mpSaveHandler->GetLatest(_W("hpl1-po-????.*.sav"));
|
||||
tWString latestSave = mpInit->mpSaveHandler->GetLatest(_W("????:*"));
|
||||
if (latestSave != _W(""))
|
||||
mpInit->mpSaveHandler->LoadGameFromFile(latestSave);
|
||||
}
|
||||
@ -784,9 +784,11 @@ public:
|
||||
return;
|
||||
|
||||
tWString originalName = gvSaveGameFileVec[mlNum][lSelected];
|
||||
tWString newName = _W("save-favorite.") + cString::SubW(originalName, originalName.find_first_of('.') + 1);
|
||||
tWString newName = _W("favorite-") + cString::SubW(originalName, originalName.find_first_of('.') + 1);
|
||||
Hpl1::logInfo(Hpl1::kDebugSaves, "adding save %s to favourites\n", cString::To8Char(newName).c_str());
|
||||
g_engine->getSaveFileManager()->copySavefile(cString::To8Char(originalName).c_str(), cString::To8Char(newName).c_str());
|
||||
Common::String originalFile(Hpl1::g_engine->mapInternalSaveToFile(cString::To8Char(originalName).c_str()));
|
||||
Common::String newFile(Hpl1::g_engine->createSaveFile(cString::To8Char(newName).c_str()));
|
||||
g_engine->getSaveFileManager()->copySavefile(originalFile, newFile);
|
||||
mpInit->mpMainMenu->UpdateWidgets();
|
||||
}
|
||||
|
||||
@ -2480,7 +2482,7 @@ void cMainMenu::CreateWidgets() {
|
||||
AddWidgetToState(eMainMenuState_Start, hplNew(cMainMenuWidget_Resume, (mpInit, vPos, kTranslate("MainMenu", "Resume"))));
|
||||
vPos.y += 60;
|
||||
} else {
|
||||
tWString latestSave = mpInit->mpSaveHandler->GetLatest(_W("hpl1-po-????.*.sav"));
|
||||
tWString latestSave = mpInit->mpSaveHandler->GetLatest(_W("????:*"));
|
||||
|
||||
if (latestSave != _W("")) {
|
||||
AddWidgetToState(eMainMenuState_Start, hplNew(cMainMenuWidget_MainButton, (mpInit, vPos, kTranslate("MainMenu", "Continue"), eMainMenuState_Continue)));
|
||||
@ -2577,18 +2579,18 @@ void cMainMenu::CreateWidgets() {
|
||||
vPos.y += 46 + 30;
|
||||
vPos.x += 15;
|
||||
|
||||
tWString sDir = _W("hpl1-po-spot");
|
||||
tWString sDir = _W("spot:");
|
||||
if (i == 1)
|
||||
sDir = _W("hpl1-po-auto");
|
||||
sDir = _W("auto:");
|
||||
else if (i == 2)
|
||||
sDir = _W("hpl1-po-favorite");
|
||||
sDir = _W("favorite:");
|
||||
|
||||
gpSaveGameList[i] = hplNew(cMainMenuWidget_SaveGameList, (
|
||||
mpInit, vPos, cVector2f(355, 170), 15, sDir, (int)i));
|
||||
AddWidgetToState(state, gpSaveGameList[i]);
|
||||
|
||||
tTempFileAndDataSet setTempFiles;
|
||||
Common::StringArray saves = g_engine->getSaveFileManager()->listSavefiles( cString::To8Char(sDir).c_str() + Common::String("*.sav"));
|
||||
Common::StringArray saves = Hpl1::g_engine->listInternalSaves(cString::To8Char(sDir).c_str() + Common::String("*"));
|
||||
for (auto &s : saves) {
|
||||
tWString sFile = cString::To16Char(s.c_str());
|
||||
cDate date = cSaveHandler::parseDate(s);
|
||||
@ -2605,13 +2607,7 @@ void cMainMenu::CreateWidgets() {
|
||||
|
||||
gvSaveGameFileVec[i].push_back(sFile);
|
||||
|
||||
sFile = cString::SetFileExtW(sFile, _W(""));
|
||||
sFile = cString::SubW(sFile, sFile.find_first_of(_W(".")) + 1);
|
||||
sFile = cString::SubW(sFile, 0, (int)sFile.length() - 3);
|
||||
sFile = cString::ReplaceCharToW(sFile, _W("_"), _W(" "));
|
||||
sFile = cString::ReplaceCharToW(sFile, _W("."), _W(":"));
|
||||
|
||||
// TODO: PROBLEM!!!
|
||||
sFile = cString::SubW(sFile, sFile.find_first_of(_W(":")) + 1);
|
||||
gpSaveGameList[i]->AddEntry(sFile);
|
||||
// gpSaveGameList[i]->AddEntry(sFile);
|
||||
}
|
||||
|
@ -610,7 +610,7 @@ void cSaveHandler::AutoSave(const tWString &asDir, int alMaxSaves) {
|
||||
sMapName = cString::ReplaceCharToW(sMapName, _W(":"), _W(" "));
|
||||
cDate date = mpInit->mpGame->GetSystem()->GetLowLevel()->getDate();
|
||||
wchar_t sTemp[512];
|
||||
swprintf(sTemp, 512, _W("hpl1-po-%ls.%ls %d-%02d-%02d_%02d.%02d.%02d_%02d.sav"),
|
||||
swprintf(sTemp, 512, _W("%ls: %ls %d-%02d-%02d %02d:%02d:%02d"),
|
||||
asDir.c_str(),
|
||||
sMapName.c_str(),
|
||||
date.year,
|
||||
@ -618,8 +618,7 @@ void cSaveHandler::AutoSave(const tWString &asDir, int alMaxSaves) {
|
||||
date.month_day,
|
||||
date.hours,
|
||||
date.minutes,
|
||||
date.seconds,
|
||||
cMath::RandRectl(0, 99));
|
||||
date.seconds);
|
||||
tWString sFile = sTemp;
|
||||
SaveGameToFile(sFile);
|
||||
|
||||
@ -629,7 +628,7 @@ void cSaveHandler::AutoSave(const tWString &asDir, int alMaxSaves) {
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cSaveHandler::AutoLoad(const tWString &asDir) {
|
||||
tWString latestSave = GetLatest(_W("hpl1-po-") + asDir + _W(".*.sav"));
|
||||
tWString latestSave = GetLatest( asDir + _W(":*"));
|
||||
LoadGameFromFile(latestSave);
|
||||
mpInit->mpGame->ResetLogicTimer();
|
||||
}
|
||||
@ -700,14 +699,15 @@ void cSaveHandler::DeleteOldestIfMax(const tWString &asDir, const tWString &asMa
|
||||
|
||||
cDate cSaveHandler::parseDate(const Common::String &saveFile) {
|
||||
cDate date;
|
||||
Common::String strDate = saveFile.substr(saveFile.findLastOf(" "));
|
||||
sscanf(strDate.c_str(), "%d-%d-%d_%d.%d.%d.sav", &date.year, &date.month, &date.month_day, &date.hours, &date.minutes, &date.seconds);
|
||||
auto firstDigit = Common::find_if(saveFile.begin(), saveFile.end(), Common::isDigit);
|
||||
Common::String strDate = saveFile.substr(Common::distance(saveFile.begin(), firstDigit));
|
||||
sscanf(strDate.c_str(), "%d-%d-%d %d:%d:%d", &date.year, &date.month, &date.month_day, &date.hours, &date.minutes, &date.seconds);
|
||||
return date;
|
||||
}
|
||||
|
||||
tWString cSaveHandler::GetLatest(const tWString &asMask) {
|
||||
// FIXME: string types
|
||||
Common::StringArray saves = g_engine->getSaveFileManager()->listSavefiles(cString::To8Char(asMask).c_str());
|
||||
Common::StringArray saves = Hpl1::g_engine->listInternalSaves(cString::To8Char(asMask).c_str());
|
||||
if (saves.empty())
|
||||
return _W("");
|
||||
cDate latestDate = parseDate(saves.front());
|
||||
|
Loading…
x
Reference in New Issue
Block a user