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

ps2input.cpp

/* ScummVM - Scumm Interpreter
 * Copyright (C) 2005 The ScummVM project
 *
 * 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.
 *
 * $Header: /cvsroot/scummvm/scummvm/backends/ps2/ps2input.cpp,v 1.4.2.2 2005/10/25 06:56:28 lavosspawn Exp $
 *
 */

#include <kernel.h>
#include <malloc.h>
#include <assert.h>
#include <libmouse.h>
#include "backends/ps2/rpckbd.h"
#include "backends/ps2/ps2input.h"
#include "backends/ps2/ps2pad.h"
#include "backends/ps2/systemps2.h"
#include "backends/ps2/sdlkeys.h"
#include "common/system.h"

Ps2Input::Ps2Input(OSystem_PS2 *system, bool mouseLoaded, bool kbdLoaded) {
      _system = system;
      _mouseLoaded = mouseLoaded;
      _kbdLoaded = kbdLoaded;
      _pad = new Ps2Pad(system);
      _lastPadCheck = 0;
      _posX = _posY = _mButtons = _padLastButtons = 0;
      _padAccel = 0;
      _minx = _miny = 0;
      _maxy = 239;
      _maxx = 319;
      _keyFlags = 0;
      if (_mouseLoaded) {
            if (PS2MouseInit() >= 0) {
                  PS2MouseSetReadMode(PS2MOUSE_READMODE_ABS);
                  printf("PS2Mouse initialized\n");
            } else { // shouldn't happen if the drivers were correctly loaded
                  printf("unable to initialize PS2Mouse!\n");
                  _mouseLoaded = false;
            }
      }
      if (_kbdLoaded) {
            if (PS2KbdInit() >= 0) {
                  PS2KbdSetReadmode(PS2KBD_READMODE_RAW);
                  printf("PS2Kbd initialized\n");
            } else {
                  printf("unable to initialize PS2Kbd!\n");
                  _kbdLoaded = false;
            }
      }
}

Ps2Input::~Ps2Input(void) {
}

void Ps2Input::newRange(uint16 minx, uint16 miny, uint16 maxx, uint16 maxy) {
      _minx = minx;
      _miny = miny;
      _maxx = maxx;
      _maxy = maxy;
      if (_mouseLoaded)
            PS2MouseSetBoundary(minx, maxx, miny, maxy);
      warpTo(_posX, _posY);
}

void Ps2Input::warpTo(uint16 x, uint16 y) {
      if ((x >= _minx) && (x <= _maxx) && (y >= _miny) && (y <= _maxy)) {
            _posX = x;
            _posY = y;
      } else {
            _posX = (x < _minx) ? (_minx) : ((x > _maxx) ? (_maxx) : (x));
            _posY = (y < _miny) ? (_miny) : ((y > _maxy) ? (_maxy) : (y));
      }
      if (_mouseLoaded)
            PS2MouseSetPosition(_posX, _posY);
}

#define JOY_THRESHOLD 30
#define PAD_CHECK_TIME 20

int Ps2Input::mapKey(int key, int mod) { // copied from sdl backend
      if (key >= SDLK_F1 && key <= SDLK_F9) {
            return key - SDLK_F1 + 315;
      } else if (key >= SDLK_KP0 && key <= SDLK_KP9) {
            return key - SDLK_KP0 + '0';
      } else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) {
            return key;
      } else if (key >= 'a' && key <= 'z' && mod & OSystem::KBD_SHIFT) {
            return key & ~0x20;
      } else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) {
            return 0;
      }
      return key;
}

