/* Sarien - A Sierra AGI resource interpreter engine * Copyright (C) 1999,2001 Stuart George and Claudio Matsuoka * * $Id: keyboard.c,v 1.67 2001/09/09 21:57:35 cmatsuoka Exp $ * * 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; see docs/COPYING for further details. */ #include #include #ifndef PALMOS #include #endif #include "sarien.h" #include "agi.h" #include "graphics.h" #include "keyboard.h" #include "menu.h" #include "text.h" /* remove later */ char last_sentence[40]; #ifdef USE_CONSOLE extern struct sarien_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 () { clean_input (); } void clean_input () { int i; for (i = 0; i < MAX_WORDS; i++) { game.ego_words[i].word = ""; game.ego_words[i].id = 0xffff; } game.num_ego_words = 0; } 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 (); _D ("key %02x pressed", key); } return key; } int handle_controller (int key) { struct vt_entry *v = &game.view_table[0]; int i; if (key == 0) return FALSE; _D (_D_WARN "key = %04x", key); for (i = 0; i < MAX_DIRS; i++) { if (game.ev_scan[i].data == KEY_SCAN(key) && KEY_ASCII(key) == 0) { _D ("event %d: scan code", i); game.ev_scan[i].occured = TRUE; report("event SC:%i occured\n", i); return TRUE; } if (game.ev_keyp[i].data == KEY_ASCII(key) && KEY_SCAN(key) == 0) { _D ("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; _D ("handling key: %02x", key); switch (key) { case KEY_ENTER: _D ("KEY_ENTER"); game.has_prompt = 0; buf[pos] = 0; strcpy (game.strings[stringdata.str], buf); _D (_D_WARN "buffer=[%s]", buf); buf[pos = 0] = 0; new_input_mode (INPUT_NORMAL); break; case KEY_ESCAPE: _D ("KEY_ESCAPE"); new_input_mode (INPUT_MENU); break; case KEY_BACKSPACE: /*0x08:*/ if (!pos) break; /* Print cursor */ /* print_character (stringdata.x + (pos + 1), stringdata.y, game.cursor_char, game.color_bg, game.color_bg ); */ 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; } /* SGEO */ 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); _D ("handling key: %02x", key); switch (key) { case KEY_ENTER: _D (("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 (game.echo_buffer, game.input_buffer); strcpy (last_sentence, formated_entry); dictionary_words (last_sentence); } /* Clear to start a new line*/ game.has_prompt = 0; game.input_buffer[game.cursor_pos = 0] = 0; _D (_D_WARN "clear lines"); clear_lines (l, l + 1, bg); flush_lines (l, l + 1); break; case KEY_ESCAPE: _D (("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 (); } _D (_D_WARN "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 (); } _D (_D_WARN "waiting..."); while (42) { poll_timer (); /* msdos driver -> does nothing */ key = do_poll_keyboard (); if (!console_keyhandler (key) && key) break; console_cycle (); } return key; }