예제 #1
0
def ascii_to_zscii(string):
    result = []
    i = 0
    while i < len(string):
        c = string[i]
        if c == '\n':
            result.append(ord('\r'))
        # NOTE: gargoyle just ignores the tab key, S 3.8.2.3 says
        # output only. But since I want to keep expected tab behavior,
        # I make this compromise.
        elif c == '\t':
            result.append(ord(' '))
        elif c in ('\r', '\b') or (len(c) == 1 and ord(c) > 31
                                   and ord(c) < 127):
            result.append(ord(c))
            # TODO (?): unicode for input (translate codes to zscii using the unicode table(s))
            # TODO: keypad digits
        elif c == '\x1b':
            esc_key_tbl = {
                # arrow keys
                '[A': 129,
                '[B': 130,
                '[C': 132,
                '[D': 131,
                # fkeys
                'OP': 133,
                'OQ': 134,
                'OR': 135,
                'OS': 136,
                '[15~': 137,
                '[17~': 138,
                '[18~': 139,
                '[19~': 140,
                '[20~': 141,
                '[21~': 142,
                '[23~': 143,
                '[24~': 144,
            }
            found = False
            next_few = string[i + 1:i + 5]
            for seq in esc_key_tbl:
                if next_few.startswith(seq):
                    result.append(esc_key_tbl[seq])
                    i += len(seq)
                    found = True
                    break
            if not found:
                result.append(ord(c))
        else:
            if DBG:
                term.puts('\nthis ascii char not yet implemented in zscii: ' +
                          str(c) + ' / ' + str(ord(c)) + '\n')
                term.puts('\nHIT ENTER TO CONTINUE\n')
                term.getch_or_esc_seq()
            result.append(ord('?'))
        i += 1
    return result
예제 #2
0
 def pause_scroll_for_user_input(self):
     # TODO: mark last paused line, set it up so such lines get
     # marked with a plus when still in the buffer, to help your
     # eye track the scroll.
     self.flush()
     if not buf_empty(self.textBuf):
         term_width, term_height = term.get_size()
         if term_width - self.env.hdr.screen_width_units > 0:
             term.home_cursor()
             term.cursor_down(term_height-1)
             # we reserve a one unit right margin for this status char
             term.cursor_right(self.env.hdr.screen_width_units)
             term.write_char_with_color('+', self.env.fg_color, self.env.bg_color)
         term.getch_or_esc_seq()
     self.update_seen_lines()
예제 #3
0
 def getch_or_esc_seq(self):
     self.flush()
     c = term.getch_or_esc_seq()
     self.update_seen_lines()
     if c == '\x7f':  #delete should be backspace
         c = '\b'
     if not is_valid_getch_char(c):
         return '?'
     return c
예제 #4
0
def ascii_to_zscii(string):
    result = []
    i = 0
    while i < len(string):
        c = string[i]
        if c == '\n':
            result.append(ord('\r'))
        # NOTE: gargoyle just ignores the tab key, S 3.8.2.3 says
        # output only. But since I want to keep expected tab behavior,
        # I make this compromise.
        elif c == '\t':
            result.append(ord(' '))
        elif c in ('\r','\b') or (len(c) == 1 and ord(c) > 31 and ord(c) < 127):
            result.append(ord(c))
            # TODO (?): unicode for input (translate codes to zscii using the unicode table(s))
            # TODO: keypad digits
        elif c == '\x1b':
            esc_key_tbl = {
                # arrow keys
                '[A': 129, '[B': 130, '[C': 132, '[D':131,
                # fkeys
                'OP': 133, 'OQ': 134, 'OR': 135, 'OS': 136, '[15~': 137,
                '[17~': 138, '[18~': 139, '[19~' :140, '[20~': 141,
                '[21~': 142, '[23~': 143, '[24~': 144,
            }
            found = False
            next_few = string[i+1:i+5]
            for seq in esc_key_tbl:
                if next_few.startswith(seq):
                    result.append(esc_key_tbl[seq])
                    i += len(seq)
                    found = True
                    break
            if not found:
                result.append(ord(c))
        else:
            if DBG:
                term.puts('\nthis ascii char not yet implemented in zscii: '+str(c)+' / '+str(ord(c)) + '\n')
                term.puts('\nHIT ENTER TO CONTINUE\n')
                term.getch_or_esc_seq()
            result.append(ord('?'))
        i += 1
    return result