bool Ps2Input::pollEvent(OSystem::Event *event) {
      bool checkPadMouse, checkPadKbd;
      checkPadMouse = checkPadKbd = _pad->padAlive();

      if (_mouseLoaded && (PS2MouseEnum() > 0)) { // usb mouse connected
            mouse_data mData;
            PS2MouseRead(&mData);
            if ((_posX != mData.x) || (_posY != mData.y)) {
                  event->mouse.x = _posX = mData.x;
                  event->mouse.y = _posY = mData.y;
                  event->type = OSystem::EVENT_MOUSEMOVE;
            return true;
            }
            if (mData.buttons != _mButtons) {
                  uint16 change = _mButtons ^ mData.buttons;
                  _mButtons = mData.buttons;
                  if (change & (PS2MOUSE_BTN1 | PS2MOUSE_BTN2)) {
                        if (change & PS2MOUSE_BTN1)
                              event->type = (_mButtons & PS2MOUSE_BTN1) ? OSystem::EVENT_LBUTTONDOWN : OSystem::EVENT_LBUTTONUP;
                        else
                              event->type = (_mButtons & PS2MOUSE_BTN2) ? OSystem::EVENT_RBUTTONDOWN : OSystem::EVENT_RBUTTONUP;
                        event->mouse.x = _posX;
                        event->mouse.y = _posY;
                        return true;
                  }
            }
            checkPadMouse = false;
      }
      if (_kbdLoaded) { // there's no way to tell if there's actually a keyboard connected
            PS2KbdRawKey key;
            if (PS2KbdReadRaw(&key) == 1) {
                  if (_usbToSdlk[key.key]) {
                        if ((_usbToSdlk[key.key] == SDLK_LSHIFT) || (_usbToSdlk[key.key] == SDLK_RSHIFT)) {
                              if (key.state & 1)
                                    _keyFlags |= OSystem::KBD_SHIFT;
                              else
                                    _keyFlags &= ~OSystem::KBD_SHIFT;
                        } else if ((_usbToSdlk[key.key] == SDLK_LCTRL) || (_usbToSdlk[key.key] == SDLK_RCTRL)) {
                              if (key.state & 1)
                                    _keyFlags |= OSystem::KBD_CTRL;
                              else
                                    _keyFlags &= ~OSystem::KBD_CTRL;
                        } else if ((_usbToSdlk[key.key] == SDLK_LALT) || (_usbToSdlk[key.key] == SDLK_RALT)) {
                              if (key.state & 1)
                                    _keyFlags |= OSystem::KBD_ALT;
                              else
                                    _keyFlags &= ~OSystem::KBD_ALT;
                        }
                        if (key.state & 1) // down
                              event->type = OSystem::EVENT_KEYDOWN;
                        else
                              event->type = OSystem::EVENT_KEYUP;
                        event->kbd.flags = 0;
                        event->kbd.keycode = _usbToSdlk[key.key];
                        event->kbd.ascii = mapKey(_usbToSdlk[key.key], _keyFlags);
                        return true;
                  } else
                        printf("unknown keycode %02X - %02X\n", key.state, key.key);
            }
      }
      if (checkPadMouse || checkPadKbd) {
            // no usb mouse, simulate it using the pad
        uint16 buttons;
            int16 joyh, joyv;
            _pad->readPad(&buttons, &joyh, &joyv);
            uint16 btnChange = buttons ^ _padLastButtons;

            if (checkPadMouse) {
                  if (btnChange & (PAD_CROSS | PAD_CIRCLE)) {
                        if (btnChange & PAD_CROSS)
                              event->type = (buttons & PAD_CROSS) ?  OSystem::EVENT_LBUTTONDOWN : OSystem::EVENT_LBUTTONUP;
                        else
                              event->type = (buttons & PAD_CIRCLE) ? OSystem::EVENT_RBUTTONDOWN : OSystem::EVENT_RBUTTONUP;
                        event->mouse.x = _posX;
                        event->mouse.y = _posY;
                        _padLastButtons = buttons;
                        return true;
                  }
                  uint32 time = _system->getMillis();
                  if (time - _lastPadCheck > PAD_CHECK_TIME) {
                        _lastPadCheck = time;
                        int16 newX = _posX;
                        int16 newY = _posY;
                        if ((ABS(joyh) > JOY_THRESHOLD) || (ABS(joyv) > JOY_THRESHOLD)) {
                              newX += joyh / 20;
                              newY += joyv / 20;
                        } else if (buttons & PAD_DIR_MASK) {
                              if (_padLastButtons & PAD_DIR_MASK) {
                                    if (_padAccel < 16)
                                          _padAccel++;
                              } else
                                    _padAccel = 0;
                              _padLastButtons = buttons;
                              if (buttons & PAD_LEFT)
                                    newX -= _padAccel >> 2;
                              if (buttons & PAD_RIGHT)
                                    newX += _padAccel >> 2;
                              if (buttons & PAD_UP)
                                    newY -= _padAccel >> 2;
                              if (buttons & PAD_DOWN)
                                    newY += _padAccel >> 2;
                        }
                        newX = ((newX < (int16)_minx) ? (_minx) : ((newX > (int16)_maxx) ? (_maxx) : ((int16)newX)));
                        newY = ((newY < (int16)_miny) ? (_miny) : ((newY > (int16)_maxy) ? (_maxy) : ((int16)newY)));
                        if ((_posX != newX) || (_posY != newY)) {
                              event->type = OSystem::EVENT_MOUSEMOVE;
                              event->mouse.x = _posX = newX;
                              event->mouse.y = _posY = newY;
                              return true;
                        }
                  }
            }
            if (checkPadKbd) {
                  if (getKeyEvent(event, btnChange, (btnChange & buttons) != 0)) {
                        _padLastButtons = buttons;
                        return true;
                  }
            }
      }
      return false;
}

