diff options
author | Paul Gilbert | 2019-06-26 20:34:53 -0700 |
---|---|---|
committer | Paul Gilbert | 2019-07-06 15:27:08 -0700 |
commit | 86f9985951203ed39e1a6c08e32730b478b10517 (patch) | |
tree | 6122934dcfb4ca6e0521e058f78f4c41c49fe4dd | |
parent | dc40211ec5e54d01f7cb822940714ed6e6da36d5 (diff) | |
download | scummvm-rg350-86f9985951203ed39e1a6c08e32730b478b10517.tar.gz scummvm-rg350-86f9985951203ed39e1a6c08e32730b478b10517.tar.bz2 scummvm-rg350-86f9985951203ed39e1a6c08e32730b478b10517.zip |
GLK: ALAN3: Re-enable main game loop
-rw-r--r-- | engines/glk/alan3/alan3.cpp | 54 | ||||
-rw-r--r-- | engines/glk/alan3/alan3.h | 16 | ||||
-rw-r--r-- | engines/glk/alan3/jumps.h | 85 | ||||
-rw-r--r-- | engines/glk/alan3/main.cpp | 120 | ||||
-rw-r--r-- | engines/glk/alan3/main.h | 3 |
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(); |