scummvm/saga/saveload.cpp
Torbjörn Andersson 3e99ea96a3 Implemented some trivial IHNM opcodes. I'm not sure if the _ethicsPoints[]
array is large enough though.

These opcodes modify what I assume to be the game state, so that
information needs to be stored in the savegames. Not for ITE, though, so
savegame compatibility is not broken by this. (Not deliberately, at least.)

svn-id: r18885
2005-09-26 07:22:32 +00:00

268 lines
6.2 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2004-2005 The ScummVM project
*
* The ReInherit Engine is (C)2000-2003 by Daniel Balsom.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
#include "common/stdafx.h"
#include "common/config-manager.h"
#include "common/savefile.h"
#include "common/system.h"
#include "common/file.h"
#include "saga/saga.h"
#include "saga/actor.h"
#include "saga/events.h"
#include "saga/interface.h"
#include "saga/isomap.h"
#include "saga/music.h"
#include "saga/render.h"
#include "saga/resnames.h"
#include "saga/scene.h"
#include "saga/script.h"
#define CURRENT_SAGA_VER 3
namespace Saga {
static SaveFileData emptySlot = {
"", 0
};
//TODO:
// - delete savegame
char* SagaEngine::calcSaveFileName(uint slotNumber) {
static char name[MAX_FILE_NAME];
sprintf(name, "%s.s%02d", _targetName.c_str(), slotNumber);
return name;
}
SaveFileData *SagaEngine::getSaveFile(uint idx) {
if (idx >= _saveFilesMaxCount) {
error("getSaveFileName wrong idx");
}
if (isSaveListFull()) {
return &_saveFiles[_saveFilesCount - idx - 1];
} else {
if (!emptySlot.name[0])
strcpy(emptySlot.name, getTextString(kTextNewSave));
return (idx == 0) ? &emptySlot : &_saveFiles[_saveFilesCount - idx];
}
}
bool SagaEngine::locateSaveFile(char *saveName, uint &titleNumber) {
uint i;
for (i = 0; i < _saveFilesCount; i++) {
if (strcmp(saveName, _saveFiles[i].name) == 0) {
if (isSaveListFull()) {
titleNumber = _saveFilesCount - i - 1;
} else {
titleNumber = _saveFilesCount - i;
}
return true;
}
}
return false;
}
uint SagaEngine::getNewSaveSlotNumber() {
uint i, j;
bool found;
if (isSaveListFull()) {
error("getNewSaveSlotNumber save list is full");
}
for (i = 0; i < MAX_SAVES; i++) {
if (_saveMarks[i]) {
found = false;
for (j = 0; j < _saveFilesCount; j++) {
if (_saveFiles[j].slotNumber == i) {
found = true;
break;
}
}
if (!found) {
return i;
}
}
}
error("getNewSaveSlotNumber save list is full");
}
void SagaEngine::fillSaveList() {
int i;
Common::InSaveFile *in;
char *name;
name = calcSaveFileName(MAX_SAVES);
name[strlen(name) - 2] = 0;
_saveFileMan->listSavefiles(name, _saveMarks, MAX_SAVES);
_saveFilesMaxCount = 0;
for (i = 0; i < MAX_SAVES; i++) {
if (_saveMarks[i]) {
_saveFilesMaxCount++;
}
_saveFiles[i].name[0] = 0;
_saveFiles[i].slotNumber = (uint)-1;
}
_saveFilesCount = 0;
i = 0;
while (i < MAX_SAVES) {
if (_saveMarks[i]) {
name = calcSaveFileName(i);
if ((in = _saveFileMan->openForLoading(name)) != NULL) {
in->read(&_saveHeader, sizeof(_saveHeader));
if (_saveHeader.type != MKID('SAGA')) {
error("SagaEngine::load wrong format");
}
strcpy(_saveFiles[_saveFilesCount].name, _saveHeader.name);
_saveFiles[_saveFilesCount].slotNumber = i;
delete in;
_saveFilesCount++;
}
}
i++;
}
/* 4debug
for (i = 0; i < 14; i++) {
sprintf(_saveFiles[i].name,"test%i", i);
_saveFiles[i].slotNumber = i;
}
_saveFilesCount = 14;
_saveFilesMaxCount = 14;
*/
}
void SagaEngine::save(const char *fileName, const char *saveName) {
Common::OutSaveFile *out;
if (!(out = _saveFileMan->openForSaving(fileName))) {
return;
}
_saveHeader.type = MKID('SAGA');
_saveHeader.size = 0;
_saveHeader.version = TO_LE_32(CURRENT_SAGA_VER);
strncpy(_saveHeader.name, saveName, SAVE_TITLE_SIZE);
out->write(&_saveHeader, sizeof(_saveHeader));
// Surrounding scene
out->writeSint32LE(_scene->getOutsetSceneNumber());
// Inset scene
out->writeSint32LE(_scene->currentSceneNumber());
if (getGameType() != GType_ITE) {
out->writeUint32LE(_globalFlags);
for (int i = 0; i < ARRAYSIZE(_ethicsPoints); i++)
out->writeByte(_ethicsPoints[i]);
}
_interface->saveState(out);
_actor->saveState(out);
out->writeSint16LE(_script->_commonBufferSize);
out->write(_script->_commonBuffer, _script->_commonBufferSize);
out->writeSint16LE(_isoMap->getMapPosition().x);
out->writeSint16LE(_isoMap->getMapPosition().y);
delete out;
}
void SagaEngine::load(const char *fileName) {
Common::InSaveFile *in;
int commonBufferSize;
int sceneNumber, insetSceneNumber;
int mapx, mapy;
if (!(in = _saveFileMan->openForLoading(fileName))) {
return;
}
in->read(&_saveHeader, sizeof(_saveHeader));
_saveHeader.size = FROM_LE_32(_saveHeader.size);
_saveHeader.version = FROM_LE_32(_saveHeader.version);
if (_saveHeader.type != MKID('SAGA')) {
error("SagaEngine::load wrong format");
}
// Surrounding scene
sceneNumber = in->readSint32LE();
// Inset scene
insetSceneNumber = in->readSint32LE();
if (getGameType() != GType_ITE) {
_globalFlags = in->readUint32LE();
for (int i = 0; i < ARRAYSIZE(_ethicsPoints); i++)
_ethicsPoints[i] = in->readByte();
}
_interface->loadState(in);
_actor->loadState(in);
commonBufferSize = in->readSint16LE();
in->read(_script->_commonBuffer, commonBufferSize);
mapx = in->readSint16LE();
mapy = in->readSint16LE();
delete in;
// Mute volume to prevent outScene music play
int volume = _music->getVolume();
_music->setVolume(0);
_isoMap->setMapPosition(mapx, mapy);
_scene->clearSceneQueue();
_scene->changeScene(sceneNumber, ACTOR_NO_ENTRANCE, kTransitionNoFade);
_events->handleEvents(0); //dissolve backgrounds
if (insetSceneNumber != sceneNumber) {
_render->setFlag(RF_DISABLE_ACTORS);
_render->drawScene();
_render->clearFlag(RF_DISABLE_ACTORS);
_scene->changeScene(insetSceneNumber, ACTOR_NO_ENTRANCE, kTransitionNoFade);
}
_music->setVolume(volume);
_interface->draw();
}
} // End of namespace Saga