aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2019-06-26 20:34:53 -0700
committerPaul Gilbert2019-07-06 15:27:08 -0700
commit86f9985951203ed39e1a6c08e32730b478b10517 (patch)
tree6122934dcfb4ca6e0521e058f78f4c41c49fe4dd /engines
parentdc40211ec5e54d01f7cb822940714ed6e6da36d5 (diff)
downloadscummvm-rg350-86f9985951203ed39e1a6c08e32730b478b10517.tar.gz
scummvm-rg350-86f9985951203ed39e1a6c08e32730b478b10517.tar.bz2
scummvm-rg350-86f9985951203ed39e1a6c08e32730b478b10517.zip
GLK: ALAN3: Re-enable main game loop
Diffstat (limited to 'engines')
-rw-r--r--engines/glk/alan3/alan3.cpp54
-rw-r--r--engines/glk/alan3/alan3.h16
-rw-r--r--engines/glk/alan3/jumps.h85
-rw-r--r--engines/glk/alan3/main.cpp120
-rw-r--r--engines/glk/alan3/main.h3
5 files changed, 179 insertions, 99 deletions
diff --git a/engines/glk/alan3/alan3.cpp b/engines/glk/alan3/alan3.cpp
index 4dd91919ac..3958bf26af 100644
--- a/engines/glk/alan3/alan3.cpp
+++ b/engines/glk/alan3/alan3.cpp
@@ -41,12 +41,16 @@ namespace Alan3 {
Alan3 *g_vm = nullptr;
Alan3::Alan3(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gameDesc),
- vm_exited_cleanly(false), _restartFlag(false), _saveSlot(-1), _pendingLook(false) {
+ vm_exited_cleanly(false), _saveSlot(-1), _pendingLook(false) {
g_vm = this;
+
+ // main
+ codfil = nullptr;
// txtfil = nullptr;
// logfil = nullptr;
memory = nullptr;
+ // options
verboseOption = false;
ignoreErrorOption = false;
debugOption = false;
@@ -86,33 +90,31 @@ bool Alan3::initialize() {
glkStatusWin = g_vm->glk_window_open(glkMainWin, winmethod_Above |
winmethod_Fixed, 1, wintype_TextGrid, 0);
g_vm->glk_set_window(glkMainWin);
+
+ // Set up the code file to point to the already opened game file
+ codfil = &_gameFile;
/*
- // Set up the code file to point to the already opened game file
- codfil = &_gameFile;
- strncpy(codfnm, getFilename().c_str(), 255);
- codfnm[255] = '\0';
-
- if (_gameFile.size() < 8) {
- GUIErrorMessage(_("This is too short to be a valid Alan3 file."));
- return false;
- }
-
- if (_gameFile.readUint32BE() != MKTAG(2, 8, 1, 0)) {
- GUIErrorMessage(_("This is not a valid Alan3 file."));
- return false;
- }
-
- // Open up the text file
- txtfil = new Common::File();
- if (!txtfil->open(Common::String::format("%s.dat", _advName.c_str()))) {
- GUIErrorMessage("Could not open adventure text data file");
- delete txtfil;
- return false;
- }
-
- // Check for a save being loaded directly from the launcher
- _saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
+ if (_gameFile.size() < 8) {
+ GUIErrorMessage(_("This is too short to be a valid Alan3 file."));
+ return false;
+ }
+
+ if (_gameFile.readUint32BE() != MKTAG(2, 8, 1, 0)) {
+ GUIErrorMessage(_("This is not a valid Alan3 file."));
+ return false;
+ }
+
+ // Open up the text file
+ txtfil = new Common::File();
+ if (!txtfil->open(Common::String::format("%s.dat", _advName.c_str()))) {
+ GUIErrorMessage("Could not open adventure text data file");
+ delete txtfil;
+ return false;
+ }
*/
+ // Check for a save being loaded directly from the launcher
+ _saveSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
+
return true;
}
diff --git a/engines/glk/alan3/alan3.h b/engines/glk/alan3/alan3.h
index f4bb7a5ddf..6693476b3c 100644
--- a/engines/glk/alan3/alan3.h
+++ b/engines/glk/alan3/alan3.h
@@ -32,8 +32,6 @@ namespace Alan3 {
* Alan3 game interpreter
*/
class Alan3 : public GlkAPI {
-private:
- bool _restartFlag;
public:
bool vm_exited_cleanly;
Common::String _advName;
@@ -66,20 +64,6 @@ public:
void runGame();
/**
- * Flag for the game to restart
- */
- void setRestart(bool flag) {
- _restartFlag = flag;
- }
-
- /**
- * Returns whether the game should restart
- */
- bool shouldRestart() const {
- return _restartFlag;
- }
-
- /**
* Returns the running interpreter type
*/
virtual InterpreterType getInterpreterType() const override {
diff --git a/engines/glk/alan3/jumps.h b/engines/glk/alan3/jumps.h
new file mode 100644
index 0000000000..882ffbd2fd
--- /dev/null
+++ b/engines/glk/alan3/jumps.h
@@ -0,0 +1,85 @@
+/* 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.
+ *
+ */
+
+#ifndef GLK_ALAN2_JUMPS
+#define GLK_ALAN2_JUMPS
+
+/* This provides a simplified version of the ScummVM coroutines to allow for automated
+ * breakouts to the main game loop from subroutinese rather than using unportable setjmps
+ */
+
+namespace Glk {
+namespace Alan3 {
+
+/**
+ * Context used for flagging when a break to the outer game loop
+ */
+struct Context {
+ bool _break;
+ Common::String _label;
+
+ /**
+ * Constructor
+ */
+ Context() : _break(false) {}
+
+ /**
+ * Clear
+ */
+ void clear() {
+ _break = false;
+ _label = "";
+ }
+};
+
+#define CALL0(METHOD) { METHOD(context); if (context._break) return; }
+#define CALL1(METHOD, P1) { METHOD(context, P1); if (context._break) return; }
+#define CALL2(METHOD, P1, P2) { METHOD(context, P2); if (context._break) return; }
+#define CALL3(METHOD, P1, P2, P3) { METHOD(context, P3); if (context._break) return; }
+#define CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, P4); if (context._break) return; }
+#define FUNC0(METHOD, RET) { RET = METHOD(context); if (context._break) return; }
+#define FUNC1(METHOD, RET, P1) { RET = METHOD(context, P1); if (context._break) return; }
+#define FUNC2(METHOD, RET, P1, P2) { RET = METHOD(context, P2); if (context._break) return; }
+#define FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P3); if (context._break) return; }
+#define FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, P4); if (context._break) return; }
+
+#define R0CALL0(METHOD) { METHOD(context); if (context._break) return 0; }
+#define R0CALL1(METHOD, P1) { METHOD(context, P1); if (context._break) return 0; }
+#define R0CALL2(METHOD, P1, P2) { METHOD(context, P2); if (context._break) return 0; }
+#define R0CALL3(METHOD, P1, P2, P3) { METHOD(context, P3); if (context._break) return 0; }
+#define R0CALL4(METHOD, P1, P2, P3, P4) { METHOD(context, P4); if (context._break) return 0; }
+#define R0FUNC0(METHOD, RET) { RET = METHOD(context); if (context._break) return 0; }
+#define R0FUNC1(METHOD, RET, P1) { RET = METHOD(context, P1); if (context._break) return 0; }
+#define R0FUNC2(METHOD, RET, P1, P2) { RET = METHOD(context, P2); if (context._break) return 0; }
+#define R0FUNC3(METHOD, RET, P1, P2, P3) { RET = METHOD(context, P3); if (context._break) return 0; }
+#define R0FUNC4(METHOD, RET, P1, P2, P3, P4) { RET = METHOD(context, P4); if (context._break) return 0; }
+
+#define CONTEXT Context &context
+#define LONG_JUMP { context._break = true; context._label = "turn"; return; }
+#define LONG_JUMP0 { context._break = true; return 0; }
+#define LONG_JUMP_LABEL(LBL) { context._break = true; context._label = LBL; return; }
+#define LONG_JUMP_LABEL0(LBL) { context._break = true; context._label = LBL; return 0; }
+
+} // End of namespace Alan2
+} // End of namespace Glk
+
+#endif
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index c9612db412..62ee3bf890 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -36,6 +36,7 @@
#include "glk/alan3/glkio.h"
#include "glk/alan3/instance.h"
#include "glk/alan3/inter.h"
+#include "glk/alan3/jumps.h"
#include "glk/alan3/lists.h"
#include "glk/alan3/literal.h"
#include "glk/alan3/location.h"
@@ -731,80 +732,85 @@ static void moveActor(int theActor) {
current.instance = previousInstance;
}
-#define RESTARTED (setjmp(restartLabel) != NO_JUMP_RETURN)
-#define ERROR_RETURNED (setjmp(returnLabel) != NO_JUMP_RETURN)
-
/*======================================================================*/
void run(void) {
- static Stack theStack = NULL; /* Needs to survive longjmp() */
+ Stack theStack = NULL;
+ Context ctx;
- openFiles();
- load(); /* Load program */
-#ifdef TODO
- if (RESTARTED) {
- deleteStack(theStack);
- }
+ do {
+ openFiles();
+ load(); // Load program
- theStack = createStack(STACKSIZE);
- setInterpreterStack(theStack);
+ if (theStack)
+ deleteStack(theStack);
- initStateStack();
+ theStack = createStack(STACKSIZE);
+ setInterpreterStack(theStack);
- if (!ERROR_RETURNED) /* Can happen in start section too... */
- init(); /* Initialise and start the adventure */
+ initStateStack();
- while (TRUE) {
- if (debugOption)
- debug(FALSE, 0, 0);
+ // Initialise and start the adventure
+ init();
- if (stackDepth(theStack) != 0)
- syserr("Stack is not empty in main loop");
+ while (!g_vm->shouldQuit()) {
+ if (!ctx._break) {
+ if (debugOption)
+ debug(FALSE, 0, 0);
- if (!current.meta)
- runPendingEvents();
+ if (stackDepth(theStack) != 0)
+ syserr("Stack is not empty in main loop");
- /* Return here if error during execution */
- switch (setjmp(returnLabel)) {
- case NO_JUMP_RETURN:
- break;
- case ERROR_RETURN:
- forgetGameState();
- forceNewPlayerInput();
- break;
- case UNDO_RETURN:
- forceNewPlayerInput();
- break;
- default:
- syserr("Unexpected longjmp() return value");
- }
+ if (!current.meta)
+ runPendingEvents();
+ } else {
+ #ifdef TODO
+ // Return here if error during execution
+ switch (setjmp(returnLabel)) {
+ case NO_JUMP_RETURN:
+ break;
+ case ERROR_RETURN:
+ forgetGameState();
+ forceNewPlayerInput();
+ break;
+ case UNDO_RETURN:
+ forceNewPlayerInput();
+ break;
+ default:
+ syserr("Unexpected longjmp() return value");
+ }
+ #endif
+ }
- recursionDepth = 0;
+ recursionDepth = 0;
- /* Move all characters, hero first */
- rememberGameState();
- current.meta = FALSE;
- moveActor(header->theHero);
+ // Move all characters, hero first
+ rememberGameState();
+ current.meta = FALSE;
+ moveActor(header->theHero);
- if (gameStateChanged)
- rememberCommands();
- else
- forgetGameState();
+ if (gameStateChanged)
+ rememberCommands();
+ else
+ forgetGameState();
- if (!current.meta) {
- current.tick++;
+ if (!current.meta) {
+ current.tick++;
- /* Remove this call? Since Eval is done up there after each event... */
- resetAndEvaluateRules(rules, header->version);
+ // Remove this call? Since Eval is done up there after each event...
+ resetAndEvaluateRules(rules, header->version);
- /* Then all the other actors... */
- for (uint i = 1; i <= header->instanceMax; i++)
- if (i != header->theHero && isAActor(i)) {
- moveActor(i);
- resetAndEvaluateRules(rules, header->version);
- }
+ /* Then all the other actors... */
+ for (uint i = 1; i <= header->instanceMax; i++)
+ if (i != header->theHero && isAActor(i)) {
+ moveActor(i);
+ resetAndEvaluateRules(rules, header->version);
+ }
+ }
+
+ if (ctx._break && ctx._label == "restart")
+ break;
}
- }
-#endif
+ } while (!g_vm->shouldQuit() && ctx._label == "restart");
}
} // End of namespace Alan3
diff --git a/engines/glk/alan3/main.h b/engines/glk/alan3/main.h
index 60e3d0527d..6934f01a97 100644
--- a/engines/glk/alan3/main.h
+++ b/engines/glk/alan3/main.h
@@ -25,12 +25,15 @@
/* Header file for main unit of ARUN Alan System interpreter */
+#include "common/stream.h"
#include "glk/alan3/types.h"
#include "glk/alan3/acode.h"
namespace Glk {
namespace Alan3 {
+extern Common::SeekableReadStream *codfil;
+
extern VerbEntry *vrbs; // Verb table pointer
extern void run();