aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm/saveload.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/scumm/saveload.cpp')
-rw-r--r--engines/scumm/saveload.cpp125
1 files changed, 67 insertions, 58 deletions
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index f9e4eb415c..267e06dafd 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -46,6 +46,8 @@
#include "sound/audiocd.h"
#include "sound/mixer.h"
+#include "graphics/thumbnail.h"
+
namespace Scumm {
struct SaveGameHeader {
@@ -71,6 +73,8 @@ struct SaveInfoSection {
#define INFOSECTION_VERSION 2
+#pragma mark -
+
void ScummEngine::requestSave(int slot, const char *name, bool temporary) {
_saveLoadSlot = slot;
_saveTemporaryState = temporary;
@@ -99,34 +103,36 @@ static bool saveSaveGameHeader(Common::OutSaveFile *out, SaveGameHeader &hdr) {
}
bool ScummEngine::saveState(int slot, bool compat) {
- char filename[256];
+ Common::String filename;
Common::OutSaveFile *out;
SaveGameHeader hdr;
if (_saveLoadSlot == 255) {
// Allow custom filenames for save game system in HE Games
- memcpy(filename, _saveLoadFileName, sizeof(_saveLoadFileName));
+ filename = _saveLoadFileName;
} else {
- makeSavegameName(filename, slot, compat);
+ filename = makeSavegameName(slot, compat);
}
- if (!(out = _saveFileMan->openForSaving(filename)))
+ if (!(out = _saveFileMan->openForSaving(filename.c_str())))
return false;
memcpy(hdr.name, _saveLoadName, sizeof(hdr.name));
saveSaveGameHeader(out, hdr);
- saveThumbnail(out);
+#if !defined(__DS__)
+ Graphics::saveThumbnail(*out);
+#endif
saveInfos(out);
Serializer ser(0, out, CURRENT_VER);
saveOrLoad(&ser);
out->finalize();
- if (out->ioFailed()) {
+ if (out->err()) {
delete out;
- debug(1, "State save as '%s' FAILED", filename);
+ debug(1, "State save as '%s' FAILED", filename.c_str());
return false;
}
delete out;
- debug(1, "State saved as '%s'", filename);
+ debug(1, "State saved as '%s'", filename.c_str());
return true;
}
@@ -135,11 +141,11 @@ static bool loadSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &h
hdr.size = in->readUint32LE();
hdr.ver = in->readUint32LE();
in->read(hdr.name, sizeof(hdr.name));
- return !in->ioFailed() && hdr.type == MKID_BE('SCVM');
+ return !in->err() && hdr.type == MKID_BE('SCVM');
}
bool ScummEngine::loadState(int slot, bool compat) {
- char filename[256];
+ Common::String filename;
Common::SeekableReadStream *in;
int i, j;
SaveGameHeader hdr;
@@ -147,15 +153,15 @@ bool ScummEngine::loadState(int slot, bool compat) {
if (_saveLoadSlot == 255) {
// Allow custom filenames for save game system in HE Games
- memcpy(filename, _saveLoadFileName, sizeof(_saveLoadFileName));
+ filename = _saveLoadFileName;
} else {
- makeSavegameName(filename, slot, compat);
+ filename = makeSavegameName(slot, compat);
}
- if (!(in = _saveFileMan->openForLoading(filename)))
+ if (!(in = _saveFileMan->openForLoading(filename.c_str())))
return false;
if (!loadSaveGameHeader(in, hdr)) {
- warning("Invalid savegame '%s'", filename);
+ warning("Invalid savegame '%s'", filename.c_str());
delete in;
return false;
}
@@ -171,30 +177,30 @@ bool ScummEngine::loadState(int slot, bool compat) {
// to work around a bug from the stone age (see below for more
// information).
if (hdr.ver < VER(7) || hdr.ver > CURRENT_VER) {
- warning("Invalid version of '%s'", filename);
+ warning("Invalid version of '%s'", filename.c_str());
delete in;
return false;
}
// We (deliberately) broke HE savegame compatibility at some point.
if (hdr.ver < VER(50) && _game.heversion >= 71) {
- warning("Unsupported version of '%s'", filename);
+ warning("Unsupported version of '%s'", filename.c_str());
delete in;
return false;
}
// Since version 52 a thumbnail is saved directly after the header.
if (hdr.ver >= VER(52)) {
- uint32 type = in->readUint32BE();
- // Check for the THMB header. Also, work around a bug which caused
- // the chunk type (incorrectly) to be written in LE on LE machines.
- if (! (type == MKID_BE('THMB') || (hdr.ver < VER(55) && type == MKID_BE('BMHT')))){
- warning("Can not load thumbnail");
- delete in;
- return false;
+ // Prior to version 75 we always required an thumbnail to be present
+ if (hdr.ver <= VER(74)) {
+ if (!Graphics::checkThumbnailHeader(*in)) {
+ warning("Can not load thumbnail");
+ delete in;
+ return false;
+ }
}
- uint32 size = in->readUint32BE();
- in->skip(size - 8);
+
+ Graphics::skipThumbnailHeader(*in);
}
// Since version 56 we save additional information about the creation of
@@ -275,7 +281,7 @@ bool ScummEngine::loadState(int slot, bool compat) {
delete in;
// Update volume settings
- updateSoundSettings();
+ syncSoundSettings();
// Init NES costume data
if (_game.platform == Common::kPlatformNES) {
@@ -385,7 +391,7 @@ bool ScummEngine::loadState(int slot, bool compat) {
if (VAR_VOICE_MODE != 0xFF)
VAR(VAR_VOICE_MODE) = ConfMan.getBool("subtitles");
- debug(1, "State loaded from '%s'", filename);
+ debug(1, "State loaded from '%s'", filename.c_str());
_sound->pauseSounds(false);
@@ -401,23 +407,24 @@ bool ScummEngine::loadState(int slot, bool compat) {
return true;
}
-void ScummEngine::makeSavegameName(char *out, int slot, bool temporary) {
- sprintf(out, "%s.%c%.2d", _targetName.c_str(), temporary ? 'c' : 's', slot);
+Common::String ScummEngine::makeSavegameName(const Common::String &target, int slot, bool temporary) {
+ char extension[6];
+ snprintf(extension, sizeof(extension), ".%c%02d", temporary ? 'c' : 's', slot);
+ return (target + extension);
}
void ScummEngine::listSavegames(bool *marks, int num) {
assert(marks);
- char prefix[256];
char slot[3];
int slotNum;
Common::StringList files;
- makeSavegameName(prefix, 99, false);
- prefix[strlen(prefix)-2] = '*';
- prefix[strlen(prefix)-1] = 0;
+ Common::String prefix = makeSavegameName(99, false);
+ prefix.setChar('*', prefix.size()-2);
+ prefix.setChar(0, prefix.size()-1);
memset(marks, false, num * sizeof(bool)); //assume no savegames for this title
- files = _saveFileMan->listSavefiles(prefix);
+ files = _saveFileMan->listSavefiles(prefix.c_str());
for (Common::StringList::const_iterator file = files.begin(); file != files.end(); ++file) {
//Obtain the last 2 digits of the filename, since they correspond to the save slot
@@ -436,11 +443,10 @@ bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion
bool ScummEngine::getSavegameName(int slot, Common::String &desc) {
Common::InSaveFile *in = 0;
bool result = false;
- char filename[256];
desc.clear();
- makeSavegameName(filename, slot, false);
- in = _saveFileMan->openForLoading(filename);
+ Common::String filename = makeSavegameName(slot, false);
+ in = _saveFileMan->openForLoading(filename.c_str());
if (in) {
result = Scumm::getSavegameName(in, desc, _game.heversion);
delete in;
@@ -474,13 +480,15 @@ bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion
return true;
}
-Graphics::Surface *ScummEngine::loadThumbnailFromSlot(int slot) {
- char filename[256];
+Graphics::Surface *ScummEngine::loadThumbnailFromSlot(const char *target, int slot) {
Common::SeekableReadStream *in;
SaveGameHeader hdr;
- makeSavegameName(filename, slot, false);
- if (!(in = _saveFileMan->openForLoading(filename))) {
+ if (slot < 0)
+ return 0;
+
+ Common::String filename = ScummEngine::makeSavegameName(target, slot, false);
+ if (!(in = g_system->getSavefileManager()->openForLoading(filename.c_str()))) {
return 0;
}
@@ -496,19 +504,29 @@ Graphics::Surface *ScummEngine::loadThumbnailFromSlot(int slot) {
return 0;
}
- Graphics::Surface *thumb = loadThumbnail(in);
+ Graphics::Surface *thumb = 0;
+ if (Graphics::checkThumbnailHeader(*in)) {
+ thumb = new Graphics::Surface();
+ assert(thumb);
+ if (!Graphics::loadThumbnail(*in, *thumb)) {
+ delete thumb;
+ thumb = 0;
+ }
+ }
delete in;
return thumb;
}
-bool ScummEngine::loadInfosFromSlot(int slot, InfoStuff *stuff) {
- char filename[256];
+bool ScummEngine::loadInfosFromSlot(const char *target, int slot, InfoStuff *stuff) {
Common::SeekableReadStream *in;
SaveGameHeader hdr;
- makeSavegameName(filename, slot, false);
- if (!(in = _saveFileMan->openForLoading(filename))) {
+ if (slot < 0)
+ return 0;
+
+ Common::String filename = makeSavegameName(target, slot, false);
+ if (!(in = g_system->getSavefileManager()->openForLoading(filename.c_str()))) {
return false;
}
@@ -524,16 +542,8 @@ bool ScummEngine::loadInfosFromSlot(int slot, InfoStuff *stuff) {
return false;
}
- uint32 type = in->readUint32BE();
-
- // Check for the THMB header. Also, work around a bug which caused
- // the chunk type (incorrectly) to be written in LE on LE machines.
- if (! (type == MKID_BE('THMB') || (hdr.ver < VER(55) && type == MKID_BE('BMHT')))){
- delete in;
+ if (!Graphics::skipThumbnailHeader(*in))
return false;
- }
- uint32 size = in->readUint32BE();
- in->skip(size - 8);
if (!loadInfos(in, stuff)) {
delete in;
@@ -588,14 +598,13 @@ bool ScummEngine::loadInfos(Common::SeekableReadStream *file, InfoStuff *stuff)
stuff->playtime = section.playtime;
// Skip over the remaining (unsupported) data
- if (section.size > SaveInfoSectionSize) {
+ if (section.size > SaveInfoSectionSize)
file->skip(section.size - SaveInfoSectionSize);
- }
return true;
}
-void ScummEngine::saveInfos(Common::OutSaveFile* file) {
+void ScummEngine::saveInfos(Common::WriteStream* file) {
SaveInfoSection section;
section.type = MKID_BE('INFO');
section.version = INFOSECTION_VERSION;