bool Ps2Input::getKeyEvent(OSystem::Event *event, uint16 buttonCode, bool down) {
      // for simulating key presses with the pad
      if (buttonCode) {
            uint8 entry = 0;
            while (!(buttonCode & 1)) {
                  entry++;
                  buttonCode >>= 1;
            }
            if (_asciiCodes[entry] || _keyCodes[entry]) {
                  event->type = (down) ? OSystem::EVENT_KEYDOWN : OSystem::EVENT_KEYUP;
                  event->kbd.ascii = _asciiCodes[entry];
                  event->kbd.keycode = _keyCodes[entry];
                  event->kbd.flags = 0;
                  return true;
            }
      }
      return false;
}

const int Ps2Input::_usbToSdlk[0x100] = {
      /* 00 */    0,
      /* 01 */    0,
      /* 02 */    0,
      /* 03 */    0,
      /* 04 */    SDLK_a,
      /* 05 */    SDLK_b,
      /* 06 */    SDLK_c,
      /* 07 */    SDLK_d,
      /* 08 */    SDLK_e,
      /* 09 */    SDLK_f,
      /* 0A */    SDLK_g,
      /* 0B */    SDLK_h,
      /* 0C */    SDLK_i,
      /* 0D */    SDLK_j,
      /* 0E */    SDLK_k,
      /* 0F */    SDLK_l,
      /* 10 */    SDLK_m,
      /* 11 */    SDLK_n,
      /* 12 */    SDLK_o,
      /* 13 */    SDLK_p,
      /* 14 */    SDLK_q,
      /* 15 */    SDLK_r,
      /* 16 */    SDLK_s,
      /* 17 */    SDLK_t,
      /* 18 */    SDLK_u,
      /* 19 */    SDLK_v,
      /* 1A */    SDLK_w,
      /* 1B */    SDLK_x,
      /* 1C */    SDLK_y,
      /* 1D */    SDLK_z,
      /* 1E */    SDLK_1,
      /* 1F */    SDLK_2,
      /* 20 */    SDLK_3,
      /* 21 */    SDLK_4,
      /* 22 */    SDLK_5,
      /* 23 */    SDLK_6,
      /* 24 */    SDLK_7,
      /* 25 */    SDLK_8,
      /* 26 */    SDLK_9,
      /* 27 */    SDLK_0,
      /* 28 */    SDLK_RETURN,
      /* 29 */    SDLK_ESCAPE,
      /* 2A */    SDLK_BACKSPACE,
      /* 2B */    SDLK_TAB,
      /* 2C */    SDLK_SPACE,
      /* 2D */    SDLK_MINUS,
      /* 2E */    SDLK_EQUALS,
      /* 2F */    SDLK_LEFTBRACKET,
      /* 30 */    SDLK_RIGHTBRACKET,
      /* 31 */    SDLK_BACKSLASH,
      /* 32 */    SDLK_HASH,
      /* 33 */    SDLK_SEMICOLON,
      /* 34 */    SDLK_QUOTE,
      /* 35 */    SDLK_BACKQUOTE,
      /* 36 */    SDLK_COMMA,
      /* 37 */    SDLK_PERIOD,
      /* 38 */    SDLK_SLASH,
      /* 39 */    SDLK_CAPSLOCK,
      /* 3A */    SDLK_F1,
      /* 3B */    SDLK_F2,
      /* 3C */    SDLK_F3,
      /* 3D */    SDLK_F4,
      /* 3E */    SDLK_F5,
      /* 3F */    SDLK_F6,
      /* 40 */    SDLK_F7,
      /* 41 */    SDLK_F8,
      /* 42 */    SDLK_F9,
      /* 43 */    SDLK_F10,
      /* 44 */    SDLK_F11,
      /* 45 */    SDLK_F12,
      /* 46 */    SDLK_PRINT,
      /* 47 */    SDLK_SCROLLOCK,
      /* 48 */    SDLK_PAUSE,
      /* 49 */    SDLK_INSERT,
      /* 4A */    SDLK_HOME,
      /* 4B */    SDLK_PAGEUP,
      /* 4C */    SDLK_DELETE,
      /* 4D */    SDLK_END,
      /* 4E */    SDLK_PAGEDOWN,
      /* 4F */    SDLK_RIGHT,
      /* 50 */    SDLK_LEFT,
      /* 51 */    SDLK_DOWN,
      /* 52 */    SDLK_UP,
      /* 53 */    SDLK_NUMLOCK,
      /* 54 */    SDLK_KP_DIVIDE,
      /* 55 */    SDLK_KP_MULTIPLY,
      /* 56 */    SDLK_KP_MINUS,
      /* 57 */    SDLK_KP_PLUS,
      /* 58 */    SDLK_KP_ENTER,
      /* 59 */    SDLK_KP1,
      /* 5A */    SDLK_KP2,
      /* 5B */    SDLK_KP3,
      /* 5C */    SDLK_KP4,
      /* 5D */    SDLK_KP5,
      /* 5E */    SDLK_KP6,
      /* 5F */    SDLK_KP7,
      /* 60 */    SDLK_KP8,
      /* 61 */    SDLK_KP9,
      /* 62 */    SDLK_KP0,
      /* 63 */    SDLK_KP_PERIOD,
      /* 64 */    0,
      /* 65 */    0,
      /* 66 */    0,
      /* 67 */    SDLK_KP_EQUALS,
      /* 68 */    0,
      /* 69 */    0,
      /* 6A */    0,
      /* 6B */    0,
      /* 6C */    0,
      /* 6D */    0,
      /* 6E */    0,
      /* 6F */    0,
      /* 70 */    0,
      /* 71 */    0,
      /* 72 */    0,
      /* 73 */    0,
      /* 74 */    0,
      /* 75 */    0,
      /* 76 */    0,
      /* 77 */    0,
      /* 78 */    0,
      /* 79 */    0,
      /* 7A */    0,
      /* 7B */    0,
      /* 7C */    0,
      /* 7D */    0,
      /* 7E */    0,
      /* 7F */    0,
      /* 80 */    0,
      /* 81 */    0,
      /* 82 */    0,
      /* 83 */    0,
      /* 84 */    0,
      /* 85 */    0,
      /* 86 */    0,
      /* 87 */    0,
      /* 88 */    0,
      /* 89 */    0,
      /* 8A */    0,
      /* 8B */    0,
      /* 8C */    0,
      /* 8D */    0,
      /* 8E */    0,
      /* 8F */    0,
      /* 90 */    0,
      /* 91 */    0,
      /* 92 */    0,
      /* 93 */    0,
      /* 94 */    0,
      /* 95 */    0,
      /* 96 */    0,
      /* 97 */    0,
      /* 98 */    0,
      /* 99 */    0,
      /* 9A */    0,
      /* 9B */    0,
      /* 9C */    0,
      /* 9D */    0,
      /* 9E */    0,
      /* 9F */    0,
      /* A0 */    0,
      /* A1 */    0,
      /* A2 */    0,
      /* A3 */    0,
      /* A4 */    0,
      /* A5 */    0,
      /* A6 */    0,
      /* A7 */    0,
      /* A8 */    0,
      /* A9 */    0,
      /* AA */    0,
      /* AB */    0,
      /* AC */    0,
      /* AD */    0,
      /* AE */    0,
      /* AF */    0,
      /* B0 */    0,
      /* B1 */    0,
      /* B2 */    0,
      /* B3 */    0,
      /* B4 */    0,
      /* B5 */    0,
      /* B6 */    0,
      /* B7 */    0,
      /* B8 */    0,
      /* B9 */    0,
      /* BA */    0,
      /* BB */    0,
      /* BC */    0,
      /* BD */    0,
      /* BE */    0,
      /* BF */    0,
      /* C0 */    0,
      /* C1 */    0,
      /* C2 */    0,
      /* C3 */    0,
      /* C4 */    0,
      /* C5 */    0,
      /* C6 */    0,
      /* C7 */    0,
      /* C8 */    0,
      /* C9 */    0,
      /* CA */    0,
      /* CB */    0,
      /* CC */    0,
      /* CD */    0,
      /* CE */    0,
      /* CF */    0,
      /* D0 */    0,
      /* D1 */    0,
      /* D2 */    0,
      /* D3 */    0,
      /* D4 */    0,
      /* D5 */    0,
      /* D6 */    0,
      /* D7 */    0,
      /* D8 */    0,
      /* D9 */    0,
      /* DA */    0,
      /* DB */    0,
      /* DC */    0,
      /* DD */    0,
      /* DE */    0,
      /* DF */    0,
      /* E0 */    SDLK_LCTRL,
      /* E1 */    SDLK_LSHIFT,
      /* E2 */    SDLK_LALT,
      /* E3 */    0,
      /* E4 */    SDLK_RCTRL,
      /* E5 */    SDLK_RSHIFT,
      /* E6 */    SDLK_RALT,
      /* E7 */    0,
      /* E8 */    0,
      /* E9 */    0,
      /* EA */    0,
      /* EB */    0,
      /* EC */    0,
      /* ED */    0,
      /* EE */    0,
      /* EF */    0,
      /* F0 */    0,
      /* F1 */    0,
      /* F2 */    0,
      /* F3 */    0,
      /* F4 */    0,
      /* F5 */    0,
      /* F6 */    0,
      /* F7 */    0,
      /* F8 */    0,
      /* F9 */    0,
      /* FA */    0,
      /* FB */    0,
      /* FC */    0,
      /* FD */    0,
      /* FE */    0,
      /* FF */    0
};

const int Ps2Input::_keyCodes[16] = {
      49,    // '1' - Select
      0,     //     - L3
      0,     //     - R3
      286, // F5  - Start
      0,     //         - Up
      0,     //         - Right
      0,     //         - Down
      0,     //         - Left
      0,     //         - L2
      0,     //         - R2
      0,     //         - L1
      0,     //         - R1
      27,    // Esc - Triangle
      0,     //         - Circle
      0,     //         - Cross
      0,     //         - Square
};

const uint16 Ps2Input::_asciiCodes[16] = {
      49,    // '1' - Select
      0,     //     - L3
      0,     //     - R3
      319, // F5  - Start
      0,     //         - Up
      0,     //         - Right
      0,     //         - Down
      0,     //         - Left
      0,     //         - L2
      0,     //         - R2
      0,     //         - L1
      0,     //         - R1
      27,    // Esc - Triangle
      0,     //         - Circle
      0,     //         - Cross
      0,     //         - Square
};


Generated by  Doxygen 1.6.0   Back to index