Quixe and timed events

I could’ve sworn I had tried that–but I must’ve not because canceling the input does the trick. Many thanks for the help!

Isn’t that a bit backwards? I’d think the IDE terps ought to be more strict than the others so surprises like this wouldn’t happen. Is there a related feature suggestion at uservoice that I could vote on?

inform7.uservoice.com/forums/573 … d-glk-call

and related:
inform7.uservoice.com/forums/573 … tions-for-
inform7.uservoice.com/forums/573 … de-interpr

(Yes, plugging all my own requests in this area)

I have added code to the Windows IDE to fail when games print to windows waiting for input, so that will be done in the next build. The others are on the to do list, at least for Windows.

Anyone know how to do this for yesorno();?

I could not cancel out of it. It would crash terminally in quixe. I want to provide yes or no links to click on, but I just couldn’t figure a way past it.

Ideas?

Here’s some code that handles this:

https://intfiction.org/t/inform-the-reliques-of-tolti-aph/67/1

–Erik

I don’t see much different than mine. It specifically crashes mid-yesorno();, not at the command prompt. I already use a cancel line event, which seems to do nothing when at this point.

Does your revised keyboard draw fix that?

Hm, it seems to work properly in Gargoyle (which is also strict about disallowing printing when line input is pending). It’s possible that this is a Quixe bug…?

(The Quixe message is: Quixe run: gli_put_char: window has pending line request)

Dang, that’s bad news. Who could fix that?

Well, proper diagnosis is probably the next step–it could also be, for example, that Gargoyle is too lenient about…whatever is different about this case…and that Quixe is not to blame at all.

Here is my very minimal code to do what (I think) you want. (You want hyperlink events, right? Not timer events?)

Instead of going north:
	say "Are you sure about this? [link 1]YES[/link] [link 2]NO[/link]: ";
	request hyperlink event;
	if the player consents:
		say "Yes? You think better of it.";
	else:
		say "No? Wise.";
	cancel hyperlink event;
	
To say link (N - number): (-
	glk_set_hyperlink({N});
-).

To say /link: (-
	glk_set_hyperlink(0);
-).

To request hyperlink event: (-
	glk_request_hyperlink_event(gg_mainwin);
-).

To cancel hyperlink event: (-
	glk_cancel_hyperlink_event(gg_mainwin);
-).

Include (-

[ HandleGlkEvent ev ischar buf   linknum;
	if (ev-->0 == 8) {
		linknum = ev-->2;
		glk_cancel_line_event(gg_mainwin, gg_event);
		if (linknum == 1) {
			glk_set_style(8);
			print "YES";
			glk_set_style(0);
			VM_PrintToBuffer(buffer, 3, "yes");
		}
		else {
			glk_set_style(8);
			print "NO";
			glk_set_style(0);
			VM_PrintToBuffer(buffer, 2, "no");
		}
		new_line;
		return 2;
	}
];

-) before "Stubs" in "Glulx.i6t".

This does not crash in either Quixe or Gargoyle. However, it turns up a bug in Quixe, which is that glk_cancel_hyperlink_event() does not work. (There’s a typo such that it turns the hyperlink flag on, so it’s effectively a synonym for glk_request_hyperlink_event().) With that bug fixed, it works correctly in all the interpreters.

(The input-style “YES”/“NO” is printed on the next line, rather than after the prompt. This is because I haven’t bothered faffing around with the echo-input flag. Note that the Mac IDE interpreter gets this wrong, albeit with prettier results; this is a long-standing bug.)

I’m using inline hyperlinks, so I don’t know what number each particular link will be, alas.

Well, that was a wild goose chase…! If you’re using Inline Hyperlinks, all you need to do this is something like this:

Instead of waving hands: say "Are you sure? [link]YES[end link] or [link]NO[end link]"; if the player consents: say "Woot!"; otherwise: say "Too bad!"

The canceling is handled automatically. I think that the crash in Quixe must be due to the bug that Zarf mentioned; this works perfectly elsewhere (e.g. Gargoyle).

Yep, I did that, so how do I specifically bypass that little bug?

It looks like zarf has pushed the fix, so you should be able to download the newest Quixe files and install them manually in your Inform templates folder (instructions for installing into template folder are here).

I am so happy I can’t even measure it!

Er, hrm, how do I… compile this back together? He made an adjustment to one of the js files that aren’t included… Hrm, sec…

Still getting the same error. Here’s the code I’m trying:

