aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippos Karapetis2007-12-08 18:25:00 +0000
committerFilippos Karapetis2007-12-08 18:25:00 +0000
commit3980bd73ea7a00de469ae64d90485dcd197689fa (patch)
treebd26f9d3b63b35d87a5ccf0538735cea17bec7c5
parentf1a1254581498d87c4db1e8a185ca84e7dc63013 (diff)
downloadscummvm-rg350-3980bd73ea7a00de469ae64d90485dcd197689fa.tar.gz
scummvm-rg350-3980bd73ea7a00de469ae64d90485dcd197689fa.tar.bz2
scummvm-rg350-3980bd73ea7a00de469ae64d90485dcd197689fa.zip
Saving and loading in Winnie the Pooh should now be endian and alignment safe. Note that this breaks older saved games and it's no longer possible to use saved games from the original game interpreter
svn-id: r29771
-rw-r--r--engines/agi/preagi_winnie.cpp66
-rw-r--r--engines/agi/preagi_winnie.h25
2 files changed, 62 insertions, 29 deletions
diff --git a/engines/agi/preagi_winnie.cpp b/engines/agi/preagi_winnie.cpp
index 893742b05c..82be15a0d0 100644
--- a/engines/agi/preagi_winnie.cpp
+++ b/engines/agi/preagi_winnie.cpp
@@ -31,12 +31,14 @@
#include "common/events.h"
#include "common/savefile.h"
+#include "common/stream.h"
namespace Agi {
// default attributes
-#define IDA_DEFAULT 0x0F
-#define IDA_DEFAULT_REV 0xF0
+#define IDA_DEFAULT 0x0F
+#define IDA_DEFAULT_REV 0xF0
+#define WTP_SAVEGAME_VERSION 1
void Winnie::parseRoomHeader(WTP_ROOM_HDR *roomHdr, byte *buffer, int len) {
bool isBigEndian = (_vm->getPlatform() == Common::kPlatformAmiga);
@@ -1192,33 +1194,73 @@ void Winnie::gameOver() {
}
void Winnie::saveGame() {
- uint8 *buffer = (uint8 *)malloc(sizeof(WTP_SAVE_GAME));
- memcpy(buffer, &_game, sizeof(WTP_SAVE_GAME));
Common::OutSaveFile* outfile;
char szFile[256] = {0};
+ int i = 0;
sprintf(szFile, IDS_WTP_FILE_SAVEGAME);
if (!(outfile = _vm->getSaveFileMan()->openForSaving(szFile)))
return;
- outfile->write(buffer, sizeof(WTP_SAVE_GAME));
- delete outfile;
- free(buffer);
+ outfile->writeUint32BE(MKID_BE('WINN')); // header
+ outfile->writeByte(WTP_SAVEGAME_VERSION);
+
+ outfile->writeByte(_game.fSound);
+ outfile->writeByte(_game.nMoves);
+ outfile->writeByte(_game.nObjMiss);
+ outfile->writeByte(_game.nObjRet);
+ outfile->writeByte(_game.iObjHave);
+
+ for(i = 0; i < IDI_WTP_MAX_FLAG; i++)
+ outfile->writeByte(_game.fGame[i]);
+
+ for(i = 0; i < IDI_WTP_MAX_OBJ_MISSING; i++)
+ outfile->writeByte(_game.iUsedObj[i]);
+
+ for(i = 0; i < IDI_WTP_MAX_ROOM_OBJ; i++)
+ outfile->writeByte(_game.iObjRoom[i]);
+
+ outfile->finalize();
+
+ if (outfile->ioFailed())
+ warning("Can't write file '%s'. (Disk full?)", szFile);
+
+ delete outfile;
}
void Winnie::loadGame() {
- uint8 *buffer = (uint8 *)malloc(sizeof(WTP_SAVE_GAME));
Common::InSaveFile* infile;
char szFile[256] = {0};
+ int saveVersion = 0;
+ int i = 0;
sprintf(szFile, IDS_WTP_FILE_SAVEGAME);
if (!(infile = _vm->getSaveFileMan()->openForLoading(szFile)))
return;
- infile->read(buffer, sizeof(WTP_SAVE_GAME));
- delete infile;
- memcpy(&_game, buffer, sizeof(WTP_SAVE_GAME));
- free(buffer);
+ if (infile->readUint32BE() != MKID_BE('WINN'))
+ error("Winnie::loadGame wrong save game format");
+
+ saveVersion = infile->readByte();
+ if (saveVersion != WTP_SAVEGAME_VERSION)
+ warning("Old save game version (%d, current version is %d). Will try and read anyway, but don't be surprised if bad things happen", saveVersion, WTP_SAVEGAME_VERSION);
+
+ _game.fSound = infile->readByte();
+ _game.nMoves = infile->readByte();
+ _game.nObjMiss = infile->readByte();
+ _game.nObjRet = infile->readByte();
+ _game.iObjHave = infile->readByte();
+
+ for(i = 0; i < IDI_WTP_MAX_FLAG; i++)
+ _game.fGame[i] = infile->readByte();
+
+ for(i = 0; i < IDI_WTP_MAX_OBJ_MISSING; i++)
+ _game.iUsedObj[i] = infile->readByte();
+
+ for(i = 0; i < IDI_WTP_MAX_ROOM_OBJ; i++)
+ _game.iObjRoom[i] = infile->readByte();
+
+ delete infile;
}
// Console-related functions
diff --git a/engines/agi/preagi_winnie.h b/engines/agi/preagi_winnie.h
index 9783992d48..045ab66ad8 100644
--- a/engines/agi/preagi_winnie.h
+++ b/engines/agi/preagi_winnie.h
@@ -274,23 +274,14 @@ struct WTP_OBJ_HDR {
// savegame
struct WTP_SAVE_GAME {
- uint16 reserved0; // 10c2 unused
- uint16 fSound; // 10c4
- uint16 nMoves; // 10c6
- uint16 nObjMiss; // 10c8
- uint16 nObjRet; // 10ca
- uint16 reserved1; // 10ce unused
- uint16 reserved2; // 10cf unused
- uint16 reserved3; // 10d0 unused
- uint16 iObjHave; // 10d2
- uint16 o10d4; // 10d4 can be ignored
- uint16 o10d6; // 10d6 can be ignored
- uint16 o10d8; // 10d8 can be ignored
- uint8 fGame[IDI_WTP_MAX_FLAG]; // 10da
- uint8 iUsedObj[IDI_WTP_MAX_OBJ_MISSING]; // 1102
- uint8 iObjRoom[IDI_WTP_MAX_ROOM_OBJ]; // 110c
- uint16 o1136; // 1136 can be ignored
- uint16 o1138; // 1138 can be ignored
+ uint8 fSound;
+ uint8 nMoves;
+ uint8 nObjMiss;
+ uint8 nObjRet;
+ uint8 iObjHave;
+ uint8 fGame[IDI_WTP_MAX_FLAG];
+ uint8 iUsedObj[IDI_WTP_MAX_OBJ_MISSING];
+ uint8 iObjRoom[IDI_WTP_MAX_ROOM_OBJ];
};
#define IDI_XOR_KEY 0x80