diff options
| author | Sven Hesse | 2008-05-10 20:59:43 +0000 | 
|---|---|---|
| committer | Sven Hesse | 2008-05-10 20:59:43 +0000 | 
| commit | 257aaa3ced14645d4410a272e89cafb7282836ac (patch) | |
| tree | bfe6be04b32b7d40d3096fa2e14f49625a7f8b25 | |
| parent | b2defd0eac9401ffeea91ef0154650e108ffc179 (diff) | |
| download | scummvm-rg350-257aaa3ced14645d4410a272e89cafb7282836ac.tar.gz scummvm-rg350-257aaa3ced14645d4410a272e89cafb7282836ac.tar.bz2 scummvm-rg350-257aaa3ced14645d4410a272e89cafb7282836ac.zip | |
Restructured saving/loading and added a stub for Woodruff
svn-id: r31989
| -rw-r--r-- | engines/gob/gob.cpp | 3 | ||||
| -rw-r--r-- | engines/gob/gob.h | 5 | ||||
| -rw-r--r-- | engines/gob/inter_v2.cpp | 31 | ||||
| -rw-r--r-- | engines/gob/module.mk | 1 | ||||
| -rw-r--r-- | engines/gob/saveload.cpp | 724 | ||||
| -rw-r--r-- | engines/gob/saveload.h | 364 | ||||
| -rw-r--r-- | engines/gob/saveload_v2.cpp | 403 | ||||
| -rw-r--r-- | engines/gob/saveload_v3.cpp | 677 | ||||
| -rw-r--r-- | engines/gob/saveload_v4.cpp | 80 | ||||
| -rw-r--r-- | engines/gob/video.h | 7 | 
10 files changed, 1460 insertions, 835 deletions
| diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index ed2fe0fc15..41f268eba2 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -89,6 +89,7 @@ GobEngine::GobEngine(OSystem *syst) : Engine(syst) {  	Common::addSpecialDebugLevel(kDebugParser, "Parser", "Parser debug level");  	Common::addSpecialDebugLevel(kDebugGameFlow, "Gameflow", "Gameflow debug level");  	Common::addSpecialDebugLevel(kDebugFileIO, "FileIO", "File Input/Output debug level"); +	Common::addSpecialDebugLevel(kDebugSaveLoad, "SaveLoad", "Saving/Loading debug level");  	Common::addSpecialDebugLevel(kDebugGraphics, "Graphics", "Graphics debug level");  	Common::addSpecialDebugLevel(kDebugCollisions, "Collisions", "Collisions debug level"); @@ -353,7 +354,7 @@ bool GobEngine::initGameParts() {  			_map = new Map_v4(this);  			_goblin = new Goblin_v4(this);  			_scenery = new Scenery_v2(this); -			_saveLoad = new SaveLoad_v3(this, _targetName.c_str()); +			_saveLoad = new SaveLoad_v4(this, _targetName.c_str());  			break;  		default: diff --git a/engines/gob/gob.h b/engines/gob/gob.h index e1d75bd2a4..0a82bceed5 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -104,8 +104,9 @@ enum {  	kDebugParser = 1 << 4,  	kDebugGameFlow = 1 << 5,  	kDebugFileIO = 1 << 6, -	kDebugGraphics = 1 << 7, -	kDebugCollisions = 1 << 8 +	kDebugSaveLoad = 1 << 7, +	kDebugGraphics = 1 << 8, +	kDebugCollisions = 1 << 9  };  inline char *strncpy0(char *dest, const char *src, size_t n) { diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 36f33e6553..6f261e9822 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -1911,7 +1911,7 @@ bool Inter_v2::o2_checkData(OpFuncParams ¶ms) {  	int16 handle;  	int16 varOff;  	int32 size; -	SaveType type; +	SaveLoad::SaveMode mode;  	evalExpr(0);  	varOff = _vm->_parse->parseVarIndex(); @@ -1919,8 +1919,8 @@ bool Inter_v2::o2_checkData(OpFuncParams ¶ms) {  	size = -1;  	handle = 1; -	type = _vm->_saveLoad->getSaveType(_vm->_global->_inter_resStr); -	if (type == kSaveNone) { +	mode = _vm->_saveLoad->getSaveMode(_vm->_global->_inter_resStr); +	if (mode == SaveLoad::kSaveModeNone) {  		handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr);  		if (handle >= 0) { @@ -1928,8 +1928,8 @@ bool Inter_v2::o2_checkData(OpFuncParams ¶ms) {  			size = _vm->_dataIO->getDataSize(_vm->_global->_inter_resStr);  		} else  			warning("File \"%s\" not found", _vm->_global->_inter_resStr); -	} else -		size = _vm->_saveLoad->getSize(type); +	} else if (mode == SaveLoad::kSaveModeSave) +		size = _vm->_saveLoad->getSize(_vm->_global->_inter_resStr);  	if (size == -1)  		handle = -1; @@ -1950,7 +1950,7 @@ bool Inter_v2::o2_readData(OpFuncParams ¶ms) {  	int16 dataVar;  	int16 handle;  	byte *buf; -	SaveType type; +	SaveLoad::SaveMode mode;  	evalExpr(0);  	dataVar = _vm->_parse->parseVarIndex(); @@ -1962,13 +1962,14 @@ bool Inter_v2::o2_readData(OpFuncParams ¶ms) {  	debugC(2, kDebugFileIO, "Read from file \"%s\" (%d, %d bytes at %d)",  			_vm->_global->_inter_resStr, dataVar, size, offset); -	type = _vm->_saveLoad->getSaveType(_vm->_global->_inter_resStr); -	if (type != kSaveNone) { +	mode = _vm->_saveLoad->getSaveMode(_vm->_global->_inter_resStr); +	if (mode == SaveLoad::kSaveModeSave) {  		WRITE_VAR(1, 1); -		if (_vm->_saveLoad->load(type, dataVar, size, offset)) +		if (_vm->_saveLoad->load(_vm->_global->_inter_resStr, dataVar, size, offset))  			WRITE_VAR(1, 0);  		return false; -	} +	} else if (mode == SaveLoad::kSaveModeIgnore) +		return false;  	if (size < 0) {  		warning("Attempted to read a raw sprite from file \"%s\"", @@ -2021,7 +2022,7 @@ bool Inter_v2::o2_writeData(OpFuncParams ¶ms) {  	int32 offset;  	int32 size;  	int16 dataVar; -	SaveType type; +	SaveLoad::SaveMode mode;  	evalExpr(0);  	dataVar = _vm->_parse->parseVarIndex(); @@ -2034,11 +2035,11 @@ bool Inter_v2::o2_writeData(OpFuncParams ¶ms) {  	WRITE_VAR(1, 1); -	type = _vm->_saveLoad->getSaveType(_vm->_global->_inter_resStr); -	if (type != kSaveNone) { -		if (_vm->_saveLoad->save(type, dataVar, size, offset)) +	mode = _vm->_saveLoad->getSaveMode(_vm->_global->_inter_resStr); +	if (mode == SaveLoad::kSaveModeSave) { +		if (_vm->_saveLoad->save(_vm->_global->_inter_resStr, dataVar, size, offset))  			WRITE_VAR(1, 0); -	} else +	} else if (mode == SaveLoad::kSaveModeNone)  		warning("Attempted to write to file \"%s\"", _vm->_global->_inter_resStr);  	return false; diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 09664f15b4..c95391cedc 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -44,6 +44,7 @@ MODULE_OBJS := \  	saveload.o \  	saveload_v2.o \  	saveload_v3.o \ +	saveload_v4.o \  	scenery.o \  	scenery_v1.o \  	scenery_v2.o \ diff --git a/engines/gob/saveload.cpp b/engines/gob/saveload.cpp index 717bc143a6..e0854151a0 100644 --- a/engines/gob/saveload.cpp +++ b/engines/gob/saveload.cpp @@ -24,456 +24,493 @@   */  #include "common/endian.h" -#include "common/file.h" +#include "common/savefile.h"  #include "gob/gob.h"  #include "gob/saveload.h" -#include "gob/global.h"  #include "gob/draw.h" -#include "gob/video.h"  namespace Gob { -SaveLoad::SaveLoad(GobEngine *vm, const char *targetName) : _vm(vm) { -	_curSlot = -1; +TempSprite::TempSprite() { +	_sprite = 0; +	_width = _height = 0; +	_size = -1; +	memset(_palette, 0, 768); +} -	_stagesCount = 0; -	_buffer = 0; +TempSprite::~TempSprite() { +	delete[] _sprite; +} -	_tempSprite = 0; -	memset(_tempPal, 0, 768); -	_tempSpriteSize = -1; +int TempSprite::getSpriteIndex(int32 size) const { +	if (size < -1000) +		size += 1000; -	_saveFiles = new char*[5]; +	return -size - 1; +} -	assert(_saveFiles); +bool TempSprite::getSpritePalette(int32 size) const { +	return size < -1000; +} -	_saveFiles[0] = new char[strlen(targetName) + 5]; -	_saveFiles[1] = 0; -	_saveFiles[2] = new char[strlen(targetName) + 5]; -	_saveFiles[3] = _saveFiles[0]; -	_saveFiles[4] = 0; +bool TempSprite::getProperties(int16 dataVar, int32 size, int32 offset, +		int &index, bool &palette) const { -	assert(_saveFiles[0] && _saveFiles[2]); +	if (size >= 0) { +		warning("Invalid index (%d)", size); +		return false; +	} -	sprintf(_saveFiles[0], "%s.s00", targetName); -	sprintf(_saveFiles[2], "%s.blo", targetName); -} +	index = getSpriteIndex(size); +	palette = getSpritePalette(size); -SaveLoad::~SaveLoad() { -	if (_buffer) { -		for (int i = 0; i < _stagesCount; i++) -			delete[] _buffer[i]; -		delete[] _buffer; +	if ((index < 0) || (index >= SPRITES_COUNT)) { +		warning("Index out of range (%d)", index); +		return false;  	} -	delete _tempSprite; +	return true; +} -	delete[] _saveFiles[0]; -	delete[] _saveFiles[2]; -	delete[] _saveFiles; +int32 TempSprite::getSize() const { +	return _size;  } -const char *SaveLoad::setCurSlot(int slot) { -	static char *slotBase = _saveFiles[0] + strlen(_saveFiles[0]) - 2; +bool TempSprite::saveSprite(const SurfaceDesc &surfDesc) { +	delete[] _sprite; -	if (_curSlot != slot) { -		_curSlot = slot; +	_width = surfDesc.getWidth(); +	_height = surfDesc.getHeight(); +	_size = _width * _height; +	_sprite = new byte[_size]; -		if (_curSlot >= 0) -			snprintf(slotBase, 3, "%02d", slot); -	} +	memcpy(_sprite, surfDesc.getVidMem(), _size); -	return _saveFiles[0]; +	return true;  } -uint32 SaveLoad::read(Common::ReadStream &in, byte *buf, -		byte *sizes, uint32 count) { -	uint32 nRead; +bool TempSprite::savePalette(const Video::Color *palette) { +	memcpy((byte *) _palette, (byte *) palette, 768); +	return true; +} -	nRead = in.read(buf, count); -	if (nRead != count) { -		warning("Can't read data: requested %d, got %d", count, nRead); -		return 0; +bool TempSprite::loadSprite(SurfaceDesc &surfDesc) { +	if (!_sprite) { +		warning("No sprite saved"); +		return false;  	} -	nRead = in.read(sizes, count); -	if (nRead != count) { -		warning("Can't read data sizes: requested %d, got %d", count, nRead); -		return 0; +	if (_size != (surfDesc.getWidth() * surfDesc.getHeight())) { +		warning("Dimensions don't match (%dx%d - %dx%d", +				_width, _height, surfDesc.getWidth(), surfDesc.getHeight()); +		return false;  	} -	return count; +	memcpy(surfDesc.getVidMem(), _sprite, _size); + +	return true;  } -uint32 SaveLoad::write(Common::WriteStream &out, byte *buf, -		byte *sizes, uint32 count) { -	uint32 written; +bool TempSprite::loadPalette(Video::Color *palette) { +	memcpy((byte *) palette, (byte *) _palette, 768); +	return true; +} -	written = out.write(buf, count); -	if (written != count) { -		warning("Can't write data: requested %d, wrote %d", count, written); -		return 0; +bool TempSprite::toBuffer(byte *buffer, int32 size, bool palette) const { + +	int32 haveSize = _size + (palette ? 768 : 0); +	if (size != haveSize) { +		warning("Sizes don't match (%d != %d)", size, haveSize); +		return false;  	} -	written = out.write(sizes, count); -	if (written != count) { -		warning("Can't write data: requested %d, wrote %d", count, written); -		return 0; +	if (palette) { +		memcpy(buffer, (byte *) _palette, 768); +		buffer += 768;  	} -	return count; +	memcpy(buffer, _sprite, _size); + +	return true;  } -bool SaveLoad::loadDataEndian(Common::ReadStream &in, -		int16 dataVar, uint32 size) { +bool TempSprite::fromBuffer(const byte *buffer, int32 size, bool palette) { +	if (palette) { +		memcpy((byte *) _palette, buffer, 768); +		buffer += 768; +		size -= 768; +	} -	bool retVal = false; +	_size = size; -	byte *varBuf = new byte[size]; -	byte *sizeBuf = new byte[size]; +	delete[] _sprite; +	_sprite = new byte[_size]; -	assert(varBuf && sizeBuf); +	memcpy(_sprite, buffer, _size); -	if (read(in, varBuf, sizeBuf, size) == size) { -		if (fromEndian(varBuf, sizeBuf, size)) { -			memcpy(_vm->_global->_inter_variables + dataVar, varBuf, size); -			memcpy(_vm->_global->_inter_variablesSizes + dataVar, sizeBuf, size); -			retVal = true; -		} -	} +	return true; +} -	delete[] varBuf; -	delete[] sizeBuf; -	return retVal; +PlainSave::PlainSave() {  } -bool SaveLoad::saveDataEndian(Common::WriteStream &out, -		int16 dataVar, uint32 size) { +PlainSave::~PlainSave() { +} -	bool retVal = false; +bool PlainSave::save(int16 dataVar, int32 size, int32 offset, const char *name, +		const byte *variables, const byte *variableSizes) const { -	byte *varBuf = new byte[size]; -	byte *sizeBuf = new byte[size]; +	if ((size <= 0) || (offset != 0)) { +		warning("Invalid size (%d) or offset (%d)", size, offset); +		return false; +	} -	assert(varBuf && sizeBuf); +	Common::SaveFileManager *saveMan = g_system->getSavefileManager(); +	Common::OutSaveFile *out = saveMan->openForSaving(name); -	memcpy(varBuf, _vm->_global->_inter_variables + dataVar, size); -	memcpy(sizeBuf, _vm->_global->_inter_variablesSizes + dataVar, size); +	if (!out) { +		warning("Can't open file \"%s\" for writing", name); +		return false; +	} -	if (toEndian(varBuf, sizeBuf, size)) -		if (write(out, varBuf, sizeBuf, size) == size) -			retVal = true; +	bool retVal; +	retVal = SaveLoad::saveDataEndian(*out, dataVar, size, variables, variableSizes); -	delete[] varBuf; -	delete[] sizeBuf; +	out->finalize(); +	if (out->ioFailed()) { +		warning("Can't write to file \"%s\"", name); +		retVal = false; +	} +	delete out;  	return retVal;  } -int32 SaveLoad::getSize(SaveType type) { -	switch (type) { -	case kSaveNone: -		return -1; -		break; - -	case kSaveGame: -		return getSizeGame(); -		break; +bool PlainSave::load(int16 dataVar, int32 size, int32 offset, const char *name, +		byte *variables, byte *variableSizes) const { -	case kSaveTempSprite: -		return getSizeTempSprite(); -		break; - -	case kSaveNotes: -		return getSizeNotes(); -		break; +	if ((size <= 0) || (offset != 0)) { +		warning("Invalid size (%d) or offset (%d)", size, offset); +		return false; +	} -	case kSaveScreenshot: -		return getSizeScreenshot(); -		break; +	Common::SaveFileManager *saveMan = g_system->getSavefileManager(); +	Common::InSaveFile *in = saveMan->openForLoading(name); -	case kSaveIgnore: -		return -1; -		break; +	if (!in) { +		warning("Can't open file \"%s\" for reading", name); +		return false;  	} -	return -1; +	bool retVal = SaveLoad::loadDataEndian(*in, dataVar, size, variables, variableSizes); +	delete in; +	return retVal;  } -bool SaveLoad::load(SaveType type, int16 dataVar, int32 size, int32 offset) { -	switch (type) { -	case kSaveNone: -		return false; -		break; - -	case kSaveGame: -		return loadGame(dataVar, size, offset); -		break; -	case kSaveTempSprite: -		return loadTempSprite(dataVar, size, offset); -		break; +StagedSave::StagedSave() { +	_mode = kModeNone; +	_name = 0; +	_loaded = false; +} -	case kSaveNotes: -		return loadNotes(dataVar, size, offset); -		break; +StagedSave::~StagedSave() { +	clear(); +} -	case kSaveScreenshot: -		return loadScreenshot(dataVar, size, offset); -		break; +void StagedSave::addStage(int32 size, bool endianed) { +	int32 offset = 0; -	case kSaveIgnore: -		return true; -		break; -	} +	if (!_stages.empty()) +		offset = _stages[_stages.size() - 1].offset + +		         _stages[_stages.size() - 1].size; -	return false; +	Stage stage(size, offset, endianed); +	_stages.push_back(stage);  } -bool SaveLoad::save(SaveType type, int16 dataVar, int32 size, int32 offset) { -	switch (type) { -	case kSaveNone: -		return false; -		break; +int StagedSave::findStage(int16 dataVar, int32 size, int32 offset) const { +	for (uint i = 0; i < _stages.size(); i++) +		if ((_stages[i].size == size) && +		    (_stages[i].offset == offset)) +			return i; + +	return -1; +} -	case kSaveGame: -		return saveGame(dataVar, size, offset); -		break; +bool StagedSave::allSaved() const { +	for (uint i = 0; i < _stages.size(); i++) +		if (!_stages[i].bufVar) +			return false; -	case kSaveTempSprite: -		return saveTempSprite(dataVar, size, offset); -		break; +	return true; +} -	case kSaveNotes: -		return saveNotes(dataVar, size, offset); -		break; +uint32 StagedSave::getSize() const { +	uint32 size = 0; -	case kSaveScreenshot: -		return saveScreenshot(dataVar, size, offset); -		break; +	for (uint i = 0; i < _stages.size(); i++) { +		if (_stages[i].endianed) +			size += 2 * _stages[i].size; +		else +			size += _stages[i].size; +	} +	 +	return size; +} -	case kSaveIgnore: -		return true; -		break; +void StagedSave::clear() { +	for (uint i = 0; i < _stages.size(); i++) { +		delete[] _stages[i].bufVar; +		delete[] _stages[i].bufVarSizes; +		_stages[i].bufVar = 0; +		_stages[i].bufVarSizes = 0;  	} -	return false; +	delete[] _name; +	_name = 0; + +	_mode = kModeNone; +	_loaded = false;  } -int32 SaveLoad::getSizeTempSprite() { -	return _tempSpriteSize; +void StagedSave::assertMode(Mode mode, const char *name) { +	if ((_mode != mode) || ((name[0] != '\0') && strcmp(_name, name))) { +		clear(); +		_mode = mode; +		_name = new char[strlen(name) + 1]; +		strcpy(_name, name); +	}  } -bool SaveLoad::loadTempSprite(int16 dataVar, int32 size, int32 offset) { -	int index; -	bool readPal; +bool StagedSave::save(int16 dataVar, int32 size, int32 offset, const char *name, +		const byte *variables, const byte *variableSizes) { -	if (size >= 0) { -		warning("Invalid attempt at loading from the temporary sprite"); +	if ((dataVar < 0) || (size <= 0) || (offset < 0)) { +		warning("Invalid dataVar (%d), size (%d) or offset (%d)", dataVar, size, offset);  		return false;  	} -	index = getSpriteIndex(size); -	readPal = getSpritePalette(size); +	int stage = findStage(dataVar, size, offset); +	if (stage == -1) { +		warning("Invalid saving procedure"); +		return false; +	} -	if ((index < 0) || (index >= SPRITES_COUNT)) { -		warning("Index out of range while loading from the temporary " -				"sprite (%d)", index); +	if (!variables || (_stages[stage].endianed && !variableSizes)) { +		warning("Missing data");  		return false;  	} -	return loadTempSprite(index, readPal); -} +	assertMode(kModeSave, name); -bool SaveLoad::saveTempSprite(int16 dataVar, int32 size, int32 offset) { -	int index; -	bool readPal; +	_stages[stage].bufVar = new byte[size]; +	memcpy(_stages[stage].bufVar, variables + dataVar, size); -	if (size >= 0) { -		warning("Invalid attempt at saving to the temporary sprite"); -		return false; +	if (_stages[stage].endianed) { +		_stages[stage].bufVarSizes = new byte[size]; +		memcpy(_stages[stage].bufVarSizes, variableSizes + dataVar, size);  	} -	index = getSpriteIndex(size); -	readPal = getSpritePalette(size); - -	if ((index < 0) || (index >= SPRITES_COUNT)) { -		warning("Index out of range while saving to the temporary sprite (%d)", -				index); -		return false; +	if (allSaved()) { +		bool result = write(); +		clear(); +		return result;  	} -	return saveTempSprite(index, readPal); +	return true;  } -bool SaveLoad::loadTempSprite(uint32 index, bool palette) { -	SurfaceDesc *sprite; +bool StagedSave::load(int16 dataVar, int32 size, int32 offset, const char *name, +		byte *variables, byte *variableSizes) { -	if (palette) { -		memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal, -				(char *) _tempPal, 768); -		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); -	} - -	sprite = _vm->_draw->_spritesArray[index]; - -	if (!sprite) { -		warning("Couldn't load from the temporary sprite: " -				"No such sprite %d", index); +	if ((dataVar < 0) || (size <= 0) || (offset < 0)) { +		warning("Invalid dataVar (%d), size (%d) or offset (%d)", dataVar, size, offset);  		return false;  	} -	if ((sprite->getWidth() != _tempSprite->getWidth()) || -			(sprite->getHeight() != _tempSprite->getHeight())) { -		warning("Resolution doesn't match while loading from the " -				"temporary sprite (%d: %dx%d vs. %dx%d)", index, -				sprite->getWidth(), sprite->getHeight(), -				_tempSprite->getWidth(), _tempSprite->getHeight()); +	int stage = findStage(dataVar, size, offset); +	if (stage == -1) { +		warning("Invalid loading procedure");  		return false;  	} -	_vm->_video->drawSprite(_tempSprite, sprite, 0, 0, -			sprite->getWidth() - 1, sprite->getHeight() - 1, 0, 0, 0); +	assertMode(kModeLoad, name); -	if (index == 21) { -		_vm->_draw->forceBlit(); -		_vm->_video->retrace(); +	if (!_loaded) { +		if (!read()) { +			clear(); +			return false; +		}  	} +	if (variables) +		memcpy(variables + dataVar, _stages[stage].bufVar, size); +	if (_stages[stage].endianed && variableSizes) +		memcpy(variableSizes + dataVar, _stages[stage].bufVarSizes, size); +  	return true;  } -bool SaveLoad::saveTempSprite(uint32 index, bool palette) { -	SurfaceDesc *sprite = _vm->_draw->_spritesArray[index]; +bool StagedSave::write() const { +	Common::SaveFileManager *saveMan = g_system->getSavefileManager(); +	Common::OutSaveFile *out = saveMan->openForSaving(_name); -	if (!sprite) { -		warning("Couldn't save to the temporary sprite: " -				"No such sprite %d", index); +	if (!out) { +		warning("Can't open file \"%s\" for writing", _name);  		return false;  	} -	delete _tempSprite; -	_tempSprite = _vm->_video->initSurfDesc(_vm->_global->_videoMode, -			sprite->getWidth(), sprite->getHeight(), 0); +	bool result = true; +	for (uint i = 0; (i < _stages.size()) && result; i++) { +		if (!_stages[i].endianed) { -	_vm->_video->drawSprite(sprite, _tempSprite, 0, 0, -			sprite->getWidth() - 1, sprite->getHeight() - 1, 0, 0, 0); +			uint32 written = out->write(_stages[i].bufVar, _stages[i].size); -	_tempSpriteSize = _vm->_draw->getSpriteRectSize(index); +			result = (written == ((uint32) _stages[i].size)); +			if (!result) +				warning("Can't write data: requested %d, wrote %d", _stages[i].size, written); -	if (palette) { -		memcpy((char *) _tempPal, -				(char *) _vm->_global->_pPaletteDesc->vgaPal, 768); -		_tempSpriteSize += 768; +		} else +			result = SaveLoad::saveDataEndian(*out, 0, _stages[i].size, +					_stages[i].bufVar, _stages[i].bufVarSizes);  	} -	return true; +	if (result) { +		out->finalize(); +		if (out->ioFailed()) { +			warning("Can't write to file \"%s\"", _name); +			result = false; +		} +	} + +	delete out; +	return result;  } -bool SaveLoad::loadSprite(Common::ReadStream &in, int32 size) { -	SurfaceDesc *sprite; -	byte *buf; -	int nRead; -	int index; -	bool readPal; +bool StagedSave::read() { +	Common::SaveFileManager *saveMan = g_system->getSavefileManager(); +	Common::InSaveFile *in = saveMan->openForLoading(_name); -	if (size >= 0) { -		warning("Invalid attempt at loading a sprite"); +	if (!in) { +		warning("Can't open file \"%s\" for reading", _name);  		return false;  	} -	index = getSpriteIndex(size); -	readPal = getSpritePalette(size); - -	if ((index < 0) || (index >= SPRITES_COUNT)) { -		warning("Index out of range while loading a sprite (%d)", -				index); +	uint32 saveSize = getSize(); +	if (in->size() != saveSize) { +		warning("Wrong size (%d != %d)", in->size(), saveSize);  		return false;  	} -	size = _vm->_draw->getSpriteRectSize(index); -	sprite = _vm->_draw->_spritesArray[index]; +	bool result = true; +	for (uint i = 0; ((i < _stages.size()) && result); i++) { +		_stages[i].bufVar = new byte[_stages[i].size]; -	if (!sprite) { -		warning("Couldn't load sprite: No such sprite %d", index); -		return false; -	} +		if (!_stages[i].endianed) { -	buf = new byte[MAX<int>(768, size)]; -	assert(buf); +			uint32 nRead = in->read(_stages[i].bufVar, _stages[i].size); -	if (readPal) { -		nRead = in.read(buf, 768); -		if (nRead != 768) { -			warning("Couldn't read a palette: requested 768, got %d", nRead); -			delete[] buf; -			return false; -		} +			result = (nRead == ((uint32) _stages[i].size)); +			if (!result) +				warning("Can't read data: requested %d, got %d", _stages[i].size, nRead); -		memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal, -				(char *) buf, 768); -		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); -	} +		} else { +			_stages[i].bufVarSizes = new byte[_stages[i].size]; -	nRead = in.read(buf, size); -	if (nRead != size) { -		warning("Couldn't read sprite data: requested %d, got %d", size, nRead); -		delete[] buf; -		return false; +			result = SaveLoad::loadDataEndian(*in, 0, _stages[i].size, +					_stages[i].bufVar, _stages[i].bufVarSizes); +		}  	} -	memcpy((char *) sprite->getVidMem(), buf, size); +	if (result) +		_loaded = true; -	delete[] buf; -	return true; +	delete in; +	return result;  } -bool SaveLoad::saveSprite(Common::WriteStream &out, int32 size) { -	SurfaceDesc *sprite; -	int written; -	int index; -	bool readPal; -	if (size >= 0) { -		warning("Invalid attempt at saving a sprite"); -		return false; -	} +SaveLoad::SaveLoad(GobEngine *vm, const char *targetName) : _vm(vm) { -	index = getSpriteIndex(size); -	readPal = getSpritePalette(size); +	_targetName = new char[strlen(targetName) + 1]; +	strcpy(_targetName, targetName); +} -	if ((index < 0) || (index >= SPRITES_COUNT)) { -		warning("Index out of range while saving a sprite (%d)", -				index); -		return false; -	} +SaveLoad::~SaveLoad() { +	delete[] _targetName; +} + +int32 SaveLoad::getSize(const char *fileName) { +	int type; + +	type = getSaveType(stripPath(fileName)); +	if (type == -1) +		return -1; + +	debugC(3, kDebugSaveLoad, "Requested size of save file \"%s\" (type %d)", +			fileName, type); + +	return getSizeVersioned(type); +} -	size = _vm->_draw->getSpriteRectSize(index); -	sprite = _vm->_draw->_spritesArray[index]; +bool SaveLoad::load(const char *fileName, int16 dataVar, int32 size, int32 offset) { +	int type; -	if (!sprite) { -		warning("Couldn't save sprite: No such sprite %d", index); +	type = getSaveType(stripPath(fileName)); +	if (type == -1)  		return false; -	} -	if (readPal) { -		written = out.write((char *) _vm->_global->_pPaletteDesc->vgaPal, 768); -		if (written != 768) { -			warning("Couldn't write a palette: requested 768, wrote %d", written); -			return false; -		} -	} +	debugC(3, kDebugSaveLoad, "Requested loading of save file \"%s\" (type %d) - %d, %d, %d", +			fileName, type, dataVar, size, offset); -	written = out.write((char *) sprite->getVidMem(), size); -	if (written != size) { -		warning("Couldn't write a sprite: requested %d, wrote %d", -				size, written); +	return loadVersioned(type, dataVar, size, offset); +} + +bool SaveLoad::save(const char *fileName, int16 dataVar, int32 size, int32 offset) { +	int type; + +	type = getSaveType(stripPath(fileName)); +	if (type == -1)  		return false; -	} -	return true; +	debugC(3, kDebugSaveLoad, "Requested saving of save file \"%s\" (type %d) - %d, %d, %d", +			fileName, type, dataVar, size, offset); + +	return saveVersioned(type, dataVar, size, offset); +} + +const char *SaveLoad::stripPath(const char *fileName) { +	const char *backSlash; +	if ((backSlash = strrchr(fileName, '\\'))) +		return backSlash + 1; + +	return fileName; +} + +char *SaveLoad::setCurrentSlot(char *destName, int slot) { +	char *slotBase = destName + strlen(destName) - 2; + +	snprintf(slotBase, 3, "%02d", slot); + +	return destName; +} + +void SaveLoad::buildIndex(byte *buffer, char *name, int n, int32 size, int32 offset) { +	Common::SaveFileManager *saveMan = g_system->getSavefileManager(); +	Common::InSaveFile *in; + +	for (int i = 0; i < n; i++, buffer += size) { +		in = saveMan->openForLoading(setCurrentSlot(name, i)); +		if (in) { +			in->seek(offset); +			in->read(buffer, size); +			delete in; +		} else +			memset(buffer, 0, size); +	}  }  bool SaveLoad::fromEndian(byte *buf, const byte *sizes, uint32 count) { @@ -514,4 +551,89 @@ bool SaveLoad::toEndian(byte *buf, const byte *sizes, uint32 count) {  	return true;  } +uint32 SaveLoad::read(Common::ReadStream &in, +		byte *buf, byte *sizes, uint32 count) { +	uint32 nRead; + +	nRead = in.read(buf, count); +	if (nRead != count) { +		warning("Can't read data: requested %d, got %d", count, nRead); +		return 0; +	} + +	nRead = in.read(sizes, count); +	if (nRead != count) { +		warning("Can't read data sizes: requested %d, got %d", count, nRead); +		return 0; +	} + +	return count; +} + +uint32 SaveLoad::write(Common::WriteStream &out, +		const byte *buf, const byte *sizes, uint32 count) { +	uint32 written; + +	written = out.write(buf, count); +	if (written != count) { +		warning("Can't write data: requested %d, wrote %d", count, written); +		return 0; +	} + +	written = out.write(sizes, count); +	if (written != count) { +		warning("Can't write data: requested %d, wrote %d", count, written); +		return 0; +	} + +	return count; +} + +bool SaveLoad::loadDataEndian(Common::ReadStream &in, +		int16 dataVar, uint32 size, byte *variables, byte *variableSizes) { + +	bool retVal = false; + +	byte *varBuf = new byte[size]; +	byte *sizeBuf = new byte[size]; + +	assert(varBuf && sizeBuf); + +	if (read(in, varBuf, sizeBuf, size) == size) { +		if (fromEndian(varBuf, sizeBuf, size)) { +			memcpy(variables + dataVar, varBuf, size); +			memcpy(variableSizes + dataVar, sizeBuf, size); +			retVal = true; +		} +	} + +	delete[] varBuf; +	delete[] sizeBuf; + +	return retVal; +} + +bool SaveLoad::saveDataEndian(Common::WriteStream &out, +		int16 dataVar, uint32 size, const byte *variables, const byte *variableSizes) { + +	bool retVal = false; + +	byte *varBuf = new byte[size]; +	byte *sizeBuf = new byte[size]; + +	assert(varBuf && sizeBuf); + +	memcpy(varBuf, variables + dataVar, size); +	memcpy(sizeBuf, variableSizes + dataVar, size); + +	if (toEndian(varBuf, sizeBuf, size)) +		if (write(out, varBuf, sizeBuf, size) == size) +			retVal = true; + +	delete[] varBuf; +	delete[] sizeBuf; + +	return retVal; +} +  } // End of namespace Gob diff --git a/engines/gob/saveload.h b/engines/gob/saveload.h index bf1e4c01a8..9b032cc73f 100644 --- a/engines/gob/saveload.h +++ b/engines/gob/saveload.h @@ -26,143 +26,317 @@  #ifndef GOB_SAVELOAD_H  #define GOB_SAVELOAD_H +#include "common/array.h"  #include "common/stream.h"  #include "gob/video.h"  namespace Gob { -enum SaveType { -	kSaveNone = -1, -	kSaveGame, -	kSaveTempSprite, -	kSaveNotes, -	kSaveScreenshot, -	kSaveIgnore +class TempSprite { +public: +	TempSprite(); +	~TempSprite(); + +	bool getProperties(int16 dataVar, int32 size, int32 offset, +			int &index, bool &palette) const; + +	int32 getSize() const; + +	bool saveSprite(const SurfaceDesc &surfDesc); +	bool savePalette(const Video::Color *palette); +	bool loadSprite(SurfaceDesc &surfDesc); +	bool loadPalette(Video::Color *palette); + +	bool toBuffer(byte *buffer, int32 size, bool palette) const; +	bool fromBuffer(const byte *buffer, int32 size, bool palette); +	 +private: +	byte *_sprite; +	int16 _width; +	int16 _height; +	int32 _size; +	Video::Color _palette[256]; + +	int getSpriteIndex(int32 size) const; +	bool getSpritePalette(int32 size) const;  }; -class SaveLoad { +class PlainSave { +public: +	PlainSave(); +	~PlainSave(); + +	bool save(int16 dataVar, int32 size, int32 offset, const char *name, +			const byte *variables, const byte *variableSizes) const; +	bool load(int16 dataVar, int32 size, int32 offset, const char *name, +			byte *variables, byte *variableSizes) const; +}; + +class StagedSave {  public: -	int32 getSize(SaveType type); -	bool load(SaveType type, int16 dataVar, int32 size, int32 offset); -	bool save(SaveType type, int16 dataVar, int32 size, int32 offset); +	StagedSave(); +	~StagedSave(); + +	void addStage(int32 size, bool endianed = true); + +	bool save(int16 dataVar, int32 size, int32 offset, const char *name, +			const byte *variables, const byte *variableSizes); +	bool load(int16 dataVar, int32 size, int32 offset, const char *name, +			byte *variables, byte *variableSizes); + +private: +	struct Stage { +		byte *bufVar; +		byte *bufVarSizes; +		int32 size; +		int32 offset; +		bool endianed; + +		Stage(int32 s = 0, int32 off = 0, bool end = true) : +			bufVar(0), bufVarSizes(0), size(s), offset(off), endianed(end) {} +	}; + +	enum Mode { +		kModeNone, +		kModeSave, +		kModeLoad +	}; + +	Common::Array<Stage> _stages; +	enum Mode _mode; +	char *_name; + +	bool _loaded; -	virtual SaveType getSaveType(const char *fileName) = 0; +	int findStage(int16 dataVar, int32 size, int32 offset) const; +	bool allSaved() const; + +	uint32 getSize() const; + +	void clear(); +	void assertMode(Mode mode, const char *name); + +	bool write() const; +	bool read(); +}; + +class SaveLoad { +public: +	enum SaveMode { +		kSaveModeNone, +		kSaveModeIgnore, +		kSaveModeSave +	};  	SaveLoad(GobEngine *vm, const char *targetName);  	virtual ~SaveLoad(); -protected: -	int _curSlot; -	char **_saveFiles; +	virtual SaveMode getSaveMode(const char *fileName) = 0; + +	int32 getSize(const char *fileName); +	bool load(const char *fileName, int16 dataVar, int32 size, int32 offset); +	bool save(const char *fileName, int16 dataVar, int32 size, int32 offset); + +	char *setCurrentSlot(char *destName, int slot); +	void buildIndex(byte *buffer, char *name, int n, int32 size, int32 offset = 0); -	int _stagesCount; -	byte **_buffer; +	static const char *stripPath(const char *fileName); -	// While using the notepad or changing the font, the original executable -	// temporarily dumps Draw::_backSurface to a file. Since that's not really -	// a nice thing to do, we work around it. -	SurfaceDesc *_tempSprite; -	Video::Color _tempPal[256]; -	int32 _tempSpriteSize; +	static bool fromEndian(byte *buf, const byte *sizes, uint32 count); +	static bool toEndian(byte *buf, const byte *sizes, uint32 count); +	static uint32 read(Common::ReadStream &in, +			byte *buf, byte *sizes, uint32 count); +	static uint32 write(Common::WriteStream &out, +			const byte *buf, const byte *sizes, uint32 count); +	static bool loadDataEndian(Common::ReadStream &in, +			int16 dataVar, uint32 size, byte *variables, byte *variableSizes); +	static bool saveDataEndian(Common::WriteStream &out, +			int16 dataVar, uint32 size, const byte *variables, const byte *variableSizes); + +protected:  	GobEngine *_vm; -	int getSpriteIndex(int32 size) { -		if (size < -1000) -			size += 1000; - -		return -size - 1; -	} -	bool getSpritePalette(int32 size) { -		return size < -1000; -	} - -	const char *setCurSlot(int slot); -	bool fromEndian(byte *buf, const byte *sizes, uint32 count); -	bool toEndian(byte *buf, const byte *sizes, uint32 count); -	uint32 read(Common::ReadStream &in, byte *buf, -			byte *sizes, uint32 count); -	uint32 write(Common::WriteStream &out, byte *buf, -			byte *sizes, uint32 count); - -	bool loadDataEndian(Common::ReadStream &in, int16 dataVar, uint32 size); -	bool saveDataEndian(Common::WriteStream &out, int16 dataVar, uint32 size); - -	bool loadTempSprite(uint32 index, bool palette); -	bool saveTempSprite(uint32 index, bool palette); -	bool loadSprite(Common::ReadStream &in, int32 size); -	bool saveSprite(Common::WriteStream &out, int32 size); - -	int32 getSizeTempSprite(); -	bool loadTempSprite(int16 dataVar, int32 size, int32 offset); -	bool saveTempSprite(int16 dataVar, int32 size, int32 offset); - -	virtual uint32 getSaveGameSize() = 0; - -	virtual int32 getSizeGame() = 0; -	virtual int32 getSizeNotes() = 0; -	virtual int32 getSizeScreenshot() = 0; -	virtual bool loadGame(int16 dataVar, int32 size, int32 offset) = 0; -	virtual bool loadNotes(int16 dataVar, int32 size, int32 offset) = 0; -	virtual bool loadScreenshot(int16 dataVar, int32 size, int32 offset) = 0; -	virtual bool saveGame(int16 dataVar, int32 size, int32 offset) = 0; -	virtual bool saveNotes(int16 dataVar, int32 size, int32 offset) = 0; -	virtual bool saveScreenshot(int16 dataVar, int32 size, int32 offset) = 0; +	char *_targetName; + +	virtual int getSaveType(const char *fileName) = 0; + +	virtual int32 getSizeVersioned(int type) = 0; +	virtual bool loadVersioned(int type, int16 dataVar, int32 size, int32 offset) = 0; +	virtual bool saveVersioned(int type, int16 dataVar, int32 size, int32 offset) = 0;  };  class SaveLoad_v2 : public SaveLoad {  public: -	virtual SaveType getSaveType(const char *fileName); +	enum SaveType { +		kSaveGame, +		kSaveTempSprite, +		kSaveNotes +	};  	SaveLoad_v2(GobEngine *vm, const char *targetName); -	virtual ~SaveLoad_v2() {} +	virtual ~SaveLoad_v2(); + +	virtual SaveMode getSaveMode(const char *fileName);  protected: -	virtual uint32 getSaveGameSize(); - -	virtual int32 getSizeGame(); -	virtual int32 getSizeNotes(); -	virtual int32 getSizeScreenshot(); -	virtual bool loadGame(int16 dataVar, int32 size, int32 offset); -	virtual bool loadNotes(int16 dataVar, int32 size, int32 offset); -	virtual bool loadScreenshot(int16 dataVar, int32 size, int32 offset); -	virtual bool saveGame(int16 dataVar, int32 size, int32 offset); -	virtual bool saveNotes(int16 dataVar, int32 size, int32 offset); -	virtual bool saveScreenshot(int16 dataVar, int32 size, int32 offset); - -	void initBuffer(); +	struct SaveFile { +		const char *sourceName; +		char *destName; +		SaveMode mode; +		SaveType type; +	}; + +	static SaveFile _saveFiles[]; + +	int32 _varSize; + +	TempSprite _tmpSprite; +	PlainSave _notes; +	StagedSave _save; + +	byte _indexBuffer[600]; +	bool _hasIndex; + +	virtual int getSaveType(const char *fileName); + +	virtual int32 getSizeVersioned(int type); +	virtual bool loadVersioned(int type, int16 dataVar, int32 size, int32 offset); +	virtual bool saveVersioned(int type, int16 dataVar, int32 size, int32 offset); + +	int getSlot(int32 offset) const; +	int getSlotRemainder(int32 offset) const; + +	int32 getSizeGame(SaveFile &saveFile); +	int32 getSizeTempSprite(SaveFile &saveFile); +	int32 getSizeNotes(SaveFile &saveFile); + +	bool loadGame(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset); +	bool loadTempSprite(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset); +	bool loadNotes(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset); + +	bool saveGame(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset); +	bool saveTempSprite(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset); +	bool saveNotes(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset); + +	void assertInited();  }; -class SaveLoad_v3 : public SaveLoad_v2 { -public: -	virtual SaveType getSaveType(const char *fileName); +enum SaveType { +	kSaveNone = -1, +	kSaveGame, +	kSaveTempSprite, +	kSaveNotes, +	kSaveScreenshot, +	kSaveIgnore +}; -	SaveLoad_v3(GobEngine *vm, const char *targetName, uint32 screenshotSize = 19968, +class SaveLoad_v3 : public SaveLoad { +public: +	enum SaveType { +		kSaveNone, +		kSaveGame, +		kSaveTempSprite, +		kSaveNotes, +		kSaveScreenshot +	}; + +	SaveLoad_v3(GobEngine *vm, const char *targetName, +			uint32 screenshotSize = 19968,  			int32 indexOffset = 40, int32 screenshotOffset = 80); -	virtual ~SaveLoad_v3() {} +	virtual ~SaveLoad_v3(); + +	virtual SaveMode getSaveMode(const char *fileName);  protected: +	struct SaveFile { +		const char *sourceName; +		char *destName; +		SaveMode mode; +		SaveType type; +		int slot; +	}; +  	bool _useScreenshots;  	bool _firstSizeGame; -	int8 _saveSlot;  	uint32 _screenshotSize;  	int32 _indexOffset;  	int32 _screenshotOffset; -	virtual uint32 getSaveGameSize(); +	static SaveFile _saveFiles[]; + +	int32 _varSize; + +	TempSprite _screenshot; +	TempSprite _tmpSprite; +	PlainSave _notes; +	StagedSave _save; + +	byte _propBuffer[1000]; +	byte _indexBuffer[1200]; +	bool _hasIndex; + +	virtual int getSaveType(const char *fileName); + +	virtual int32 getSizeVersioned(int type); +	virtual bool loadVersioned(int type, int16 dataVar, int32 size, int32 offset); +	virtual bool saveVersioned(int type, int16 dataVar, int32 size, int32 offset); + +	int getSlot(int32 offset) const; +	int getSlotRemainder(int32 offset) const; + +	int32 getSizeGame(SaveFile &saveFile); +	int32 getSizeTempSprite(SaveFile &saveFile); +	int32 getSizeNotes(SaveFile &saveFile); +	int32 getSizeScreenshot(SaveFile &saveFile); + +	bool loadGame(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset); +	bool loadTempSprite(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset); +	bool loadNotes(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset); +	bool loadScreenshot(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset); + +	bool saveGame(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset); +	bool saveTempSprite(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset); +	bool saveNotes(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset); +	bool saveScreenshot(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset); + +	void assertInited(); + +	void buildScreenshotIndex(byte *buffer, char *name, int n); +}; + +class SaveLoad_v4 : public SaveLoad { +public: +	enum SaveType { +		kSaveNone +	}; + +	SaveLoad_v4(GobEngine *vm, const char *targetName); +	virtual ~SaveLoad_v4(); + +	virtual SaveMode getSaveMode(const char *fileName); + +protected: +	struct SaveFile { +		const char *sourceName; +		char *destName; +		SaveMode mode; +		SaveType type; +	}; + +	static SaveFile _saveFiles[]; + +	int32 _varSize; + +	virtual int getSaveType(const char *fileName); -	virtual int32 getSizeGame(); -	virtual int32 getSizeScreenshot(); -	virtual bool loadGame(int16 dataVar, int32 size, int32 offset); -	virtual bool loadScreenshot(int16 dataVar, int32 size, int32 offset); -	virtual bool saveGame(int16 dataVar, int32 size, int32 offset); -	virtual bool saveNotes(int16 dataVar, int32 size, int32 offset); -	virtual bool saveScreenshot(int16 dataVar, int32 size, int32 offset); +	virtual int32 getSizeVersioned(int type); +	virtual bool loadVersioned(int type, int16 dataVar, int32 size, int32 offset); +	virtual bool saveVersioned(int type, int16 dataVar, int32 size, int32 offset); -	bool saveGame(int32 screenshotSize); -	void initBuffer(); +	void assertInited();  };  } // End of namespace Gob diff --git a/engines/gob/saveload_v2.cpp b/engines/gob/saveload_v2.cpp index ab7211b216..2754646198 100644 --- a/engines/gob/saveload_v2.cpp +++ b/engines/gob/saveload_v2.cpp @@ -24,273 +24,346 @@   */  #include "common/endian.h" -#include "common/file.h" +#include "common/savefile.h"  #include "gob/gob.h"  #include "gob/saveload.h"  #include "gob/global.h"  #include "gob/game.h" +#include "gob/draw.h"  namespace Gob { +SaveLoad_v2::SaveFile SaveLoad_v2::_saveFiles[] = { +	{  "cat.inf", 0, kSaveModeSave, kSaveGame}, +	{  "cat.cat", 0, kSaveModeSave, kSaveGame}, +	{ "save.inf", 0, kSaveModeSave, kSaveTempSprite}, +	{ "bloc.inf", 0, kSaveModeSave, kSaveNotes} +}; +  SaveLoad_v2::SaveLoad_v2(GobEngine *vm, const char *targetName) : -	SaveLoad(vm, targetName) { +		SaveLoad(vm, targetName) { + +	_saveFiles[0].destName = new char[strlen(targetName) + 5]; +	_saveFiles[1].destName = _saveFiles[0].destName; +	_saveFiles[2].destName = 0; +	_saveFiles[3].destName = new char[strlen(targetName) + 5]; -	_stagesCount = 1; +	sprintf(_saveFiles[0].destName, "%s.s00", targetName); +	sprintf(_saveFiles[3].destName, "%s.blo", targetName); + +	_varSize = 0; +	_hasIndex = false;  } -SaveType SaveLoad_v2::getSaveType(const char *fileName) { -	const char *backSlash; -	if ((backSlash = strrchr(fileName, '\\'))) -		fileName = backSlash + 1; - -	if (!scumm_stricmp(fileName, "cat.inf")) -		return kSaveGame; -	if (!scumm_stricmp(fileName, "cat.cat")) -		return kSaveGame; -	if (!scumm_stricmp(fileName, "save.inf")) -		return kSaveTempSprite; -	if (!scumm_stricmp(fileName, "bloc.inf")) -		return kSaveNotes; - -	return kSaveNone; +SaveLoad_v2::~SaveLoad_v2() { +	delete[] _saveFiles[0].destName; +	delete[] _saveFiles[3].destName;  } -uint32 SaveLoad_v2::getSaveGameSize() { -	return 80 + (READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4) * 2; +SaveLoad::SaveMode SaveLoad_v2::getSaveMode(const char *fileName) { +	for (int i = 0; i < ARRAYSIZE(_saveFiles); i++) +		if (!scumm_stricmp(fileName, _saveFiles[i].sourceName)) +			return _saveFiles[i].mode; + +	return kSaveModeNone;  } -int32 SaveLoad_v2::getSizeNotes() { -	Common::SaveFileManager *saveMan = g_system->getSavefileManager(); -	Common::InSaveFile *in; -	int32 size = -1; +int SaveLoad_v2::getSaveType(const char *fileName) { +	for (int i = 0; i < ARRAYSIZE(_saveFiles); i++) +		if (!scumm_stricmp(fileName, _saveFiles[i].sourceName)) +			return i; -	in = saveMan->openForLoading(_saveFiles[(int) kSaveNotes]); -	if (in) { -		size = in->size(); -		delete in; +	return -1; +} + +int32 SaveLoad_v2::getSizeVersioned(int type) { +	assertInited(); + +	switch (_saveFiles[type].type) { +	case kSaveGame: +		return getSizeGame(_saveFiles[type]); +	case kSaveTempSprite: +		return getSizeTempSprite(_saveFiles[type]); +	case kSaveNotes: +		return getSizeNotes(_saveFiles[type]);  	} -	return size; +	return -1;  } -int32 SaveLoad_v2::getSizeGame() { +bool SaveLoad_v2::loadVersioned(int type, int16 dataVar, int32 size, int32 offset) { +	assertInited(); + +	switch (_saveFiles[type].type) { +	case kSaveGame: +		if (loadGame(_saveFiles[type], dataVar, size, offset)) +			return true; + +		warning("While loading from slot %d", getSlot(offset)); +		break; + +	case kSaveTempSprite: +		if(loadTempSprite(_saveFiles[type], dataVar, size, offset)) +			return true; + +		warning("While loading the temporary sprite"); +		break; + +	case kSaveNotes: +		if (loadNotes(_saveFiles[type], dataVar, size, offset)) +			return true; + +		warning("While loading the notes"); +		break; +	} + +	return false; +} + +bool SaveLoad_v2::saveVersioned(int type, int16 dataVar, int32 size, int32 offset) { +	assertInited(); + +	switch (_saveFiles[type].type) { +	case kSaveGame: +		if (saveGame(_saveFiles[type], dataVar, size, offset)) +			return true; + +		warning("While saving to slot %d", getSlot(offset)); +		break; + +	case kSaveTempSprite: +		if(saveTempSprite(_saveFiles[type], dataVar, size, offset)) +			return true; + +		warning("While saving the temporary sprite"); +		break; + +	case kSaveNotes: +		if (saveNotes(_saveFiles[type], dataVar, size, offset)) +			return true; + +		warning("While saving the notes"); +		break; +	} + +	return false; +} + +int SaveLoad_v2::getSlot(int32 offset) const { +	return ((offset - 600) / _varSize); +} + +int SaveLoad_v2::getSlotRemainder(int32 offset) const { +	return ((offset - 600) % _varSize); +} + +int32 SaveLoad_v2::getSizeGame(SaveFile &saveFile) {  	Common::SaveFileManager *saveMan = g_system->getSavefileManager();  	Common::InSaveFile *in;  	for (int i = 14; i >= 0; i--) { -		in = saveMan->openForLoading(setCurSlot(i)); +		in = saveMan->openForLoading(setCurrentSlot(saveFile.destName, i));  		if (in) {  			delete in; -			return (i + 1) * READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * -				4 + 600; +			return (i + 1) * _varSize + 600;  		}  	}  	return -1;  } -int32 SaveLoad_v2::getSizeScreenshot() { -	return -1; +int32 SaveLoad_v2::getSizeTempSprite(SaveFile &saveFile) { +	return _tmpSprite.getSize();  } -bool SaveLoad_v2::loadGame(int16 dataVar, int32 size, int32 offset) { +int32 SaveLoad_v2::getSizeNotes(SaveFile &saveFile) {  	Common::SaveFileManager *saveMan = g_system->getSavefileManager();  	Common::InSaveFile *in; -	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4; +	int32 size = -1; + +	in = saveMan->openForLoading(saveFile.destName); +	if (in) { +		size = in->size(); +		delete in; +	} + +	return size; +} + +bool SaveLoad_v2::loadGame(SaveFile &saveFile, +		int16 dataVar, int32 size, int32 offset) {  	if (size == 0) {  		dataVar = 0; -		size = varSize; +		size = _varSize;  	} -	int slot = (offset - 600) / varSize; -	int slotR = (offset - 600) % varSize; - -	if ((offset == 0) && (size == 600)) { +	if (offset == 0) { +		debugC(3, kDebugSaveLoad, "Loading save index"); -		byte *varBuf = _vm->_global->_inter_variables + dataVar; -		for (int i = 0; i < 15; i++, varBuf += 40) { -			in = saveMan->openForLoading(setCurSlot(i)); -			if (in) { -				in->read(varBuf, 40); -				delete in; -			} else -				memset(varBuf, 0, 40); +		if (size != 600) { +			warning("Requested index has wrong size (%d)", size); +			return false;  		} + +		SaveLoad::buildIndex(_vm->_global->_inter_variables + dataVar, +				saveFile.destName, 15, 40);  		memset(_vm->_global->_inter_variablesSizes + dataVar, 0, 600); -		return true; -	} else if ((offset > 0) && (slot < 15) && -			(slotR == 0) && (size == varSize)) { +	} else { +		int slot = getSlot(offset); +		int slotRem = getSlotRemainder(offset); + +		debugC(2, kDebugSaveLoad, "Loading from slot %d", slot);  -		in = saveMan->openForLoading(setCurSlot(slot)); -		if (!in) { -			warning("Can't open file for slot %d", slot); +		SaveLoad::setCurrentSlot(saveFile.destName, slot); + +		if ((slot >= 15) || (slotRem != 0)) { +			warning("Invalid loading procedure (%d, %d, %d, %d, %d)", +					dataVar, size, offset, slot, slotRem);  			return false;  		} -		uint32 sGameSize = getSaveGameSize(); -		uint32 fSize = in->size(); -		if (fSize != sGameSize) { -			warning("Can't load from slot %d: Wrong size (%d, %d)", slot, -					fSize, sGameSize); -			delete in; +		if (!_save.load(dataVar, size, 40, saveFile.destName, +					_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes))  			return false; -		} +	} -		in->seek(80); -		if (loadDataEndian(*in, dataVar, size)) { -			delete in; -			debugC(1, kDebugFileIO, "Loading from slot %d", slot); -			return true; -		} -		delete in; +	return true; +} -	} else -		warning("Invalid loading procedure (%d, %d, %d, %d)", -				offset, size, slot, slotR); +bool SaveLoad_v2::loadTempSprite(SaveFile &saveFile, +		int16 dataVar, int32 size, int32 offset) { -	return false; -} +	debugC(3, kDebugSaveLoad, "Loading from the temporary sprite"); -bool SaveLoad_v2::loadNotes(int16 dataVar, int32 size, int32 offset) { -	bool retVal; +	int index; +	bool palette; -	if ((size <= 0) || (offset != 0)) { -		warning("Invalid attempt at loading the notes (%d, %d)", size, offset); +	if (!_tmpSprite.getProperties(dataVar, size, offset, index, palette))  		return false; -	} - -	Common::SaveFileManager *saveMan = g_system->getSavefileManager(); -	char *sName = _saveFiles[(int) kSaveNotes]; -	Common::InSaveFile *in = saveMan->openForLoading(sName); -	if (!in) { -		warning("Can't open file \"%s\" for reading", sName); +	if (!_tmpSprite.loadSprite(*_vm->_draw->_spritesArray[index]))  		return false; + +	if (palette) { +		if (!_tmpSprite.loadPalette(_vm->_global->_pPaletteDesc->vgaPal)) +			return false; + +		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);  	} -	retVal = loadDataEndian(*in, dataVar, size); -	delete in; -	return retVal; -} +	if (index == 21) { +		_vm->_draw->forceBlit(); +		_vm->_video->retrace(); +	} -bool SaveLoad_v2::loadScreenshot(int16 dataVar, int32 size, int32 offset) { -	return false; +	return true;  } -bool SaveLoad_v2::saveGame(int16 dataVar, int32 size, int32 offset) { -	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4; +bool SaveLoad_v2::loadNotes(SaveFile &saveFile, +		int16 dataVar, int32 size, int32 offset) { + +	debugC(2, kDebugSaveLoad, "Loading the notes"); + +	return _notes.load(dataVar, size, offset, saveFile.destName, +			_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes); +} -	initBuffer(); +bool SaveLoad_v2::saveGame(SaveFile &saveFile, +		int16 dataVar, int32 size, int32 offset) {  	if (size == 0) {  		dataVar = 0; -		size = varSize; +		size = _varSize;  	} -	int slot = (offset - 600) / varSize; -	int slotR = (offset - 600) % varSize; +	if (offset == 0) { +		debugC(3, kDebugSaveLoad, "Saving save index"); -	if ((offset == 0) && (size == 600)) { +		if (size != 600) { +			warning("Requested index has wrong size (%d)", size); +			return false; +		} -		delete[] _buffer[0]; -		_buffer[0] = new byte[1200]; -		assert(_buffer[0]); +		memcpy(_indexBuffer, _vm->_global->_inter_variables + dataVar, 600); +		_hasIndex = true; -		memcpy(_buffer[0], _vm->_global->_inter_variables + dataVar, 600); -		memset(_buffer[0] + 600, 0, 600); +	} else { +		int slot = getSlot(offset); +		int slotRem = getSlotRemainder(offset); -		return true; +		debugC(2, kDebugSaveLoad, "Saving to slot %d", slot); -	} else if ((offset > 0) && (slot < 15) && -			(slotR == 0) && (size == varSize)) { +		SaveLoad::setCurrentSlot(saveFile.destName, slot); -		if (!_buffer[0]) { -			warning("Tried to save without writing the index first"); +		if ((slot >= 15) || (slotRem != 0)) { +			warning("Invalid saving procedure (%d, %d, %d, %d, %d)", +					dataVar, size, offset, slot, slotRem);  			return false;  		} -		Common::SaveFileManager *saveMan = g_system->getSavefileManager(); -		Common::OutSaveFile *out; - -		out = saveMan->openForSaving(setCurSlot(slot)); -		if (!out) { -			warning("Can't open file for slot %d for writing", slot); -			delete[] _buffer[0]; -			_buffer[0] = 0; +		if (!_hasIndex) { +			warning("No index written yet");  			return false;  		} -		bool retVal = false; +		_hasIndex = false; -		if (out->write(_buffer[0] + slot * 40, 40) == 40) -			if (out->write(_buffer[0] + 600 + slot * 40, 40) == 40) -				if (saveDataEndian(*out, dataVar, size)) { -					out->finalize(); -					if (!out->ioFailed()) -						retVal = true; -				} - -		if (!retVal) -			warning("Can't save to slot %d", slot); -		else -			debugC(1, kDebugFileIO, "Saved to slot %d", slot); - -		delete[] _buffer[0]; -		_buffer[0] = 0; -		delete out; +		byte sizes[40]; +		memset(sizes, 0, 40); +		if(!_save.save(0, 40, 0, saveFile.destName, _indexBuffer + (slot * 40), sizes)) +			return false; -		return retVal; +		if (!_save.save(dataVar, size, 40, saveFile.destName, +					_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes)) +			return false; -	} else -		warning("Invalid saving procedure (%d, %d, %d, %d)", -				offset, size, slot, slotR); +	} -	return false; +	return true;  } -bool SaveLoad_v2::saveNotes(int16 dataVar, int32 size, int32 offset) { -	bool retVal; +bool SaveLoad_v2::saveTempSprite(SaveFile &saveFile, +		int16 dataVar, int32 size, int32 offset) { -	if ((size <= 0) || (offset != 0)) { -		warning("Invalid attempt at saving the notes (%d, %d)", size, offset); -		return false; -	} +	debugC(3, kDebugSaveLoad, "Saving to the temporary sprite"); -	Common::SaveFileManager *saveMan = g_system->getSavefileManager(); -	char *sName = _saveFiles[(int) kSaveNotes]; +	int index; +	bool palette; -	Common::OutSaveFile *out = saveMan->openForSaving(sName); -	if (!out) { -		warning("Can't open file \"%s\" for writing", sName); +	if (!_tmpSprite.getProperties(dataVar, size, offset, index, palette))  		return false; -	} -	retVal = saveDataEndian(*out, dataVar, size); +	if (!_tmpSprite.saveSprite(*_vm->_draw->_spritesArray[index])) +		return false; -	out->finalize(); -	if (out->ioFailed()) { -		warning("Can't save notes"); -		retVal = false; -	} +	if (palette) +		if (!_tmpSprite.savePalette(_vm->_global->_pPaletteDesc->vgaPal)) +			return false; -	delete out; -	return retVal; +	return true;  } -bool SaveLoad_v2::saveScreenshot(int16 dataVar, int32 size, int32 offset) { +bool SaveLoad_v2::saveNotes(SaveFile &saveFile, +		int16 dataVar, int32 size, int32 offset) { + +	debugC(2, kDebugSaveLoad, "Saving the notes"); + +	return _notes.save(dataVar, size, offset, saveFile.destName, +			_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes);  	return false;  } -void SaveLoad_v2::initBuffer() { -	if (_buffer) +void SaveLoad_v2::assertInited() { +	if (_varSize > 0)  		return; -	_buffer = new byte*[_stagesCount]; -	assert(_buffer); -	_buffer[0] = 0; +	_varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4; + +	_save.addStage(40); +	_save.addStage(_varSize);  }  } // End of namespace Gob diff --git a/engines/gob/saveload_v3.cpp b/engines/gob/saveload_v3.cpp index 4a4036fded..ae8d160eb2 100644 --- a/engines/gob/saveload_v3.cpp +++ b/engines/gob/saveload_v3.cpp @@ -24,62 +24,178 @@   */  #include "common/endian.h" -#include "common/file.h" +#include "common/savefile.h"  #include "gob/gob.h"  #include "gob/saveload.h"  #include "gob/global.h"  #include "gob/game.h" +#include "gob/draw.h"  namespace Gob { +SaveLoad_v3::SaveFile SaveLoad_v3::_saveFiles[] = { +	{    "cat.inf", 0, kSaveModeSave,   kSaveGame,       -1}, +	{    "ima.inf", 0, kSaveModeSave,   kSaveScreenshot, -1}, +	{  "intro.$$$", 0, kSaveModeSave,   kSaveTempSprite, -1}, +	{   "bloc.inf", 0, kSaveModeSave,   kSaveNotes,      -1}, +	{   "prot",     0, kSaveModeIgnore, kSaveNone,       -1}, +	{ "config",     0, kSaveModeIgnore, kSaveNone,       -1}, +}; +  SaveLoad_v3::SaveLoad_v3(GobEngine *vm, const char *targetName,  		uint32 screenshotSize, int32 indexOffset, int32 screenshotOffset) : -	SaveLoad_v2(vm, targetName) { +	SaveLoad(vm, targetName) {  	_screenshotSize = screenshotSize;  	_indexOffset = indexOffset;  	_screenshotOffset = screenshotOffset; -	_saveSlot = -1; -	_stagesCount = 3; -  	_useScreenshots = false;  	_firstSizeGame = true; + +	_saveFiles[0].destName = new char[strlen(targetName) + 5]; +	_saveFiles[1].destName = _saveFiles[0].destName; +	_saveFiles[2].destName = 0; +	_saveFiles[3].destName = new char[strlen(targetName) + 5]; +	_saveFiles[4].destName = 0; +	_saveFiles[5].destName = 0; + +	sprintf(_saveFiles[0].destName, "%s.s00", targetName); +	sprintf(_saveFiles[3].destName, "%s.blo", targetName); + +	_varSize = 0; +	_hasIndex = false; +	memset(_propBuffer, 0, 1000);  } -SaveType SaveLoad_v3::getSaveType(const char *fileName) { -	const char *backSlash; -	if ((backSlash = strrchr(fileName, '\\'))) -		fileName = backSlash + 1; - -	if (!scumm_stricmp(fileName, "cat.inf")) -		return kSaveGame; -	if (!scumm_stricmp(fileName, "ima.inf")) -		return kSaveScreenshot; -	if (!scumm_stricmp(fileName, "intro.$$$")) -		return kSaveTempSprite; -	if (!scumm_stricmp(fileName, "bloc.inf")) -		return kSaveNotes; -	if (!scumm_stricmp(fileName, "prot")) -		return kSaveIgnore; -	if (!scumm_stricmp(fileName, "config")) -		return kSaveIgnore; - -	return kSaveNone; +SaveLoad_v3::~SaveLoad_v3() { +	delete[] _saveFiles[0].destName; +	delete[] _saveFiles[3].destName;  } -uint32 SaveLoad_v3::getSaveGameSize() { -	uint32 size; +SaveLoad::SaveMode SaveLoad_v3::getSaveMode(const char *fileName) { +	for (int i = 0; i < ARRAYSIZE(_saveFiles); i++) +		if (!scumm_stricmp(fileName, _saveFiles[i].sourceName)) +			return _saveFiles[i].mode; -	size = 1040 + (READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4) * 2; -	if (_useScreenshots) -		size += _screenshotSize; +	return kSaveModeNone; +} -	return size; +int SaveLoad_v3::getSaveType(const char *fileName) { +	for (int i = 0; i < ARRAYSIZE(_saveFiles); i++) +		if (!scumm_stricmp(fileName, _saveFiles[i].sourceName)) +			return i; + +	return -1; +} + +int32 SaveLoad_v3::getSizeVersioned(int type) { +	assertInited(); + +	switch (_saveFiles[type].type) { +	case kSaveGame: +		return getSizeGame(_saveFiles[type]); +	case kSaveTempSprite: +		return getSizeTempSprite(_saveFiles[type]); +	case kSaveNotes: +		return getSizeNotes(_saveFiles[type]); +	case kSaveScreenshot: +		return getSizeScreenshot(_saveFiles[type]); +	default: +		break; +	} + +	return -1; +} + +bool SaveLoad_v3::loadVersioned(int type, int16 dataVar, int32 size, int32 offset) { +	assertInited(); + +	switch (_saveFiles[type].type) { +	case kSaveGame: +		if (loadGame(_saveFiles[type], dataVar, size, offset)) +			return true; + +		warning("While loading from slot %d", getSlot(offset)); +		break; + +	case kSaveTempSprite: +		if(loadTempSprite(_saveFiles[type], dataVar, size, offset)) +			return true; + +		warning("While loading the temporary sprite"); +		break; + +	case kSaveNotes: +		if (loadNotes(_saveFiles[type], dataVar, size, offset)) +			return true; + +		warning("While loading the notes"); +		break; + +	case kSaveScreenshot: +		if (loadScreenshot(_saveFiles[type], dataVar, size, offset)) +			return true; + +		warning("While loading a screenshot"); +		break; + +	default: +		break; +	} + +	return false; +} + +bool SaveLoad_v3::saveVersioned(int type, int16 dataVar, int32 size, int32 offset) { +	assertInited(); + +	switch (_saveFiles[type].type) { +	case kSaveGame: +		if (saveGame(_saveFiles[type], dataVar, size, offset)) +			return true; + +		warning("While saving to slot %d", getSlot(offset)); +		break; + +	case kSaveTempSprite: +		if(saveTempSprite(_saveFiles[type], dataVar, size, offset)) +			return true; + +		warning("While saving the temporary sprite"); +		break; + +	case kSaveNotes: +		if (saveNotes(_saveFiles[type], dataVar, size, offset)) +			return true; + +		warning("While saving the notes"); +		break; + +	case kSaveScreenshot: +		if (saveScreenshot(_saveFiles[type], dataVar, size, offset)) +			return true; + +		warning("While saving a screenshot"); +		break; + +	default: +		break; +	} + +	return false; +} + +int SaveLoad_v3::getSlot(int32 offset) const { +	return ((offset - 1700) / _varSize);  } -int32 SaveLoad_v3::getSizeGame() { +int SaveLoad_v3::getSlotRemainder(int32 offset) const { +	return ((offset - 1700) % _varSize); +} + +int32 SaveLoad_v3::getSizeGame(SaveFile &saveFile) {  	if (_firstSizeGame) {  		_firstSizeGame = false;  		return -1; @@ -89,358 +205,413 @@ int32 SaveLoad_v3::getSizeGame() {  	Common::InSaveFile *in;  	int32 size = -1; -	int slot = _curSlot; +	int slot = saveFile.slot;  	for (int i = 29; i >= 0; i--) { -		in = saveMan->openForLoading(setCurSlot(i)); +		in = saveMan->openForLoading(setCurrentSlot(saveFile.destName, i));  		if (in) {  			delete in; -			size = (i + 1) * READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * -				4 + 1700; +			size = (i + 1) * _varSize + 1700;  			break;  		}  	} -	setCurSlot(slot); +	setCurrentSlot(saveFile.destName, slot);  	return size;  } -int32 SaveLoad_v3::getSizeScreenshot() { +int32 SaveLoad_v3::getSizeTempSprite(SaveFile &saveFile) { +	return _tmpSprite.getSize(); +} + +int32 SaveLoad_v3::getSizeNotes(SaveFile &saveFile) {  	Common::SaveFileManager *saveMan = g_system->getSavefileManager();  	Common::InSaveFile *in;  	int32 size = -1; -	_useScreenshots = true; -	int slot = _curSlot; +	in = saveMan->openForLoading(saveFile.destName); +	if (in) { +		size = in->size(); +		delete in; +	} + +	return size; +} + +int32 SaveLoad_v3::getSizeScreenshot(SaveFile &saveFile) { +	if (!_useScreenshots) { +		_useScreenshots = true; +		_save.addStage(_screenshotSize, false); +	} + +	Common::SaveFileManager *saveMan = g_system->getSavefileManager(); +	Common::InSaveFile *in; +	int32 size = -1; + +	int slot = saveFile.slot;  	for (int i = 29; i >= 0; i--) { -		in = saveMan->openForLoading(setCurSlot(i)); +		in = saveMan->openForLoading(setCurrentSlot(saveFile.destName, i));  		if (in) {  			delete in;  			size = (i + 1) * _screenshotSize + _screenshotOffset;  			break;  		}  	} -	setCurSlot(slot); +	setCurrentSlot(saveFile.destName, slot);  	return size;  } -bool SaveLoad_v3::loadGame(int16 dataVar, int32 size, int32 offset) { -	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4; -	Common::SaveFileManager *saveMan = g_system->getSavefileManager(); -	Common::InSaveFile *in; +bool SaveLoad_v3::loadGame(SaveFile &saveFile, +		int16 dataVar, int32 size, int32 offset) { -	int slot = (offset - 1700) / varSize; -	int slotR = (offset - 1700) % varSize; +	if (size == 0) { +		dataVar = 0; +		size = _varSize; +	} -	initBuffer(); +	if (offset < 500) { +		debugC(3, kDebugSaveLoad, "Loading global properties"); -	if ((size > 0) && (offset < 500) && ((size + offset) <= 500)) { +		if ((size + offset) > 500) { +			warning("Wrong global properties list size (%d, %d)", size, offset); +			return false; +		}  		memcpy(_vm->_global->_inter_variables + dataVar, -				_buffer[0] + offset, size); +				_propBuffer + offset, size);  		memcpy(_vm->_global->_inter_variablesSizes + dataVar, -				_buffer[0] + offset + 500, size); -		return true; +				_propBuffer + offset + 500, size); -	} else if ((size == 1200) && (offset == 500)) { +	} else if (offset == 500) { +		debugC(3, kDebugSaveLoad, "Loading save index"); -		memset(_buffer[1], 0, 1200); - -		slot = _curSlot; -		for (int i = 0; i < 30; i++) { -			in = saveMan->openForLoading(setCurSlot(i)); -			if (in) { -				in->seek(1000); -				in->read(_buffer[1] + i * 40, 40); -				delete in; -			} +		if (size != 1200) { +			warning("Requested index has wrong size (%d)", size); +			return false;  		} -		setCurSlot(slot); -		memcpy(_vm->_global->_inter_variables + dataVar, _buffer[1], 1200); +		int slot = saveFile.slot; + +		SaveLoad::buildIndex(_vm->_global->_inter_variables + dataVar, +				saveFile.destName, 30, 40, 1000);  		memset(_vm->_global->_inter_variablesSizes + dataVar, 0, 1200); -		return true; -	} else if ((offset > 0) && (slot < 30) && -			(slotR == 0) && (size == 0)) { +		setCurrentSlot(saveFile.destName, slot); + +	} else { +		saveFile.slot = getSlot(offset); +		int slotRem = getSlotRemainder(offset); -		in = saveMan->openForLoading(setCurSlot(slot)); -		if (!in) { -			warning("Can't open file for slot %d", slot); +		debugC(2, kDebugSaveLoad, "Loading from slot %d", saveFile.slot);  + +		SaveLoad::setCurrentSlot(saveFile.destName, saveFile.slot); + +		if ((saveFile.slot < 0) || (saveFile.slot >= 30) || (slotRem != 0)) { +			warning("Invalid loading procedure (%d, %d, %d, %d, %d)", +					dataVar, size, offset, saveFile.slot, slotRem);  			return false;  		} -		uint32 sGameSize = getSaveGameSize(); -		uint32 fSize = in->size(); -		if (fSize != sGameSize) { -			warning("Can't load from slot %d: Wrong size (%d, %d)", slot, -					fSize, sGameSize); -			delete in; +		if (!_save.load(dataVar, size, 540, saveFile.destName, +					_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes))  			return false; -		} +	} -		byte varBuf[500], sizeBuf[500]; -		if (read(*in, varBuf, sizeBuf, 500) == 500) { -			if (fromEndian(varBuf, sizeBuf, 500)) { -				memcpy(_buffer[0], varBuf, 500); -				memcpy(_buffer[0] + 500, sizeBuf, 500); -				in->seek(1040); -				if (loadDataEndian(*in, 0, varSize)) { -					delete in; -					debugC(1, kDebugFileIO, "Loading from slot %d", slot); -					return true; -				} -			} -		} -		delete in; +	return true; +} -	} else -		warning("Invalid loading procedure (%d, %d, %d, %d)", -				offset, size, slot, slotR); +bool SaveLoad_v3::loadTempSprite(SaveFile &saveFile, +		int16 dataVar, int32 size, int32 offset) { -	return false; +	debugC(3, kDebugSaveLoad, "Loading from the temporary sprite"); + +	int index; +	bool palette; + +	if (!_tmpSprite.getProperties(dataVar, size, offset, index, palette)) +		return false; + +	if (!_tmpSprite.loadSprite(*_vm->_draw->_spritesArray[index])) +		return false; + +	if (palette) { +		if (!_tmpSprite.loadPalette(_vm->_global->_pPaletteDesc->vgaPal)) +			return false; + +		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); +	} + +	if (index == 21) { +		_vm->_draw->forceBlit(); +		_vm->_video->retrace(); +	} + +	return true;  } -bool SaveLoad_v3::loadScreenshot(int16 dataVar, int32 size, int32 offset) { -	Common::SaveFileManager *saveMan = g_system->getSavefileManager(); -	Common::InSaveFile *in; +bool SaveLoad_v3::loadNotes(SaveFile &saveFile, +		int16 dataVar, int32 size, int32 offset) { -	int slot = (offset - _screenshotOffset) / _screenshotSize; -	int slotR = (offset - _screenshotOffset) % _screenshotSize; +	debugC(2, kDebugSaveLoad, "Loading the notes"); -	_useScreenshots = true; -	if ((size == 40) && (offset == _indexOffset)) { -		char buf[40]; +	return _notes.load(dataVar, size, offset, saveFile.destName, +			_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes); +} -		memset(buf, 0, 40); +bool SaveLoad_v3::loadScreenshot(SaveFile &saveFile, +		int16 dataVar, int32 size, int32 offset) { -		slot = _curSlot; -		for (int i = 0; i < 30; i++) { -			in = saveMan->openForLoading(setCurSlot(i)); -			if (in) { -				delete in; -				buf[i] = 1; -			} +	debugC(3, kDebugSaveLoad, "Loading a screenshot"); + +	if (!_useScreenshots) { +		_useScreenshots = true; +		_save.addStage(_screenshotSize, false); +	} + +	if (offset == _indexOffset) { +		if (size != 40) { +			warning("Requested index has wrong size (%d)", size); +			return false;  		} -		setCurSlot(slot); -		memcpy(_vm->_global->_inter_variables + dataVar, buf, 40); +		byte buffer[40]; +		memset(buffer, 0, 40); + +		int slot = saveFile.slot; +		buildScreenshotIndex(buffer, saveFile.destName, 30); +		setCurrentSlot(saveFile.destName, slot); + +		memcpy(_vm->_global->_inter_variables + dataVar, buffer, 40);  		memset(_vm->_global->_inter_variablesSizes + dataVar, 0, 40); -		return true; -	} else if ((offset > 0) && (slot < 30) && -			(slotR == 0) && (size < 0)) { +	} else { +		saveFile.slot = (offset - _screenshotOffset) / _screenshotSize; +		int slotRem = (offset - _screenshotOffset) % _screenshotSize; -		int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4; +		SaveLoad::setCurrentSlot(saveFile.destName, saveFile.slot); -		in = saveMan->openForLoading(setCurSlot(slot)); -		if (!in) { -			warning("Can't open file for slot %d", slot); +		if ((saveFile.slot < 0) || (saveFile.slot >= 30) || (slotRem != 0)) { +			warning("Invalid loading procedure (%d, %d, %d, %d, %d)", +					dataVar, size, offset, saveFile.slot, slotRem);  			return false;  		} -		uint32 sGameSize = getSaveGameSize(); -		uint32 fSize = in->size(); -		if (fSize != sGameSize) { -			warning("Can't load screenshot from slot %d: Wrong size (%d, %d)", -					slot, fSize, sGameSize); -			delete in; +		byte *buffer = new byte[_screenshotSize]; + +		if (!_save.load(0, _screenshotSize, _varSize + 540, saveFile.destName, buffer, 0)) { +			delete[] buffer;  			return false;  		} -		in->seek(1040 + varSize * 2); +		int index; +		bool palette; -		bool success = loadSprite(*in, size); -		delete in; -		return success; +		if (!_screenshot.getProperties(dataVar, size, offset, index, palette)) { +			delete[] buffer; +			return false; +		} -	} else -		warning("Invalid attempt at loading a screenshot (%d, %d, %d, %d)", -				offset, size, slot, slotR); +		if (!_screenshot.fromBuffer(buffer, _screenshotSize, palette)) { +			delete[] buffer; +			return false; +		} -	return false; +		if (!_screenshot.loadSprite(*_vm->_draw->_spritesArray[index])) { +			delete[] buffer; +			return false; +		} + +		if (palette) { +			if (!_screenshot.loadPalette(_vm->_global->_pPaletteDesc->vgaPal)) { +				delete[] buffer; +				return false; +			} +			_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); +		} + +		delete[] buffer; +	} + +	return true;  } -bool SaveLoad_v3::saveGame(int16 dataVar, int32 size, int32 offset) { -	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4; +bool SaveLoad_v3::saveGame(SaveFile &saveFile, +		int16 dataVar, int32 size, int32 offset) { -	int slot = (offset - 1700) / varSize; -	int slotR = (offset - 1700) % varSize; +	if (size == 0) { +		dataVar = 0; +		size = _varSize; +	} -	initBuffer(); +	if (offset < 500) { +		debugC(3, kDebugSaveLoad, "Loading global properties"); -	if ((size > 0) && (offset < 500) && ((size + offset) <= 500)) { +		if ((size + offset) > 500) { +			warning("Wrong global properties list size (%d, %d)", size, offset); +			return false; +		} -		memcpy(_buffer[0] + offset, +		memcpy(_propBuffer + offset,  				_vm->_global->_inter_variables + dataVar, size); -		memcpy(_buffer[0] + offset + 500, +		memcpy(_propBuffer + offset + 500,  				_vm->_global->_inter_variablesSizes + dataVar, size); -		return true; - -	} else if ((size > 0) && (offset >= 500) && (offset < 1700) && -			((size + offset) <= 1700)) { +	} else if (offset == 500) { +		debugC(3, kDebugSaveLoad, "Saving save index"); -		memcpy(_buffer[1] + offset - 500, -				_vm->_global->_inter_variables + dataVar, size); +		if (size != 1200) { +			warning("Requested index has wrong size (%d)", size); +			return false; +		} -		return true; +		memcpy(_indexBuffer, _vm->_global->_inter_variables + dataVar, size); +		_hasIndex = true; -	} else if ((offset > 0) && (slot < 30) && -			(slotR == 0) && (size == 0)) { +	} else { +		saveFile.slot = getSlot(offset); +		int slotRem = getSlotRemainder(offset); -		_saveSlot = -1; +		debugC(2, kDebugSaveLoad, "Saving to slot %d", saveFile.slot); -		delete _buffer[2]; -		_buffer[2] = new byte[varSize * 2]; -		assert(_buffer[2]); +		SaveLoad::setCurrentSlot(saveFile.destName, saveFile.slot); -		memcpy(_buffer[2], _vm->_global->_inter_variables, varSize); -		memcpy(_buffer[2] + varSize, -				_vm->_global->_inter_variablesSizes, varSize); +		if ((saveFile.slot < 0) || (saveFile.slot >= 30) || (slotRem != 0)) { +			warning("Invalid saving procedure (%d, %d, %d, %d, %d)", +					dataVar, size, offset, saveFile.slot, slotRem); +			return false; +		} -		if (!toEndian(_buffer[2], _buffer[2] + varSize, varSize)) { -			delete _buffer[2]; -			_buffer[2] = 0; +		if (!_hasIndex) { +			warning("No index written yet");  			return false;  		} -		_saveSlot = slot; +		_hasIndex = false; -		if (!_useScreenshots) -			return saveGame(0); +		if(!_save.save(0, 500, 0, saveFile.destName, _propBuffer, _propBuffer + 500)) +			return false; -		return true; +		if(!_save.save(0, 40, 500, saveFile.destName, _indexBuffer + (saveFile.slot * 40), 0)) +			return false; -	} else -		warning("Invalid saving procedure (%d, %d, %d, %d)", -				offset, size, slot, slotR); +		if (!_save.save(dataVar, size, 540, saveFile.destName, +					_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes)) +			return false; -	return false; -} +	} -bool SaveLoad_v3::saveNotes(int16 dataVar, int32 size, int32 offset) { -	return SaveLoad_v2::saveNotes(dataVar, size - 160, offset); +	return true;  } -bool SaveLoad_v3::saveScreenshot(int16 dataVar, int32 size, int32 offset) { -	int slot = (offset - _screenshotOffset) / _screenshotSize; -	int slotR = (offset - _screenshotOffset) % _screenshotSize; +bool SaveLoad_v3::saveTempSprite(SaveFile &saveFile, +		int16 dataVar, int32 size, int32 offset) { -	_useScreenshots = true; +	debugC(3, kDebugSaveLoad, "Saving to the temporary sprite"); -	if ((offset < _screenshotOffset) && (size > 0)) { +	int index; +	bool palette; -		return true; +	if (!_tmpSprite.getProperties(dataVar, size, offset, index, palette)) +		return false; -	} else if ((offset > 0) && (slot < 30) && -			(slotR == 0) && (size < 0)) { +	if (!_tmpSprite.saveSprite(*_vm->_draw->_spritesArray[index])) +		return false; + +	if (palette) +		if (!_tmpSprite.savePalette(_vm->_global->_pPaletteDesc->vgaPal)) +			return false; + +	return true; +} -		return saveGame(size); +bool SaveLoad_v3::saveNotes(SaveFile &saveFile, +		int16 dataVar, int32 size, int32 offset) { -	} else -		warning("Invalid attempt at saving a screenshot (%d, %d, %d, %d)", -				offset, size, slot, slotR); +	debugC(2, kDebugSaveLoad, "Saving the notes"); +	return _notes.save(dataVar, size - 160, offset, saveFile.destName, +			_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes);  	return false;  } -bool SaveLoad_v3::saveGame(int32 screenshotSize) { -	int8 slot = _saveSlot; - -	_saveSlot = -1; +bool SaveLoad_v3::saveScreenshot(SaveFile &saveFile, +		int16 dataVar, int32 size, int32 offset) { -	initBuffer(); +	debugC(3, kDebugSaveLoad, "Saving a screenshot"); -	if ((slot < 0) || (slot > 29)) { -		warning("Can't save to slot %d: Out of range", slot); -		delete[] _buffer[2]; -		_buffer[2] = 0; -		return false; +	if (!_useScreenshots) { +		_useScreenshots = true; +		_save.addStage(_screenshotSize, false);  	} -	if (!_buffer[2]) { -		warning("Can't save to slot %d: No data", slot); -		return false; -	} +	if (offset >= _screenshotOffset) { -	Common::SaveFileManager *saveMan = g_system->getSavefileManager(); -	Common::OutSaveFile *out; +		saveFile.slot = (offset - _screenshotOffset) / _screenshotSize; +		int slotRem = (offset - _screenshotOffset) % _screenshotSize; -	out = saveMan->openForSaving(setCurSlot(slot)); -	if (!out) { -		warning("Can't open file for slot %d for writing", slot); -		delete[] _buffer[2]; -		_buffer[2] = 0; -		return false; -	} +		setCurrentSlot(saveFile.destName, saveFile.slot); + +		if ((saveFile.slot < 0) || (saveFile.slot >= 30) || (slotRem != 0)) { +			warning("Invalid saving procedure (%d, %d, %d, %d, %d)", +					dataVar, size, offset, saveFile.slot, slotRem); +			return false; +		} -	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4; -	byte varBuf[500], sizeBuf[500]; +		int index; +		bool palette; -	memcpy(varBuf, _buffer[0], 500); -	memcpy(sizeBuf, _buffer[0] + 500, 500); +		if (!_screenshot.getProperties(dataVar, size, offset, index, palette)) +			return false; -	bool retVal = false; -	if (toEndian(varBuf, sizeBuf, 500)) -		if (write(*out, varBuf, sizeBuf, 500) == 500) -			if (out->write(_buffer[1] + slot * 40, 40) == 40) -				if (out->write(_buffer[2], varSize * 2) == ((uint32) (varSize * 2))) { -					out->flush(); -					if (!out->ioFailed()) -						retVal = true; -				} +		if (!_screenshot.saveSprite(*_vm->_draw->_spritesArray[index])) +			return false; -	delete[] _buffer[2]; -	_buffer[2] = 0; +		if (palette) +			if (!_screenshot.savePalette(_vm->_global->_pPaletteDesc->vgaPal)) +				return false; -	if (!retVal) { -		warning("Can't save to slot %d", slot); -		delete out; -		return false; -	} +		 +		byte *buffer = new byte[_screenshotSize]; -	if (_useScreenshots) { -		if (screenshotSize >= 0) { -			warning("Can't save to slot %d: Screenshot expected", slot); -			delete out; +		if (!_screenshot.toBuffer(buffer, _screenshotSize, palette)) { +			delete[] buffer;  			return false;  		} -		if (!saveSprite(*out, screenshotSize)) { -			delete out; +		if (!_save.save(0, _screenshotSize, _varSize + 540, saveFile.destName, buffer, 0)) { +			delete[] buffer;  			return false;  		} -	} -	out->finalize(); -	if (out->ioFailed()) { -		warning("Can't save to slot %d", slot); -		delete out; -		return false; +		delete[] buffer;  	} -	debugC(1, kDebugFileIO, "Saved to slot %d", slot); -	delete out;  	return true;  } -void SaveLoad_v3::initBuffer() { -	if (_buffer) +void SaveLoad_v3::assertInited() { +	if (_varSize > 0)  		return; -	_buffer = new byte*[_stagesCount]; - -	assert(_buffer); +	_varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4; -	_buffer[0] = new byte[1000]; -	_buffer[1] = new byte[1200]; -	_buffer[2] = 0; +	_save.addStage(500); +	_save.addStage(40, false); +	_save.addStage(_varSize); +} -	assert(_buffer[0] && _buffer[1]); +void SaveLoad_v3::buildScreenshotIndex(byte *buffer, char *name, int n) { +	Common::SaveFileManager *saveMan = g_system->getSavefileManager(); +	Common::InSaveFile *in; -	memset(_buffer[0], 0, 1000); -	memset(_buffer[1], 0, 1200); +	memset(buffer, 0, n); +	for (int i = 0; i < n; i++) { +		in = saveMan->openForLoading(setCurrentSlot(name, i)); +		if (in) { +			delete in; +			buffer[i] = 1; +		} +	}  }  } // End of namespace Gob diff --git a/engines/gob/saveload_v4.cpp b/engines/gob/saveload_v4.cpp new file mode 100644 index 0000000000..2235b4834e --- /dev/null +++ b/engines/gob/saveload_v4.cpp @@ -0,0 +1,80 @@ +/* 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$ + * + */ + +#include "common/endian.h" + +#include "gob/gob.h" +#include "gob/saveload.h" +#include "gob/game.h" + +namespace Gob { + +SaveLoad_v4::SaveFile SaveLoad_v4::_saveFiles[] = { +	{ "", 0, kSaveModeNone, kSaveNone } +}; + +SaveLoad_v4::SaveLoad_v4(GobEngine *vm, const char *targetName) : +	SaveLoad(vm, targetName) { + +	_varSize = 0; +} + +SaveLoad_v4::~SaveLoad_v4() { +} + +SaveLoad::SaveMode SaveLoad_v4::getSaveMode(const char *fileName) { +	return kSaveModeNone; +} + +int SaveLoad_v4::getSaveType(const char *fileName) { +	return -1; +} + +int32 SaveLoad_v4::getSizeVersioned(int type) { +	assertInited(); + +	return -1; +} + +bool SaveLoad_v4::loadVersioned(int type, int16 dataVar, int32 size, int32 offset) { +	assertInited(); + +	return false; +} + +bool SaveLoad_v4::saveVersioned(int type, int16 dataVar, int32 size, int32 offset) { +	assertInited(); + +	return false; +} + +void SaveLoad_v4::assertInited() { +	if (_varSize > 0) +		return; + +	_varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4; +} + +} // End of namespace Gob diff --git a/engines/gob/video.h b/engines/gob/video.h index 4a585d8857..1ab513205b 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -37,10 +37,11 @@ class SurfaceDesc : public ReferenceCounter<SurfaceDesc> {  public:  	int16 _vidMode; -	int16 getWidth() { return _width; } -	int16 getHeight() { return _height; } +	int16 getWidth() const { return _width; } +	int16 getHeight() const { return _height; }  	byte *getVidMem() { return _vidMem; } -	bool hasOwnVidMem() { return _ownVidMem; } +	const byte *getVidMem() const { return _vidMem; } +	bool hasOwnVidMem() const { return _ownVidMem; }  	void setVidMem(byte *vidMem);  	void resize(int16 width, int16 height); | 
