Logo Search packages:      
Sourcecode: sarien version File versions  Download package

keyboard.c

/*  Sarien - A Sierra AGI resource interpreter engine
 *  Copyright (C) 1999-2003 Stuart George and Claudio Matsuoka
 *
 *  $Id: keyboard.c,v 1.78 2003/07/16 18:32:05 bootstrap666 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 <stdio.h>
#include <string.h>

#ifndef PALMOS
#include <ctype.h>
#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 ()
{
      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 ();
            _D ("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;

      _D (_D_WARN "key = %04x", key);

      for (i = 0; i < MAX_DIRS; i++) {
            if (game.ev_keyp[i].data == key) {
                  _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);
            print_character (stringdata.x + strlen (game.strings[stringdata.str]) + 1, stringdata.y,
                  ' ', game.color_fg, game.color_bg);
            return;
      case KEY_ESCAPE:
            _D ("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);

      _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;
}


Generated by  Doxygen 1.6.0   Back to index