Quixe and timed events

Quixe doesn’t seem to like timed events very much. It works fine when I’m doing the linear kind of timers that are in Erik Temple’s Real-Time Delays extension, e.g.:

wait 1500 ms before continuing But things get hairy if I try to do a more random-access timers that activate the “A glulx timed activity rule:”:

start a 1500 millisecond timer When the rule is activated, trying to output any text (e.g., say “hello world”) causes errors such as “Quixe run: gli_put_char: window has pending line request” or “Quixe run: gli_put_char: window has pending line request.”

Any thoughts? I’m guessing that these types of timers just aren’t compatible with Quixe–but I’m wishing they were.

This kind of thing has often happened to me. Basically, the interpreters that are included in the Inform IDEs (Mac OS and Windows) don’t enforce proscriptions against certain actions that are technically illegal under Glulx. One of those actions is trying to print to a window when input is pending. Unfortunately, if you have a timed event in Glulx, chances are very good that you also have input pending in the main window (i.e., the cursor is waiting for the player to type), and thus, if you try to print from the timed activity rules, you will be doing so illegally. Again, the IDE interpreters just ignore this, but Quixe and Gargoyle both recognize it as illegal.

The solution is, you need to cancel line input before printing anything, e.g.:

[code]To cancel line input in main window: (- glk_cancel_line_event(gg_mainwin); -)

A glulx timed activity rule:
cancel line input in main window;
print “The timer has fired!”[/code]

–Erik

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. >”;