Added Nitfol and Frotz source code.
[projects/chimara/chimara.git] / interpreters / frotz / input.c
diff --git a/interpreters/frotz/input.c b/interpreters/frotz/input.c
new file mode 100644 (file)
index 0000000..975830c
--- /dev/null
@@ -0,0 +1,298 @@
+/* input.c - High level input functions
+ *     Copyright (c) 1995-1997 Stefan Jokisch
+ *
+ * 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);
+extern zchar stream_read_input (int, zchar *, zword, zword, 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 */
+
+/*
+ * read_yes_or_no
+ *
+ * Ask the user a question; return true if the answer is yes.
+ *
+ */
+
+bool read_yes_or_no (const char *s)
+{
+    zchar key;
+
+    print_string (s);
+    print_string ("? (y/n) >");
+
+    key = stream_read_key (0, 0);
+
+    if (key == 'y' || key == 'Y') {
+       print_string ("y\n");
+       return TRUE;
+    } else {
+       print_string ("n\n");
+       return FALSE;
+    }
+
+}/* read_yes_or_no */
+
+/*
+ * 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);
+
+    } 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 */
+       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 */
+
+    if (key == ZC_BAD)
+       return;
+
+    /* Store key */
+
+    store (translate_to_zscii (key));
+
+}/* z_read_char */
+