Player Experience Upgrade

version 2/111127 by Aaron Reed

  • Home page
  • Beginning
  • Previous
  • Next



  • Section - Nothing Entered Advanced Version

    Include (- [ Keyboard a_buffer a_table nw i w w2 x1 x2;
        sline1 = score; sline2 = turns;

        while (true) {
            ! Save the start of the buffer, in case "oops" needs to restore it
            for (i=0 : i<64 : i++) oops_workspace->i = a_buffer->i;
        
            ! In case of an array entry corruption that shouldn't happen, but would be
            ! disastrous if it did:
            #Ifdef TARGET_ZCODE;
            a_buffer->0 = INPUT_BUFFER_LEN;
            a_table->0 = 15; ! Allow to split input into this many words
            #Endif; ! TARGET_
        
            ! Print the prompt, and read in the words and dictionary addresses
            PrintPrompt();
            DrawStatusLine();
            KeyboardPrimitive(a_buffer, a_table);
        
            ! Set nw to the number of words
            #Ifdef TARGET_ZCODE; nw = a_table->1; #Ifnot; nw = a_table-->0; #Endif;
        
            ! If the line was blank, get a fresh line
            !if (nw == 0) {
            ! @push etype; etype = BLANKLINE_PE;
            ! players_command = 100;
            ! BeginActivity(PRINTING_A_PARSER_ERROR_ACT);
            ! if (ForActivity(PRINTING_A_PARSER_ERROR_ACT) == false) L__M(##Miscellany,10);
            ! EndActivity(PRINTING_A_PARSER_ERROR_ACT);
            ! @pull etype;
            ! continue;
            !}
        
            ! Unless the opening word was OOPS, return
            ! Conveniently, a_table-->1 is the first word on both the Z-machine and Glulx
        
            w = a_table-->1;
            if (w == OOPS1__WD or OOPS2__WD or OOPS3__WD) {
                if (oops_from == 0) { L__M(##Miscellany, 14); continue; }
                if (nw == 1) { L__M(##Miscellany, 15); continue; }
                if (nw > 2) { L__M(##Miscellany, 16); continue; }
            
                ! So now we know: there was a previous mistake, and the player has
                ! attempted to correct a single word of it.
            
                for (i=0 : i<INPUT_BUFFER_LEN : i++) buffer2->i = a_buffer->i;
                #Ifdef TARGET_ZCODE;
                x1 = a_table->9; ! Start of word following "oops"
                x2 = a_table->8; ! Length of word following "oops"
                #Ifnot; ! TARGET_GLULX
                x1 = a_table-->6; ! Start of word following "oops"
                x2 = a_table-->5; ! Length of word following "oops"
                #Endif; ! TARGET_
            
                ! Repair the buffer to the text that was in it before the "oops"
                ! was typed:
                for (i=0 : i<64 : i++) a_buffer->i = oops_workspace->i;
                VM_Tokenise(a_buffer,a_table);
            
                ! Work out the position in the buffer of the word to be corrected:
                #Ifdef TARGET_ZCODE;
                w = a_table->(4*oops_from + 1); ! Start of word to go
                w2 = a_table->(4*oops_from); ! Length of word to go
                #Ifnot; ! TARGET_GLULX
                w = a_table-->(3*oops_from); ! Start of word to go
                w2 = a_table-->(3*oops_from - 1); ! Length of word to go
                #Endif; ! TARGET_
            
                ! Write spaces over the word to be corrected:
                for (i=0 : i<w2 : i++) a_buffer->(i+w) = ' ';
            
                if (w2 < x2) {
                    ! If the replacement is longer than the original, move up...
                    for (i=INPUT_BUFFER_LEN-1 : i>=w+x2 : i-- )
                        a_buffer->i = a_buffer->(i-x2+w2);

                    ! ...increasing buffer size accordingly.
                    #Ifdef TARGET_ZCODE;
                    a_buffer->1 = (a_buffer->1) + (x2-w2);
                    #Ifnot; ! TARGET_GLULX
                    a_buffer-->0 = (a_buffer-->0) + (x2-w2);
                    #Endif; ! TARGET_
                }
            
                ! Write the correction in:
                for (i=0 : i<x2 : i++) a_buffer->(i+w) = buffer2->(i+x1);
            
                VM_Tokenise(a_buffer, a_table);
                #Ifdef TARGET_ZCODE; nw = a_table->1; #Ifnot; nw = a_table-->0; #Endif;
            
                return nw;
            }

            ! Undo handling
        
            if ((w == UNDO1__WD or UNDO2__WD or UNDO3__WD) && (nw==1)) {
                Perform_Undo();
                continue;
            }
            i = VM_Save_Undo();
            #ifdef PREVENT_UNDO; undo_flag = 0; #endif;
            #ifndef PREVENT_UNDO; undo_flag = 2; #endif;
            if (i == -1) undo_flag = 0;
            if (i == 0) undo_flag = 1;
            if (i == 2) {
                VM_RestoreWindowColours();
                VM_Style(SUBHEADER_VMSTY);
                SL_Location(); print "^";
                ! print (name) location, "^";
                VM_Style(NORMAL_VMSTY);
                L__M(##Miscellany, 13);
                continue;
            }
            return nw;
        }
    ]; -) instead of "Reading the Command" in "Parser.i6t".

    The blank line replacement is an indexed text variable.
    The blank line replacement is usually "look".

    After reading a command (this is the Smarter Parser advanced replace blank line rule):
        let T be indexed text;
        now T is the player's command;
        if T is "":
            if the normal blank lines option is inactive:
                say ">[blank line replacement in upper case][command clarification break]";
                change the text of the player's command to the blank line replacement;
            otherwise:
                issue miscellaneous library message number 10; ["I beg your pardon?"]
                stop the action.