aboutsummaryrefslogtreecommitdiff
path: root/engines/glk
diff options
context:
space:
mode:
authorPaul Gilbert2019-11-12 20:53:57 -0800
committerPaul Gilbert2019-11-12 20:54:06 -0800
commit536c1f0fa94982b34724c40214c91bd0b9629214 (patch)
tree5b1e06b86c7dfa7a3d9f0f1044f28251c02a5987 /engines/glk
parent92d4d43f326a196b927050353dab16b524e28cda (diff)
downloadscummvm-rg350-536c1f0fa94982b34724c40214c91bd0b9629214.tar.gz
scummvm-rg350-536c1f0fa94982b34724c40214c91bd0b9629214.tar.bz2
scummvm-rg350-536c1f0fa94982b34724c40214c91bd0b9629214.zip
GLK: ARCHETYPE: Hooking up savegame code
Diffstat (limited to 'engines/glk')
-rw-r--r--engines/glk/archetype/archetype.cpp21
-rw-r--r--engines/glk/archetype/archetype.h2
-rw-r--r--engines/glk/archetype/game_stat.cpp12
-rw-r--r--engines/glk/archetype/misc.cpp4
-rw-r--r--engines/glk/archetype/saveload.cpp10
-rw-r--r--engines/glk/archetype/sys_object.cpp34
-rw-r--r--engines/glk/quetzal.cpp2
7 files changed, 52 insertions, 33 deletions
diff --git a/engines/glk/archetype/archetype.cpp b/engines/glk/archetype/archetype.cpp
index b5ef41fdfc..204bd9fb2f 100644
--- a/engines/glk/archetype/archetype.cpp
+++ b/engines/glk/archetype/archetype.cpp
@@ -30,6 +30,7 @@
#include "glk/archetype/saveload.h"
#include "glk/archetype/sys_object.h"
#include "glk/archetype/timestamp.h"
+#include "glk/archetype/game_stat.h"
namespace Glk {
namespace Archetype {
@@ -94,13 +95,13 @@ void Archetype::deinitialize() {
}
Common::Error Archetype::readSaveData(Common::SeekableReadStream *rs) {
- // TODO
- return Common::kReadingFailed;
+ return load_game_state(rs, Object_List) ? Common::kNoError : Common::kNoGameDataFoundError;
}
Common::Error Archetype::writeGameData(Common::WriteStream *ws) {
- // TODO
- return Common::kWritingFailed;
+ save_game_state(ws, Object_List);
+
+ return Common::kNoError;
}
void Archetype::interpret() {
@@ -128,6 +129,7 @@ void Archetype::write(const String fmt, ...) {
Common::String s = Common::String::vformat(fmt.c_str(), ap);
va_end(ap);
+ _lastOutputText = s;
glk_put_buffer(s.c_str(), s.size());
}
@@ -138,10 +140,21 @@ void Archetype::writeln(const String fmt, ...) {
va_end(ap);
s += '\n';
+ _lastOutputText = s;
glk_put_buffer(s.c_str(), s.size());
}
String Archetype::readLine() {
+ // WORKAROUND: THe original archetype games prompt for save file names due to script
+ // code before calling the save/load code. It's a bit hacky, but we detect the occurance
+ // of save/load in the text just before the readLine call and skip waiting for text
+ String text = _lastOutputText;
+ text.toLowercase();
+ if (text.contains("save") || text.contains("load")) {
+ writeln();
+ return "";
+ }
+
event_t ev;
char buffer[MAX_INPUT_LINE + 1];
diff --git a/engines/glk/archetype/archetype.h b/engines/glk/archetype/archetype.h
index a54fa172de..beb67b6680 100644
--- a/engines/glk/archetype/archetype.h
+++ b/engines/glk/archetype/archetype.h
@@ -46,8 +46,8 @@ enum DebugFlag {
class Archetype : public GlkAPI {
private:
int _saveSlot;
- bool Translating;
winid_t _mainWindow;
+ String _lastOutputText;
public:
// keywords.cpp
XArrayType Literals, Vocabulary;
diff --git a/engines/glk/archetype/game_stat.cpp b/engines/glk/archetype/game_stat.cpp
index 015065a3ed..bbebed457d 100644
--- a/engines/glk/archetype/game_stat.cpp
+++ b/engines/glk/archetype/game_stat.cpp
@@ -43,7 +43,7 @@ void save_game_state(Common::WriteStream *bfile, XArrayType &objects) {
for (i = 1; i < Dynamic; ++i) {
if (index_xarray(objects, i, p)) {
ObjectPtr op = (ObjectPtr)p;
- bfile->writeUint32LE(vContSeq);
+ bfile->writeByte(vContSeq);
dump_item_list(bfile, op->attributes, EXPR_LIST);
}
@@ -51,12 +51,12 @@ void save_game_state(Common::WriteStream *bfile, XArrayType &objects) {
for (i = Dynamic; i <= (int)objects.size(); ++i) {
if (index_xarray(objects, i, p)) {
- bfile->writeUint32LE(vContSeq);
+ bfile->writeByte(vContSeq);
dump_object(bfile, (ObjectPtr)p);
}
}
- bfile->writeUint32LE(vEndSeq);
+ bfile->writeByte(vEndSeq);
}
bool load_game_state(Common::ReadStream *bfile, XArrayType &objects) {
@@ -83,7 +83,7 @@ bool load_game_state(Common::ReadStream *bfile, XArrayType &objects) {
// objects are a little different since they might vary between game states
for (i = 1; i < Dynamic; ++i) {
if (index_xarray(objects, i, p)) {
- sentinel = (StatementKind)bfile->readUint32LE();
+ sentinel = (StatementKind)bfile->readByte();
op = (ObjectPtr)p;
dispose_item_list(op->attributes, EXPR_LIST);
load_item_list(bfile, op->attributes, EXPR_LIST);
@@ -102,13 +102,13 @@ bool load_game_state(Common::ReadStream *bfile, XArrayType &objects) {
}
// sentinel has been set from before
- sentinel = (StatementKind)bfile->readUint32LE();
+ sentinel = (StatementKind)bfile->readByte();
while (sentinel == CONT_SEQ) {
load_object(bfile, op);
p = op;
append_to_xarray(objects, p);
- sentinel = (StatementKind)bfile->readUint32LE();
+ sentinel = (StatementKind)bfile->readByte();
}
if (Encryption == UNPURPLE)
diff --git a/engines/glk/archetype/misc.cpp b/engines/glk/archetype/misc.cpp
index f2c0c780ff..b0e8b41eb2 100644
--- a/engines/glk/archetype/misc.cpp
+++ b/engines/glk/archetype/misc.cpp
@@ -151,7 +151,8 @@ String formatFilename(const String &name, const String &ext, bool replace) {
void load_string(Common::ReadStream *fIn, String &the_string) {
char buffer[257];
size_t strSize = fIn->readByte();
- (void)fIn->readByte(); // Redundant second copy of the length
+ size_t strSize2 = fIn->readByte(); // Redundant second copy of the length
+ assert(strSize2 == strSize);
fIn->read(buffer, strSize);
buffer[strSize] = '\0';
@@ -163,6 +164,7 @@ void load_string(Common::ReadStream *fIn, String &the_string) {
void dump_string(Common::WriteStream *fOut, const String &the_string) {
assert(the_string.size() < 256);
fOut->writeByte(the_string.size());
+ fOut->writeByte(the_string.size());
if (Encryption == NONE) {
fOut->write(the_string.c_str(), the_string.size());
diff --git a/engines/glk/archetype/saveload.cpp b/engines/glk/archetype/saveload.cpp
index 61069e3161..dc36346cf8 100644
--- a/engines/glk/archetype/saveload.cpp
+++ b/engines/glk/archetype/saveload.cpp
@@ -36,7 +36,7 @@ void saveload_init() {
vContSeq = CONT_SEQ;
Dynamic = 0;
- Translating = true;
+ Translating = false;
}
// ===================== Forward Declarations =======================
@@ -306,7 +306,7 @@ static void walk_expr(MissionType mission, Common::Stream *bfile, ExprTree &the_
case NUMERIC:
switch (mission) {
case LOAD:
- the_expr->_data._numeric.acl_int = readStream->readUint32LE();
+ the_expr->_data._numeric.acl_int = readStream->readSint32LE();
break;
case DUMP:
writeStream->writeSint32LE(the_expr->_data._numeric.acl_int);
@@ -591,14 +591,14 @@ void load_object(Common::ReadStream *f_in, ObjectPtr &the_object) {
}
void dump_object(Common::WriteStream *f_out, const ObjectPtr the_object) {
- f_out->writeUint16LE(the_object->inherited_from);
+ f_out->writeSint16LE(the_object->inherited_from);
dump_item_list(f_out, the_object->attributes, EXPR_LIST);
dump_item_list(f_out, the_object->methods, STMT_LIST);
if (the_object->other == nullptr) {
- f_out->writeUint16LE(vEndSeq);
+ f_out->writeByte(vEndSeq);
} else {
- f_out->writeUint16LE(vContSeq);
+ f_out->writeByte(vContSeq);
dump_stmt(f_out, the_object->other);
}
}
diff --git a/engines/glk/archetype/sys_object.cpp b/engines/glk/archetype/sys_object.cpp
index ad98afbff7..784d9a4cd7 100644
--- a/engines/glk/archetype/sys_object.cpp
+++ b/engines/glk/archetype/sys_object.cpp
@@ -73,6 +73,9 @@ void send_to_system(int transport, String &strmsg, ResultType &result, ContextTy
NodePtr np;
void *p;
+ if (g_vm->shouldQuit())
+ return;
+
if (transport == OP_SEND)
the_caller = context.self;
else
@@ -266,33 +269,32 @@ void send_to_system(int transport, String &strmsg, ResultType &result, ContextTy
sys_state = IDLING;
break;
- case SAVE_STATE: {
- Common::OutSaveFile *stfile = g_system->getSavefileManager()->openForSaving(strmsg);
- if (stfile == nullptr) {
- g_vm->writeln("Error opening %s", strmsg.c_str());
+ case SAVE_STATE:
+ if (g_vm->saveGame().getCode() != Common::kNoError) {
+ g_vm->writeln("Error saving savegame");
cleanup(result);
} else {
- save_game_state(stfile, g_vm->Object_List);
result._kind = RESERVED;
result._data._reserved.keyword = RW_TRUE;
-
- stfile->finalize();
- delete stfile;
}
sys_state = IDLING;
break;
- }
case LOAD_STATE: {
- Common::InSaveFile *stfile = g_system->getSavefileManager()->openForLoading(strmsg);
- if (stfile == nullptr) {
- g_vm->writeln("Error opening %s", strmsg.c_str());
- cleanup(result);
- } else {
+ Common::ErrorCode errCode = g_vm->loadGame().getCode();
+
+ if (errCode == Common::kNoError) {
result._kind = RESERVED;
- result._data._reserved.keyword = load_game_state(stfile, g_vm->Object_List) ? RW_TRUE : RW_FALSE;
- delete stfile;
+ result._data._reserved.keyword = RW_TRUE;
+
+ } else if (errCode == Common::kNoGameDataFoundError) {
+ result._kind = RESERVED;
+ result._data._reserved.keyword = RW_FALSE;
+
+ } else {
+ g_vm->writeln("Error restoring savegame");
+ cleanup(result);
}
sys_state = IDLING;
diff --git a/engines/glk/quetzal.cpp b/engines/glk/quetzal.cpp
index 7a11a575d2..48e1ef030e 100644
--- a/engines/glk/quetzal.cpp
+++ b/engines/glk/quetzal.cpp
@@ -44,6 +44,8 @@ uint32 QuetzalBase::getInterpreterTag(InterpreterType interpType) {
return MKTAG('A', 'L', 'N', '2');
case INTERPRETER_ALAN3:
return MKTAG('A', 'L', 'N', '3');
+ case INTERPRETER_ARCHETYPE:
+ return MKTAG('A', 'R', 'C', 'H');
case INTERPRETER_FROTZ:
return MKTAG('Z', 'C', 'O', 'D');
case INTERPRETER_GEAS: