[Scummvm-git-logs] scummvm master -> f4b12285d09dbf78c2e636483b0662c4ed400fad

dreammaster paulfgilbert at gmail.com
Tue Oct 1 04:06:10 CEST 2019


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
13de2f1771 GLK: QUEST: Fleshing out savegame code, hooking to GMM
f4b12285d0 GLK: QUEST: Support loading savegames from the launcher


Commit: 13de2f177135b8f243d373c1aaa5367aaa9b1845
    https://github.com/scummvm/scummvm/commit/13de2f177135b8f243d373c1aaa5367aaa9b1845
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-30T18:20:07-07:00

Commit Message:
GLK: QUEST: Fleshing out savegame code, hooking to GMM

Changed paths:
    engines/glk/quest/geas_impl.h
    engines/glk/quest/geas_runner.h
    engines/glk/quest/geas_state.cpp
    engines/glk/quest/geas_state.h
    engines/glk/quest/quest.cpp
    engines/glk/quest/quest.h
    engines/glk/quetzal.cpp


diff --git a/engines/glk/quest/geas_impl.h b/engines/glk/quest/geas_impl.h
index 1bdbbfd..cdfe106 100644
--- a/engines/glk/quest/geas_impl.h
+++ b/engines/glk/quest/geas_impl.h
@@ -90,6 +90,7 @@ public:
 	void set_game(const String &fname);
 
 	bool is_running() const;
+	GeasState *getState() { return &state; }
 	String get_banner();
 	void run_command(String);
 	bool try_match(String s, bool, bool);
diff --git a/engines/glk/quest/geas_runner.h b/engines/glk/quest/geas_runner.h
index bc6d858..5910757 100644
--- a/engines/glk/quest/geas_runner.h
+++ b/engines/glk/quest/geas_runner.h
@@ -24,6 +24,7 @@
 #define GLK_QUEST_GEAS_RUNNER
 
 #include "glk/quest/string.h"
+#include "glk/quest/geas_state.h"
 #include "common/array.h"
 #include "common/stream.h"
 
@@ -199,6 +200,7 @@ public:
 	GeasRunner(GeasInterface *_gi) : gi(_gi) {}
 
 	virtual bool is_running() const = 0;
+	virtual GeasState *getState() = 0;
 	virtual String get_banner() = 0;
 	virtual void run_command(String) = 0;
 
