Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
23 KB
Referenced Files
None
Subscribers
None
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

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)

Event Timeline