diff options
| -rw-r--r-- | engines/glk/POTFILES | 1 | ||||
| -rw-r--r-- | engines/glk/advsys/advsys.cpp | 6 | ||||
| -rw-r--r-- | engines/glk/advsys/advsys.h | 9 | ||||
| -rw-r--r-- | engines/glk/alan2/alan2.cpp | 8 | ||||
| -rw-r--r-- | engines/glk/alan2/alan2.h | 9 | ||||
| -rw-r--r-- | engines/glk/frotz/frotz.cpp | 37 | ||||
| -rw-r--r-- | engines/glk/frotz/frotz.h | 19 | ||||
| -rw-r--r-- | engines/glk/glk.cpp | 42 | ||||
| -rw-r--r-- | engines/glk/glk.h | 9 | ||||
| -rw-r--r-- | engines/glk/glulxe/exec.cpp | 8 | ||||
| -rw-r--r-- | engines/glk/glulxe/glulxe.h | 9 | ||||
| -rw-r--r-- | engines/glk/glulxe/serial.cpp | 18 | ||||
| -rw-r--r-- | engines/glk/hugo/hugo.cpp | 75 | ||||
| -rw-r--r-- | engines/glk/hugo/hugo.h | 9 | ||||
| -rw-r--r-- | engines/glk/magnetic/magnetic.cpp | 8 | ||||
| -rw-r--r-- | engines/glk/magnetic/magnetic.h | 9 | ||||
| -rw-r--r-- | engines/glk/quetzal.cpp | 18 | ||||
| -rw-r--r-- | engines/glk/quetzal.h | 5 | ||||
| -rw-r--r-- | engines/glk/scott/scott.cpp | 28 | ||||
| -rw-r--r-- | engines/glk/scott/scott.h | 9 | ||||
| -rw-r--r-- | engines/glk/tads/tads.cpp | 8 | ||||
| -rw-r--r-- | engines/glk/tads/tads.h | 9 | 
22 files changed, 217 insertions, 136 deletions
| diff --git a/engines/glk/POTFILES b/engines/glk/POTFILES index 2a9e70d807..cedc0e1d66 100644 --- a/engines/glk/POTFILES +++ b/engines/glk/POTFILES @@ -5,6 +5,7 @@ engines/glk/advsys/advsys.cpp  engines/glk/advsys/vm.cpp  engines/glk/alan2/alan2.cpp  engines/glk/frotz/detection.cpp +engines/glk/frotz/frotz.cpp  engines/glk/glulxe/glulxe.cpp  engines/glk/magnetic/magnetic.cpp  engines/glk/scott/scott.cpp diff --git a/engines/glk/advsys/advsys.cpp b/engines/glk/advsys/advsys.cpp index ad8412843f..51003205b1 100644 --- a/engines/glk/advsys/advsys.cpp +++ b/engines/glk/advsys/advsys.cpp @@ -102,11 +102,13 @@ bool AdvSys::singleAction() {  	return true;  } -Common::Error AdvSys::loadGameData(strid_t save) { +Common::Error AdvSys::readSaveData(Common::SeekableReadStream *rs) { +	rs->read(_saveArea, rs->size());  	return Common::kNoError;  } -Common::Error AdvSys::saveGameData(strid_t save, const Common::String &desc) { +Common::Error AdvSys::writeGameData(Common::WriteStream *ws) { +	ws->write(_saveArea, _saveSize);  	return Common::kNoError;  } diff --git a/engines/glk/advsys/advsys.h b/engines/glk/advsys/advsys.h index 688a8fe094..8b7b7fb56b 100644 --- a/engines/glk/advsys/advsys.h +++ b/engines/glk/advsys/advsys.h @@ -67,14 +67,15 @@ public:  	}  	/** -	 * Load a savegame from the passed stream +	 * Load a savegame from the passed Quetzal file chunk stream  	 */ -	virtual Common::Error loadGameData(strid_t save) override; +	virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;  	/** -	 * Save the game to the passed stream +	 * Save the game. The passed write stream represents access to the UMem chunk +	 * in the Quetzal save file that will be created  	 */ -	virtual Common::Error saveGameData(strid_t save, const Common::String &desc) override; +	virtual Common::Error writeGameData(Common::WriteStream *ws) override;  };  } // End of namespace AdvSys diff --git a/engines/glk/alan2/alan2.cpp b/engines/glk/alan2/alan2.cpp index da9dbf1115..492d425d98 100644 --- a/engines/glk/alan2/alan2.cpp +++ b/engines/glk/alan2/alan2.cpp @@ -61,14 +61,14 @@ void Alan2::runGame() {  	// TODO  } -Common::Error Alan2::loadGameData(strid_t file) { +Common::Error Alan2::readSaveData(Common::SeekableReadStream *rs) {  	// TODO -	return Common::kNoError; +	return Common::kReadingFailed;  } -Common::Error Alan2::saveGameData(strid_t file, const Common::String &desc) { +Common::Error Alan2::writeGameData(Common::WriteStream *ws) {  	// TODO -	return Common::kNoError; +	return Common::kWritingFailed;  }  bool Alan2::is_gamefile_valid() { diff --git a/engines/glk/alan2/alan2.h b/engines/glk/alan2/alan2.h index a6ded4304a..a8e500a0dd 100644 --- a/engines/glk/alan2/alan2.h +++ b/engines/glk/alan2/alan2.h @@ -68,14 +68,15 @@ public:  	virtual InterpreterType getInterpreterType() const override { return INTERPRETER_ALAN2; }  	/** -	 * Load a savegame from the passed stream +	 * Load a savegame from the passed Quetzal file chunk stream  	 */ -	virtual Common::Error loadGameData(strid_t file) override; +	virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;  	/** -	 * Save the game to the passed stream +	 * Save the game. The passed write stream represents access to the UMem chunk +	 * in the Quetzal save file that will be created  	 */ -	virtual Common::Error saveGameData(strid_t file, const Common::String &desc) override; +	virtual Common::Error writeGameData(Common::WriteStream *ws) override;  	/**  	 * Output a string to the screen diff --git a/engines/glk/frotz/frotz.cpp b/engines/glk/frotz/frotz.cpp index 0c33f417ec..02ee0900c9 100644 --- a/engines/glk/frotz/frotz.cpp +++ b/engines/glk/frotz/frotz.cpp @@ -26,6 +26,7 @@  #include "glk/frotz/quetzal.h"  #include "engines/util.h"  #include "common/config-manager.h" +#include "common/translation.h"  namespace Glk {  namespace Frotz { @@ -90,17 +91,13 @@ void Frotz::initialize() {  	z_restart();  } -Common::Error Frotz::saveGameData(strid_t file, const Common::String &desc) { -	Quetzal q(story_fp); -	bool success = q.save(*file, this, desc); +Common::Error Frotz::loadGameState(int slot) { +	FileReference ref(slot, "", fileusage_SavedGame | fileusage_TextMode); -	if (!success) -		print_string("Error writing save file\n"); +	strid_t file = _streams->openFileStream(&ref, filemode_Read); +	if (file == nullptr) +		return Common::kReadingFailed; -	return Common::kNoError; -} - -Common::Error Frotz::loadGameData(strid_t file) {  	Quetzal q(story_fp);  	bool success = q.restore(*file, this) == 2; @@ -123,14 +120,32 @@ Common::Error Frotz::loadGameData(strid_t file) {  		 * seems to cover up most of the resulting badness.  		 */  		if (h_version > V3 && h_version != V6 && (h_screen_rows != old_screen_rows -					|| h_screen_cols != old_screen_cols)) +			|| h_screen_cols != old_screen_cols))  			erase_window(1);  	} else { -		error("Error reading save file"); +		error(_("Error reading save file"));  	}  	return Common::kNoError;  } +Common::Error Frotz::saveGameState(int slot, const Common::String &desc) { +	Common::String msg; +	FileReference ref(slot, desc, fileusage_BinaryMode | fileusage_SavedGame); + +	strid_t file = _streams->openFileStream(&ref, filemode_Write); +	if (file == nullptr) +		return Common::kWritingFailed; + +	Quetzal q(story_fp); +	bool success = q.save(*file, this, desc); + +	if (!success) +		print_string(_("Error writing save file\n")); + +	return Common::kNoError; + +} +  } // End of namespace Frotz  } // End of namespace Glk diff --git a/engines/glk/frotz/frotz.h b/engines/glk/frotz/frotz.h index 8312e16b49..a8083a3093 100644 --- a/engines/glk/frotz/frotz.h +++ b/engines/glk/frotz/frotz.h @@ -72,14 +72,25 @@ public:  	virtual void runGame() override;  	/** -	 * Load a savegame from the passed stream +	 * Load a savegame from a given slot  	 */ -	virtual Common::Error loadGameData(strid_t file) override; +	virtual Common::Error loadGameState(int slot) override;  	/** -	 * Save the game to the passed stream +	 * Save the game to a given slot  	 */ -	virtual Common::Error saveGameData(strid_t file, const Common::String &desc) override; +	virtual Common::Error saveGameState(int slot, const Common::String &desc) override; + +	/** +	 * Loading method not used for Frotz sub-engine +	 */ +	virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override { return Common::kReadingFailed; } + +	/** +	 * Saving method not used for Frotz sub-engine +	 */ +	virtual Common::Error writeGameData(Common::WriteStream *ws) override { return Common::kWritingFailed; } +  };  extern Frotz *g_vm; diff --git a/engines/glk/glk.cpp b/engines/glk/glk.cpp index 7155cd8190..b3760cafd4 100644 --- a/engines/glk/glk.cpp +++ b/engines/glk/glk.cpp @@ -33,6 +33,7 @@  #include "glk/conf.h"  #include "glk/events.h"  #include "glk/picture.h" +#include "glk/quetzal.h"  #include "glk/screen.h"  #include "glk/selection.h"  #include "glk/sound.h" @@ -182,10 +183,32 @@ Common::Error GlkEngine::loadGameState(int slot) {  	if (file == nullptr)  		return Common::kReadingFailed; -	Common::Error result = loadGameData(file); +	Common::ErrorCode errCode = Common::kNoError; +	QuetzalReader r; +	if (r.open(*file, ID_IFSF)) { +		// First scan for a SCVM chunk. It has information of the game the save is for, +		// so if present we can validate the save is for this game +		for (QuetzalReader::Iterator it = r.begin(); it != r.end(); ++it) { +			if ((*it)._id == ID_SCVM) { + +			} +		} + +		if (errCode != Common::kNoError) { +			// Scan for an uncompressed memory chunk +			errCode = Common::kReadingFailed;		// Presume we won't find chunk +			for (QuetzalReader::Iterator it = r.begin(); it != r.end(); ++it) { +				if ((*it)._id == ID_UMem) { +					Common::SeekableReadStream *rs = it.getStream(); +					errCode = readSaveData(rs).getCode(); +					delete rs; +				} +			} +		} +	}  	file->close(); -	return result; +	return errCode;  }  Common::Error GlkEngine::saveGameState(int slot, const Common::String &desc) { @@ -196,10 +219,21 @@ Common::Error GlkEngine::saveGameState(int slot, const Common::String &desc) {  	if (file == nullptr)  		return Common::kWritingFailed; -	Common::Error result = saveGameData(file, desc); +	Common::ErrorCode errCode = Common::kNoError; +	QuetzalWriter w; + +	// Add the uncompressed memory chunk with the game's save data +	{ +		Common::WriteStream &ws = w.add(ID_UMem); +		errCode = writeGameData(&ws).getCode(); +	} + +	if (errCode != Common::kNoError) { +		w.save(*file, desc); +	}  	file->close(); -	return result; +	return errCode;  }  void GlkEngine::beep() { diff --git a/engines/glk/glk.h b/engines/glk/glk.h index f96f384027..739f1774d9 100644 --- a/engines/glk/glk.h +++ b/engines/glk/glk.h @@ -198,14 +198,15 @@ public:  	virtual Common::Error saveGameState(int slot, const Common::String &desc) override;  	/** -	 * Load a savegame from the passed file +	 * Load a savegame from the passed Quetzal file chunk stream  	 */ -	virtual Common::Error loadGameData(strid_t file) = 0; +	virtual Common::Error readSaveData(Common::SeekableReadStream *rs) = 0;  	/** -	 * Save the game to the passed file +	 * Save the game. The passed write stream represents access to the UMem chunk +	 * in the Quetzal save file that will be created  	 */ -	virtual Common::Error saveGameData(strid_t file, const Common::String &desc) = 0; +	virtual Common::Error writeGameData(Common::WriteStream *ws) = 0;  	/**  	 * Generate a beep diff --git a/engines/glk/glulxe/exec.cpp b/engines/glk/glulxe/exec.cpp index 5fd15a3be6..cd26241700 100644 --- a/engines/glk/glulxe/exec.cpp +++ b/engines/glk/glulxe/exec.cpp @@ -681,12 +681,20 @@ PerformJump: /* goto label for successful jumping... ironic, no? */  			case op_save:  				push_callstub(inst[1].desttype, inst[1].value); +#ifdef TODO  				value = saveGameData(find_stream_by_id(inst[0].value), "Savegame").getCode() == Common::kNoError ? 0 : 1; +#else +				error("TODO"); +#endif  				pop_callstub(value);  				break;  			case op_restore: +#ifdef TODO  				value = loadGameData(find_stream_by_id(inst[0].value)).getCode() == Common::kNoError ? 0 : 1; +#else +				error("TODO"); +#endif  				if (value == 0) {  					/* We've succeeded, and the stack now contains the callstub  					   saved during saveundo. Ignore this opcode's operand. */ diff --git a/engines/glk/glulxe/glulxe.h b/engines/glk/glulxe/glulxe.h index 56a912eeca..bf1bad9afe 100644 --- a/engines/glk/glulxe/glulxe.h +++ b/engines/glk/glulxe/glulxe.h @@ -407,14 +407,15 @@ public:  	}  	/** -	 * Load a savegame from the passed stream +	 * Load a savegame from the passed Quetzal file chunk stream  	 */ -	virtual Common::Error loadGameData(strid_t str) override; +	virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;  	/** -	 * Save the game to the passed stream +	 * Save the game. The passed write stream represents access to the UMem chunk +	 * in the Quetzal save file that will be created  	 */ -	virtual Common::Error saveGameData(strid_t str, const Common::String &desc) override; +	virtual Common::Error writeGameData(Common::WriteStream *ws) override;  	/**  	 * \defgroup Main access methods diff --git a/engines/glk/glulxe/serial.cpp b/engines/glk/glulxe/serial.cpp index d485160302..81cfa9e41b 100644 --- a/engines/glk/glulxe/serial.cpp +++ b/engines/glk/glulxe/serial.cpp @@ -232,13 +232,13 @@ uint Glulxe::perform_restoreundo() {  	return res;  } -Common::Error Glulxe::saveGameData(strid_t str, const Common::String &desc) { +Common::Error Glulxe::writeGameData(Common::WriteStream *ws) {  	dest_t dest;  	int ix; -	uint res, lx, val; +	uint res = 0, lx, val;  	uint memstart = 0, memlen = 0, stackstart = 0, stacklen = 0;  	uint heapstart = 0, heaplen = 0, filestart = 0, filelen = 0; - +#ifdef TODO  	stream_get_iosys(&val, &lx);  	if (val != 2) {  		/* Not using the Glk I/O system, so bail. This function only @@ -246,14 +246,14 @@ Common::Error Glulxe::saveGameData(strid_t str, const Common::String &desc) {  		fatal_error("Streams are only available in Glk I/O system.");  	} -	if (str == nullptr) +	if (ws == nullptr)  		return Common::kUnknownError;  	dest.ismem = false;  	dest.size = 0;  	dest.pos = 0;  	dest.ptr = nullptr; -	dest.str = str; +	dest.str = ws;  	res = 0; @@ -357,11 +357,11 @@ Common::Error Glulxe::saveGameData(strid_t str, const Common::String &desc) {  	}  	/* All done. */ - +#endif  	return res ? Common::kUnknownError : Common::kNoError;  } -Common::Error Glulxe::loadGameData(strid_t str) { +Common::Error Glulxe::readSaveData(Common::SeekableReadStream *rs) {  	dest_t dest;  	int ix;  	uint lx, res, val; @@ -369,7 +369,7 @@ Common::Error Glulxe::loadGameData(strid_t str) {  	uint heapsumlen = 0;  	uint *heapsumarr = nullptr;  	bool fromshell = false; - +#ifdef TODO  	/* If profiling is enabled and active then fail. */  #if VM_PROFILING  	if (profile_profiling_active()) @@ -475,7 +475,7 @@ Common::Error Glulxe::loadGameData(strid_t str) {  	if (res)  		return Common::kUnknownError; - +#endif  	return Common::kNoError;  } diff --git a/engines/glk/hugo/hugo.cpp b/engines/glk/hugo/hugo.cpp index cd4660d0ef..72db1a2489 100644 --- a/engines/glk/hugo/hugo.cpp +++ b/engines/glk/hugo/hugo.cpp @@ -152,7 +152,7 @@ void Hugo::runGame() {  	hugo_closefiles();  } -Common::Error Hugo::loadGameData(strid_t save) { +Common::Error Hugo::readSaveData(Common::SeekableReadStream *rs) {  	char testid[3], testserial[9];  	int lbyte, hbyte;  	int j; @@ -160,18 +160,18 @@ Common::Error Hugo::loadGameData(strid_t save) {  	long i;  	/* Check ID */ -	testid[0] = (char)hugo_fgetc(save); -	testid[1] = (char)hugo_fgetc(save); +	testid[0] = (char)hugo_fgetc(rs); +	testid[1] = (char)hugo_fgetc(rs);  	testid[2] = '\0'; -	if (hugo_ferror(save)) goto RestoreError; +	if (hugo_ferror(rs)) goto RestoreError;  	if (strcmp(testid, id)) { -		GUIErrorMessage("Incorrect save file."); +		GUIErrorMessage("Incorrect rs file.");  		goto RestoreError;  	}  	/* Check serial number */ -	if (!hugo_fgets(testserial, 9, save)) goto RestoreError; +	if (!hugo_fgets(testserial, 9, rs)) goto RestoreError;  	if (strcmp(testserial, serial))  	{  		GUIErrorMessage("Save file created by different version."); @@ -181,7 +181,7 @@ Common::Error Hugo::loadGameData(strid_t save) {  	/* Restore variables */  	for (k=0; k<MAXGLOBALS+MAXLOCALS; k++)  	{ -		if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) +		if ((lbyte = hugo_fgetc(rs))==EOF || (hbyte = hugo_fgetc(rs))==EOF)  			goto RestoreError;  		var[k] = lbyte + hbyte * 256;  	} @@ -193,11 +193,11 @@ Common::Error Hugo::loadGameData(strid_t save) {  	while (i<codeend-(long)(objtable*16L))  	{ -		if ((hbyte = hugo_fgetc(save))==EOF && hugo_ferror(save)) goto RestoreError; +		if ((hbyte = hugo_fgetc(rs))==EOF && hugo_ferror(rs)) goto RestoreError;  		if (hbyte==0)  		{ -			if ((lbyte = hugo_fgetc(save))==EOF && hugo_ferror(save)) goto RestoreError; +			if ((lbyte = hugo_fgetc(rs))==EOF && hugo_ferror(rs)) goto RestoreError;  			SETMEM(objtable*16L+i, (unsigned char)lbyte);  			i++; @@ -217,28 +217,25 @@ Common::Error Hugo::loadGameData(strid_t save) {  	}  	/* Restore undo data */ -	if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) +	if ((lbyte = hugo_fgetc(rs))==EOF || (hbyte = hugo_fgetc(rs))==EOF)  		goto RestoreError;  	undosize = lbyte + hbyte*256;  	/* We can only restore undo data if it was saved by a port with  	   the same MAXUNDO as us */ -	if (undosize==MAXUNDO) -	{ -		for (k=0; k<MAXUNDO; k++) -		{ -			for (j=0; j<5; j++) -			{ -				if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) +	if (undosize == MAXUNDO) { +		for (k = 0; k < MAXUNDO; k++) { +			for (j=0; j<5; j++) { +				if ((lbyte = hugo_fgetc(rs))==EOF || (hbyte = hugo_fgetc(rs))==EOF)  					goto RestoreError;  				undostack[k][j] = lbyte + hbyte*256;  			}  		} -		if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) goto RestoreError; +		if ((lbyte = hugo_fgetc(rs))==EOF || (hbyte = hugo_fgetc(rs))==EOF) goto RestoreError;  		undoptr = lbyte + hbyte*256; -		if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) goto RestoreError; +		if ((lbyte = hugo_fgetc(rs))==EOF || (hbyte = hugo_fgetc(rs))==EOF) goto RestoreError;  		undoturn = lbyte + hbyte*256; -		if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) goto RestoreError; +		if ((lbyte = hugo_fgetc(rs))==EOF || (hbyte = hugo_fgetc(rs))==EOF) goto RestoreError;  		undoinvalid = (unsigned char)lbyte, undorecord = (unsigned char)hbyte;  	}  	else undoinvalid = true; @@ -249,32 +246,31 @@ RestoreError:  	return Common::kReadingFailed;  } -Common::Error Hugo::saveGameData(strid_t save, const Common::String &desc) { +Common::Error Hugo::writeGameData(Common::WriteStream *ws) {  	int c, j;  	int lbyte, hbyte;  	long i;  	int samecount = 0;  	/* Write ID */ -	if (hugo_fputc(id[0], save) == EOF || hugo_fputc(id[1], save) == EOF) goto SaveError; +	if (hugo_fputc(id[0], ws) == EOF || hugo_fputc(id[1], ws) == EOF) goto SaveError;  	/* Write serial number */ -	if (hugo_fputs(serial, save) == EOF) goto SaveError; +	if (hugo_fputs(serial, ws) == EOF) goto SaveError;  	/* Save variables */  	for (c = 0; c<MAXGLOBALS + MAXLOCALS; c++)  	{  		hbyte = (unsigned int)var[c] / 256;  		lbyte = (unsigned int)var[c] - hbyte * 256; -		if (hugo_fputc(lbyte, save) == EOF || hugo_fputc(hbyte, save) == EOF) goto SaveError; +		if (hugo_fputc(lbyte, ws) == EOF || hugo_fputc(hbyte, ws) == EOF) goto SaveError;  	}  	/* Save objtable to end of code space */  	if (hugo_fseek(game, objtable * 16L, SEEK_SET)) goto SaveError; -	for (i = 0; i <= codeend - (long)(objtable * 16L); i++) -	{ +	for (i = 0; i <= codeend - (long)(objtable * 16L); i++) {  		if ((lbyte = hugo_fgetc(game)) == EOF) goto SaveError;  		hbyte = MEM(objtable * 16L + i); @@ -282,45 +278,42 @@ Common::Error Hugo::saveGameData(strid_t save, const Common::String &desc) {  		if (lbyte == hbyte && samecount<255) samecount++;  		/* If memory differs (or samecount exceeds 1 byte) */ -		else -		{ +		else {  			if (samecount) -				if (hugo_fputc(samecount, save) == EOF) goto SaveError; +				if (hugo_fputc(samecount, ws) == EOF) goto SaveError;  			if (lbyte != hbyte)  			{ -				if (hugo_fputc(0, save) == EOF) goto SaveError; -				if (hugo_fputc(hbyte, save) == EOF) goto SaveError; +				if (hugo_fputc(0, ws) == EOF) goto SaveError; +				if (hugo_fputc(hbyte, ws) == EOF) goto SaveError;  				samecount = 0;  			}  			else samecount = 1;  		}  	}  	if (samecount) -		if (hugo_fputc(samecount, save) == EOF) goto SaveError; +		if (hugo_fputc(samecount, ws) == EOF) goto SaveError;  	/* Save undo data */  	/* Save the number of turns in this port's undo stack */  	hbyte = (unsigned int)MAXUNDO / 256;  	lbyte = (unsigned int)MAXUNDO - hbyte * 256; -	if (hugo_fputc(lbyte, save) == EOF || hugo_fputc(hbyte, save) == EOF) +	if (hugo_fputc(lbyte, ws) == EOF || hugo_fputc(hbyte, ws) == EOF)  		goto SaveError; -	for (c = 0; c<MAXUNDO; c++) -	{ -		for (j = 0; j<5; j++) -		{ +	for (c = 0; c < MAXUNDO; c++) { +		for (j = 0; j < 5; j++) {  			hbyte = (unsigned int)undostack[c][j] / 256;  			lbyte = (unsigned int)undostack[c][j] - hbyte * 256; -			if (hugo_fputc(lbyte, save) == EOF || hugo_fputc(hbyte, save) == EOF) +			if (hugo_fputc(lbyte, ws) == EOF || hugo_fputc(hbyte, ws) == EOF)  				goto SaveError;  		}  	} -	if (hugo_fputc(undoptr - (undoptr / 256) * 256, save) == EOF || hugo_fputc(undoptr / 256, save) == EOF) +	if (hugo_fputc(undoptr - (undoptr / 256) * 256, ws) == EOF || hugo_fputc(undoptr / 256, ws) == EOF)  		goto SaveError; -	if (hugo_fputc(undoturn - (undoturn / 256) * 256, save) == EOF || hugo_fputc(undoturn / 256, save) == EOF) +	if (hugo_fputc(undoturn - (undoturn / 256) * 256, ws) == EOF || hugo_fputc(undoturn / 256, ws) == EOF)  		goto SaveError; -	if (hugo_fputc(undoinvalid, save) == EOF || hugo_fputc(undorecord, save) == EOF) +	if (hugo_fputc(undoinvalid, ws) == EOF || hugo_fputc(undorecord, ws) == EOF)  		goto SaveError;  	return Common::kNoError; diff --git a/engines/glk/hugo/hugo.h b/engines/glk/hugo/hugo.h index f2d83b895b..1cd1682344 100644 --- a/engines/glk/hugo/hugo.h +++ b/engines/glk/hugo/hugo.h @@ -1191,14 +1191,15 @@ public:  	virtual InterpreterType getInterpreterType() const override { return INTERPRETER_HUGO; }  	/** -	 * Load a savegame from the passed stream +	 * Load a savegame from the passed Quetzal file chunk stream  	 */ -	virtual Common::Error loadGameData(strid_t save) override; +	virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;  	/** -	 * Save the game to the passed stream +	 * Save the game. The passed write stream represents access to the UMem chunk +	 * in the Quetzal save file that will be created  	 */ -	virtual Common::Error saveGameData(strid_t save, const Common::String &desc) override; +	virtual Common::Error writeGameData(Common::WriteStream *ws) override;  };  } // End of namespace Hugo diff --git a/engines/glk/magnetic/magnetic.cpp b/engines/glk/magnetic/magnetic.cpp index c658b8c5fd..7bd3fd686d 100644 --- a/engines/glk/magnetic/magnetic.cpp +++ b/engines/glk/magnetic/magnetic.cpp @@ -58,14 +58,14 @@ void Magnetic::runGame() {  	// TODO  } -Common::Error Magnetic::loadGameData(strid_t file) { +Common::Error Magnetic::readSaveData(Common::SeekableReadStream *rs) {  	// TODO -	return Common::kNoError; +	return Common::kReadingFailed;  } -Common::Error Magnetic::saveGameData(strid_t file, const Common::String &desc) { +Common::Error Magnetic::writeGameData(Common::WriteStream *ws) {  	// TODO -	return Common::kNoError; +	return Common::kWritingFailed;  }  bool Magnetic::is_gamefile_valid() { diff --git a/engines/glk/magnetic/magnetic.h b/engines/glk/magnetic/magnetic.h index 04f13331bf..c926ede9e6 100644 --- a/engines/glk/magnetic/magnetic.h +++ b/engines/glk/magnetic/magnetic.h @@ -191,14 +191,15 @@ public:  	virtual InterpreterType getInterpreterType() const override { return INTERPRETER_MAGNETIC; }  	/** -	 * Load a savegame from the passed stream +	 * Load a savegame from the passed Quetzal file chunk stream  	 */ -	virtual Common::Error loadGameData(strid_t file) override; +	virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;  	/** -	 * Save the game to the passed stream +	 * Save the game. The passed write stream represents access to the UMem chunk +	 * in the Quetzal save file that will be created  	 */ -	virtual Common::Error saveGameData(strid_t file, const Common::String &desc) override; +	virtual Common::Error writeGameData(Common::WriteStream *ws) override;  };  } // End of namespace Magnetic diff --git a/engines/glk/quetzal.cpp b/engines/glk/quetzal.cpp index 1dd93a892d..ae81d8818d 100644 --- a/engines/glk/quetzal.cpp +++ b/engines/glk/quetzal.cpp @@ -29,15 +29,6 @@  namespace Glk { -static Common::String readString(Common::ReadStream *src) { -	char c; -	Common::String result; -	while ((c = src->readByte()) != 0) -		result += c; - -	return result; -} -  void QuetzalReader::clear() {  	_chunks.clear();  	_stream = nullptr; @@ -141,6 +132,15 @@ bool QuetzalReader::getSavegameMetaInfo(Common::SeekableReadStream *rs, SaveStat  	return true;  } +Common::String QuetzalReader::readString(Common::ReadStream *src) { +	char c; +	Common::String result; +	while ((c = src->readByte()) != 0) +		result += c; + +	return result; +} +  /*--------------------------------------------------------------------------*/  Common::WriteStream &QuetzalWriter::add(uint32 chunkId) { diff --git a/engines/glk/quetzal.h b/engines/glk/quetzal.h index b398571f38..7f2dd30a71 100644 --- a/engines/glk/quetzal.h +++ b/engines/glk/quetzal.h @@ -143,6 +143,11 @@ public:  	 * Loads a Quetzal save and extract's it's description and meta info  	 */  	static bool getSavegameMetaInfo(Common::SeekableReadStream *rs, SaveStateDescriptor &ssd); + +	/** +	 * Support method for reading a string from a stream +	 */ +	static Common::String readString(Common::ReadStream *src);  };  /** diff --git a/engines/glk/scott/scott.cpp b/engines/glk/scott/scott.cpp index b918f8cda2..11b01c9e7e 100644 --- a/engines/glk/scott/scott.cpp +++ b/engines/glk/scott/scott.cpp @@ -21,6 +21,7 @@   */  #include "glk/scott/scott.h" +#include "glk/quetzal.h"  #include "common/config-manager.h"  #include "common/translation.h" @@ -508,41 +509,44 @@ void Scott::lineInput(char *buf, size_t n) {  	buf[ev.val1] = 0;  } -Common::Error Scott::saveGameData(strid_t file, const Common::String &desc) { +Common::Error Scott::writeGameData(Common::WriteStream *ws) {  	Common::String msg;  	for (int ct = 0; ct < 16; ct++) {  		msg = Common::String::format("%d %d\n", _counters[ct], _roomSaved[ct]); -		glk_put_string_stream(file, msg.c_str()); +		ws->write(msg.c_str(), msg.size()); +		ws->writeByte(0);  	}  	msg = Common::String::format("%u %d %d %d %d %d\n",  								 _bitFlags, (_bitFlags & (1 << DARKBIT)) ? 1 : 0,  								 MY_LOC, _currentCounter, _savedRoom, _gameHeader._lightTime); -	glk_put_string_stream(file, msg.c_str()); +	ws->write(msg.c_str(), msg.size()); +	ws->writeByte(0);  	for (int ct = 0; ct <= _gameHeader._numItems; ct++) {  		msg = Common::String::format("%hd\n", (short)_items[ct]._location); -		glk_put_string_stream(file, msg.c_str()); +		ws->write(msg.c_str(), msg.size()); +		ws->writeByte(0);  	}  	output(_("Saved.\n"));  	return Common::kNoError;  } -Common::Error Scott::loadGameData(strid_t file) { -	char buf[128]; +Common::Error Scott::readSaveData(Common::SeekableReadStream *rs) { +	Common::String line;  	int ct = 0;  	short lo;  	short darkFlag;  	for (ct = 0; ct < 16; ct++) { -		glk_get_line_stream(file, buf, sizeof buf); -		sscanf(buf, "%d %d", &_counters[ct], &_roomSaved[ct]); +		line = QuetzalReader::readString(rs); +		sscanf(line.c_str(), "%d %d", &_counters[ct], &_roomSaved[ct]);  	} -	glk_get_line_stream(file, buf, sizeof buf); -	sscanf(buf, "%u %hd %d %d %d %d\n", +	line = QuetzalReader::readString(rs); +	sscanf(line.c_str(), "%u %hd %d %d %d %d\n",  		   &_bitFlags, &darkFlag, &MY_LOC, &_currentCounter, &_savedRoom,  		   &_gameHeader._lightTime); @@ -550,8 +554,8 @@ Common::Error Scott::loadGameData(strid_t file) {  	if (darkFlag)  		_bitFlags |= (1 << 15);  	for (ct = 0; ct <= _gameHeader._numItems; ct++) { -		glk_get_line_stream(file, buf, sizeof buf); -		sscanf(buf, "%hd\n", &lo); +		line = QuetzalReader::readString(rs); +		sscanf(line.c_str(), "%hd\n", &lo);  		_items[ct]._location = (unsigned char)lo;  	} diff --git a/engines/glk/scott/scott.h b/engines/glk/scott/scott.h index 4739e9470a..b7527fe6fc 100644 --- a/engines/glk/scott/scott.h +++ b/engines/glk/scott/scott.h @@ -177,14 +177,15 @@ public:  	virtual void runGame() override;  	/** -	 * Load a savegame from the passed stream +	 * Load a savegame from the passed Quetzal file chunk stream  	 */ -	virtual Common::Error loadGameData(strid_t file) override; +	virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;  	/** -	 * Save the game to the passed stream +	 * Save the game. The passed write stream represents access to the UMem chunk +	 * in the Quetzal save file that will be created  	 */ -	virtual Common::Error saveGameData(strid_t file, const Common::String &desc) override; +	virtual Common::Error writeGameData(Common::WriteStream *ws) override;  };  } // End of namespace Scott diff --git a/engines/glk/tads/tads.cpp b/engines/glk/tads/tads.cpp index 6ce2915469..fc598dbf4a 100644 --- a/engines/glk/tads/tads.cpp +++ b/engines/glk/tads/tads.cpp @@ -42,14 +42,14 @@ bool TADS::hasFeature(EngineFeature f) const {  	return GlkAPI::hasFeature(f);  } -Common::Error TADS::loadGameData(strid_t file) { +Common::Error TADS::readSaveData(Common::SeekableReadStream *rs) {  	// TODO -	return Common::kNoError; +	return Common::kReadingFailed;  } -Common::Error TADS::saveGameData(strid_t file, const Common::String &desc) { +Common::Error TADS::writeGameData(Common::WriteStream *ws) {  	// TODO -	return Common::kNoError; +	return Common::kWritingFailed;  }  } // End of namespace TADS diff --git a/engines/glk/tads/tads.h b/engines/glk/tads/tads.h index 6ad8780a2b..f30cf9f10d 100644 --- a/engines/glk/tads/tads.h +++ b/engines/glk/tads/tads.h @@ -54,14 +54,15 @@ public:  	virtual bool hasFeature(EngineFeature f) const override;  	/** -	 * Load a savegame from the passed stream +	 * Load a savegame from the passed Quetzal file chunk stream  	 */ -	virtual Common::Error loadGameData(strid_t file) override; +	virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;  	/** -	 * Save the game to the passed stream +	 * Save the game. The passed write stream represents access to the UMem chunk +	 * in the Quetzal save file that will be created  	 */ -	virtual Common::Error saveGameData(strid_t file, const Common::String &desc) override; +	virtual Common::Error writeGameData(Common::WriteStream *ws) override;  };  extern TADS *g_vm; | 
