aboutsummaryrefslogtreecommitdiff
path: root/engines/agi/keyboard.cpp
diff options
context:
space:
mode:
authorPaweł Kołodziejski2006-05-23 23:43:52 +0000
committerPaweł Kołodziejski2006-05-23 23:43:52 +0000
commit107073537e4ad24e294e28a2a62f8d3ad33008ff (patch)
tree9eade8ff944f701d2676aa2ddd94e3585be9c813 /engines/agi/keyboard.cpp
parent3a025038da6d351789d5daf29e4751678c47fed1 (diff)
downloadscummvm-rg350-107073537e4ad24e294e28a2a62f8d3ad33008ff.tar.gz
scummvm-rg350-107073537e4ad24e294e28a2a62f8d3ad33008ff.tar.bz2
scummvm-rg350-107073537e4ad24e294e28a2a62f8d3ad33008ff.zip
imported AGI engine
svn-id: r22588
Diffstat (limited to 'engines/agi/keyboard.cpp')
-rw-r--r--engines/agi/keyboard.cpp388
1 files changed, 388 insertions, 0 deletions
diff --git a/engines/agi/keyboard.cpp b/engines/agi/keyboard.cpp
new file mode 100644
index 0000000000..998b95f1cd
--- /dev/null
+++ b/engines/agi/keyboard.cpp
@@ -0,0 +1,388 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * Copyright (C) 1999-2003 Sarien Team
+ *
+ * This program 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.
+
+ * This program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "agi/agi.h"
+#include "agi/graphics.h"
+#include "agi/keyboard.h"
+#include "agi/menu.h"
+#include "agi/text.h" /* remove later */
+
+namespace Agi {
+
+char last_sentence[40];
+
+#ifdef USE_CONSOLE
+extern struct agi_console console;
+#endif
+
+/* FIXME */
+extern int open_dialogue;
+
+struct string_data {
+ int x;
+ int y;
+ int len;
+ int str;
+};
+
+struct string_data stringdata;
+
+/*
+ * IBM-PC keyboard scancodes
+ */
+uint8 scancode_table[26] = {
+ 30, /* A */
+ 48, /* B */
+ 46, /* C */
+ 32, /* D */
+ 18, /* E */
+ 33, /* F */
+ 34, /* G */
+ 35, /* H */
+ 23, /* I */
+ 36, /* J */
+ 37, /* K */
+ 38, /* L */
+ 50, /* M */
+ 49, /* N */
+ 24, /* O */
+ 25, /* P */
+ 16, /* Q */
+ 19, /* R */
+ 31, /* S */
+ 20, /* T */
+ 22, /* U */
+ 47, /* V */
+ 17, /* W */
+ 45, /* X */
+ 21, /* Y */
+ 44 /* Z */
+};
+
+void init_words() {
+ game.num_ego_words = 0;
+}
+
+void clean_input() {
+ while (game.num_ego_words)
+ free(game.ego_words[--game.num_ego_words].word);
+}
+
+void get_string(int x, int y, int len, int str) {
+ new_input_mode(INPUT_GETSTRING);
+ stringdata.x = x;
+ stringdata.y = y;
+ stringdata.len = len;
+ stringdata.str = str;
+}
+
+/**
+ * Raw key grabber.
+ * poll_keyboard() is the raw key grabber (above the gfx driver, that is).
+ * It handles console keys and insulates AGI from the console. In the main
+ * loop, handle_keys() handles keyboard input and ego movement.
+ */
+int do_poll_keyboard() {
+ int key = 0;
+
+ /* If a key is ready, rip it */
+ if (keypress()) {
+ key = get_key();
+ debugC(3, kDebugLevelInput, "key %02x pressed", key);
+ }
+
+ return key;
+}
+
+int handle_controller(int key) {
+ struct vt_entry *v = &game.view_table[0];
+ int i;
+
+ /* The Black Cauldron needs KEY_ESCAPE to use menus */
+ if (key == 0 /*|| key == KEY_ESCAPE */ )
+ return false;
+
+ debugC(3, kDebugLevelInput, "key = %04x", key);
+
+ for (i = 0; i < MAX_DIRS; i++) {
+ if (game.ev_keyp[i].data == key) {
+ debugC(3, kDebugLevelInput, "event %d: key press", i);
+ game.ev_keyp[i].occured = true;
+ report("event AC:%i occured\n", i);
+ return true;
+ }
+ }
+
+#ifdef USE_MOUSE
+ if (key == BUTTON_LEFT) {
+ if (getflag(F_menus_work) && mouse.y <= CHAR_LINES) {
+ new_input_mode(INPUT_MENU);
+ return true;
+ }
+ }
+#endif
+
+ if (game.player_control) {
+ int d = 0;
+
+ if (!KEY_ASCII(key)) {
+ switch (key) {
+ case KEY_UP:
+ d = 1;
+ break;
+ case KEY_DOWN:
+ d = 5;
+ break;
+ case KEY_LEFT:
+ d = 7;
+ break;
+ case KEY_RIGHT:
+ d = 3;
+ break;
+ case KEY_UP_RIGHT:
+ d = 2;
+ break;
+ case KEY_DOWN_RIGHT:
+ d = 4;
+ break;
+ case KEY_UP_LEFT:
+ d = 8;
+ break;
+ case KEY_DOWN_LEFT:
+ d = 6;
+ break;
+ }
+ }
+#ifdef USE_MOUSE
+ if (!opt.agimouse) {
+ /* Handle mouse button events */
+ if (key == BUTTON_LEFT) {
+ v->flags |= ADJ_EGO_XY;
+ v->parm1 = WIN_TO_PIC_X(mouse.x);
+ v->parm2 = WIN_TO_PIC_Y(mouse.y);
+ return true;
+ }
+ }
+#endif
+
+ v->flags &= ~ADJ_EGO_XY;
+
+ if (d || key == KEY_STATIONARY) {
+ v->direction = v->direction == d ? 0 : d;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void handle_getstring(int key) {
+ static int pos = 0; /* Cursor position */
+ static char buf[40];
+
+ if (KEY_ASCII(key) == 0)
+ return;
+
+ debugC(3, kDebugLevelInput, "handling key: %02x", key);
+
+ switch (key) {
+ case KEY_ENTER:
+ debugC(3, kDebugLevelInput, "KEY_ENTER");
+ game.has_prompt = 0;
+ buf[pos] = 0;
+ strcpy(game.strings[stringdata.str], buf);
+ debugC(3, kDebugLevelInput, "buffer=[%s]", buf);
+ buf[pos = 0] = 0;
+ new_input_mode(INPUT_NORMAL);
+ print_character(stringdata.x + strlen(game.strings[stringdata.str]) + 1,
+ stringdata.y, ' ', game.color_fg, game.color_bg);
+ return;
+ case KEY_ESCAPE:
+ debugC(3, kDebugLevelInput, "KEY_ESCAPE");
+ game.has_prompt = 0;
+ buf[pos = 0] = 0;
+ strcpy(game.strings[stringdata.str], buf);
+ new_input_mode(INPUT_NORMAL);
+ /* new_input_mode (INPUT_MENU); */
+ break;
+ case KEY_BACKSPACE: /*0x08: */
+ if (!pos)
+ break;
+
+ print_character(stringdata.x + (pos + 1), stringdata.y,
+ ' ', game.color_fg, game.color_bg);
+
+ pos--;
+ buf[pos] = 0;
+ break;
+ default:
+ if (key < 0x20 || key > 0x7f)
+ break;
+
+ if (pos >= stringdata.len)
+ break;
+
+ buf[pos++] = key;
+ buf[pos] = 0;
+
+ /* Echo */
+ print_character(stringdata.x + pos, stringdata.y, buf[pos - 1],
+ game.color_fg, game.color_bg);
+
+ break;
+ }
+
+ /* print cursor */
+ print_character(stringdata.x + pos + 1, stringdata.y,
+ (char)game.cursor_char, game.color_fg, game.color_bg);
+}
+
+void handle_keys(int key) {
+ uint8 *p = NULL;
+ int c = 0;
+ static uint8 formated_entry[256];
+ int l = game.line_user_input;
+ int fg = game.color_fg, bg = game.color_bg;
+
+ setvar(V_word_not_found, 0);
+
+ debugC(3, kDebugLevelInput, "handling key: %02x", key);
+
+ switch (key) {
+ case KEY_ENTER:
+ debugC(3, kDebugLevelInput, "KEY_ENTER");
+ game.keypress = 0;
+
+ /* Remove all leading spaces */
+ for (p = game.input_buffer; *p && *p == 0x20; p++);
+
+ /* Copy to internal buffer */
+ for (; *p; p++) {
+ /* Squash spaces */
+ if (*p == 0x20 && *(p + 1) == 0x20) {
+ p++;
+ continue;
+ }
+ formated_entry[c++] = tolower(*p);
+ }
+ formated_entry[c++] = 0;
+
+ /* Handle string only if it's not empty */
+ if (formated_entry[0]) {
+ strcpy((char *)game.echo_buffer, (const char *)game.input_buffer);
+ strcpy(last_sentence, (const char *)formated_entry);
+ dictionary_words(last_sentence);
+ }
+
+ /* Clear to start a new line */
+ game.has_prompt = 0;
+ game.input_buffer[game.cursor_pos = 0] = 0;
+ debugC(3, kDebugLevelInput, "clear lines");
+ clear_lines(l, l + 1, bg);
+ flush_lines(l, l + 1);
+
+ break;
+ case KEY_ESCAPE:
+ debugC(3, kDebugLevelInput, "KEY_ESCAPE");
+ new_input_mode(INPUT_MENU);
+ break;
+ case KEY_BACKSPACE:
+ /* Ignore backspace at start of line */
+ if (game.cursor_pos == 0)
+ break;
+
+ /* erase cursor */
+ print_character(game.cursor_pos + 1, l, ' ', fg, bg);
+ game.input_buffer[--game.cursor_pos] = 0;
+ /* Print cursor */
+ print_character(game.cursor_pos + 1, l, game.cursor_char, fg, bg);
+ break;
+ default:
+ /* Ignore invalid keystrokes */
+ if (key < 0x20 || key > 0x7f)
+ break;
+
+ /* Maximum input size reached */
+ if (game.cursor_pos >= getvar(V_max_input_chars))
+ break;
+
+ game.input_buffer[game.cursor_pos++] = key;
+ game.input_buffer[game.cursor_pos] = 0;
+
+ /* echo */
+ print_character(game.cursor_pos, l, game.input_buffer[game.cursor_pos - 1], fg, bg);
+
+ /* Print cursor */
+ print_character(game.cursor_pos + 1, l, game.cursor_char, fg, bg);
+ break;
+ }
+}
+
+int wait_key() {
+ int key;
+
+ /* clear key queue */
+ while (keypress()) {
+ get_key();
+ }
+
+ debugC(3, kDebugLevelInput, "waiting...");
+ while (42) {
+ poll_timer(); /* msdos driver -> does nothing */
+ key = do_poll_keyboard();
+ if (!console_keyhandler(key)) {
+ if (key == KEY_ENTER || key == KEY_ESCAPE
+#ifdef USE_MOUSE
+ || key == BUTTON_LEFT
+#endif
+ )
+ break;
+ }
+ console_cycle();
+ }
+ return key;
+}
+
+int wait_any_key() {
+ int key;
+
+ /* clear key queue */
+ while (keypress()) {
+ get_key();
+ }
+
+ debugC(3, kDebugLevelInput, "waiting...");
+ while (42) {
+ poll_timer(); /* msdos driver -> does nothing */
+ key = do_poll_keyboard();
+ if (!console_keyhandler(key) && key)
+ break;
+ console_cycle();
+ }
+ return key;
+}
+
+} // End of namespace Agi