+ 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).
This commit is contained in:
3kinox 2015-10-14 15:05:02 +02:00
parent 9ab554af5b
commit fb0d7139f2
11 changed files with 255 additions and 80 deletions

View File

@ -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

View File

@ -0,0 +1,42 @@
#include "GamePad.h"
#ifdef SDL_BUILD
#include "SDL/joystick.h"
#endif
vector<GamePad*> 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<GamePad*>& 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
}

139
plugins/onepad/GamePad.h Normal file
View File

@ -0,0 +1,139 @@
#pragma once
#include "onepad.h"
#include "controller.h"
#ifdef SDL_BUILD
#include <SDL.h>
#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<GamePad*>& 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<int> vbuttonstate, vaxisstate, vhatstate;
};
extern vector<GamePad*> s_vgamePad;
extern bool GamePadIdWithinBounds(int joyid);

View File

@ -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 <gtk/gtk.h>
@ -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<JoystickInfo*>::iterator it = s_vjoysticks.begin();
vector<GamePad*>::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<JoystickInfo*>::iterator itjoy;
vector<GamePad*>::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);

View File

@ -22,7 +22,7 @@
#include <string.h>
#include <gtk/gtk.h>
#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;
}

View File

@ -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<JoystickInfo*>::iterator it = s_vjoysticks.begin();
vector<GamePad*>::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);

View File

@ -25,30 +25,24 @@
// Joystick definitions //
//////////////////////////
vector<JoystickInfo*> s_vjoysticks;
static u32 s_bSDLInit = false;
void JoystickInfo::UpdateReleaseState()
{
vector<JoystickInfo*>::iterator itjoy = s_vjoysticks.begin();
vector<GamePad*>::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<JoystickInfo*>& vjoysticks)
void JoystickInfo::EnumerateJoysticks(vector<GamePad*>& vjoysticks)
{
if (!s_bSDLInit)
@ -67,7 +61,7 @@ void JoystickInfo::EnumerateJoysticks(vector<JoystickInfo*>& vjoysticks)
s_bSDLInit = true;
}
vector<JoystickInfo*>::iterator it = vjoysticks.begin();
vector<GamePad*>::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));

View File

@ -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 <SDL.h>
#if SDL_MAJOR_VERSION >= 2
#include <SDL_haptic.h>
#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<JoystickInfo*>& vjoysticks);
static void EnumerateJoysticks(vector<GamePad*>& 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<JoystickInfo*> s_vjoysticks;
extern bool JoystickIdWithinBounds(int joyid);
#endif

View File

@ -20,7 +20,7 @@
*/
#pragma once
#include <string.h> // for memset
#ifdef __linux__
#define MAX_KEYS 24
#else

View File

@ -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];

View File

@ -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"