Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
35 KB
Referenced Files
None
Subscribers
None
diff --git a/util/events.cpp b/util/events.cpp
index 5ee46b7e..18895a56 100644
--- a/util/events.cpp
+++ b/util/events.cpp
@@ -1,494 +1,500 @@
#ifdef USE_SDL
#include <SDL.h>
#endif
#ifdef USE_ALLEGRO5
#include <allegro5/allegro.h>
#endif
#include <vector>
#include "bitmap.h"
#include "events.h"
#include "exceptions/shutdown_exception.h"
#include "configuration.h"
#include "debug.h"
#include "funcs.h"
#include "thread.h"
#include "init.h"
#include "parameter.h"
#include "input/keyboard.h"
#include "input/joystick.h"
#include "input/input-manager.h"
namespace Util{
EventManager::EventManager():
bufferKeys(false){
#ifdef USE_ALLEGRO5
queue = al_create_event_queue();
if (al_is_keyboard_installed()){
al_register_event_source(queue, al_get_keyboard_event_source());
}
if (Graphics::the_display != NULL){
al_register_event_source(queue, al_get_display_event_source(Graphics::the_display));
}
#endif
}
#ifdef USE_SDL
static void handleKeyDown(Keyboard & keyboard, const SDL_Event & event){
keyboard.press(event.key.keysym.sym, event.key.keysym.unicode);
}
static void handleKeyUp(Keyboard & keyboard, const SDL_Event & event){
keyboard.release(event.key.keysym.sym);
}
static void handleJoystickButtonUp(Joystick * joystick, const SDL_Event & event){
int device = event.jbutton.which;
int button = event.jbutton.button;
if (device == joystick->getDeviceId()){
joystick->releaseButton(button);
}
}
static void handleJoystickHat(Joystick * joystick, const SDL_Event & event){
int device = event.jhat.which;
int motion = event.jhat.value;
+ if (device == joystick->getDeviceId()){
+ joystick->hatMotion(motion);
+ }
+
+#if 0
/* should up/down control left/right -- flip these values? */
#if WII
const int axis_up_down = 0;
const int axis_left_right = 1;
const int up = 1;
const int down = -1;
const int left = -1;
const int right = 1;
#else
const int axis_up_down = 1;
const int axis_left_right = 0;
const int up = -1;
const int down = 1;
const int left = -1;
const int right = 1;
#endif
switch (motion){
case SDL_HAT_CENTERED: break;
case SDL_HAT_UP: joystick->axisMotion(axis_up_down, up); break;
case SDL_HAT_DOWN: joystick->axisMotion(axis_up_down, down); break;
case SDL_HAT_RIGHT: joystick->axisMotion(axis_left_right, right); break;
case SDL_HAT_LEFT: joystick->axisMotion(axis_left_right, left); break;
default: break;
}
+#endif
}
static void handleJoystickButtonDown(Joystick * joystick, const SDL_Event & event){
int device = event.jbutton.which;
int button = event.jbutton.button;
if (device == joystick->getDeviceId()){
joystick->pressButton(button);
}
}
static void handleJoystickAxis(Joystick * joystick, const SDL_Event & event){
int device = event.jaxis.which;
int axis = event.jaxis.axis;
int value = event.jaxis.value;
if (device == joystick->getDeviceId()){
joystick->axisMotion(axis, value);
}
}
void EventManager::runSDL(Keyboard & keyboard, Joystick * joystick){
keyboard.poll();
if (joystick){
joystick->poll();
}
SDL_Event event;
while (SDL_PollEvent(&event) == 1){
switch (event.type){
case SDL_QUIT : {
dispatch(CloseWindow);
break;
}
case SDL_KEYDOWN : {
handleKeyDown(keyboard, event);
// dispatch(Key, event.key.keysym.sym);
break;
}
case SDL_KEYUP : {
handleKeyUp(keyboard, event);
break;
}
case SDL_JOYBUTTONDOWN: {
if (joystick != NULL){
handleJoystickButtonDown(joystick, event);
}
break;
}
case SDL_JOYHATMOTION : {
if (joystick != NULL){
handleJoystickHat(joystick, event);
}
break;
}
case SDL_JOYBUTTONUP: {
if (joystick != NULL){
handleJoystickButtonUp(joystick, event);
}
break;
}
case SDL_JOYAXISMOTION: {
if (joystick != NULL){
handleJoystickAxis(joystick, event);
}
break;
}
case SDL_VIDEORESIZE : {
int width = event.resize.w;
int height = event.resize.h;
/* to keep the perspective correct
* 640/480 = 1.33333
*/
double ratio = (double) GFX_X / (double) GFX_Y;
if (width > height){
height = (int)((double) width / ratio);
} else {
width = (int)((double) height * ratio);
}
dispatch(ResizeScreen, width, height);
break;
}
default : {
break;
}
}
}
}
#endif
#ifdef USE_ALLEGRO
void EventManager::runAllegro(Keyboard & keyboard, Joystick * joystick){
keyboard.poll();
}
#endif
#ifdef USE_ALLEGRO5
static void handleKeyDown(Keyboard & keyboard, const ALLEGRO_EVENT & event){
keyboard.press(event.keyboard.keycode, event.keyboard.unichar);
}
static void handleKeyUp(Keyboard & keyboard, const ALLEGRO_EVENT & event){
keyboard.release(event.keyboard.keycode);
}
static void handleResize(const ALLEGRO_EVENT & event){
double width = event.display.width;
double height = event.display.height;
if (width < GFX_X){
width = GFX_X;
}
if (height < GFX_Y){
height = GFX_Y;
}
/* to keep the perspective correct
* 640/480 = 1.33333
*/
double ratio = (double) GFX_X / (double) GFX_Y;
if (width > height){
height = width / ratio;
} else {
width = height * ratio;
}
ALLEGRO_DISPLAY * display = event.display.source;
al_acknowledge_resize(display);
al_resize_display(display, (int) width, (int) height);
ALLEGRO_TRANSFORM transformation;
al_identity_transform(&transformation);
// al_scale_transform(&transformation, (double) al_get_display_width(display) / (double) GFX_X, (double) al_get_display_height(display) / (double) GFX_Y);
al_scale_transform(&transformation, (double) width / (double) GFX_X, (double) height / (double) GFX_Y);
al_set_target_bitmap(Graphics::getScreenBuffer().getData()->getBitmap());
al_use_transform(&transformation);
}
void EventManager::runAllegro5(Keyboard & keyboard, Joystick * joystick){
keyboard.poll();
ALLEGRO_EVENT event;
while (al_get_next_event(queue, &event)){
switch (event.type){
/*
case ALLEGRO_EVENT_KEY_DOWN: {
Global::debug(0) << "Key down " << event.keyboard.keycode << std::endl;
handleKeyDown(keyboard, event);
break;
}
*/
case ALLEGRO_EVENT_DISPLAY_RESIZE: {
handleResize(event);
break;
}
case ALLEGRO_EVENT_KEY_UP: {
handleKeyUp(keyboard, event);
break;
}
case ALLEGRO_EVENT_KEY_CHAR : {
// Global::debug(0) << "Key char " << event.keyboard.keycode << " unicode " << event.keyboard.unichar << std::endl;
handleKeyDown(keyboard, event);
break;
}
}
}
/*
if (joystick){
joystick->poll();
}
SDL_Event event;
while (SDL_PollEvent(&event) == 1){
switch (event.type){
case SDL_QUIT : {
dispatch(CloseWindow);
break;
}
case SDL_KEYDOWN : {
handleKeyDown(keyboard, event);
// dispatch(Key, event.key.keysym.sym);
break;
}
case SDL_KEYUP : {
handleKeyUp(keyboard, event);
break;
}
case SDL_JOYBUTTONDOWN: {
if (joystick != NULL){
handleJoystickButtonDown(joystick, event);
}
break;
}
case SDL_JOYHATMOTION : {
if (joystick != NULL){
handleJoystickHat(joystick, event);
}
break;
}
case SDL_JOYBUTTONUP: {
if (joystick != NULL){
handleJoystickButtonUp(joystick, event);
}
break;
}
case SDL_JOYAXISMOTION: {
if (joystick != NULL){
handleJoystickAxis(joystick, event);
}
break;
}
case SDL_VIDEORESIZE : {
int width = event.resize.w;
int height = event.resize.h;
/ * to keep the perspective correct
* 640/480 = 1.33333
* /
if (width > height){
height = (int)((double) width / 1.3333333333);
} else {
width = (int)((double) height * 1.3333333333);
}
dispatch(ResizeScreen, width, height);
break;
}
default : {
break;
}
}
}
*/
}
#endif
void EventManager::run(Keyboard & keyboard, Joystick * joystick){
#ifdef USE_SDL
runSDL(keyboard, joystick);
#elif USE_ALLEGRO
runAllegro(keyboard, joystick);
#elif USE_ALLEGRO5
runAllegro5(keyboard, joystick);
#endif
}
/* kill the program if the user requests */
void EventManager::waitForThread(WaitThread & thread){
// Keyboard dummy;
while (!thread.isRunning()){
try{
/* input manager will run the event manager */
InputManager::poll();
// run(dummy);
} catch (const ShutdownException & death){
thread.kill();
throw death;
}
Util::rest(10);
}
}
EventManager::~EventManager(){
#ifdef USE_ALLEGRO5
al_destroy_event_queue(queue);
#endif
}
void EventManager::enableKeyBuffer(){
bufferKeys = true;
}
void EventManager::disableKeyBuffer(){
bufferKeys = false;
}
void EventManager::dispatch(Event type, int arg1){
switch (type){
case Key : {
if (bufferKeys){
keys.push_back(KeyType(arg1));
}
break;
}
default : {
break;
}
}
}
void EventManager::dispatch(Event type, int arg1, int arg2){
switch (type){
case ResizeScreen : {
Global::debug(1) << "Resizing screen to " << arg1 << ", " << arg2 << std::endl;
if (Graphics::setGraphicsMode(0, arg1, arg2) == 0){
Configuration::setScreenWidth(arg1);
Configuration::setScreenHeight(arg2);
}
break;
}
default : break;
}
}
void EventManager::dispatch(Event type){
switch (type){
case CloseWindow : {
throw ShutdownException();
}
default : break;
}
}
class LoopDone: public std::exception {
public:
LoopDone(){
}
~LoopDone() throw () {
}
};
Logic::~Logic(){
}
Draw::Draw():
frames(0),
second_counter(Global::second_counter),
fps(0){
}
void Draw::drawFirst(const Graphics::Bitmap & screen){
}
Draw::~Draw(){
}
double Draw::getFps() const {
return fps;
}
void Draw::updateFrames(){
if (second_counter != Global::second_counter){
int difference = Global::second_counter - second_counter;
double alpha = 0.2;
/* unlikely, but just in case */
if (difference == 0){
difference = 1;
}
fps = (alpha * fps) + ((1 - alpha) * (double) frames / difference);
// fps[fps_index] = (double) frames / (double) difference;
// fps_index = (fps_index+1) % max_fps_index;
second_counter = Global::second_counter;
frames = 0;
}
frames += 1;
}
static void doStandardLoop(Logic & logic, Draw & draw){
const Graphics::Bitmap & screen = *Graphics::screenParameter.current();
draw.drawFirst(screen);
Global::speed_counter4 = 0;
double runCounter = 0;
try{
while (!logic.done()){
if (Global::speed_counter4 > 0){
// Global::debug(0) << "Speed counter " << Global::speed_counter4 << std::endl;
runCounter += logic.ticks(Global::speed_counter4);
Global::speed_counter4 = 0;
bool need_draw = false;
while (runCounter >= 1.0){
need_draw = true;
InputManager::poll();
runCounter -= 1;
logic.run();
if (Global::shutdown()){
throw ShutdownException();
}
if (logic.done()){
/* quit the loop immediately */
throw LoopDone();
}
}
if (need_draw){
draw.updateFrames();
draw.draw(screen);
}
}
while (Global::speed_counter4 == 0){
/* if the fps is limited then don't keep redrawing */
if (Global::rateLimit){
rest(1);
} else {
draw.updateFrames();
draw.draw(screen);
}
}
}
} catch (const LoopDone & done){
}
}
void standardLoop(Logic & logic, Draw & draw){
/* if a screen already exists (because we have nested standardLoops) then
* leave this parameter alone, otherwise set a new parameter.
*/
/*
if (Parameter<Graphics::Bitmap*>::current() == NULL){
doStandardLoop(logic, draw);
} else {
doStandardLoop(logic, draw);
}
*/
doStandardLoop(logic, draw);
}
}
diff --git a/util/input/joystick.cpp b/util/input/joystick.cpp
index f082d191..78744046 100644
--- a/util/input/joystick.cpp
+++ b/util/input/joystick.cpp
@@ -1,83 +1,88 @@
#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;
*/
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 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 Button5: return "Button5";
+ case Button6: return "Button6";
case Quit: return "Quit";
}
return "Unknown";
}
void Joystick::pressButton(int button){
}
void Joystick::releaseButton(int button){
}
void Joystick::axisMotion(int axis, int motion){
}
+
+void Joystick::hatMotion(int motion){
+}
diff --git a/util/input/joystick.h b/util/input/joystick.h
index 2192a2fd..4d8802a1 100644
--- a/util/input/joystick.h
+++ b/util/input/joystick.h
@@ -1,107 +1,108 @@
#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),
button5(false),
button6(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),
button5(copy.button5),
button6(copy.button6),
quit(copy.quit){
}
/* true if something is pressed */
bool pressed(){
return left || right || up || down ||
button1 || button2 || button3 || button4 ||
button5 || button6 ||
quit;
}
bool left;
bool right;
bool up;
bool down;
bool button1;
bool button2;
bool button3;
bool button4;
bool button5;
bool button6;
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);
+ virtual void hatMotion(int motion);
static Joystick * create();
enum Key{
Invalid = -1,
Up = 0,
Down,
Left,
Right,
Button1,
Button2,
Button3,
Button4,
Button5,
Button6,
Quit,
};
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 40efac84..4f5961af 100644
--- a/util/input/sdl/joystick.cpp
+++ b/util/input/sdl/joystick.cpp
@@ -1,419 +1,528 @@
#ifdef USE_SDL
#include <SDL.h>
#include "joystick.h"
#include "util/debug.h"
#include <string>
#include <vector>
using std::string;
using std::vector;
class ButtonMapping{
public:
ButtonMapping(){
}
virtual ~ButtonMapping(){
}
virtual int toNative(int button) = 0;
virtual int fromNative(int button) = 0;
virtual Joystick::Key toKey(int button) = 0;
virtual void axisMotionEvents(int axis, int motion, vector<Joystick::Event> & events) = 0;
+ virtual void hatMotionEvents(int motion, vector<Joystick::Event> & events) = 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;
case 5: return Joystick::Button5;
case 6: return Joystick::Button6;
default: return Joystick::Invalid;
}
}
+
+ virtual void hatMotionEvents(int motion, vector<Joystick::Event> & events){
+ }
void axisMotionEvents(int axis, int motion, vector<Joystick::Event> & events){
/* 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;
}
}
*/
}
};
/* 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 L1: return Joystick::Button5;
case R1: return Joystick::Button6;
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 */
void axisMotionEvents(int axis, int motion, vector<Joystick::Event> & events){
}
+
+ virtual void hatMotionEvents(int motion, vector<Joystick::Event> & events){
+ }
};
class LogitechPrecision: public ButtonMapping {
public:
enum Buttons{
Button1 = 0,
Button2 = 1,
Button3 = 2,
Button4 = 3,
Start = 8,
Select = 9,
R2 = 7,
R1 = 5,
L2 = 6,
L1 = 4
};
int toNative(int button){
return -1;
}
int fromNative(int button){
return -1;
}
Joystick::Key toKey(int button){
switch (button){
case Button1: return Joystick::Button1;
case Button2: return Joystick::Button2;
case Button3: return Joystick::Button3;
case Button4: return Joystick::Button4;
case L1: return Joystick::Button5;
case R1: return Joystick::Button6;
case Start: return Joystick::Quit;
}
return Joystick::Invalid;
}
/* axis 1. negative up, positive down
* axis 0, negative left, positive right
*/
void axisMotionEvents(int axis, int motion, vector<Joystick::Event> & events){
if (axis == 0){
if (motion < 0){
events.push_back(Joystick::Event(Joystick::Left, true));
} else if (motion > 0){
events.push_back(Joystick::Event(Joystick::Right, true));
} else if (motion == 0){
/* fake a release for left and right */
events.push_back(Joystick::Event(Joystick::Left, false));
events.push_back(Joystick::Event(Joystick::Right, false));
}
} else if (axis == 1){
if (motion < 0){
events.push_back(Joystick::Event(Joystick::Up, true));
} else if (motion > 0){
events.push_back(Joystick::Event(Joystick::Down, true));
} else if (motion == 0){
events.push_back(Joystick::Event(Joystick::Up, false));
events.push_back(Joystick::Event(Joystick::Down, false));
}
}
}
+
+ virtual void hatMotionEvents(int motion, vector<Joystick::Event> & events){
+ }
};
/* 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,
L1 = 13,
R1 = 12,
L2 = 15,
R2 = 14,
L3 = 6,
R3 = 5
};
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 L1: return Joystick::Button5;
case R1: return Joystick::Button6;
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 */
void axisMotionEvents(int axis, int motion, vector<Joystick::Event> & events){
}
+
+ virtual void hatMotionEvents(int motion, vector<Joystick::Event> & events){
+ }
+};
+
+class XBox360Controller: public ButtonMapping {
+public:
+ enum Buttons{
+ A = 0,
+ B = 1,
+ X = 2,
+ Y = 3,
+ L1 = 4,
+ R1 = 5,
+ Start = 6,
+ Xbox = 7,
+ L3 = 8,
+ R3 = 9,
+ select = 10
+ };
+
+ int toNative(int button){
+ return 0;
+ }
+
+ int fromNative(int button){
+ return 0;
+ }
+
+ Joystick::Key toKey(int button){
+ switch (button){
+ case A: return Joystick::Button1;
+ case B: return Joystick::Button2;
+ case X: return Joystick::Button3;
+ case Y: return Joystick::Button4;
+ case L1: return Joystick::Button5;
+ case R1: return Joystick::Button6;
+ case Start: return Joystick::Quit;
+ }
+ return Joystick::Invalid;
+ }
+
+ void axisMotionEvents(int axis, int motion, vector<Joystick::Event> & events){
+ /* axis 6 and 7 are the hats. sdl passes them as hat events */
+ #if 0
+ if (axis == 6){
+ if (motion < 0){
+ events.push_back(Joystick::Event(Joystick::Left, true));
+ } else if (motion > 0){
+ events.push_back(Joystick::Event(Joystick::Right, true));
+ } else if (motion == 0){
+ /* fake a release for left and right */
+ events.push_back(Joystick::Event(Joystick::Left, false));
+ events.push_back(Joystick::Event(Joystick::Right, false));
+ }
+ } else if (axis == 7){
+ if (motion < 0){
+ events.push_back(Joystick::Event(Joystick::Up, true));
+ } else if (motion > 0){
+ events.push_back(Joystick::Event(Joystick::Down, true));
+ } else if (motion == 0){
+ events.push_back(Joystick::Event(Joystick::Up, false));
+ events.push_back(Joystick::Event(Joystick::Down, false));
+ }
+ }
+ #endif
+ }
+
+ virtual void hatMotionEvents(int motion, vector<Joystick::Event> & events){
+ bool up = false;
+ bool down = false;
+ bool left = false;
+ bool right = false;
+ switch (motion){
+ case SDL_HAT_CENTERED: break;
+ case SDL_HAT_UP: up = true; break;
+ case SDL_HAT_RIGHT: right = true; break;
+ case SDL_HAT_DOWN: down = true; break;
+ case SDL_HAT_LEFT: left = true; break;
+ case SDL_HAT_RIGHTUP: right = true; up = true; break;
+ case SDL_HAT_RIGHTDOWN: right = true; down = true; break;
+ case SDL_HAT_LEFTUP: left = true; up = true; break;
+ case SDL_HAT_LEFTDOWN: left = true; down = true; break;
+ }
+
+ events.push_back(Joystick::Event(Joystick::Left, left));
+ events.push_back(Joystick::Event(Joystick::Right, right));
+ events.push_back(Joystick::Event(Joystick::Down, down));
+ events.push_back(Joystick::Event(Joystick::Up, up));
+ }
};
ButtonMapping * makeButtonMapping(string name){
#ifdef PS3
return new Ps3Controller();
#endif
if (name == "Sony PLAYSTATION(R)3 Controller"){
return new Playstation3Controller();
}
if (name == "Logitech Logitech(R) Precision(TM) Gamepad"){
return new LogitechPrecision();
}
+ if (name == "Microsoft X-Box 360 pad"){
+ return new XBox360Controller();
+ }
return new DefaultButtonMapping();
}
void SDLJoystick::poll(){
events.clear();
}
static bool read_button(SDL_Joystick * joystick, int button){
return SDL_JoystickGetButton(joystick, button);
}
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, 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){
Key event = buttonMapping->toKey(button);
if (event != Invalid){
events.push_back(Event(event, true));
}
}
}
void SDLJoystick::releaseButton(int button){
if (joystick){
Key event = buttonMapping->toKey(button);
if (event != Invalid){
events.push_back(Event(event, false));
}
}
}
+void SDLJoystick::hatMotion(int motion){
+ if (joystick){
+ buttonMapping->hatMotionEvents(motion, events);
+ }
+}
+
void SDLJoystick::axisMotion(int axis, int motion){
// Global::debug(0) << "Axis motion on " << axis << " motion " << motion << std::endl;
if (joystick){
buttonMapping->axisMotionEvents(axis, motion, events);
/*
Event move = buttonMapping->axisMotionToEvent(axis, motion);
if (move.key != Invalid){
events.push_back(move);
}
*/
}
}
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 88381e86..380f7a15 100644
--- a/util/input/sdl/joystick.h
+++ b/util/input/sdl/joystick.h
@@ -1,36 +1,37 @@
#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 void hatMotion(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:20 AM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
68366
Default Alt Text
(35 KB)

Event Timeline