예제 #5
0
 def msg(self, text):
     self.write(text)
     self.flush()
     term.getch_or_esc_seq()
예제 #6
0
    def get_line_of_input(self, prompt='', prefilled=''):
        env = self.env

        for c in prompt:
            self.write_unwrapped(
                [ScreenChar(c, env.fg_color, env.bg_color, env.text_style)])
        self.flush()
        self.update_seen_lines()

        row, col = env.cursor[env.current_window]

        term.home_cursor()
        term.cursor_down(row)
        term.cursor_right(col)
        term.set_color(env.fg_color, env.bg_color)
        if line_empty(self.textBuf[row][col:]):
            term.fill_to_eol_with_bg_color()
        term.show_cursor()

        col = max(
            0, col - len(prefilled)
        )  # TODO: prefilled is a seldom-used old and crusty feature, but make unicode safe
        env.cursor[env.current_window] = row, col

        class CursorLine(object):
            def __init__(self, cursor_start, chars):
                self.cursor = cursor_start
                self.chars = chars

            def backspace(self):
                if self.cursor == 0:
                    return
                self.left()
                self.delete_char()

            def delete_char(self):
                del self.chars[self.cursor:self.cursor + 1]
                self.refresh_rest_of_line(is_delete=True)

            def refresh_rest_of_line(self, is_delete=False):
                rest = self.chars[self.cursor:]
                term.puts(''.join(rest))
                to_back_up = len(rest)
                if is_delete:
                    term.puts(' ')
                    to_back_up += 1
                if to_back_up:
                    term.cursor_left(to_back_up)

            def left(self):
                if self.cursor > 0:
                    self.cursor -= 1
                    term.cursor_left()

            def right(self):
                if self.cursor < len(self.chars):
                    self.cursor += 1
                    term.cursor_right()

            def home(self):
                while self.cursor > 0:
                    self.left()

            def end(self):
                while self.cursor != len(self.chars):
                    self.right()

            def kill_left(self):
                while self.chars[:self.cursor]:
                    self.backspace()

            def kill_right(self):
                while self.chars[self.cursor:]:
                    self.delete_char()

            def insert(self, c):
                self.chars.insert(self.cursor, c)
                term.puts(c)
                self.cursor += 1
                self.refresh_rest_of_line()

        cursor_start = len(prefilled)
        cursor_line = CursorLine(cursor_start, [c for c in prefilled])

        max_input_len = 120  # 120 char limit seen on gargoyle
        c = term.getch_or_esc_seq()
        while c != '\n' and c != '\r':
            if c == '\b' or c == '\x7f':
                cursor_line.backspace()

            # normal edit keys and a bit of readline flavor

            # left arrow or C-b
            elif c == '\x1b[D' or c == '\x02':
                cursor_line.left()

            # right arrow or C-f
            elif c == '\x1b[C' or c == '\x06':
                cursor_line.right()

            # home or C-a
            elif c == '\x1b[H' or c == '\x01':
                cursor_line.home()

            # end or C-e
            elif c == '\x1b[F' or c == '\x05':
                cursor_line.end()

            # delete or C-d
            elif c == '\x1b[3~' or c == '\x04':
                cursor_line.delete_char()

            # C-u, kill left of cursor
            elif c == '\x15':
                cursor_line.kill_left()

            # C-u, kill right of cursor
            elif c == '\x0b':
                cursor_line.kill_right()

            else:
                if is_valid_inline_char(c) and len(
                        cursor_line.chars) < max_input_len:
                    if c == '\t':
                        if len(cursor_line.chars) + 4 <= max_input_len:
                            for i in range(4):
                                cursor_line.insert(' ')
                    else:
                        cursor_line.insert(c)

            c = term.getch_or_esc_seq()

        term.hide_cursor()
        term.flush()
        for c in cursor_line.chars:
            self.write_unwrapped(
                [ScreenChar(c, env.fg_color, env.bg_color, env.text_style)])
        self.new_line_via_spaces(env.fg_color, env.bg_color, env.text_style)
        term.home_cursor()
        return ''.join(cursor_line.chars)
예제 #7
0
 def msg(self, text):
     self.write(text)
     self.write('[press any key to continue]\n')
     self.flush()
     term.getch_or_esc_seq()