mirror of
				https://github.com/Rockbox/rockbox.git
				synced 2025-10-26 23:36:37 -04:00 
			
		
		
		
	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
		
			
				
	
	
		
			301 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			301 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* 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 */
 |