intfiction.org

The Interactive Fiction Community Forum
It is currently Sat May 18, 2013 4:18 pm

All times are UTC - 6 hours [ DST ]




Post new topic Reply to topic  [ 21 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
PostPosted: Mon Aug 23, 2010 10:25 pm 
Offline

Joined: Tue Jul 20, 2010 6:08 am
Posts: 41
Erik,

I'm not sure I understand what you want to do, but as luck would have it, i'm currently working on a real time implementation in Gluxl.

Here's a little example
http://www.sendspace.com/file/7tikra
1. the download link is at the bottom of the page (don't pay attention to the other links)
2. Why can't I upload gblorbs to this forum ? I thought there were known to be virtually virus-free.

Walkthrough:
Spoiler: show
open box
x device
x button
push button


Top
 Profile Send private message  
 
PostPosted: Mon Aug 23, 2010 10:35 pm 
Offline

Joined: Sat Jan 23, 2010 4:56 pm
Posts: 2081
Got it. Here you go:

Code:
To re-request line event in main window:
   (-  glk_request_line_event(gg_mainwin, buffer + WORDSIZE, INPUT_BUFFER_LEN - WORDSIZE, buffer-->0); -)

To cancel line input in the/-- main-window:
   (- glk_cancel_line_event(gg_mainwin, gg_event); buffer-->0 = gg_event-->2; -)


I've tested this in the IDE, Zoom, Quixe, and GlkTerm.

I don't know where you got "buffer->1" from, but it wasn't right.

The deeper problem was that your cancel routine was throwing away information: specifically, the number of characters in the incomplete input. It's a library convention that that number lives in buffer-->0. So it's the library's responsibility to store that value there; you can see VM_ReadKeyboard() doing it. The cancel-line-input phrase must do it too.

Once that's done, the re-request phrase can pull the value out, and pass it to glk_request_line_event().

That leaves the Zoom problem that I mentioned, but it's merely cosmetic. Zoom doesn't echo the partial input on the (original) command prompt line. Other interpreters do echo it. Zoom is wrong here (sorry!). However, a future Glk revision will allow the *game* to specify whether that echo occurs, and then hopefully we can all get back onto the same page.


Top
 Profile Send private message  
 
PostPosted: Mon Aug 23, 2010 11:34 pm 
Offline

Joined: Thu Oct 22, 2009 4:31 pm
Posts: 1137
zarf wrote:
Got it. Here you go:

Code:
To re-request line event in main window:
   (-  glk_request_line_event(gg_mainwin, buffer + WORDSIZE, INPUT_BUFFER_LEN - WORDSIZE, buffer-->0); -)

To cancel line input in the/-- main-window:
   (- glk_cancel_line_event(gg_mainwin, gg_event); buffer-->0 = gg_event-->2; -)


Thanks! This is definitely closer (and teaches me something about what you can do with events in these calls--very flexible!), but unfortunately it isn't right either. We aren't distinguishing between the length of the buffer (defined by the previous input) and the number of characters typed into the interrupted line. Here's the output I get using this code:

Quote:
Test
You can see a button here.

>press button
Click. Is that a clock ticking?

>loo

Boom! There's an explosion somewhere else in the complex.

>looss button [this should just be "loo"]



zarf wrote:
I don't know where you got "buffer->1" from, but it wasn't right.


I don't remember where I got it either, but my understanding was that buffer->1 is the number of characters typed in the interrupted input, whereas buffer->0 is the length of the buffer, which in practice is set by the previous *completed* command. It seems that that is wrong, but conceptually that's the problem we're be dealing with--we're still getting the wrong value. I think that the information being stored by the cancel event code is really just 0--you'll note that the game reacts exactly the same if you get the fourth entry from the event array (gg_event-->3) instead of from gg_event-->2. According to the spec, gg_event-->3 in this case returns 0.

I'll keep futzing--and try to figure out where I got the idea that buffer->1 stores the number of characters typed--tomorrow.

--Erik

_________________
Glimmr: Advanced Graphics for I7
blog | download | bug-tracker


Top
 Profile Send private message  
 
PostPosted: Mon Aug 23, 2010 11:58 pm 
Offline

Joined: Sat Jan 23, 2010 4:56 pm
Posts: 2081
Quote:
We aren't distinguishing between the length of the buffer (defined by the previous input) and the number of characters typed into the interrupted line.


Yes I am. One is INPUT_BUFFER_LEN-WORDSIZE, the other is gg_event-->2.

I've pasted my whole program below. The phrase "show the buffer" displays what's really going on inside the system. After the "cancel line input", the length of the interrupted input is pushed into buffer-->0, and then "show the buffer" prints it.

Quote:
Test
You can see a button here.

>press button
Buffer contains 12 chars: p r e s s b u t t o n
Click. Is that a clock ticking?

>
Buffer contains 3 chars: l o o
Boom! There's an explosion somewhere else in the complex.

>loo


Code:
"Test Case" by Andrew Plotkin

Include Glulx Entry Points by Emily Short.

Test is a room.

The button is a device in Test.
   
Instead of pushing the button:
    show the buffer;
    say "Click. Is that a clock ticking?";
    start a 2000 millisecond timer.

A glulx timed activity rule:
    if the reading a command activity is going on:
        cancel line input in the main-window;
        say "[line break]";
        show the buffer;
        say "Boom! There's an explosion somewhere else in the complex.";
        stop the timer;
        say "[line break]";
        say "[command prompt][run paragraph on]";
        re-request line event in main window.

Include (-

[ DebugShowBuffer  ix len ch;
    len = buffer-->0;
    print "Buffer contains ", len, " chars: ";
    for (ix=0 : ix<len : ix++) {
        ch = buffer->(4+ix);
        if (ch < 32)
            print "(", ch, ") ";
        else
            print (char) ch, " ";
    }
    new_line;
];

-).

To show the buffer:
    (- DebugShowBuffer(); -).

To re-request line event in main window:
    (-  glk_request_line_event(gg_mainwin, buffer + WORDSIZE, INPUT_BUFFER_LEN - WORDSIZE, buffer-->0); -)

To cancel line input in the/-- main-window:
    (- glk_cancel_line_event(gg_mainwin, gg_event); buffer-->0 = gg_event-->2; -)

To start a/-- (T - a number) millisecond/ms timer:
    (- if (glk_gestalt(gestalt_Timer, 0)) glk_request_timer_events({T});  -)

To stop the/-- timer:
    (- if (glk_gestalt(gestalt_Timer, 0)) glk_request_timer_events(0); -)



Top
 Profile Send private message  
 
PostPosted: Tue Aug 24, 2010 6:37 am 
Offline

Joined: Thu Oct 22, 2009 4:31 pm
Posts: 1137
Ugh, very sorry about that! When I pasted this new code in, I forgot that my example code was now using the input cancellation phrase that is built into Glulx Entry Points, so the new one (the one that saves the information about the length of the buffer) was not being used.

Fixing that, this code works great for me too.

Thank you so much for the help!

Erik

_________________
Glimmr: Advanced Graphics for I7
blog | download | bug-tracker


Top
 Profile Send private message  
 
PostPosted: Tue Aug 24, 2010 3:06 pm 
Offline

Joined: Thu Oct 22, 2009 4:31 pm
Posts: 1137
zarf wrote:
I don't know where you got "buffer->1" from, but it wasn't right.


I figured out where I got this: in the section on buffers in the DM4 (section 2.5):

Quote:
You must already have set text_array->0 to the maximum number of characters you will allow to be read. (If this is N, then the array must be defined with at least N + 3 entries, the last of which guards against overruns.) The number of characters actually read, not counting the carriage return, will be placed into text_array->1 and the characters themselves into entries from text_array->2 onwards.


I assumed that this must be the structure of all buffers, but I'm guessing now that it's the structure of text_array only...

--Erik

_________________
Glimmr: Advanced Graphics for I7
blog | download | bug-tracker


Top
 Profile Send private message  
 
PostPosted: Tue Aug 24, 2010 8:47 pm 
Offline

Joined: Sat Jan 23, 2010 4:56 pm
Posts: 2081
Aha -- right.

That describes the behavior of the I6 "read" statement, which generates the Z-code @aread opcode. In Glulx, the "read" statement doesn't compile at all. (Line-reading is too complicated for the compiler to handle without library support.) So there's no exact equivalent to that section in the Glulx world. The library's code, as you've seen, uses buffer-->0 (a four-byte length value) followed by one-byte characters.


Top
 Profile Send private message  
 
PostPosted: Wed Aug 25, 2010 11:38 am 
Offline

Joined: Sat Jan 23, 2010 4:56 pm
Posts: 2081
I just found a bug in this setup. Unfortunately, fixing it will be ugly.

When Inform goes into a *disambiguation* prompt, it's actually working off of a different character array. (buffer2 rather than buffer.) It's also at a different point in the main turn loop.

The result is that if you add "The red ball is in Test. The blue ball is in Test." to my game, and then do "push button" followed (quickly) by "get ball", the event will hang up -- it won't reach the timer event. If you either complete the disambig, or type a completely new command, the event will fire during the *next* input prompt. (Merely hitting Return isn't enough to move forward, since the parser is still waiting.)

(I have not diagnosed exactly what's going on in the library guts in this case.)

Entering a YesOrNo input also freezes the event.


Top
 Profile Send private message  
 
PostPosted: Wed Aug 25, 2010 1:49 pm 
Offline

Joined: Thu Oct 22, 2009 4:31 pm
Posts: 1137
Ah.

The YesNo() routine uses buffer rather than buffer2, so the yes-no problem is really caused by the line that checks to see whether or not the reading a command activity is going on, not by any deeper issue.

Would it be possible to solve the buffer2 issue by hacking VM_ReadKeyboard to store a reference to the passed array as a global? (VM_ReadKeyboard is also used for the disambiguation questions. The temporary variable that represents the buffer array in VM_ReadKeyboard is a_buffer.) These two lines could then refer to that global:

To re-request line event in main window:
(- glk_request_line_event(gg_mainwin, global + WORDSIZE, INPUT_BUFFER_LEN - WORDSIZE, global-->0); -)

To cancel line input in the/-- main-window:
(- glk_cancel_line_event(gg_mainwin, gg_event); global-->0 = gg_event-->2; -)

I'm not sure how to do this, though--would it be a pointer? (This--pointers, stacks, memory management--is where my lack of knowledge of C and real programming in general *really* ducks in to bite me!)

Alternatively, surrounding the code that generates disambiguation input with flags and then testing for those when the timed event fires might also work, e.g.:

Code:
disambiguating = true;
answer_words=Keyboard(buffer2, parse2);
disambiguating = false;


When disambiguating is true, we use alternate versions of the cancel line input and re-request input phrases.

--Erik

_________________
Glimmr: Advanced Graphics for I7
blog | download | bug-tracker


Top
 Profile Send private message  
 
PostPosted: Wed Aug 25, 2010 3:49 pm 
Offline

Joined: Sat Jan 23, 2010 4:56 pm
Posts: 2081
Either strategy will work. (You just declare an ordinary global. I6 doesn't *have* memory management.)

However, I'm still worried about running arbitrary code inside the disambig prompt or the yesorno prompt. As long as you're just printing text, it's fine. If you rearrange the world (move objects around), you could produce some funky results. (Imagine having both the red and blue balls explode in a timed event... I think the worst outcome is an incongruous "You see no such thing" error, but I'd have to do a lot of code tracing to prove it to myself.)

The scariest situation is trying to end the game (set deadflag) in a timed event. Test that very carefully.


Top
 Profile Send private message  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC - 6 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group