diff --git a/engines/glk/quest/geas_state.cpp b/engines/glk/quest/geas_state.cpp
index 3a9b411..9319772 100644
--- a/engines/glk/quest/geas_state.cpp
+++ b/engines/glk/quest/geas_state.cpp
@@ -29,116 +29,92 @@
 namespace Glk {
 namespace Quest {
 
-Common::WriteStream &operator<< (Common::WriteStream &o, const StringMap &m) {
-	for (StringMap::iterator i = m.begin(); i != m.end(); ++i)
-		o << (*i)._key << " -> " << (*i)._value << "\n";
-
-	return o;
+void Serializer::sync(bool &b) {
+	byte v = b ? 1 : 0;
+	syncAsByte(v);
+	if (isLoading())
+		b = v != 0;
 }
 
-class GeasOutputStream {
-	Common::WriteStream *_ws;
-public:
-	GeasOutputStream &put(const String &s) {
-		_ws->writeString(s);
-		_ws->writeByte(0);
-		return *this;
-	}
-	GeasOutputStream &put(char ch) {
-		_ws->writeByte(ch);
-		return *this;
-	}
-	GeasOutputStream &put(int i) {
-		Common::String s = Common::String::format("%d", i);
-		_ws->writeString(s);
-		_ws->writeByte(0);
-		return *this;
-	}
-	GeasOutputStream &put(uint i) {
-		Common::String s = Common::String::format("%u", i);
-		_ws->writeString(s);
-		_ws->writeByte(0);
-		return *this;
-	}
-	GeasOutputStream &put(unsigned long i) {
-		Common::String s = Common::String::format("%lu", i);
-		_ws->writeString(s);
-		_ws->writeByte(0);
-		return *this;
-	}
+void Serializer::sync(String &s) {
+	Common::String str = s;
+	Common::Serializer::syncString(str);
+	if (isLoading())
+		s = String(str.c_str());
+}
+	
+void Serializer::sync(PropertyRecord &pr) {
+	sync(pr.name);
+	sync(pr.data);
+}
 
-	void write_out(const String &gameName, const String &saveName) {
-#ifdef TODO
-		ofstream ofs;
-		ofs.open(savename.c_str());
-		if (!ofs.is_open())
-			error("Unable to open \"%s\"", savename.c_str());
-		ofs << "QUEST300" << char(0) << gamename << char(0);
-		String tmp = o.str();
-		for (uint i = 0; i < tmp.size(); i ++)
-			ofs << char (255 - tmp[i]);
-		cerr << "Done writing save game\n";
-#else
-		error("TODO");
-#endif
-	}
-};
+void Serializer::sync(ObjectRecord &pr) {
+	sync(pr.name);
+	sync(pr.hidden);
+	sync(pr.invisible);
+	sync(pr.parent);
+}
 
-template <class T> void write_to(GeasOutputStream &gos, const Common::Array<T> &v) {
-	gos.put(v.size());
-	for (uint i = 0; i < v.size(); i ++)
-		write_to(gos, v[i]);
+void Serializer::sync(ExitRecord &er) {
+	sync(er.src);
+	sync(er.dest);
 }
 
-void write_to(GeasOutputStream &gos, const PropertyRecord &pr) {
-	gos.put(pr.name).put(pr.data);
+void Serializer::sync(TimerRecord &tr) {
+	sync(tr.name);
+	sync(tr.is_running);
+	syncAsUint32LE(tr.interval);
+	syncAsUint32LE(tr.timeleft);
 }
 
-void write_to(GeasOutputStream &gos, const ObjectRecord &pr) {
-	gos.put(pr.name).put(char(pr.hidden ? 0 : 1))
-	.put(char(pr.invisible ? 0 : 1)).put(pr.parent);
+void Serializer::sync(SVarRecord &svr) {
+	svr.sync(*this);
 }
 
-void write_to(GeasOutputStream &gos, const ExitRecord &er) {
-	gos.put(er.src).put(er.dest);
+void Serializer::sync(IVarRecord &ivr) {
+	ivr.sync(*this);
 }
 
-void write_to(GeasOutputStream &gos, const TimerRecord &tr) {
-	gos.put(tr.name).put(tr.is_running ? 0 : 1).put(tr.interval)
-	.put(tr.timeleft);
+void Serializer::sync(GeasState &gs) {
+	sync(gs.location);
+	sync(gs.props);
+	sync(gs.objs);
+	sync(gs.exits);
+	sync(gs.timers);
+	sync(gs.svars);
+	sync(gs.ivars);
 }
 
+/*----------------------------------------------------------------------*/
 
-void write_to(GeasOutputStream &gos, const SVarRecord &svr) {
-	gos.put(svr.name);
-	gos.put(svr.max());
-	for (uint i = 0; i < svr.size(); i ++)
-		gos.put(svr.get(i));
-}
+void SVarRecord::sync(Serializer &s) {
+	s.sync(name);
+	
+	uint count = data.size();
+	s.syncAsUint32LE(count);
+	if (s.isLoading())
+		data.resize(count);
 
-void write_to(GeasOutputStream &gos, const IVarRecord &ivr) {
-	gos.put(ivr.name);
-	gos.put(ivr.max());
-	for (uint i = 0; i < ivr.size(); i ++)
-		gos.put(ivr.get(i));
+	for (uint i = 0; i < size(); ++i)
+		s.sync(data[i]);
 }
 
-void write_to(GeasOutputStream &gos, const GeasState &gs) {
-	gos.put(gs.location);
-	write_to(gos, gs.props);
-	write_to(gos, gs.objs);
-	write_to(gos, gs.exits);
-	write_to(gos, gs.timers);
-	write_to(gos, gs.svars);
-	write_to(gos, gs.ivars);
-}
+/*----------------------------------------------------------------------*/
+
+void IVarRecord::sync(Serializer &s) {
+	s.sync(name);
 
-void save_game_to(String gamename, String savename, const GeasState &gs) {
-	GeasOutputStream gos;
-	write_to(gos, gs);
-	gos.write_out(gamename, savename);
+	uint count = data.size();
+	s.syncAsUint32LE(count);
+	if (s.isLoading())
+		data.resize(count);
+
+	for (uint i = 0; i < size(); ++i)
+		s.syncAsSint32LE(data[i]);
 }
 
+/*----------------------------------------------------------------------*/
+
 GeasState::GeasState(GeasInterface &gi, const GeasFile &gf) {
 	running = false;
 
@@ -270,12 +246,24 @@ GeasState::GeasState(GeasInterface &gi, const GeasFile &gf) {
 	cerr << "GeasState::GeasState() done with variables" << endl;
 }
 
-Common::WriteStream &operator<< (Common::WriteStream &o, const PropertyRecord &pr) {
+void GeasState::load(Common::SeekableReadStream *rs) {
+	Serializer s(rs, nullptr);
+	s.sync(*this);
+}
+
+void GeasState::save(Common::WriteStream *ws) {
+	Serializer s(nullptr, ws);
+	s.sync(*this);
+}
+
+/*----------------------------------------------------------------------*/
+
+Common::WriteStream &operator<<(Common::WriteStream &o, const PropertyRecord &pr) {
 	o << pr.name << ", data == " << pr.data;
 	return o;
 }
 
-Common::WriteStream &operator<< (Common::WriteStream &o, const ObjectRecord &objr) {
+Common::WriteStream &operator<<(Common::WriteStream &o, const ObjectRecord &objr) {
 	o << objr.name << ", parent == " << objr.parent;
 	if (objr.hidden)
 		o << ", hidden";
@@ -284,23 +272,23 @@ Common::WriteStream &operator<< (Common::WriteStream &o, const ObjectRecord &obj
 	return o;
 }
 
-Common::WriteStream &operator<< (Common::WriteStream &o, const ExitRecord er) {
+Common::WriteStream &operator<<(Common::WriteStream &o, const ExitRecord er) {
 	return o << er.src << ": " << er.dest;
 }
 
-Common::WriteStream &operator<< (Common::WriteStream &o, const TimerRecord &tr) {
+Common::WriteStream &operator<<(Common::WriteStream &o, const TimerRecord &tr) {
 	return o << tr.name << ": " << (tr.is_running ? "" : "not ") << "running ("
-	       << tr.timeleft << " // " << tr.interval << ")";
+		<< tr.timeleft << " // " << tr.interval << ")";
 }
 
-Common::WriteStream &operator<< (Common::WriteStream &o, const SVarRecord &sr) {
+Common::WriteStream &operator<<(Common::WriteStream &o, const SVarRecord &sr) {
 	o << sr.name << ": ";
 	if (sr.size() == 0)
 		o << "(empty)";
 	else if (sr.size() <= 1)
 		o << "<" << sr.get(0) << ">";
 	else
-		for (uint i = 0; i < sr.size(); i ++) {
+		for (uint i = 0; i < sr.size(); i++) {
 			o << i << ": <" << sr.get(i) << ">";
 			if (i + 1 < sr.size())
 				o << ", ";
@@ -308,14 +296,14 @@ Common::WriteStream &operator<< (Common::WriteStream &o, const SVarRecord &sr) {
 	return o;
 }
 
-Common::WriteStream &operator<< (Common::WriteStream &o, const IVarRecord &ir) {
+Common::WriteStream &operator<<(Common::WriteStream &o, const IVarRecord &ir) {
 	o << ir.name << ": ";
 	if (ir.size() == 0)
 		o << "(empty)";
 	else if (ir.size() <= 1)
 		o << ir.get(0);
 	else
-		for (uint i = 0; i < ir.size(); i ++) {
+		for (uint i = 0; i < ir.size(); i++) {
 			o << i << ": " << ir.get(i);
 			if (i + 1 < ir.size())
 				o << ", ";
@@ -323,30 +311,30 @@ Common::WriteStream &operator<< (Common::WriteStream &o, const IVarRecord &ir) {
 	return o;
 }
 
-Common::WriteStream &operator<< (Common::WriteStream &o, const GeasState &gs) {
+Common::WriteStream &operator<<(Common::WriteStream &o, const GeasState &gs) {
 	o << "location == " << gs.location << "\nprops: \n";
 
-	for (uint i = 0; i < gs.props.size(); i ++)
+	for (uint i = 0; i < gs.props.size(); i++)
 		o << "    " << i << ": " << gs.props[i] << "\n";
 
 	o << "objs:\n";
-	for (uint i = 0; i < gs.objs.size(); i ++)
+	for (uint i = 0; i < gs.objs.size(); i++)
 		o << "    " << i << ": " << gs.objs[i] << "\n";
 
 	o << "exits:\n";
-	for (uint i = 0; i < gs.exits.size(); i ++)
+	for (uint i = 0; i < gs.exits.size(); i++)
 		o << "    " << i << ": " << gs.exits[i] << "\n";
 
 	o << "timers:\n";
-	for (uint i = 0; i < gs.timers.size(); i ++)
+	for (uint i = 0; i < gs.timers.size(); i++)
 		o << "    " << i << ": " << gs.timers[i] << "\n";
 
 	o << "String variables:\n";
-	for (uint i = 0; i < gs.svars.size(); i ++)
+	for (uint i = 0; i < gs.svars.size(); i++)
 		o << "    " << i << ": " << gs.svars[i] << "\n";
 
 	o << "integer variables:\n";
-	for (uint i = 0; i < gs.svars.size(); i ++)
+	for (uint i = 0; i < gs.svars.size(); i++)
 		o << "    " << i << ": " << gs.svars[i] << "\n";
 
 	return o;
diff --git a/engines/glk/quest/geas_state.h b/engines/glk/quest/geas_state.h
index 647ee45..92d31ea 100644
--- a/engines/glk/quest/geas_state.h
+++ b/engines/glk/quest/geas_state.h
@@ -26,13 +26,21 @@
 #include "glk/quest/string.h"
 #include "common/array.h"
 #include "common/stream.h"
+#include "common/serializer.h"
 
 namespace Glk {
 namespace Quest {
 
+struct GeasFile;
+struct GeasState;
+class Serializer;
+class GeasInterface;
+
 struct PropertyRecord {
 	String name, data;
-	PropertyRecord(String in_name, String in_data) : name(in_name), data(in_data) {}
+
+	PropertyRecord() {}
+	PropertyRecord(const String &in_name, const String &in_data) : name(in_name), data(in_data) {}
 };
 
 struct ObjectRecord {
@@ -45,7 +53,9 @@ struct ObjectRecord {
 
 struct ExitRecord {
 	String src, dest;
-	ExitRecord(String in_src, String in_dest) : src(in_src), dest(in_dest) {}
+
+	ExitRecord() {}
+	ExitRecord(const String &in_src, const String &in_dest) : src(in_src), dest(in_dest) {}
 };
 
 struct TimerRecord {
@@ -84,6 +94,8 @@ public:
 	String get() const {
 		return data[0];
 	}
+
+	void sync(Serializer &s);
 };
 
 struct IVarRecord {
@@ -116,10 +128,34 @@ public:
 	int get() const {
 		return data[0];
 	}
+
+	void sync(Serializer &s);
 };
 
-struct GeasFile;
-class GeasInterface;
+class Serializer : public Common::Serializer {
+public:
+	Serializer(Common::SeekableReadStream *in, Common::WriteStream *out) : Common::Serializer(in, out) {}
+
+	void sync(bool &b);
+	void sync(String &s);
+	void sync(PropertyRecord &pr);
+	void sync(ObjectRecord &pr);
+	void sync(ExitRecord &er);
+	void sync(TimerRecord &tr);
+	void sync(SVarRecord &svr);
+	void sync(IVarRecord &ivr);
+	void sync(GeasState &gs);
+
+	template <class T> void sync(Common::Array<T> &v) {
+		uint count = v.size();
+		syncAsUint32LE(count);
+		if (isLoading())
+			v.resize(count);
+
+		for (uint idx = 0; idx < count; ++idx)
+			sync(v[idx]);
+	}
+};
 
 struct GeasState {
 	//private:
@@ -139,31 +175,27 @@ public:
 	//void register_block (String blockname, String blocktype);
 
 	GeasState() : running(false) {}
-	//GeasState (GeasRunner &, const GeasFile &);
 	GeasState(GeasInterface &, const GeasFile &);
-	/*
-	bool has_svar (string s) { for (uint i = 0; i < svars.size(); i ++) if (svars[i].name == s) return true; }
-	uint find_svar (string s) { for (uint i = 0; i < svars.size(); i ++) if (svars[i].name == s) return i; svars.push_back (SVarRecord (s)); return svars.size() - 1;}
-	string get_svar (string s, uint index) { if (!has_svar(s)) return "!"; return svars[find_svar(s)].get(index); }
-	string get_svar (string s) { return get_svar (s, 0); }
-
-	bool has_ivar (string s) { for (uint i = 0; i < ivars.size(); i ++) if (ivars[i].name == s) return true; }
-	uint find_ivar (string s) { for (uint i = 0; i < ivars.size(); i ++) if (ivars[i].name == s) return i; ivars.push_back (IVarRecord (s)); return ivars.size() - 1;}
-	int get_ivar (string s, uint index) { if (!has_ivar(s)) return -32767; return ivars[find_ivar(s)].get(index); }
-	int get_ivar (string s) { return get_ivar (s, 0); }
-	*/
-};
 
-void save_game_to(String gamename, String savename, const GeasState &gs);
+	/**
+	 * Save the state
+	 */
+	void load(Common::SeekableReadStream *rs);
+
+	/**
+	 * Save the state
+	 */
+	void save(Common::WriteStream *ws);
+};
 
-Common::WriteStream &operator<< (Common::WriteStream &o, const StringMap &m);
-Common::WriteStream &operator<< (Common::WriteStream &o, const PropertyRecord &pr);
-Common::WriteStream &operator<< (Common::WriteStream &o, const ObjectRecord &objr);
-Common::WriteStream &operator<< (Common::WriteStream &o, const ExitRecord er);
-Common::WriteStream &operator<< (Common::WriteStream &o, const TimerRecord &tr);
-Common::WriteStream &operator<< (Common::WriteStream &o, const SVarRecord &sr);
-Common::WriteStream &operator<< (Common::WriteStream &o, const IVarRecord &ir);
-Common::WriteStream &operator<< (Common::WriteStream &o, const GeasState &gs);
+Common::WriteStream &operator<<(Common::WriteStream &o, const StringMap &m);
+Common::WriteStream &operator<<(Common::WriteStream &o, const PropertyRecord &pr);
+Common::WriteStream &operator<<(Common::WriteStream &o, const ObjectRecord &objr);
+Common::WriteStream &operator<<(Common::WriteStream &o, const ExitRecord er);
+Common::WriteStream &operator<<(Common::WriteStream &o, const TimerRecord &tr);
+Common::WriteStream &operator<<(Common::WriteStream &o, const SVarRecord &sr);
+Common::WriteStream &operator<<(Common::WriteStream &o, const IVarRecord &ir);
+Common::WriteStream &operator<<(Common::WriteStream &o, const GeasState &gs);
 
 } // End of namespace Quest
 } // End of namespace Glk
diff --git a/engines/glk/quest/quest.cpp b/engines/glk/quest/quest.cpp
index 8536f69..839f58d 100644
--- a/engines/glk/quest/quest.cpp
+++ b/engines/glk/quest/quest.cpp
@@ -32,7 +32,8 @@ namespace Quest {
 
 Quest *g_vm;
 
-Quest::Quest(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc), _saveSlot(-1) {
+Quest::Quest(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
+		_saveSlot(-1), _runner(nullptr) {
 	g_vm = this;
 }
 
@@ -54,12 +55,11 @@ void Quest::playGame() {
 	char cur_buf[1024];
 	char buf[200];
 
-	GeasRunner *gr = GeasRunner::get_runner(new GeasGlkInterface());
-	gr->set_game(String(getFilename().c_str()));
-	banner = gr->get_banner();
+	_runner->set_game(String(getFilename().c_str()));
+	banner = _runner->get_banner();
 	draw_banner();
 
-	while (gr->is_running()) {
+	while (_runner->is_running()) {
 		if (inputwin != mainglkwin)
 			glk_window_clear(inputwin);
 		else
@@ -84,12 +84,12 @@ void Quest::playGame() {
 					String cmd = String(buf, ev.val1);
 					if (inputwin == mainglkwin)
 						ignore_lines = 2;
-					gr->run_command(cmd);
+					_runner->run_command(cmd);
 				}
 				break;
 
 			case evtype_Timer:
-				gr->tick_timers();
+				_runner->tick_timers();
 				break;
 
 			case evtype_Arrange:
@@ -141,11 +141,28 @@ bool Quest::initialize() {
 	glk_request_timer_events(1000);
 	ignore_lines = 0;
 
+	_runner = GeasRunner::get_runner(new GeasGlkInterface());
+
 	return true;
 }
 
 void Quest::deinitialize() {
 	Streams::deinitialize();
+
+	delete _runner;
+}
+
+Common::Error Quest::readSaveData(Common::SeekableReadStream *rs) {
+	GeasState *gs = _runner->getState();
+	gs->load(rs);
+	return Common::kNoError;
+}
+
+Common::Error Quest::writeGameData(Common::WriteStream *ws) {
+	GeasState *gs = _runner->getState();
+	gs->save(ws);
+
+	return Common::kNoError;
 }
 
 } // End of namespace Quest
diff --git a/engines/glk/quest/quest.h b/engines/glk/quest/quest.h
index cb0994d..ed8d60e 100644
--- a/engines/glk/quest/quest.h
+++ b/engines/glk/quest/quest.h
@@ -25,6 +25,7 @@
 
 #include "glk/glk_api.h"
 #include "glk/quest/string.h"
+#include "glk/quest/geas_runner.h"
 
 namespace Glk {
 namespace Quest {
@@ -35,6 +36,7 @@ namespace Quest {
 class Quest : public GlkAPI {
 private:
 	int _saveSlot;
+	GeasRunner *_runner;
 public:
 	String banner;
 private:
@@ -71,24 +73,28 @@ public:
 	}
 
 	/**
-	 * Savegames aren't supported for Quest games
+	 * Returns true if a savegame can be loaded
 	 */
-	virtual bool canLoadGameStateCurrently() override { return false; }
+	virtual bool canLoadGameStateCurrently() override {
+		return _runner != nullptr;
+	}
 
 	/**
-	 * Savegames aren't supported for Quest games
+	 * Returns true if the game can be saved
 	 */
-	virtual bool canSaveGameStateCurrently() override { return false; }
+	virtual bool canSaveGameStateCurrently() override {
+		return _runner != nullptr;
+	}
 
 	/**
 	 * Savegames aren't supported for Quest games
 	 */
-	virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override { return Common::kUnknownError; }
+	virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;
 
 	/**
 	 * Savegames aren't supported for Quest games
 	 */
-	virtual Common::Error writeGameData(Common::WriteStream *ws) override { return Common::kUnknownError; }
+	virtual Common::Error writeGameData(Common::WriteStream *ws) override;
 };
 
 extern Quest *g_vm;
diff --git a/engines/glk/quetzal.cpp b/engines/glk/quetzal.cpp
index 0a2bc44..60f683b 100644
--- a/engines/glk/quetzal.cpp
+++ b/engines/glk/quetzal.cpp
@@ -44,7 +44,7 @@ const uint32 INTERPRETER_IDS[INTERPRETER_TADS3 + 1] = {
 	MKTAG('J', 'A', 'C', 'L'),
 	MKTAG('L', 'V', 'L', '9'),
 	MKTAG('M', 'A', 'G', 'N'),
-	MKTAG('Q', 'E', 'S', 'T'),
+	MKTAG('Q', 'U', 'E', 'S'),
 	MKTAG('S', 'C', 'A', 'R'),
 	MKTAG('S', 'C', 'O', 'T'),
 	MKTAG('T', 'A', 'D', '2'),


Commit: f4b12285d09dbf78c2e636483b0662c4ed400fad
    https://github.com/scummvm/scummvm/commit/f4b12285d09dbf78c2e636483b0662c4ed400fad
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2019-09-30T19:05:48-07:00

Commit Message:
GLK: QUEST: Support loading savegames from the launcher

Changed paths:
    engines/glk/quest/geas_glk.cpp
    engines/glk/quest/quest.cpp
    engines/glk/quest/quest.h


diff --git a/engines/glk/quest/geas_glk.cpp b/engines/glk/quest/geas_glk.cpp
index 6b5f8b1..a6324fa 100644
--- a/engines/glk/quest/geas_glk.cpp
+++ b/engines/glk/quest/geas_glk.cpp
@@ -63,7 +63,8 @@ void draw_banner() {
 }
 
 void glk_put_cstring(const char *s) {
-	g_vm->glk_put_string(s);
+	if (!g_vm->loadingSavegame())
+		g_vm->glk_put_string(s);
 }
 
 GeasResult GeasGlkInterface::print_normal(const String &s) {
diff --git a/engines/glk/quest/quest.cpp b/engines/glk/quest/quest.cpp
index 839f58d..06e4c96 100644
--- a/engines/glk/quest/quest.cpp
+++ b/engines/glk/quest/quest.cpp
@@ -55,7 +55,20 @@ void Quest::playGame() {
 	char cur_buf[1024];
 	char buf[200];
 
+	// Check for savegame to load immediate
+	_saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
+
+	// Set initial game state
 	_runner->set_game(String(getFilename().c_str()));
+
+	if (_saveSlot != -1) {
+		int saveSlot = _saveSlot;
+		_saveSlot = -1;
+
+		if (loadGameState(saveSlot).getCode() == Common::kNoError)
+			_runner->run_command("look");
+	}
+
 	banner = _runner->get_banner();
 	draw_banner();
 
diff --git a/engines/glk/quest/quest.h b/engines/glk/quest/quest.h
index ed8d60e..ab6e8b8 100644
--- a/engines/glk/quest/quest.h
+++ b/engines/glk/quest/quest.h
@@ -95,6 +95,11 @@ public:
 	 * Savegames aren't supported for Quest games
 	 */
 	virtual Common::Error writeGameData(Common::WriteStream *ws) override;
+
+	/**
+	 * Returns true if a savegame is being loaded directly from the ScummVM launcher
+	 */
+	bool loadingSavegame() const { return _saveSlot != -1; }
 };
 
 extern Quest *g_vm;





More information about the Scummvm-git-logs mailing list