To get an input:
(-VM_ReadKeyboard(buffer, parse):wink:

To decide whether player consents:
say “[link]yes[end link] or [link]no[end link][line break]”;
While 1 is 1:
get an input;
if the player’s command matches “yes”:
decide on true;
if the player’s command matches “no”:
decide on false;
say “Please choose yes or no. >”;

Well, I’m baffled. Even with the fixed version of the glkote, Quixe is indeed still crashing on the attempt to print (i.e., “gli_put_char” [should be “glk_put_char”, no?]) during line input. Zarf’s code works, but any solution that uses Glulx Entry Points fails in the same way.

This is baffling because there is no attempt to print in any of the GEP code as far as I can tell. My best guess is that something other than a straight “say” is nevertheless resulting in a put_char request. Nothing intentionally printed is causing the problem; if it were, Gargoyle–which suppresses text printed illegally–would not produce the desired output. Instead, Gargoyle’s output is identical to the Mac IDE interpreter’s, and the latter doesn’t suppress output at all. (Well, they aren’t exactly identical–the IDE interpreter doesn’t print a line break when the line event is canceled as Gargoyle does, but that is a well-known divergence from spec on the part of the IDE terp.)

For reference, I’ve pulled out the relevant code from GEP and Inline Hyperlinks–the HandleGlkEvent code (excerpted from GEP) controls the flow, and the code beneath is the sequence of rules that are being called by HandleGlkEvent. This is followed by a complete example along the lines of Zarf’s but using Inline Hyperlinks. Finally, the same example using the Basic Hyperlinks extension (which also uses GEP under the hood).

[code]Include (-

[ HandleGlkEvent ev context abortres newcmd cmdlen ;
context = 0; ! suppress ignored warning
switch (ev–>0) {
evtype_Hyperlink:
FollowRulebook( (+glulx hyperlink rules+) );
if ( FollowRulebook( (+command-counting rules +) ) && RulebookSucceeded())
{
FollowRulebook( (+input-cancelling rules+) );
FollowRulebook( (+command-showing rules+) );
if ( FollowRulebook( (+command-pasting rules+) ) ) return 2;
}
}
];

-) before “Glulx.i6t”.

A glulx hyperlink rule (this is the default inline hyperlink handling rule):
now the current hyperlink ID is the link number of the selected hyperlink;
unless the current hyperlink ID is 0:
cancel glulx hyperlink request in main window;
cancel glulx hyperlink request in status window;
follow the hyperlink processing rules;
if the status window is the hyperlink source:
request glulx hyperlink event in status window;
otherwise:
request glulx hyperlink event in main window.

A hyperlink processing rule (this is the default command replacement by hyperlinks rule):
now the glulx replacement command is entry (current hyperlink ID) of the hyperlink list;
rule succeeds.

A command-counting rule (this is the ordinary checking for content rule):
if the number of characters in the glulx replacement command is 0, rule fails;
rule succeeds.

An input-cancelling rule (this is the cancelling input in the main window rule):
cancel line input in the main window;
cancel character input in the main window;

To cancel line input in the/-- main window:
(- glk_cancel_line_event(gg_mainwin, GLK_NULL); -)

To cancel character input in the/-- main window:
(- glk_cancel_char_event(gg_mainwin); -)

A command-showing rule (this is the print text to the input prompt rule):
say input-style-for-glulx;
say Glulx replacement command;
say roman type;

A command-pasting rule (this is the glue replacement command into parse buffer rule):
change the text of the player’s command to the Glulx replacement command;
rule succeeds.

[/code]

[code]Include Inline Hyperlinks by Erik Temple.

Release along with an interpreter.

Test is a room.

Instead of jumping:
say “Are you sure? [link]YES[end link] or [link]NO[end link]”;
if the player consents:
say “Whee!”;
otherwise:
say “You maintain your dignity.”[/code]

[code]Include Basic Hyperlinks by Emily Short.

Release along with an interpreter.

Test is a room.

Instead of jumping:
say “Are you sure? [set link 1]YES[end link] or [set link 2]NO[end link]”;
if the player consents:
say “Whee!”;
otherwise:
say “You maintain your dignity.”

Table of Hyperlink Glulx Replacement Commands (continued)
linknum replacement
1 “YES”
2 “NO”[/code]

Maybe someone else can make sense of this.

OK, I’ve just run the Inline Hyperlinks example from the previous post step-by-step through EMacsUser’s awesome debugger (in Gargoyle, since I don’t think it’s possible to use with Quixe), and found that the flow is indeed just as I described. There is absolutely NO PRINTING to any window while line input is pending after clicking on a hyperlink in the yes/no routine. So I’m happy to call this a bug in Quixe.

What type of bug remains to be seen. Could GlkOte itself be trying to print? Or failing to cancel the line event despite the call to glk_cancel_line_event?