From fb0d7139f24127049ae4ac9307198ccc3bcc7ea6 Mon Sep 17 00:00:00 2001 From: 3kinox Date: Wed, 14 Oct 2015 15:05:02 +0200 Subject: [PATCH] onepad: + Isolate every SDL code paths and replace any call to them by call to a generic class "GamePad" of which JoystickInfo is now a child. + Now backends can be added by inheriting GamePad generic class. + There is just one function change which is redundant with next commits but otherwise commit will not compile(which is more evil). --- plugins/onepad/CMakeLists.txt | 12 ++- plugins/onepad/GamePad.cpp | 42 ++++++++ plugins/onepad/GamePad.h | 139 ++++++++++++++++++++++++++ plugins/onepad/Linux/dialog.cpp | 20 ++-- plugins/onepad/Linux/ini.cpp | 10 +- plugins/onepad/Linux/linux.cpp | 28 +++--- plugins/onepad/{ => SDL}/joystick.cpp | 42 ++++---- plugins/onepad/{ => SDL}/joystick.h | 30 +++--- plugins/onepad/controller.h | 2 +- plugins/onepad/onepad.cpp | 8 +- plugins/onepad/onepad.h | 2 +- 11 files changed, 255 insertions(+), 80 deletions(-) create mode 100644 plugins/onepad/GamePad.cpp create mode 100644 plugins/onepad/GamePad.h rename plugins/onepad/{ => SDL}/joystick.cpp (90%) rename plugins/onepad/{ => SDL}/joystick.h (90%) diff --git a/plugins/onepad/CMakeLists.txt b/plugins/onepad/CMakeLists.txt index 68ffb82df2..b0c93908c7 100644 --- a/plugins/onepad/CMakeLists.txt +++ b/plugins/onepad/CMakeLists.txt @@ -13,18 +13,20 @@ set(onepadFinalFlags "") # onepad sources set(onepadSources controller.cpp - joystick.cpp + GamePad.cpp + SDL/joystick.cpp keyboard.cpp - KeyStatus.cpp + KeyStatus.cpp onepad.cpp) # onepad headers set(onepadHeaders bitwise.h controller.h - joystick.h + GamePad.h + SDL/joystick.h keyboard.h - KeyStatus.h + KeyStatus.h onepad.h) # onepad Linux sources @@ -49,10 +51,12 @@ if (SDL2_API) set(onepadFinalLibs ${SDL2_LIBRARIES} ) + add_definitions(-DSDL_BUILD) else() set(onepadFinalLibs ${SDL_LIBRARY} ) + add_definitions(-DSDL_BUILD) endif() set(onepadFinalLibs diff --git a/plugins/onepad/GamePad.cpp b/plugins/onepad/GamePad.cpp new file mode 100644 index 0000000000..a20c4cf5cb --- /dev/null +++ b/plugins/onepad/GamePad.cpp @@ -0,0 +1,42 @@ +#include "GamePad.h" +#ifdef SDL_BUILD +#include "SDL/joystick.h" +#endif + +vector s_vgamePad; +bool GamePadIdWithinBounds(int GamePadId) +{ + return ((GamePadId >= 0) && (GamePadId < (int)s_vgamePad.size())); +} + +/** + * Following static methods are just forwarders to their backend + * This is where link between agnostic and specific code is done + **/ + +/** + * Find every interesting devices and create right structure for them(depend on backend) + **/ +void GamePad::EnumerateGamePads(vector& vgamePad) +{ +#ifdef SDL_BUILD + JoystickInfo::EnumerateJoysticks(vgamePad); +#endif +} +void GamePad::UpdateReleaseState() +{ +#ifdef SDL_BUILD + JoystickInfo::UpdateReleaseState(); +#endif +} +/** + * Update state of every attached devices + **/ +void GamePad::UpdateGamePadState() +{ +#ifdef SDL_BUILD + SDL_JoystickUpdate(); // No need to make yet another function call for that +#endif +} + + diff --git a/plugins/onepad/GamePad.h b/plugins/onepad/GamePad.h new file mode 100644 index 0000000000..1d400715fb --- /dev/null +++ b/plugins/onepad/GamePad.h @@ -0,0 +1,139 @@ +#pragma once + +#include "onepad.h" +#include "controller.h" +#ifdef SDL_BUILD +#include +#define HAT_UP SDL_HAT_UP +#define HAT_DOWN SDL_HAT_DOWN +#define HAT_RIGHT SDL_HAT_RIGHT +#define HAT_LEFT SDL_HAT_LEFT +#endif + +class GamePad +{ + public: + GamePad() : devname(""), _id(-1), numbuttons(0), numaxes(0), numhats(0), + deadzone(1500), pad(-1) { + vbuttonstate.clear(); + vaxisstate.clear(); + vhatstate.clear(); + } + + virtual ~GamePad() + { + return; + } + + GamePad(const GamePad&); // copy constructor + GamePad& operator=(const GamePad&); // assignment + + /** + * Find every interesting devices and create right structure for them(depend on backend) + **/ + static void EnumerateGamePads(vector& vgamePad); + static void UpdateReleaseState(); + /** + * Update state of every attached devices + **/ + static void UpdateGamePadState(); + + /** + * Causes devices to rumble + * Rumble will differ according to type which is either 0(small motor) or 1(big motor) + **/ + virtual void Rumble(int type){return;} + + virtual bool Init(int id){return false;} // opens a handle and gets information + + /** + * Used for GUI checkbox to give feedback to the user + **/ + virtual void TestForce(){return;} + + virtual bool PollButtons(u32 &pkey){return false;} + virtual bool PollAxes(u32 &pkey){return false;} + virtual bool PollHats(u32 &pkey){return false;} + + virtual int GetHat(int key_to_axis) + { + return 0; + } + + virtual int GetButton(int key_to_button) + { + return 0; + } + + virtual const string& GetName() + { + return devname; + } + + virtual int GetNumButtons() + { + return numbuttons; + } + + virtual int GetNumAxes() + { + return numaxes; + } + + virtual int GetNumHats() + { + return numhats; + } + + virtual int GetDeadzone() + { + return deadzone; + } + + virtual void SaveState(){return;} + + virtual int GetButtonState(int i) + { + return vbuttonstate[i]; + } + + virtual int GetAxisState(int i) + { + return vaxisstate[i]; + } + + virtual int GetHatState(int i) + { + //PAD_LOG("Getting POV State of %d.\n", i); + return vhatstate[i]; + } + + virtual void SetButtonState(int i, int state) + { + vbuttonstate[i] = state; + } + + virtual void SetAxisState(int i, int value) + { + vaxisstate[i] = value; + } + + virtual void SetHatState(int i, int value) + { + //PAD_LOG("We should set %d to %d.\n", i, value); + vhatstate[i] = value; + } + + virtual int GetAxisFromKey(int pad, int index){return 0;} +// These fields need to be inherited by child classes + protected: + string devname; // pretty device name + int _id; + int numbuttons, numaxes, numhats; + int deadzone; + int pad; + vector vbuttonstate, vaxisstate, vhatstate; +}; + +extern vector s_vgamePad; +extern bool GamePadIdWithinBounds(int joyid); diff --git a/plugins/onepad/Linux/dialog.cpp b/plugins/onepad/Linux/dialog.cpp index cbd693e569..03c68fbfcc 100644 --- a/plugins/onepad/Linux/dialog.cpp +++ b/plugins/onepad/Linux/dialog.cpp @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "joystick.h" +#include "GamePad.h" #include "keyboard.h" #include "onepad.h" #include @@ -243,14 +243,14 @@ keys_tree *key_tree_manager; void populate_new_joysticks(GtkComboBoxText *box) { char str[255]; - JoystickInfo::EnumerateJoysticks(s_vjoysticks); + GamePad::EnumerateGamePads(s_vgamePad); gtk_combo_box_text_append_text(box, "Keyboard/mouse only"); - vector::iterator it = s_vjoysticks.begin(); + vector::iterator it = s_vgamePad.begin(); // Get everything in the vector vjoysticks. - while (it != s_vjoysticks.end()) + while (it != s_vgamePad.end()) { sprintf(str, "Keyboard/mouse and %s - but: %d, axes: %d, hats: %d", (*it)->GetName().c_str(), (*it)->GetNumButtons(), (*it)->GetNumAxes(), (*it)->GetNumHats()); @@ -262,7 +262,7 @@ void populate_new_joysticks(GtkComboBoxText *box) void set_current_joy() { u32 joyid = conf->get_joyid(current_pad); - if (JoystickIdWithinBounds(joyid)) + if (GamePadIdWithinBounds(joyid)) // 0 is special case for no gamepad. So you must increase of 1. gtk_combo_box_set_active(GTK_COMBO_BOX(joy_choose_cbox), joyid+1); else @@ -305,10 +305,10 @@ void config_key(int pad, int key) u32 key_pressed = 0; // I don't have any guarantee that not-yet-pressed state is egual to released state - JoystickInfo::UpdateReleaseState(); + GamePad::UpdateReleaseState(); while (!captured) { - vector::iterator itjoy; + vector::iterator itjoy; if (PollX11KeyboardMouseEvent(key_pressed)) { @@ -321,10 +321,10 @@ void config_key(int pad, int key) break; } - SDL_JoystickUpdate(); + GamePad::UpdateGamePadState(); - itjoy = s_vjoysticks.begin(); - while ((itjoy != s_vjoysticks.end()) && (!captured)) + itjoy = s_vgamePad.begin(); + while ((itjoy != s_vgamePad.end()) && (!captured)) { if ((*itjoy)->PollButtons(key_pressed)) { set_key(pad, key, key_pressed); diff --git a/plugins/onepad/Linux/ini.cpp b/plugins/onepad/Linux/ini.cpp index a88ea433d2..c494b80c08 100644 --- a/plugins/onepad/Linux/ini.cpp +++ b/plugins/onepad/Linux/ini.cpp @@ -22,7 +22,7 @@ #include #include -#include "joystick.h" +#include "GamePad.h" #include "keyboard.h" #include "onepad.h" #include "linux.h" @@ -73,19 +73,19 @@ string KeyName(int pad, int key, int keysym) int axis = key_to_axis(pad, key); switch(key_to_hat_dir(pad, key)) { - case SDL_HAT_UP: + case HAT_UP: sprintf(&tmp[0], "JPOVU-%d", axis); break; - case SDL_HAT_RIGHT: + case HAT_RIGHT: sprintf(&tmp[0], "JPOVR-%d", axis); break; - case SDL_HAT_DOWN: + case HAT_DOWN: sprintf(&tmp[0], "JPOVD-%d", axis); break; - case SDL_HAT_LEFT: + case HAT_LEFT: sprintf(&tmp[0], "JPOVL-%d", axis); break; } diff --git a/plugins/onepad/Linux/linux.cpp b/plugins/onepad/Linux/linux.cpp index 10e00b020b..086cc5cd95 100644 --- a/plugins/onepad/Linux/linux.cpp +++ b/plugins/onepad/Linux/linux.cpp @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "joystick.h" +#include "GamePad.h" #include "onepad.h" #include "keyboard.h" @@ -74,34 +74,34 @@ void _PADclose() { SetAutoRepeat(true); - vector::iterator it = s_vjoysticks.begin(); + vector::iterator it = s_vgamePad.begin(); // Delete everything in the vector vjoysticks. - while (it != s_vjoysticks.end()) + while (it != s_vgamePad.end()) { delete *it; it ++; } - s_vjoysticks.clear(); + s_vgamePad.clear(); } void PollForJoystickInput(int cpad) { int joyid = conf->get_joyid(cpad); - if (!JoystickIdWithinBounds(joyid)) return; + if (!GamePadIdWithinBounds(joyid)) return; - SDL_JoystickUpdate(); + GamePad::UpdateGamePadState(); for (int i = 0; i < MAX_KEYS; i++) { - JoystickInfo* pjoy = s_vjoysticks[joyid]; + GamePad* gamePad = s_vgamePad[joyid]; switch (type_of_joykey(cpad, i)) { case PAD_JOYBUTTONS: { - int value = SDL_JoystickGetButton((pjoy)->GetJoy(), key_to_button(cpad, i)); + int value = gamePad->GetButton(key_to_button(cpad, i)); if (value) key_status->press(cpad, i); else @@ -111,7 +111,7 @@ void PollForJoystickInput(int cpad) } case PAD_HAT: { - int value = SDL_JoystickGetHat((pjoy)->GetJoy(), key_to_axis(cpad, i)); + int value = gamePad->GetHat(key_to_axis(cpad, i)); // key_to_hat_dir and SDL_JoystickGetHat are a 4 bits bitmap, one for each directions. Only 1 bit can be high for // key_to_hat_dir. SDL_JoystickGetHat handles diagonal too (2 bits) so you must check the intersection @@ -125,12 +125,12 @@ void PollForJoystickInput(int cpad) } case PAD_AXIS: { - int value = pjoy->GetAxisFromKey(cpad, i); + int value = gamePad->GetAxisFromKey(cpad, i); bool sign = key_to_axis_sign(cpad, i); bool full_axis = key_to_axis_type(cpad, i); if (IsAnalogKey(i)) { - if (abs(value) > pjoy->GetDeadzone()) + if (abs(value) > gamePad->GetDeadzone()) key_status->press(cpad, i, value); else key_status->release(cpad, i); @@ -138,15 +138,15 @@ void PollForJoystickInput(int cpad) } else { if (full_axis) { value += 0x8000; - if (value > pjoy->GetDeadzone()) + if (value > gamePad->GetDeadzone()) key_status->press(cpad, i, min(value/256 , 0xFF)); else key_status->release(cpad, i); } else { - if (sign && (-value > pjoy->GetDeadzone())) + if (sign && (-value > gamePad->GetDeadzone())) key_status->press(cpad, i, min(-value /128, 0xFF)); - else if (!sign && (value > pjoy->GetDeadzone())) + else if (!sign && (value > gamePad->GetDeadzone())) key_status->press(cpad, i, min(value /128, 0xFF)); else key_status->release(cpad, i); diff --git a/plugins/onepad/joystick.cpp b/plugins/onepad/SDL/joystick.cpp similarity index 90% rename from plugins/onepad/joystick.cpp rename to plugins/onepad/SDL/joystick.cpp index 3d941f46c6..6cf3b36317 100644 --- a/plugins/onepad/joystick.cpp +++ b/plugins/onepad/SDL/joystick.cpp @@ -25,30 +25,24 @@ // Joystick definitions // ////////////////////////// -vector s_vjoysticks; static u32 s_bSDLInit = false; void JoystickInfo::UpdateReleaseState() { - vector::iterator itjoy = s_vjoysticks.begin(); + vector::iterator itjoy = s_vgamePad.begin(); SDL_JoystickUpdate(); // Save everything in the vector s_vjoysticks. - while (itjoy != s_vjoysticks.end()) + while (itjoy != s_vgamePad.end()) { (*itjoy)->SaveState(); itjoy++; } } -bool JoystickIdWithinBounds(int joyid) -{ - return ((joyid >= 0) && (joyid < (int)s_vjoysticks.size())); -} - // opens handles to all possible joysticks -void JoystickInfo::EnumerateJoysticks(vector& vjoysticks) +void JoystickInfo::EnumerateJoysticks(vector& vjoysticks) { if (!s_bSDLInit) @@ -67,7 +61,7 @@ void JoystickInfo::EnumerateJoysticks(vector& vjoysticks) s_bSDLInit = true; } - vector::iterator it = vjoysticks.begin(); + vector::iterator it = vjoysticks.begin(); // Delete everything in the vector vjoysticks. while (it != vjoysticks.end()) @@ -143,26 +137,14 @@ void JoystickInfo::InitHapticEffect() #endif } -void JoystickInfo::DoHapticEffect(int type, int pad, int force) +void JoystickInfo::Rumble(int type) { if (type > 1) return; if ( !(conf->pad_options[pad].forcefeedback) ) return; #if SDL_MAJOR_VERSION >= 2 - int joyid = conf->get_joyid(pad); - if (!JoystickIdWithinBounds(joyid)) return; - JoystickInfo* pjoy = s_vjoysticks[joyid]; - - if (pjoy->haptic == NULL) return; - if (pjoy->haptic_effect_id[type] < 0) return; - - // FIXME: might need to multiply force - pjoy->haptic_effect_data[type].periodic.magnitude = force * conf->get_ff_intensity() ; // force/32767 strength - // Upload the new effect - SDL_HapticUpdateEffect(pjoy->haptic, pjoy->haptic_effect_id[type], &pjoy->haptic_effect_data[type]); - - // run the effect once - SDL_HapticRunEffect( pjoy->haptic, pjoy->haptic_effect_id[type], 1 ); + if (haptic == NULL) return; + return; #endif } @@ -360,6 +342,16 @@ bool JoystickInfo::PollHats(u32 &pkey) return false; } +int JoystickInfo::GetHat(int key_to_axis) +{ + return SDL_JoystickGetHat(GetJoy(),key_to_axis); +} + +int JoystickInfo::GetButton(int key_to_button) +{ + return SDL_JoystickGetButton(GetJoy(),key_to_button); +} + int JoystickInfo::GetAxisFromKey(int pad, int index) { return SDL_JoystickGetAxis(GetJoy(), key_to_axis(pad, index)); diff --git a/plugins/onepad/joystick.h b/plugins/onepad/SDL/joystick.h similarity index 90% rename from plugins/onepad/joystick.h rename to plugins/onepad/SDL/joystick.h index a7da84b6c1..1941c0b049 100644 --- a/plugins/onepad/joystick.h +++ b/plugins/onepad/SDL/joystick.h @@ -19,20 +19,19 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef __JOYSTICK_H__ -#define __JOYSTICK_H__ +#pragma once #include #if SDL_MAJOR_VERSION >= 2 #include #endif - +#include "GamePad.h" #include "onepad.h" #include "controller.h" // holds all joystick info -class JoystickInfo +class JoystickInfo : GamePad { public: JoystickInfo() : devname(""), _id(-1), numbuttons(0), numaxes(0), numhats(0), @@ -57,10 +56,10 @@ class JoystickInfo void Destroy(); // opens handles to all possible joysticks - static void EnumerateJoysticks(vector& vjoysticks); + static void EnumerateJoysticks(vector& vjoysticks); void InitHapticEffect(); - static void DoHapticEffect(int type, int pad, int force); + void Rumble(int type); bool Init(int id); // opens a handle and gets information @@ -70,6 +69,10 @@ class JoystickInfo bool PollAxes(u32 &pkey); bool PollHats(u32 &pkey); + int GetHat(int key_to_axis); + + int GetButton(int key_to_button); + const string& GetName() { return devname; @@ -134,16 +137,15 @@ class JoystickInfo vhatstate[i] = value; } - SDL_Joystick* GetJoy() - { - return joy; - } - int GetAxisFromKey(int pad, int index); static void UpdateReleaseState(); private: + SDL_Joystick* GetJoy() + { + return joy; + } string devname; // pretty device name int _id; int numbuttons, numaxes, numhats; @@ -159,9 +161,3 @@ class JoystickInfo int haptic_effect_id[2]; #endif }; - - -extern int s_selectedpad; -extern vector s_vjoysticks; -extern bool JoystickIdWithinBounds(int joyid); -#endif diff --git a/plugins/onepad/controller.h b/plugins/onepad/controller.h index 41db6513e7..8d8f7a920b 100644 --- a/plugins/onepad/controller.h +++ b/plugins/onepad/controller.h @@ -20,7 +20,7 @@ */ #pragma once - +#include // for memset #ifdef __linux__ #define MAX_KEYS 24 #else diff --git a/plugins/onepad/onepad.cpp b/plugins/onepad/onepad.cpp index 6d036876ef..f77bf5d48d 100644 --- a/plugins/onepad/onepad.cpp +++ b/plugins/onepad/onepad.cpp @@ -263,7 +263,7 @@ EXPORT_C_(s32) PADopen(void *pDsp) mutex_WasInit = true; #ifdef __linux__ - JoystickInfo::EnumerateJoysticks(s_vjoysticks); + GamePad::EnumerateGamePads(s_vgamePad); #endif return _PADopen(pDsp); } @@ -421,7 +421,8 @@ u8 _PADpoll(u8 value) { padVibF[curPad][2] = vib_small; // SetDeviceForceS (padVibC[curPad], vib_small); - JoystickInfo::DoHapticEffect(0, curPad, vib_small); + GamePad* gamePad = s_vgamePad[conf->get_joyid(curPad)]; + gamePad->Rumble(0); } /* Big Motor */ @@ -431,7 +432,8 @@ u8 _PADpoll(u8 value) { padVibF[curPad][3] = vib_big; // SetDeviceForceB (padVibC[curPad], vib_big); - JoystickInfo::DoHapticEffect(1, curPad, vib_big); + GamePad* gamePad = s_vgamePad[conf->get_joyid(curPad)]; + gamePad->Rumble(1); } return padID[curPad]; diff --git a/plugins/onepad/onepad.h b/plugins/onepad/onepad.h index f97796e70a..0e76352f2c 100644 --- a/plugins/onepad/onepad.h +++ b/plugins/onepad/onepad.h @@ -48,7 +48,7 @@ using namespace std; #include "PS2Edefs.h" #ifdef __linux__ -#include "joystick.h" +#include "GamePad.h" #endif #include "bitwise.h" #include "controller.h"