aboutsummaryrefslogtreecommitdiff
path: root/engines/lab/savegame.cpp
diff options
context:
space:
mode:
authorFilippos Karapetis2015-02-19 15:41:15 +0200
committerEugene Sandulenko2015-12-15 00:05:02 +0100
commit0a71969018bf773cde8092df47f58ecea99f3f79 (patch)
tree3af89829414dd19f6b15e4c7eecbe483785338b1 /engines/lab/savegame.cpp
parent6af7abeab242b9446a1aeb6725643b40fe078611 (diff)
downloadscummvm-rg350-0a71969018bf773cde8092df47f58ecea99f3f79.tar.gz
scummvm-rg350-0a71969018bf773cde8092df47f58ecea99f3f79.tar.bz2
scummvm-rg350-0a71969018bf773cde8092df47f58ecea99f3f79.zip
LAB: Rewrite the save/load system
The two different save/load dialogs from the original have been dropped and replaced with the ScummVM save/load dialogs. The whole save/load code has been rewritten to be endian safe and use our common code. The original save format has not been preserved. The current implementation crashes when loading, but it's a good start
Diffstat (limited to 'engines/lab/savegame.cpp')
-rw-r--r--engines/lab/savegame.cpp376
1 files changed, 147 insertions, 229 deletions
diff --git a/engines/lab/savegame.cpp b/engines/lab/savegame.cpp
index c5d3499071..5cf0674852 100644
--- a/engines/lab/savegame.cpp
+++ b/engines/lab/savegame.cpp
@@ -28,297 +28,215 @@
*
*/
+#include "common/savefile.h"
+
+#include "graphics/surface.h"
+#include "graphics/thumbnail.h"
+
#include "lab/lab.h"
#include "lab/stddefines.h"
#include "lab/labfun.h"
-#include "lab/modernsavegame.h"
namespace Lab {
-/* The version string */
-#if defined(DOSCODE)
-#define SAVEVERSION "LBS2"
-#else
-#define SAVEVERSION "LBS3"
-#define SAVEVERSION_COMPAT "LBS2"
-#endif
+// Labyrinth of Time ScummVM
+#define SAVEGAME_ID MKTAG('L', 'O', 'T', 'S')
+#define SAVEGAME_VERSION 1
#define BOOKMARK 0
#define CARDMARK 1
#define FLOPPY 2
-typedef void *LABFH;
-#define INVALID_LABFH NULL
-uint16 FileType, FileNum;
+/*----- The machine independent section of saveGame.c -----*/
+/* Lab: Labyrinth specific */
+extern byte combination[6];
+extern uint16 CurTile[4] [4];
+extern CrumbData BreadCrumbs[MAX_CRUMBS];
+extern uint16 NumCrumbs;
+extern bool DroppingCrumbs;
+extern bool FollowingCrumbs;
-/*----- The Amiga specific area of saveGame.c -----*/
+void writeSaveGameHeader(Common::OutSaveFile *out, const Common::String &saveName) {
+ out->writeUint32BE(SAVEGAME_ID);
+ // Write version
+ out->writeByte(SAVEGAME_VERSION);
-/*****************************************************************************/
-/* Opens a file to write to from disk. */
-/*****************************************************************************/
-static LABFH saveGameOpen(char *filename, bool iswrite) {
- warning("STUB: saveGameOpen");
- return 0;
-
-#if 0
- if (iswrite) {
- unlink(filename);
- return fopen(filename, "wb");
- } else
- return fopen(filename, "rb");
-#endif
-}
+ // Write savegame name
+ out->writeString(saveName);
+ out->writeByte(0);
+ // Save the game thumbnail
+ Graphics::saveThumbnail(*out);
+ // Creation date/time
+ TimeDate curTime;
+ g_system->getTimeAndDate(curTime);
+ uint32 saveDate = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF);
+ uint16 saveTime = ((curTime.tm_hour & 0xFF) << 8) | ((curTime.tm_min) & 0xFF);
+ uint32 playTime = g_engine->getTotalPlayTime() / 1000;
-/*****************************************************************************/
-/* Closes a file. */
-/*****************************************************************************/
-static void saveGameClose(LABFH file, bool iswrite) {
- warning("STUB: saveGameClose");
- return;
-
-#if 0
- if (file != INVALID_LABFH)
- fclose(file);
-#endif
+ out->writeUint32BE(saveDate);
+ out->writeUint16BE(saveTime);
+ out->writeUint32BE(playTime);
}
+bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) {
+ uint32 id = in->readUint32BE();
+
+ // Check if it's a valid ScummVM savegame
+ if (id != SAVEGAME_ID)
+ return false;
+ // Read in the version
+ header.version = in->readByte();
+ // Check that the save version isn't newer than this binary
+ if (header.version > SAVEGAME_VERSION)
+ return false;
-/*****************************************************************************/
-/* Writes a block of memory to whatever it is that we're writing to. */
-/*****************************************************************************/
-static void saveGameWriteBlock(LABFH file, void *data, uint32 size) {
- warning("STUB: saveGameWriteBlock");
- return;
-
- //fwrite(data, 1, size, file);
-}
-
-
+ // Read in the save name
+ Common::String saveName;
+ char ch;
+ while ((ch = (char)in->readByte()) != '\0')
+ saveName += ch;
+ header.desc.setDescription(saveName);
-/*****************************************************************************/
-/* Writes a block of memory to whatever it is that we're writing to. */
-/*****************************************************************************/
-static void saveGameReadBlock(LABFH file, void *data, uint32 size) {
- warning("STUB: saveGameReadBlock");
- return;
+ // Get the thumbnail
+ header.desc.setThumbnail(Graphics::loadThumbnail(*in));
- //fread(data, 1, size, file);
-}
+ uint32 saveDate = in->readUint32BE();
+ uint16 saveTime = in->readUint16BE();
+ uint32 playTime = in->readUint32BE();
+ int day = (saveDate >> 24) & 0xFF;
+ int month = (saveDate >> 16) & 0xFF;
+ int year = saveDate & 0xFFFF;
+ header.desc.setSaveDate(year, month, day);
+ int hour = (saveTime >> 8) & 0xFF;
+ int minutes = saveTime & 0xFF;
+ header.desc.setSaveTime(hour, minutes);
+ header.desc.setPlayTime(playTime * 1000);
+ g_engine->setTotalPlayTime(playTime * 1000);
-/*----- The machine independent section of saveGame.c -----*/
-
+ return true;
+}
-/* Lab: Labyrinth specific */
-extern uint16 combination[6];
-extern uint16 CurTile[4] [4];
-
-#if !defined(DOSCODE)
-extern CrumbData BreadCrumbs[MAX_CRUMBS];
-extern uint16 NumCrumbs;
-extern bool DroppingCrumbs;
-extern bool FollowingCrumbs;
-#endif
+extern char *getPictName(CloseDataPtr *LCPtr);
/*****************************************************************************/
/* Writes the game out to disk. */
-/* Assumes that the file has already been openned and is there. */
/*****************************************************************************/
-static bool saveGame(uint16 RoomNum, uint16 Direction, uint16 Quarters, LABFH file) {
-#if !defined(DOSCODE)
- uint16 temp;
- CrumbData crumbs[sizeof(BreadCrumbs) / sizeof(CrumbData)];
-#endif
- uint16 last, counter, counter1;
- char c;
-
- saveGameWriteBlock(file, (void *)SAVEVERSION, 4L);
-#if defined(DOSCODE)
- saveGameWriteBlock(file, &RoomNum, 2L);
- saveGameWriteBlock(file, &Direction, 2L);
- saveGameWriteBlock(file, &Quarters, 2L);
-#else
- temp = swapUShort(RoomNum);
- saveGameWriteBlock(file, &temp, 2L);
- temp = swapUShort(Direction);
- saveGameWriteBlock(file, &temp, 2L);
- temp = swapUShort(Quarters);
- saveGameWriteBlock(file, &temp, 2L);
-#endif
-
- last = g_lab->_conditions->_lastElement / 8;
- saveGameWriteBlock(file, g_lab->_conditions->_array, (uint32) last);
-
- last = g_lab->_roomsFound->_lastElement / 8;
- saveGameWriteBlock(file, g_lab->_roomsFound->_array, (uint32) last);
-
- /* LAB: the combination lock and tile stuff */
- for (counter = 0; counter < 6; counter++) {
- c = (char)combination[counter];
- saveGameWriteBlock(file, &c, 1L);
- }
-
- for (counter = 0; counter < 4; counter++)
- for (counter1 = 0; counter1 < 4; counter1++)
-#if defined(DOSCODE)
- saveGameWriteBlock(file, &(CurTile[counter] [counter1]), 2L);
-
-#else
- {
- temp = swapUShort(CurTile[counter] [counter1]);
- saveGameWriteBlock(file, &temp, 2L);
- }
-#endif
-
-#if !defined(DOSCODE)
- saveGameWriteBlock(file, g_SaveGameImage, SAVED_IMAGE_SIZE);
- memcpy(crumbs, BreadCrumbs, sizeof BreadCrumbs);
- swapUShortPtr(&crumbs[0].RoomNum, sizeof(BreadCrumbs) / sizeof(uint16));
- saveGameWriteBlock(file, crumbs, sizeof BreadCrumbs);
-#endif
-
- saveGameClose(file, true);
-
- return true;
-}
-
+bool saveGame(uint16 RoomNum, uint16 Direction, uint16 Quarters, int slot, Common::String desc) {
+ uint16 i, j;
+ Common::String fileName = g_lab->generateSaveFileName(slot);
+ Common::SaveFileManager *saveFileManager = g_system->getSavefileManager();
+ Common::OutSaveFile *file = saveFileManager->openForSaving(fileName);
+ if (!file)
+ return false;
-/*****************************************************************************/
-/* Reads the game from disk. */
-/* Assumes that the file has already been openned and is there. */
-/*****************************************************************************/
-static bool loadGame(uint16 *RoomNum, uint16 *Direction, uint16 *Quarters, LABFH file) {
-#if !defined(DOSCODE)
- uint16 t;
- CrumbData crumbs[sizeof(BreadCrumbs) / sizeof(CrumbData)];
-#endif
- char temp[5], c;
- uint16 last, counter, counter1;
-
- saveGameReadBlock(file, temp, 4L);
- temp[4] = 0;
-
- /*
- if (strcmp(temp, SAVEVERSION) != 0)
- {
- saveGameClose(file, false);
- return false;
- }
- */
-
-#if defined(DOSCODE)
- saveGameReadBlock(file, RoomNum, 2L);
- saveGameReadBlock(file, Direction, 2L);
- saveGameReadBlock(file, Quarters, 2L);
-#else
- saveGameReadBlock(file, &t, 2L);
- *RoomNum = swapUShort(t);
- saveGameReadBlock(file, &t, 2L);
- *Direction = swapUShort(t);
- saveGameReadBlock(file, &t, 2L);
- *Quarters = swapUShort(t);
-#endif
-
- last = g_lab->_conditions->_lastElement / 8;
- saveGameReadBlock(file, g_lab->_conditions->_array, (uint32) last);
-
- last = g_lab->_roomsFound->_lastElement / 8;
- saveGameReadBlock(file, g_lab->_roomsFound->_array, (uint32) last);
-
- /* LAB: the combination lock and tile stuff */
- for (counter = 0; counter < 6; counter++) {
- saveGameReadBlock(file, &c, 1L);
- combination[counter] = c;
- }
+ // Load scene pic
+ CloseDataPtr CPtr = NULL;
+ readPict(getPictName(&CPtr), true);
- for (counter = 0; counter < 4; counter++)
- for (counter1 = 0; counter1 < 4; counter1++)
-#if defined(DOSCODE)
- saveGameReadBlock(file, &(CurTile[counter] [counter1]), 2L);
+ writeSaveGameHeader(file, desc);
+ file->writeUint16LE(RoomNum);
+ file->writeUint16LE(Direction);
+ file->writeUint16LE(Quarters);
-#else
- {
- saveGameReadBlock(file, &t, 2L);
- CurTile[counter] [counter1] = swapUShort(t);
- }
-#endif
+ // Conditions
+ for (i = 0; i < g_lab->_conditions->_lastElement / (8 * 2); i++)
+ file->writeUint16LE(g_lab->_conditions->_array[i]);
- if (strcmp(temp, SAVEVERSION) == 0) {
- saveGameReadBlock(file, g_SaveGameImage, SAVED_IMAGE_SIZE);
+ // Rooms found
+ for (i = 0; i < g_lab->_roomsFound->_lastElement / (8 * 2); i++)
+ file->writeUint16LE(g_lab->_roomsFound->_array[i]);
- memset(crumbs, 0, sizeof BreadCrumbs);
- saveGameReadBlock(file, crumbs, sizeof BreadCrumbs);
- swapUShortPtr(&crumbs[0].RoomNum, sizeof(BreadCrumbs) / sizeof(uint16));
- memcpy(BreadCrumbs, crumbs, sizeof BreadCrumbs);
- DroppingCrumbs = (BreadCrumbs[0].RoomNum != 0);
- FollowingCrumbs = false;
+ // Combination lock and tile stuff
+ for (i = 0; i < 6; i++)
+ file->writeByte(combination[i]);
- for (counter = 0; counter < MAX_CRUMBS; counter++)
- if (BreadCrumbs[counter].RoomNum == 0) break;
+ // Tiles
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 4; j++)
+ file->writeUint16LE(CurTile[i][j]);
- NumCrumbs = counter;
+ // Breadcrumbs
+ for (i = 0; i < sizeof(BreadCrumbs); i++) {
+ file->writeUint16LE(BreadCrumbs[i].RoomNum);
+ file->writeUint16LE(BreadCrumbs[i].Direction);
}
- saveGameClose(file, false);
+ file->flush();
+ file->finalize();
+ delete file;
return true;
}
-
/*****************************************************************************/
-/* Saves the game to the floppy disk. */
+/* Reads the game from disk. */
/*****************************************************************************/
-bool saveFloppy(char *path, uint16 RoomNum, uint16 Direction, uint16 NumQuarters, uint16 filenum, uint16 type) {
- LABFH FPtr;
-
- g_music->checkMusic();
-
- FileType = type;
- FileNum = filenum;
-
- if ((FPtr = saveGameOpen(path, true)) != INVALID_LABFH)
- saveGame(RoomNum, Direction, NumQuarters, FPtr);
- else
+bool loadGame(uint16 *RoomNum, uint16 *Direction, uint16 *Quarters, int slot) {
+ uint16 i, j;
+ Common::String fileName = g_lab->generateSaveFileName(slot);
+ Common::SaveFileManager *saveFileManager = g_system->getSavefileManager();
+ Common::InSaveFile *file = saveFileManager->openForLoading(fileName);
+
+ if (!file)
return false;
- return true;
-}
-
-
-
-
-/*****************************************************************************/
-/* Reads the game from the floppy disk. */
-/*****************************************************************************/
-bool readFloppy(char *path, uint16 *RoomNum, uint16 *Direction, uint16 *NumQuarters, uint16 filenum, uint16 type) {
- LABFH FPtr;
+ SaveGameHeader header;
+ readSaveGameHeader(file, header);
+ *RoomNum = file->readUint16LE();
+ *Direction = file->readUint16LE();
+ *Quarters = file->readUint16LE();
+
+ // Conditions
+ for (i = 0; i < g_lab->_conditions->_lastElement / (8 * 2); i++)
+ g_lab->_conditions->_array[i] = file->readUint16LE();
+
+ // Rooms found
+ for (i = 0; i < g_lab->_roomsFound->_lastElement / (8 * 2); i++)
+ g_lab->_roomsFound->_array[i] = file->readUint16LE();
+
+ // Combination lock and tile stuff
+ for (i = 0; i < 6; i++)
+ combination[i] = file->readByte();
+
+ // Tiles
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 4; j++)
+ CurTile[i][j] = file->readUint16LE();
+
+ // Breadcrumbs
+ for (i = 0; i < sizeof(BreadCrumbs); i++) {
+ BreadCrumbs[i].RoomNum = file->readUint16LE();
+ BreadCrumbs[i].Direction = file->readUint16LE();
+ }
- g_music->checkMusic();
+ DroppingCrumbs = (BreadCrumbs[0].RoomNum != 0);
+ FollowingCrumbs = false;
- FileType = type;
- FileNum = filenum;
+ for (i = 0; i < sizeof(BreadCrumbs); i++) {
+ if (BreadCrumbs[i].RoomNum == 0)
+ break;
+ NumCrumbs++;
+ }
- if ((FPtr = saveGameOpen(path, false)) != INVALID_LABFH) {
- if (!loadGame(RoomNum, Direction, NumQuarters, FPtr))
- return false;
- } else
- return false;
+ delete file;
return true;
}
+
} // End of namespace Lab