Text Window Input-Output Control

version 2 by Erik Temple

  • Home page
  • Beginning
  • Previous
  • Next



  • Chapter - Hacked VM routines

    Include (-

    [ VM_KeyChar win nostat done res ix jx ch;
    jx = ch; ! squash compiler warnings
    if (win == 0) win = (+ current text input window +).ref_number;
    if (gg_commandstr ~= 0 && gg_command_reading ~= false) {
    done = glk_get_line_stream(gg_commandstr, gg_arguments, 31);
    if (done == 0) {
    glk_stream_close(gg_commandstr, 0);
    gg_commandstr = 0;
    gg_command_reading = false;
    ! fall through to normal user input.
    } else {
    ! Trim the trailing newline
    if (gg_arguments->(done-1) == 10) done = done-1;
    res = gg_arguments->0;
    if (res == '\') {
    res = 0;
    for (ix=1 : ix<done : ix++) {
    ch = gg_arguments->ix;
    if (ch >= '0' && ch <= '9') {
    @shiftl res 4 res;
    res = res + (ch-'0');
    } else if (ch >= 'a' && ch <= 'f') {
    @shiftl res 4 res;
    res = res + (ch+10-'a');
    } else if (ch >= 'A' && ch <= 'F') {
    @shiftl res 4 res;
    res = res + (ch+10-'A');
    }
    }
    }
    jump KCPContinue;
    }
    }
    done = false;
    glk_request_char_event(win);
    while (~~done) {
    glk_select(gg_event);
    switch (gg_event-->0) {
    5: ! evtype_Arrange
    if (nostat) {
    glk_cancel_char_event(win);
    res = $80000000;
    done = true;
    break;
    }
    DrawStatusLine();
    2: ! evtype_CharInput
    if (gg_event-->1 == win) {
    res = gg_event-->2;
    done = true;
    }
    }
    ix = HandleGlkEvent(gg_event, 1, gg_arguments);
    if (ix == 2) {
    res = gg_arguments-->0;
    done = true;
    } else if (ix == -1) done = false;
    }
    if (gg_commandstr ~= 0 && gg_command_reading == false) {
    if (res < 32 || res >= 256 || (res == '\' or ' ')) {
    glk_put_char_stream(gg_commandstr, '\');
    done = 0;
    jx = res;
    for (ix=0 : ix<8 : ix++) {
    @ushiftr jx 28 ch;
    @shiftl jx 4 jx;
    ch = ch & $0F;
    if (ch ~= 0 || ix == 7) done = 1;
    if (done) {
    if (ch >= 0 && ch <= 9) ch = ch + '0';
    else ch = (ch - 10) + 'A';
    glk_put_char_stream(gg_commandstr, ch);
    }
    }
    } else {
    glk_put_char_stream(gg_commandstr, res);
    }
    glk_put_char_stream(gg_commandstr, 10); ! newline
    }
    .KCPContinue;
    return res;
    ];

    [ VM_KeyDelay tenths key done ix;
    glk_request_char_event( (+ current text input window +).ref_number );
    glk_request_timer_events(tenths*100);
    while (~~done) {
    glk_select(gg_event);
    ix = HandleGlkEvent(gg_event, 1, gg_arguments);
    if (ix == 2) {
    key = gg_arguments-->0;
    done = true;
    }
    else if (ix >= 0 && gg_event-->0 == 1 or 2) {
    key = gg_event-->2;
    done = true;
    }
    }
    glk_cancel_char_event( (+ current text input window +).ref_number );
    glk_request_timer_events(0);
    return key;
    ];

    [ VM_ReadKeyboard a_buffer a_table done ix;
    if (gg_commandstr ~= 0 && gg_command_reading ~= false) {
    done = glk_get_line_stream(gg_commandstr, a_buffer+WORDSIZE,
    (INPUT_BUFFER_LEN-WORDSIZE)-1);
    if (done == 0) {
    glk_stream_close(gg_commandstr, 0);
    gg_commandstr = 0;
    gg_command_reading = false;
    ! L__M(##CommandsRead, 5); would come after prompt
    ! fall through to normal user input.
    }
    else {
    ! Trim the trailing newline
    if ((a_buffer+WORDSIZE)->(done-1) == 10) done = done-1;
    a_buffer-->0 = done;
    VM_Style(INPUT_VMSTY);
    glk_put_buffer(a_buffer+WORDSIZE, done);
    VM_Style(NORMAL_VMSTY);
    print "^";
    jump KPContinue;
    }
    }
    done = false;
    glk_request_line_event( (+ current text input window +).ref_number, a_buffer+WORDSIZE, INPUT_BUFFER_LEN-WORDSIZE, 0);
    while (~~done) {
    glk_select(gg_event);
    switch (gg_event-->0) {
    5: ! evtype_Arrange
    DrawStatusLine();
    3: ! evtype_LineInput
    if (gg_event-->1 == (+ current text input window +).ref_number) {
    a_buffer-->0 = gg_event-->2;
    done = true;
    }
    }
    ix = HandleGlkEvent(gg_event, 0, a_buffer);
    if (ix == 2) done = true;
    else if (ix == -1) done = false;
    }
    if (gg_commandstr ~= 0 && gg_command_reading == false) {
    glk_put_buffer_stream(gg_commandstr, a_buffer+WORDSIZE, a_buffer-->0);
    glk_put_char_stream(gg_commandstr, 10); ! newline
    }
    .KPContinue;
    VM_Tokenise(a_buffer,a_table);
    ! It's time to close any quote window we've got going.
    if (gg_quotewin) {
    glk_window_close(gg_quotewin, 0);
    gg_quotewin = 0;
    }
    #ifdef ECHO_COMMANDS;
    print "** ";
    for (ix=WORDSIZE: ix<(a_buffer-->0)+WORDSIZE: ix++) print (char) a_buffer->ix;
    print "^";
    #endif; ! ECHO_COMMANDS
    ];

    -) instead of "Keyboard Input" in "Glulx.i6t"