mirror of https://github.com/PCSX2/pcsx2.git
Merge pull request #892 from 3kinox/rumble_onepad
Implement rumble and isolate SDL code path
This commit is contained in:
commit
9b796d0f27
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
@ -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,int pad){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);
|
|
@ -69,7 +69,7 @@ void KeyStatus::press(u32 pad, u32 index, s32 value)
|
|||
// Normal mode : expect value 0 -> 80 -> FF
|
||||
// Reverse mode: expect value FF -> 7F -> 0
|
||||
u8 force = (value / 256);
|
||||
if (analog_is_reversed(index)) analog_set(pad, index, 0x7F - force);
|
||||
if (analog_is_reversed(pad,index)) analog_set(pad, index, 0x7F - force);
|
||||
else analog_set(pad, index, 0x80 + force);
|
||||
}
|
||||
}
|
||||
|
@ -117,25 +117,25 @@ void KeyStatus::analog_set(u32 pad, u32 index, u8 value)
|
|||
}
|
||||
}
|
||||
|
||||
bool KeyStatus::analog_is_reversed(u32 index)
|
||||
bool KeyStatus::analog_is_reversed(u32 pad, u32 index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case PAD_L_RIGHT:
|
||||
case PAD_L_LEFT:
|
||||
return ((conf->options & PADOPTION_REVERSELX) != 0);
|
||||
return (conf->pad_options[pad].reverse_lx);
|
||||
|
||||
case PAD_R_LEFT:
|
||||
case PAD_R_RIGHT:
|
||||
return ((conf->options & PADOPTION_REVERSERX) != 0);
|
||||
return (conf->pad_options[pad].reverse_rx);
|
||||
|
||||
case PAD_L_UP:
|
||||
case PAD_L_DOWN:
|
||||
return ((conf->options & PADOPTION_REVERSELY) != 0);
|
||||
return (conf->pad_options[pad].reverse_ly);
|
||||
|
||||
case PAD_R_DOWN:
|
||||
case PAD_R_UP:
|
||||
return ((conf->options & PADOPTION_REVERSERY) != 0);
|
||||
return (conf->pad_options[pad].reverse_ry);
|
||||
|
||||
default: return false;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ class KeyStatus
|
|||
PADAnalog m_internal_analog_joy[2];
|
||||
|
||||
void analog_set(u32 pad, u32 index, u8 value);
|
||||
bool analog_is_reversed(u32 index);
|
||||
bool analog_is_reversed(u32 pad, u32 index);
|
||||
u8 analog_merge(u8 kbd, u8 joy);
|
||||
|
||||
public:
|
||||
|
|
|
@ -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
|
||||
|
@ -294,7 +294,7 @@ typedef struct
|
|||
mask = mask_value;
|
||||
|
||||
gtk_fixed_put(GTK_FIXED(area), widget, x, y);
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), mask & conf->options);
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), mask & conf->packed_options);
|
||||
g_signal_connect(widget, "toggled", G_CALLBACK(on_toggle_option), this);
|
||||
}
|
||||
} dialog_checkbox;
|
||||
|
@ -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);
|
||||
|
@ -393,9 +393,13 @@ void on_toggle_option(GtkToggleButton *togglebutton, gpointer user_data)
|
|||
dialog_checkbox *checkbox = (dialog_checkbox*)user_data;
|
||||
|
||||
if (gtk_toggle_button_get_active(togglebutton))
|
||||
conf->options |= checkbox->mask;
|
||||
{
|
||||
conf->packed_options |= checkbox->mask;
|
||||
if(checkbox->mask == PADOPTION_FORCEFEEDBACK && (conf->get_joyid(current_pad)< s_vgamePad.size()))
|
||||
s_vgamePad[conf->get_joyid(current_pad)]->TestForce();
|
||||
}
|
||||
else
|
||||
conf->options &= ~checkbox->mask;
|
||||
conf->packed_options &= ~checkbox->mask;
|
||||
}
|
||||
|
||||
void joy_changed(GtkComboBoxText *box, gpointer user_data)
|
||||
|
@ -427,23 +431,6 @@ void pad_changed(GtkNotebook *notebook, void *notebook_page, int page, void *dat
|
|||
set_current_joy();
|
||||
}
|
||||
|
||||
//void on_forcefeedback_toggled(GtkToggleButton *togglebutton, gpointer user_data)
|
||||
//{
|
||||
// int mask = PADOPTION_REVERSELX << (16 * s_selectedpad);
|
||||
//
|
||||
// if (gtk_toggle_button_get_active(togglebutton))
|
||||
// {
|
||||
// conf->options |= mask;
|
||||
//
|
||||
// u32 joyid = conf->get_joyid(current_pad);
|
||||
// if (JoystickIdWithinBounds(joyid)) s_vjoysticks[joyid]->TestForce();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// conf->options &= ~mask;
|
||||
// }
|
||||
//}
|
||||
|
||||
struct button_positions
|
||||
{
|
||||
const char* label;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -129,10 +129,10 @@ void SaveConfig()
|
|||
}
|
||||
|
||||
fprintf(f, "log = %d\n", conf->log);
|
||||
fprintf(f, "options = %d\n", conf->options);
|
||||
fprintf(f, "mouse_sensibility = %d\n", conf->sensibility);
|
||||
fprintf(f, "options = %d\n", conf->packed_options);
|
||||
fprintf(f, "mouse_sensibility = %d\n", conf->get_sensibility());
|
||||
fprintf(f, "joy_pad_map = %d\n", conf->joyid_map);
|
||||
fprintf(f, "ff_intensity = %d\n", conf->ff_intensity);
|
||||
fprintf(f, "ff_intensity = %d\n", conf->get_ff_intensity());
|
||||
|
||||
for (int pad = 0; pad < 2; pad++)
|
||||
{
|
||||
|
@ -174,13 +174,13 @@ void LoadConfig()
|
|||
if (fscanf(f, "log = %d\n", &value) == 0) goto error;
|
||||
conf->log = value;
|
||||
if (fscanf(f, "options = %d\n", &value) == 0) goto error;
|
||||
conf->options = value;
|
||||
conf->packed_options = value;
|
||||
if (fscanf(f, "mouse_sensibility = %d\n", &value) == 0) goto error;
|
||||
conf->sensibility = value;
|
||||
conf->set_sensibility(value);
|
||||
if (fscanf(f, "joy_pad_map = %d\n", &value) == 0) goto error;
|
||||
conf->joyid_map = value;
|
||||
if (fscanf(f, "ff_intensity = %d\n", &value) == 0) goto error;
|
||||
conf->ff_intensity = value;
|
||||
conf->set_ff_intensity(value);
|
||||
|
||||
for (int pad = 0; pad < 2; pad++)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
@ -56,10 +50,7 @@ void JoystickInfo::EnumerateJoysticks(vector<JoystickInfo*>& vjoysticks)
|
|||
#if SDL_MAJOR_VERSION >= 2
|
||||
// Tell SDL to catch event even if the windows isn't focussed
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
||||
// SDL in 3rdparty wrap X11 call. In order to get x11 symbols loaded
|
||||
// video must be loaded too.
|
||||
// Example of X11 symbol are XAutoRepeatOn/XAutoRepeatOff
|
||||
if (SDL_Init(SDL_INIT_JOYSTICK|SDL_INIT_VIDEO|SDL_INIT_HAPTIC|SDL_INIT_GAMECONTROLLER|SDL_INIT_EVENTS) < 0) return;
|
||||
if (SDL_Init(SDL_INIT_JOYSTICK|SDL_INIT_HAPTIC|SDL_INIT_EVENTS) < 0) return;
|
||||
#else
|
||||
if (SDL_Init(SDL_INIT_JOYSTICK) < 0) return;
|
||||
#endif
|
||||
|
@ -67,7 +58,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())
|
||||
|
@ -85,84 +76,68 @@ void JoystickInfo::EnumerateJoysticks(vector<JoystickInfo*>& vjoysticks)
|
|||
}
|
||||
}
|
||||
|
||||
void JoystickInfo::InitHapticEffect()
|
||||
void JoystickInfo::GenerateDefaultEffect()
|
||||
{
|
||||
for(int i=0;i<NB_EFFECT;i++)
|
||||
{
|
||||
SDL_HapticEffect effect;
|
||||
memset( &effect, 0, sizeof(SDL_HapticEffect) ); // 0 is safe default
|
||||
SDL_HapticDirection direction;
|
||||
direction.type = SDL_HAPTIC_POLAR; // We'll be using polar direction encoding.
|
||||
direction.dir[0] = 18000;
|
||||
effect.periodic.direction = direction;
|
||||
effect.periodic.period = 10;
|
||||
effect.periodic.magnitude = (Sint16)(conf->get_ff_intensity()); // Effect at maximum instensity
|
||||
effect.periodic.offset = 0;
|
||||
effect.periodic.phase = 18000;
|
||||
effect.periodic.length = 125; // 125ms feels quite near to original
|
||||
effect.periodic.delay = 0;
|
||||
effect.periodic.attack_length = 0;
|
||||
effects[i] = effect;
|
||||
}
|
||||
}
|
||||
|
||||
void JoystickInfo::Rumble(int type, int pad)
|
||||
{
|
||||
if (type > 1) return;
|
||||
if ( !(conf->pad_options[pad].forcefeedback) ) return;
|
||||
|
||||
#if SDL_MAJOR_VERSION >= 2
|
||||
if (haptic == NULL) return;
|
||||
|
||||
#if 0
|
||||
additional field of the effect
|
||||
/* Trigger */
|
||||
Uint16 button; /**< Button that triggers the effect. */
|
||||
Uint16 interval; /**< How soon it can be triggered again after button. */
|
||||
|
||||
// periodic parameter
|
||||
Sint16 offset; /**< Mean value of the wave. */
|
||||
Uint16 phase; /**< Horizontal shift given by hundredth of a cycle. */
|
||||
#endif
|
||||
|
||||
/*******************************************************************/
|
||||
/* Effect big & small */
|
||||
/*******************************************************************/
|
||||
for (int new_effect = 0; new_effect < 2 ; new_effect++) {
|
||||
|
||||
// Direction of the effect SDL_HapticDirection
|
||||
haptic_effect_data[new_effect].periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates
|
||||
haptic_effect_data[new_effect].periodic.direction.dir[0] = 18000; // Force comes from south
|
||||
|
||||
// periodic parameter
|
||||
haptic_effect_data[new_effect].periodic.period = 20; // 20 ms
|
||||
haptic_effect_data[new_effect].periodic.magnitude = 2000; // 2000/32767 strength
|
||||
|
||||
// Replay
|
||||
haptic_effect_data[new_effect].periodic.length = 60; // 60 ms long
|
||||
haptic_effect_data[new_effect].periodic.delay = 0; // start 0 second after the upload
|
||||
|
||||
// enveloppe
|
||||
haptic_effect_data[new_effect].periodic.attack_length = 5;// Takes 5 ms to get max strength
|
||||
haptic_effect_data[new_effect].periodic.attack_level = 0; // start at 0
|
||||
haptic_effect_data[new_effect].periodic.fade_length = 5; // Takes 5 ms to fade away
|
||||
haptic_effect_data[new_effect].periodic.fade_level = 0; // finish at 0
|
||||
if(first)
|
||||
{// If done multiple times, device memory will be filled
|
||||
first = 0;
|
||||
GenerateDefaultEffect();
|
||||
/** Sine and triangle are quite probably the best, don't change that lightly and if you do
|
||||
* keep effects ordered by type
|
||||
**/
|
||||
/** Effect for small motor **/
|
||||
/** Sine seems to be the only effect making little motor from DS3/4 react
|
||||
* Intensity has pretty much no effect either(which is coherent with what is explain in hid_sony driver
|
||||
**/
|
||||
effects[0].type = SDL_HAPTIC_SINE;
|
||||
effects_id[0] = SDL_HapticNewEffect(haptic, &effects[0]);
|
||||
if(effects_id[0] < 0)
|
||||
{
|
||||
fprintf(stderr,"ERROR: Effect is not uploaded! %s, id is %d\n",SDL_GetError(),effects_id[0]);
|
||||
}
|
||||
|
||||
/** Effect for big motor **/
|
||||
effects[1].type = SDL_HAPTIC_TRIANGLE;
|
||||
effects_id[1] = SDL_HapticNewEffect(haptic, &effects[1]);
|
||||
if(effects_id[1] < 0)
|
||||
{
|
||||
fprintf(stderr,"ERROR: Effect is not uploaded! %s, id is %d\n",SDL_GetError(),effects_id[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
/* Effect small */
|
||||
/*******************************************************************/
|
||||
haptic_effect_data[0].type = SDL_HAPTIC_LEFTRIGHT;
|
||||
|
||||
/*******************************************************************/
|
||||
/* Effect big */
|
||||
/*******************************************************************/
|
||||
haptic_effect_data[1].type = SDL_HAPTIC_TRIANGLE;
|
||||
|
||||
/*******************************************************************/
|
||||
/* Upload effect to the device */
|
||||
/*******************************************************************/
|
||||
for (int i = 0 ; i < 2 ; i++)
|
||||
haptic_effect_id[i] = SDL_HapticNewEffect(haptic, &haptic_effect_data[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void JoystickInfo::DoHapticEffect(int type, int pad, int force)
|
||||
{
|
||||
if (type > 1) return;
|
||||
if ( !(conf->options & (PADOPTION_FORCEFEEDBACK << 16 * pad)) ) 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->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 );
|
||||
int id;
|
||||
id = effects_id[type];
|
||||
if(SDL_HapticRunEffect(haptic, id, 1) != 0)
|
||||
{
|
||||
fprintf(stderr,"ERROR: Effect is not working! %s, id is %d\n",SDL_GetError(),id);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -179,7 +154,9 @@ void JoystickInfo::Destroy()
|
|||
#endif
|
||||
|
||||
#if SDL_MAJOR_VERSION >= 2
|
||||
#if SDL_MINOR_VERSION >= 4 // Version before 2.0.4 are bugged, JoystickClose crashes randomly
|
||||
if (joy) SDL_JoystickClose(joy);
|
||||
#endif
|
||||
#else
|
||||
if (SDL_JoystickOpened(_id)) SDL_JoystickClose(joy);
|
||||
#endif
|
||||
|
@ -230,8 +207,7 @@ bool JoystickInfo::Init(int id)
|
|||
PAD_LOG("Haptic devices not supported!\n");
|
||||
} else {
|
||||
haptic = SDL_HapticOpenFromJoystick(joy);
|
||||
// upload some default effect
|
||||
InitHapticEffect();
|
||||
first = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -251,7 +227,14 @@ void JoystickInfo::SaveState()
|
|||
}
|
||||
|
||||
void JoystickInfo::TestForce()
|
||||
{
|
||||
{ // This code just use standard rumble to check that SDL handles the pad correctly! --3kinox
|
||||
if(haptic == NULL) return; // Otherwise, core dump!
|
||||
SDL_HapticRumbleInit( haptic );
|
||||
// Make the haptic pad rumble 60% strength for half a second, shoudld be enough for user to see if it works or not
|
||||
if( SDL_HapticRumblePlay( haptic, 0.60, 400 ) != 0)
|
||||
{
|
||||
fprintf(stderr,"ERROR: Rumble is not working! %s\n",SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
bool JoystickInfo::PollButtons(u32 &pkey)
|
||||
|
@ -289,7 +272,7 @@ bool JoystickInfo::PollAxes(u32 &pkey)
|
|||
if (found_hack != string::npos) {
|
||||
// The analog mode of the hat button is quite erratic. Values can be in half- axis
|
||||
// or full axis... So better keep them as button for the moment -- gregory
|
||||
if (i >= 8 && i <= 11 && (conf->options & PADOPTION_SIXAXIS_USB))
|
||||
if (i >= 8 && i <= 11 && (conf->pad_options[pad].sixaxis_usb))
|
||||
continue;
|
||||
// Disable accelerometer
|
||||
if ((i >= 4 && i <= 6))
|
||||
|
@ -360,6 +343,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));
|
|
@ -19,31 +19,29 @@
|
|||
* 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"
|
||||
|
||||
#define NB_EFFECT 2 // Don't use more than two, ps2 only has one for big motor and one for small(like most systems)
|
||||
// holds all joystick info
|
||||
class JoystickInfo
|
||||
class JoystickInfo : GamePad
|
||||
{
|
||||
public:
|
||||
JoystickInfo() : devname(""), _id(-1), numbuttons(0), numaxes(0), numhats(0),
|
||||
deadzone(1500), pad(-1), joy(NULL) {
|
||||
vbuttonstate.clear();
|
||||
vaxisstate.clear();
|
||||
vhatstate.clear();
|
||||
vbuttonstate.clear();
|
||||
vaxisstate.clear();
|
||||
vhatstate.clear();
|
||||
#if SDL_MAJOR_VERSION >= 2
|
||||
haptic = NULL;
|
||||
for (int i = 0 ; i < 2 ; i++)
|
||||
haptic_effect_id[i] = -1;
|
||||
haptic = NULL;
|
||||
first = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -57,10 +55,9 @@ 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,int pad);
|
||||
|
||||
bool Init(int id); // opens a handle and gets information
|
||||
|
||||
|
@ -70,6 +67,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 +135,16 @@ 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;
|
||||
}
|
||||
void GenerateDefaultEffect();
|
||||
string devname; // pretty device name
|
||||
int _id;
|
||||
int numbuttons, numaxes, numhats;
|
||||
|
@ -155,13 +156,8 @@ class JoystickInfo
|
|||
SDL_Joystick* joy;
|
||||
#if SDL_MAJOR_VERSION >= 2
|
||||
SDL_Haptic* haptic;
|
||||
SDL_HapticEffect haptic_effect_data[2];
|
||||
int haptic_effect_id[2];
|
||||
bool first;
|
||||
SDL_HapticEffect effects[NB_EFFECT];
|
||||
int effects_id[NB_EFFECT];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
extern int s_selectedpad;
|
||||
extern vector<JoystickInfo*> s_vjoysticks;
|
||||
extern bool JoystickIdWithinBounds(int joyid);
|
||||
#endif
|
|
@ -19,9 +19,8 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __CONTROLLER_H__
|
||||
#define __CONTROLLER_H__
|
||||
|
||||
#pragma once
|
||||
#include <string.h> // for memset
|
||||
#ifdef __linux__
|
||||
#define MAX_KEYS 24
|
||||
#else
|
||||
|
@ -55,23 +54,37 @@ extern int hat_to_key(int dir, int axis_id);
|
|||
|
||||
extern int PadEnum[2][2];
|
||||
|
||||
struct PADconf
|
||||
class PADconf
|
||||
{
|
||||
u32 ff_intensity;
|
||||
u32 sensibility;
|
||||
public:
|
||||
union {
|
||||
struct {
|
||||
u32 forcefeedback :1;
|
||||
u32 reverse_lx :1;
|
||||
u32 reverse_ly :1;
|
||||
u32 reverse_rx :1;
|
||||
u32 reverse_ry :1;
|
||||
u32 mouse_l :1;
|
||||
u32 mouse_r :1;
|
||||
u32 sixaxis_usb :1;
|
||||
u32 _free : 8; // The 8 remaining bits are unused, do what you wish with them ;)
|
||||
} pad_options[2]; // One for each pads
|
||||
u32 packed_options; // Only first 8 bits of each 16 bits series are really used, rest is padding
|
||||
};
|
||||
|
||||
u32 keys[2][MAX_KEYS];
|
||||
u32 log;
|
||||
u32 options; // upper 16 bits are for pad2
|
||||
u32 sensibility;
|
||||
u32 joyid_map;
|
||||
u32 ff_intensity;
|
||||
map<u32,u32> keysym_map[2];
|
||||
|
||||
PADconf() { init(); }
|
||||
|
||||
void init() {
|
||||
memset(&keys, 0, sizeof(keys));
|
||||
log = options = joyid_map = 0;
|
||||
ff_intensity = 100;
|
||||
log = packed_options = joyid_map = 0;
|
||||
ff_intensity = 0x7FFF; // set it at max value by default
|
||||
sensibility = 500;
|
||||
for (int pad = 0; pad < 2 ; pad++)
|
||||
keysym_map[pad].clear();
|
||||
|
@ -87,6 +100,43 @@ struct PADconf
|
|||
int shift = 8 * pad;
|
||||
return ((joyid_map >> shift) & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return (a copy of) private memner ff_instensity
|
||||
**/
|
||||
u32 get_ff_intensity()
|
||||
{
|
||||
return ff_intensity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set intensity while checking that the new value is within
|
||||
* valid range, more than 0x7FFF will cause pad not to rumble(and less than 0 is obviously bad)
|
||||
**/
|
||||
void set_ff_intensity(u32 new_intensity)
|
||||
{
|
||||
if(new_intensity < 0x7FFF && new_intensity >= 0)
|
||||
{
|
||||
ff_intensity = new_intensity;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sensibility value, sensibility is not yet implemented(and will probably be after evdev)
|
||||
* However, there will be an upper range too, less than 0 is an obvious wrong
|
||||
* Anyway, we are doing object oriented code, members are definitely not supposed to be public
|
||||
**/
|
||||
void set_sensibility(u32 new_sensibility)
|
||||
{
|
||||
if(sensibility > 0)
|
||||
{
|
||||
sensibility = new_sensibility;
|
||||
}
|
||||
}
|
||||
|
||||
u32 get_sensibility()
|
||||
{
|
||||
return sensibility;
|
||||
}
|
||||
};
|
||||
extern PADconf *conf;
|
||||
#endif
|
||||
|
|
|
@ -142,11 +142,11 @@ void AnalyzeKeyEvent(int pad, keyEvent &evt)
|
|||
// 1/ small move == no move. Cons : can not do small movement
|
||||
// 2/ use a watchdog timer thread
|
||||
// 3/ ??? idea welcome ;)
|
||||
if (conf->options & ((PADOPTION_MOUSE_L|PADOPTION_MOUSE_R) << 16 * pad )) {
|
||||
if (conf->pad_options[pad].mouse_l|conf->pad_options[pad].mouse_r) {
|
||||
unsigned int pad_x;
|
||||
unsigned int pad_y;
|
||||
// Note when both PADOPTION_MOUSE_R and PADOPTION_MOUSE_L are set, take only the right one
|
||||
if (conf->options & (PADOPTION_MOUSE_R << 16 * pad)) {
|
||||
if (conf->pad_options[pad].mouse_r) {
|
||||
pad_x = PAD_R_RIGHT;
|
||||
pad_y = PAD_R_UP;
|
||||
} else {
|
||||
|
@ -156,7 +156,7 @@ void AnalyzeKeyEvent(int pad, keyEvent &evt)
|
|||
|
||||
unsigned x = evt.key & 0xFFFF;
|
||||
unsigned int value = (s_previous_mouse_x > x) ? s_previous_mouse_x - x : x - s_previous_mouse_x;
|
||||
value *= conf->sensibility;
|
||||
value *= conf->get_sensibility();
|
||||
|
||||
if (x == 0)
|
||||
key_status->press(pad, pad_x, -MAX_ANALOG_VALUE);
|
||||
|
@ -172,7 +172,7 @@ void AnalyzeKeyEvent(int pad, keyEvent &evt)
|
|||
|
||||
unsigned y = evt.key >> 16;
|
||||
value = (s_previous_mouse_y > y) ? s_previous_mouse_y - y : y - s_previous_mouse_y;
|
||||
value *= conf->sensibility;
|
||||
value *= conf->get_sensibility();
|
||||
|
||||
if (y == 0)
|
||||
key_status->press(pad, pad_y, -MAX_ANALOG_VALUE);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
@ -300,7 +300,6 @@ EXPORT_C_(u32) PADquery()
|
|||
void PADsetMode(int pad, int mode)
|
||||
{
|
||||
padMode[pad] = mode;
|
||||
// FIXME FEEDBACK
|
||||
padVib0[pad] = 0;
|
||||
padVib1[pad] = 0;
|
||||
padVibF[pad][0] = 0;
|
||||
|
@ -413,7 +412,6 @@ u8 _PADpoll(u8 value)
|
|||
|
||||
buf = stdpar[curPad];
|
||||
|
||||
// FIXME FEEDBACK. Set effect here
|
||||
/* Small Motor */
|
||||
vib_small = padVibF[curPad][0] ? 2000 : 0;
|
||||
// if ((padVibF[curPad][2] != vib_small) && (padVibC[curPad] >= 0))
|
||||
|
@ -421,7 +419,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,curPad);
|
||||
}
|
||||
|
||||
/* Big Motor */
|
||||
|
@ -431,7 +430,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,curPad);
|
||||
}
|
||||
|
||||
return padID[curPad];
|
||||
|
@ -491,7 +491,7 @@ u8 _PADpoll(u8 value)
|
|||
switch (curCmd)
|
||||
{
|
||||
case CMD_READ_DATA_AND_VIBRATE:
|
||||
// FIXME FEEDBACK
|
||||
|
||||
if (curByte == padVib0[curPad])
|
||||
padVibF[curPad][0] = value;
|
||||
if (curByte == padVib1[curPad])
|
||||
|
@ -557,7 +557,7 @@ u8 _PADpoll(u8 value)
|
|||
break;
|
||||
|
||||
case CMD_VIBRATION_TOGGLE:
|
||||
// FIXME FEEDBACK
|
||||
|
||||
if (curByte >= 2)
|
||||
{
|
||||
if (curByte == padVib0[curPad])
|
||||
|
@ -567,16 +567,10 @@ u8 _PADpoll(u8 value)
|
|||
if (value == 0x00)
|
||||
{
|
||||
padVib0[curPad] = curByte;
|
||||
// FIXME: code from SSSXPAD I'm not sure we need this part
|
||||
// if ((padID[curPad] & 0x0f) < (curByte - 1) / 2)
|
||||
// padID[curPad] = (padID[curPad] & 0xf0) + (curByte - 1) / 2;
|
||||
}
|
||||
else if (value == 0x01)
|
||||
{
|
||||
padVib1[curPad] = curByte;
|
||||
// FIXME: code from SSSXPAD I'm not sure we need this part
|
||||
// if ((padID[curPad] & 0x0f) < (curByte - 1) / 2)
|
||||
// padID[curPad] = (padID[curPad] & 0xf0) + (curByte - 1) / 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue