Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F126000
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
23 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/util/input/input-manager.h b/util/input/input-manager.h
index f37bb09c..dda353f8 100644
--- a/util/input/input-manager.h
+++ b/util/input/input-manager.h
@@ -1,287 +1,287 @@
#ifndef _paintown_input_manager
#define _paintown_input_manager
#include <vector>
#include <algorithm>
#include "input.h"
#include "input-map.h"
#include "util/funcs.h"
#include "util/events.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);
+ JoystickState<X> * state = input.getJoystickState(event.key);
if (state != NULL){
- events.push_back(typename InputMap<X>::InputEvent(state->out, -1, true));
+ events.push_back(typename InputMap<X>::InputEvent(state->out, -1, event.enabled));
}
}
}
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;
Util::EventManager eventManager;
// std::vector<int> bufferedKeys;
// bool bufferKeys;
};
#endif
diff --git a/util/input/joystick.h b/util/input/joystick.h
index f08324ed..97517321 100644
--- a/util/input/joystick.h
+++ b/util/input/joystick.h
@@ -1,91 +1,98 @@
#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;
+ struct Event{
+ Event(Key key, bool enabled):
+ key(key), enabled(enabled){
+ }
+
+ Key key;
+ bool enabled;
+ };
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/sdl/joystick.cpp b/util/input/sdl/joystick.cpp
index b62735d1..6317188a 100644
--- a/util/input/sdl/joystick.cpp
+++ b/util/input/sdl/joystick.cpp
@@ -1,175 +1,338 @@
#ifdef USE_SDL
#include <SDL.h>
#include "joystick.h"
+#include "util/debug.h"
+#include <string>
-void SDLJoystick::poll(){
- events.clear();
-}
+using std::string;
-static bool read_button(SDL_Joystick * joystick, int button){
- return SDL_JoystickGetButton(joystick, button);
-}
+class ButtonMapping{
+public:
+ ButtonMapping(){
+ }
-#ifdef PS3
-static int to_native_button(int button){
- switch (button){
- case 0: return 8;
- case 1: return 9;
- case 2: return 10;
- case 3: return 11;
- case 4: return 4;
- }
- return button;
-}
+ virtual ~ButtonMapping(){
+ }
+
+ virtual int toNative(int button) = 0;
+ virtual int fromNative(int button) = 0;
+ virtual Joystick::Key toKey(int button) = 0;
+ virtual Joystick::Key axisMotionToKey(int axis, int motion) = 0;
+};
+
+class DefaultButtonMapping: public ButtonMapping {
+public:
+ int toNative(int button){
+ return button;
+ }
+
+ int fromNative(int button){
+ return button;
+ }
+
+ Joystick::Key toKey(int button){
+ switch (button){
+ case 0: return Joystick::Button1;
+ case 1: return Joystick::Button2;
+ case 2: return Joystick::Button3;
+ case 3: return Joystick::Button4;
+ case 4: return Joystick::Quit;
+ default: return Joystick::Invalid;
+ }
+ }
+
+ Joystick::Key axisMotionToKey(int axis, int motion){
+ /* FIXME */
+ /*
+ if (axis == 0){
+ if (motion < 0){
+ return Joystick::Left;
+ } else if (motion > 0){
+ return Joystick::Right;
+ }
+ } else if (axis == 1){
+ if (motion < 0){
+ return Joystick::Up;
+ } else if (motion > 0){
+ return Joystick::Down;
+ }
+ }
+ */
+
+ return Joystick::Invalid;
+ }
+};
+
+/* used when a ps3 controller is plugged into a usb port of a normal pc */
+class Playstation3Controller: public ButtonMapping {
+public:
+ enum Buttons{
+ Cross = 14,
+ Circle = 13,
+ Triangle = 12,
+ Square = 15,
+ Start = 3,
+ Select = 0,
+ Up = 4,
+ Left = 7,
+ Down = 6,
+ Right = 5,
+ Stick1 = 1,
+ Stick2 = 2,
+ L2 = 8,
+ L1 = 10,
+ R2 = 9,
+ R1 = 11,
+ /* the middle ps3 button */
+ Ps3 = 16
+ };
+
+ int toNative(int button){
+ switch (button){
+ case 0: return Square;
+ case 1: return Cross;
+ case 2: return Circle;
+ case 3: return Triangle;
+ case 4: return Start;
+ }
+
+ return button;
+ }
+
+ int fromNative(int button){
+ switch (button){
+ case Square: return 0;
+ case Cross: return 1;
+ case Circle: return 2;
+ case Triangle: return 3;
+ case Start: return Start;
+ default: return 5;
+ }
+
+ return button;
+ }
+
+ Joystick::Key toKey(int button){
+ switch (button){
+ case Square: return Joystick::Button1;
+ case Cross: return Joystick::Button2;
+ case Circle: return Joystick::Button3;
+ case Triangle: return Joystick::Button4;
+ case Start: return Joystick::Quit;
+ case Up: return Joystick::Up;
+ case Down: return Joystick::Down;
+ case Left: return Joystick::Left;
+ case Right: return Joystick::Right;
+ default: return Joystick::Invalid;
+ }
+ }
+
+ /* TODO */
+ Joystick::Key axisMotionToKey(int axis, int motion){
+ return Joystick::Invalid;
+ }
+};
+
+/* used for the ps3 controller with psl1ght's SDL version */
+class Ps3Controller: public ButtonMapping {
+public:
+ enum Buttons{
+ Left = 0,
+ Down = 1,
+ Right = 2,
+ Up = 3,
+ Select = 7,
+ Start = 4,
+ Square = 8,
+ Cross = 9,
+ Circle = 10,
+ Triangle = 11
+ };
+
+ int toNative(int button){
+ switch (button){
+ case 0: return Square;
+ case 1: return Cross;
+ case 2: return Circle;
+ case 3: return Triangle;
+ case 4: return Start;
+ }
+ return button;
+ }
-static int from_native_button(int button){
- switch (button){
- case 8: return 0;
- case 9: return 1;
- case 10: return 2;
- case 11: return 3;
- case 4: return 4;
- default: return 5;
+ int fromNative(int button){
+ switch (button){
+ case Square: return 0;
+ case Cross: return 1;
+ case Circle: return 2;
+ case Triangle: return 3;
+ case Start: return Start;
+ default: return 5;
+ }
+ return button;
+ }
+
+ Joystick::Key toKey(int button){
+ switch (button){
+ case Square: return Joystick::Button1;
+ case Cross: return Joystick::Button2;
+ case Circle: return Joystick::Button3;
+ case Triangle: return Joystick::Button4;
+ case Start: return Joystick::Quit;
+ case Up: return Joystick::Up;
+ case Down: return Joystick::Down;
+ case Left: return Joystick::Left;
+ case Right: return Joystick::Right;
+ default: return Joystick::Invalid;
+ }
+ }
+
+ /* TODO */
+ Joystick::Key axisMotionToKey(int axis, int motion){
+ return Joystick::Invalid;
+ }
+};
+
+ButtonMapping * makeButtonMapping(string name){
+#ifdef PS3
+ return new Ps3Controller();
+#endif
+ if (name == "Sony PLAYSTATION(R)3 Controller"){
+ return new Playstation3Controller();
}
- return button;
+ return new DefaultButtonMapping();
}
-#else
-static int to_native_button(int button){
- return button;
+
+void SDLJoystick::poll(){
+ events.clear();
}
-static int from_native_button(int button){
- return button;
+static bool read_button(SDL_Joystick * joystick, int button){
+ return SDL_JoystickGetButton(joystick, button);
}
-#endif
JoystickInput SDLJoystick::readAll(){
JoystickInput input;
+ return input;
if (joystick){
int buttons = SDL_JoystickNumButtons(joystick);
switch (buttons > 5 ? 5 : buttons){
- case 5: input.quit = read_button(joystick, to_native_button(4));
- case 4: input.button4 = read_button(joystick, to_native_button(3));
- case 3: input.button3 = read_button(joystick, to_native_button(2));
- case 2: input.button2 = read_button(joystick, to_native_button(1));
- case 1: input.button1 = read_button(joystick, to_native_button(0));
+ case 5: input.quit = read_button(joystick, buttonMapping->toNative(4));
+ case 4: input.button4 = read_button(joystick, buttonMapping->toNative(3));
+ case 3: input.button3 = read_button(joystick, buttonMapping->toNative(2));
+ case 2: input.button2 = read_button(joystick, buttonMapping->toNative(1));
+ case 1: input.button1 = read_button(joystick, buttonMapping->toNative(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);
+ Global::debug(1) << "Opened joystick '" << SDL_JoystickName(0) << "'" << std::endl;
+ buttonMapping = makeButtonMapping(SDL_JoystickName(0));
}
}
void SDLJoystick::pressButton(int button){
+ // Global::debug(0) << "Pressed button " << button << std::endl;
if (joystick){
- Event event = Invalid;
- switch (from_native_button(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;
+ Key event = buttonMapping->toKey(button);
+ if (event != Invalid){
+ events.push_back(Event(event, true));
}
- events.push_back(event);
}
}
void SDLJoystick::releaseButton(int button){
+ if (joystick){
+ Key event = buttonMapping->toKey(button);
+ if (event != Invalid){
+ events.push_back(Event(event, false));
+ }
+ }
}
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);
- }
+ Key move = buttonMapping->axisMotionToKey(axis, motion);
+ if (move != Invalid){
+ events.push_back(Event(move, true));
}
}
}
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
index cf4c3d32..88381e86 100644
--- a/util/input/sdl/joystick.h
+++ b/util/input/sdl/joystick.h
@@ -1,28 +1,36 @@
#ifndef _paintown_sdl_joystick_h
#define _paintown_sdl_joystick_h
#ifdef USE_SDL
#include <SDL.h>
#include "../joystick.h"
+#include "util/pointer.h"
+
+class ButtonMapping;
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:
+ /* convert buttons between what paintown wants and what sdl wants */
+ int to_native_button(int button);
+ int from_native_button(int button);
+
SDLJoystick();
SDL_Joystick * joystick;
+ Util::ReferenceCount<ButtonMapping> buttonMapping;
};
#endif
#endif
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Jun 11, 10:21 AM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
68372
Default Alt Text
(23 KB)
Attached To
Mode
R75 R-Tech1
Attached
Detach File
Event Timeline