Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
101 KB
Referenced Files
None
Subscribers
None
diff --git a/util/input/allegro/allegro-joystick.cpp b/util/input/allegro/allegro-joystick.cpp
new file mode 100644
index 00000000..09e95ba1
--- /dev/null
+++ b/util/input/allegro/allegro-joystick.cpp
@@ -0,0 +1,56 @@
+#ifdef USE_ALLEGRO
+
+#include <allegro.h>
+#include "allegro-joystick.h"
+
+void AllegroJoystick::poll(){
+ ::poll_joystick();
+}
+
+JoystickInput AllegroJoystick::readAll(){
+ JoystickInput input;
+ JOYSTICK_INFO * info = &joy[0];
+ switch(info->num_buttons > 4 ? 4 : info->num_buttons){
+ case 4: input.button4 = info->button[3].b;
+ case 3: input.button3 = info->button[2].b;
+ case 2: input.button2 = info->button[1].b;
+ case 1: input.button1 = info->button[0].b;
+ case 0: {
+ break;
+ }
+ }
+
+ for (int stick = 0; stick < info->num_sticks; stick++){
+ JOYSTICK_STICK_INFO * this_stick = &info->stick[stick];
+ if (this_stick->num_axis > 0){
+ int position = this_stick->axis[0].pos;
+ if (position < 0){
+ input.left = true;
+ } else if (position > 0){
+ input.right = true;
+ }
+ }
+ if (this_stick->num_axis > 1){
+ int position = this_stick->axis[1].pos;
+ if (position < 0){
+ input.up = true;
+ } else if (position > 0){
+ input.down = true;
+ }
+ }
+ }
+
+ return input;
+}
+
+AllegroJoystick::~AllegroJoystick(){
+}
+
+AllegroJoystick::AllegroJoystick(){
+}
+
+int AllegroJoystick::getDeviceId() const {
+ return 0;
+}
+
+#endif
diff --git a/util/input/allegro/allegro-joystick.h b/util/input/allegro/allegro-joystick.h
new file mode 100644
index 00000000..bbecff48
--- /dev/null
+++ b/util/input/allegro/allegro-joystick.h
@@ -0,0 +1,19 @@
+#ifndef _paintown_allegro_joystick_h
+#define _paintown_allegro_joystick_h
+
+#include "../joystick.h"
+
+class AllegroJoystick: public Joystick {
+public:
+ virtual void poll();
+ virtual JoystickInput readAll();
+ virtual int getDeviceId() const;
+
+ virtual ~AllegroJoystick();
+
+ friend class Joystick;
+protected:
+ AllegroJoystick();
+};
+
+#endif
diff --git a/util/input/allegro/keyboard.cpp b/util/input/allegro/keyboard.cpp
new file mode 100644
index 00000000..5ac4dbe3
--- /dev/null
+++ b/util/input/allegro/keyboard.cpp
@@ -0,0 +1,317 @@
+#include <allegro.h>
+#ifdef WINDOWS
+#include <winalleg.h>
+#endif
+#include "../keyboard.h"
+#include "util/thread.h"
+#include "util/funcs.h"
+#include "globals.h"
+#include <iostream>
+#include <vector>
+#include <map>
+
+using namespace std;
+
+const int Keyboard::Key_A = ::KEY_A;
+const int Keyboard::Key_B = ::KEY_B;
+const int Keyboard::Key_C = ::KEY_C;
+const int Keyboard::Key_D = ::KEY_D;
+const int Keyboard::Key_E = ::KEY_E;
+const int Keyboard::Key_F = ::KEY_F;
+const int Keyboard::Key_G = ::KEY_G;
+const int Keyboard::Key_H = ::KEY_H;
+const int Keyboard::Key_I = ::KEY_I;
+const int Keyboard::Key_J = ::KEY_J;
+const int Keyboard::Key_K = ::KEY_K;
+const int Keyboard::Key_L = ::KEY_L;
+const int Keyboard::Key_M = ::KEY_M;
+const int Keyboard::Key_N = ::KEY_N;
+const int Keyboard::Key_O = ::KEY_O;
+const int Keyboard::Key_P = ::KEY_P;
+const int Keyboard::Key_Q = ::KEY_Q;
+const int Keyboard::Key_R = ::KEY_R;
+const int Keyboard::Key_S = ::KEY_S;
+const int Keyboard::Key_T = ::KEY_T;
+const int Keyboard::Key_U = ::KEY_U;
+const int Keyboard::Key_V = ::KEY_V;
+const int Keyboard::Key_W = ::KEY_W;
+const int Keyboard::Key_X = ::KEY_X;
+const int Keyboard::Key_Y = ::KEY_Y;
+const int Keyboard::Key_Z = ::KEY_Z;
+const int Keyboard::Key_0 = ::KEY_0;
+const int Keyboard::Key_1 = ::KEY_1;
+const int Keyboard::Key_2 = ::KEY_2;
+const int Keyboard::Key_3 = ::KEY_3;
+const int Keyboard::Key_4 = ::KEY_4;
+const int Keyboard::Key_5 = ::KEY_5;
+const int Keyboard::Key_6 = ::KEY_6;
+const int Keyboard::Key_7 = ::KEY_7;
+const int Keyboard::Key_8 = ::KEY_8;
+const int Keyboard::Key_9 = ::KEY_9;
+const int Keyboard::Key_0_PAD = ::KEY_0_PAD;
+const int Keyboard::Key_1_PAD = ::KEY_1_PAD;
+const int Keyboard::Key_2_PAD = ::KEY_2_PAD;
+const int Keyboard::Key_3_PAD = ::KEY_3_PAD;
+const int Keyboard::Key_4_PAD = ::KEY_4_PAD;
+const int Keyboard::Key_5_PAD = ::KEY_5_PAD;
+const int Keyboard::Key_6_PAD = ::KEY_6_PAD;
+const int Keyboard::Key_7_PAD = ::KEY_7_PAD;
+const int Keyboard::Key_8_PAD = ::KEY_8_PAD;
+const int Keyboard::Key_9_PAD = ::KEY_9_PAD;
+const int Keyboard::Key_F1 = ::KEY_F1;
+const int Keyboard::Key_F2 = ::KEY_F2;
+const int Keyboard::Key_F3 = ::KEY_F3;
+const int Keyboard::Key_F4 = ::KEY_F4;
+const int Keyboard::Key_F5 = ::KEY_F5;
+const int Keyboard::Key_F6 = ::KEY_F6;
+const int Keyboard::Key_F7 = ::KEY_F7;
+const int Keyboard::Key_F8 = ::KEY_F8;
+const int Keyboard::Key_F9 = ::KEY_F9;
+const int Keyboard::Key_F10 = ::KEY_F10;
+const int Keyboard::Key_F11 = ::KEY_F11;
+const int Keyboard::Key_F12 = ::KEY_F12;
+const int Keyboard::Key_ESC = ::KEY_ESC;
+const int Keyboard::Key_TILDE = ::KEY_TILDE;
+const int Keyboard::Key_MINUS = ::KEY_MINUS;
+const int Keyboard::Key_EQUALS = ::KEY_EQUALS;
+const int Keyboard::Key_BACKSPACE = ::KEY_BACKSPACE;
+const int Keyboard::Key_TAB = ::KEY_TAB;
+const int Keyboard::Key_OPENBRACE = ::KEY_OPENBRACE;
+const int Keyboard::Key_CLOSEBRACE = ::KEY_CLOSEBRACE;
+const int Keyboard::Key_ENTER = ::KEY_ENTER;
+const int Keyboard::Key_COLON = ::KEY_COLON;
+const int Keyboard::Key_QUOTE = ::KEY_QUOTE;
+const int Keyboard::Key_BACKSLASH = ::KEY_BACKSLASH;
+const int Keyboard::Key_BACKSLASH2 = ::KEY_BACKSLASH2;
+const int Keyboard::Key_COMMA = ::KEY_COMMA;
+const int Keyboard::Key_STOP = ::KEY_STOP;
+const int Keyboard::Key_SLASH = ::KEY_SLASH;
+const int Keyboard::Key_SPACE = ::KEY_SPACE;
+const int Keyboard::Key_INSERT = ::KEY_INSERT;
+const int Keyboard::Key_DEL = ::KEY_DEL;
+const int Keyboard::Key_HOME = ::KEY_HOME;
+const int Keyboard::Key_END = ::KEY_END;
+const int Keyboard::Key_PGUP = ::KEY_PGUP;
+const int Keyboard::Key_PGDN = ::KEY_PGDN;
+const int Keyboard::Key_LEFT = ::KEY_LEFT;
+const int Keyboard::Key_RIGHT = ::KEY_RIGHT;
+const int Keyboard::Key_UP = ::KEY_UP;
+const int Keyboard::Key_DOWN = ::KEY_DOWN;
+const int Keyboard::Key_SLASH_PAD = ::KEY_SLASH_PAD;
+const int Keyboard::Key_ASTERISK = ::KEY_ASTERISK;
+const int Keyboard::Key_MINUS_PAD = ::KEY_MINUS_PAD;
+const int Keyboard::Key_PLUS_PAD = ::KEY_PLUS_PAD;
+const int Keyboard::Key_DEL_PAD = ::KEY_DEL_PAD;
+const int Keyboard::Key_ENTER_PAD = ::KEY_ENTER_PAD;
+const int Keyboard::Key_PRTSCR = ::KEY_PRTSCR;
+const int Keyboard::Key_PAUSE = ::KEY_PAUSE;
+const int Keyboard::Key_ABNT_C1 = ::KEY_ABNT_C1;
+const int Keyboard::Key_YEN = ::KEY_YEN;
+const int Keyboard::Key_KANA = ::KEY_KANA;
+const int Keyboard::Key_CONVERT = ::KEY_CONVERT;
+const int Keyboard::Key_NOCONVERT = ::KEY_NOCONVERT;
+const int Keyboard::Key_AT = ::KEY_AT;
+const int Keyboard::Key_CIRCUMFLEX = ::KEY_CIRCUMFLEX;
+const int Keyboard::Key_COLON2 = ::KEY_COLON2;
+const int Keyboard::Key_KANJI = ::KEY_KANJI;
+const int Keyboard::Key_EQUALS_PAD = ::KEY_EQUALS_PAD;
+const int Keyboard::Key_BACKQUOTE = ::KEY_BACKQUOTE;
+const int Keyboard::Key_SEMICOLON = ::KEY_SEMICOLON;
+const int Keyboard::Key_COMMAND = ::KEY_COMMAND;
+
+/*
+const int Keyboard::Key_UNKNOWN1 = ::KEY_UNKNOWN1;
+const int Keyboard::Key_UNKNOWN2 = ::KEY_UNKNOWN2;
+const int Keyboard::Key_UNKNOWN3 = ::KEY_UNKNOWN3;
+const int Keyboard::Key_UNKNOWN4 = ::KEY_UNKNOWN4;
+const int Keyboard::Key_UNKNOWN5 = ::KEY_UNKNOWN5;
+const int Keyboard::Key_UNKNOWN6 = ::KEY_UNKNOWN6;
+const int Keyboard::Key_UNKNOWN7 = ::KEY_UNKNOWN7;
+const int Keyboard::Key_UNKNOWN8 = ::KEY_UNKNOWN8;
+*/
+
+const int Keyboard::Key_MODIFIERS = ::KEY_MODIFIERS;
+const int Keyboard::Key_LSHIFT = ::KEY_LSHIFT;
+const int Keyboard::Key_RSHIFT = ::KEY_RSHIFT;
+const int Keyboard::Key_LCONTROL = ::KEY_LCONTROL;
+const int Keyboard::Key_RCONTROL = ::KEY_RCONTROL;
+const int Keyboard::Key_ALT = ::KEY_ALT;
+const int Keyboard::Key_ALTGR = ::KEY_ALTGR;
+const int Keyboard::Key_LWIN = ::KEY_LWIN;
+const int Keyboard::Key_RWIN = ::KEY_RWIN;
+const int Keyboard::Key_MENU = ::KEY_MENU;
+const int Keyboard::Key_SCRLOCK = ::KEY_SCRLOCK;
+const int Keyboard::Key_NUMLOCK = ::KEY_NUMLOCK;
+const int Keyboard::Key_CAPSLOCK = ::KEY_CAPSLOCK;
+
+static Util::Thread::Lock keyboardData;
+
+static vector<Keyboard::KeyData> stolenKeys;
+static int steal_keys(int unicode, int * scancode){
+ // Global::debug(0) << "Steal key " << unicode << " " << *scancode << endl;
+ Util::Thread::acquireLock(&keyboardData);
+ stolenKeys.push_back(Keyboard::KeyData(*scancode, unicode, true));
+ Util::Thread::releaseLock(&keyboardData);
+ return unicode;
+}
+
+static map<int, bool> stolenPresses;
+static void steal_scancode(int scancode){
+ Util::Thread::acquireLock(&keyboardData);
+ if (scancode & 0x80){
+ stolenPresses[scancode & 0x7f] = false;
+ } else {
+ stolenPresses[scancode & 0x7f] = true;
+ }
+ Util::Thread::releaseLock(&keyboardData);
+}
+
+Keyboard::Keyboard():
+enableBuffer(false){
+ /*
+ for ( int q = 0; q < KEY_MAX; q++ ){
+ my_keys[ q ] = 0;
+ }
+ */
+ setAllDelay( 0 );
+
+ Util::Thread::initializeLock(&keyboardData);
+ ::keyboard_ucallback = steal_keys;
+ ::keyboard_lowlevel_callback = steal_scancode;
+}
+
+/* KEY_MAX is defined in allegro at
+ * allegro/include/allegro/keyboard.h
+ */
+void Keyboard::poll(){
+ buffer.clear();
+
+ // keyState.clear();
+ Util::Thread::acquireLock(&keyboardData);
+ for (vector<KeyData>::iterator it = stolenKeys.begin(); it != stolenKeys.end(); it++){
+ const KeyData & data = *it;
+ keyState[data.key] = data;
+ }
+ stolenKeys.clear();
+
+ for (map<int, bool>::iterator it = stolenPresses.begin(); it != stolenPresses.end(); it++){
+ int key = it->first;
+ bool pressed = it->second;
+ keyState[key].enabled = pressed;
+
+ if (pressed){
+ press(key, keyState[key].unicode);
+ } else {
+ release(key);
+ }
+ }
+ stolenPresses.clear();
+ Util::Thread::releaseLock(&keyboardData);
+
+ /*
+ ::poll_keyboard();
+ keyState.clear();
+ while (::keypressed()){
+ int unicode;
+ int key = ::ureadkey(&unicode);
+ keyState[key] = KeyData(key, unicode, true);
+ }
+ */
+
+#if 0
+ for ( int q = 0; q < KEY_MAX; q++ ){
+ // my_keys[ q ] = key[ q ];
+ if ( key[ q ] ){
+ /* my_keys[ q ] becomes negative so that the key
+ * can be pressed the first time without having
+ * to wait for a delay
+ */
+ if ( my_keys[ q ] <= 0 ){
+ my_keys[ q ] -= 1;
+ } else {
+ my_keys[ q ] += 1;
+ }
+ // printf( "Key %d = %d\n", q, my_keys[ q ] );
+ } else {
+ my_keys[ q ] = 0;
+ }
+ }
+#endif
+}
+
+#if 0
+std::vector<Keyboard::KeyData> Keyboard::readData(){
+ std::vector<Keyboard::KeyData> out;
+ /* TODO */
+ return out;
+}
+
+std::vector<Keyboard::unicode_t> Keyboard::readText(){
+ std::vector<Keyboard::unicode_t> out;
+ /* TODO */
+ return out;
+}
+#endif
+
+void Keyboard::readKeys( vector< int > & all_keys ){
+
+ for (std::map<KeyType, KeyData>::iterator it = keyState.begin(); it != keyState.end(); it++){
+ KeyType key = it->first;
+ const KeyData & data = it->second;
+ if (data.enabled){
+ all_keys.push_back(key);
+ }
+ }
+
+/*
+ for ( map<int,int>::const_iterator it = my_keys.begin(); it != my_keys.end(); it++ ){
+ const int & key = it->first;
+ const int & delay = it->second;
+ if ( delay != 0 ){
+ Global::debug( 6 ) << "Key " << key << " delay " << delay << " key_delay " << key_delay[ key ] << endl;
+ }
+ if ( delay < 0 ){
+ all_keys.push_back( key );
+ my_keys[ key ] = 1;
+ } else if ( delay > key_delay[ key ] ){
+ all_keys.push_back( key );
+ my_keys[ key ] = 1;
+ }
+ }
+ */
+}
+
+/*
+int Keyboard::readKey(){
+ return ::readkey() >> 8;
+}
+*/
+
+void Keyboard::wait(){
+ clear();
+ poll();
+ while ( keypressed() ){
+ poll();
+ Util::rest( 1 );
+ }
+}
+
+bool Keyboard::keypressed(){
+ return ::keypressed();
+ /*
+ for ( map<int,int>::const_iterator it = my_keys.begin(); it != my_keys.end(); it++ ){
+ const int & n = (*it).second;
+ if ( n < 0 || n > key_delay[ it->first ] ){
+ return true;
+ }
+ }
+ return false;
+ */
+}
+
+void Keyboard::clear(){
+ ::clear_keybuf();
+ buffer.clear();
+ keyState.clear();
+ // my_keys.clear();
+}
diff --git a/util/input/input-manager.cpp b/util/input/input-manager.cpp
new file mode 100644
index 00000000..031b3bc9
--- /dev/null
+++ b/util/input/input-manager.cpp
@@ -0,0 +1,236 @@
+#include "input-manager.h"
+#include "configuration.h"
+/* FIXME: break this dependancy */
+#include "paintown-engine/object/object.h"
+#include "joystick.h"
+#include "util/events.h"
+#include "globals.h"
+#include "util/debug.h"
+#include <stdlib.h>
+#include <vector>
+
+using namespace std;
+
+InputManager * InputManager::manager = 0;
+
+InputManager::InputManager():
+capture(0),
+joystick(NULL){
+ manager = this;
+ if (Configuration::isJoystickEnabled()){
+ joystick = Joystick::create();
+ }
+}
+
+InputManager::~InputManager(){
+ delete joystick;
+}
+
+bool InputManager::anyInput(){
+ if (manager == 0){
+ Global::debug(0) << "*BUG* Input manager not set up" << endl;
+ exit(0);
+ }
+
+ return manager->_anyInput();
+}
+
+bool InputManager::_anyInput(){
+ if (keyboard.keypressed()){
+ return true;
+ }
+
+ if (joystick){
+ JoystickInput all_joystick = joystick->readAll();
+ if (all_joystick.pressed()){
+ return true;
+ }
+ }
+
+ return false;
+}
+
+vector<Input::PaintownInput> InputManager::getInput(const Configuration & configuration, const int facing){
+ if (manager == 0){
+ Global::debug(0) << "*BUG* Input manager not set up" << endl;
+ exit(0);
+ }
+
+ return manager->_getInput(configuration, facing);
+}
+
+/*
+void InputManager::enableBufferInput(){
+ manager->bufferKeys = true;
+}
+
+void InputManager::disableBufferInput(){
+ manager->bufferKeys = false;
+}
+*/
+
+void InputManager::waitForClear(){
+ manager->keyboard.clear();
+ while (anyInput()){
+ poll();
+ Util::rest(1);
+ }
+}
+
+void InputManager::waitForKeys(int key1, int key2){
+ InputMap<int> wait;
+ wait.set(key1, 0, false, 1);
+ wait.set(key2, 0, false, 1);
+ InputManager::waitForRelease(wait, 1);
+ InputManager::waitForPress(wait, 1);
+ InputManager::waitForRelease(wait, 1);
+}
+
+void InputManager::waitForKeys(int key){
+ InputMap<int> wait;
+ wait.set(key, 0, false, 1);
+ InputManager::waitForRelease(wait, 1);
+ InputManager::waitForPress(wait, 1);
+ InputManager::waitForRelease(wait, 1);
+}
+
+/* these mappings should agree with configuration.cpp:defaultJoystick1Keys,
+ * but otherwise they are completely arbitrary
+ */
+static Input::PaintownInput convertJoystickKey(const Joystick::Key key, const int facing){
+ switch (key){
+ case Joystick::Up : return Input::Up;
+ case Joystick::Down : return Input::Down;
+ case Joystick::Left : {
+ if (facing == Paintown::Object::FACING_RIGHT){
+ return Input::Back;
+ } else {
+ return Input::Forward;
+ }
+ }
+ case Joystick::Right : {
+ if (facing == Paintown::Object::FACING_RIGHT){
+ return Input::Forward;
+ } else {
+ return Input::Back;
+ }
+ }
+ case Joystick::Button1 : return Input::Attack1;
+ case Joystick::Button2 : return Input::Attack2;
+ case Joystick::Button3 : return Input::Attack3;
+ case Joystick::Button4 : return Input::Jump;
+ default : return Input::Unknown;
+ }
+}
+
+static vector<Input::PaintownInput> convertJoystick(const Configuration & configuration, JoystickInput input, const int facing){
+ vector<Input::PaintownInput> all;
+
+ if (input.up){
+ all.push_back(convertJoystickKey(configuration.getJoystickUp(), facing));
+ }
+
+ if (input.right){
+ all.push_back(convertJoystickKey(configuration.getJoystickRight(), facing));
+ }
+
+ if (input.left){
+ all.push_back(convertJoystickKey(configuration.getJoystickLeft(), facing));
+ }
+
+ if (input.down){
+ all.push_back(convertJoystickKey(configuration.getJoystickDown(), facing));
+ }
+
+ if (input.button1){
+ all.push_back(convertJoystickKey(configuration.getJoystickAttack1(), facing));
+ }
+
+ if (input.button2){
+ all.push_back(convertJoystickKey(configuration.getJoystickAttack2(), facing));
+ }
+
+ if (input.button3){
+ all.push_back(convertJoystickKey(configuration.getJoystickAttack3(), facing));
+ }
+
+ if (input.button4){
+ all.push_back(convertJoystickKey(configuration.getJoystickJump(), facing));
+ }
+
+ return all;
+}
+
+void InputManager::poll(){
+ if (manager == 0){
+ Global::debug(0) << "*BUG* Input manager not set up" << endl;
+ exit(0);
+ }
+
+ return manager->_poll();
+}
+
+int InputManager::readKey(){
+ return manager->_readKey();
+}
+
+int InputManager::_readKey(){
+ std::vector<int> keys;
+ do{
+ keyboard.readKeys(keys);
+ if (keys.size() == 0){
+ Util::rest(1);
+ poll();
+ }
+ } while (keys.size() == 0);
+ return keys.front();
+}
+
+void InputManager::_poll(){
+ /* FIXME: not sure if its a good idea to put the event manager here */
+ Util::EventManager eventManager;
+ /*
+ if (bufferKeys){
+ eventManager.enableKeyBuffer();
+ }
+ */
+ eventManager.run(keyboard, joystick);
+
+ // keyboard.poll();
+ /*
+ if (joystick != NULL){
+ joystick->poll();
+ }
+ */
+
+ // const vector<Util::EventManager::KeyType> & keys = eventManager.getBufferedKeys();
+ // bufferedKeys.insert(bufferedKeys.end(), keys.begin(), keys.end());
+}
+
+vector<Input::PaintownInput> InputManager::_getInput(const Configuration & configuration, const int facing){
+
+ InputMap<Input::PaintownInput> input;
+
+ enum Input::PaintownInput all[] = {Input::Forward, Input::Back, Input::Up, Input::Down, Input::Attack1, Input::Attack2, Input::Attack3, Input::Jump, Input::Grab};
+ for (unsigned int i = 0; i < sizeof(all) / sizeof(Input::PaintownInput); i++){
+ input.set(configuration.getKey(all[i], facing), 0, false, all[i]);
+ input.set(configuration.getJoystickKey(all[i], facing), 0, false, all[i]);
+ }
+
+ InputMap<Input::PaintownInput>::Output state = InputManager::getMap(input);
+ return InputMap<Input::PaintownInput>::getAllPressed(state);
+
+ /*
+ vector<int> all_keys;
+ keyboard.readKeys( all_keys );
+
+ vector<Input::PaintownInput> real_input = Input::convertKeyboard(configuration, facing, all_keys);
+
+ if (joystick != NULL){
+ vector<Input::PaintownInput> joystick_keys = convertJoystick(configuration, joystick->readAll(), facing);
+ real_input.insert(real_input.begin(), joystick_keys.begin(), joystick_keys.end());
+ }
+
+ return real_input;
+ */
+}
diff --git a/util/input/input-manager.h b/util/input/input-manager.h
new file mode 100644
index 00000000..97a32fb8
--- /dev/null
+++ b/util/input/input-manager.h
@@ -0,0 +1,285 @@
+#ifndef _paintown_input_manager
+#define _paintown_input_manager
+
+#include <vector>
+#include <algorithm>
+#include "input.h"
+#include "input-map.h"
+#include "util/funcs.h"
+#include "keyboard.h"
+#include "exceptions/exception.h"
+
+class Configuration;
+class Joystick;
+
+template <class Output>
+class InputHandler{
+public:
+ InputHandler(){
+ }
+
+ virtual ~InputHandler(){
+ }
+
+ virtual void press(const Output & out, Keyboard::unicode_t unicode) = 0;
+ virtual void release(const Output & out, Keyboard::unicode_t unicode) = 0;
+};
+
+/* handles keyboard/joystick/whatever input during the game */
+class InputManager{
+public:
+ /* main has one instance of this and thats it.
+ * should the janitor have the reference instead?
+ */
+ friend int paintown_main(int, char**);
+ friend int main(int, char **);
+
+ /* returns true if any input device is activated (keys pressed, joystick button */
+ static bool anyInput();
+
+ static std::vector<Input::PaintownInput> getInput(const Configuration & configuration, const int facing);
+ static void poll();
+ /*
+ static void enableBufferInput();
+ static void disableBufferInput();
+ */
+ static void waitForKeys(int key1, int key2);
+ static void waitForKeys(int key1);
+ static int readKey();
+ static void waitForClear();
+
+ /*
+ template <class X>
+ static void observeKeyboard(InputMap<X> & input){
+ manager->keyboard.addObserver(InputMap<X>::observeKey, &input);
+ }
+
+ template <class X>
+ static void unObserveKeyboard(InputMap<X> & input){
+ manager->keyboard.removeObserver(InputMap<X>::observeKey, &input);
+ }
+ */
+
+ static std::vector<Keyboard::unicode_t> readText(){
+ return manager->keyboard.readText();
+ }
+
+ template <typename X>
+ static std::vector<Keyboard::unicode_t> readText(InputMap<X> & input, typename InputMap<X>::Output & output){
+ return manager->_readText(input, output);
+ }
+
+ template <typename X>
+ static typename InputMap<X>::Output getMap(InputMap<X> & input){
+ if (manager){
+ return manager->_getMap(input);
+ }
+ /* just crash hard.. who cares */
+ throw Exception::Base(__FILE__, __LINE__);
+ /* make the compiler happy about returning something */
+ return *(typename InputMap<X>::Output*)1;
+ }
+
+ template <typename X>
+ static typename std::vector<typename InputMap<X>::InputEvent> getEvents(InputMap<X> & input){
+ return manager->_getEvents(input);
+ }
+
+ template <typename X>
+ static void handleEvents(InputMap<X> & input, InputHandler<X> & handler){
+ typename std::vector<typename InputMap<X>::InputEvent> events = getEvents(input);
+ for (typename std::vector<typename InputMap<X>::InputEvent>::iterator it = events.begin(); it != events.end(); it++){
+ const typename InputMap<X>::InputEvent & event = *it;
+ if (event.enabled){
+ handler.press(event.out, event.unicode);
+ } else {
+ handler.release(event.out, event.unicode);
+ }
+ }
+ }
+
+ template <typename X>
+ static bool pressed(InputMap<X> & input, X out){
+ if (manager){
+ return manager->_pressed(input, out);
+ }
+ return false;
+ }
+
+ /* wait for a key to be released
+ * really this waits for all inputs that would result in `out'
+ * being generated to stop.
+ */
+ template <typename X>
+ static void waitForRelease(InputMap<X> & input, X out){
+ while (InputManager::pressed(input, out)){
+ Util::rest(1);
+ InputManager::poll();
+ }
+ }
+
+ template <typename X>
+ static void waitForPress(InputMap<X> & input, X out){
+ while (!InputManager::pressed(input, out)){
+ Util::rest(1);
+ InputManager::poll();
+ }
+ }
+
+ template <typename X>
+ static void captureInput(InputMap<X> & input){
+ manager->_captureInput(input);
+ }
+
+ template <typename X>
+ static void releaseInput(InputMap<X> & input){
+ manager->_releaseInput(input);
+ }
+
+protected:
+ InputManager();
+ virtual ~InputManager();
+
+ virtual bool _anyInput();
+
+ virtual int _readKey();
+
+ virtual std::vector<Input::PaintownInput> _getInput(const Configuration & configuration, const int facing);
+
+ template <typename X>
+ void _captureInput(InputMap<X> & input){
+ capture = (void*) &input;
+ }
+
+ template <typename X>
+ void _releaseInput(InputMap<X> & input){
+ if (capture == (void*) &input){
+ capture = 0;
+ }
+ }
+
+ template <typename X>
+ std::vector<Keyboard::unicode_t> _readText(InputMap<X> & input, typename InputMap<X>::Output & output){
+ std::vector<Keyboard::unicode_t> text;
+ std::vector<Keyboard::KeyData> all = keyboard.readData();
+ for (std::vector<Keyboard::KeyData>::iterator it = all.begin(); it != all.end(); it++){
+ const Keyboard::KeyData & data = *it;
+ KeyState<X> * state = input.getState(data.key);
+ if (state != NULL && output[state->out]){
+ text.push_back(data.unicode);
+ }
+ }
+
+ return text;
+ }
+
+ void removeDuplicates(std::vector<int> & storage){
+ std::vector<int> output;
+ int last = -1;
+ for (std::vector<int>::iterator it = storage.begin(); it != storage.end(); it++){
+ if (*it != last){
+ output.push_back(*it);
+ last = *it;
+ }
+ }
+ storage = output;
+ }
+
+ template <typename X>
+ typename std::vector<typename InputMap<X>::InputEvent> _getEvents(InputMap<X> & input){
+ std::vector<typename InputMap<X>::InputEvent> events;
+ if (capture != NULL && capture != &input){
+ return events;
+ }
+
+ const std::vector<typename Keyboard::KeyData> & buffer = keyboard.getBufferedKeys();
+ for (std::vector<Keyboard::KeyData>::const_iterator it = buffer.begin(); it != buffer.end(); it++){
+ const Keyboard::KeyData & data = *it;
+ KeyState<X> * state = input.getState(data.key);
+ if (state != NULL){
+ events.push_back(typename InputMap<X>::InputEvent(state->out, data.unicode, data.enabled));
+ }
+ }
+
+ if (joystick){
+ const std::vector<typename Joystick::Event> & joystickEvents = joystick->getEvents();
+ for (std::vector<Joystick::Event>::const_iterator it = joystickEvents.begin(); it != joystickEvents.end(); it++){
+ Joystick::Event event = *it;
+ JoystickState<X> * state = input.getJoystickState(event);
+ if (state != NULL){
+ events.push_back(typename InputMap<X>::InputEvent(state->out, -1, true));
+ }
+ }
+ }
+
+ return events;
+ }
+
+ template <typename X>
+ typename InputMap<X>::Output _getMap(InputMap<X> & input){
+ typename InputMap<X>::Output output;
+
+ if (capture != 0 && capture != &input){
+ return output;
+ }
+
+ std::vector<int> all_keys;
+ keyboard.readKeys(all_keys);
+ keyboard.readBufferedKeys(all_keys);
+ // all_keys.insert(all_keys.end(), bufferedKeys.begin(), bufferedKeys.end());
+ // all_keys.insert(all_keys.end(), keyboard.currentKeys().begin(), keyboard.currentKeys.end());
+ std::sort(all_keys.begin(), all_keys.end());
+ removeDuplicates(all_keys);
+ // std::unique(all_keys.begin(), all_keys.end());
+ // bufferedKeys.clear();
+
+ input.read(all_keys, &output);
+
+ if (joystick != NULL){
+ JoystickInput all_joystick = joystick->readAll();
+ input.read(all_joystick, &output);
+ }
+
+ /* just bumps an internal counter */
+ input.update();
+
+ return output;
+ }
+
+ template <typename X>
+ bool _pressed(InputMap<X> & input, X result){
+
+ if (capture != 0 && capture != &input){
+ return false;
+ }
+
+ std::vector<int> all_keys;
+ keyboard.readKeys(all_keys);
+ // all_keys.insert(all_keys.end(), bufferedKeys.begin(), bufferedKeys.end());
+ std::sort(all_keys.begin(), all_keys.end());
+ removeDuplicates(all_keys);
+ // bufferedKeys.clear();
+ bool out = false;
+
+ out = input.pressed(all_keys, result);
+
+ if (joystick != NULL){
+ JoystickInput all_joystick = joystick->readAll();
+ out |= input.pressed(all_joystick, result);
+ }
+
+ return out;
+ }
+
+ virtual void _poll();
+
+private:
+ static InputManager * manager;
+ void * capture;
+ Joystick * joystick;
+ Keyboard keyboard;
+ // std::vector<int> bufferedKeys;
+ // bool bufferKeys;
+};
+
+#endif
diff --git a/util/input/input-map.h b/util/input/input-map.h
new file mode 100644
index 00000000..bd76d826
--- /dev/null
+++ b/util/input/input-map.h
@@ -0,0 +1,300 @@
+#ifndef _paintown_input_map_h
+#define _paintown_input_map_h
+
+#include <map>
+#include <vector>
+#include "joystick.h"
+#include "keyboard.h"
+#include "globals.h"
+#include <iostream>
+
+template <typename X>
+struct KeyState{
+ KeyState(unsigned int delay, bool block, X out, unsigned int last_read):
+ delay(delay),
+ block(block),
+ out(out),
+ pressed(false),
+ last_read(0),
+ seen(0){
+ }
+
+ unsigned int delay;
+ bool block;
+ X out;
+ bool pressed;
+ unsigned int last_read;
+ unsigned int seen;
+};
+
+/* cant typedef a template'd struct so we have to copy/paste the definition
+ */
+template <typename X>
+struct JoystickState{
+ JoystickState(unsigned int delay, bool block, X out, unsigned int last_read):
+ delay(delay),
+ block(block),
+ out(out),
+ pressed(false),
+ last_read(0),
+ seen(0){
+ }
+
+ unsigned int delay;
+ bool block;
+ X out;
+ bool pressed;
+ unsigned int last_read;
+ unsigned int seen;
+};
+
+/* maps a raw input device (keyboard, joystick, etc.) to some user-defined type
+ * the template parameter, X, is that user-defined type
+ */
+template <typename X>
+class InputMap{
+public:
+ typedef std::map<X, bool> Output;
+
+ struct InputEvent{
+ InputEvent(const X & out, Keyboard::unicode_t unicode, bool enabled):
+ out(out),
+ unicode(unicode),
+ enabled(enabled){
+ }
+
+ InputEvent(const InputEvent & input):
+ out(input.out),
+ unicode(input.unicode),
+ enabled(input.enabled){
+ }
+
+ InputEvent(){
+ }
+
+ bool operator[](const X & is) const {
+ return this->out == is;
+ }
+
+ X out;
+ Keyboard::unicode_t unicode;
+ bool enabled;
+ };
+
+ InputMap():
+ last_read(0){
+ }
+
+ InputMap(const InputMap & copy){
+ for (typename std::map<Keyboard::KeyType, KeyState<X>* >::const_iterator it = copy.key_states.begin(); it != copy.key_states.end(); it++){
+ key_states[(*it).first] = new KeyState<X>(*(*it).second);
+ }
+ for (typename std::map<typename Joystick::Key, JoystickState<X>* >::const_iterator it = copy.joy_states.begin(); it != copy.joy_states.end(); it++){
+ joy_states[(*it).first] = new JoystickState<X>(*(*it).second);
+ }
+ last_read = copy.last_read;
+ }
+
+ InputMap & operator=(const InputMap & copy){
+ for (typename std::map<Keyboard::KeyType, KeyState<X>* >::const_iterator it = copy.key_states.begin(); it != copy.key_states.end(); it++){
+ key_states[(*it).first] = new KeyState<X>(*(*it).second);
+ }
+ for (typename std::map<typename Joystick::Key, JoystickState<X>* >::const_iterator it = copy.joy_states.begin(); it != copy.joy_states.end(); it++){
+ joy_states[(*it).first] = new JoystickState<X>(*(*it).second);
+ }
+ last_read = copy.last_read;
+ return *this;
+ }
+
+ virtual ~InputMap(){
+ for (typename std::map<Keyboard::KeyType, KeyState<X>*>::iterator it = key_states.begin(); it != key_states.end(); it++){
+ delete (*it).second;
+ }
+
+ for (typename std::map<typename Joystick::Key, JoystickState<X>* >::iterator it = joy_states.begin(); it != joy_states.end(); it++){
+ delete (*it).second;
+ }
+ }
+
+ /* key: the keyboard key to recognize, something like KEY_A
+ * delay: time before successive keys are recognized (if held down)
+ * block: if true then the key must be released before it will
+ * be recognized again. false allows repetition.
+ * out: user defined value to set if this key is pressed
+ */
+ void set(Keyboard::KeyType key, int delay, bool block, X out){
+ key_states[key] = new KeyState<X>(delay, block, out, last_read);
+ }
+
+ /* change an existing key */
+ void update(Keyboard::KeyType key, int delay, bool block, X out){
+ if (key_states[key] != 0){
+ key_states[key]->delay = delay;
+ key_states[key]->block = block;
+ key_states[key]->out = out;
+ }
+ }
+
+ /* mostly the same stuff but for joysticks.
+ */
+ void set(typename Joystick::Key key, int delay, bool block, X out){
+ joy_states[key] = new JoystickState<X>(delay, block, out, last_read);
+ }
+
+ static std::vector<X> getAllPressed(const Output & output){
+ std::vector<X> out;
+
+ for (typename Output::const_iterator it = output.begin(); it != output.end(); it++){
+ if ((*it).second){
+ out.push_back((*it).first);
+ }
+ }
+
+ return out;
+ }
+
+ /*
+ static void observeKey(const Keyboard::KeyData & data, void * self){
+ InputMap<X> * me = (InputMap<X>*) self;
+
+ KeyState<X> * state = state = getState(data.key);
+ if (state != NULL){
+ events.push_back(InputEvent(state->out, data.unicode, data.enabled));
+ }
+ }
+ */
+
+ bool pressed(const std::vector<int> & keys, X out){
+ for (std::vector<int>::const_iterator it = keys.begin(); it != keys.end(); it++){
+ Keyboard::KeyType key = *it;
+ KeyState<X> * state = key_states[key];
+ if (state != 0){
+ if (state->out == out){
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ virtual KeyState<X> * getState(int key){
+ return key_states[key];
+ }
+
+ virtual JoystickState<X> * getJoystickState(Joystick::Key key){
+ return joy_states[key];
+ }
+
+ void read(const std::vector<int> & keys, Output * output){
+ for (std::vector<int>::const_iterator it = keys.begin(); it != keys.end(); it++){
+ Keyboard::KeyType key = *it;
+ KeyState<X> * state = getState(key);
+ if (state != NULL){
+ bool use = false;
+ // Global::debug(0) << "read " << key << " last read is " << state->last_read << " my last read is " << last_read << std::endl;
+ if (state->block){
+ if (last_read - state->last_read > 1){
+ use = true;
+ }
+ } else if (last_read - state->last_read > 1 || state->seen >= state->delay){
+ use = true;
+ state->seen = 0;
+ } else {
+ state->seen += 1;
+ }
+
+ state->last_read = last_read;
+
+ // state->last_read = last_read;
+
+ (*output)[state->out] = use;
+ }
+ }
+ }
+
+ /* called by the input manager when the map is read */
+ void update(){
+ last_read += 1;
+ }
+
+ void read(const JoystickInput & joystick, Output * output){
+#define do_joy(field, key) if (joystick.field){\
+ JoystickState<X> * state = joy_states[Joystick::key];\
+ doJoyState(state, output);\
+}
+
+ do_joy(down, Down);
+ do_joy(up, Up);
+ do_joy(left, Left);
+ do_joy(right, Right);
+ do_joy(button1, Button1);
+ do_joy(button2, Button2);
+ do_joy(button3, Button3);
+ do_joy(button4, Button4);
+ /*
+ if (joystick.up){
+ JoystickState<X> * state = joy_states[Joystick::Up];
+ doJoyState(state);
+ }
+
+ if (joystick.down){
+ JoystickState<X> * state = joy_states[Joystick::Down];
+ doJoyState(state);
+ }
+ */
+#undef do_joy
+
+ }
+
+ bool pressed(const JoystickInput & joystick, X out){
+#define do_joy(field, key) if (joystick.field){\
+ JoystickState<X> * state = joy_states[Joystick::key];\
+ if (state != 0 && state->out == out){\
+ return true;\
+ }\
+}
+
+ do_joy(down, Down);
+ do_joy(up, Up);
+ do_joy(left, Left);
+ do_joy(right, Right);
+ do_joy(button1, Button1);
+ do_joy(button2, Button2);
+ do_joy(button3, Button3);
+ do_joy(button4, Button4);
+
+
+#undef do_joy
+ return false;
+ }
+
+protected:
+ void doJoyState(JoystickState<X> * state, Output * output){
+ if (state != 0){
+ bool use = false;
+ if (state->block){
+ if (last_read - state->last_read > 1){
+ use = true;
+ }
+ } else if (last_read - state->last_read > 1 || state->seen >= state->delay){
+ use = true;
+ state->seen = 0;
+ } else {
+ state->seen += 1;
+ }
+
+ state->last_read = last_read;
+
+ // state->last_read = last_read;
+
+ (*output)[state->out] = use;
+ }
+ }
+
+private:
+ std::map<Keyboard::KeyType, KeyState<X>* > key_states;
+ std::map<typename Joystick::Key, JoystickState<X>* > joy_states;
+ unsigned int last_read;
+};
+
+#endif
diff --git a/util/input/input.cpp b/util/input/input.cpp
new file mode 100644
index 00000000..cbc02f14
--- /dev/null
+++ b/util/input/input.cpp
@@ -0,0 +1,48 @@
+#include "input.h"
+#include "configuration.h"
+#include "paintown-engine/object/object.h"
+#include <vector>
+
+using namespace std;
+
+static Input::PaintownInput convertKey(const Configuration & configuration, const int facing, const int key){
+ if (key == configuration.getRight()){
+ switch (facing){
+ case Paintown::Object::FACING_LEFT : return Input::Back;
+ case Paintown::Object::FACING_RIGHT : return Input::Forward;
+ }
+ } else if (key == configuration.getLeft()){
+ switch (facing){
+ case Paintown::Object::FACING_LEFT : return Input::Forward;
+ case Paintown::Object::FACING_RIGHT : return Input::Back;
+ }
+ } else if (key == configuration.getJump()){
+ return Input::Jump;
+ } else if (key == configuration.getUp()){
+ return Input::Up;
+ } else if (key == configuration.getDown()){
+ return Input::Down;
+ } else if (key == configuration.getAttack1()){
+ return Input::Attack1;
+ } else if (key == configuration.getAttack2()){
+ return Input::Attack2;
+ } else if (key == configuration.getAttack3()){
+ return Input::Attack3;
+ }
+
+ return Input::Unknown;
+}
+
+vector<Input::PaintownInput> Input::convertKeyboard(const Configuration & configuration, int facing, const vector<int> & keys){
+ vector<Input::PaintownInput> all;
+
+ for (vector<int>::const_iterator it = keys.begin(); it != keys.end(); it++){
+ Input::PaintownInput in = convertKey(configuration, facing, *it);
+ if (in != Unknown){
+ all.push_back(in);
+ }
+
+ }
+
+ return all;
+}
diff --git a/util/input/input.h b/util/input/input.h
new file mode 100644
index 00000000..ed0c990a
--- /dev/null
+++ b/util/input/input.h
@@ -0,0 +1,32 @@
+#ifndef _paintown_input_h
+#define _paintown_input_h
+
+#include <vector>
+#include "joystick.h"
+
+class Configuration;
+
+class Input{
+public:
+ /* don't change these numbers, but you can add to them */
+ enum PaintownInput{
+ Unknown = -1,
+ Forward = 0,
+ Back = 1,
+ Up = 2,
+ Down = 3,
+ Attack1 = 4,
+ Attack2 = 5,
+ Attack3 = 6,
+ Jump = 7,
+ Grab = 8,
+ Attack4 = 9,
+ Attack5 = 10,
+ Attack6 = 11,
+ };
+
+ /* TODO: remove this method.. useless now. */
+ static std::vector<PaintownInput> convertKeyboard(const Configuration & configuration,int facing, const std::vector<int> & keys);
+};
+
+#endif
diff --git a/util/input/joystick.cpp b/util/input/joystick.cpp
new file mode 100644
index 00000000..363d22a6
--- /dev/null
+++ b/util/input/joystick.cpp
@@ -0,0 +1,82 @@
+#include <stdlib.h>
+#include "joystick.h"
+
+/*
+#ifdef LINUX
+#include "linux_joystick.h"
+#endif
+*/
+
+#ifdef USE_ALLEGRO
+#include "allegro/allegro-joystick.h"
+#endif
+#ifdef USE_SDL
+#ifdef WII
+#include "wii/joystick.h"
+#include "sdl/joystick.h"
+#elif MINPSPW
+#include "psp/joystick.h"
+#else
+#include "sdl/joystick.h"
+#endif
+#endif
+
+Joystick * Joystick::create(){
+#ifdef USE_ALLEGRO
+ return new AllegroJoystick();
+#endif
+#ifdef USE_SDL
+#ifdef WII
+ return new SDLJoystick();
+ // return new WiiJoystick();
+#elif MINPSPW
+ return new PSPJoystick();
+#else
+ return new SDLJoystick();
+#endif
+#endif
+/*
+#ifdef LINUX
+ return new LinuxJoystick();
+#endif
+ return NULL;
+*/
+}
+
+Joystick::Joystick(){
+}
+
+Joystick::~Joystick(){
+}
+
+bool Joystick::pressed(){
+ JoystickInput input = readAll();
+ return input.up || input.down || input.left || input.right ||
+ input.button1 || input.button2 || input.button3 || input.button4 ||
+ input.quit;
+}
+
+const char * Joystick::keyToName(Key key){
+ switch (key){
+ case Invalid : return "Invalid";
+ case Up : return "Up";
+ case Down : return "Down";
+ case Left : return "Left";
+ case Right : return "Right";
+ case Button1 : return "Button1";
+ case Button2 : return "Button2";
+ case Button3 : return "Button3";
+ case Button4 : return "Button4";
+ case Quit: return "Quit";
+ }
+ return "Unknown";
+}
+
+void Joystick::pressButton(int button){
+}
+
+void Joystick::releaseButton(int button){
+}
+
+void Joystick::axisMotion(int axis, int motion){
+}
diff --git a/util/input/joystick.h b/util/input/joystick.h
new file mode 100644
index 00000000..f08324ed
--- /dev/null
+++ b/util/input/joystick.h
@@ -0,0 +1,91 @@
+#ifndef _paintown_joystick_h
+#define _paintown_joystick_h
+
+#include <vector>
+
+struct JoystickInput{
+ JoystickInput():
+ left(false),
+ right(false),
+ up(false),
+ down(false),
+ button1(false),
+ button2(false),
+ button3(false),
+ button4(false),
+ quit(false){
+ }
+
+ JoystickInput(const JoystickInput & copy):
+ left(copy.left),
+ right(copy.right),
+ up(copy.up),
+ down(copy.down),
+ button1(copy.button1),
+ button2(copy.button2),
+ button3(copy.button3),
+ button4(copy.button4),
+ quit(copy.quit){
+ }
+
+ /* true if something is pressed */
+ bool pressed(){
+ return left || right || up || down ||
+ button1 || button2 || button3 || button4 ||
+ quit;
+ }
+
+ bool left;
+ bool right;
+ bool up;
+ bool down;
+ bool button1;
+ bool button2;
+ bool button3;
+ bool button4;
+ bool quit;
+};
+
+class Joystick{
+public:
+ virtual void poll() = 0;
+ virtual JoystickInput readAll() = 0;
+ virtual bool pressed();
+ virtual ~Joystick();
+
+ virtual int getDeviceId() const = 0;
+ virtual void pressButton(int button);
+ virtual void releaseButton(int button);
+ virtual void axisMotion(int axis, int motion);
+
+ static Joystick * create();
+
+ enum Key{
+ Invalid = -1,
+ Up = 0,
+ Down,
+ Left,
+ Right,
+ Button1,
+ Button2,
+ Button3,
+ Button4,
+ Quit,
+ };
+
+ typedef Key Event;
+
+ virtual inline const std::vector<Event> & getEvents() const {
+ return events;
+ }
+
+ static const char * keyToName(Key key);
+
+protected:
+
+ std::vector<Event> events;
+
+ Joystick();
+};
+
+#endif
diff --git a/util/input/keyboard.cpp b/util/input/keyboard.cpp
new file mode 100644
index 00000000..2da26fe4
--- /dev/null
+++ b/util/input/keyboard.cpp
@@ -0,0 +1,400 @@
+#ifdef USE_ALLEGRO
+#include "allegro/keyboard.cpp"
+#endif
+#ifdef USE_SDL
+#include "sdl/keyboard.cpp"
+#endif
+
+bool Keyboard::isNumber( int key ){
+ return key == Key_0 ||
+ key == Key_1 ||
+ key == Key_2 ||
+ key == Key_3 ||
+ key == Key_4 ||
+ key == Key_5 ||
+ key == Key_6 ||
+ key == Key_7 ||
+ key == Key_8 ||
+ key == Key_9;
+}
+
+bool Keyboard::isChar( int key ){
+ return key == Key_A ||
+ key == Key_B ||
+ key == Key_C ||
+ key == Key_D ||
+ key == Key_E ||
+ key == Key_F ||
+ key == Key_G ||
+ key == Key_H ||
+ key == Key_I ||
+ key == Key_J ||
+ key == Key_K ||
+ key == Key_L ||
+ key == Key_M ||
+ key == Key_N ||
+ key == Key_O ||
+ key == Key_P ||
+ key == Key_Q ||
+ key == Key_R ||
+ key == Key_S ||
+ key == Key_T ||
+ key == Key_U ||
+ key == Key_V ||
+ key == Key_W ||
+ key == Key_X ||
+ key == Key_Y ||
+ key == Key_Z ||
+ key == Key_MINUS;
+}
+
+bool Keyboard::isAlpha( int key ){
+ return isNumber( key ) || isChar( key );
+}
+
+
+const char * Keyboard::keyToName( int key ){
+ switch ( key ){
+ case Keyboard::Key_A : return "A";
+ case Keyboard::Key_B : return "B";
+ case Keyboard::Key_C : return "C";
+ case Keyboard::Key_D : return "D";
+ case Keyboard::Key_E : return "E";
+ case Keyboard::Key_F : return "F";
+ case Keyboard::Key_G : return "G";
+ case Keyboard::Key_H : return "H";
+ case Keyboard::Key_I : return "I";
+ case Keyboard::Key_J : return "J";
+ case Keyboard::Key_K : return "K";
+ case Keyboard::Key_L : return "L";
+ case Keyboard::Key_M : return "M";
+ case Keyboard::Key_N : return "N";
+ case Keyboard::Key_O : return "O";
+ case Keyboard::Key_P : return "P";
+ case Keyboard::Key_Q : return "Q";
+ case Keyboard::Key_R : return "R";
+ case Keyboard::Key_S : return "S";
+ case Keyboard::Key_T : return "T";
+ case Keyboard::Key_U : return "U";
+ case Keyboard::Key_V : return "V";
+ case Keyboard::Key_W : return "W";
+ case Keyboard::Key_X : return "X";
+ case Keyboard::Key_Y : return "Y";
+ case Keyboard::Key_Z : return "Z";
+ case Keyboard::Key_0 : return "0";
+ case Keyboard::Key_1 : return "1";
+ case Keyboard::Key_2 : return "2";
+ case Keyboard::Key_3 : return "3";
+ case Keyboard::Key_4 : return "4";
+ case Keyboard::Key_5 : return "5";
+ case Keyboard::Key_6 : return "6";
+ case Keyboard::Key_7 : return "7";
+ case Keyboard::Key_8 : return "8";
+ case Keyboard::Key_9 : return "9";
+ case Keyboard::Key_0_PAD : return "0_PAD";
+ case Keyboard::Key_1_PAD : return "1_PAD";
+ case Keyboard::Key_2_PAD : return "2_PAD";
+ case Keyboard::Key_3_PAD : return "3_PAD";
+ case Keyboard::Key_4_PAD : return "4_PAD";
+ case Keyboard::Key_5_PAD : return "5_PAD";
+ case Keyboard::Key_6_PAD : return "6_PAD";
+ case Keyboard::Key_7_PAD : return "7_PAD";
+ case Keyboard::Key_8_PAD : return "8_PAD";
+ case Keyboard::Key_9_PAD : return "9_PAD";
+ case Keyboard::Key_F1 : return "F1";
+ case Keyboard::Key_F2 : return "F2";
+ case Keyboard::Key_F3 : return "F3";
+ case Keyboard::Key_F4 : return "F4";
+ case Keyboard::Key_F5 : return "F5";
+ case Keyboard::Key_F6 : return "F6";
+ case Keyboard::Key_F7 : return "F7";
+ case Keyboard::Key_F8 : return "F8";
+ case Keyboard::Key_F9 : return "F9";
+ case Keyboard::Key_F10 : return "F10";
+ case Keyboard::Key_F11 : return "F11";
+ case Keyboard::Key_F12 : return "F12";
+ case Keyboard::Key_ESC : return "ESC";
+ case Keyboard::Key_TILDE : return "~";
+ case Keyboard::Key_MINUS : return "-";
+ case Keyboard::Key_EQUALS : return "=";
+ case Keyboard::Key_BACKSPACE : return "BACKSPACE";
+ case Keyboard::Key_TAB : return "TAB";
+ case Keyboard::Key_OPENBRACE : return "OPENBRACE";
+ case Keyboard::Key_CLOSEBRACE : return "CLOSEBRACE";
+ case Keyboard::Key_ENTER : return "ENTER";
+ case Keyboard::Key_COLON : return "COLON";
+ case Keyboard::Key_QUOTE : return "QUOTE";
+ case Keyboard::Key_BACKSLASH : return "BACKSLASH";
+ case Keyboard::Key_BACKSLASH2 : return "BACKSLASH2";
+ case Keyboard::Key_COMMA : return "COMMA";
+ case Keyboard::Key_STOP : return ".";
+ case Keyboard::Key_SLASH : return "SLASH";
+ case Keyboard::Key_SPACE : return "SPACE";
+ case Keyboard::Key_INSERT : return "INSERT";
+ case Keyboard::Key_DEL : return "DEL";
+ case Keyboard::Key_HOME : return "HOME";
+ case Keyboard::Key_END : return "END";
+ case Keyboard::Key_PGUP : return "PGUP";
+ case Keyboard::Key_PGDN : return "PGDN";
+ case Keyboard::Key_LEFT : return "LEFT";
+ case Keyboard::Key_RIGHT : return "RIGHT";
+ case Keyboard::Key_UP : return "UP";
+ case Keyboard::Key_DOWN : return "DOWN";
+ case Keyboard::Key_SLASH_PAD : return "SLASH_PAD";
+ case Keyboard::Key_ASTERISK : return "ASTERISK";
+ case Keyboard::Key_MINUS_PAD : return "MINUS_PAD";
+ case Keyboard::Key_PLUS_PAD : return "PLUS_PAD";
+ case Keyboard::Key_DEL_PAD : return "DEL_PAD";
+ case Keyboard::Key_ENTER_PAD : return "ENTER_PAD";
+ case Keyboard::Key_PRTSCR : return "PRTSCR";
+ case Keyboard::Key_PAUSE : return "PAUSE";
+ case Keyboard::Key_ABNT_C1 : return "ABNT_C1";
+ case Keyboard::Key_YEN : return "YEN";
+ case Keyboard::Key_KANA : return "KANA";
+ case Keyboard::Key_CONVERT : return "CONVERT";
+ case Keyboard::Key_NOCONVERT : return "NOCONVERT";
+ case Keyboard::Key_AT : return "AT";
+ case Keyboard::Key_CIRCUMFLEX : return "CIRCUMFLEX";
+ case Keyboard::Key_COLON2 : return "COLON2";
+ case Keyboard::Key_KANJI : return "KANJI";
+ case Keyboard::Key_EQUALS_PAD : return "EQUALS_PAD";
+ case Keyboard::Key_BACKQUOTE : return "BACKQUOTE";
+ case Keyboard::Key_SEMICOLON : return "SEMICOLON";
+ case Keyboard::Key_COMMAND : return "COMMAND";
+ /*
+ case Keyboard::Key_UNKNOWN1 : return "UNKNOWN1";
+ case Keyboard::Key_UNKNOWN2 : return "UNKNOWN2";
+ case Keyboard::Key_UNKNOWN3 : return "UNKNOWN3";
+ case Keyboard::Key_UNKNOWN4 : return "UNKNOWN4";
+ case Keyboard::Key_UNKNOWN5 : return "UNKNOWN5";
+ case Keyboard::Key_UNKNOWN6 : return "UNKNOWN6";
+ case Keyboard::Key_UNKNOWN7 : return "UNKNOWN7";
+ case Keyboard::Key_UNKNOWN8 : return "UNKNOWN8";
+ */
+ // case Keyboard::Key_MODIFIERS : return "MODIFIERS";
+ case Keyboard::Key_LSHIFT : return "LSHIFT";
+ case Keyboard::Key_RSHIFT : return "RSHIFT";
+ case Keyboard::Key_LCONTROL : return "LCONTROL";
+ case Keyboard::Key_RCONTROL : return "RCONTROL";
+ case Keyboard::Key_ALT : return "ALT";
+ case Keyboard::Key_ALTGR : return "ALTGR";
+ case Keyboard::Key_LWIN : return "LWIN";
+ case Keyboard::Key_RWIN : return "RWIN";
+ case Keyboard::Key_MENU : return "MENU";
+ case Keyboard::Key_SCRLOCK : return "SCRLOCK";
+ case Keyboard::Key_NUMLOCK : return "NUMLOCK";
+ case Keyboard::Key_CAPSLOCK : return "CAPSLOCK";
+ default : return "Unknown key";
+ }
+}
+
+void Keyboard::setDelay( const int key, const int delay ){
+ key_delay[ key ] = delay;
+}
+
+void Keyboard::setAllDelay( const int delay ){
+ setDelay( Key_A, delay );
+ setDelay( Key_B, delay );
+ setDelay( Key_C, delay );
+ setDelay( Key_D, delay );
+ setDelay( Key_E, delay );
+ setDelay( Key_F, delay );
+ setDelay( Key_G, delay );
+ setDelay( Key_H, delay );
+ setDelay( Key_I, delay );
+ setDelay( Key_J, delay );
+ setDelay( Key_K, delay );
+ setDelay( Key_L, delay );
+ setDelay( Key_M, delay );
+ setDelay( Key_N, delay );
+ setDelay( Key_O, delay );
+ setDelay( Key_P, delay );
+ setDelay( Key_Q, delay );
+ setDelay( Key_R, delay );
+ setDelay( Key_S, delay );
+ setDelay( Key_T, delay );
+ setDelay( Key_U, delay );
+ setDelay( Key_V, delay );
+ setDelay( Key_W, delay );
+ setDelay( Key_X, delay );
+ setDelay( Key_Y, delay );
+ setDelay( Key_Z, delay );
+ setDelay( Key_0, delay );
+ setDelay( Key_1, delay );
+ setDelay( Key_2, delay );
+ setDelay( Key_3, delay );
+ setDelay( Key_4, delay );
+ setDelay( Key_5, delay );
+ setDelay( Key_6, delay );
+ setDelay( Key_7, delay );
+ setDelay( Key_8, delay );
+ setDelay( Key_9, delay );
+ setDelay( Key_0_PAD, delay );
+ setDelay( Key_1_PAD, delay );
+ setDelay( Key_2_PAD, delay );
+ setDelay( Key_3_PAD, delay );
+ setDelay( Key_4_PAD, delay );
+ setDelay( Key_5_PAD, delay );
+ setDelay( Key_6_PAD, delay );
+ setDelay( Key_7_PAD, delay );
+ setDelay( Key_8_PAD, delay );
+ setDelay( Key_9_PAD, delay );
+ setDelay( Key_F1, delay );
+ setDelay( Key_F2, delay );
+ setDelay( Key_F3, delay );
+ setDelay( Key_F4, delay );
+ setDelay( Key_F5, delay );
+ setDelay( Key_F6, delay );
+ setDelay( Key_F7, delay );
+ setDelay( Key_F8, delay );
+ setDelay( Key_F9, delay );
+ setDelay( Key_F10, delay );
+ setDelay( Key_F11, delay );
+ setDelay( Key_F12, delay );
+ setDelay( Key_ESC, delay );
+ setDelay( Key_TILDE, delay );
+ setDelay( Key_MINUS, delay );
+ setDelay( Key_EQUALS, delay );
+ setDelay( Key_BACKSPACE, delay );
+ setDelay( Key_TAB, delay );
+ setDelay( Key_OPENBRACE, delay );
+ setDelay( Key_CLOSEBRACE, delay );
+ setDelay( Key_ENTER, delay );
+ setDelay( Key_COLON, delay );
+ setDelay( Key_QUOTE, delay );
+ setDelay( Key_BACKSLASH, delay );
+ setDelay( Key_BACKSLASH2, delay );
+ setDelay( Key_COMMA, delay );
+ setDelay( Key_STOP, delay );
+ setDelay( Key_SLASH, delay );
+ setDelay( Key_SPACE, delay );
+ setDelay( Key_INSERT, delay );
+ setDelay( Key_DEL, delay );
+ setDelay( Key_HOME, delay );
+ setDelay( Key_END, delay );
+ setDelay( Key_PGUP, delay );
+ setDelay( Key_PGDN, delay );
+ setDelay( Key_LEFT, delay );
+ setDelay( Key_RIGHT, delay );
+ setDelay( Key_UP, delay );
+ setDelay( Key_DOWN, delay );
+ setDelay( Key_SLASH_PAD, delay );
+ setDelay( Key_ASTERISK, delay );
+ setDelay( Key_MINUS_PAD, delay );
+ setDelay( Key_PLUS_PAD, delay );
+ setDelay( Key_DEL_PAD, delay );
+ setDelay( Key_ENTER_PAD, delay );
+ setDelay( Key_PRTSCR, delay );
+ setDelay( Key_PAUSE, delay );
+ setDelay( Key_ABNT_C1, delay );
+ setDelay( Key_YEN, delay );
+ setDelay( Key_KANA, delay );
+ setDelay( Key_CONVERT, delay );
+ setDelay( Key_NOCONVERT, delay );
+ setDelay( Key_AT, delay );
+ setDelay( Key_CIRCUMFLEX, delay );
+ setDelay( Key_COLON2, delay );
+ setDelay( Key_KANJI, delay );
+ setDelay( Key_EQUALS_PAD, delay );
+ setDelay( Key_BACKQUOTE, delay );
+ setDelay( Key_SEMICOLON, delay );
+ setDelay( Key_COMMAND, delay );
+ /*
+ setDelay( Key_UNKNOWN1, delay );
+ setDelay( Key_UNKNOWN2, delay );
+ setDelay( Key_UNKNOWN3, delay );
+ setDelay( Key_UNKNOWN4, delay );
+ setDelay( Key_UNKNOWN5, delay );
+ setDelay( Key_UNKNOWN6, delay );
+ setDelay( Key_UNKNOWN7, delay );
+ setDelay( Key_UNKNOWN8, delay );
+ */
+ setDelay( Key_MODIFIERS, delay );
+ setDelay( Key_LSHIFT, delay );
+ setDelay( Key_RSHIFT, delay );
+ setDelay( Key_LCONTROL, delay );
+ setDelay( Key_RCONTROL, delay );
+ setDelay( Key_ALT, delay );
+ setDelay( Key_ALTGR, delay );
+ setDelay( Key_LWIN, delay );
+ setDelay( Key_RWIN, delay );
+ setDelay( Key_MENU, delay );
+ setDelay( Key_SCRLOCK, delay );
+ setDelay( Key_NUMLOCK, delay );
+ setDelay( Key_CAPSLOCK, delay );
+}
+
+void Keyboard::press(KeyType key, unicode_t unicode){
+ keyState[key].key = key;
+ keyState[key].unicode = unicode;
+ keyState[key].enabled = true;
+ // if (enableBuffer){
+ buffer.push_back(keyState[key]);
+ // }
+ /*
+ KeyData data(key, unicode, true);
+ for (std::vector<Observer>::iterator it = observers.begin(); it != observers.end(); it++){
+ Observer observer = (*it);
+ observer.callback(data, observer.extra);
+ }
+ */
+}
+
+void Keyboard::release(KeyType key){
+ keyState[key].enabled = false;
+ buffer.push_back(keyState[key]);
+ /*
+ KeyData data(key, 0, false);
+ for (std::vector<Observer>::iterator it = observers.begin(); it != observers.end(); it++){
+ Observer observer = (*it);
+ observer.callback(data, observer.extra);
+ }
+ */
+}
+
+void Keyboard::readBufferedKeys(std::vector<int> & keys){
+ for (std::vector<KeyData>::iterator it = buffer.begin(); it != buffer.end(); it++){
+ const KeyData & data = *it;
+ keys.push_back(data.key);
+ }
+}
+
+std::vector<Keyboard::KeyData> Keyboard::readData(){
+ std::vector<Keyboard::KeyData> out;
+ for (std::map<KeyType, KeyData>::iterator it = keyState.begin(); it != keyState.end(); it++){
+ KeyType key = it->first;
+ const KeyData & data = it->second;
+ if (data.enabled){
+ out.push_back(data);
+ }
+ }
+ return out;
+}
+
+std::vector<Keyboard::unicode_t> Keyboard::readText(){
+ std::vector<Keyboard::unicode_t> out;
+ for (std::map<KeyType, KeyData>::iterator it = keyState.begin(); it != keyState.end(); it++){
+ KeyType key = it->first;
+ const KeyData & data = it->second;
+ if (data.enabled){
+ out.push_back(data.unicode);
+ }
+ }
+ return out;
+}
+
+/*
+void Keyboard::addObserver(ObserverCallback observer, void * data){
+ observers.push_back(Observer(observer, data));
+}
+
+void Keyboard::removeObserver(ObserverCallback observer, void * data){
+ for (std::vector<Observer>::iterator it = observers.begin(); it != observers.end(); it++){
+ const Observer & what = *it;
+ if (what.callback == observer && what.extra == data){
+ observers.erase(it);
+ break;
+ }
+ }
+}
+*/
diff --git a/util/input/keyboard.h b/util/input/keyboard.h
new file mode 100644
index 00000000..a9ec1735
--- /dev/null
+++ b/util/input/keyboard.h
@@ -0,0 +1,261 @@
+#ifndef _paintown_keyboard_h
+#define _paintown_keyboard_h
+
+#include <map>
+#include <vector>
+#include <stdint.h>
+
+/* handles allegro key[] array better than keypressed()
+ * and readkey()
+ */
+class Keyboard{
+private:
+ Keyboard();
+public:
+ friend class InputManager;
+
+ typedef const int KeyType;
+ typedef uint32_t unicode_t;
+
+ struct KeyData{
+ KeyData():
+ key(-1),
+ unicode(-1),
+ enabled(false){
+ }
+
+ KeyData(int key, unicode_t unicode, bool enabled):
+ key(key),
+ unicode(unicode),
+ enabled(enabled){
+ }
+
+ int key;
+ /* Converted to a unicode character in UTF-32 */
+ unicode_t unicode;
+ /* whether the key is being pressed */
+ bool enabled;
+ };
+
+ /*
+ typedef void (*ObserverCallback)(const KeyData & data, void * extra);
+ struct Observer{
+ Observer():
+ callback(NULL),
+ extra(NULL){
+ }
+
+ Observer(ObserverCallback callback, void * extra):
+ callback(callback),
+ extra(extra){
+ }
+
+ ObserverCallback callback;
+ void * extra;
+ };
+ */
+
+ /* poll:
+ * Put the keys in Allegro's key[] array into our map of int -> bool
+ */
+ void poll();
+
+ /* wait for all keys to be released */
+ void wait();
+
+ /* []:
+ * Extract a boolean value given a key number
+ */
+#if 0
+ inline bool operator[] ( const int i ){
+
+ /* if the key has been pressed for the first time return true */
+ if ( my_keys[ i ] < 0 ){
+ my_keys[ i ] = 1;
+ return true;
+ }
+
+ bool b = my_keys[ i ] > key_delay[ i ];
+ if ( b ){
+ my_keys[ i ] = 1;
+ }
+ return b;
+ }
+#endif
+
+ /* keypressed:
+ * Returns true if a key is pressed
+ */
+ bool keypressed();
+
+ /* readKeys:
+ * Store all pressed keys in a user supplied vector
+ */
+ void readKeys(std::vector< int > & all_keys);
+ void readBufferedKeys(std::vector<int> & keys);
+ std::vector<KeyData> readData();
+ std::vector<unicode_t> readText();
+
+ // int readKey();
+ void clear();
+
+ void setDelay( const int key, const int delay );
+ void setAllDelay( const int delay );
+
+ inline const std::vector<KeyData> & getBufferedKeys() const {
+ return buffer;
+ }
+
+ static const char * keyToName( int key );
+ static bool isNumber( int key );
+ static bool isChar( int key );
+ static bool isAlpha( int key );
+
+ static KeyType Key_A;
+ static KeyType Key_B;
+ static KeyType Key_C;
+ static KeyType Key_D;
+ static KeyType Key_E;
+ static KeyType Key_F;
+ static KeyType Key_G;
+ static KeyType Key_H;
+ static KeyType Key_I;
+ static KeyType Key_J;
+ static KeyType Key_K;
+ static KeyType Key_L;
+ static KeyType Key_M;
+ static KeyType Key_N;
+ static KeyType Key_O;
+ static KeyType Key_P;
+ static KeyType Key_Q;
+ static KeyType Key_R;
+ static KeyType Key_S;
+ static KeyType Key_T;
+ static KeyType Key_U;
+ static KeyType Key_V;
+ static KeyType Key_W;
+ static KeyType Key_X;
+ static KeyType Key_Y;
+ static KeyType Key_Z;
+ static KeyType Key_0;
+ static KeyType Key_1;
+ static KeyType Key_2;
+ static KeyType Key_3;
+ static KeyType Key_4;
+ static KeyType Key_5;
+ static KeyType Key_6;
+ static KeyType Key_7;
+ static KeyType Key_8;
+ static KeyType Key_9;
+ static KeyType Key_0_PAD;
+ static KeyType Key_1_PAD;
+ static KeyType Key_2_PAD;
+ static KeyType Key_3_PAD;
+ static KeyType Key_4_PAD;
+ static KeyType Key_5_PAD;
+ static KeyType Key_6_PAD;
+ static KeyType Key_7_PAD;
+ static KeyType Key_8_PAD;
+ static KeyType Key_9_PAD;
+ static KeyType Key_F1;
+ static KeyType Key_F2;
+ static KeyType Key_F3;
+ static KeyType Key_F4;
+ static KeyType Key_F5;
+ static KeyType Key_F6;
+ static KeyType Key_F7;
+ static KeyType Key_F8;
+ static KeyType Key_F9;
+ static KeyType Key_F10;
+ static KeyType Key_F11;
+ static KeyType Key_F12;
+ static KeyType Key_ESC;
+ static KeyType Key_TILDE;
+ static KeyType Key_MINUS;
+ static KeyType Key_EQUALS;
+ static KeyType Key_BACKSPACE;
+ static KeyType Key_TAB;
+ static KeyType Key_OPENBRACE;
+ static KeyType Key_CLOSEBRACE;
+ static KeyType Key_ENTER;
+ static KeyType Key_COLON;
+ static KeyType Key_QUOTE;
+ static KeyType Key_BACKSLASH;
+ static KeyType Key_BACKSLASH2;
+ static KeyType Key_COMMA;
+ static KeyType Key_STOP;
+ static KeyType Key_SLASH;
+ static KeyType Key_SPACE;
+ static KeyType Key_INSERT;
+ static KeyType Key_DEL;
+ static KeyType Key_HOME;
+ static KeyType Key_END;
+ static KeyType Key_PGUP;
+ static KeyType Key_PGDN;
+ static KeyType Key_LEFT;
+ static KeyType Key_RIGHT;
+ static KeyType Key_UP;
+ static KeyType Key_DOWN;
+ static KeyType Key_SLASH_PAD;
+ static KeyType Key_ASTERISK;
+ static KeyType Key_MINUS_PAD;
+ static KeyType Key_PLUS_PAD;
+ static KeyType Key_DEL_PAD;
+ static KeyType Key_ENTER_PAD;
+ static KeyType Key_PRTSCR;
+ static KeyType Key_PAUSE;
+ static KeyType Key_ABNT_C1;
+ static KeyType Key_YEN;
+ static KeyType Key_KANA;
+ static KeyType Key_CONVERT;
+ static KeyType Key_NOCONVERT;
+ static KeyType Key_AT;
+ static KeyType Key_CIRCUMFLEX;
+ static KeyType Key_COLON2;
+ static KeyType Key_KANJI;
+ static KeyType Key_EQUALS_PAD;
+ static KeyType Key_BACKQUOTE;
+ static KeyType Key_SEMICOLON;
+ static KeyType Key_COMMAND;
+ /*
+ static KeyType Key_UNKNOWN1;
+ static KeyType Key_UNKNOWN2;
+ static KeyType Key_UNKNOWN3;
+ static KeyType Key_UNKNOWN4;
+ static KeyType Key_UNKNOWN5;
+ static KeyType Key_UNKNOWN6;
+ static KeyType Key_UNKNOWN7;
+ static KeyType Key_UNKNOWN8;
+ */
+ static KeyType Key_MODIFIERS;
+ static KeyType Key_LSHIFT;
+ static KeyType Key_RSHIFT;
+ static KeyType Key_LCONTROL;
+ static KeyType Key_RCONTROL;
+ static KeyType Key_ALT;
+ static KeyType Key_ALTGR;
+ static KeyType Key_LWIN;
+ static KeyType Key_RWIN;
+ static KeyType Key_MENU;
+ static KeyType Key_SCRLOCK;
+ static KeyType Key_NUMLOCK;
+ static KeyType Key_CAPSLOCK;
+
+ void press(KeyType key, unicode_t unicode);
+ void release(KeyType key);
+ /*
+ virtual void addObserver(ObserverCallback observer, void * extra);
+ virtual void removeObserver(ObserverCallback observer, void * extra);
+ */
+
+protected:
+ // std::map<int,int> my_keys;
+ std::map<int,int> key_delay;
+ // std::vector<Observer> observers;
+
+ std::map<KeyType, KeyData> keyState;
+ std::vector<KeyData> buffer;
+ bool enableBuffer;
+};
+
+#endif
diff --git a/util/input/linux_joystick.cpp b/util/input/linux_joystick.cpp
new file mode 100644
index 00000000..ef26c57f
--- /dev/null
+++ b/util/input/linux_joystick.cpp
@@ -0,0 +1,406 @@
+#ifdef LINUX
+
+/* based on
+ * jstest.c Version 1.2
+ *
+ * Copyright (c) 1996-1999 Vojtech Pavlik
+ *
+ * Sponsored by SuSE
+ */
+
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <iostream>
+#include <sstream>
+
+#include <linux/input.h>
+#include <linux/joystick.h>
+
+#include "linux_joystick.h"
+#include "util/debug.h"
+
+using namespace std;
+
+static const char *axis_names[ABS_MAX + 1] = {
+"X", "Y", "Z", "Rx", "Ry", "Rz", "Throttle", "Rudder",
+"Wheel", "Gas", "Brake", "?", "?", "?", "?", "?",
+"Hat0X", "Hat0Y", "Hat1X", "Hat1Y", "Hat2X", "Hat2Y", "Hat3X", "Hat3Y",
+"?", "?", "?", "?", "?", "?", "?",
+};
+
+static const char *button_names[KEY_MAX - BTN_MISC + 1] = {
+"Btn0", "Btn1", "Btn2", "Btn3", "Btn4", "Btn5", "Btn6", "Btn7", "Btn8", "Btn9", "?", "?", "?", "?", "?", "?",
+"LeftBtn", "RightBtn", "MiddleBtn", "SideBtn", "ExtraBtn", "ForwardBtn", "BackBtn", "TaskBtn", "?", "?", "?", "?", "?", "?", "?", "?",
+"Trigger", "ThumbBtn", "ThumbBtn2", "TopBtn", "TopBtn2", "PinkieBtn", "BaseBtn", "BaseBtn2", "BaseBtn3", "BaseBtn4", "BaseBtn5", "BaseBtn6", "BtnDead",
+"BtnA", "BtnB", "BtnC", "BtnX", "BtnY", "BtnZ", "BtnTL", "BtnTR", "BtnTL2", "BtnTR2", "BtnSelect", "BtnStart", "BtnMode", "BtnThumbL", "BtnThumbR", "?",
+"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
+"WheelBtn", "Gear up",
+};
+
+/* tries to open one /dev/input/jsX and return an open file descriptor */
+static int read_joystick(){
+ for (int num = 0; num < 100; num++){
+ ostringstream name;
+ name << "/dev/input/js" << num;
+ const char * cname = name.str().c_str();
+ int fd = open(cname, O_RDONLY);
+ if (fd >= 0){
+ return fd;
+ }
+ }
+ return -1;
+}
+
+LinuxJoystick::LinuxJoystick():
+button(0),
+axis(0){
+ file = read_joystick();
+ if (file == -1){
+ Global::debug(0) << "Could not open joystick" << endl;
+ } else {
+ Global::debug(1) << "Opened joystick " << endl;
+
+ /* grab useful info */
+ ioctl(file, JSIOCGVERSION, &version);
+ ioctl(file, JSIOCGAXES, &axes);
+ ioctl(file, JSIOCGBUTTONS, &buttons);
+ ioctl(file, JSIOCGNAME(NAME_LENGTH), name);
+ ioctl(file, JSIOCGAXMAP, axmap);
+ ioctl(file, JSIOCGBTNMAP, btnmap);
+
+ /* put joystick in nonblocking mode */
+ fcntl(file, F_SETFL, O_NONBLOCK);
+
+ axis = new int[axes];
+ memset(axis, 0, sizeof(int) * axes);
+ button = new char[buttons];
+ memset(button, 0, sizeof(char) * buttons);
+
+ Global::debug(1) << "Joystick axis: " << (int)axes << " buttons: " << (int)buttons << endl;
+ }
+}
+
+LinuxJoystick::~LinuxJoystick(){
+ delete[] axis;
+ delete[] button;
+ if (file != -1){
+ close(file);
+ }
+}
+
+void LinuxJoystick::poll(){
+
+ struct js_event js;
+
+ if (file == -1){
+ return;
+ }
+
+ /* from an email by Vojtech Pavlik:
+ * "if you #include <linux/joystick.h>, the struct is defined in such a way
+ * that gcc doesn't add padding."
+ */
+ int bytes = read(file, &js, sizeof(struct js_event));
+ if (bytes == sizeof(struct js_event)){
+ Global::debug(4) << "Event: type " << (int)js.type << " time " << (int)js.time << " number " << (int)js.number << " value " << (int)js.value << endl;
+
+ if (errno != EAGAIN) {
+ perror("joystick: error reading");
+ return;
+ }
+
+ switch (js.type & ~JS_EVENT_INIT) {
+ case JS_EVENT_BUTTON:
+ button[js.number] = js.value;
+ break;
+ case JS_EVENT_AXIS:
+ axis[js.number] = js.value;
+ break;
+ }
+ }
+}
+
+bool LinuxJoystick::pressed(){
+ if (file == -1){
+ return false;
+ }
+
+ for (int i = 0; i < axes; i++){
+ if (axis[i]){
+ return true;
+ }
+ }
+ for (int i = 0; i < buttons; i++){
+ if (button[i]){
+ return true;
+ }
+ }
+ return false;
+}
+
+JoystickInput LinuxJoystick::readAll(){
+ JoystickInput input;
+ if (file == -1){
+ return input;
+ }
+ if (axes > 0){
+ if (axis[0] < 0){
+ input.left = true;
+ }
+ if (axis[0] > 0){
+ input.right = true;
+ }
+ if (axes > 1){
+ if (axis[1] < 0){
+ input.up = true;
+ }
+ if (axis[1] > 0){
+ input.down = true;
+ }
+ }
+ }
+
+ if (buttons > 0 && button[0]){
+ input.button1 = true;
+ }
+ if (buttons > 1 && button[1]){
+ input.button2 = true;
+ }
+ if (buttons > 2 && button[2]){
+ input.button3 = true;
+ }
+ if (buttons > 3 && button[3]){
+ input.button4 = true;
+ }
+
+ Global::debug(1) << "joystick input up " << input.up
+ << " down " << input.down
+ << " left " << input.left
+ << " right " << input.right
+ << " button1 " << input.button1
+ << " button2 " << input.button2
+ << " button3 " << input.button3
+ << " button4 " << input.button4
+ << endl;
+ return input;
+}
+
+#if 0
+int main (int argc, char **argv)
+{
+ int fd, i;
+ unsigned char axes = 2;
+ unsigned char buttons = 2;
+ int version = 0x000800;
+ char name[NAME_LENGTH] = "Unknown";
+ uint16_t btnmap[KEY_MAX - BTN_MISC + 1];
+ uint8_t axmap[ABS_MAX + 1];
+
+ if (argc < 2 || argc > 3 || !strcmp("--help", argv[1])) {
+ puts("");
+ puts("Usage: jstest [<mode>] <device>");
+ puts("");
+ puts("Modes:");
+ puts(" --normal One-line mode showing immediate status");
+ puts(" --old Same as --normal, using 0.x interface");
+ puts(" --event Prints events as they come in");
+ puts(" --nonblock Same as --event, in nonblocking mode");
+ puts(" --select Same as --event, using select() call");
+ puts("");
+ return 1;
+ }
+ if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
+ perror("jstest");
+ return 1;
+ }
+
+ ioctl(fd, JSIOCGVERSION, &version);
+ ioctl(fd, JSIOCGAXES, &axes);
+ ioctl(fd, JSIOCGBUTTONS, &buttons);
+ ioctl(fd, JSIOCGNAME(NAME_LENGTH), name);
+ ioctl(fd, JSIOCGAXMAP, axmap);
+ ioctl(fd, JSIOCGBTNMAP, btnmap);
+
+
+ printf("Driver version is %d.%d.%d.\n",
+ version >> 16, (version >> 8) & 0xff, version & 0xff);
+
+ printf("Joystick (%s) has %d axes (", name, axes);
+ for (i = 0; i < axes; i++)
+ printf("%s%s", i > 0 ? ", " : "", axis_names[axmap[i]]);
+ puts(")");
+
+ printf("and %d buttons (", buttons);
+ for (i = 0; i < buttons; i++)
+ printf("%s%s", i > 0 ? ", " : "", button_names[btnmap[i] - BTN_MISC]);
+ puts(").");
+
+ printf("Testing ... (interrupt to exit)\n");
+
+/*
+ * Old (0.x) interface.
+ */
+
+ if ((argc == 2 && version < 0x010000) || !strcmp("--old", argv[1])) {
+
+ struct JS_DATA_TYPE js;
+
+ while (1) {
+
+ if (read(fd, &js, JS_RETURN) != JS_RETURN) {
+ perror("\njstest: error reading");
+ return 1;
+ }
+
+ printf("Axes: X:%3d Y:%3d Buttons: A:%s B:%s\r",
+ js.x, js.y, (js.buttons & 1) ? "on " : "off", (js.buttons & 2) ? "on " : "off");
+
+ fflush(stdout);
+
+ usleep(10000);
+ }
+ }
+
+/*
+ * Event interface, single line readout.
+ */
+
+ if (argc == 2 || !strcmp("--normal", argv[1])) {
+
+ int *axis;
+ char *button;
+ int i;
+ struct js_event js;
+
+ axis = calloc(axes, sizeof(int));
+ button = calloc(buttons, sizeof(char));
+
+ while (1) {
+ if (read(fd, &js, sizeof(struct js_event)) != sizeof(struct js_event)) {
+ perror("\njstest: error reading");
+ return 1;
+ }
+
+ switch(js.type & ~JS_EVENT_INIT) {
+ case JS_EVENT_BUTTON:
+ button[js.number] = js.value;
+ break;
+ case JS_EVENT_AXIS:
+ axis[js.number] = js.value;
+ break;
+ }
+
+ printf("\r");
+
+ if (axes) {
+ printf("Axes: ");
+ for (i = 0; i < axes; i++)
+ printf("%2d:%6d ", i, axis[i]);
+ }
+
+ if (buttons) {
+ printf("Buttons: ");
+ for (i = 0; i < buttons; i++)
+ printf("%2d:%s ", i, button[i] ? "on " : "off");
+ }
+
+ fflush(stdout);
+ }
+ }
+
+
+/*
+ * Event interface, events being printed.
+ */
+
+ if (!strcmp("--event", argv[1])) {
+
+ struct js_event js;
+
+ while (1) {
+ if (read(fd, &js, sizeof(struct js_event)) != sizeof(struct js_event)) {
+ perror("\njstest: error reading");
+ return 1;
+ }
+
+ printf("Event: type %d, time %d, number %d, value %d\n",
+ js.type, js.time, js.number, js.value);
+
+ fflush(stdout);
+ }
+ }
+
+/*
+ * Reading in nonblocking mode.
+ */
+
+ if (!strcmp("--nonblock", argv[1])) {
+
+ struct js_event js;
+
+ fcntl(fd, F_SETFL, O_NONBLOCK);
+
+ while (1) {
+
+ while (read(fd, &js, sizeof(struct js_event)) == sizeof(struct js_event)) {
+ printf("Event: type %d, time %d, number %d, value %d\n",
+ js.type, js.time, js.number, js.value);
+ }
+
+ if (errno != EAGAIN) {
+ perror("\njstest: error reading");
+ return 1;
+ }
+
+ usleep(10000);
+ }
+ }
+
+/*
+ * Using select() on joystick fd.
+ */
+
+ if (!strcmp("--select", argv[1])) {
+
+ struct js_event js;
+ struct timeval tv;
+ fd_set set;
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+
+ while (1) {
+
+ FD_ZERO(&set);
+ FD_SET(fd, &set);
+
+ if (select(fd+1, &set, NULL, NULL, &tv)) {
+
+ if (read(fd, &js, sizeof(struct js_event)) != sizeof(struct js_event)) {
+ perror("\njstest: error reading");
+ return 1;
+ }
+
+ printf("Event: type %d, time %d, number %d, value %d\n",
+ js.type, js.time, js.number, js.value);
+
+ }
+
+ }
+ }
+
+ printf("jstest: unknown mode: %s\n", argv[1]);
+ return -1;
+}
+#endif
+
+#endif
diff --git a/util/input/linux_joystick.h b/util/input/linux_joystick.h
new file mode 100644
index 00000000..8c528628
--- /dev/null
+++ b/util/input/linux_joystick.h
@@ -0,0 +1,36 @@
+#ifdef LINUX
+
+#include "joystick.h"
+
+#include <stdint.h>
+#include <vector>
+#include <linux/input.h>
+#include <linux/joystick.h>
+
+#define NAME_LENGTH 1024
+
+class LinuxJoystick: public Joystick {
+public:
+ virtual void poll();
+ virtual JoystickInput readAll();
+ virtual bool pressed();
+
+ virtual ~LinuxJoystick();
+
+ friend class Joystick;
+protected:
+ LinuxJoystick();
+
+ /* file descriptor for /dev/input/jsX */
+ int file;
+ char name[NAME_LENGTH];
+ unsigned char axes;
+ unsigned char buttons;
+ int version;
+ uint16_t btnmap[KEY_MAX - BTN_MISC + 1];
+ uint8_t axmap[ABS_MAX + 1];
+ char * button;
+ int * axis;
+};
+
+#endif
diff --git a/util/input/psp/joystick.cpp b/util/input/psp/joystick.cpp
new file mode 100644
index 00000000..5008175a
--- /dev/null
+++ b/util/input/psp/joystick.cpp
@@ -0,0 +1,54 @@
+#ifdef MINPSPW
+
+#include "joystick.h"
+
+void PSPJoystick::poll(){
+ sceCtrlPeekBufferPositive(&joystick, 1);
+}
+
+int PSPJoystick::getDeviceId() const {
+ /* FIXME */
+ return 0;
+}
+
+JoystickInput PSPJoystick::readAll(){
+ JoystickInput input;
+ if(joystick.Buttons != 0){
+ if(joystick.Buttons & PSP_CTRL_START){
+ //input.button7 = true;
+ } else if(joystick.Buttons & PSP_CTRL_SELECT){
+ //input.button8 = true;
+ } else if(joystick.Buttons & PSP_CTRL_SQUARE){
+ input.button1 = true;
+ } else if(joystick.Buttons & PSP_CTRL_CROSS){
+ input.button2 = true;
+ } else if(joystick.Buttons & PSP_CTRL_TRIANGLE){
+ input.button3 = true;
+ } else if(joystick.Buttons & PSP_CTRL_CIRCLE){
+ input.button4 = true;
+ } else if(joystick.Buttons & PSP_CTRL_RTRIGGER){
+ } else if(joystick.Buttons & PSP_CTRL_LTRIGGER){
+ } else if(joystick.Buttons & PSP_CTRL_LEFT){
+ input.left = true;
+ } else if(joystick.Buttons & PSP_CTRL_RIGHT){
+ input.right = true;
+ } else if(joystick.Buttons & PSP_CTRL_DOWN){
+ input.down = true;
+ } else if(joystick.Buttons & PSP_CTRL_UP){
+ input.up = true;
+ }
+ }
+
+ return input;
+}
+
+PSPJoystick::~PSPJoystick(){
+ // no cleanup required
+}
+
+PSPJoystick::PSPJoystick(){
+ sceCtrlSetSamplingCycle(0);
+ sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
+}
+
+#endif
diff --git a/util/input/psp/joystick.h b/util/input/psp/joystick.h
new file mode 100644
index 00000000..c08770a3
--- /dev/null
+++ b/util/input/psp/joystick.h
@@ -0,0 +1,27 @@
+#ifndef _paintown_psp_joystick_h
+#define _paintown_psp_joystick_h
+
+#ifdef MINPSPW
+
+#include "../joystick.h"
+
+#include <pspctrl.h>
+
+class PSPJoystick: public Joystick {
+public:
+ virtual void poll();
+ virtual JoystickInput readAll();
+ virtual int getDeviceId() const;
+
+ virtual ~PSPJoystick();
+
+ friend class Joystick;
+protected:
+ PSPJoystick();
+ // joystick
+ SceCtrlData joystick;
+};
+
+#endif
+
+#endif
diff --git a/util/input/sdl/joystick.cpp b/util/input/sdl/joystick.cpp
new file mode 100644
index 00000000..a3711b82
--- /dev/null
+++ b/util/input/sdl/joystick.cpp
@@ -0,0 +1,142 @@
+#ifdef USE_SDL
+
+#include <SDL.h>
+#include "joystick.h"
+
+void SDLJoystick::poll(){
+ events.clear();
+}
+
+static bool read_button(SDL_Joystick * joystick, int button){
+ return SDL_JoystickGetButton(joystick, button);
+}
+
+JoystickInput SDLJoystick::readAll(){
+ JoystickInput input;
+ if (joystick){
+ int buttons = SDL_JoystickNumButtons(joystick);
+ switch (buttons > 5 ? 5 : buttons){
+ case 5: input.quit = read_button(joystick, 4);
+ case 4: input.button4 = read_button(joystick, 3);
+ case 3: input.button3 = read_button(joystick, 2);
+ case 2: input.button2 = read_button(joystick, 1);
+ case 1: input.button1 = read_button(joystick, 0);
+ case 0: {
+ break;
+ }
+ }
+ }
+
+ int axis = SDL_JoystickNumAxes(joystick);
+ if (axis > 0){
+ int position = SDL_JoystickGetAxis(joystick, 0);
+ if (position < 0){
+ input.left = true;
+ } else if (position > 0){
+ input.right = true;
+ }
+ }
+
+ if (axis > 1){
+ int position = SDL_JoystickGetAxis(joystick, 1);
+ if (position < 0){
+ input.up = true;
+ } else if (position > 0){
+ input.down = true;
+ }
+ }
+
+ int hats = SDL_JoystickNumHats(joystick);
+ if (hats > 0){
+ int hat = SDL_JoystickGetHat(joystick, 0);
+ if ((hat & SDL_HAT_UP) == SDL_HAT_UP){
+ input.up = true;
+ }
+ if ((hat & SDL_HAT_DOWN) == SDL_HAT_DOWN){
+ input.down = true;
+ }
+ if ((hat & SDL_HAT_LEFT) == SDL_HAT_LEFT){
+ input.left = true;
+ }
+ if ((hat & SDL_HAT_RIGHT) == SDL_HAT_RIGHT){
+ input.right = true;
+ }
+ if ((hat & SDL_HAT_RIGHTUP) == SDL_HAT_RIGHTUP){
+ input.right = true;
+ input.up = true;
+ }
+ if ((hat & SDL_HAT_RIGHTDOWN) == SDL_HAT_RIGHTDOWN){
+ input.right = true;
+ input.down = true;
+ }
+ if ((hat & SDL_HAT_LEFTDOWN) == SDL_HAT_LEFTDOWN){
+ input.left = true;
+ input.down = true;
+ }
+ if ((hat & SDL_HAT_LEFTUP) == SDL_HAT_LEFTUP){
+ input.left = true;
+ input.up = true;
+ }
+ }
+
+ return input;
+}
+
+SDLJoystick::~SDLJoystick(){
+ if (joystick){
+ SDL_JoystickClose(joystick);
+ }
+}
+
+SDLJoystick::SDLJoystick():
+joystick(NULL){
+ if (SDL_NumJoysticks() > 0){
+ joystick = SDL_JoystickOpen(0);
+ }
+}
+
+void SDLJoystick::pressButton(int button){
+ if (joystick){
+ Event event = Invalid;
+ switch (button){
+ case 0: event = Button1; break;
+ case 1: event = Button2; break;
+ case 2: event = Button3; break;
+ case 3: event = Button4; break;
+ case 4: event = Quit; break;
+ default: break;
+ }
+ events.push_back(event);
+ }
+}
+
+void SDLJoystick::releaseButton(int button){
+}
+
+void SDLJoystick::axisMotion(int axis, int motion){
+ if (joystick){
+ if (axis == 0){
+ if (motion < 0){
+ events.push_back(Left);
+ } else if (motion > 0){
+ events.push_back(Right);
+ }
+ } else if (axis == 1){
+ if (motion < 0){
+ events.push_back(Up);
+ } else if (motion > 0){
+ events.push_back(Down);
+ }
+ }
+ }
+}
+
+int SDLJoystick::getDeviceId() const {
+ if (joystick){
+ return SDL_JoystickIndex(joystick);
+ }
+
+ return -1;
+}
+
+#endif
diff --git a/util/input/sdl/joystick.h b/util/input/sdl/joystick.h
new file mode 100644
index 00000000..cf4c3d32
--- /dev/null
+++ b/util/input/sdl/joystick.h
@@ -0,0 +1,28 @@
+#ifndef _paintown_sdl_joystick_h
+#define _paintown_sdl_joystick_h
+
+#ifdef USE_SDL
+
+#include <SDL.h>
+#include "../joystick.h"
+
+class SDLJoystick: public Joystick {
+public:
+ virtual void poll();
+ virtual JoystickInput readAll();
+ virtual int getDeviceId() const;
+ virtual void pressButton(int button);
+ virtual void releaseButton(int button);
+ virtual void axisMotion(int axis, int motion);
+
+ virtual ~SDLJoystick();
+
+ friend class Joystick;
+protected:
+ SDLJoystick();
+ SDL_Joystick * joystick;
+};
+
+#endif
+
+#endif
diff --git a/util/input/sdl/keyboard.cpp b/util/input/sdl/keyboard.cpp
new file mode 100644
index 00000000..f720e801
--- /dev/null
+++ b/util/input/sdl/keyboard.cpp
@@ -0,0 +1,196 @@
+#include <SDL.h>
+#include "../keyboard.h"
+#include "../input-manager.h"
+#include "util/funcs.h"
+
+Keyboard::Keyboard():
+enableBuffer(false){
+}
+
+void Keyboard::poll(){
+ buffer.clear();
+ SDL_PumpEvents();
+}
+
+void Keyboard::wait(){
+ while (keypressed()){
+ Util::rest(1);
+ poll();
+ }
+}
+
+bool Keyboard::keypressed(){
+ int keys = 0;
+ Uint8 * state = SDL_GetKeyState(&keys);
+ for (int i = 0; i < keys; i++){
+ if (i != SDLK_NUMLOCK && state[i] == 1){
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#if 0
+void Keyboard::readKeys( std::vector<int> & all_keys ){
+ int keys = 0;
+ Uint8 * state = SDL_GetKeyState(&keys);
+ /* FIXME: the mapping between SDLK_* and our keyboard values are not 1-1 so
+ * use a function here that returns the right mapping.
+ */
+ for (int i = 0; i < keys; i++){
+ if (i != SDLK_NUMLOCK && state[i] == 1){
+ all_keys.push_back(i);
+ }
+ }
+}
+#endif
+
+void Keyboard::readKeys(std::vector<int> & all_keys){
+ for (std::map<KeyType, KeyData>::iterator it = keyState.begin(); it != keyState.end(); it++){
+ KeyType key = it->first;
+ const KeyData & data = it->second;
+ if (data.enabled){
+ all_keys.push_back(key);
+ }
+ }
+}
+
+/*
+int Keyboard::readKey(){
+ std::vector<int> keys;
+ do{
+ readKeys(keys);
+ Util::rest(1);
+ InputManager::poll();
+ poll();
+ } while (keys.size() == 0);
+ return keys.front();
+}
+*/
+
+void Keyboard::clear(){
+ buffer.clear();
+ keyState.clear();
+}
+
+Keyboard::KeyType Keyboard::Key_A = SDLK_a;
+Keyboard::KeyType Keyboard::Key_B = SDLK_b;
+Keyboard::KeyType Keyboard::Key_C = SDLK_c;
+Keyboard::KeyType Keyboard::Key_D = SDLK_d;
+Keyboard::KeyType Keyboard::Key_E = SDLK_e;
+Keyboard::KeyType Keyboard::Key_F = SDLK_f;
+Keyboard::KeyType Keyboard::Key_G = SDLK_g;
+Keyboard::KeyType Keyboard::Key_H = SDLK_h;
+Keyboard::KeyType Keyboard::Key_I = SDLK_i;
+Keyboard::KeyType Keyboard::Key_J = SDLK_j;
+Keyboard::KeyType Keyboard::Key_K = SDLK_k;
+Keyboard::KeyType Keyboard::Key_L = SDLK_l;
+Keyboard::KeyType Keyboard::Key_M = SDLK_m;
+Keyboard::KeyType Keyboard::Key_N = SDLK_n;
+Keyboard::KeyType Keyboard::Key_O = SDLK_o;
+Keyboard::KeyType Keyboard::Key_P = SDLK_p;
+Keyboard::KeyType Keyboard::Key_Q = SDLK_q;
+Keyboard::KeyType Keyboard::Key_R = SDLK_r;
+Keyboard::KeyType Keyboard::Key_S = SDLK_s;
+Keyboard::KeyType Keyboard::Key_T = SDLK_t;
+Keyboard::KeyType Keyboard::Key_U = SDLK_u;
+Keyboard::KeyType Keyboard::Key_V = SDLK_v;
+Keyboard::KeyType Keyboard::Key_W = SDLK_w;
+Keyboard::KeyType Keyboard::Key_X = SDLK_x;
+Keyboard::KeyType Keyboard::Key_Y = SDLK_y;
+Keyboard::KeyType Keyboard::Key_Z = SDLK_z;
+Keyboard::KeyType Keyboard::Key_0 = SDLK_0;
+Keyboard::KeyType Keyboard::Key_1 = SDLK_1;
+Keyboard::KeyType Keyboard::Key_2 = SDLK_2;
+Keyboard::KeyType Keyboard::Key_3 = SDLK_3;
+Keyboard::KeyType Keyboard::Key_4 = SDLK_4;
+Keyboard::KeyType Keyboard::Key_5 = SDLK_5;
+Keyboard::KeyType Keyboard::Key_6 = SDLK_6;
+Keyboard::KeyType Keyboard::Key_7 = SDLK_7;
+Keyboard::KeyType Keyboard::Key_8 = SDLK_8;
+Keyboard::KeyType Keyboard::Key_9 = SDLK_9;
+Keyboard::KeyType Keyboard::Key_0_PAD = SDLK_KP0;
+Keyboard::KeyType Keyboard::Key_1_PAD = SDLK_KP1;
+Keyboard::KeyType Keyboard::Key_2_PAD = SDLK_KP2;
+Keyboard::KeyType Keyboard::Key_3_PAD = SDLK_KP3;
+Keyboard::KeyType Keyboard::Key_4_PAD = SDLK_KP4;
+Keyboard::KeyType Keyboard::Key_5_PAD = SDLK_KP5;
+Keyboard::KeyType Keyboard::Key_6_PAD = SDLK_KP6;
+Keyboard::KeyType Keyboard::Key_7_PAD = SDLK_KP7;
+Keyboard::KeyType Keyboard::Key_8_PAD = SDLK_KP8;
+Keyboard::KeyType Keyboard::Key_9_PAD = SDLK_KP9;
+Keyboard::KeyType Keyboard::Key_F1 = SDLK_F1;
+Keyboard::KeyType Keyboard::Key_F2 = SDLK_F2;
+Keyboard::KeyType Keyboard::Key_F3 = SDLK_F3;
+Keyboard::KeyType Keyboard::Key_F4 = SDLK_F4;
+Keyboard::KeyType Keyboard::Key_F5 = SDLK_F5;
+Keyboard::KeyType Keyboard::Key_F6 = SDLK_F6;
+Keyboard::KeyType Keyboard::Key_F7 = SDLK_F7;
+Keyboard::KeyType Keyboard::Key_F8 = SDLK_F8;
+Keyboard::KeyType Keyboard::Key_F9 = SDLK_F9;
+Keyboard::KeyType Keyboard::Key_F10 = SDLK_F10;
+Keyboard::KeyType Keyboard::Key_F11 = SDLK_F11;
+Keyboard::KeyType Keyboard::Key_F12 = SDLK_F12;
+Keyboard::KeyType Keyboard::Key_ESC = SDLK_ESCAPE;
+Keyboard::KeyType Keyboard::Key_TILDE = SDLK_BACKQUOTE;
+Keyboard::KeyType Keyboard::Key_MINUS = SDLK_MINUS;
+Keyboard::KeyType Keyboard::Key_EQUALS = SDLK_EQUALS;
+Keyboard::KeyType Keyboard::Key_BACKSPACE = SDLK_BACKSPACE;
+Keyboard::KeyType Keyboard::Key_TAB = SDLK_TAB;
+Keyboard::KeyType Keyboard::Key_OPENBRACE = SDLK_LEFTBRACKET;
+Keyboard::KeyType Keyboard::Key_CLOSEBRACE = SDLK_RIGHTBRACKET;
+Keyboard::KeyType Keyboard::Key_ENTER = SDLK_RETURN;
+Keyboard::KeyType Keyboard::Key_COLON = SDLK_COLON;
+Keyboard::KeyType Keyboard::Key_QUOTE = SDLK_QUOTEDBL;
+Keyboard::KeyType Keyboard::Key_BACKSLASH = SDLK_BACKSLASH;
+Keyboard::KeyType Keyboard::Key_BACKSLASH2 = 999; /* FIXME */
+Keyboard::KeyType Keyboard::Key_COMMA = SDLK_COMMA;
+Keyboard::KeyType Keyboard::Key_STOP = SDLK_PERIOD;
+Keyboard::KeyType Keyboard::Key_SLASH = SDLK_SLASH;
+Keyboard::KeyType Keyboard::Key_SPACE = SDLK_SPACE;
+Keyboard::KeyType Keyboard::Key_INSERT = SDLK_INSERT;
+Keyboard::KeyType Keyboard::Key_DEL = SDLK_DELETE;
+Keyboard::KeyType Keyboard::Key_HOME = SDLK_HOME;
+Keyboard::KeyType Keyboard::Key_END = SDLK_END;
+Keyboard::KeyType Keyboard::Key_PGUP = SDLK_PAGEUP;
+Keyboard::KeyType Keyboard::Key_PGDN = SDLK_PAGEDOWN;
+Keyboard::KeyType Keyboard::Key_LEFT = SDLK_LEFT;
+Keyboard::KeyType Keyboard::Key_RIGHT = SDLK_RIGHT;
+Keyboard::KeyType Keyboard::Key_UP = SDLK_UP;
+Keyboard::KeyType Keyboard::Key_DOWN = SDLK_DOWN;
+Keyboard::KeyType Keyboard::Key_SLASH_PAD = SDLK_KP_DIVIDE;
+Keyboard::KeyType Keyboard::Key_ASTERISK = SDLK_ASTERISK;
+Keyboard::KeyType Keyboard::Key_MINUS_PAD = SDLK_KP_MINUS;
+Keyboard::KeyType Keyboard::Key_PLUS_PAD = SDLK_KP_PLUS;
+Keyboard::KeyType Keyboard::Key_DEL_PAD = 1000; /* FIXME */
+Keyboard::KeyType Keyboard::Key_ENTER_PAD = SDLK_KP_ENTER;
+Keyboard::KeyType Keyboard::Key_PRTSCR = SDLK_PRINT;
+Keyboard::KeyType Keyboard::Key_PAUSE = SDLK_PAUSE;
+Keyboard::KeyType Keyboard::Key_ABNT_C1 = 1001; /* FIXME */
+Keyboard::KeyType Keyboard::Key_YEN = 1002;
+Keyboard::KeyType Keyboard::Key_KANA = 1003;
+Keyboard::KeyType Keyboard::Key_CONVERT = 1004;
+Keyboard::KeyType Keyboard::Key_NOCONVERT = 1005;
+Keyboard::KeyType Keyboard::Key_AT = SDLK_AT;
+Keyboard::KeyType Keyboard::Key_CIRCUMFLEX = SDLK_CARET;
+Keyboard::KeyType Keyboard::Key_COLON2 = 1006;
+Keyboard::KeyType Keyboard::Key_KANJI = 1007;
+Keyboard::KeyType Keyboard::Key_EQUALS_PAD = SDLK_KP_EQUALS;
+Keyboard::KeyType Keyboard::Key_BACKQUOTE = 1008;
+Keyboard::KeyType Keyboard::Key_SEMICOLON = SDLK_SEMICOLON;
+Keyboard::KeyType Keyboard::Key_COMMAND = 1009;
+
+Keyboard::KeyType Keyboard::Key_MODIFIERS = 1010;
+Keyboard::KeyType Keyboard::Key_LSHIFT = SDLK_LSHIFT;
+Keyboard::KeyType Keyboard::Key_RSHIFT = SDLK_RSHIFT;
+Keyboard::KeyType Keyboard::Key_LCONTROL = SDLK_LCTRL;
+Keyboard::KeyType Keyboard::Key_RCONTROL = SDLK_RCTRL;
+Keyboard::KeyType Keyboard::Key_ALT = SDLK_LALT;
+Keyboard::KeyType Keyboard::Key_ALTGR = SDLK_RALT;
+Keyboard::KeyType Keyboard::Key_LWIN = SDLK_LMETA;
+Keyboard::KeyType Keyboard::Key_RWIN = SDLK_RMETA;
+Keyboard::KeyType Keyboard::Key_MENU = SDLK_HELP;
+Keyboard::KeyType Keyboard::Key_SCRLOCK = SDLK_SCROLLOCK;
+Keyboard::KeyType Keyboard::Key_NUMLOCK = SDLK_NUMLOCK;
+Keyboard::KeyType Keyboard::Key_CAPSLOCK = SDLK_CAPSLOCK;
diff --git a/util/input/text-input.cpp b/util/input/text-input.cpp
new file mode 100644
index 00000000..52ba653f
--- /dev/null
+++ b/util/input/text-input.cpp
@@ -0,0 +1,207 @@
+#include "input-map.h"
+#include "text-input.h"
+#include "input-manager.h"
+#include <string.h>
+#include <sstream>
+#include <string>
+
+using namespace std;
+
+static const int Shift = 198;
+static const int Control = 199;
+static const int Backspace = 200;
+
+TextInput::TextInput(const string & start):
+InputMap<unsigned char>(),
+blockingKeys(false),
+enabled(false),
+handle(201){
+ const int delay = 100;
+ /*
+ set(Keyboard::Key_TILDE, delay * 2, false, Toggle);
+ set(Keyboard::Key_ESC, delay, false, Esc);
+ set(Keyboard::Key_ENTER, 0, false, Enter);
+ */
+
+ // set(Keyboard::Key_LCONTROL, 0, false, Control);
+ set(Keyboard::Key_BACKSPACE, delay, false, Backspace);
+ /*
+ set(Keyboard::Key_LSHIFT, 0, false, Shift);
+ set(Keyboard::Key_RSHIFT, 0, false, Shift);
+ */
+
+ text.str(start);
+ text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
+ text.clear();
+}
+
+int TextInput::nextHandle(){
+ int i = handle;
+ handle += 1;
+ return i;
+}
+
+void TextInput::addBlockingHandle(int key, callback function, void * data){
+ int handle = nextHandle();
+ set(key, 1, true, handle);
+ callbacks[handle] = Callback(function, data);
+}
+
+void TextInput::addHandle(int key, int delay, callback function, void * data){
+ int handle = nextHandle();
+ set(key, delay, false, handle);
+ callbacks[handle] = Callback(function, data);
+}
+
+bool TextInput::doInput(){
+ bool modified = false;
+ /* TODO: ensure these codes are consistent across platforms. So far
+ * they seem to work in windows xp and linux (ubuntu)
+ */
+ const Keyboard::unicode_t control_u = 21;
+ const Keyboard::unicode_t control_w = 23;
+
+ if (enabled){
+ vector<InputEvent> events = InputManager::getEvents(*this);
+
+ /* the order of reading input is arbitrary right now. I'm not
+ * sure it matters what order things are done in, but probably
+ * a few corner cases exist. When they come up please document them.
+ */
+
+ for (vector<InputEvent>::iterator it = events.begin(); it != events.end(); it++){
+ InputEvent event = *it;
+
+ if (event.enabled){
+ if (event.out == Backspace){
+ backspace();
+ modified = true;
+ }
+
+ if (callbacks.find(event.out) != callbacks.end()){
+ Callback & callback = callbacks[event.out];
+ callback.function(callback.data);
+ }
+
+ if (event.unicode == control_u){
+ clearInput();
+ modified = true;
+ }
+ if (event.unicode == control_w){
+ deleteLastWord();
+ modified = true;
+ }
+
+ /* FIXME: whats the maximum unicode value? */
+ if (event.unicode >= 32 && event.unicode < 0xffffff){
+ this->text << (unsigned char) event.unicode;
+ modified = true;
+ }
+ }
+ }
+ }
+
+ return modified;
+}
+
+void TextInput::enable(){
+ InputManager::captureInput(*this);
+ enabled = true;
+}
+
+void TextInput::disable(){
+ InputManager::releaseInput(*this);
+ enabled = false;
+}
+
+string TextInput::getText(){
+ return text.str();
+}
+
+/*
+void TextInput::clear(){
+ text.str("");
+ text.clear();
+}
+*/
+
+void TextInput::setText(const std::string & text){
+ this->text.str(text);
+ this->text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
+ this->text.clear();
+}
+
+void TextInput::clearInput(){
+ text.str(string());
+ text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
+ text.clear();
+}
+
+void TextInput::backspace(){
+ string now = text.str();
+ now = now.substr(0, now.size()-1);
+ text.str(now);
+ text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
+ text.clear();
+}
+
+void TextInput::deleteLastWord(){
+ string now = text.str();
+ // Global::debug(0) << "Delete last word '" << now << "'" << endl;
+
+ if (now.size() > 0){
+ if (now.at(now.size() - 1) != ' '){
+ int here = now.size() - 1;
+ while (here > 0 && now.at(here) != ' '){
+ here -= 1;
+ }
+ if (now.at(here) == ' '){
+ here += 1;
+ }
+ now.erase(here);
+ } else {
+ int here = now.size() - 1;
+ while (here > 0 && now.at(here) == ' '){
+ here -= 1;
+ }
+ if (here > 0){
+ while (here > 0 && now.at(here) != ' '){
+ here -= 1;
+ }
+ if (now.at(here) == ' '){
+ here += 1;
+ }
+ }
+ now.erase(here);
+ }
+ text.str(now);
+ text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
+ text.clear();
+ }
+
+ /*
+ size_t get = now.rfind(" ");
+ if (get != string::npos){
+ Global::debug(0) << "get " << get << " size " << now.size() << endl;
+ if (get == now.size() - 1){
+ get = now.find_last_not_of(' ');
+ get = now.rfind(' ', get);
+ if (get != string::npos){
+ get = 0;
+ }
+ now.erase(get + 1);
+ } else {
+ now = now.substr(0, get + 1);
+ }
+ text.str(now);
+ text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
+ text.clear();
+ } else {
+ clearInput();
+ }
+ */
+}
+
+TextInput::~TextInput(){
+ disable();
+}
diff --git a/util/input/text-input.h b/util/input/text-input.h
new file mode 100644
index 00000000..d37dabff
--- /dev/null
+++ b/util/input/text-input.h
@@ -0,0 +1,81 @@
+#ifndef _paintown_text_input_h
+#define _paintown_text_input_h
+
+#include "input-map.h"
+#include <sstream>
+#include <string>
+#include <map>
+
+typedef void (*callback)(void * arg);
+
+struct Callback{
+ Callback():
+ function(0),
+ data(0){
+ }
+
+ Callback(callback function, void * data):
+ function(function),
+ data(data){
+ }
+
+ callback function;
+ void * data;
+};
+
+class TextInput: public InputMap<unsigned char> {
+public:
+ TextInput(const std::string & start = "");
+
+ /* returns true if the text was modified */
+ bool doInput();
+ void enable();
+ void disable();
+
+ void addHandle(int key, int delay, callback function, void * data);
+ void addBlockingHandle(int key, callback function, void * data);
+
+ inline void setBlockingKeys(){
+ blockingKeys = true;
+ }
+
+ std::string getText();
+ void setText(const std::string & text);
+
+ void clearInput();
+ // void clear();
+
+ bool isEnabled() const {
+ return enabled;
+ }
+
+ void backspace();
+ void deleteLastWord();
+
+ virtual KeyState<unsigned char> * getState(int key){
+ KeyState<unsigned char> * state = InputMap<unsigned char>::getState(key);
+ if (state == NULL){
+ if (blockingKeys){
+ set(key, 0, true, key);
+ } else {
+ set(key, 10, false, key);
+ }
+ state = InputMap<unsigned char>::getState(key);
+ }
+ return state;
+ }
+
+ virtual ~TextInput();
+
+protected:
+ int nextHandle();
+
+ std::ostringstream text;
+ /* whether key repeat is on or off */
+ bool blockingKeys;
+ bool enabled;
+ std::map<int, Callback> callbacks;
+ int handle;
+};
+
+#endif
diff --git a/util/input/wii/joystick.cpp b/util/input/wii/joystick.cpp
new file mode 100644
index 00000000..256110b3
--- /dev/null
+++ b/util/input/wii/joystick.cpp
@@ -0,0 +1,139 @@
+#ifdef WII
+
+#include "joystick.h"
+
+#include <ogc/pad.h>
+#include <wiiuse/wpad.h>
+
+void WiiJoystick::poll(){
+ PAD_ScanPads();
+ WPAD_ScanPads();
+}
+
+JoystickInput WiiJoystick::readAll(){
+ JoystickInput input;
+ // Number passed should be a port 1-4 I believe same with gc pad this can be modified later for multiplayer
+
+ // Wii data
+ WPADData * wpad;
+ wpad = WPAD_Data(0);
+
+ // Gamecube
+ u16 gcheld = PAD_ButtonsHeld(0);
+
+ // Wii controller
+ if (wpad->exp.type == WPAD_EXP_CLASSIC){
+ // Classic controller
+ if(wpad->btns_h & WPAD_CLASSIC_BUTTON_UP){
+ input.up = true;
+ }
+ if(wpad->btns_h & WPAD_CLASSIC_BUTTON_DOWN){
+ input.down = true;
+ }
+ if(wpad->btns_h & WPAD_CLASSIC_BUTTON_LEFT){
+ input.left = true;
+ }
+ if(wpad->btns_h & WPAD_CLASSIC_BUTTON_RIGHT){
+ input.right = true;
+ }
+ } else if (wpad->exp.type == WPAD_EXP_NUNCHUK){
+ // With nunchuck
+ if(wpad->exp.nunchuk.js.pos.y >= 0xB0){
+ input.up = true;
+ }
+ if(wpad->exp.nunchuk.js.pos.y <= 0x40){
+ input.down = true;
+ }
+ if(wpad->exp.nunchuk.js.pos.x <= 0x40){
+ input.left = true;
+ }
+ if(wpad->exp.nunchuk.js.pos.x >= 0xB0){
+ input.right = true;
+ }
+ } else {
+ // No attachment
+ if(wpad->btns_h & WPAD_BUTTON_UP){
+ if(wpad->ir.valid){
+ input.up = true;
+ } else {
+ input.left = true;
+ }
+ }
+ if(wpad->btns_h & WPAD_BUTTON_DOWN){
+ if(wpad->ir.valid){
+ input.down = true;
+ } else {
+ input.right = true;
+ }
+ }
+ if(wpad->btns_h & WPAD_BUTTON_LEFT){
+ if(wpad->ir.valid){
+ input.left = true;
+ } else {
+ input.down = true;
+ }
+ }
+ if(wpad->btns_h & WPAD_BUTTON_RIGHT){
+ if(wpad->ir.valid){
+ input.right = true;
+ } else {
+ input.up = true;
+ }
+ }
+ }
+
+ // Gamecube controller
+ if(gcheld & PAD_BUTTON_UP){
+ input.up = true;
+ }
+ if(gcheld & PAD_BUTTON_DOWN){
+ input.down = true;
+ }
+ if(gcheld & PAD_BUTTON_LEFT){
+ input.left = true;
+ }
+ if(gcheld & PAD_BUTTON_RIGHT){
+ input.right = true;
+ }
+
+ // Check all input buttons
+ if (wpad->btns_h & WPAD_CLASSIC_BUTTON_X || wpad->btns_h & WPAD_BUTTON_1 || gcheld & PAD_BUTTON_X){
+ input.button1 = true;
+ }
+ if (wpad->btns_h & WPAD_CLASSIC_BUTTON_Y || wpad->btns_h & WPAD_BUTTON_2 || gcheld & PAD_BUTTON_Y){
+ input.button2 = true;
+ }
+ if (wpad->btns_h & WPAD_CLASSIC_BUTTON_A || wpad->btns_h & WPAD_BUTTON_A || gcheld & PAD_BUTTON_A){
+ input.button3 = true;
+ }
+ if (wpad->btns_h & WPAD_CLASSIC_BUTTON_B || wpad->btns_h & WPAD_BUTTON_B || gcheld & PAD_BUTTON_B){
+ input.button4 = true;
+ }
+ if (wpad->btns_h & WPAD_CLASSIC_BUTTON_PLUS || wpad->btns_h & WPAD_BUTTON_PLUS || gcheld & PAD_BUTTON_START){
+ // enter
+ }
+ if (wpad->btns_h & WPAD_CLASSIC_BUTTON_HOME || wpad->btns_h & WPAD_BUTTON_HOME || gcheld & PAD_BUTTON_MENU){
+ // esc
+ }
+ if (wpad->btns_h & WPAD_CLASSIC_BUTTON_MINUS || wpad->btns_h & WPAD_BUTTON_MINUS){
+ // ?
+ }
+
+ return input;
+}
+
+int WiiJoystick::getDeviceId() const {
+ /* FIXME! Figure out the device id */
+ return 0;
+}
+
+WiiJoystick::~WiiJoystick(){
+ WPAD_Shutdown();
+}
+
+WiiJoystick::WiiJoystick(){
+ WPAD_Init();
+ PAD_Init();
+}
+
+#endif
diff --git a/util/input/wii/joystick.h b/util/input/wii/joystick.h
new file mode 100644
index 00000000..6c3a9ca5
--- /dev/null
+++ b/util/input/wii/joystick.h
@@ -0,0 +1,23 @@
+#ifndef _paintown_wii_joystick_h
+#define _paintown_wii_joystick_h
+
+#ifdef WII
+
+#include "../joystick.h"
+
+class WiiJoystick: public Joystick {
+public:
+ virtual void poll();
+ virtual JoystickInput readAll();
+ virtual int getDeviceId() const;
+
+ virtual ~WiiJoystick();
+
+ friend class Joystick;
+protected:
+ WiiJoystick();
+};
+
+#endif
+
+#endif

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jun 11, 11:48 AM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
68869
Default Alt Text
(101 KB)

Event Timeline