aboutsummaryrefslogtreecommitdiff
path: root/engines/agos/saveload.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/agos/saveload.cpp')
-rw-r--r--engines/agos/saveload.cpp190
1 files changed, 89 insertions, 101 deletions
diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp
index 48671390f0..b968ae645c 100644
--- a/engines/agos/saveload.cpp
+++ b/engines/agos/saveload.cpp
@@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@@ -33,107 +33,82 @@
namespace AGOS {
+
+// FIXME: This code counts savegames, but callers in many cases assume
+// that the return value + 1 indicates an empty slot.
int AGOSEngine::countSaveGames() {
- Common::InSaveFile *f = NULL;
Common::StringArray filenames;
- uint i = 1;
- char slot[4];
+ uint s, numSaveGames = 1;
int slotNum;
bool marks[256];
- char *prefix = genSaveName(998);
- prefix[strlen(prefix)-3] = '*';
- prefix[strlen(prefix)-2] = '\0';
+ // Get the name of (possibly non-existent) savegame slot 998, and replace
+ // the extension by * to get a pattern.
+ Common::String tmp = genSaveName(998);
+ assert(tmp.size() >= 4 && tmp[tmp.size()-4] == '.');
+ Common::String prefix = Common::String(tmp.c_str(), tmp.size()-3) + "*";
+
memset(marks, false, 256 * sizeof(bool)); //assume no savegames for this title
filenames = _saveFileMan->listSavefiles(prefix);
for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file){
//Obtain the last 3 digits of the filename, since they correspond to the save slot
- slot[0] = file->c_str()[file->size()-3];
- slot[1] = file->c_str()[file->size()-2];
- slot[2] = file->c_str()[file->size()-1];
- slot[3] = '\0';
-
- slotNum = atoi(slot);
+ assert(file->size() >= 4);
+ slotNum = atoi(file->c_str() + file->size() - 3);
if (slotNum >= 0 && slotNum < 256)
marks[slotNum] = true; //mark this slot as valid
}
- while (i < 256) {
- if (marks[i] &&
- (f = _saveFileMan->openForLoading(genSaveName(i)))) {
- i++;
- delete f;
- } else
- break;
+ // locate first empty slot
+ for (s = 1; s < 256; s++) {
+ if (marks[s])
+ numSaveGames++;
}
- return i;
+ return numSaveGames;
}
#ifdef ENABLE_AGOS2
-char *AGOSEngine_PuzzlePack::genSaveName(int slot) {
- static char buf[20];
-
+Common::String AGOSEngine_PuzzlePack::genSaveName(int slot) const {
if (getGameId() == GID_DIMP)
- sprintf(buf, "dimp.sav");
+ return "dimp.sav";
else
- sprintf(buf, "swampy.sav");
-
- return buf;
+ return "swampy.sav";
}
-char *AGOSEngine_Feeble::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "feeble.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Feeble::genSaveName(int slot) const {
+ return Common::String::format("feeble.%.3d", slot);
}
#endif
-char *AGOSEngine_Simon2::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "simon2.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Simon2::genSaveName(int slot) const {
+ return Common::String::format("simon2.%.3d", slot);
}
-char *AGOSEngine_Simon1::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "simon1.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Simon1::genSaveName(int slot) const {
+ return Common::String::format("simon1.%.3d", slot);
}
-char *AGOSEngine_Waxworks::genSaveName(int slot) {
- static char buf[20];
-
+Common::String AGOSEngine_Waxworks::genSaveName(int slot) const {
if (getPlatform() == Common::kPlatformDOS)
- sprintf(buf, "waxworks-pc.%.3d", slot);
+ return Common::String::format("waxworks-pc.%.3d", slot);
else
- sprintf(buf, "waxworks.%.3d", slot);
-
- return buf;
+ return Common::String::format("waxworks.%.3d", slot);
}
-char *AGOSEngine_Elvira2::genSaveName(int slot) {
- static char buf[20];
-
+Common::String AGOSEngine_Elvira2::genSaveName(int slot) const {
if (getPlatform() == Common::kPlatformDOS)
- sprintf(buf, "elvira2-pc.%.3d", slot);
+ return Common::String::format("elvira2-pc.%.3d", slot);
else
- sprintf(buf, "elvira2.%.3d", slot);
-
- return buf;
+ return Common::String::format("elvira2.%.3d", slot);
}
-char *AGOSEngine_Elvira1::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "elvira1.%.3d", slot);
- return buf;
+Common::String AGOSEngine_Elvira1::genSaveName(int slot) const {
+ return Common::String::format("elvira1.%.3d", slot);
}
-char *AGOSEngine::genSaveName(int slot) {
- static char buf[20];
- sprintf(buf, "pn.%.3d", slot);
- return buf;
+Common::String AGOSEngine::genSaveName(int slot) const {
+ return Common::String::format("pn.%.3d", slot);
}
#ifdef ENABLE_AGOS2
@@ -177,12 +152,12 @@ void AGOSEngine::quickLoadOrSave() {
waitForSync(1122);
}
- char *filename = genSaveName(_saveLoadSlot);
+ Common::String filename = genSaveName(_saveLoadSlot);
if (_saveLoadType == 2) {
Subroutine *sub;
success = loadGame(genSaveName(_saveLoadSlot));
if (!success) {
- buf = Common::String::format(_("Failed to load game state from file:\n\n%s"), filename);
+ buf = Common::String::format(_("Failed to load game state from file:\n\n%s"), filename.c_str());
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
drawIconArray(2, me(), 0, 0);
setBitFlag(97, true);
@@ -217,7 +192,7 @@ void AGOSEngine::quickLoadOrSave() {
} else {
success = saveGame(_saveLoadSlot, _saveLoadName);
if (!success)
- buf = Common::String::format(_("Failed to save game state to file:\n\n%s"), filename);
+ buf = Common::String::format(_("Failed to save game state to file:\n\n%s"), filename.c_str());
}
if (!success) {
@@ -225,7 +200,7 @@ void AGOSEngine::quickLoadOrSave() {
dialog.runModal();
} else if (_saveLoadType == 1) {
- buf = Common::String::format(_("Successfully saved game state in file:\n\n%s"), filename);
+ buf = Common::String::format(_("Successfully saved game state in file:\n\n%s"), filename.c_str());
GUI::TimedMessageDialog dialog(buf, 1500);
dialog.runModal();
@@ -315,7 +290,7 @@ void AGOSEngine::userGame(bool load) {
const char *message1;
int i = 0, numSaveGames;
char *name;
- char buf[10];
+ memset(_saveBuf, 0, sizeof(_saveBuf));
numSaveGames = countSaveGames();
@@ -344,8 +319,8 @@ restart:
for (; *message1; message1++)
windowPutChar(window, *message1);
- memset(buf, 0, 10);
- name = buf;
+ memset(_saveBuf, 0, 10);
+ name = _saveBuf;
_saveGameNameLen = 0;
while (!shouldQuit()) {
@@ -403,9 +378,10 @@ restart:
_gameStoppedClock = getTime() - saveTime + _gameStoppedClock;
}
-void AGOSEngine_Elvira2::listSaveGames(char *dst) {
+void AGOSEngine_Elvira2::listSaveGames() {
Common::InSaveFile *in;
uint y, slot;
+ char *dst = _saveBuf;
const uint8 num = (getGameType() == GType_WW) ? 3 : 4;
@@ -488,7 +464,7 @@ void AGOSEngine_Elvira2::userGame(bool load) {
int i, numSaveGames;
char *name;
bool b;
- char buf[200];
+ memset(_saveBuf, 0, sizeof(_saveBuf));
_saveOrLoad = load;
@@ -504,28 +480,28 @@ void AGOSEngine_Elvira2::userGame(bool load) {
const uint8 num = (getGameType() == GType_WW) ? 3 : 4;
- listSaveGames(buf);
+ listSaveGames();
if (!load) {
WindowBlock *window = _windowArray[num];
int16 slot = -1;
- name = buf + 192;
+ name = _saveBuf + 192;
while (!shouldQuit()) {
windowPutChar(window, 128);
_saveLoadEdit = true;
- i = userGameGetKey(&b, buf, 128);
+ i = userGameGetKey(&b, 128);
if (b) {
if (i <= 223) {
if (!confirmOverWrite(window)) {
- listSaveGames(buf);
+ listSaveGames();
continue;
}
- if (!saveGame(_saveLoadRowCurPos + i, buf + i * 8))
+ if (!saveGame(_saveLoadRowCurPos + i, _saveBuf + i * 8))
fileError(_windowArray[num], true);
}
@@ -537,7 +513,7 @@ void AGOSEngine_Elvira2::userGame(bool load) {
slot = matchSaveGame(name, numSaveGames);
if (slot >= 0) {
if (!confirmOverWrite(window)) {
- listSaveGames(buf);
+ listSaveGames();
continue;
}
}
@@ -559,11 +535,11 @@ void AGOSEngine_Elvira2::userGame(bool load) {
if (slot < 0)
slot = numSaveGames;
- if (!saveGame(slot, buf + 192))
+ if (!saveGame(slot, _saveBuf + 192))
fileError(_windowArray[num], true);
}
} else {
- i = userGameGetKey(&b, buf, 128);
+ i = userGameGetKey(&b, 128);
if (i != 225) {
if (!loadGame(genSaveName(_saveLoadRowCurPos + i)))
fileError(_windowArray[num], false);
@@ -579,7 +555,7 @@ get_out:;
restartAnimation();
}
-int AGOSEngine_Elvira2::userGameGetKey(bool *b, char *buf, uint maxChar) {
+int AGOSEngine_Elvira2::userGameGetKey(bool *b, uint maxChar) {
HitArea *ha;
*b = true;
@@ -607,7 +583,7 @@ int AGOSEngine_Elvira2::userGameGetKey(bool *b, char *buf, uint maxChar) {
if (_saveLoadRowCurPos >= _numSaveGameRows)
_saveLoadRowCurPos = 1;
- listSaveGames(buf);
+ listSaveGames();
} else if (ha->id < 224) {
return ha->id - 200;
}
@@ -616,9 +592,10 @@ int AGOSEngine_Elvira2::userGameGetKey(bool *b, char *buf, uint maxChar) {
return 225;
}
-void AGOSEngine_Simon1::listSaveGames(char *dst) {
+void AGOSEngine_Simon1::listSaveGames() {
Common::InSaveFile *in;
uint16 i, slot, lastSlot;
+ char *dst = _saveBuf;
disableFileBoxes();
@@ -700,7 +677,7 @@ void AGOSEngine_Simon1::userGame(bool load) {
WindowBlock *window;
char *name;
bool b;
- char buf[108];
+ memset(_saveBuf, 0, sizeof(_saveBuf));
int maxChar = (_language == Common::HE_ISR) ? 155: 128;
_saveOrLoad = load;
@@ -723,7 +700,7 @@ void AGOSEngine_Simon1::userGame(bool load) {
_saveLoadEdit = false;
restart:;
- i = userGameGetKey(&b, buf, maxChar);
+ i = userGameGetKey(&b, maxChar);
if (i == 205)
goto get_out;
@@ -749,7 +726,7 @@ restart:;
}
window->textLength = 3;
- name = buf + i * 18;
+ name = _saveBuf + i * 18;
// now process entire savegame name to get correct x offset for cursor
_saveGameNameLen = 0;
@@ -782,7 +759,7 @@ restart:;
_saveLoadEdit = true;
- i = userGameGetKey(&b, buf, maxChar);
+ i = userGameGetKey(&b, maxChar);
if (b) {
if (i == 205)
@@ -833,7 +810,7 @@ restart:;
}
}
- if (!saveGame(_saveLoadRowCurPos + result, buf + result * 18))
+ if (!saveGame(_saveLoadRowCurPos + result, _saveBuf + result * 18))
fileError(_windowArray[5], true);
} else {
if (!loadGame(genSaveName(_saveLoadRowCurPos + i)))
@@ -846,12 +823,12 @@ get_out:;
_gameStoppedClock = getTime() - saveTime + _gameStoppedClock;
}
-int AGOSEngine_Simon1::userGameGetKey(bool *b, char *buf, uint maxChar) {
+int AGOSEngine_Simon1::userGameGetKey(bool *b, uint maxChar) {
HitArea *ha;
*b = true;
if (!_saveLoadEdit) {
- listSaveGames(buf);
+ listSaveGames();
}
_keyPressed.reset();
@@ -880,7 +857,7 @@ int AGOSEngine_Simon1::userGameGetKey(bool *b, char *buf, uint maxChar) {
_saveLoadRowCurPos -= 6;
_saveLoadEdit = false;
- listSaveGames(buf);
+ listSaveGames();
}
} else if (ha->id == 207) {
if (_saveDialogFlag) {
@@ -889,7 +866,7 @@ int AGOSEngine_Simon1::userGameGetKey(bool *b, char *buf, uint maxChar) {
_saveLoadRowCurPos = _numSaveGameRows;
_saveLoadEdit = false;
- listSaveGames(buf);
+ listSaveGames();
}
} else if (ha->id < 214) {
return ha->id - 208;
@@ -1041,7 +1018,7 @@ void writeItemID(Common::WriteStream *f, uint16 val) {
f->writeUint32BE(val - 1);
}
-bool AGOSEngine::loadGame(const char *filename, bool restartMode) {
+bool AGOSEngine::loadGame(const Common::String &filename, bool restartMode) {
char ident[100];
Common::SeekableReadStream *f = NULL;
uint num, item_index, i;
@@ -1050,7 +1027,12 @@ bool AGOSEngine::loadGame(const char *filename, bool restartMode) {
if (restartMode) {
// Load restart state
- f = _archives.createReadStreamForMember(filename);
+ Common::File *file = new Common::File();
+ if (!file->open(filename)) {
+ delete file;
+ file = nullptr;
+ }
+ f = file;
} else {
f = _saveFileMan->openForLoading(filename);
}
@@ -1215,7 +1197,7 @@ bool AGOSEngine::saveGame(uint slot, const char *caption) {
return result;
}
-bool AGOSEngine_Elvira2::loadGame(const char *filename, bool restartMode) {
+bool AGOSEngine_Elvira2::loadGame(const Common::String &filename, bool restartMode) {
char ident[100];
Common::SeekableReadStream *f = NULL;
uint num, item_index, i, j;
@@ -1224,7 +1206,12 @@ bool AGOSEngine_Elvira2::loadGame(const char *filename, bool restartMode) {
if (restartMode) {
// Load restart state
- f = _archives.createReadStreamForMember(filename);
+ Common::File *file = new Common::File();
+ if (!file->open(filename)) {
+ delete file;
+ file = nullptr;
+ }
+ f = file;
} else {
f = _saveFileMan->openForLoading(filename);
}
@@ -1274,7 +1261,6 @@ bool AGOSEngine_Elvira2::loadGame(const char *filename, bool restartMode) {
uint16 room = _currentRoom;
_currentRoom = f->readUint16BE();
-
if (_roomsListPtr) {
byte *p = _roomsListPtr;
if (room == _currentRoom) {
@@ -1306,8 +1292,7 @@ bool AGOSEngine_Elvira2::loadGame(const char *filename, bool restartMode) {
for (uint16 z = minNum; z <= maxNum; z++) {
uint16 itemNum = z + 2;
- Item *item = derefItem(itemNum);
- item->parent = 0;
+ _itemArrayPtr[itemNum] = 0;
}
}
}
@@ -1331,6 +1316,9 @@ bool AGOSEngine_Elvira2::loadGame(const char *filename, bool restartMode) {
uint parent = f->readUint16BE();
uint next = f->readUint16BE();
+ if (getGameType() == GType_WW && getPlatform() == Common::kPlatformDOS && derefItem(item->parent) == NULL)
+ item->parent = 0;
+
parent_item = derefItem(parent);
setItemParent(item, parent_item);
@@ -1633,7 +1621,7 @@ void AGOSEngine_PN::getFilename() {
}
}
-int AGOSEngine_PN::loadFile(char *name) {
+int AGOSEngine_PN::loadFile(const Common::String &name) {
Common::InSaveFile *f;
haltAnimation();
@@ -1666,7 +1654,7 @@ int AGOSEngine_PN::loadFile(char *name) {
return 0;
}
-int AGOSEngine_PN::saveFile(char *name) {
+int AGOSEngine_PN::saveFile(const Common::String &name) {
Common::OutSaveFile *f;
sysftodb();
haltAnimation();