ASYLUM: Implement saving of games

- Added stubs for saveLoadWithSerializer

git-svn-id: http://asylumengine.googlecode.com/svn/trunk@678 0bfb4aae-4ea4-11de-8d8d-752d95cf3e3c
This commit is contained in:
Julien Templier 2010-12-08 02:31:49 +00:00 committed by Eugene Sandulenko
parent 54381ad846
commit af09eeccee
No known key found for this signature in database
GPG Key ID: 014D387312D34F08
13 changed files with 241 additions and 68 deletions

View File

@ -510,6 +510,10 @@ void AsylumEngine::updateReverseStereo() {
_scene->worldstats()->reverseStereo = Config.reverseStereo;
}
void AsylumEngine::saveLoadWithSerializer(Common::Serializer &s) {
error("[AsylumEngine::saveLoadWithSerializer] Not implemented!");
}
//////////////////////////////////////////////////////////////////////////
// Game flags
//////////////////////////////////////////////////////////////////////////

View File

@ -26,6 +26,7 @@
#ifndef ASYLUM_ENGINE_H
#define ASYLUM_ENGINE_H
#include "asylum/puzzles/data.h"
#include "asylum/resources/data.h"
#include "asylum/console.h"
@ -34,6 +35,7 @@
#include "common/random.h"
#include "common/scummsys.h"
#include "common/serializer.h"
#include "common/system.h"
#include "engines/advancedDetector.h"
@ -79,7 +81,7 @@ class Sound;
class Text;
class Video;
class AsylumEngine: public Engine {
class AsylumEngine: public Engine, public Common::Serializable {
protected:
// Engine APIs
virtual Common::Error run();
@ -119,13 +121,6 @@ public:
*/
uint32 getTick() { return _system->getMillis(); }
/**
* Gets the shared data.
*
* @return a pointer to the shared data.
*/
SharedData *getData() { return &_data; }
/**
* Resets the game
*/
@ -152,6 +147,9 @@ public:
Text *text() { return _text; }
Video *video() { return _video; }
SharedData *data() { return &_data; }
PuzzleData *puzzleData() { return &_puzzleData; }
// Flags
void setGameFlagByIndex(int32 index);
int32 getGameFlagByIndex(int32 index);
@ -204,6 +202,9 @@ public:
*/
Common::Point getSinCosValues(int32 index1, int32 index2);
// Serializable
void saveLoadWithSerializer(Common::Serializer &s);
private:
const ADGameDescription *_gameDescription;
@ -231,6 +232,7 @@ private:
Puzzle *_puzzles[16];
// Game data
PuzzleData _puzzleData;
SharedData _data;
int _gameFlags[145];
bool _introPlayed;

View File

@ -345,7 +345,7 @@ bool Console::cmdRunScript(int32 argc, const char **argv) {
// Check parameters
if (index >= getScript()->_scripts.size()) {
DebugPrintf("[Error] Invalid index (was: %d - valid: [0-%d])\n", index, _vm->encounter()->_items.size() - 1);
DebugPrintf("[Error] Invalid index (was: %d - valid: [0-%d])\n", index, _vm->encounter()->items()->size() - 1);
return true;
}

View File

@ -0,0 +1,48 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* 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.
*
* $URL$
* $Id$
*
*/
#ifndef ASYLUM_PUZZLE_DATA_H
#define ASYLUM_PUZZLE_DATA_H
#include "asylum/console.h"
#include "common/serializer.h"
namespace Asylum {
struct PuzzleData : public Common::Serializable {
public:
// Serializable
void saveLoadWithSerializer(Common::Serializer &s) {
error("[PuzzleData::saveLoadWithSerializer] Not implemented!");
}
private:
};
} // End of namespace Asylum
#endif // ASYLUM_PUZZLE_DATA_H

View File

@ -1193,7 +1193,7 @@ void Actor::enableActorsChapter2(AsylumEngine *engine) {
engine->clearGameFlag(kGameFlag442);
// Reset shared data
engine->getData()->resetActorData();
engine->data()->resetActorData();
engine->scene()->getActor(13)->enable();
engine->scene()->getActor(13)->processStatus(2300, 71, false);

View File

@ -31,11 +31,44 @@
#include "asylum/shared.h"
#include "common/array.h"
#include "common/serializer.h"
namespace Asylum {
class AsylumEngine;
struct EncounterItem {
int16 keywordIndex;
int16 field2;
ResourceId scriptResourceId;
int16 keywords[50];
byte value;
EncounterItem() {
keywordIndex = 0;
field2 = 0;
scriptResourceId = kResourceNone;
memset(&keywords, 0, sizeof(keywords));
value = 0;
}
};
class EncounterVariables : public Common::Array<int16>, public Common::Serializable {
public:
// Serializable
void saveLoadWithSerializer(Common::Serializer &s) {
error("[EncounterVariables::saveLoadWithSerializer] Not implemented!");
}
};
class EncounterItems : public Common::Array<EncounterItem>, public Common::Serializable {
public:
// Serializable
void saveLoadWithSerializer(Common::Serializer &s) {
error("[EncounterItems::saveLoadWithSerializer] Not implemented!");
}
};
class Encounter : public EventHandler {
public:
Encounter(AsylumEngine *engine);
@ -54,6 +87,10 @@ public:
void disablePlayerOnExit(bool state) { _disablePlayerOnExit = state; }
bool isRunning() { return _isRunning; }
// Accessors (for saving game)
EncounterItems *items() { return &_items; }
EncounterVariables *variables() { return &_variables; }
private:
AsylumEngine *_vm;
@ -65,14 +102,6 @@ private:
kEncounterArray8000 = 0x8000
};
struct EncounterItem {
int16 keywordIndex;
int16 field2;
ResourceId scriptResourceId;
int16 keywords[50];
byte value;
};
struct EncounterGraphic {
int32 frameIndex;
int32 frameCount;
@ -114,8 +143,8 @@ private:
}
};
Common::Array<int16> _variables;
Common::Array<EncounterItem> _items;
EncounterVariables _variables;
EncounterItems _items;
EncounterDrawingStruct _drawingStructs[2];
int32 _keywordIndexes[50];

View File

@ -335,6 +335,10 @@ bool ScriptManager::process() {
return false;
}
void ScriptManager::saveLoadWithSerializer(Common::Serializer &s) {
error("[ScriptManager::saveLoadWithSerializer] Not implemented!");
}
//////////////////////////////////////////////////////////////////////////
// Opcode Functions
//////////////////////////////////////////////////////////////////////////

View File

@ -30,6 +30,7 @@
#include "common/array.h"
#include "common/func.h"
#include "common/serializer.h"
#include "common/stack.h"
#include "common/stream.h"
@ -117,7 +118,7 @@ struct ActionArea {
}
};
class ScriptManager {
class ScriptManager : public Common::Serializable {
public:
ScriptManager(AsylumEngine *engine);
virtual ~ScriptManager();
@ -167,6 +168,9 @@ public:
bool isProcessingSkipped() { return _skipProcessing; }
// Serializable
void saveLoadWithSerializer(Common::Serializer &s);
private:
enum ObjectEnableType {
kObjectEnableType0,

View File

@ -76,7 +76,7 @@ WorldStats::WorldStats(AsylumEngine *engine) : _vm(engine) {
musicFlag = 0;
musicResourceId = kResourceNone;
musicStatusExt = 0;
numActionLists = 0;
numScripts = 0;
numPolygons = 0;
memset(&cursorResourcesAlternate, kResourceNone, sizeof(cursorResourcesAlternate));
@ -220,7 +220,7 @@ void WorldStats::load(Common::SeekableReadStream *stream) {
//////////////////////////////////////////////////////////////////////////
// Read number of scripts and polygons
numActionLists = stream->readUint32LE();
numScripts = stream->readUint32LE();
numPolygons = stream->readUint32LE();
// Load the alternate cursor resources
@ -357,4 +357,9 @@ Common::String WorldStats::toString() {
return output;
}
void WorldStats::saveLoadWithSerializer(Common::Serializer &s) {
error("[WorldStats::saveLoadWithSerializer] Not implemented!");
}
} // end of namespace Asylum

View File

@ -28,8 +28,9 @@
#include "asylum/system/sound.h"
#include "common/rect.h"
#include "common/array.h"
#include "common/rect.h"
#include "common/serializer.h"
namespace Asylum {
@ -64,7 +65,7 @@ enum CursorResourceType {
kCursorResourceTalkNPC2
};
class WorldStats {
class WorldStats : public Common::Serializable {
public:
WorldStats(AsylumEngine *engine);
virtual ~WorldStats();
@ -124,7 +125,7 @@ public:
Common::Array<Object*> objects; // maxsize 400
Common::Array<Actor*> actors; // maxsize 50
// ActorData is stored in each actor instance
int32 numActionLists;
int32 numScripts;
int32 numPolygons;
ResourceId cursorResourcesAlternate[64];
Common::Array<ActionArea*> actions; // maxsize 400
@ -154,6 +155,9 @@ public:
Common::String toString();
// Serializable
void saveLoadWithSerializer(Common::Serializer &s);
private:
AsylumEngine *_vm;
};

View File

@ -607,13 +607,14 @@ enum ObjectFlag {
#define getEncounter() _vm->encounter()
#define getCursor() _vm->cursor()
#define getMenu() _vm->menu()
#define getPuzzleData() _vm->puzzleData()
#define getResource() _vm->resource()
#define getSound() _vm->sound()
#define getSaveLoad() _vm->savegame()
#define getScene() _vm->scene()
#define getScreen() _vm->screen()
#define getScript() _vm->script()
#define getSharedData() _vm->getData()
#define getSharedData() _vm->data()
#define getSpecial() _vm->special()
#define getSpeech() _vm->speech()
#define getText() _vm->text()

View File

@ -25,6 +25,9 @@
#include "asylum/system/savegame.h"
#include "asylum/puzzles/data.h"
#include "asylum/resources/encounters.h"
#include "asylum/resources/script.h"
#include "asylum/resources/worldstats.h"
@ -44,13 +47,15 @@ namespace Asylum {
#define SAVEGAME_BUILD 851
#define SAVEGAME_VERSION_SIZE 11
#define SAVEGAME_NAME_SIZE 45
#define SAVEGAME_NAME "asylum"
#define SAVEGAME_QUICKSLOT 25
#define SAVEGAME_MOVIES "asylum.movies"
const char savegame_version[12] = "v1.01 FINAL";
const Common::String savegame_version = "v1.01 FINAL";
Savegame::Savegame(AsylumEngine *engine) : _vm(engine), _index(0), _valid(false) {
memset(&_moviesViewed, 0, sizeof(_moviesViewed));
@ -78,8 +83,8 @@ void Savegame::loadList() {
if (!file)
error("[Savegame::loadList] Cannot open savegame: %s", getFilename(i).c_str());
read(file, (byte *)&_savegameToScene[i], 4, 1, "Level");
read(file, (byte *)&_names[i], 1, 45, "Game Name");
_savegameToScene[i] = read(file, "Level");
_names[i] = read(file, 45, "Game Name");
_savegames[i] = true;
delete file;
@ -162,16 +167,13 @@ bool Savegame::quickSave() {
save();
} else {
char name[45];
Common::InSaveFile *file = g_system->getSavefileManager()->openForLoading(getFilename(SAVEGAME_QUICKSLOT));
if (!file)
return false;
// Read game name
read(file, 1, "Level");
read(file, (byte *)&name, 1, 45, "Game Name");
_names[_index] = name;
seek(file, 1, "Level");
_names[_index] = read(file, 45, "Game Name");
delete file;
@ -202,7 +204,7 @@ bool Savegame::check() {
if (!file)
return false;
read(file, 2, "Level and Name");
seek(file, 2, "Level and Name");
bool valid = false;
if (readHeader(file))
@ -231,13 +233,9 @@ bool Savegame::isSavegamePresent(Common::String filename) {
// Reading & writing
//////////////////////////////////////////////////////////////////////////
bool Savegame::readHeader(Common::InSaveFile *file) {
int32 versionLength = 0;
int32 version = 0;
int32 build = 0;
read(file, (byte *)&versionLength, 4, 1, "Version Length");
read(file, (byte *)&version, 4, 1, "Version");
read(file, (byte *)&build, 4, 1, "Build");
uint32 versionLength = read(file, "Version Length");
Common::String version = read(file, versionLength, "Version");
/*uint32 build = */read(file, "Build");
// Original does not do any version check
// TODO check version to make sure we can read the data
@ -248,40 +246,97 @@ bool Savegame::readHeader(Common::InSaveFile *file) {
void Savegame::writeHeader(Common::OutSaveFile *file) {
// We write saved games with a 1.01 final version (build 851)
int length = SAVEGAME_VERSION_SIZE;
int build = SAVEGAME_BUILD;
write(file, (byte *)&length, 4, 1, "Version Length");
write(file, (byte *)&savegame_version, 1, SAVEGAME_VERSION_SIZE, "Version");
write(file, (byte *)&build, 4, 1, "Build");
write(file, SAVEGAME_VERSION_SIZE, "Version Length");
write(file, savegame_version, SAVEGAME_VERSION_SIZE, "Version");
write(file, SAVEGAME_BUILD, "Build");
}
bool Savegame::loadData(Common::String filename) {
//Common::InSaveFile *file = g_system->getSavefileManager()->openForLoading(getFilename(_index));
error("[Savegame::loadData] Not implemented!");
}
bool Savegame::saveData(Common::String filename, Common::String name, ChapterIndex chapter) {
error("[Savegame::saveData] Not implemented!");
Common::OutSaveFile *file = g_system->getSavefileManager()->openForSaving(getFilename(_index));
if (!file)
return false;
write(file, chapter, "Level");
write(file, name, SAVEGAME_NAME_SIZE, "Game Name");
writeHeader(file);
write(file, _vm, 1512, 1, "Game Stats");
write(file, getWorld(), 951928, 1, "World Stats");
write(file, getPuzzleData(), 752, 1, "Blowup Puzzle Data");
write(file, getEncounter()->items(), 109, getEncounter()->items()->size(), "Encounter Data");
write(file, getEncounter()->variables(), 2, getEncounter()->variables()->size(), "Encounter Variables");
if (getWorld()->numScripts)
write(file, getScript(), 7096, getWorld()->numScripts, "Action Lists");
write(file, _vm->getTick(), "Time");
delete file;
return true;
}
void Savegame::read(Common::InSaveFile *file, uint32 size, Common::String description) {
void Savegame::seek(Common::InSaveFile *file, uint32 offset, Common::String description) {
if (offset == 0)
return;
uint32 size = 0;
uint32 count = 0;
for (uint i = 0; i < offset; i++) {
size = file->readUint32LE();
count = file->readUint32LE();
file->seek(size * count, SEEK_CUR);
}
}
uint32 Savegame::read(Common::InSaveFile *file, Common::String description) {
error("[Savegame::read] Not implemented!");
}
void Savegame::read(Common::InSaveFile *file, byte *data, uint32 size, uint32 count, Common::String description) {
Common::String Savegame::read(Common::InSaveFile *file, uint32 strLength, Common::String description) {
error("[Savegame::read] Not implemented!");
}
void Savegame::read(Common::InSaveFile *file, Common::Serializable *data, uint32 size, uint32 count, Common::String description) {
error("[Savegame::read] Not implemented!");
}
void Savegame::write(Common::OutSaveFile *file, byte *data, uint32 size, uint32 count, Common::String description) {
error("[Savegame::write] Not implemented!");
void Savegame::write(Common::OutSaveFile *file, uint32 val, Common::String description) {
file->writeUint32LE(4);
file->writeUint32LE(1);
// Write data
// TODO check for errors
file->writeUint32LE(val);
}
void Savegame::write(Common::OutSaveFile *file, Common::String val, uint32 count, Common::String description) {
file->writeUint32LE(1);
file->writeUint32LE(count);
// Write data
// TODO check for errors
file->writeString(val);
}
void Savegame::write(Common::OutSaveFile *file, Common::Serializable *data, uint32 size, uint32 count, Common::String description) {
error("[Savegame::write] Not implemented!");
file->writeUint32LE(size);
file->writeUint32LE(count);
if (size * count == 0)
return;
Common::Serializer ser(NULL, file);
data->saveLoadWithSerializer(ser);
}
//////////////////////////////////////////////////////////////////////////

View File

@ -175,25 +175,34 @@ private:
bool saveData(Common::String filename, Common::String name, ChapterIndex chapter);
/**
* Reads header data from a file
* Seeks to a specific place in the file
*
* @param [in,out] file If non-null, the file.
* @param size The size.
* @param offset Offset index of the info into the file
* @param description The description.
*/
void read(Common::InSaveFile *file, uint32 size, Common::String description);
void seek(Common::InSaveFile *file, uint32 offset, Common::String description);
/**
* Reads data from a file.
* Reads data from a file.
*
* @param [in,out] file If non-null, the file.
* @param [in,out] data If non-null, the data.
* @param size The size.
* @param count Number of.
* @param description The description.
* @param [in,out] file If non-null, the file.
* @param description The description.
*
* @return the value
*/
void read(Common::InSaveFile *file, byte *data, uint32 size, uint32 count, Common::String description);
uint32 read(Common::InSaveFile *file, Common::String description);
/**
* Reads data from a file.
*
* @param [in,out] file If non-null, the file.
* @param strLength Length of the string.
* @param description The description.
*
* @return the string
*/
Common::String read(Common::InSaveFile *file, uint32 strLength, Common::String description);
/**
* Reads data from a file.
@ -210,12 +219,20 @@ private:
* Writes data to a file.
*
* @param [in,out] file If non-null, the file.
* @param [in,out] data If non-null, the data.
* @param size The size.
* @param count Number of.
* @param val The value
* @param description The description.
*/
void write(Common::OutSaveFile *file, byte *data, uint32 size, uint32 count, Common::String description);
void write(Common::OutSaveFile *file, uint32 val, Common::String description);
/**
* Writes data to a file.
*
* @param [in,out] file If non-null, the file.
* @param val The string
* @param count The size of the string.
* @param description The description.
*/
void write(Common::OutSaveFile *file, Common::String val, uint32 count, Common::String description);
/**
* Writes data to a file.