mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-16 06:49:58 +00:00
3e99ea96a3
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
268 lines
6.2 KiB
C++
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
|