aboutsummaryrefslogtreecommitdiff
path: root/engines/agi/saveload.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/agi/saveload.cpp')
-rw-r--r--engines/agi/saveload.cpp166
1 files changed, 96 insertions, 70 deletions
diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp
index 2130473810..7c84f1dd72 100644
--- a/engines/agi/saveload.cpp
+++ b/engines/agi/saveload.cpp
@@ -23,10 +23,10 @@
*
*/
-/*
- * Savegame support by Vasyl Tsvirkunov <vasyl@pacbell.net>
- * Multi-slots by Claudio Matsuoka <claudio@helllabs.org>
- */
+//
+// Savegame support by Vasyl Tsvirkunov <vasyl@pacbell.net>
+// Multi-slots by Claudio Matsuoka <claudio@helllabs.org>
+//
#include <time.h> // for extended infos
@@ -39,22 +39,23 @@
#include "agi/keyboard.h"
#include "agi/menu.h"
-#define SAVEGAME_VERSION 4
+#define SAVEGAME_VERSION 5
-/*
- * Version 0 (Sarien): view table has 64 entries
- * Version 1 (Sarien): view table has 256 entries (needed in KQ3)
- * Version 2 (ScummVM): first ScummVM version
- * Version 3 (ScummVM): added AGIPAL save/load support
- * Version 4 (ScummVM): added thumbnails and save creation date/time
- */
+//
+// Version 0 (Sarien): view table has 64 entries
+// Version 1 (Sarien): view table has 256 entries (needed in KQ3)
+// Version 2 (ScummVM): first ScummVM version
+// Version 3 (ScummVM): added AGIPAL save/load support
+// Version 4 (ScummVM): added thumbnails and save creation date/time
+// Version 5 (ScummVM): Added game md5
+//
namespace Agi {
-static const uint32 AGIflag=MKID_BE('AGI:');
+static const uint32 AGIflag = MKID_BE('AGI:');
int AgiEngine::saveGame(const char *fileName, const char *description) {
- char gameIDstring[8]="gameIDX";
+ char gameIDstring[8] = "gameIDX";
int i;
Common::OutSaveFile *out;
int result = errOK;
@@ -96,6 +97,10 @@ int AgiEngine::saveGame(const char *fileName, const char *description) {
out->write(gameIDstring, 8);
debugC(5, kDebugLevelMain | kDebugLevelSavegame, "Writing game id (%s, %s)", gameIDstring, _game.id);
+ const char *tmp = getGameMD5();
+ for (i = 0; i < 32; i++)
+ out->writeByte(tmp[i]);
+
for (i = 0; i < MAX_FLAGS; i++)
out->writeByte(_game.flags[i]);
for (i = 0; i < MAX_VARS; i++)
@@ -128,20 +133,20 @@ int AgiEngine::saveGame(const char *fileName, const char *description) {
out->writeSint16BE((int16)_game.colorFg);
out->writeSint16BE((int16)_game.colorBg);
- /* game.hires */
- /* game.sbuf */
- /* game.ego_words */
- /* game.num_ego_words */
+ // game.hires
+ // game.sbuf
+ // game.ego_words
+ // game.num_ego_words
out->writeSint16BE((int16)_game.numObjects);
for (i = 0; i < (int16)_game.numObjects; i++)
out->writeSint16BE((int16)objectGetLocation(i));
- /* game.ev_keyp */
+ // game.ev_keyp
for (i = 0; i < MAX_STRINGS; i++)
out->write(_game.strings[i], MAX_STRINGLEN);
- /* record info about loaded resources */
+ // record info about loaded resources
for (i = 0; i < MAX_DIRS; i++) {
out->writeByte(_game.dirLogic[i].flags);
out->writeSint16BE((int16)_game.logics[i].sIP);
@@ -154,10 +159,10 @@ int AgiEngine::saveGame(const char *fileName, const char *description) {
for (i = 0; i < MAX_DIRS; i++)
out->writeByte(_game.dirSound[i].flags);
- /* game.pictures */
- /* game.logics */
- /* game.views */
- /* game.sounds */
+ // game.pictures
+ // game.logics
+ // game.views
+ // game.sounds
for (i = 0; i < MAX_VIEWTABLE; i++) {
VtEntry *v = &_game.viewTable[i];
@@ -169,23 +174,23 @@ int AgiEngine::saveGame(const char *fileName, const char *description) {
out->writeSint16BE(v->yPos);
out->writeByte(v->currentView);
- /* v->view_data */
+ // v->view_data
out->writeByte(v->currentLoop);
out->writeByte(v->numLoops);
- /* v->loop_data */
+ // v->loop_data
out->writeByte(v->currentCel);
out->writeByte(v->numCels);
- /* v->cel_data */
- /* v->cel_data_2 */
+ // v->cel_data
+ // v->cel_data_2
out->writeSint16BE(v->xPos2);
out->writeSint16BE(v->yPos2);
- /* v->s */
+ // v->s
out->writeSint16BE(v->xSize);
out->writeSint16BE(v->ySize);
@@ -206,7 +211,7 @@ int AgiEngine::saveGame(const char *fileName, const char *description) {
out->writeByte(v->parm4);
}
- /* Save image stack */
+ // Save image stack
for (i = 0; i < _imageStack.size(); i++) {
ImageStackElement ise = _imageStack[i];
@@ -299,19 +304,37 @@ int AgiEngine::loadGame(const char *fileName, bool checkId) {
strncpy(_game.id, loadId, 8);
+ if (saveVersion >= 5) {
+ char md5[32 + 1];
+
+ for (i = 0; i < 32; i++) {
+ md5[i] = in->readByte();
+
+ }
+ md5[i] = 0; // terminate
+
+ debug(0, "Saved game MD5: %s", md5);
+
+ if (strcmp(md5, getGameMD5())) {
+ warning("Game was saved with different gamedata - you may encounter problems");
+
+ debug(0, "You have %s and save is %s.", getGameMD5(), md5);
+ }
+ }
+
for (i = 0; i < MAX_FLAGS; i++)
_game.flags[i] = in->readByte();
for (i = 0; i < MAX_VARS; i++)
_game.vars[i] = in->readByte();
- setvar(vFreePages, 255); // Set amount of free memory to the maximum value (Overwriting the just loaded value)
+ setvar(vFreePages, 180); // Set amount of free memory to realistic value (Overwriting the just loaded value)
_game.horizon = in->readSint16BE();
_game.lineStatus = in->readSint16BE();
_game.lineUserInput = in->readSint16BE();
_game.lineMinPrint = in->readSint16BE();
- /* These are never saved */
+ // These are never saved
_game.cursorPos = 0;
_game.inputBuffer[0] = 0;
_game.echoBuffer[0] = 0;
@@ -339,27 +362,27 @@ int AgiEngine::loadGame(const char *fileName, bool checkId) {
_game.msgBoxTicks = 0;
_game.block.active = false;
- /* game.window - fixed by close_window() */
- /* game.has_window - fixed by close_window() */
+ // game.window - fixed by close_window()
+ // game.has_window - fixed by close_window()
_game.gfxMode = in->readSint16BE();
_game.cursorChar = in->readByte();
_game.colorFg = in->readSint16BE();
_game.colorBg = in->readSint16BE();
- /* game.hires - rebuilt from image stack */
- /* game.sbuf - rebuilt from image stack */
+ // game.hires - rebuilt from image stack
+ // game.sbuf - rebuilt from image stack
- /* game.ego_words - fixed by clean_input */
- /* game.num_ego_words - fixed by clean_input */
+ // game.ego_words - fixed by clean_input
+ // game.num_ego_words - fixed by clean_input
_game.numObjects = in->readSint16BE();
for (i = 0; i < (int16)_game.numObjects; i++)
objectSetLocation(i, in->readSint16BE());
- /* Those are not serialized */
+ // Those are not serialized
for (i = 0; i < MAX_DIRS; i++) {
- _game.evKeyp[i].occured = false;
+ _game.controllerOccured[i] = false;
}
for (i = 0; i < MAX_STRINGS; i++)
@@ -395,10 +418,10 @@ int AgiEngine::loadGame(const char *fileName, bool checkId) {
agiUnloadResource(rSOUND, i);
}
- /* game.pictures - loaded above */
- /* game.logics - loaded above */
- /* game.views - loaded above */
- /* game.sounds - loaded above */
+ // game.pictures - loaded above
+ // game.logics - loaded above
+ // game.views - loaded above
+ // game.sounds - loaded above
for (i = 0; i < vtEntries; i++) {
VtEntry *v = &_game.viewTable[i];
@@ -410,23 +433,23 @@ int AgiEngine::loadGame(const char *fileName, bool checkId) {
v->yPos = in->readSint16BE();
v->currentView = in->readByte();
- /* v->view_data - fixed below */
+ // v->view_data - fixed below
v->currentLoop = in->readByte();
v->numLoops = in->readByte();
- /* v->loop_data - fixed below */
+ // v->loop_data - fixed below
v->currentCel = in->readByte();
v->numCels = in->readByte();
- /* v->cel_data - fixed below */
- /* v->cel_data_2 - fixed below */
+ // v->cel_data - fixed below
+ // v->cel_data_2 - fixed below
v->xPos2 = in->readSint16BE();
v->yPos2 = in->readSint16BE();
- /* v->s - fixed below */
+ // v->s - fixed below
v->xSize = in->readSint16BE();
v->ySize = in->readSint16BE();
@@ -450,7 +473,7 @@ int AgiEngine::loadGame(const char *fileName, bool checkId) {
memset(&_game.viewTable[i], 0, sizeof(VtEntry));
}
- /* Fix some pointers in viewtable */
+ // Fix some pointers in viewtable
for (i = 0; i < MAX_VIEWTABLE; i++) {
VtEntry *v = &_game.viewTable[i];
@@ -461,20 +484,20 @@ int AgiEngine::loadGame(const char *fileName, bool checkId) {
if (!(_game.dirView[v->currentView].flags & RES_LOADED))
agiLoadResource(rVIEW, v->currentView);
- setView(v, v->currentView); /* Fix v->view_data */
- setLoop(v, v->currentLoop); /* Fix v->loop_data */
- setCel(v, v->currentCel); /* Fix v->cel_data */
+ setView(v, v->currentView); // Fix v->view_data
+ setLoop(v, v->currentLoop); // Fix v->loop_data
+ setCel(v, v->currentCel); // Fix v->cel_data
v->celData2 = v->celData;
- v->s = NULL; /* not sure if it is used... */
+ v->s = NULL; // not sure if it is used...
}
_sprites->eraseBoth();
- /* Clear input line */
+ // Clear input line
_gfx->clearScreen(0);
writeStatus();
- /* Recreate background from saved image stack */
+ // Recreate background from saved image stack
clearImageStack();
while ((t = in->readByte()) != 0) {
for (i = 0; i < 7; i++)
@@ -483,7 +506,7 @@ int AgiEngine::loadGame(const char *fileName, bool checkId) {
parm[3], parm[4], parm[5], parm[6]);
}
- //Load AGIPAL Data
+ // Load AGIPAL Data
if (saveVersion >= 3)
_gfx->setAGIPal(in->readSint16BE());
@@ -492,7 +515,7 @@ int AgiEngine::loadGame(const char *fileName, bool checkId) {
setflag(fRestoreJustRan, true);
- _game.hasPrompt = 0; /* force input line repaint if necessary */
+ _game.hasPrompt = 0; // force input line repaint if necessary
cleanInput();
_sprites->eraseBoth();
@@ -517,20 +540,23 @@ const char *AgiEngine::getSavegameFilename(int num) {
}
void AgiEngine::getSavegameDescription(int num, char *buf, bool showEmpty) {
- char fileName[MAX_PATH];
+ char fileName[MAXPATHLEN];
Common::InSaveFile *in;
debugC(4, kDebugLevelMain | kDebugLevelSavegame, "Current game id is %s", _targetName.c_str());
sprintf(fileName, "%s", getSavegameFilename(num));
if (!(in = _saveFileMan->openForLoading(fileName))) {
debugC(4, kDebugLevelMain | kDebugLevelSavegame, "File %s does not exist", fileName);
+
if (showEmpty)
strcpy(buf, " (empty slot)");
else
*buf = 0;
} else {
debugC(4, kDebugLevelMain | kDebugLevelSavegame, "Successfully opened %s for reading", fileName);
+
uint32 type = in->readUint32BE();
+
if (type == AGIflag) {
debugC(6, kDebugLevelMain | kDebugLevelSavegame, "Has AGI flag, good start");
in->read(buf, 31);
@@ -546,13 +572,13 @@ void AgiEngine::getSavegameDescription(int num, char *buf, bool showEmpty) {
int AgiEngine::selectSlot() {
int i, key, active = 0;
int rc = -1;
- int hm = 1, vm = 3; /* box margins */
+ int hm = 1, vm = 3; // box margins
int xmin, xmax, slotClicked;
char desc[NUM_VISIBLE_SLOTS][40];
int textCentre, buttonLength, buttonX[2], buttonY;
const char *buttonText[] = { " OK ", "Cancel", NULL };
- setflag(fNoSaveLoadAllowed, true);
+ _noSaveLoadAllowed = true;
for (i = 0; i < NUM_VISIBLE_SLOTS; i++) {
getSavegameDescription(_firstSlot + i, desc[i]);
@@ -571,7 +597,7 @@ int AgiEngine::selectSlot() {
int oldFirstSlot = _firstSlot + 1;
int oldActive = active + 1;
- while (!(shouldQuit() || restartGame)) {
+ while (!(shouldQuit() || _restartGame)) {
int sbPos = 0;
// Use the extreme scrollbar positions only if the extreme
@@ -613,7 +639,7 @@ int AgiEngine::selectSlot() {
oldFirstSlot = _firstSlot;
}
- _gfx->pollTimer(); /* msdos driver -> does nothing */
+ pollTimer();
key = doPollKeyboard();
// It may happen that somebody will open GMM while
@@ -643,7 +669,7 @@ int AgiEngine::selectSlot() {
rc = -1;
goto getout;
}
- slotClicked = ((int)g_mouse.y-1)/CHAR_COLS-(vm+4);
+ slotClicked = ((int)g_mouse.y - 1) / CHAR_COLS - (vm + 4);
xmin = (hm + 1) * CHAR_COLS;
xmax = xmin + CHAR_COLS * 34;
if ((int)g_mouse.x >= xmin && (int)g_mouse.x <= xmax) {
@@ -737,13 +763,13 @@ press:
getout:
closeWindow();
- setflag(fNoSaveLoadAllowed, false);
+ _noSaveLoadAllowed = false;
return rc;
}
int AgiEngine::saveGameDialog() {
- char fileName[MAX_PATH];
+ char fileName[MAXPATHLEN];
char *desc;
const char *buttons[] = { "Do as I say!", "I regret", NULL };
char dstr[200];
@@ -828,7 +854,7 @@ int AgiEngine::saveGameDialog() {
}
int AgiEngine::saveGameSimple() {
- char fileName[MAX_PATH];
+ char fileName[MAXPATHLEN];
sprintf(fileName, "%s", getSavegameFilename(0));
int result = saveGame(fileName, "Default savegame");
@@ -838,9 +864,9 @@ int AgiEngine::saveGameSimple() {
}
int AgiEngine::loadGameDialog() {
- char fileName[MAX_PATH];
+ char fileName[MAXPATHLEN];
int rc, slot = 0;
- int hm, vm, hp, vp; /* box margins */
+ int hm, vm, hp, vp; // box margins
int w;
hm = 1;
@@ -879,7 +905,7 @@ int AgiEngine::loadGameDialog() {
}
int AgiEngine::loadGameSimple() {
- char fileName[MAX_PATH];
+ char fileName[MAXPATHLEN];
int rc = 0;
sprintf(fileName, "%s", getSavegameFilename(0));