diff options
Diffstat (limited to 'backends/ps2/ps2input.cpp')
-rw-r--r-- | backends/ps2/ps2input.cpp | 546 |
1 files changed, 546 insertions, 0 deletions
diff --git a/backends/ps2/ps2input.cpp b/backends/ps2/ps2input.cpp new file mode 100644 index 0000000000..3feb1b0d50 --- /dev/null +++ b/backends/ps2/ps2input.cpp @@ -0,0 +1,546 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include <kernel.h> +#include <malloc.h> +#include <assert.h> +#include <libmouse.h> +#include <libkbd.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); + PS2KbdSetBlockingMode(PS2KBD_NONBLOCKING); + 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 +}; + |