diff --git a/stepmania/src/arch/InputHandler/InputHandler_Linux_Joystick.cpp b/stepmania/src/arch/InputHandler/InputHandler_Linux_Joystick.cpp new file mode 100644 index 0000000000..6c02f036a5 --- /dev/null +++ b/stepmania/src/arch/InputHandler/InputHandler_Linux_Joystick.cpp @@ -0,0 +1,120 @@ +#include "global.h" +#include "InputHandler_Linux_Joystick.h" +#include "RageLog.h" +#include "RageUtil.h" +#include "InputFilter.h" + +#include +#include +#include + +#include +#include + +static const char *Paths[InputHandler_Linux_Joystick::NUM_JOYSTICKS] = +{ + "/dev/js0", + "/dev/js1", +}; + +InputHandler_Linux_Joystick::InputHandler_Linux_Joystick() +{ + for(int i = 0; i < NUM_JOYSTICKS; ++i) + fds[i] = -1; + + for(int i = 0; i < NUM_JOYSTICKS; ++i) + { + fds[i] = open(Paths[i], O_RDONLY); + + if(fds[i] != -1) + LOG->Info("Opened %s", Paths[i]); + } +} + +InputHandler_Linux_Joystick::~InputHandler_Linux_Joystick() +{ + for(int i = 0; i < NUM_JOYSTICKS; ++i) + if(fds[i] != -1) close(fds[i]); +} + +void InputHandler_Linux_Joystick::Update(float fDeltaTime) +{ + while(1) + { + fd_set fdset; + FD_ZERO(&fdset); + int max_fd = -1; + + for(int i = 0; i < NUM_JOYSTICKS; ++i) + { + if (fds[i] < 0) + continue; + + FD_SET(fds[i], &fdset); + max_fd = max(max_fd, fds[i]); + } + + if(max_fd == -1) + return; + + struct timeval zero = {0,0}; + if ( select(max_fd+1, &fdset, NULL, NULL, &zero) <= 0 ) + return; + + for(int i = 0; i < NUM_JOYSTICKS; ++i) + { + if(!FD_ISSET(fds[i], &fdset)) + continue; + + js_event event; + int ret = read(fds[i], &event, sizeof(event)); + if(ret != sizeof(event)) + { + LOG->Warn("Unexpected packet (size %i != %i) from joystick %i; disabled", ret, sizeof(event), i); + close(fds[i]); + fds[i] = -1; + continue; + } + + InputDevice id = InputDevice(DEVICE_JOY1 + i); + + event.type &= ~JS_EVENT_INIT; + switch (event.type) { + case JS_EVENT_BUTTON: { + INPUTFILTER->ButtonPressed(DeviceInput(id, JOY_1 + event.number), event.value); + break; + } + + case JS_EVENT_AXIS: { + JoystickButton neg = (JoystickButton)(JOY_LEFT+2*event.number); + JoystickButton pos = (JoystickButton)(JOY_RIGHT+2*event.number); + INPUTFILTER->ButtonPressed(DeviceInput(id, neg), event.value < -16000); + INPUTFILTER->ButtonPressed(DeviceInput(id, pos), event.value > +16000); + break; + } + + default: + LOG->Warn("Unexpected packet (type %i) from joystick %i; disabled", event.type, i); + close(fds[i]); + fds[i] = -1; + continue; + } + + } + + } +} + +void InputHandler_Linux_Joystick::GetDevicesAndDescriptions(vector& vDevicesOut, vector& vDescriptionsOut) +{ + for(int i = 0; i < NUM_JOYSTICKS; ++i) + { + if (fds[i] < 0) + continue; + + vDevicesOut.push_back( InputDevice(DEVICE_JOY1+i) ); + vDescriptionsOut.push_back( ssprintf("Joystick %i", i) ); + } +} + + diff --git a/stepmania/src/arch/InputHandler/InputHandler_Linux_Joystick.h b/stepmania/src/arch/InputHandler/InputHandler_Linux_Joystick.h new file mode 100644 index 0000000000..a20ea86b01 --- /dev/null +++ b/stepmania/src/arch/InputHandler/InputHandler_Linux_Joystick.h @@ -0,0 +1,26 @@ +#ifndef INPUT_HANDLER_LINUX_JOYSTICK_H +#define INPUT_HANDLER_LINUX_JOYSTICK_H 1 + +#include "InputHandler.h" + + +class InputHandler_Linux_Joystick: public InputHandler +{ +public: + enum { NUM_JOYSTICKS = 2 }; + void Update(float fDeltaTime); + InputHandler_Linux_Joystick(); + ~InputHandler_Linux_Joystick(); + void GetDevicesAndDescriptions(vector& vDevicesOut, vector& vDescriptionsOut); + +private: + int fds[NUM_JOYSTICKS]; +}; + +#endif +/* +----------------------------------------------------------------------------- + Copyright (c) 2003 by the person(s) listed below. All rights reserved. + Glenn Maynard +----------------------------------------------------------------------------- +*/ diff --git a/stepmania/src/arch/InputHandler/InputHandler_Linux_tty.cpp b/stepmania/src/arch/InputHandler/InputHandler_Linux_tty.cpp new file mode 100644 index 0000000000..3eb18ffc9c --- /dev/null +++ b/stepmania/src/arch/InputHandler/InputHandler_Linux_tty.cpp @@ -0,0 +1,196 @@ +#include "global.h" + +/* This handler is used for odd cases where we don't use SDL for input. */ + +#include "InputHandler_Linux_tty.h" +#include "InputHandler_Linux_tty_keys.h" +#include "InputFilter.h" + +#include "RageUtil.h" +#include "RageLog.h" +#include "RageException.h" + +#include "archutils/Unix/SignalHandler.h" + +#include "SDL_utils.h" + +#include + +#include +#include + +#include +#include +#include + + +/* Map from keys (ignoring shifts) to SDLK values. */ +static int keys[NR_KEYS]; +static termios saved_kbd_termios; +static int saved_kbd_mode; + +/* This is normally a singleton. Keep track of it, so we can access it + * from our signal handler. */ +static InputHandler_Linux_tty *handler = NULL; + +void InputHandler_Linux_tty::OnCrash(int signo) +{ + /* Make sure we delete the input handler if we crash, so we don't leave + * the terminal in raw mode. */ + delete handler; + handler = NULL; +} + + +InputHandler_Linux_tty::InputHandler_Linux_tty() +{ + fd = open("/dev/tty", O_RDWR); + if(fd == -1) + RageException::Throw("open(\"/dev/tty\"): %s", strerror(errno)); + + if (tcgetattr(fd, &saved_kbd_termios) == -1) + RageException::Throw("tcgetattr(%i) failed: %s", fd, strerror(errno)); + termios keyboard_termios = saved_kbd_termios; + keyboard_termios.c_lflag &= ~(ICANON | ECHO | ISIG); + keyboard_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); + keyboard_termios.c_cc[VMIN] = 0; + keyboard_termios.c_cc[VTIME] = 0; + if (tcsetattr(fd, TCSAFLUSH, &keyboard_termios) == -1) + RageException::Throw("tcsetattr(%i, TCSAFLUSH) failed: %s", fd, strerror(errno)); + + if (ioctl(fd, KDGKBMODE, &saved_kbd_mode) == -1) + RageException::Throw("ioctl(%i, KDGKBMODE) failed: %s", fd, strerror(errno)); + if (ioctl(fd, KDSKBMODE, K_MEDIUMRAW) == -1) + RageException::Throw("ioctl(%i, KDSKBMODE, K_MEDIUMRAW) failed: %s", fd, strerror(errno)); + + if (ioctl(fd, KDSETMODE, KD_GRAPHICS) == -1 ) + RageException::Throw("ioctl(%i, KDSETMODE, KD_GRAPHICS) failed: %s", fd, strerror(errno)); + + memset(keys, 0, sizeof(keys)); + + for (int i = 0; i < NR_KEYS; ++i) + { + switch(i) + { + case SCANCODE_PRINTSCREEN: keys[i] = SDLK_PRINT; continue; + case SCANCODE_BREAK: keys[i] = SDLK_BREAK; continue; + case SCANCODE_BREAK_ALTERNATIVE: keys[i] = SDLK_PAUSE; continue; + case SCANCODE_LEFTSHIFT: keys[i] = SDLK_LSHIFT; continue; + case SCANCODE_RIGHTSHIFT: keys[i] = SDLK_RSHIFT; continue; + case SCANCODE_LEFTCONTROL: keys[i] = SDLK_LCTRL; continue; + case SCANCODE_RIGHTCONTROL: keys[i] = SDLK_RCTRL; continue; + case SCANCODE_RIGHTWIN: keys[i] = SDLK_RSUPER; continue; + case SCANCODE_LEFTWIN: keys[i] = SDLK_LSUPER; continue; + case 127: keys[i] = SDLK_MENU; continue; + } + + kbentry entry; + + entry.kb_table = 0; + entry.kb_index = i; + if (ioctl(fd, KDGKBENT, &entry)) + continue; /* error */ + + const int kern_map = entry.kb_value; + + switch(kern_map) + { + case K_ENTER: keys[i] = SDLK_RETURN; break; + case K_F1: keys[i] = SDLK_F1; break; + case K_F2: keys[i] = SDLK_F2; break; + case K_F3: keys[i] = SDLK_F3; break; + case K_F4: keys[i] = SDLK_F4; break; + case K_F5: keys[i] = SDLK_F5; break; + case K_F6: keys[i] = SDLK_F6; break; + case K_F7: keys[i] = SDLK_F7; break; + case K_F8: keys[i] = SDLK_F8; break; + case K_F9: keys[i] = SDLK_F9; break; + case K_F10: keys[i] = SDLK_F10; break; + case K_F11: keys[i] = SDLK_F11; break; + case K_F12: keys[i] = SDLK_F12; break; + case K_UP: keys[i] = SDLK_UP; break; + case K_DOWN: keys[i] = SDLK_DOWN; break; + case K_LEFT: keys[i] = SDLK_LEFT; break; + case K_RIGHT: keys[i] = SDLK_RIGHT; break; + case K_P0: keys[i] = SDLK_KP0; break; + case K_P1: keys[i] = SDLK_KP1; break; + case K_P2: keys[i] = SDLK_KP2; break; + case K_P3: keys[i] = SDLK_KP3; break; + case K_P4: keys[i] = SDLK_KP4; break; + case K_P5: keys[i] = SDLK_KP5; break; + case K_P6: keys[i] = SDLK_KP6; break; + case K_P7: keys[i] = SDLK_KP7; break; + case K_P8: keys[i] = SDLK_KP8; break; + case K_P9: keys[i] = SDLK_KP9; break; + case K_PPLUS: keys[i] = SDLK_KP_PLUS; break; + case K_PMINUS: keys[i] = SDLK_KP_MINUS; break; + case K_PSTAR: keys[i] = SDLK_KP_MULTIPLY; break; + case K_PSLASH: keys[i] = SDLK_KP_DIVIDE; break; + case K_PENTER: keys[i] = SDLK_KP_ENTER; break; + case K_PDOT: keys[i] = SDLK_KP_PERIOD; break; + case K_ALT: keys[i] = SDLK_LALT; break; + case K_ALTGR: keys[i] = SDLK_RALT; break; + case K_INSERT: keys[i] = SDLK_INSERT; break; + case K_REMOVE: keys[i] = SDLK_DELETE; break; + case K_PGUP: keys[i] = SDLK_PAGEUP; break; + case K_PGDN: keys[i] = SDLK_PAGEDOWN; break; + case K_FIND: keys[i] = SDLK_HOME; break; + case K_SELECT: keys[i] = SDLK_END; break; + case K_NUM: keys[i] = SDLK_NUMLOCK; break; + case K_CAPS: keys[i] = SDLK_CAPSLOCK; break; + case K_F13: keys[i] = SDLK_PRINT; break; + case K_HOLD: keys[i] = SDLK_SCROLLOCK; break; + case K_PAUSE: keys[i] = SDLK_PAUSE; break; + case 127: keys[i] = SDLK_BACKSPACE; break; + default: keys[i] = KVAL(kern_map); + } + } + + handler = this; + SignalHandler::OnClose(OnCrash); +} + + +InputHandler_Linux_tty::~InputHandler_Linux_tty() +{ + LOG->Trace("~InputHandler_Linux_tty"); + ioctl(fd, KDSETMODE, KD_TEXT); + ioctl(fd, KDSKBMODE, saved_kbd_mode); + tcsetattr(fd, TCSAFLUSH, &saved_kbd_termios); + close(fd); + + handler = NULL; +} + +void InputHandler_Linux_tty::Update(float fDeltaTime) +{ + while (1) + { + fd_set fdset; + FD_ZERO(&fdset); + FD_SET(fd, &fdset); + + struct timeval zero = {0,0}; + if ( select(fd+1, &fdset, NULL, NULL, &zero) <= 0 ) + return; + + unsigned char keybuf[BUFSIZ]; + SDL_keysym keysym; + + int ret = read(fd, keybuf, BUFSIZ); + for ( int i=0; i < ret; ++i ) { + const int key = keybuf[i] & 0x7F; + const int butno = keys[key]; + const bool pressed = !(keybuf[i] & 0x80); + + INPUTFILTER->ButtonPressed(DeviceInput(DEVICE_KEYBOARD, butno), pressed); + } + } +} + +void InputHandler_Linux_tty::GetDevicesAndDescriptions(vector& vDevicesOut, vector& vDescriptionsOut) +{ + vDevicesOut.push_back( InputDevice(DEVICE_KEYBOARD) ); + vDescriptionsOut.push_back( "Keyboard" ); +} + diff --git a/stepmania/src/arch/InputHandler/InputHandler_Linux_tty.h b/stepmania/src/arch/InputHandler/InputHandler_Linux_tty.h new file mode 100644 index 0000000000..256757f79c --- /dev/null +++ b/stepmania/src/arch/InputHandler/InputHandler_Linux_tty.h @@ -0,0 +1,19 @@ +#ifndef INPUT_HANDLER_LINUX_TTY_H +#define INPUT_HANDLER_LINUX_TTY_H 1 + +#include "InputHandler.h" + +class InputHandler_Linux_tty: public InputHandler +{ + int fd; + static void OnCrash(int); + +public: + void Update(float fDeltaTime); + InputHandler_Linux_tty(); + ~InputHandler_Linux_tty(); + void GetDevicesAndDescriptions(vector& vDevicesOut, vector& vDescriptionsOut); +}; + +#endif + diff --git a/stepmania/src/arch/InputHandler/InputHandler_Linux_tty_keys.h b/stepmania/src/arch/InputHandler/InputHandler_Linux_tty_keys.h new file mode 100644 index 0000000000..bad8b1dfac --- /dev/null +++ b/stepmania/src/arch/InputHandler/InputHandler_Linux_tty_keys.h @@ -0,0 +1,142 @@ +/* Keyboard interface for svgalib. */ +/* Can be used independently. */ + +#ifndef VGAKEYBOARD_H +#define VGAKEYBOARD_H + +#define SCANCODE_ESCAPE 1 + +#define SCANCODE_1 2 +#define SCANCODE_2 3 +#define SCANCODE_3 4 +#define SCANCODE_4 5 +#define SCANCODE_5 6 +#define SCANCODE_6 7 +#define SCANCODE_7 8 +#define SCANCODE_8 9 +#define SCANCODE_9 10 +#define SCANCODE_0 11 + +#define SCANCODE_MINUS 12 +#define SCANCODE_EQUAL 13 + +#define SCANCODE_BACKSPACE 14 +#define SCANCODE_TAB 15 + +#define SCANCODE_Q 16 +#define SCANCODE_W 17 +#define SCANCODE_E 18 +#define SCANCODE_R 19 +#define SCANCODE_T 20 +#define SCANCODE_Y 21 +#define SCANCODE_U 22 +#define SCANCODE_I 23 +#define SCANCODE_O 24 +#define SCANCODE_P 25 +#define SCANCODE_BRACKET_LEFT 26 +#define SCANCODE_BRACKET_RIGHT 27 + +#define SCANCODE_ENTER 28 + +#define SCANCODE_LEFTCONTROL 29 + +#define SCANCODE_A 30 +#define SCANCODE_S 31 +#define SCANCODE_D 32 +#define SCANCODE_F 33 +#define SCANCODE_G 34 +#define SCANCODE_H 35 +#define SCANCODE_J 36 +#define SCANCODE_K 37 +#define SCANCODE_L 38 +#define SCANCODE_SEMICOLON 39 +#define SCANCODE_APOSTROPHE 40 +#define SCANCODE_GRAVE 41 + +#define SCANCODE_LEFTSHIFT 42 +#define SCANCODE_BACKSLASH 43 + +#define SCANCODE_Z 44 +#define SCANCODE_X 45 +#define SCANCODE_C 46 +#define SCANCODE_V 47 +#define SCANCODE_B 48 +#define SCANCODE_N 49 +#define SCANCODE_M 50 +#define SCANCODE_COMMA 51 +#define SCANCODE_PERIOD 52 +#define SCANCODE_SLASH 53 + +#define SCANCODE_RIGHTSHIFT 54 +#define SCANCODE_KEYPADMULTIPLY 55 + +#define SCANCODE_LEFTALT 56 +#define SCANCODE_SPACE 57 +#define SCANCODE_CAPSLOCK 58 + +#define SCANCODE_F1 59 +#define SCANCODE_F2 60 +#define SCANCODE_F3 61 +#define SCANCODE_F4 62 +#define SCANCODE_F5 63 +#define SCANCODE_F6 64 +#define SCANCODE_F7 65 +#define SCANCODE_F8 66 +#define SCANCODE_F9 67 +#define SCANCODE_F10 68 + +#define SCANCODE_NUMLOCK 69 +#define SCANCODE_SCROLLLOCK 70 + +#define SCANCODE_KEYPAD7 71 +#define SCANCODE_CURSORUPLEFT 71 +#define SCANCODE_KEYPAD8 72 +#define SCANCODE_CURSORUP 72 +#define SCANCODE_KEYPAD9 73 +#define SCANCODE_CURSORUPRIGHT 73 +#define SCANCODE_KEYPADMINUS 74 +#define SCANCODE_KEYPAD4 75 +#define SCANCODE_CURSORLEFT 75 +#define SCANCODE_KEYPAD5 76 +#define SCANCODE_KEYPAD6 77 +#define SCANCODE_CURSORRIGHT 77 +#define SCANCODE_KEYPADPLUS 78 +#define SCANCODE_KEYPAD1 79 +#define SCANCODE_CURSORDOWNLEFT 79 +#define SCANCODE_KEYPAD2 80 +#define SCANCODE_CURSORDOWN 80 +#define SCANCODE_KEYPAD3 81 +#define SCANCODE_CURSORDOWNRIGHT 81 +#define SCANCODE_KEYPAD0 82 +#define SCANCODE_KEYPADPERIOD 83 + +#define SCANCODE_LESS 86 + +#define SCANCODE_F11 87 +#define SCANCODE_F12 88 + +#define SCANCODE_KEYPADENTER 96 +#define SCANCODE_RIGHTCONTROL 97 +#define SCANCODE_CONTROL 97 +#define SCANCODE_KEYPADDIVIDE 98 +#define SCANCODE_PRINTSCREEN 99 +#define SCANCODE_RIGHTALT 100 +#define SCANCODE_BREAK 101 /* Beware: is 119 */ +#define SCANCODE_BREAK_ALTERNATIVE 119 /* on some keyboards! */ + +#define SCANCODE_HOME 102 +#define SCANCODE_CURSORBLOCKUP 103 /* Cursor key block */ +#define SCANCODE_PAGEUP 104 +#define SCANCODE_CURSORBLOCKLEFT 105 /* Cursor key block */ +#define SCANCODE_CURSORBLOCKRIGHT 106 /* Cursor key block */ +#define SCANCODE_END 107 +#define SCANCODE_CURSORBLOCKDOWN 108 /* Cursor key block */ +#define SCANCODE_PAGEDOWN 109 +#define SCANCODE_INSERT 110 +#define SCANCODE_REMOVE 111 + +#define SCANCODE_RIGHTWIN 126 +#define SCANCODE_LEFTWIN 125 + +#endif +