From 7f28c94eda576e3f972fc05468188986f2e45885 Mon Sep 17 00:00:00 2001 From: Torne Wuff Date: Sun, 17 Jan 2010 22:15:13 +0000 Subject: New plugin: frotz, a Z-machine interpreter, for playing interactive fiction. The interpreter more or less passes all the tests in the z-machine test suite. It should build for every target except Archos (for which it is disabled). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24267 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/frotz/input.c | 301 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100644 apps/plugins/frotz/input.c (limited to 'apps/plugins/frotz/input.c') diff --git a/apps/plugins/frotz/input.c b/apps/plugins/frotz/input.c new file mode 100644 index 0000000000..296bffc529 --- /dev/null +++ b/apps/plugins/frotz/input.c @@ -0,0 +1,301 @@ +/* input.c - High level input functions + * Copyright (c) 1995-1997 Stefan Jokisch + * + * Changes for Rockbox copyright 2009 Torne Wuff + * + * This file is part of Frotz. + * + * Frotz is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Frotz is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "frotz.h" + +extern int save_undo (void); + +extern zchar stream_read_key (zword, zword, bool); +extern zchar stream_read_input (int, zchar *, zword, zword, bool, bool); + +extern void tokenise_line (zword, zword, zword, bool); + +/* + * is_terminator + * + * Check if the given key is an input terminator. + * + */ + +bool is_terminator (zchar key) +{ + + if (key == ZC_TIME_OUT) + return TRUE; + if (key == ZC_RETURN) + return TRUE; + if (key >= ZC_HKEY_MIN && key <= ZC_HKEY_MAX) + return TRUE; + + if (h_terminating_keys != 0) + + if (key >= ZC_ARROW_MIN && key <= ZC_MENU_CLICK) { + + zword addr = h_terminating_keys; + zbyte c; + + do { + LOW_BYTE (addr, c) + if (c == 255 || key == translate_from_zscii (c)) + return TRUE; + addr++; + } while (c != 0); + + } + + return FALSE; + +}/* is_terminator */ + +/* + * z_make_menu, add or remove a menu and branch if successful. + * + * zargs[0] = number of menu + * zargs[1] = table of menu entries or 0 to remove menu + * + */ + +void z_make_menu (void) +{ + + /* This opcode was only used for the Macintosh version of Journey. + It controls menus with numbers greater than 2 (menus 0, 1 and 2 + are system menus). Frotz doesn't implement menus yet. */ + + branch (FALSE); + +}/* z_make_menu */ + +extern bool read_yes_or_no (const char *s); + +/* + * read_string + * + * Read a string from the current input stream. + * + */ + +void read_string (int max, zchar *buffer) +{ + zchar key; + + buffer[0] = 0; + + do { + + key = stream_read_input (max, buffer, 0, 0, FALSE, FALSE); + + } while (key != ZC_RETURN); + +}/* read_string */ + +/* + * read_number + * + * Ask the user to type in a number and return it. + * + */ + +int read_number (void) +{ + zchar buffer[6]; + int value = 0; + int i; + + read_string (5, buffer); + + for (i = 0; buffer[i] != 0; i++) + if (buffer[i] >= '0' && buffer[i] <= '9') + value = 10 * value + buffer[i] - '0'; + + return value; + +}/* read_number */ + +/* + * z_read, read a line of input and (in V5+) store the terminating key. + * + * zargs[0] = address of text buffer + * zargs[1] = address of token buffer + * zargs[2] = timeout in tenths of a second (optional) + * zargs[3] = packed address of routine to be called on timeout + * + */ + +void z_read (void) +{ + zchar buffer[INPUT_BUFFER_SIZE]; + zword addr; + zchar key; + zbyte max, size; + zbyte c; + int i; + + /* Supply default arguments */ + + if (zargc < 3) + zargs[2] = 0; + + /* Get maximum input size */ + + addr = zargs[0]; + + LOW_BYTE (addr, max) + + if (h_version <= V4) + max--; + + if (max >= INPUT_BUFFER_SIZE) + max = INPUT_BUFFER_SIZE - 1; + + /* Get initial input size */ + + if (h_version >= V5) { + addr++; + LOW_BYTE (addr, size) + } else size = 0; + + /* Copy initial input to local buffer */ + + for (i = 0; i < size; i++) { + addr++; + LOW_BYTE (addr, c) + buffer[i] = translate_from_zscii (c); + } + + buffer[i] = 0; + + /* Draw status line for V1 to V3 games */ + + if (h_version <= V3) + z_show_status (); + + /* Read input from current input stream */ + + key = stream_read_input ( + max, buffer, /* buffer and size */ + zargs[2], /* timeout value */ + zargs[3], /* timeout routine */ + TRUE, /* enable hot keys */ + h_version == V6); /* no script in V6 */ + + if (key == ZC_BAD) + return; + + /* Perform save_undo for V1 to V4 games */ + + if (h_version <= V4) + save_undo (); + + /* Copy local buffer back to dynamic memory */ + + for (i = 0; buffer[i] != 0; i++) { + + if (key == ZC_RETURN) { + + if (buffer[i] >= 'A' && buffer[i] <= 'Z') + buffer[i] += 'a' - 'A'; + if (buffer[i] >= 0xc0 && buffer[i] <= 0xde && buffer[i] != 0xd7) + buffer[i] += 0x20; + + } + + storeb ((zword) (zargs[0] + ((h_version <= V4) ? 1 : 2) + i), translate_to_zscii (buffer[i])); + + } + + /* Add null character (V1-V4) or write input length into 2nd byte */ + + if (h_version <= V4) + storeb ((zword) (zargs[0] + 1 + i), 0); + else + storeb ((zword) (zargs[0] + 1), i); + + /* Tokenise line if a token buffer is present */ + + if (key == ZC_RETURN && zargs[1] != 0) + tokenise_line (zargs[0], zargs[1], 0, FALSE); + + /* Store key */ + + if (h_version >= V5) + store (translate_to_zscii (key)); + +}/* z_read */ + +/* + * z_read_char, read and store a key. + * + * zargs[0] = input device (must be 1) + * zargs[1] = timeout in tenths of a second (optional) + * zargs[2] = packed address of routine to be called on timeout + * + */ + +void z_read_char (void) +{ + zchar key; + + /* Supply default arguments */ + + if (zargc < 2) + zargs[1] = 0; + + /* Read input from the current input stream */ + + key = stream_read_key ( + zargs[1], /* timeout value */ + zargs[2], /* timeout routine */ + TRUE); /* enable hot keys */ + + if (key == ZC_BAD) + return; + + /* Store key */ + + store (translate_to_zscii (key)); + +}/* z_read_char */ + +/* + * z_read_mouse, write the current mouse status into a table. + * + * zargs[0] = address of table + * + */ + +void z_read_mouse (void) +{ + zword btn; + + /* Read the mouse position and which buttons are down */ + + btn = os_read_mouse (); + hx_mouse_y = mouse_y; + hx_mouse_x = mouse_x; + + storew ((zword) (zargs[0] + 0), hx_mouse_y); + storew ((zword) (zargs[0] + 2), hx_mouse_x); + storew ((zword) (zargs[0] + 4), btn); /* mouse button bits */ + storew ((zword) (zargs[0] + 6), 0); /* menu selection */ + +}/* z_read_mouse */ -- cgit v1.2.3