diff options
| -rw-r--r-- | engines/gob/save/savehandler.cpp | 2 | ||||
| -rw-r--r-- | engines/gob/save/saveload.h | 79 | ||||
| -rw-r--r-- | engines/gob/save/saveload_inca2.cpp | 328 | 
3 files changed, 407 insertions, 2 deletions
| diff --git a/engines/gob/save/savehandler.cpp b/engines/gob/save/savehandler.cpp index 8b7a661278..d447b0dbd6 100644 --- a/engines/gob/save/savehandler.cpp +++ b/engines/gob/save/savehandler.cpp @@ -340,6 +340,8 @@ bool TempSpriteHandler::isSprite(int32 size) {  // Contruct the index  int TempSpriteHandler::getIndex(int32 size) {  	// Palette flag +	if (size < -3000) +		size += 3000;  	if (size < -1000)  		size += 1000; diff --git a/engines/gob/save/saveload.h b/engines/gob/save/saveload.h index dd99bf466b..89beafd9fc 100644 --- a/engines/gob/save/saveload.h +++ b/engines/gob/save/saveload.h @@ -337,6 +337,9 @@ protected:  /** Save/Load class for Inca 2. */  class SaveLoad_Inca2 : public SaveLoad {  public: +	static const uint32 kSlotCount =  40; +	static const uint32 kPropsSize = 500; +  	SaveLoad_Inca2(GobEngine *vm, const char *targetName);  	virtual ~SaveLoad_Inca2(); @@ -361,10 +364,84 @@ protected:  		bool save(int16 dataVar, int32 size, int32 offset);  	}; +	class ScreenshotHandler; + +	/** Handles the save slots. */ +	class GameHandler : public SaveHandler { +	friend class SaveLoad_Inca2::ScreenshotHandler; +	public: + +		GameHandler(GobEngine *vm, const char *target); +		~GameHandler(); + +		int32 getSize(); +		bool load(int16 dataVar, int32 size, int32 offset); +		bool save(int16 dataVar, int32 size, int32 offset); + +		bool saveScreenshot(int slot, const SavePartSprite *screenshot); +		bool loadScreenshot(int slot, SavePartSprite *screenshot); + +		/** Slot file construction. */ +		class File : public SlotFileIndexed { +		public: +			File(GobEngine *vm, const char *base); +			File(const File &file); +			~File(); + +			int getSlot(int32 offset) const; +			int getSlotRemainder(int32 offset) const; +		}; + +	private: + +		File *_slotFile; + +		byte _props[kPropsSize]; + +		SaveReader *_reader; +		SaveWriter *_writer; + +		void buildIndex(); + +		bool createReader(int slot); +		bool createWriter(int slot); +	}; + +	/** Handles the screenshots. */ +	class ScreenshotHandler : public TempSpriteHandler { +	public: +		ScreenshotHandler(GobEngine *vm, GameHandler *gameHandler); +		~ScreenshotHandler(); + +		int32 getSize(); +		bool load(int16 dataVar, int32 size, int32 offset); +		bool save(int16 dataVar, int32 size, int32 offset); + +	private: +		/** Slot file construction. */ +		class File : public SaveLoad_Inca2::GameHandler::File { +		public: +			File(const SaveLoad_Inca2::GameHandler::File &file); +			~File(); + +			int getSlot(int32 offset) const; +			int getSlotRemainder(int32 offset) const; + +			void buildIndex(byte *buffer) const; +		}; + +		File *_file; +		GameHandler *_gameHandler; + +		byte _index[80]; +	}; +  	static SaveFile _saveFiles[]; -	VoiceHandler *_voiceHandler; +	VoiceHandler      *_voiceHandler;  	TempSpriteHandler *_tempSpriteHandler; +	GameHandler       *_gameHandler; +	ScreenshotHandler *_screenshotHandler;  	SaveHandler *getHandler(const char *fileName) const;  	const char *getDescription(const char *fileName) const; diff --git a/engines/gob/save/saveload_inca2.cpp b/engines/gob/save/saveload_inca2.cpp index 4577440ec8..e32c4fd25c 100644 --- a/engines/gob/save/saveload_inca2.cpp +++ b/engines/gob/save/saveload_inca2.cpp @@ -39,6 +39,328 @@ SaveLoad_Inca2::SaveFile SaveLoad_Inca2::_saveFiles[] = {  }; +SaveLoad_Inca2::GameHandler::File::File(GobEngine *vm, const char *base) : +	SlotFileIndexed(vm, SaveLoad_Inca2::kSlotCount, base, "s") { +} + +SaveLoad_Inca2::GameHandler::File::File(const File &file) : +	SlotFileIndexed(file._vm, file._slotCount, file._base, file._ext) { +} + +SaveLoad_Inca2::GameHandler::File::~File() { +} + +int SaveLoad_Inca2::GameHandler::File::getSlot(int32 offset) const { +	uint32 varSize = SaveHandler::getVarSize(_vm); + +	if (varSize == 0) +		return -1; + +	return offset - kPropsSize; +} + +int SaveLoad_Inca2::GameHandler::File::getSlotRemainder(int32 offset) const { +	return 0; +} + + +SaveLoad_Inca2::GameHandler::GameHandler(GobEngine *vm, const char *target) : +	SaveHandler(vm) { + +	_slotFile = new File(vm, target); + +	memset(_props, 0x00, kPropsSize); +	memset(_props, 0x20, 10); + +	_props[43] = 0x01; +	_props[79] = 0x03; + +	buildIndex(); + +	_writer = 0; +	_reader = 0; +} + +SaveLoad_Inca2::GameHandler::~GameHandler() { +	delete _slotFile; +	delete _reader; +	delete _writer; +} + +int32 SaveLoad_Inca2::GameHandler::getSize() { +	return _slotFile->tallyUpFiles(1, kPropsSize); +} + +bool SaveLoad_Inca2::GameHandler::load(int16 dataVar, int32 size, int32 offset) { +	if (((uint32) offset) < kPropsSize) { +		// Global properties, like joker usage + +		debugC(3, kDebugSaveLoad, "Loading global properties"); + +		if (((uint32) (offset + size)) > kPropsSize) { +			warning("Wrong global properties list size (%d, %d)", size, offset); +			return false; +		} + +		if (((uint32) (offset + size)) >= kPropsSize) +			buildIndex(); + +		_vm->_inter->_variables->copyFrom(dataVar, _props + offset, size); + +	} else { +		int32 slot = offset - kPropsSize; + +		if ((size != 1) || (slot < 0) || ((uint32)slot >= kSlotCount)) { +			warning("Invalid loading procedure (%d, %d, %d)", dataVar, size, offset); +			return false; +		} + +		WRITE_VARO_UINT8(dataVar, 0); +		if (!createReader(slot)) +			return true; + +		SavePartInfo info(0, (uint32) _vm->getGameType(), 0, _vm->getEndianness(), 1); +		SavePartVars vars(_vm, 1); + +		if (!_reader->readPart(0, &info)) +			return true; +		if (!_reader->readPart(1, &vars)) +			return true; + +		// Read the save point number +		if (!vars.writeInto(dataVar, 0, 1)) { +			WRITE_VARO_UINT8(dataVar, 0); +			return true; +		} +	} + +	return true; +} + +bool SaveLoad_Inca2::GameHandler::save(int16 dataVar, int32 size, int32 offset) { +	if (((uint32) offset) < kPropsSize) { +		// Global properties, like joker usage + +		debugC(3, kDebugSaveLoad, "Saving global properties"); + +		if (((uint32) (offset + size)) > kPropsSize) { +			warning("Wrong global properties list size (%d, %d)", size, offset); +			return false; +		} + +		_vm->_inter->_variables->copyTo(dataVar, _props + offset, size); + +	} else { +		// Save point flag + +		int32 slot = offset - kPropsSize; + +		if ((size != 1) || (slot < 0) || ((uint32)slot >= kSlotCount)) { +			warning("Invalid saving procedure (%d, %d, %d)", dataVar, size, offset); +			return false; +		} + +		if (!createWriter(slot)) +			return false; + +		SavePartInfo info(0, (uint32) _vm->getGameType(), 0, _vm->getEndianness(), 1); +		SavePartVars vars(_vm, 1); + +		// Write the save point number +		if (!vars.readFrom(dataVar, 0, 1)) +			return false; + +		if (!_writer->writePart(0, &info)) +			return false; +		if (!_writer->writePart(1, &vars)) +			return false; +	} + +	return true; +} + +bool SaveLoad_Inca2::GameHandler::saveScreenshot(int slot, +		const SavePartSprite *screenshot) { + +	if (!createWriter(slot)) +		return false; + +	return _writer->writePart(2, screenshot); +} + +bool SaveLoad_Inca2::GameHandler::loadScreenshot(int slot, +		SavePartSprite *screenshot) { + +	if (!createReader(slot)) +		return false; + +	return _reader->readPart(2, screenshot); +} + +void SaveLoad_Inca2::GameHandler::buildIndex() { +	_props[499] = _slotFile->getSlotMax(); +} + +bool SaveLoad_Inca2::GameHandler::createReader(int slot) { +	// If slot < 0, just check if a reader exists +	if (slot < 0) +		return (_reader != 0); + +	if (!_reader || (_reader->getSlot() != ((uint32) slot))) { +		Common::String slotFile = _slotFile->build(slot); + +		if (slotFile.empty()) +			return false; + +		delete _reader; + +		_reader = new SaveReader(3, slot, slotFile); + +		if (!_reader->load()) { +			delete _reader; +			_reader = 0; +			return false; +		} +	} + +	return true; +} + +bool SaveLoad_Inca2::GameHandler::createWriter(int slot) { +	// If slot < 0, just check if a writer exists +	if (slot < 0) +		return (_writer != 0); + +	if (!_writer || (_writer->getSlot() != ((uint32) slot))) { +		Common::String slotFile = _slotFile->build(slot); + +		if (slotFile.empty()) +			return false; + +		delete _writer; +		_writer = new SaveWriter(3, slot, slotFile); +	} + +	return true; +} + + +SaveLoad_Inca2::ScreenshotHandler::File::File(const SaveLoad_Inca2::GameHandler::File &file) : SaveLoad_Inca2::GameHandler::File(file) { + +} + +SaveLoad_Inca2::ScreenshotHandler::File::~File() { +} + +int SaveLoad_Inca2::ScreenshotHandler::File::getSlot(int32 offset) const { +	return (offset - 80) / 15168; +} + +int SaveLoad_Inca2::ScreenshotHandler::File::getSlotRemainder(int32 offset) const { +	return (offset - 80) % 15168; +} + +void SaveLoad_Inca2::ScreenshotHandler::File::buildIndex(byte *buffer) const { +	Common::SaveFileManager *saveMan = g_system->getSavefileManager(); +	Common::InSaveFile *in; + +	for (uint32 i = 0; i < 40; i++, buffer++) { +		Common::String slotFile = build(i); + +		if (!slotFile.empty() && ((in = saveMan->openForLoading(slotFile)))) { +			delete in; +			*buffer = 1; +		} else +			*buffer = 0; +	} +} + + +SaveLoad_Inca2::ScreenshotHandler::ScreenshotHandler(GobEngine *vm, +		GameHandler *gameHandler) : TempSpriteHandler(vm) { + +	assert(gameHandler); + +	_gameHandler = gameHandler; + +	_file = new File(*_gameHandler->_slotFile); + +	memset(_index, 0, 80); +} + +SaveLoad_Inca2::ScreenshotHandler::~ScreenshotHandler() { +	delete _file; +} + +int32 SaveLoad_Inca2::ScreenshotHandler::getSize() { +	return _file->tallyUpFiles(15168, 80); +} + +bool SaveLoad_Inca2::ScreenshotHandler::load(int16 dataVar, int32 size, int32 offset) { +	if (offset < 80) { +		// Screenshot index list + +		if ((size + offset) > 80) { +			warning("Wrong screenshot index offset (%d, %d)", size, offset); +			return false; +		} + +		// Create/Fake the index +		_file->buildIndex(_index + 40); + +		_vm->_inter->_variables->copyFrom(dataVar, _index + offset, size); + +	} else { +		// Screenshot + +		uint32 slot = _file->getSlot(offset); +		int slotRem = _file->getSlotRemainder(offset); + +		if ((slot >= kSlotCount) || (slotRem != 0)) { +			warning("Invalid screenshot loading procedure (%d, %d, %d, %d, %d)", +					dataVar, size, offset, slot, slotRem); +			return false; +		} + +		if (!TempSpriteHandler::createSprite(dataVar, size, offset)) +			return false; + +		if (!_gameHandler->loadScreenshot(slot, _sprite)) +			return false; + +		if (!TempSpriteHandler::load(dataVar, size, offset)) +			return false; +	} + +	return true; +} + +bool SaveLoad_Inca2::ScreenshotHandler::save(int16 dataVar, int32 size, int32 offset) { +	if (offset < 80) { +		// Index, we'll ignore that + +	} else { +		// Screenshot + +		uint32 slot = _file->getSlot(offset); +		int slotRem = _file->getSlotRemainder(offset); + +		if ((slot >= kSlotCount) || (slotRem != 0)) { +			warning("Invalid screenshot saving procedure (%d, %d, %d, %d, %d)", +					dataVar, size, offset, slot, slotRem); +			return false; +		} + +		if (!TempSpriteHandler::save(dataVar, size, offset)) +			return false; + +		return _gameHandler->saveScreenshot(slot, _sprite); +	} + +	return true; +} + +  SaveLoad_Inca2::VoiceHandler::VoiceHandler(GobEngine *vm) : SaveHandler(vm) {  } @@ -65,11 +387,15 @@ bool SaveLoad_Inca2::VoiceHandler::save(int16 dataVar, int32 size, int32 offset)  SaveLoad_Inca2::SaveLoad_Inca2(GobEngine *vm, const char *targetName) : SaveLoad(vm) { -	_tempSpriteHandler = new TempSpriteHandler(vm);  	_voiceHandler      = new VoiceHandler(vm); +	_tempSpriteHandler = new TempSpriteHandler(vm); +	_gameHandler       = new GameHandler(vm, targetName); +	_screenshotHandler = new ScreenshotHandler(vm, _gameHandler);  	_saveFiles[1].handler = _voiceHandler;  	_saveFiles[2].handler = _tempSpriteHandler; +	_saveFiles[3].handler = _gameHandler; +	_saveFiles[4].handler = _screenshotHandler;  }  SaveLoad_Inca2::~SaveLoad_Inca2() { | 
