GLK: ALAN3: Outer game loop to handle forfeit setjmp replacement

This commit is contained in:
Paul Gilbert 2019-06-29 14:42:50 -07:00
parent f0d5304a4c
commit c833d39ccf
4 changed files with 86 additions and 67 deletions

View File

@ -25,6 +25,7 @@
#include "glk/alan3/main.h"
#include "glk/alan3/glkio.h"
#include "glk/alan3/options.h"
#include "glk/alan3/output.h"
#include "glk/alan3/syserr.h"
#include "common/system.h"
#include "common/config-manager.h"
@ -67,6 +68,12 @@ Alan3::Alan3(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, g
statusLineOption = true;
regressionTestOption = false;
// output
anyOutput = false;
capitalize = false;
needSpace = false;
skipSpace = false;
// syserr
setSyserrHandler(nullptr);
}

View File

@ -651,7 +651,7 @@ static char *scriptName(int theActor, int theScript) {
/*----------------------------------------------------------------------*/
static void moveActor(int theActor) {
static void moveActor(CONTEXT, int theActor) {
ScriptEntry *scr;
StepEntry *step;
Aint previousInstance = current.instance;
@ -659,17 +659,18 @@ static void moveActor(int theActor) {
current.actor = theActor;
current.instance = theActor;
current.location = where(theActor, TRANSITIVE);
if (theActor == (int)HERO) {
#ifdef TODO
/* Ask him! */
if (setjmp(forfeitLabel) == 0) {
if (context._break || theActor == (int)HERO) {
if (context._break) {
// Forfeit jump destination
assert(context._label == "forfeit");
context.clear();
} else {
// Ask him!
parse();
capitalize = TRUE;
fail = FALSE; /* fail only aborts one actor */
fail = FALSE; // fail only aborts one actor
}
#else
syserr("TODO: moveActor setjmp");
#endif
} else if (admin[theActor].script != 0) {
for (scr = (ScriptEntry *) pointerTo(header->scriptTableAddress); !isEndOfArray(scr); scr++) {
if (scr->code == admin[theActor].script) {
@ -748,63 +749,73 @@ void run(void) {
init();
while (!g_vm->shouldQuit()) {
if (ctx._break) {
#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
ctx.clear();
} else {
if (debugOption)
debug(FALSE, 0, 0);
if (stackDepth(theStack) != 0)
syserr("Stack is not empty in main loop");
if (!current.meta)
runPendingEvents();
}
recursionDepth = 0;
// Move all characters, hero first
rememberGameState();
current.meta = FALSE;
moveActor(header->theHero);
if (gameStateChanged)
rememberCommands();
else
forgetGameState();
if (!current.meta) {
current.tick++;
// 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);
if (!(ctx._break && ctx._label == "forfeit")) {
if (ctx._break) {
assert(ctx._label == "return");
#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
ctx.clear();
} else {
if (debugOption)
debug(FALSE, 0, 0);
if (stackDepth(theStack) != 0)
syserr("Stack is not empty in main loop");
if (!current.meta)
runPendingEvents();
}
recursionDepth = 0;
// Move all characters, hero first
rememberGameState();
current.meta = FALSE;
}
if (ctx._break && ctx._label == "restart")
break;
moveActor(ctx, header->theHero);
if (!ctx._break) {
if (gameStateChanged)
rememberCommands();
else
forgetGameState();
if (!current.meta) {
current.tick++;
// 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(ctx, i);
if (ctx._break)
break;
resetAndEvaluateRules(rules, header->version);
}
}
}
if (ctx._break && ctx._label == "restart")
break;
}
}
} while (!g_vm->shouldQuit() && ctx._label == "restart");
}

View File

@ -40,10 +40,10 @@ namespace Glk {
namespace Alan3 {
/* PUBLIC DATA */
bool anyOutput = FALSE;
bool capitalize = FALSE;
bool needSpace = FALSE;
bool skipSpace = FALSE;
bool anyOutput;
bool capitalize;
bool needSpace;
bool skipSpace;
/* Screen formatting info */
int col, lin;

View File

@ -36,6 +36,7 @@ extern int pageLength, pageWidth;
extern bool anyOutput;
extern bool needSpace;
extern bool capitalize;
extern bool skipSpace;
/* Log file */
extern strid_t logFile;