mirror of https://github.com/PCSX2/pcsx2.git
PAD: clang-format
This commit is contained in:
parent
2e0be1f75a
commit
82f7a23be4
|
@ -28,10 +28,10 @@ std::vector<std::unique_ptr<GamePad>> s_vgamePad;
|
||||||
/**
|
/**
|
||||||
* Find every interesting devices and create right structure for them(depend on backend)
|
* Find every interesting devices and create right structure for them(depend on backend)
|
||||||
**/
|
**/
|
||||||
void GamePad::EnumerateGamePads(std::vector<std::unique_ptr<GamePad>> &vgamePad)
|
void GamePad::EnumerateGamePads(std::vector<std::unique_ptr<GamePad>>& vgamePad)
|
||||||
{
|
{
|
||||||
#ifdef SDL_BUILD
|
#ifdef SDL_BUILD
|
||||||
JoystickInfo::EnumerateJoysticks(vgamePad);
|
JoystickInfo::EnumerateJoysticks(vgamePad);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,33 +40,34 @@ void GamePad::EnumerateGamePads(std::vector<std::unique_ptr<GamePad>> &vgamePad)
|
||||||
**/
|
**/
|
||||||
void GamePad::DoRumble(unsigned type, unsigned pad)
|
void GamePad::DoRumble(unsigned type, unsigned pad)
|
||||||
{
|
{
|
||||||
int index = uid_to_index(pad);
|
int index = uid_to_index(pad);
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
s_vgamePad[index]->Rumble(type, pad);
|
s_vgamePad[index]->Rumble(type, pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GamePad::index_to_uid(int index)
|
size_t GamePad::index_to_uid(int index)
|
||||||
{
|
{
|
||||||
if ((index >= 0) && (index < (int)s_vgamePad.size()))
|
if ((index >= 0) && (index < (int)s_vgamePad.size()))
|
||||||
return s_vgamePad[index]->GetUniqueIdentifier();
|
return s_vgamePad[index]->GetUniqueIdentifier();
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GamePad::uid_to_index(int pad)
|
int GamePad::uid_to_index(int pad)
|
||||||
{
|
{
|
||||||
size_t uid = g_conf.get_joy_uid(pad);
|
size_t uid = g_conf.get_joy_uid(pad);
|
||||||
|
|
||||||
for (int i = 0; i < (int)s_vgamePad.size(); ++i) {
|
for (int i = 0; i < (int)s_vgamePad.size(); ++i)
|
||||||
if (s_vgamePad[i]->GetUniqueIdentifier() == uid)
|
{
|
||||||
return i;
|
if (s_vgamePad[i]->GetUniqueIdentifier() == uid)
|
||||||
}
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
// Current uid wasn't found maybe the pad was unplugged. Or
|
// Current uid wasn't found maybe the pad was unplugged. Or
|
||||||
// user didn't select it. Fallback to 1st pad for
|
// user didn't select it. Fallback to 1st pad for
|
||||||
// 1st player. And 2nd pad for 2nd player.
|
// 1st player. And 2nd pad for 2nd player.
|
||||||
if ((int)s_vgamePad.size() > pad)
|
if ((int)s_vgamePad.size() > pad)
|
||||||
return pad;
|
return pad;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,66 +25,66 @@
|
||||||
class GamePad
|
class GamePad
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GamePad()
|
GamePad()
|
||||||
: m_deadzone(1500)
|
: m_deadzone(1500)
|
||||||
, m_no_error(false)
|
, m_no_error(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~GamePad()
|
virtual ~GamePad()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GamePad(const GamePad &); // copy constructor
|
GamePad(const GamePad&); // copy constructor
|
||||||
GamePad &operator=(const GamePad &); // assignment
|
GamePad& operator=(const GamePad&); // assignment
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find every interesting devices and create right structure for them(depend on backend)
|
* Find every interesting devices and create right structure for them(depend on backend)
|
||||||
*/
|
*/
|
||||||
static void EnumerateGamePads(std::vector<std::unique_ptr<GamePad>> &vgamePad);
|
static void EnumerateGamePads(std::vector<std::unique_ptr<GamePad>>& vgamePad);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update state of every attached devices
|
* Update state of every attached devices
|
||||||
*/
|
*/
|
||||||
virtual void UpdateGamePadState() = 0;
|
virtual void UpdateGamePadState() = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Causes devices to rumble
|
* Causes devices to rumble
|
||||||
* Rumble will differ according to type which is either 0(small motor) or 1(big motor)
|
* Rumble will differ according to type which is either 0(small motor) or 1(big motor)
|
||||||
*/
|
*/
|
||||||
virtual void Rumble(unsigned type, unsigned pad) {}
|
virtual void Rumble(unsigned type, unsigned pad) {}
|
||||||
/*
|
/*
|
||||||
* Safely dispatch to the Rumble method above
|
* Safely dispatch to the Rumble method above
|
||||||
*/
|
*/
|
||||||
static void DoRumble(unsigned type, unsigned pad);
|
static void DoRumble(unsigned type, unsigned pad);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used for GUI checkbox to give feedback to the user
|
* Used for GUI checkbox to give feedback to the user
|
||||||
*/
|
*/
|
||||||
virtual bool TestForce(float strength = 0.6) { return false; }
|
virtual bool TestForce(float strength = 0.6) { return false; }
|
||||||
|
|
||||||
virtual const char *GetName() = 0;
|
virtual const char* GetName() = 0;
|
||||||
|
|
||||||
virtual int GetInput(gamePadValues input) = 0;
|
virtual int GetInput(gamePadValues input) = 0;
|
||||||
|
|
||||||
int GetDeadzone()
|
int GetDeadzone()
|
||||||
{
|
{
|
||||||
return m_deadzone;
|
return m_deadzone;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual size_t GetUniqueIdentifier() = 0;
|
virtual size_t GetUniqueIdentifier() = 0;
|
||||||
|
|
||||||
static size_t index_to_uid(int index);
|
static size_t index_to_uid(int index);
|
||||||
static int uid_to_index(int pad);
|
static int uid_to_index(int pad);
|
||||||
|
|
||||||
bool IsProperlyInitialized()
|
bool IsProperlyInitialized()
|
||||||
{
|
{
|
||||||
return m_no_error;
|
return m_no_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int m_deadzone;
|
int m_deadzone;
|
||||||
bool m_no_error;
|
bool m_no_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::vector<std::unique_ptr<GamePad>> s_vgamePad;
|
extern std::vector<std::unique_ptr<GamePad>> s_vgamePad;
|
||||||
|
|
|
@ -17,176 +17,187 @@
|
||||||
|
|
||||||
void KeyStatus::Init()
|
void KeyStatus::Init()
|
||||||
{
|
{
|
||||||
for (int pad = 0; pad < GAMEPAD_NUMBER; pad++) {
|
for (int pad = 0; pad < GAMEPAD_NUMBER; pad++)
|
||||||
m_button[pad] = 0xFFFF;
|
{
|
||||||
m_internal_button_kbd[pad] = 0xFFFF;
|
m_button[pad] = 0xFFFF;
|
||||||
m_internal_button_joy[pad] = 0xFFFF;
|
m_internal_button_kbd[pad] = 0xFFFF;
|
||||||
m_state_acces[pad] = false;
|
m_internal_button_joy[pad] = 0xFFFF;
|
||||||
|
m_state_acces[pad] = false;
|
||||||
|
|
||||||
for (int index = 0; index < MAX_KEYS; index++) {
|
for (int index = 0; index < MAX_KEYS; index++)
|
||||||
m_button_pressure[pad][index] = 0xFF;
|
{
|
||||||
m_internal_button_pressure[pad][index] = 0xFF;
|
m_button_pressure[pad][index] = 0xFF;
|
||||||
}
|
m_internal_button_pressure[pad][index] = 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
m_analog[pad].lx = m_analog_released_val;
|
m_analog[pad].lx = m_analog_released_val;
|
||||||
m_analog[pad].ly = m_analog_released_val;
|
m_analog[pad].ly = m_analog_released_val;
|
||||||
m_analog[pad].rx = m_analog_released_val;
|
m_analog[pad].rx = m_analog_released_val;
|
||||||
m_analog[pad].ry = m_analog_released_val;
|
m_analog[pad].ry = m_analog_released_val;
|
||||||
m_internal_analog_kbd[pad].lx = m_analog_released_val;
|
m_internal_analog_kbd[pad].lx = m_analog_released_val;
|
||||||
m_internal_analog_kbd[pad].ly = m_analog_released_val;
|
m_internal_analog_kbd[pad].ly = m_analog_released_val;
|
||||||
m_internal_analog_kbd[pad].rx = m_analog_released_val;
|
m_internal_analog_kbd[pad].rx = m_analog_released_val;
|
||||||
m_internal_analog_kbd[pad].ry = m_analog_released_val;
|
m_internal_analog_kbd[pad].ry = m_analog_released_val;
|
||||||
m_internal_analog_joy[pad].lx = m_analog_released_val;
|
m_internal_analog_joy[pad].lx = m_analog_released_val;
|
||||||
m_internal_analog_joy[pad].ly = m_analog_released_val;
|
m_internal_analog_joy[pad].ly = m_analog_released_val;
|
||||||
m_internal_analog_joy[pad].rx = m_analog_released_val;
|
m_internal_analog_joy[pad].rx = m_analog_released_val;
|
||||||
m_internal_analog_joy[pad].ry = m_analog_released_val;
|
m_internal_analog_joy[pad].ry = m_analog_released_val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyStatus::press(u32 pad, u32 index, s32 value)
|
void KeyStatus::press(u32 pad, u32 index, s32 value)
|
||||||
{
|
{
|
||||||
if (!IsAnalogKey(index)) {
|
if (!IsAnalogKey(index))
|
||||||
m_internal_button_pressure[pad][index] = value;
|
{
|
||||||
if (m_state_acces[pad])
|
m_internal_button_pressure[pad][index] = value;
|
||||||
clear_bit(m_internal_button_kbd[pad], index);
|
if (m_state_acces[pad])
|
||||||
else
|
clear_bit(m_internal_button_kbd[pad], index);
|
||||||
clear_bit(m_internal_button_joy[pad], index);
|
else
|
||||||
} else {
|
clear_bit(m_internal_button_joy[pad], index);
|
||||||
// clamp value
|
}
|
||||||
if (value > MAX_ANALOG_VALUE)
|
else
|
||||||
value = MAX_ANALOG_VALUE;
|
{
|
||||||
else if (value < -MAX_ANALOG_VALUE)
|
// clamp value
|
||||||
value = -MAX_ANALOG_VALUE;
|
if (value > MAX_ANALOG_VALUE)
|
||||||
|
value = MAX_ANALOG_VALUE;
|
||||||
|
else if (value < -MAX_ANALOG_VALUE)
|
||||||
|
value = -MAX_ANALOG_VALUE;
|
||||||
|
|
||||||
// Left -> -- -> Right
|
// Left -> -- -> Right
|
||||||
// Value range : FFFF8002 -> 0 -> 7FFE
|
// Value range : FFFF8002 -> 0 -> 7FFE
|
||||||
// Force range : 80 -> 0 -> 7F
|
// Force range : 80 -> 0 -> 7F
|
||||||
// Normal mode : expect value 0 -> 80 -> FF
|
// Normal mode : expect value 0 -> 80 -> FF
|
||||||
// Reverse mode: expect value FF -> 7F -> 0
|
// Reverse mode: expect value FF -> 7F -> 0
|
||||||
u8 force = (value / 256);
|
u8 force = (value / 256);
|
||||||
if (analog_is_reversed(pad, index))
|
if (analog_is_reversed(pad, index))
|
||||||
analog_set(pad, index, m_analog_released_val - force);
|
analog_set(pad, index, m_analog_released_val - force);
|
||||||
else
|
else
|
||||||
analog_set(pad, index, m_analog_released_val + force);
|
analog_set(pad, index, m_analog_released_val + force);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyStatus::release(u32 pad, u32 index)
|
void KeyStatus::release(u32 pad, u32 index)
|
||||||
{
|
{
|
||||||
if (!IsAnalogKey(index)) {
|
if (!IsAnalogKey(index))
|
||||||
if (m_state_acces[pad])
|
{
|
||||||
set_bit(m_internal_button_kbd[pad], index);
|
if (m_state_acces[pad])
|
||||||
else
|
set_bit(m_internal_button_kbd[pad], index);
|
||||||
set_bit(m_internal_button_joy[pad], index);
|
else
|
||||||
} else {
|
set_bit(m_internal_button_joy[pad], index);
|
||||||
analog_set(pad, index, m_analog_released_val);
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
analog_set(pad, index, m_analog_released_val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 KeyStatus::get(u32 pad)
|
u16 KeyStatus::get(u32 pad)
|
||||||
{
|
{
|
||||||
return m_button[pad];
|
return m_button[pad];
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyStatus::analog_set(u32 pad, u32 index, u8 value)
|
void KeyStatus::analog_set(u32 pad, u32 index, u8 value)
|
||||||
{
|
{
|
||||||
PADAnalog *m_internal_analog_ref;
|
PADAnalog* m_internal_analog_ref;
|
||||||
if (m_state_acces[pad])
|
if (m_state_acces[pad])
|
||||||
m_internal_analog_ref = &m_internal_analog_kbd[pad];
|
m_internal_analog_ref = &m_internal_analog_kbd[pad];
|
||||||
else
|
else
|
||||||
m_internal_analog_ref = &m_internal_analog_joy[pad];
|
m_internal_analog_ref = &m_internal_analog_joy[pad];
|
||||||
|
|
||||||
switch (index) {
|
switch (index)
|
||||||
case PAD_R_LEFT:
|
{
|
||||||
case PAD_R_RIGHT:
|
case PAD_R_LEFT:
|
||||||
m_internal_analog_ref->rx = value;
|
case PAD_R_RIGHT:
|
||||||
break;
|
m_internal_analog_ref->rx = value;
|
||||||
|
break;
|
||||||
|
|
||||||
case PAD_R_DOWN:
|
case PAD_R_DOWN:
|
||||||
case PAD_R_UP:
|
case PAD_R_UP:
|
||||||
m_internal_analog_ref->ry = value;
|
m_internal_analog_ref->ry = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAD_L_LEFT:
|
case PAD_L_LEFT:
|
||||||
case PAD_L_RIGHT:
|
case PAD_L_RIGHT:
|
||||||
m_internal_analog_ref->lx = value;
|
m_internal_analog_ref->lx = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAD_L_DOWN:
|
case PAD_L_DOWN:
|
||||||
case PAD_L_UP:
|
case PAD_L_UP:
|
||||||
m_internal_analog_ref->ly = value;
|
m_internal_analog_ref->ly = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KeyStatus::analog_is_reversed(u32 pad, u32 index)
|
bool KeyStatus::analog_is_reversed(u32 pad, u32 index)
|
||||||
{
|
{
|
||||||
switch (index) {
|
switch (index)
|
||||||
case PAD_L_RIGHT:
|
{
|
||||||
case PAD_L_LEFT:
|
case PAD_L_RIGHT:
|
||||||
return (g_conf.pad_options[pad].reverse_lx);
|
case PAD_L_LEFT:
|
||||||
|
return (g_conf.pad_options[pad].reverse_lx);
|
||||||
|
|
||||||
case PAD_R_LEFT:
|
case PAD_R_LEFT:
|
||||||
case PAD_R_RIGHT:
|
case PAD_R_RIGHT:
|
||||||
return (g_conf.pad_options[pad].reverse_rx);
|
return (g_conf.pad_options[pad].reverse_rx);
|
||||||
|
|
||||||
case PAD_L_UP:
|
case PAD_L_UP:
|
||||||
case PAD_L_DOWN:
|
case PAD_L_DOWN:
|
||||||
return (g_conf.pad_options[pad].reverse_ly);
|
return (g_conf.pad_options[pad].reverse_ly);
|
||||||
|
|
||||||
case PAD_R_DOWN:
|
case PAD_R_DOWN:
|
||||||
case PAD_R_UP:
|
case PAD_R_UP:
|
||||||
return (g_conf.pad_options[pad].reverse_ry);
|
return (g_conf.pad_options[pad].reverse_ry);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 KeyStatus::get(u32 pad, u32 index)
|
u8 KeyStatus::get(u32 pad, u32 index)
|
||||||
{
|
{
|
||||||
switch (index) {
|
switch (index)
|
||||||
case PAD_R_LEFT:
|
{
|
||||||
case PAD_R_RIGHT:
|
case PAD_R_LEFT:
|
||||||
return m_analog[pad].rx;
|
case PAD_R_RIGHT:
|
||||||
|
return m_analog[pad].rx;
|
||||||
|
|
||||||
case PAD_R_DOWN:
|
case PAD_R_DOWN:
|
||||||
case PAD_R_UP:
|
case PAD_R_UP:
|
||||||
return m_analog[pad].ry;
|
return m_analog[pad].ry;
|
||||||
|
|
||||||
case PAD_L_LEFT:
|
case PAD_L_LEFT:
|
||||||
case PAD_L_RIGHT:
|
case PAD_L_RIGHT:
|
||||||
return m_analog[pad].lx;
|
return m_analog[pad].lx;
|
||||||
|
|
||||||
case PAD_L_DOWN:
|
case PAD_L_DOWN:
|
||||||
case PAD_L_UP:
|
case PAD_L_UP:
|
||||||
return m_analog[pad].ly;
|
return m_analog[pad].ly;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return m_button_pressure[pad][index];
|
return m_button_pressure[pad][index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 KeyStatus::analog_merge(u8 kbd, u8 joy)
|
u8 KeyStatus::analog_merge(u8 kbd, u8 joy)
|
||||||
{
|
{
|
||||||
if (kbd != m_analog_released_val)
|
if (kbd != m_analog_released_val)
|
||||||
return kbd;
|
return kbd;
|
||||||
else
|
else
|
||||||
return joy;
|
return joy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyStatus::commit_status(u32 pad)
|
void KeyStatus::commit_status(u32 pad)
|
||||||
{
|
{
|
||||||
m_button[pad] = m_internal_button_kbd[pad] & m_internal_button_joy[pad];
|
m_button[pad] = m_internal_button_kbd[pad] & m_internal_button_joy[pad];
|
||||||
|
|
||||||
for (int index = 0; index < MAX_KEYS; index++)
|
for (int index = 0; index < MAX_KEYS; index++)
|
||||||
m_button_pressure[pad][index] = m_internal_button_pressure[pad][index];
|
m_button_pressure[pad][index] = m_internal_button_pressure[pad][index];
|
||||||
|
|
||||||
m_analog[pad].lx = analog_merge(m_internal_analog_kbd[pad].lx, m_internal_analog_joy[pad].lx);
|
m_analog[pad].lx = analog_merge(m_internal_analog_kbd[pad].lx, m_internal_analog_joy[pad].lx);
|
||||||
m_analog[pad].ly = analog_merge(m_internal_analog_kbd[pad].ly, m_internal_analog_joy[pad].ly);
|
m_analog[pad].ly = analog_merge(m_internal_analog_kbd[pad].ly, m_internal_analog_joy[pad].ly);
|
||||||
m_analog[pad].rx = analog_merge(m_internal_analog_kbd[pad].rx, m_internal_analog_joy[pad].rx);
|
m_analog[pad].rx = analog_merge(m_internal_analog_kbd[pad].rx, m_internal_analog_joy[pad].rx);
|
||||||
m_analog[pad].ry = analog_merge(m_internal_analog_kbd[pad].ry, m_internal_analog_joy[pad].ry);
|
m_analog[pad].ry = analog_merge(m_internal_analog_kbd[pad].ry, m_internal_analog_joy[pad].ry);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
u8 lx, ly;
|
u8 lx, ly;
|
||||||
u8 rx, ry;
|
u8 rx, ry;
|
||||||
} PADAnalog;
|
} PADAnalog;
|
||||||
|
|
||||||
#define MAX_ANALOG_VALUE 32766
|
#define MAX_ANALOG_VALUE 32766
|
||||||
|
@ -29,44 +29,44 @@ typedef struct
|
||||||
class KeyStatus
|
class KeyStatus
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
const u8 m_analog_released_val;
|
const u8 m_analog_released_val;
|
||||||
|
|
||||||
u16 m_button[GAMEPAD_NUMBER];
|
u16 m_button[GAMEPAD_NUMBER];
|
||||||
u16 m_internal_button_kbd[GAMEPAD_NUMBER];
|
u16 m_internal_button_kbd[GAMEPAD_NUMBER];
|
||||||
u16 m_internal_button_joy[GAMEPAD_NUMBER];
|
u16 m_internal_button_joy[GAMEPAD_NUMBER];
|
||||||
|
|
||||||
u8 m_button_pressure[GAMEPAD_NUMBER][MAX_KEYS];
|
u8 m_button_pressure[GAMEPAD_NUMBER][MAX_KEYS];
|
||||||
u8 m_internal_button_pressure[GAMEPAD_NUMBER][MAX_KEYS];
|
u8 m_internal_button_pressure[GAMEPAD_NUMBER][MAX_KEYS];
|
||||||
|
|
||||||
bool m_state_acces[GAMEPAD_NUMBER];
|
bool m_state_acces[GAMEPAD_NUMBER];
|
||||||
|
|
||||||
PADAnalog m_analog[GAMEPAD_NUMBER];
|
PADAnalog m_analog[GAMEPAD_NUMBER];
|
||||||
PADAnalog m_internal_analog_kbd[GAMEPAD_NUMBER];
|
PADAnalog m_internal_analog_kbd[GAMEPAD_NUMBER];
|
||||||
PADAnalog m_internal_analog_joy[GAMEPAD_NUMBER];
|
PADAnalog m_internal_analog_joy[GAMEPAD_NUMBER];
|
||||||
|
|
||||||
void analog_set(u32 pad, u32 index, u8 value);
|
void analog_set(u32 pad, u32 index, u8 value);
|
||||||
bool analog_is_reversed(u32 pad, u32 index);
|
bool analog_is_reversed(u32 pad, u32 index);
|
||||||
u8 analog_merge(u8 kbd, u8 joy);
|
u8 analog_merge(u8 kbd, u8 joy);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
KeyStatus()
|
KeyStatus()
|
||||||
: m_analog_released_val(0x7F)
|
: m_analog_released_val(0x7F)
|
||||||
{
|
{
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
void keyboard_state_acces(u32 pad) { m_state_acces[pad] = true; }
|
void keyboard_state_acces(u32 pad) { m_state_acces[pad] = true; }
|
||||||
void joystick_state_acces(u32 pad) { m_state_acces[pad] = false; }
|
void joystick_state_acces(u32 pad) { m_state_acces[pad] = false; }
|
||||||
|
|
||||||
void press(u32 pad, u32 index, s32 value = 0xFF);
|
void press(u32 pad, u32 index, s32 value = 0xFF);
|
||||||
void release(u32 pad, u32 index);
|
void release(u32 pad, u32 index);
|
||||||
|
|
||||||
u16 get(u32 pad);
|
u16 get(u32 pad);
|
||||||
u8 get(u32 pad, u32 index);
|
u8 get(u32 pad, u32 index);
|
||||||
|
|
||||||
|
|
||||||
void commit_status(u32 pad);
|
void commit_status(u32 pad);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern KeyStatus g_key_status;
|
extern KeyStatus g_key_status;
|
||||||
|
|
|
@ -41,240 +41,255 @@ static keyEvent s_event;
|
||||||
std::string s_padstrIniPath("inis/");
|
std::string s_padstrIniPath("inis/");
|
||||||
std::string s_padstrLogPath("logs/");
|
std::string s_padstrLogPath("logs/");
|
||||||
|
|
||||||
FILE *padLog = NULL;
|
FILE* padLog = NULL;
|
||||||
|
|
||||||
KeyStatus g_key_status;
|
KeyStatus g_key_status;
|
||||||
|
|
||||||
MtQueue<keyEvent> g_ev_fifo;
|
MtQueue<keyEvent> g_ev_fifo;
|
||||||
|
|
||||||
|
|
||||||
void __LogToConsole(const char *fmt, ...)
|
void __LogToConsole(const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list list;
|
va_list list;
|
||||||
|
|
||||||
va_start(list, fmt);
|
va_start(list, fmt);
|
||||||
|
|
||||||
if (padLog != NULL)
|
if (padLog != NULL)
|
||||||
vfprintf(padLog, fmt, list);
|
vfprintf(padLog, fmt, list);
|
||||||
|
|
||||||
printf("OnePAD: ");
|
printf("OnePAD: ");
|
||||||
vprintf(fmt, list);
|
vprintf(fmt, list);
|
||||||
va_end(list);
|
va_end(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initLogging()
|
void initLogging()
|
||||||
{
|
{
|
||||||
#ifdef PAD_LOG
|
#ifdef PAD_LOG
|
||||||
if (padLog)
|
if (padLog)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const std::string LogFile(s_padstrLogPath + "padLog.txt");
|
const std::string LogFile(s_padstrLogPath + "padLog.txt");
|
||||||
padLog = fopen(LogFile.c_str(), "w");
|
padLog = fopen(LogFile.c_str(), "w");
|
||||||
|
|
||||||
if (padLog)
|
if (padLog)
|
||||||
setvbuf(padLog, NULL, _IONBF, 0);
|
setvbuf(padLog, NULL, _IONBF, 0);
|
||||||
|
|
||||||
PAD_LOG("PADinit\n");
|
PAD_LOG("PADinit\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseLogging()
|
void CloseLogging()
|
||||||
{
|
{
|
||||||
#ifdef PAD_LOG
|
#ifdef PAD_LOG
|
||||||
if (padLog) {
|
if (padLog)
|
||||||
fclose(padLog);
|
{
|
||||||
padLog = NULL;
|
fclose(padLog);
|
||||||
}
|
padLog = NULL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PADinit()
|
s32 PADinit()
|
||||||
{
|
{
|
||||||
initLogging();
|
initLogging();
|
||||||
|
|
||||||
PADLoadConfig();
|
PADLoadConfig();
|
||||||
|
|
||||||
Pad::reset_all();
|
Pad::reset_all();
|
||||||
|
|
||||||
query.reset();
|
query.reset();
|
||||||
|
|
||||||
for (int port = 0; port < 2; port++)
|
for (int port = 0; port < 2; port++)
|
||||||
slots[port] = 0;
|
slots[port] = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PADshutdown()
|
void PADshutdown()
|
||||||
{
|
{
|
||||||
CloseLogging();
|
CloseLogging();
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PADopen(void *pDsp)
|
s32 PADopen(void* pDsp)
|
||||||
{
|
{
|
||||||
memset(&event, 0, sizeof(event));
|
memset(&event, 0, sizeof(event));
|
||||||
g_key_status.Init();
|
g_key_status.Init();
|
||||||
|
|
||||||
g_ev_fifo.reset();
|
g_ev_fifo.reset();
|
||||||
|
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
#if defined(__unix__) || defined(__APPLE__)
|
||||||
GamePad::EnumerateGamePads(s_vgamePad);
|
GamePad::EnumerateGamePads(s_vgamePad);
|
||||||
#endif
|
#endif
|
||||||
return _PADopen(pDsp);
|
return _PADopen(pDsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PADsetSettingsDir(const char *dir)
|
void PADsetSettingsDir(const char* dir)
|
||||||
{
|
{
|
||||||
// Get the path to the ini directory.
|
// Get the path to the ini directory.
|
||||||
s_padstrIniPath = (dir == NULL) ? "inis/" : dir;
|
s_padstrIniPath = (dir == NULL) ? "inis/" : dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PADsetLogDir(const char *dir)
|
void PADsetLogDir(const char* dir)
|
||||||
{
|
{
|
||||||
// Get the path to the log directory.
|
// Get the path to the log directory.
|
||||||
s_padstrLogPath = (dir == NULL) ? "logs/" : dir;
|
s_padstrLogPath = (dir == NULL) ? "logs/" : dir;
|
||||||
|
|
||||||
// Reload the log file after updated the path
|
// Reload the log file after updated the path
|
||||||
CloseLogging();
|
CloseLogging();
|
||||||
initLogging();
|
initLogging();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PADclose()
|
void PADclose()
|
||||||
{
|
{
|
||||||
_PADclose();
|
_PADclose();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 PADquery()
|
u32 PADquery()
|
||||||
{
|
{
|
||||||
return 3; // both
|
return 3; // both
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PADsetSlot(u8 port, u8 slot)
|
s32 PADsetSlot(u8 port, u8 slot)
|
||||||
{
|
{
|
||||||
port--;
|
port--;
|
||||||
slot--;
|
slot--;
|
||||||
if (port > 1 || slot > 3) {
|
if (port > 1 || slot > 3)
|
||||||
return 0;
|
{
|
||||||
}
|
return 0;
|
||||||
// Even if no pad there, record the slot, as it is the active slot regardless.
|
}
|
||||||
slots[port] = slot;
|
// Even if no pad there, record the slot, as it is the active slot regardless.
|
||||||
|
slots[port] = slot;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PADfreeze(int mode, freezeData *data)
|
s32 PADfreeze(int mode, freezeData* data)
|
||||||
{
|
{
|
||||||
if (!data)
|
if (!data)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (mode == FREEZE_SIZE) {
|
if (mode == FREEZE_SIZE)
|
||||||
data->size = sizeof(PadPluginFreezeData);
|
{
|
||||||
|
data->size = sizeof(PadPluginFreezeData);
|
||||||
|
}
|
||||||
|
else if (mode == FREEZE_LOAD)
|
||||||
|
{
|
||||||
|
PadPluginFreezeData* pdata = (PadPluginFreezeData*)(data->data);
|
||||||
|
|
||||||
} else if (mode == FREEZE_LOAD) {
|
Pad::stop_vibrate_all();
|
||||||
PadPluginFreezeData *pdata = (PadPluginFreezeData *)(data->data);
|
|
||||||
|
|
||||||
Pad::stop_vibrate_all();
|
if (data->size != sizeof(PadPluginFreezeData) || pdata->version != PAD_SAVE_STATE_VERSION ||
|
||||||
|
strncmp(pdata->format, "OnePad", sizeof(pdata->format)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (data->size != sizeof(PadPluginFreezeData) || pdata->version != PAD_SAVE_STATE_VERSION ||
|
query = pdata->query;
|
||||||
strncmp(pdata->format, "OnePad", sizeof(pdata->format)))
|
if (pdata->query.slot < 4)
|
||||||
return 0;
|
{
|
||||||
|
query = pdata->query;
|
||||||
|
}
|
||||||
|
|
||||||
query = pdata->query;
|
// Tales of the Abyss - pad fix
|
||||||
if (pdata->query.slot < 4) {
|
// - restore data for both ports
|
||||||
query = pdata->query;
|
for (int port = 0; port < 2; port++)
|
||||||
}
|
{
|
||||||
|
for (int slot = 0; slot < 4; slot++)
|
||||||
|
{
|
||||||
|
u8 mode = pdata->padData[port][slot].mode;
|
||||||
|
|
||||||
// Tales of the Abyss - pad fix
|
if (mode != MODE_DIGITAL && mode != MODE_ANALOG && mode != MODE_DS2_NATIVE)
|
||||||
// - restore data for both ports
|
{
|
||||||
for (int port = 0; port < 2; port++) {
|
break;
|
||||||
for (int slot = 0; slot < 4; slot++) {
|
}
|
||||||
u8 mode = pdata->padData[port][slot].mode;
|
|
||||||
|
|
||||||
if (mode != MODE_DIGITAL && mode != MODE_ANALOG && mode != MODE_DS2_NATIVE) {
|
memcpy(&pads[port][slot], &pdata->padData[port][slot], sizeof(PadFreezeData));
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&pads[port][slot], &pdata->padData[port][slot], sizeof(PadFreezeData));
|
if (pdata->slot[port] < 4)
|
||||||
}
|
slots[port] = pdata->slot[port];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mode == FREEZE_SAVE)
|
||||||
|
{
|
||||||
|
if (data->size != sizeof(PadPluginFreezeData))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (pdata->slot[port] < 4)
|
PadPluginFreezeData* pdata = (PadPluginFreezeData*)(data->data);
|
||||||
slots[port] = pdata->slot[port];
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (mode == FREEZE_SAVE) {
|
// Tales of the Abyss - pad fix
|
||||||
if (data->size != sizeof(PadPluginFreezeData))
|
// - PCSX2 only saves port0 (save #1), then port1 (save #2)
|
||||||
return 0;
|
|
||||||
|
|
||||||
PadPluginFreezeData *pdata = (PadPluginFreezeData *)(data->data);
|
memset(pdata, 0, data->size);
|
||||||
|
strncpy(pdata->format, "OnePad", sizeof(pdata->format));
|
||||||
|
pdata->version = PAD_SAVE_STATE_VERSION;
|
||||||
|
pdata->query = query;
|
||||||
|
|
||||||
// Tales of the Abyss - pad fix
|
for (int port = 0; port < 2; port++)
|
||||||
// - PCSX2 only saves port0 (save #1), then port1 (save #2)
|
{
|
||||||
|
for (int slot = 0; slot < 4; slot++)
|
||||||
|
{
|
||||||
|
pdata->padData[port][slot] = pads[port][slot];
|
||||||
|
}
|
||||||
|
|
||||||
memset(pdata, 0, data->size);
|
pdata->slot[port] = slots[port];
|
||||||
strncpy(pdata->format, "OnePad", sizeof(pdata->format));
|
}
|
||||||
pdata->version = PAD_SAVE_STATE_VERSION;
|
}
|
||||||
pdata->query = query;
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (int port = 0; port < 2; port++) {
|
return 0;
|
||||||
for (int slot = 0; slot < 4; slot++) {
|
|
||||||
pdata->padData[port][slot] = pads[port][slot];
|
|
||||||
}
|
|
||||||
|
|
||||||
pdata->slot[port] = slots[port];
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 PADstartPoll(int pad)
|
u8 PADstartPoll(int pad)
|
||||||
{
|
{
|
||||||
return pad_start_poll(pad);
|
return pad_start_poll(pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 PADpoll(u8 value)
|
u8 PADpoll(u8 value)
|
||||||
{
|
{
|
||||||
return pad_poll(value);
|
return pad_poll(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PADkeyEvent is called every vsync (return NULL if no event)
|
// PADkeyEvent is called every vsync (return NULL if no event)
|
||||||
keyEvent * PADkeyEvent()
|
keyEvent* PADkeyEvent()
|
||||||
{
|
{
|
||||||
#ifdef SDL_BUILD
|
#ifdef SDL_BUILD
|
||||||
// Take the opportunity to handle hot plugging here
|
// Take the opportunity to handle hot plugging here
|
||||||
SDL_Event events;
|
SDL_Event events;
|
||||||
while (SDL_PollEvent(&events)) {
|
while (SDL_PollEvent(&events))
|
||||||
switch (events.type) {
|
{
|
||||||
case SDL_CONTROLLERDEVICEADDED:
|
switch (events.type)
|
||||||
case SDL_CONTROLLERDEVICEREMOVED:
|
{
|
||||||
GamePad::EnumerateGamePads(s_vgamePad);
|
case SDL_CONTROLLERDEVICEADDED:
|
||||||
break;
|
case SDL_CONTROLLERDEVICEREMOVED:
|
||||||
default:
|
GamePad::EnumerateGamePads(s_vgamePad);
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (g_ev_fifo.size() == 0) {
|
if (g_ev_fifo.size() == 0)
|
||||||
// PAD_LOG("No events in queue, returning empty event\n");
|
{
|
||||||
s_event = event;
|
// PAD_LOG("No events in queue, returning empty event\n");
|
||||||
event.evt = 0;
|
s_event = event;
|
||||||
event.key = 0;
|
event.evt = 0;
|
||||||
return &s_event;
|
event.key = 0;
|
||||||
}
|
return &s_event;
|
||||||
s_event = g_ev_fifo.dequeue();
|
}
|
||||||
AnalyzeKeyEvent(s_event);
|
s_event = g_ev_fifo.dequeue();
|
||||||
// PAD_LOG("Returning Event. Event Type: %d, Key: %d\n", s_event.evt, s_event.key);
|
AnalyzeKeyEvent(s_event);
|
||||||
return &s_event;
|
// PAD_LOG("Returning Event. Event Type: %d, Key: %d\n", s_event.evt, s_event.key);
|
||||||
|
return &s_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__unix__)
|
#if defined(__unix__)
|
||||||
void PADWriteEvent(keyEvent &evt)
|
void PADWriteEvent(keyEvent& evt)
|
||||||
{
|
{
|
||||||
// if (evt.evt != 6) { // Skip mouse move events for logging
|
// if (evt.evt != 6) { // Skip mouse move events for logging
|
||||||
// PAD_LOG("Pushing Event. Event Type: %d, Key: %d\n", evt.evt, evt.key);
|
// PAD_LOG("Pushing Event. Event Type: %d, Key: %d\n", evt.evt, evt.key);
|
||||||
// }
|
// }
|
||||||
g_ev_fifo.push(evt);
|
g_ev_fifo.push(evt);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -43,55 +43,58 @@
|
||||||
|
|
||||||
#define PADdefs
|
#define PADdefs
|
||||||
|
|
||||||
enum PadOptions {
|
enum PadOptions
|
||||||
PADOPTION_FORCEFEEDBACK = 0x1,
|
{
|
||||||
PADOPTION_REVERSELX = 0x2,
|
PADOPTION_FORCEFEEDBACK = 0x1,
|
||||||
PADOPTION_REVERSELY = 0x4,
|
PADOPTION_REVERSELX = 0x2,
|
||||||
PADOPTION_REVERSERX = 0x8,
|
PADOPTION_REVERSELY = 0x4,
|
||||||
PADOPTION_REVERSERY = 0x10,
|
PADOPTION_REVERSERX = 0x8,
|
||||||
PADOPTION_MOUSE_L = 0x20,
|
PADOPTION_REVERSERY = 0x10,
|
||||||
PADOPTION_MOUSE_R = 0x40,
|
PADOPTION_MOUSE_L = 0x20,
|
||||||
|
PADOPTION_MOUSE_R = 0x40,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PadCommands {
|
enum PadCommands
|
||||||
CMD_SET_VREF_PARAM = 0x40,
|
{
|
||||||
CMD_QUERY_DS2_ANALOG_MODE = 0x41,
|
CMD_SET_VREF_PARAM = 0x40,
|
||||||
CMD_READ_DATA_AND_VIBRATE = 0x42,
|
CMD_QUERY_DS2_ANALOG_MODE = 0x41,
|
||||||
CMD_CONFIG_MODE = 0x43,
|
CMD_READ_DATA_AND_VIBRATE = 0x42,
|
||||||
CMD_SET_MODE_AND_LOCK = 0x44,
|
CMD_CONFIG_MODE = 0x43,
|
||||||
CMD_QUERY_MODEL_AND_MODE = 0x45,
|
CMD_SET_MODE_AND_LOCK = 0x44,
|
||||||
CMD_QUERY_ACT = 0x46, // ??
|
CMD_QUERY_MODEL_AND_MODE = 0x45,
|
||||||
CMD_QUERY_COMB = 0x47, // ??
|
CMD_QUERY_ACT = 0x46, // ??
|
||||||
CMD_QUERY_MODE = 0x4C, // QUERY_MODE ??
|
CMD_QUERY_COMB = 0x47, // ??
|
||||||
CMD_VIBRATION_TOGGLE = 0x4D,
|
CMD_QUERY_MODE = 0x4C, // QUERY_MODE ??
|
||||||
CMD_SET_DS2_NATIVE_MODE = 0x4F // SET_DS2_NATIVE_MODE
|
CMD_VIBRATION_TOGGLE = 0x4D,
|
||||||
|
CMD_SET_DS2_NATIVE_MODE = 0x4F // SET_DS2_NATIVE_MODE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum gamePadValues {
|
enum gamePadValues
|
||||||
PAD_L2 = 0, // L2 button
|
{
|
||||||
PAD_R2, // R2 button
|
PAD_L2 = 0, // L2 button
|
||||||
PAD_L1, // L1 button
|
PAD_R2, // R2 button
|
||||||
PAD_R1, // R1 button
|
PAD_L1, // L1 button
|
||||||
PAD_TRIANGLE, // Triangle button ▲
|
PAD_R1, // R1 button
|
||||||
PAD_CIRCLE, // Circle button ●
|
PAD_TRIANGLE, // Triangle button ▲
|
||||||
PAD_CROSS, // Cross button ✖
|
PAD_CIRCLE, // Circle button ●
|
||||||
PAD_SQUARE, // Square button ■
|
PAD_CROSS, // Cross button ✖
|
||||||
PAD_SELECT, // Select button
|
PAD_SQUARE, // Square button ■
|
||||||
PAD_L3, // Left joystick button (L3)
|
PAD_SELECT, // Select button
|
||||||
PAD_R3, // Right joystick button (R3)
|
PAD_L3, // Left joystick button (L3)
|
||||||
PAD_START, // Start button
|
PAD_R3, // Right joystick button (R3)
|
||||||
PAD_UP, // Directional pad ↑
|
PAD_START, // Start button
|
||||||
PAD_RIGHT, // Directional pad →
|
PAD_UP, // Directional pad ↑
|
||||||
PAD_DOWN, // Directional pad ↓
|
PAD_RIGHT, // Directional pad →
|
||||||
PAD_LEFT, // Directional pad ←
|
PAD_DOWN, // Directional pad ↓
|
||||||
PAD_L_UP, // Left joystick (Up) ↑
|
PAD_LEFT, // Directional pad ←
|
||||||
PAD_L_RIGHT, // Left joystick (Right) →
|
PAD_L_UP, // Left joystick (Up) ↑
|
||||||
PAD_L_DOWN, // Left joystick (Down) ↓
|
PAD_L_RIGHT, // Left joystick (Right) →
|
||||||
PAD_L_LEFT, // Left joystick (Left) ←
|
PAD_L_DOWN, // Left joystick (Down) ↓
|
||||||
PAD_R_UP, // Right joystick (Up) ↑
|
PAD_L_LEFT, // Left joystick (Left) ←
|
||||||
PAD_R_RIGHT, // Right joystick (Right) →
|
PAD_R_UP, // Right joystick (Up) ↑
|
||||||
PAD_R_DOWN, // Right joystick (Down) ↓
|
PAD_R_RIGHT, // Right joystick (Right) →
|
||||||
PAD_R_LEFT // Right joystick (Left) ←
|
PAD_R_DOWN, // Right joystick (Down) ↓
|
||||||
|
PAD_R_LEFT // Right joystick (Left) ←
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
#if defined(__unix__) || defined(__APPLE__)
|
||||||
|
@ -102,7 +105,7 @@ enum gamePadValues {
|
||||||
#include "KeyStatus.h"
|
#include "KeyStatus.h"
|
||||||
#include "mt_queue.h"
|
#include "mt_queue.h"
|
||||||
|
|
||||||
extern FILE *padLog;
|
extern FILE* padLog;
|
||||||
extern void initLogging();
|
extern void initLogging();
|
||||||
|
|
||||||
//#define PAD_LOG __Log
|
//#define PAD_LOG __Log
|
||||||
|
@ -111,31 +114,31 @@ extern void initLogging();
|
||||||
extern keyEvent event;
|
extern keyEvent event;
|
||||||
extern MtQueue<keyEvent> g_ev_fifo;
|
extern MtQueue<keyEvent> g_ev_fifo;
|
||||||
|
|
||||||
s32 _PADopen(void *pDsp);
|
s32 _PADopen(void* pDsp);
|
||||||
void _PADclose();
|
void _PADclose();
|
||||||
void PADsetMode(int pad, int mode);
|
void PADsetMode(int pad, int mode);
|
||||||
|
|
||||||
void __LogToConsole(const char *fmt, ...);
|
void __LogToConsole(const char* fmt, ...);
|
||||||
void PADLoadConfig();
|
void PADLoadConfig();
|
||||||
void PADSaveConfig();
|
void PADSaveConfig();
|
||||||
|
|
||||||
void SysMessage(char *fmt, ...);
|
void SysMessage(char* fmt, ...);
|
||||||
|
|
||||||
s32 PADinit();
|
s32 PADinit();
|
||||||
void PADshutdown();
|
void PADshutdown();
|
||||||
s32 PADopen(void *pDsp);
|
s32 PADopen(void* pDsp);
|
||||||
void PADsetSettingsDir(const char *dir);
|
void PADsetSettingsDir(const char* dir);
|
||||||
void PADsetLogDir(const char *dir);
|
void PADsetLogDir(const char* dir);
|
||||||
void PADclose();
|
void PADclose();
|
||||||
u32 PADquery();
|
u32 PADquery();
|
||||||
s32 PADsetSlot(u8 port, u8 slot);
|
s32 PADsetSlot(u8 port, u8 slot);
|
||||||
s32 PADfreeze(int mode, freezeData *data);
|
s32 PADfreeze(int mode, freezeData* data);
|
||||||
u8 PADstartPoll(int pad);
|
u8 PADstartPoll(int pad);
|
||||||
u8 PADpoll(u8 value);
|
u8 PADpoll(u8 value);
|
||||||
keyEvent * PADkeyEvent();
|
keyEvent* PADkeyEvent();
|
||||||
void PADupdate(int pad);
|
void PADupdate(int pad);
|
||||||
void PADconfigure();
|
void PADconfigure();
|
||||||
|
|
||||||
#if defined(__unix__)
|
#if defined(__unix__)
|
||||||
void PADWriteEvent(keyEvent &evt);
|
void PADWriteEvent(keyEvent& evt);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,263 +22,284 @@
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
// opens handles to all possible joysticks
|
// opens handles to all possible joysticks
|
||||||
void JoystickInfo::EnumerateJoysticks(std::vector<std::unique_ptr<GamePad>> &vjoysticks)
|
void JoystickInfo::EnumerateJoysticks(std::vector<std::unique_ptr<GamePad>>& vjoysticks)
|
||||||
{
|
{
|
||||||
uint32_t flag = SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_EVENTS | SDL_INIT_GAMECONTROLLER;
|
uint32_t flag = SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_EVENTS | SDL_INIT_GAMECONTROLLER;
|
||||||
|
|
||||||
if ((SDL_WasInit(0) & flag) != flag) {
|
if ((SDL_WasInit(0) & flag) != flag)
|
||||||
// Tell SDL to catch event even if the windows isn't focussed
|
{
|
||||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
// Tell SDL to catch event even if the windows isn't focussed
|
||||||
|
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
||||||
|
|
||||||
if (SDL_Init(flag) < 0)
|
if (SDL_Init(flag) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// WTF! Give me back the control of my system
|
// WTF! Give me back the control of my system
|
||||||
struct sigaction action = {};
|
struct sigaction action = {};
|
||||||
action.sa_handler = SIG_DFL;
|
action.sa_handler = SIG_DFL;
|
||||||
sigaction(SIGINT, &action, nullptr);
|
sigaction(SIGINT, &action, nullptr);
|
||||||
sigaction(SIGTERM, &action, nullptr);
|
sigaction(SIGTERM, &action, nullptr);
|
||||||
|
|
||||||
SDL_JoystickEventState(SDL_QUERY);
|
SDL_JoystickEventState(SDL_QUERY);
|
||||||
SDL_GameControllerEventState(SDL_QUERY);
|
SDL_GameControllerEventState(SDL_QUERY);
|
||||||
SDL_EventState(SDL_CONTROLLERDEVICEADDED, SDL_ENABLE);
|
SDL_EventState(SDL_CONTROLLERDEVICEADDED, SDL_ENABLE);
|
||||||
SDL_EventState(SDL_CONTROLLERDEVICEREMOVED, SDL_ENABLE);
|
SDL_EventState(SDL_CONTROLLERDEVICEREMOVED, SDL_ENABLE);
|
||||||
|
|
||||||
{ // Support as much Joystick as possible
|
{ // Support as much Joystick as possible
|
||||||
GBytes *bytes = g_resource_lookup_data(PAD_res_get_resource(), "/PAD/res/game_controller_db.txt", G_RESOURCE_LOOKUP_FLAGS_NONE, nullptr);
|
GBytes* bytes = g_resource_lookup_data(PAD_res_get_resource(), "/PAD/res/game_controller_db.txt", G_RESOURCE_LOOKUP_FLAGS_NONE, nullptr);
|
||||||
|
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
// SDL forget to add const for SDL_RWFromMem API...
|
// SDL forget to add const for SDL_RWFromMem API...
|
||||||
void *data = const_cast<void *>(g_bytes_get_data(bytes, &size));
|
void* data = const_cast<void*>(g_bytes_get_data(bytes, &size));
|
||||||
|
|
||||||
SDL_GameControllerAddMappingsFromRW(SDL_RWFromMem(data, size), 1);
|
SDL_GameControllerAddMappingsFromRW(SDL_RWFromMem(data, size), 1);
|
||||||
|
|
||||||
g_bytes_unref(bytes);
|
g_bytes_unref(bytes);
|
||||||
|
|
||||||
// Add user mapping too
|
// Add user mapping too
|
||||||
for (auto const &map : g_conf.sdl2_mapping)
|
for (auto const& map : g_conf.sdl2_mapping)
|
||||||
SDL_GameControllerAddMapping(map.c_str());
|
SDL_GameControllerAddMapping(map.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vjoysticks.clear();
|
vjoysticks.clear();
|
||||||
|
|
||||||
for (int i = 0; i < SDL_NumJoysticks(); ++i) {
|
for (int i = 0; i < SDL_NumJoysticks(); ++i)
|
||||||
vjoysticks.push_back(std::unique_ptr<GamePad>(new JoystickInfo(i)));
|
{
|
||||||
// Something goes wrong in the init, let's drop it
|
vjoysticks.push_back(std::unique_ptr<GamePad>(new JoystickInfo(i)));
|
||||||
if (!vjoysticks.back()->IsProperlyInitialized())
|
// Something goes wrong in the init, let's drop it
|
||||||
vjoysticks.pop_back();
|
if (!vjoysticks.back()->IsProperlyInitialized())
|
||||||
}
|
vjoysticks.pop_back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoystickInfo::Rumble(unsigned type, unsigned pad)
|
void JoystickInfo::Rumble(unsigned type, unsigned pad)
|
||||||
{
|
{
|
||||||
if (type >= m_effects_id.size())
|
if (type >= m_effects_id.size())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(g_conf.pad_options[pad].forcefeedback))
|
if (!(g_conf.pad_options[pad].forcefeedback))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_haptic == nullptr)
|
if (m_haptic == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int id = m_effects_id[type];
|
int id = m_effects_id[type];
|
||||||
if (SDL_HapticRunEffect(m_haptic, id, 1) != 0) {
|
if (SDL_HapticRunEffect(m_haptic, id, 1) != 0)
|
||||||
fprintf(stderr, "ERROR: Effect is not working! %s, id is %d\n", SDL_GetError(), id);
|
{
|
||||||
}
|
fprintf(stderr, "ERROR: Effect is not working! %s, id is %d\n", SDL_GetError(), id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JoystickInfo::~JoystickInfo()
|
JoystickInfo::~JoystickInfo()
|
||||||
{
|
{
|
||||||
// Haptic must be closed before the joystick
|
// Haptic must be closed before the joystick
|
||||||
if (m_haptic != nullptr) {
|
if (m_haptic != nullptr)
|
||||||
for (const auto &eid : m_effects_id) {
|
{
|
||||||
if (eid >= 0)
|
for (const auto& eid : m_effects_id)
|
||||||
SDL_HapticDestroyEffect(m_haptic, eid);
|
{
|
||||||
}
|
if (eid >= 0)
|
||||||
|
SDL_HapticDestroyEffect(m_haptic, eid);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_HapticClose(m_haptic);
|
SDL_HapticClose(m_haptic);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_controller != nullptr) {
|
if (m_controller != nullptr)
|
||||||
|
{
|
||||||
#if SDL_MINOR_VERSION >= 4
|
#if SDL_MINOR_VERSION >= 4
|
||||||
// Version before 2.0.4 are bugged, JoystickClose crashes randomly
|
// Version before 2.0.4 are bugged, JoystickClose crashes randomly
|
||||||
// Note: GameControllerClose calls JoystickClose)
|
// Note: GameControllerClose calls JoystickClose)
|
||||||
SDL_GameControllerClose(m_controller);
|
SDL_GameControllerClose(m_controller);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JoystickInfo::JoystickInfo(int id)
|
JoystickInfo::JoystickInfo(int id)
|
||||||
: GamePad()
|
: GamePad()
|
||||||
, m_controller(nullptr)
|
, m_controller(nullptr)
|
||||||
, m_haptic(nullptr)
|
, m_haptic(nullptr)
|
||||||
, m_unique_id(0)
|
, m_unique_id(0)
|
||||||
{
|
{
|
||||||
SDL_Joystick *joy = nullptr;
|
SDL_Joystick* joy = nullptr;
|
||||||
m_effects_id.fill(-1);
|
m_effects_id.fill(-1);
|
||||||
// Values are hardcoded currently but it could be later extended to allow remapping of the buttons
|
// Values are hardcoded currently but it could be later extended to allow remapping of the buttons
|
||||||
m_pad_to_sdl[PAD_L2] = SDL_CONTROLLER_AXIS_TRIGGERLEFT;
|
m_pad_to_sdl[PAD_L2] = SDL_CONTROLLER_AXIS_TRIGGERLEFT;
|
||||||
m_pad_to_sdl[PAD_R2] = SDL_CONTROLLER_AXIS_TRIGGERRIGHT;
|
m_pad_to_sdl[PAD_R2] = SDL_CONTROLLER_AXIS_TRIGGERRIGHT;
|
||||||
m_pad_to_sdl[PAD_L1] = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
|
m_pad_to_sdl[PAD_L1] = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
|
||||||
m_pad_to_sdl[PAD_R1] = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
|
m_pad_to_sdl[PAD_R1] = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
|
||||||
m_pad_to_sdl[PAD_TRIANGLE] = SDL_CONTROLLER_BUTTON_Y;
|
m_pad_to_sdl[PAD_TRIANGLE] = SDL_CONTROLLER_BUTTON_Y;
|
||||||
m_pad_to_sdl[PAD_CIRCLE] = SDL_CONTROLLER_BUTTON_B;
|
m_pad_to_sdl[PAD_CIRCLE] = SDL_CONTROLLER_BUTTON_B;
|
||||||
m_pad_to_sdl[PAD_CROSS] = SDL_CONTROLLER_BUTTON_A;
|
m_pad_to_sdl[PAD_CROSS] = SDL_CONTROLLER_BUTTON_A;
|
||||||
m_pad_to_sdl[PAD_SQUARE] = SDL_CONTROLLER_BUTTON_X;
|
m_pad_to_sdl[PAD_SQUARE] = SDL_CONTROLLER_BUTTON_X;
|
||||||
m_pad_to_sdl[PAD_SELECT] = SDL_CONTROLLER_BUTTON_BACK;
|
m_pad_to_sdl[PAD_SELECT] = SDL_CONTROLLER_BUTTON_BACK;
|
||||||
m_pad_to_sdl[PAD_L3] = SDL_CONTROLLER_BUTTON_LEFTSTICK;
|
m_pad_to_sdl[PAD_L3] = SDL_CONTROLLER_BUTTON_LEFTSTICK;
|
||||||
m_pad_to_sdl[PAD_R3] = SDL_CONTROLLER_BUTTON_RIGHTSTICK;
|
m_pad_to_sdl[PAD_R3] = SDL_CONTROLLER_BUTTON_RIGHTSTICK;
|
||||||
m_pad_to_sdl[PAD_START] = SDL_CONTROLLER_BUTTON_START;
|
m_pad_to_sdl[PAD_START] = SDL_CONTROLLER_BUTTON_START;
|
||||||
m_pad_to_sdl[PAD_UP] = SDL_CONTROLLER_BUTTON_DPAD_UP;
|
m_pad_to_sdl[PAD_UP] = SDL_CONTROLLER_BUTTON_DPAD_UP;
|
||||||
m_pad_to_sdl[PAD_RIGHT] = SDL_CONTROLLER_BUTTON_DPAD_RIGHT;
|
m_pad_to_sdl[PAD_RIGHT] = SDL_CONTROLLER_BUTTON_DPAD_RIGHT;
|
||||||
m_pad_to_sdl[PAD_DOWN] = SDL_CONTROLLER_BUTTON_DPAD_DOWN;
|
m_pad_to_sdl[PAD_DOWN] = SDL_CONTROLLER_BUTTON_DPAD_DOWN;
|
||||||
m_pad_to_sdl[PAD_LEFT] = SDL_CONTROLLER_BUTTON_DPAD_LEFT;
|
m_pad_to_sdl[PAD_LEFT] = SDL_CONTROLLER_BUTTON_DPAD_LEFT;
|
||||||
m_pad_to_sdl[PAD_L_UP] = SDL_CONTROLLER_AXIS_LEFTY;
|
m_pad_to_sdl[PAD_L_UP] = SDL_CONTROLLER_AXIS_LEFTY;
|
||||||
m_pad_to_sdl[PAD_L_RIGHT] = SDL_CONTROLLER_AXIS_LEFTX;
|
m_pad_to_sdl[PAD_L_RIGHT] = SDL_CONTROLLER_AXIS_LEFTX;
|
||||||
m_pad_to_sdl[PAD_L_DOWN] = SDL_CONTROLLER_AXIS_LEFTY;
|
m_pad_to_sdl[PAD_L_DOWN] = SDL_CONTROLLER_AXIS_LEFTY;
|
||||||
m_pad_to_sdl[PAD_L_LEFT] = SDL_CONTROLLER_AXIS_LEFTX;
|
m_pad_to_sdl[PAD_L_LEFT] = SDL_CONTROLLER_AXIS_LEFTX;
|
||||||
m_pad_to_sdl[PAD_R_UP] = SDL_CONTROLLER_AXIS_RIGHTY;
|
m_pad_to_sdl[PAD_R_UP] = SDL_CONTROLLER_AXIS_RIGHTY;
|
||||||
m_pad_to_sdl[PAD_R_RIGHT] = SDL_CONTROLLER_AXIS_RIGHTX;
|
m_pad_to_sdl[PAD_R_RIGHT] = SDL_CONTROLLER_AXIS_RIGHTX;
|
||||||
m_pad_to_sdl[PAD_R_DOWN] = SDL_CONTROLLER_AXIS_RIGHTY;
|
m_pad_to_sdl[PAD_R_DOWN] = SDL_CONTROLLER_AXIS_RIGHTY;
|
||||||
m_pad_to_sdl[PAD_R_LEFT] = SDL_CONTROLLER_AXIS_RIGHTX;
|
m_pad_to_sdl[PAD_R_LEFT] = SDL_CONTROLLER_AXIS_RIGHTX;
|
||||||
|
|
||||||
if (SDL_IsGameController(id)) {
|
if (SDL_IsGameController(id))
|
||||||
m_controller = SDL_GameControllerOpen(id);
|
{
|
||||||
joy = SDL_GameControllerGetJoystick(m_controller);
|
m_controller = SDL_GameControllerOpen(id);
|
||||||
} else {
|
joy = SDL_GameControllerGetJoystick(m_controller);
|
||||||
joy = SDL_JoystickOpen(id);
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
joy = SDL_JoystickOpen(id);
|
||||||
|
}
|
||||||
|
|
||||||
if (joy == nullptr) {
|
if (joy == nullptr)
|
||||||
fprintf(stderr, "PAD: failed to open joystick %d\n", id);
|
{
|
||||||
return;
|
fprintf(stderr, "PAD: failed to open joystick %d\n", id);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Collect Device Information
|
// Collect Device Information
|
||||||
char guid[64];
|
char guid[64];
|
||||||
SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joy), guid, 64);
|
SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joy), guid, 64);
|
||||||
const char *devname = SDL_JoystickNameForIndex(id);
|
const char* devname = SDL_JoystickNameForIndex(id);
|
||||||
|
|
||||||
if (m_controller == nullptr) {
|
if (m_controller == nullptr)
|
||||||
fprintf(stderr, "PAD: Joystick (%s,GUID:%s) isn't yet supported by the SDL2 game controller API\n"
|
{
|
||||||
"Fortunately you can use AntiMicro (https://github.com/AntiMicro/antimicro) or Steam to configure your joystick\n"
|
fprintf(stderr, "PAD: Joystick (%s,GUID:%s) isn't yet supported by the SDL2 game controller API\n"
|
||||||
"The mapping can be stored in OnePAD2.ini as 'SDL2 = <...mapping description...>'\n"
|
"Fortunately you can use AntiMicro (https://github.com/AntiMicro/antimicro) or Steam to configure your joystick\n"
|
||||||
"Please report it to us (https://github.com/PCSX2/pcsx2/issues) so we can add your joystick to our internal database.",
|
"The mapping can be stored in OnePAD2.ini as 'SDL2 = <...mapping description...>'\n"
|
||||||
devname, guid);
|
"Please report it to us (https://github.com/PCSX2/pcsx2/issues) so we can add your joystick to our internal database.",
|
||||||
|
devname, guid);
|
||||||
|
|
||||||
#if SDL_MINOR_VERSION >= 4 // Version before 2.0.4 are bugged, JoystickClose crashes randomly
|
#if SDL_MINOR_VERSION >= 4 // Version before 2.0.4 are bugged, JoystickClose crashes randomly
|
||||||
SDL_JoystickClose(joy);
|
SDL_JoystickClose(joy);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::hash<std::string> hash_me;
|
std::hash<std::string> hash_me;
|
||||||
m_unique_id = hash_me(std::string(guid));
|
m_unique_id = hash_me(std::string(guid));
|
||||||
|
|
||||||
// Default haptic effect
|
// Default haptic effect
|
||||||
SDL_HapticEffect effects[NB_EFFECT];
|
SDL_HapticEffect effects[NB_EFFECT];
|
||||||
for (int i = 0; i < NB_EFFECT; i++) {
|
for (int i = 0; i < NB_EFFECT; i++)
|
||||||
SDL_HapticEffect effect;
|
{
|
||||||
memset(&effect, 0, sizeof(SDL_HapticEffect)); // 0 is safe default
|
SDL_HapticEffect effect;
|
||||||
SDL_HapticDirection direction;
|
memset(&effect, 0, sizeof(SDL_HapticEffect)); // 0 is safe default
|
||||||
direction.type = SDL_HAPTIC_POLAR; // We'll be using polar direction encoding.
|
SDL_HapticDirection direction;
|
||||||
direction.dir[0] = 18000;
|
direction.type = SDL_HAPTIC_POLAR; // We'll be using polar direction encoding.
|
||||||
effect.periodic.direction = direction;
|
direction.dir[0] = 18000;
|
||||||
effect.periodic.period = 10;
|
effect.periodic.direction = direction;
|
||||||
effect.periodic.magnitude = (Sint16)(g_conf.get_ff_intensity()); // Effect at maximum instensity
|
effect.periodic.period = 10;
|
||||||
effect.periodic.offset = 0;
|
effect.periodic.magnitude = (Sint16)(g_conf.get_ff_intensity()); // Effect at maximum instensity
|
||||||
effect.periodic.phase = 18000;
|
effect.periodic.offset = 0;
|
||||||
effect.periodic.length = 125; // 125ms feels quite near to original
|
effect.periodic.phase = 18000;
|
||||||
effect.periodic.delay = 0;
|
effect.periodic.length = 125; // 125ms feels quite near to original
|
||||||
effect.periodic.attack_length = 0;
|
effect.periodic.delay = 0;
|
||||||
/* Sine and triangle are quite probably the best, don't change that lightly and if you do
|
effect.periodic.attack_length = 0;
|
||||||
|
/* Sine and triangle are quite probably the best, don't change that lightly and if you do
|
||||||
* keep effects ordered by type
|
* keep effects ordered by type
|
||||||
*/
|
*/
|
||||||
if (i == 0) {
|
if (i == 0)
|
||||||
/* Effect for small motor */
|
{
|
||||||
/* Sine seems to be the only effect making little motor from DS3/4 react
|
/* 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
|
* Intensity has pretty much no effect either(which is coherent with what is explain in hid_sony driver
|
||||||
*/
|
*/
|
||||||
effect.type = SDL_HAPTIC_SINE;
|
effect.type = SDL_HAPTIC_SINE;
|
||||||
} else {
|
}
|
||||||
/** Effect for big motor **/
|
else
|
||||||
effect.type = SDL_HAPTIC_TRIANGLE;
|
{
|
||||||
}
|
/** Effect for big motor **/
|
||||||
|
effect.type = SDL_HAPTIC_TRIANGLE;
|
||||||
|
}
|
||||||
|
|
||||||
effects[i] = effect;
|
effects[i] = effect;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_JoystickIsHaptic(joy)) {
|
if (SDL_JoystickIsHaptic(joy))
|
||||||
m_haptic = SDL_HapticOpenFromJoystick(joy);
|
{
|
||||||
|
m_haptic = SDL_HapticOpenFromJoystick(joy);
|
||||||
|
|
||||||
for (auto &eid : m_effects_id) {
|
for (auto& eid : m_effects_id)
|
||||||
eid = SDL_HapticNewEffect(m_haptic, &effects[0]);
|
{
|
||||||
if (eid < 0) {
|
eid = SDL_HapticNewEffect(m_haptic, &effects[0]);
|
||||||
fprintf(stderr, "ERROR: Effect is not uploaded! %s\n", SDL_GetError());
|
if (eid < 0)
|
||||||
m_haptic = nullptr;
|
{
|
||||||
break;
|
fprintf(stderr, "ERROR: Effect is not uploaded! %s\n", SDL_GetError());
|
||||||
}
|
m_haptic = nullptr;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(stdout, "PAD: controller (%s) detected%s, GUID:%s\n",
|
fprintf(stdout, "PAD: controller (%s) detected%s, GUID:%s\n",
|
||||||
devname, m_haptic ? " with rumble support" : "", guid);
|
devname, m_haptic ? " with rumble support" : "", guid);
|
||||||
|
|
||||||
m_no_error = true;
|
m_no_error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *JoystickInfo::GetName()
|
const char* JoystickInfo::GetName()
|
||||||
{
|
{
|
||||||
return SDL_JoystickName(SDL_GameControllerGetJoystick(m_controller));
|
return SDL_JoystickName(SDL_GameControllerGetJoystick(m_controller));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t JoystickInfo::GetUniqueIdentifier()
|
size_t JoystickInfo::GetUniqueIdentifier()
|
||||||
{
|
{
|
||||||
return m_unique_id;
|
return m_unique_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JoystickInfo::TestForce(float strength = 0.60)
|
bool JoystickInfo::TestForce(float strength = 0.60)
|
||||||
{
|
{
|
||||||
// This code just use standard rumble to check that SDL handles the pad correctly! --3kinox
|
// This code just use standard rumble to check that SDL handles the pad correctly! --3kinox
|
||||||
if (m_haptic == nullptr)
|
if (m_haptic == nullptr)
|
||||||
return false; // Otherwise, core dump!
|
return false; // Otherwise, core dump!
|
||||||
|
|
||||||
SDL_HapticRumbleInit(m_haptic);
|
SDL_HapticRumbleInit(m_haptic);
|
||||||
|
|
||||||
// Make the haptic pad rumble 60% strength for half a second, shoudld be enough for user to see if it works or not
|
// 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(m_haptic, strength, 400) != 0) {
|
if (SDL_HapticRumblePlay(m_haptic, strength, 400) != 0)
|
||||||
fprintf(stderr, "ERROR: Rumble is not working! %s\n", SDL_GetError());
|
{
|
||||||
return false;
|
fprintf(stderr, "ERROR: Rumble is not working! %s\n", SDL_GetError());
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int JoystickInfo::GetInput(gamePadValues input)
|
int JoystickInfo::GetInput(gamePadValues input)
|
||||||
{
|
{
|
||||||
float k = g_conf.get_sensibility() / 100.0; // convert sensibility to float
|
float k = g_conf.get_sensibility() / 100.0; // convert sensibility to float
|
||||||
|
|
||||||
// Handle analog inputs which range from -32k to +32k. Range conversion is handled later in the controller
|
// Handle analog inputs which range from -32k to +32k. Range conversion is handled later in the controller
|
||||||
if (IsAnalogKey(input)) {
|
if (IsAnalogKey(input))
|
||||||
int value = SDL_GameControllerGetAxis(m_controller, (SDL_GameControllerAxis)m_pad_to_sdl[input]);
|
{
|
||||||
value *= k;
|
int value = SDL_GameControllerGetAxis(m_controller, (SDL_GameControllerAxis)m_pad_to_sdl[input]);
|
||||||
return (abs(value) > m_deadzone) ? value : 0;
|
value *= k;
|
||||||
}
|
return (abs(value) > m_deadzone) ? value : 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle triggers which range from 0 to +32k. They must be converted to 0-255 range
|
// Handle triggers which range from 0 to +32k. They must be converted to 0-255 range
|
||||||
if (input == PAD_L2 || input == PAD_R2) {
|
if (input == PAD_L2 || input == PAD_R2)
|
||||||
int value = SDL_GameControllerGetAxis(m_controller, (SDL_GameControllerAxis)m_pad_to_sdl[input]);
|
{
|
||||||
return (value > m_deadzone) ? value / 128 : 0;
|
int value = SDL_GameControllerGetAxis(m_controller, (SDL_GameControllerAxis)m_pad_to_sdl[input]);
|
||||||
}
|
return (value > m_deadzone) ? value / 128 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Remain buttons
|
// Remain buttons
|
||||||
int value = SDL_GameControllerGetButton(m_controller, (SDL_GameControllerButton)m_pad_to_sdl[input]);
|
int value = SDL_GameControllerGetButton(m_controller, (SDL_GameControllerButton)m_pad_to_sdl[input]);
|
||||||
return value ? 0xFF : 0; // Max pressure
|
return value ? 0xFF : 0; // Max pressure
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoystickInfo::UpdateGamePadState()
|
void JoystickInfo::UpdateGamePadState()
|
||||||
{
|
{
|
||||||
SDL_GameControllerUpdate();
|
SDL_GameControllerUpdate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,32 +26,32 @@
|
||||||
class JoystickInfo : public GamePad
|
class JoystickInfo : public GamePad
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
JoystickInfo(int id);
|
JoystickInfo(int id);
|
||||||
~JoystickInfo();
|
~JoystickInfo();
|
||||||
|
|
||||||
JoystickInfo(const JoystickInfo &) = delete; // copy constructor
|
JoystickInfo(const JoystickInfo&) = delete; // copy constructor
|
||||||
JoystickInfo &operator=(const JoystickInfo &) = delete; // assignment
|
JoystickInfo& operator=(const JoystickInfo&) = delete; // assignment
|
||||||
|
|
||||||
|
|
||||||
// opens handles to all possible joysticks
|
// opens handles to all possible joysticks
|
||||||
static void EnumerateJoysticks(std::vector<std::unique_ptr<GamePad>> &vjoysticks);
|
static void EnumerateJoysticks(std::vector<std::unique_ptr<GamePad>>& vjoysticks);
|
||||||
|
|
||||||
void Rumble(unsigned type, unsigned pad) override;
|
void Rumble(unsigned type, unsigned pad) override;
|
||||||
|
|
||||||
bool TestForce(float) override;
|
bool TestForce(float) override;
|
||||||
|
|
||||||
const char *GetName() final;
|
const char* GetName() final;
|
||||||
|
|
||||||
int GetInput(gamePadValues input) final;
|
int GetInput(gamePadValues input) final;
|
||||||
|
|
||||||
void UpdateGamePadState() final;
|
void UpdateGamePadState() final;
|
||||||
|
|
||||||
size_t GetUniqueIdentifier() final;
|
size_t GetUniqueIdentifier() final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_GameController *m_controller;
|
SDL_GameController* m_controller;
|
||||||
SDL_Haptic *m_haptic;
|
SDL_Haptic* m_haptic;
|
||||||
std::array<int, NB_EFFECT> m_effects_id;
|
std::array<int, NB_EFFECT> m_effects_id;
|
||||||
size_t m_unique_id;
|
size_t m_unique_id;
|
||||||
std::array<int, MAX_KEYS> m_pad_to_sdl;
|
std::array<int, MAX_KEYS> m_pad_to_sdl;
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,25 +14,25 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
static void __forceinline set_bit(T &value, int bit)
|
static void __forceinline set_bit(T& value, int bit)
|
||||||
{
|
{
|
||||||
value |= (1 << bit);
|
value |= (1 << bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
static void __forceinline clear_bit(T &value, int bit)
|
static void __forceinline clear_bit(T& value, int bit)
|
||||||
{
|
{
|
||||||
value &= ~(1 << bit);
|
value &= ~(1 << bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
static void __forceinline toggle_bit(T &value, int bit)
|
static void __forceinline toggle_bit(T& value, int bit)
|
||||||
{
|
{
|
||||||
value ^= (1 << bit);
|
value ^= (1 << bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
static bool __forceinline test_bit(T &value, int bit)
|
static bool __forceinline test_bit(T& value, int bit)
|
||||||
{
|
{
|
||||||
return (value & (1 << bit));
|
return (value & (1 << bit));
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,21 +18,21 @@
|
||||||
|
|
||||||
__forceinline void set_keyboard_key(int pad, int keysym, int index)
|
__forceinline void set_keyboard_key(int pad, int keysym, int index)
|
||||||
{
|
{
|
||||||
g_conf.keysym_map[pad][keysym] = index;
|
g_conf.keysym_map[pad][keysym] = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
__forceinline int get_keyboard_key(int pad, int keysym)
|
__forceinline int get_keyboard_key(int pad, int keysym)
|
||||||
{
|
{
|
||||||
// You must use find instead of []
|
// You must use find instead of []
|
||||||
// [] will create an element if the key does not exist and return 0
|
// [] will create an element if the key does not exist and return 0
|
||||||
std::map<u32, u32>::iterator it = g_conf.keysym_map[pad].find(keysym);
|
std::map<u32, u32>::iterator it = g_conf.keysym_map[pad].find(keysym);
|
||||||
if (it != g_conf.keysym_map[pad].end())
|
if (it != g_conf.keysym_map[pad].end())
|
||||||
return it->second;
|
return it->second;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
__forceinline bool IsAnalogKey(int index)
|
__forceinline bool IsAnalogKey(int index)
|
||||||
{
|
{
|
||||||
return ((index >= PAD_L_UP) && (index <= PAD_R_LEFT));
|
return ((index >= PAD_L_UP) && (index <= PAD_R_LEFT));
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,101 +24,103 @@ extern bool IsAnalogKey(int index);
|
||||||
|
|
||||||
class PADconf
|
class PADconf
|
||||||
{
|
{
|
||||||
u32 ff_intensity;
|
u32 ff_intensity;
|
||||||
u32 sensibility;
|
u32 sensibility;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
u16 forcefeedback : 1;
|
u16 forcefeedback : 1;
|
||||||
u16 reverse_lx : 1;
|
u16 reverse_lx : 1;
|
||||||
u16 reverse_ly : 1;
|
u16 reverse_ly : 1;
|
||||||
u16 reverse_rx : 1;
|
u16 reverse_rx : 1;
|
||||||
u16 reverse_ry : 1;
|
u16 reverse_ry : 1;
|
||||||
u16 mouse_l : 1;
|
u16 mouse_l : 1;
|
||||||
u16 mouse_r : 1;
|
u16 mouse_r : 1;
|
||||||
u16 _free : 9; // The 9 remaining bits are unused, do what you wish with them ;)
|
u16 _free : 9; // The 9 remaining bits are unused, do what you wish with them ;)
|
||||||
} pad_options[GAMEPAD_NUMBER]; // One for each pads
|
} pad_options[GAMEPAD_NUMBER]; // One for each pads
|
||||||
u32 packed_options; // Only first 8 bits of each 16 bits series are really used, rest is padding
|
u32 packed_options; // Only first 8 bits of each 16 bits series are really used, rest is padding
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 log;
|
u32 log;
|
||||||
u32 ftw;
|
u32 ftw;
|
||||||
std::map<u32, u32> keysym_map[GAMEPAD_NUMBER];
|
std::map<u32, u32> keysym_map[GAMEPAD_NUMBER];
|
||||||
std::array<size_t, GAMEPAD_NUMBER> unique_id;
|
std::array<size_t, GAMEPAD_NUMBER> unique_id;
|
||||||
std::vector<std::string> sdl2_mapping;
|
std::vector<std::string> sdl2_mapping;
|
||||||
|
|
||||||
PADconf() { init(); }
|
PADconf() { init(); }
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
log = 0;
|
log = 0;
|
||||||
ftw = 1;
|
ftw = 1;
|
||||||
packed_options = 0;
|
packed_options = 0;
|
||||||
ff_intensity = 0x7FFF; // set it at max value by default
|
ff_intensity = 0x7FFF; // set it at max value by default
|
||||||
sensibility = 100;
|
sensibility = 100;
|
||||||
for (int pad = 0; pad < GAMEPAD_NUMBER; pad++) {
|
for (int pad = 0; pad < GAMEPAD_NUMBER; pad++)
|
||||||
keysym_map[pad].clear();
|
{
|
||||||
}
|
keysym_map[pad].clear();
|
||||||
unique_id.fill(0);
|
}
|
||||||
sdl2_mapping.clear();
|
unique_id.fill(0);
|
||||||
}
|
sdl2_mapping.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void set_joy_uid(u32 pad, size_t uid)
|
void set_joy_uid(u32 pad, size_t uid)
|
||||||
{
|
{
|
||||||
if (pad < GAMEPAD_NUMBER)
|
if (pad < GAMEPAD_NUMBER)
|
||||||
unique_id[pad] = uid;
|
unique_id[pad] = uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t get_joy_uid(u32 pad)
|
size_t get_joy_uid(u32 pad)
|
||||||
{
|
{
|
||||||
if (pad < GAMEPAD_NUMBER)
|
if (pad < GAMEPAD_NUMBER)
|
||||||
return unique_id[pad];
|
return unique_id[pad];
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return (a copy of) private memner ff_instensity
|
* Return (a copy of) private memner ff_instensity
|
||||||
**/
|
**/
|
||||||
u32 get_ff_intensity()
|
u32 get_ff_intensity()
|
||||||
{
|
{
|
||||||
return ff_intensity;
|
return ff_intensity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set intensity while checking that the new value is within
|
* 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)
|
* 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)
|
void set_ff_intensity(u32 new_intensity)
|
||||||
{
|
{
|
||||||
if (new_intensity <= 0x7FFF) {
|
if (new_intensity <= 0x7FFF)
|
||||||
ff_intensity = new_intensity;
|
{
|
||||||
}
|
ff_intensity = new_intensity;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set sensibility value.
|
* Set sensibility value.
|
||||||
* There will be an upper range, and less than 0 is obviously wrong.
|
* There will be an upper range, and less than 0 is obviously wrong.
|
||||||
* We are doing object oriented code, so members are definitely not supposed to be public.
|
* We are doing object oriented code, so members are definitely not supposed to be public.
|
||||||
**/
|
**/
|
||||||
void set_sensibility(u32 new_sensibility)
|
void set_sensibility(u32 new_sensibility)
|
||||||
{
|
{
|
||||||
if (new_sensibility > 0)
|
if (new_sensibility > 0)
|
||||||
{
|
{
|
||||||
sensibility = new_sensibility;
|
sensibility = new_sensibility;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sensibility = 1;
|
sensibility = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 get_sensibility()
|
u32 get_sensibility()
|
||||||
{
|
{
|
||||||
return sensibility;
|
return sensibility;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
extern PADconf g_conf;
|
extern PADconf g_conf;
|
||||||
|
|
|
@ -23,104 +23,107 @@ extern std::string s_padstrIniPath;
|
||||||
|
|
||||||
void DefaultKeyboardValues()
|
void DefaultKeyboardValues()
|
||||||
{
|
{
|
||||||
set_keyboard_key(0, XK_a, PAD_L2);
|
set_keyboard_key(0, XK_a, PAD_L2);
|
||||||
set_keyboard_key(0, XK_semicolon, PAD_R2);
|
set_keyboard_key(0, XK_semicolon, PAD_R2);
|
||||||
set_keyboard_key(0, XK_w, PAD_L1);
|
set_keyboard_key(0, XK_w, PAD_L1);
|
||||||
set_keyboard_key(0, XK_p, PAD_R1);
|
set_keyboard_key(0, XK_p, PAD_R1);
|
||||||
set_keyboard_key(0, XK_i, PAD_TRIANGLE);
|
set_keyboard_key(0, XK_i, PAD_TRIANGLE);
|
||||||
set_keyboard_key(0, XK_l, PAD_CIRCLE);
|
set_keyboard_key(0, XK_l, PAD_CIRCLE);
|
||||||
set_keyboard_key(0, XK_k, PAD_CROSS);
|
set_keyboard_key(0, XK_k, PAD_CROSS);
|
||||||
set_keyboard_key(0, XK_j, PAD_SQUARE);
|
set_keyboard_key(0, XK_j, PAD_SQUARE);
|
||||||
set_keyboard_key(0, XK_v, PAD_SELECT);
|
set_keyboard_key(0, XK_v, PAD_SELECT);
|
||||||
set_keyboard_key(0, XK_n, PAD_START);
|
set_keyboard_key(0, XK_n, PAD_START);
|
||||||
set_keyboard_key(0, XK_e, PAD_UP);
|
set_keyboard_key(0, XK_e, PAD_UP);
|
||||||
set_keyboard_key(0, XK_f, PAD_RIGHT);
|
set_keyboard_key(0, XK_f, PAD_RIGHT);
|
||||||
set_keyboard_key(0, XK_d, PAD_DOWN);
|
set_keyboard_key(0, XK_d, PAD_DOWN);
|
||||||
set_keyboard_key(0, XK_s, PAD_LEFT);
|
set_keyboard_key(0, XK_s, PAD_LEFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PADSaveConfig()
|
void PADSaveConfig()
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE* f;
|
||||||
|
|
||||||
const std::string iniFile(s_padstrIniPath + "PAD.ini");
|
const std::string iniFile(s_padstrIniPath + "PAD.ini");
|
||||||
f = fopen(iniFile.c_str(), "w");
|
f = fopen(iniFile.c_str(), "w");
|
||||||
if (f == NULL) {
|
if (f == NULL)
|
||||||
printf("PAD: failed to save ini %s\n", iniFile.c_str());
|
{
|
||||||
return;
|
printf("PAD: failed to save ini %s\n", iniFile.c_str());
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(f, "first_time_wizard = %d\n", g_conf.ftw);
|
fprintf(f, "first_time_wizard = %d\n", g_conf.ftw);
|
||||||
fprintf(f, "log = %d\n", g_conf.log);
|
fprintf(f, "log = %d\n", g_conf.log);
|
||||||
fprintf(f, "options = %d\n", g_conf.packed_options);
|
fprintf(f, "options = %d\n", g_conf.packed_options);
|
||||||
fprintf(f, "mouse_sensibility = %d\n", g_conf.get_sensibility());
|
fprintf(f, "mouse_sensibility = %d\n", g_conf.get_sensibility());
|
||||||
fprintf(f, "ff_intensity = %d\n", g_conf.get_ff_intensity());
|
fprintf(f, "ff_intensity = %d\n", g_conf.get_ff_intensity());
|
||||||
fprintf(f, "uid[0] = %zu\n", g_conf.get_joy_uid(0));
|
fprintf(f, "uid[0] = %zu\n", g_conf.get_joy_uid(0));
|
||||||
fprintf(f, "uid[1] = %zu\n", g_conf.get_joy_uid(1));
|
fprintf(f, "uid[1] = %zu\n", g_conf.get_joy_uid(1));
|
||||||
|
|
||||||
for (int pad = 0; pad < GAMEPAD_NUMBER; pad++)
|
for (int pad = 0; pad < GAMEPAD_NUMBER; pad++)
|
||||||
for (auto const &it : g_conf.keysym_map[pad])
|
for (auto const& it : g_conf.keysym_map[pad])
|
||||||
fprintf(f, "PAD %d:KEYSYM 0x%x = %d\n", pad, it.first, it.second);
|
fprintf(f, "PAD %d:KEYSYM 0x%x = %d\n", pad, it.first, it.second);
|
||||||
|
|
||||||
for (auto const &it : g_conf.sdl2_mapping)
|
for (auto const& it : g_conf.sdl2_mapping)
|
||||||
fprintf(f, "SDL2 = %s\n", it.c_str());
|
fprintf(f, "SDL2 = %s\n", it.c_str());
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PADLoadConfig()
|
void PADLoadConfig()
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE* f;
|
||||||
bool have_user_setting = false;
|
bool have_user_setting = false;
|
||||||
|
|
||||||
g_conf.init();
|
g_conf.init();
|
||||||
|
|
||||||
const std::string iniFile(s_padstrIniPath + "PAD.ini");
|
const std::string iniFile(s_padstrIniPath + "PAD.ini");
|
||||||
f = fopen(iniFile.c_str(), "r");
|
f = fopen(iniFile.c_str(), "r");
|
||||||
if (f == NULL) {
|
if (f == NULL)
|
||||||
printf("OnePAD: failed to load ini %s\n", iniFile.c_str());
|
{
|
||||||
PADSaveConfig(); //save and return
|
printf("OnePAD: failed to load ini %s\n", iniFile.c_str());
|
||||||
return;
|
PADSaveConfig(); //save and return
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
if (fscanf(f, "first_time_wizard = %u\n", &value) == 1)
|
if (fscanf(f, "first_time_wizard = %u\n", &value) == 1)
|
||||||
g_conf.ftw = value;
|
g_conf.ftw = value;
|
||||||
|
|
||||||
if (fscanf(f, "log = %u\n", &value) == 1)
|
if (fscanf(f, "log = %u\n", &value) == 1)
|
||||||
g_conf.log = value;
|
g_conf.log = value;
|
||||||
|
|
||||||
if (fscanf(f, "options = %u\n", &value) == 1)
|
if (fscanf(f, "options = %u\n", &value) == 1)
|
||||||
g_conf.packed_options = value;
|
g_conf.packed_options = value;
|
||||||
|
|
||||||
if (fscanf(f, "mouse_sensibility = %u\n", &value) == 1)
|
if (fscanf(f, "mouse_sensibility = %u\n", &value) == 1)
|
||||||
g_conf.set_sensibility(value);
|
g_conf.set_sensibility(value);
|
||||||
|
|
||||||
if (fscanf(f, "ff_intensity = %u\n", &value) == 1)
|
if (fscanf(f, "ff_intensity = %u\n", &value) == 1)
|
||||||
g_conf.set_ff_intensity(value);
|
g_conf.set_ff_intensity(value);
|
||||||
|
|
||||||
size_t uid;
|
size_t uid;
|
||||||
if (fscanf(f, "uid[0] = %zu\n", &uid) == 1)
|
if (fscanf(f, "uid[0] = %zu\n", &uid) == 1)
|
||||||
g_conf.set_joy_uid(0, uid);
|
g_conf.set_joy_uid(0, uid);
|
||||||
if (fscanf(f, "uid[1] = %zu\n", &uid) == 1)
|
if (fscanf(f, "uid[1] = %zu\n", &uid) == 1)
|
||||||
g_conf.set_joy_uid(1, uid);
|
g_conf.set_joy_uid(1, uid);
|
||||||
|
|
||||||
u32 pad;
|
u32 pad;
|
||||||
u32 keysym;
|
u32 keysym;
|
||||||
u32 index;
|
u32 index;
|
||||||
while (fscanf(f, "PAD %u:KEYSYM 0x%x = %u\n", &pad, &keysym, &index) == 3) {
|
while (fscanf(f, "PAD %u:KEYSYM 0x%x = %u\n", &pad, &keysym, &index) == 3)
|
||||||
set_keyboard_key(pad & 1, keysym, index);
|
{
|
||||||
if (pad == 0)
|
set_keyboard_key(pad & 1, keysym, index);
|
||||||
have_user_setting = true;
|
if (pad == 0)
|
||||||
}
|
have_user_setting = true;
|
||||||
|
}
|
||||||
|
|
||||||
char sdl2[512];
|
char sdl2[512];
|
||||||
while (fscanf(f, "SDL2 = %511[^\n]\n", sdl2) == 1)
|
while (fscanf(f, "SDL2 = %511[^\n]\n", sdl2) == 1)
|
||||||
g_conf.sdl2_mapping.push_back(std::string(sdl2));
|
g_conf.sdl2_mapping.push_back(std::string(sdl2));
|
||||||
|
|
||||||
if (!have_user_setting)
|
if (!have_user_setting)
|
||||||
DefaultKeyboardValues();
|
DefaultKeyboardValues();
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,36 +28,41 @@
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char *KeysymToChar(int keysym)
|
char* KeysymToChar(int keysym)
|
||||||
{
|
{
|
||||||
LPWORD temp;
|
LPWORD temp;
|
||||||
|
|
||||||
ToAscii((UINT)keysym, NULL, NULL, temp, NULL);
|
ToAscii((UINT)keysym, NULL, NULL, temp, NULL);
|
||||||
return (char *)temp;
|
return (char*)temp;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// g_key_status.press but with proper handling for analog buttons
|
/// g_key_status.press but with proper handling for analog buttons
|
||||||
static void PressButton(u32 pad, u32 button) {
|
static void PressButton(u32 pad, u32 button)
|
||||||
// Analog controls.
|
{
|
||||||
if (IsAnalogKey(button)) {
|
// Analog controls.
|
||||||
switch (button) {
|
if (IsAnalogKey(button))
|
||||||
case PAD_R_LEFT:
|
{
|
||||||
case PAD_R_UP:
|
switch (button)
|
||||||
case PAD_L_LEFT:
|
{
|
||||||
case PAD_L_UP:
|
case PAD_R_LEFT:
|
||||||
g_key_status.press(pad, button, -MAX_ANALOG_VALUE);
|
case PAD_R_UP:
|
||||||
break;
|
case PAD_L_LEFT:
|
||||||
case PAD_R_RIGHT:
|
case PAD_L_UP:
|
||||||
case PAD_R_DOWN:
|
g_key_status.press(pad, button, -MAX_ANALOG_VALUE);
|
||||||
case PAD_L_RIGHT:
|
break;
|
||||||
case PAD_L_DOWN:
|
case PAD_R_RIGHT:
|
||||||
g_key_status.press(pad, button, MAX_ANALOG_VALUE);
|
case PAD_R_DOWN:
|
||||||
break;
|
case PAD_L_RIGHT:
|
||||||
}
|
case PAD_L_DOWN:
|
||||||
} else {
|
g_key_status.press(pad, button, MAX_ANALOG_VALUE);
|
||||||
g_key_status.press(pad, button);
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_key_status.press(pad, button);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
|
@ -69,41 +74,54 @@ static void PressButton(u32 pad, u32 button) {
|
||||||
// Keyboard keys use discriminator 0
|
// Keyboard keys use discriminator 0
|
||||||
// Mouse buttons use discriminator 1
|
// Mouse buttons use discriminator 1
|
||||||
|
|
||||||
void UpdateKeyboardInput() {
|
void UpdateKeyboardInput()
|
||||||
for (int pad = 0; pad < GAMEPAD_NUMBER; pad++) {
|
{
|
||||||
const auto& map = g_conf.keysym_map[pad];
|
for (int pad = 0; pad < GAMEPAD_NUMBER; pad++)
|
||||||
// If we loop over all keys press/release based on current state,
|
{
|
||||||
// joystick axes (which have two bound keys) will always go to the later-polled key
|
const auto& map = g_conf.keysym_map[pad];
|
||||||
// Instead, release all keys first and then set the ones that are pressed
|
// If we loop over all keys press/release based on current state,
|
||||||
for (const auto& key : map) g_key_status.release(pad, key.second);
|
// joystick axes (which have two bound keys) will always go to the later-polled key
|
||||||
for (const auto& key : map) {
|
// Instead, release all keys first and then set the ones that are pressed
|
||||||
bool state;
|
for (const auto& key : map)
|
||||||
if (key.first >> 16 == 0) {
|
g_key_status.release(pad, key.second);
|
||||||
state = CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key.first);
|
for (const auto& key : map)
|
||||||
} else {
|
{
|
||||||
state = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, (CGMouseButton)(key.first & 0xFFFF));
|
bool state;
|
||||||
}
|
if (key.first >> 16 == 0)
|
||||||
if (state) PressButton(pad, key.second);
|
{
|
||||||
}
|
state = CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key.first);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, (CGMouseButton)(key.first & 0xFFFF));
|
||||||
|
}
|
||||||
|
if (state)
|
||||||
|
PressButton(pad, key.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PollForNewKeyboardKeys(u32 &pkey) {
|
bool PollForNewKeyboardKeys(u32& pkey)
|
||||||
// All keycodes in <HIToolbox/Events.h> are 0x7e or lower. If you notice
|
{
|
||||||
// keys that aren't being recognized, bump this number up!
|
// All keycodes in <HIToolbox/Events.h> are 0x7e or lower. If you notice
|
||||||
for (int key = 0; key < 0x80; key++) {
|
// keys that aren't being recognized, bump this number up!
|
||||||
if (CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key)) {
|
for (int key = 0; key < 0x80; key++)
|
||||||
pkey = key == kVK_Escape ? 0 : key;
|
{
|
||||||
return true;
|
if (CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key))
|
||||||
}
|
{
|
||||||
}
|
pkey = key == kVK_Escape ? 0 : key;
|
||||||
for (auto btn : {kCGMouseButtonLeft, kCGMouseButtonCenter, kCGMouseButtonRight}) {
|
return true;
|
||||||
if (CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, btn)) {
|
}
|
||||||
pkey = btn | (1 << 16);
|
}
|
||||||
return true;
|
for (auto btn : {kCGMouseButtonLeft, kCGMouseButtonCenter, kCGMouseButtonRight})
|
||||||
}
|
{
|
||||||
}
|
if (CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, btn))
|
||||||
return false;
|
{
|
||||||
|
pkey = btn | (1 << 16);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
#elif defined(__unix__)
|
#elif defined(__unix__)
|
||||||
static bool s_grab_input = false;
|
static bool s_grab_input = false;
|
||||||
|
@ -111,243 +129,265 @@ static bool s_Shift = false;
|
||||||
static unsigned int s_previous_mouse_x = 0;
|
static unsigned int s_previous_mouse_x = 0;
|
||||||
static unsigned int s_previous_mouse_y = 0;
|
static unsigned int s_previous_mouse_y = 0;
|
||||||
|
|
||||||
void AnalyzeKeyEvent(keyEvent &evt)
|
void AnalyzeKeyEvent(keyEvent& evt)
|
||||||
{
|
{
|
||||||
KeySym key = (KeySym)evt.key;
|
KeySym key = (KeySym)evt.key;
|
||||||
int pad = 0;
|
int pad = 0;
|
||||||
int index = -1;
|
int index = -1;
|
||||||
|
|
||||||
for (int cpad = 0; cpad < GAMEPAD_NUMBER; cpad++) {
|
for (int cpad = 0; cpad < GAMEPAD_NUMBER; cpad++)
|
||||||
int tmp_index = get_keyboard_key(cpad, key);
|
{
|
||||||
if (tmp_index != -1) {
|
int tmp_index = get_keyboard_key(cpad, key);
|
||||||
pad = cpad;
|
if (tmp_index != -1)
|
||||||
index = tmp_index;
|
{
|
||||||
}
|
pad = cpad;
|
||||||
}
|
index = tmp_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (evt.evt) {
|
switch (evt.evt)
|
||||||
case KeyPress:
|
{
|
||||||
// Shift F12 is not yet use by pcsx2. So keep it to grab/ungrab input
|
case KeyPress:
|
||||||
// I found it very handy vs the automatic fullscreen detection
|
// Shift F12 is not yet use by pcsx2. So keep it to grab/ungrab input
|
||||||
// 1/ Does not need to detect full-screen
|
// I found it very handy vs the automatic fullscreen detection
|
||||||
// 2/ Can use a debugger in full-screen
|
// 1/ Does not need to detect full-screen
|
||||||
// 3/ Can grab input in window without the need of a pixelated full-screen
|
// 2/ Can use a debugger in full-screen
|
||||||
if (key == XK_Shift_R || key == XK_Shift_L)
|
// 3/ Can grab input in window without the need of a pixelated full-screen
|
||||||
s_Shift = true;
|
if (key == XK_Shift_R || key == XK_Shift_L)
|
||||||
if (key == XK_F12 && s_Shift) {
|
s_Shift = true;
|
||||||
if (!s_grab_input) {
|
if (key == XK_F12 && s_Shift)
|
||||||
s_grab_input = true;
|
{
|
||||||
XGrabPointer(GSdsp, GSwin, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, GSwin, None, CurrentTime);
|
if (!s_grab_input)
|
||||||
XGrabKeyboard(GSdsp, GSwin, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
{
|
||||||
} else {
|
s_grab_input = true;
|
||||||
s_grab_input = false;
|
XGrabPointer(GSdsp, GSwin, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, GSwin, None, CurrentTime);
|
||||||
XUngrabPointer(GSdsp, CurrentTime);
|
XGrabKeyboard(GSdsp, GSwin, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
XUngrabKeyboard(GSdsp, CurrentTime);
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
|
s_grab_input = false;
|
||||||
|
XUngrabPointer(GSdsp, CurrentTime);
|
||||||
|
XUngrabKeyboard(GSdsp, CurrentTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
PressButton(pad, index);
|
PressButton(pad, index);
|
||||||
|
|
||||||
//PAD_LOG("Key pressed:%d\n", index);
|
//PAD_LOG("Key pressed:%d\n", index);
|
||||||
|
|
||||||
event.evt = KEYPRESS;
|
event.evt = KEYPRESS;
|
||||||
event.key = key;
|
event.key = key;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KeyRelease:
|
case KeyRelease:
|
||||||
if (key == XK_Shift_R || key == XK_Shift_L)
|
if (key == XK_Shift_R || key == XK_Shift_L)
|
||||||
s_Shift = false;
|
s_Shift = false;
|
||||||
|
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
g_key_status.release(pad, index);
|
g_key_status.release(pad, index);
|
||||||
|
|
||||||
event.evt = KEYRELEASE;
|
event.evt = KEYRELEASE;
|
||||||
event.key = key;
|
event.key = key;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FocusOut:
|
case FocusOut:
|
||||||
s_Shift = false;
|
s_Shift = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
g_key_status.press(pad, index);
|
g_key_status.press(pad, index);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ButtonRelease:
|
case ButtonRelease:
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
g_key_status.release(pad, index);
|
g_key_status.release(pad, index);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionNotify:
|
case MotionNotify:
|
||||||
// FIXME: How to handle when the mouse does not move, no event generated!!!
|
// FIXME: How to handle when the mouse does not move, no event generated!!!
|
||||||
// 1/ small move == no move. Cons : can not do small movement
|
// 1/ small move == no move. Cons : can not do small movement
|
||||||
// 2/ use a watchdog timer thread
|
// 2/ use a watchdog timer thread
|
||||||
// 3/ ??? idea welcome ;)
|
// 3/ ??? idea welcome ;)
|
||||||
if (g_conf.pad_options[pad].mouse_l | g_conf.pad_options[pad].mouse_r) {
|
if (g_conf.pad_options[pad].mouse_l | g_conf.pad_options[pad].mouse_r)
|
||||||
unsigned int pad_x;
|
{
|
||||||
unsigned int pad_y;
|
unsigned int pad_x;
|
||||||
// Note when both PADOPTION_MOUSE_R and PADOPTION_MOUSE_L are set, take only the right one
|
unsigned int pad_y;
|
||||||
if (g_conf.pad_options[pad].mouse_r) {
|
// Note when both PADOPTION_MOUSE_R and PADOPTION_MOUSE_L are set, take only the right one
|
||||||
pad_x = PAD_R_RIGHT;
|
if (g_conf.pad_options[pad].mouse_r)
|
||||||
pad_y = PAD_R_UP;
|
{
|
||||||
} else {
|
pad_x = PAD_R_RIGHT;
|
||||||
pad_x = PAD_L_RIGHT;
|
pad_y = PAD_R_UP;
|
||||||
pad_y = PAD_L_UP;
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
pad_x = PAD_L_RIGHT;
|
||||||
|
pad_y = PAD_L_UP;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned x = evt.key & 0xFFFF;
|
unsigned x = evt.key & 0xFFFF;
|
||||||
unsigned int value = (s_previous_mouse_x > x) ? s_previous_mouse_x - x : x - s_previous_mouse_x;
|
unsigned int value = (s_previous_mouse_x > x) ? s_previous_mouse_x - x : x - s_previous_mouse_x;
|
||||||
value *= g_conf.get_sensibility();
|
value *= g_conf.get_sensibility();
|
||||||
|
|
||||||
if (x == 0)
|
if (x == 0)
|
||||||
g_key_status.press(pad, pad_x, -MAX_ANALOG_VALUE);
|
g_key_status.press(pad, pad_x, -MAX_ANALOG_VALUE);
|
||||||
else if (x == 0xFFFF)
|
else if (x == 0xFFFF)
|
||||||
g_key_status.press(pad, pad_x, MAX_ANALOG_VALUE);
|
g_key_status.press(pad, pad_x, MAX_ANALOG_VALUE);
|
||||||
else if (x < (s_previous_mouse_x - 2))
|
else if (x < (s_previous_mouse_x - 2))
|
||||||
g_key_status.press(pad, pad_x, -value);
|
g_key_status.press(pad, pad_x, -value);
|
||||||
else if (x > (s_previous_mouse_x + 2))
|
else if (x > (s_previous_mouse_x + 2))
|
||||||
g_key_status.press(pad, pad_x, value);
|
g_key_status.press(pad, pad_x, value);
|
||||||
else
|
else
|
||||||
g_key_status.release(pad, pad_x);
|
g_key_status.release(pad, pad_x);
|
||||||
|
|
||||||
|
|
||||||
unsigned y = evt.key >> 16;
|
unsigned y = evt.key >> 16;
|
||||||
value = (s_previous_mouse_y > y) ? s_previous_mouse_y - y : y - s_previous_mouse_y;
|
value = (s_previous_mouse_y > y) ? s_previous_mouse_y - y : y - s_previous_mouse_y;
|
||||||
value *= g_conf.get_sensibility();
|
value *= g_conf.get_sensibility();
|
||||||
|
|
||||||
if (y == 0)
|
if (y == 0)
|
||||||
g_key_status.press(pad, pad_y, -MAX_ANALOG_VALUE);
|
g_key_status.press(pad, pad_y, -MAX_ANALOG_VALUE);
|
||||||
else if (y == 0xFFFF)
|
else if (y == 0xFFFF)
|
||||||
g_key_status.press(pad, pad_y, MAX_ANALOG_VALUE);
|
g_key_status.press(pad, pad_y, MAX_ANALOG_VALUE);
|
||||||
else if (y < (s_previous_mouse_y - 2))
|
else if (y < (s_previous_mouse_y - 2))
|
||||||
g_key_status.press(pad, pad_y, -value);
|
g_key_status.press(pad, pad_y, -value);
|
||||||
else if (y > (s_previous_mouse_y + 2))
|
else if (y > (s_previous_mouse_y + 2))
|
||||||
g_key_status.press(pad, pad_y, value);
|
g_key_status.press(pad, pad_y, value);
|
||||||
else
|
else
|
||||||
g_key_status.release(pad, pad_y);
|
g_key_status.release(pad, pad_y);
|
||||||
|
|
||||||
s_previous_mouse_x = x;
|
s_previous_mouse_x = x;
|
||||||
s_previous_mouse_y = y;
|
s_previous_mouse_y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateKeyboardInput()
|
void UpdateKeyboardInput()
|
||||||
{
|
{
|
||||||
keyEvent evt = {0};
|
keyEvent evt = {0};
|
||||||
XEvent E = {0};
|
XEvent E = {0};
|
||||||
|
|
||||||
// Keyboard input send by PCSX2
|
// Keyboard input send by PCSX2
|
||||||
g_ev_fifo.consume_all(AnalyzeKeyEvent);
|
g_ev_fifo.consume_all(AnalyzeKeyEvent);
|
||||||
|
|
||||||
// keyboard input
|
// keyboard input
|
||||||
while (XPending(GSdsp) > 0) {
|
while (XPending(GSdsp) > 0)
|
||||||
XNextEvent(GSdsp, &E);
|
{
|
||||||
|
XNextEvent(GSdsp, &E);
|
||||||
|
|
||||||
// Change the format of the structure to be compatible with GSOpen2
|
// Change the format of the structure to be compatible with GSOpen2
|
||||||
// mode (event come from pcsx2 not X)
|
// mode (event come from pcsx2 not X)
|
||||||
evt.evt = E.type;
|
evt.evt = E.type;
|
||||||
switch (E.type) {
|
switch (E.type)
|
||||||
case MotionNotify:
|
{
|
||||||
evt.key = (E.xbutton.x & 0xFFFF) | (E.xbutton.y << 16);
|
case MotionNotify:
|
||||||
break;
|
evt.key = (E.xbutton.x & 0xFFFF) | (E.xbutton.y << 16);
|
||||||
case ButtonRelease:
|
break;
|
||||||
case ButtonPress:
|
case ButtonRelease:
|
||||||
evt.key = E.xbutton.button;
|
case ButtonPress:
|
||||||
break;
|
evt.key = E.xbutton.button;
|
||||||
default:
|
break;
|
||||||
evt.key = (int)XLookupKeysym(&E.xkey, 0);
|
default:
|
||||||
}
|
evt.key = (int)XLookupKeysym(&E.xkey, 0);
|
||||||
|
}
|
||||||
|
|
||||||
AnalyzeKeyEvent(evt);
|
AnalyzeKeyEvent(evt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PollForNewKeyboardKeys(u32 &pkey)
|
bool PollForNewKeyboardKeys(u32& pkey)
|
||||||
{
|
{
|
||||||
GdkEvent *ev = gdk_event_get();
|
GdkEvent* ev = gdk_event_get();
|
||||||
|
|
||||||
if (ev != NULL) {
|
if (ev != NULL)
|
||||||
if (ev->type == GDK_KEY_PRESS) {
|
{
|
||||||
pkey = ev->key.keyval != GDK_KEY_Escape ? ev->key.keyval : 0;
|
if (ev->type == GDK_KEY_PRESS)
|
||||||
return true;
|
{
|
||||||
} else if (ev->type == GDK_BUTTON_PRESS) {
|
pkey = ev->key.keyval != GDK_KEY_Escape ? ev->key.keyval : 0;
|
||||||
pkey = ev->button.button;
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
else if (ev->type == GDK_BUTTON_PRESS)
|
||||||
}
|
{
|
||||||
|
pkey = ev->button.button;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
LRESULT WINAPI PADwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
LRESULT WINAPI PADwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
static bool lbutton = false, rbutton = false;
|
static bool lbutton = false, rbutton = false;
|
||||||
for (int pad = 0; pad < GAMEPAD_NUMBER; ++pad)
|
for (int pad = 0; pad < GAMEPAD_NUMBER; ++pad)
|
||||||
{
|
{
|
||||||
g_key_status.keyboard_state_acces(pad);
|
g_key_status.keyboard_state_acces(pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (msg) {
|
switch (msg)
|
||||||
case WM_KEYDOWN:
|
{
|
||||||
if (lParam & 0x40000000)
|
case WM_KEYDOWN:
|
||||||
return TRUE;
|
if (lParam & 0x40000000)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
for (int pad = 0; pad < GAMEPAD_NUMBER; ++pad) {
|
for (int pad = 0; pad < GAMEPAD_NUMBER; ++pad)
|
||||||
for (int i = 0; i < MAX_KEYS; i++) {
|
{
|
||||||
assert(0);
|
for (int i = 0; i < MAX_KEYS; i++)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
#if 0
|
#if 0
|
||||||
if (wParam == get_key(pad, i)) {
|
if (wParam == get_key(pad, i)) {
|
||||||
g_key_status.press(pad, i);
|
g_key_status.press(pad, i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event.evt = KEYPRESS;
|
event.evt = KEYPRESS;
|
||||||
event.key = wParam;
|
event.key = wParam;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
for (int pad = 0; pad < GAMEPAD_NUMBER; ++pad) {
|
for (int pad = 0; pad < GAMEPAD_NUMBER; ++pad)
|
||||||
for (int i = 0; i < MAX_KEYS; i++) {
|
{
|
||||||
assert(0);
|
for (int i = 0; i < MAX_KEYS; i++)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
#if 0
|
#if 0
|
||||||
if (wParam == get_key(pad, i)) {
|
if (wParam == get_key(pad, i)) {
|
||||||
g_key_status.release(pad, i);
|
g_key_status.release(pad, i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
event.evt = KEYRELEASE;
|
event.evt = KEYRELEASE;
|
||||||
event.key = wParam;
|
event.key = wParam;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
case WM_QUIT:
|
case WM_QUIT:
|
||||||
event.evt = KEYPRESS;
|
event.evt = KEYPRESS;
|
||||||
event.key = VK_ESCAPE;
|
event.key = VK_ESCAPE;
|
||||||
return GSwndProc(hWnd, msg, wParam, lParam);
|
return GSwndProc(hWnd, msg, wParam, lParam);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return GSwndProc(hWnd, msg, wParam, lParam);
|
return GSwndProc(hWnd, msg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int pad = 0; pad < GAMEPAD_NUMBER; ++pad)
|
for (int pad = 0; pad < GAMEPAD_NUMBER; ++pad)
|
||||||
g_key_status.commit_status(pad);
|
g_key_status.commit_status(pad);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,17 +24,17 @@
|
||||||
|
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
#if defined(__unix__) || defined(__APPLE__)
|
||||||
|
|
||||||
extern void AnalyzeKeyEvent(keyEvent &evt);
|
extern void AnalyzeKeyEvent(keyEvent& evt);
|
||||||
extern void UpdateKeyboardInput();
|
extern void UpdateKeyboardInput();
|
||||||
extern bool PollForNewKeyboardKeys(u32 &pkey);
|
extern bool PollForNewKeyboardKeys(u32& pkey);
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
extern Display *GSdsp;
|
extern Display* GSdsp;
|
||||||
extern Window GSwin;
|
extern Window GSwin;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
extern char *KeysymToChar(int keysym);
|
extern char* KeysymToChar(int keysym);
|
||||||
extern WNDPROC GSwndProc;
|
extern WNDPROC GSwndProc;
|
||||||
extern HWND GShwnd;
|
extern HWND GShwnd;
|
||||||
|
|
||||||
|
|
|
@ -23,102 +23,106 @@
|
||||||
#include "wx_dialog/dialog.h"
|
#include "wx_dialog/dialog.h"
|
||||||
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
Display *GSdsp;
|
Display* GSdsp;
|
||||||
Window GSwin;
|
Window GSwin;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void SysMessage(const char *fmt, ...)
|
static void SysMessage(const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list list;
|
va_list list;
|
||||||
char msg[512];
|
char msg[512];
|
||||||
|
|
||||||
va_start(list, fmt);
|
va_start(list, fmt);
|
||||||
vsprintf(msg, fmt, list);
|
vsprintf(msg, fmt, list);
|
||||||
va_end(list);
|
va_end(list);
|
||||||
|
|
||||||
if (msg[strlen(msg) - 1] == '\n')
|
if (msg[strlen(msg) - 1] == '\n')
|
||||||
msg[strlen(msg) - 1] = 0;
|
msg[strlen(msg) - 1] = 0;
|
||||||
|
|
||||||
wxMessageDialog dialog(nullptr, msg, "Info", wxOK);
|
wxMessageDialog dialog(nullptr, msg, "Info", wxOK);
|
||||||
dialog.ShowModal();
|
dialog.ShowModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 _PADopen(void *pDsp)
|
s32 _PADopen(void* pDsp)
|
||||||
{
|
{
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
GSdsp = *(Display **)pDsp;
|
GSdsp = *(Display**)pDsp;
|
||||||
GSwin = (Window) * (((u32 *)pDsp) + 1);
|
GSwin = (Window) * (((u32*)pDsp) + 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _PADclose()
|
void _PADclose()
|
||||||
{
|
{
|
||||||
s_vgamePad.clear();
|
s_vgamePad.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PollForJoystickInput(int cpad)
|
void PollForJoystickInput(int cpad)
|
||||||
{
|
{
|
||||||
int index = GamePad::uid_to_index(cpad);
|
int index = GamePad::uid_to_index(cpad);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto &gamePad = s_vgamePad[index];
|
auto& gamePad = s_vgamePad[index];
|
||||||
|
|
||||||
gamePad->UpdateGamePadState();
|
gamePad->UpdateGamePadState();
|
||||||
|
|
||||||
for (int i = 0; i < MAX_KEYS; i++) {
|
for (int i = 0; i < MAX_KEYS; i++)
|
||||||
s32 value = gamePad->GetInput((gamePadValues)i);
|
{
|
||||||
if (value != 0)
|
s32 value = gamePad->GetInput((gamePadValues)i);
|
||||||
g_key_status.press(cpad, i, value);
|
if (value != 0)
|
||||||
else
|
g_key_status.press(cpad, i, value);
|
||||||
g_key_status.release(cpad, i);
|
else
|
||||||
}
|
g_key_status.release(cpad, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PADupdate(int pad)
|
void PADupdate(int pad)
|
||||||
{
|
{
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
// Gamepad inputs don't count as an activity. Therefore screensaver will
|
// Gamepad inputs don't count as an activity. Therefore screensaver will
|
||||||
// be fired after a couple of minute.
|
// be fired after a couple of minute.
|
||||||
// Emulate an user activity
|
// Emulate an user activity
|
||||||
static int count = 0;
|
static int count = 0;
|
||||||
count++;
|
count++;
|
||||||
if ((count & 0xFFF) == 0) {
|
if ((count & 0xFFF) == 0)
|
||||||
// 1 call every 4096 Vsync is enough
|
{
|
||||||
XResetScreenSaver(GSdsp);
|
// 1 call every 4096 Vsync is enough
|
||||||
}
|
XResetScreenSaver(GSdsp);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Actually PADupdate is always call with pad == 0. So you need to update both
|
// Actually PADupdate is always call with pad == 0. So you need to update both
|
||||||
// pads -- Gregory
|
// pads -- Gregory
|
||||||
|
|
||||||
// Poll keyboard/mouse event. There is currently no way to separate pad0 from pad1 event.
|
// Poll keyboard/mouse event. There is currently no way to separate pad0 from pad1 event.
|
||||||
// So we will populate both pad in the same time
|
// So we will populate both pad in the same time
|
||||||
for (int cpad = 0; cpad < GAMEPAD_NUMBER; cpad++) {
|
for (int cpad = 0; cpad < GAMEPAD_NUMBER; cpad++)
|
||||||
g_key_status.keyboard_state_acces(cpad);
|
{
|
||||||
}
|
g_key_status.keyboard_state_acces(cpad);
|
||||||
UpdateKeyboardInput();
|
}
|
||||||
|
UpdateKeyboardInput();
|
||||||
|
|
||||||
// Get joystick state + Commit
|
// Get joystick state + Commit
|
||||||
for (int cpad = 0; cpad < GAMEPAD_NUMBER; cpad++) {
|
for (int cpad = 0; cpad < GAMEPAD_NUMBER; cpad++)
|
||||||
g_key_status.joystick_state_acces(cpad);
|
{
|
||||||
|
g_key_status.joystick_state_acces(cpad);
|
||||||
|
|
||||||
PollForJoystickInput(cpad);
|
PollForJoystickInput(cpad);
|
||||||
|
|
||||||
g_key_status.commit_status(cpad);
|
g_key_status.commit_status(cpad);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pad::rumble_all();
|
Pad::rumble_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PADconfigure()
|
void PADconfigure()
|
||||||
{
|
{
|
||||||
ScopedCoreThreadPause paused_core;
|
ScopedCoreThreadPause paused_core;
|
||||||
PADLoadConfig();
|
PADLoadConfig();
|
||||||
|
|
||||||
DisplayDialog();
|
DisplayDialog();
|
||||||
paused_core.AllowResume();
|
paused_core.AllowResume();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,5 +3,5 @@
|
||||||
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
|
||||||
extern GResource *PAD_res_get_resource (void);
|
extern GResource* PAD_res_get_resource(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,8 +29,8 @@ static const u8 setNativeMode[7] = {0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A};
|
||||||
static u8 queryMaskMode[7] = {0x5A, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x5A};
|
static u8 queryMaskMode[7] = {0x5A, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x5A};
|
||||||
|
|
||||||
static const u8 queryAct[2][7] = {
|
static const u8 queryAct[2][7] = {
|
||||||
{0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A},
|
{0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A},
|
||||||
{0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14}};
|
{0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14}};
|
||||||
|
|
||||||
QueryInfo query;
|
QueryInfo query;
|
||||||
Pad pads[2][4];
|
Pad pads[2][4];
|
||||||
|
@ -42,29 +42,30 @@ int slots[2] = {0, 0};
|
||||||
|
|
||||||
void QueryInfo::reset()
|
void QueryInfo::reset()
|
||||||
{
|
{
|
||||||
port = 0;
|
port = 0;
|
||||||
slot = 0;
|
slot = 0;
|
||||||
lastByte = 1;
|
lastByte = 1;
|
||||||
currentCommand = 0;
|
currentCommand = 0;
|
||||||
numBytes = 0;
|
numBytes = 0;
|
||||||
queryDone = 1;
|
queryDone = 1;
|
||||||
memset(response, 0xF3, sizeof(response));
|
memset(response, 0xF3, sizeof(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 QueryInfo::start_poll(int _port)
|
u8 QueryInfo::start_poll(int _port)
|
||||||
{
|
{
|
||||||
if (port > 1) {
|
if (port > 1)
|
||||||
reset();
|
{
|
||||||
return 0;
|
reset();
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
queryDone = 0;
|
queryDone = 0;
|
||||||
port = _port;
|
port = _port;
|
||||||
slot = slots[port];
|
slot = slots[port];
|
||||||
numBytes = 2;
|
numBytes = 2;
|
||||||
lastByte = 0;
|
lastByte = 0;
|
||||||
|
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
@ -73,7 +74,7 @@ u8 QueryInfo::start_poll(int _port)
|
||||||
|
|
||||||
void Pad::set_mode(int _mode)
|
void Pad::set_mode(int _mode)
|
||||||
{
|
{
|
||||||
mode = _mode;
|
mode = _mode;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
fprintf(stdout, "OnePad: set new pad mode=");
|
fprintf(stdout, "OnePad: set new pad mode=");
|
||||||
|
@ -90,38 +91,40 @@ void Pad::set_mode(int _mode)
|
||||||
|
|
||||||
void Pad::set_vibrate(int motor, u8 val)
|
void Pad::set_vibrate(int motor, u8 val)
|
||||||
{
|
{
|
||||||
nextVibrate[motor] = val;
|
nextVibrate[motor] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pad::reset_vibrate()
|
void Pad::reset_vibrate()
|
||||||
{
|
{
|
||||||
set_vibrate(0, 0);
|
set_vibrate(0, 0);
|
||||||
set_vibrate(1, 0);
|
set_vibrate(1, 0);
|
||||||
memset(vibrate, 0xFF, sizeof(vibrate));
|
memset(vibrate, 0xFF, sizeof(vibrate));
|
||||||
vibrate[0] = 0x5A;
|
vibrate[0] = 0x5A;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pad::reset()
|
void Pad::reset()
|
||||||
{
|
{
|
||||||
memset(this, 0, sizeof(PadFreezeData));
|
memset(this, 0, sizeof(PadFreezeData));
|
||||||
|
|
||||||
set_mode(MODE_DIGITAL);
|
set_mode(MODE_DIGITAL);
|
||||||
umask[0] = umask[1] = 0xFF;
|
umask[0] = umask[1] = 0xFF;
|
||||||
|
|
||||||
// Sets up vibrate variable.
|
// Sets up vibrate variable.
|
||||||
reset_vibrate();
|
reset_vibrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pad::rumble(unsigned port)
|
void Pad::rumble(unsigned port)
|
||||||
{
|
{
|
||||||
for (unsigned motor = 0; motor < 2; motor++) {
|
for (unsigned motor = 0; motor < 2; motor++)
|
||||||
// TODO: Probably be better to send all of these at once.
|
{
|
||||||
if (nextVibrate[motor] | currentVibrate[motor]) {
|
// TODO: Probably be better to send all of these at once.
|
||||||
currentVibrate[motor] = nextVibrate[motor];
|
if (nextVibrate[motor] | currentVibrate[motor])
|
||||||
|
{
|
||||||
|
currentVibrate[motor] = nextVibrate[motor];
|
||||||
|
|
||||||
GamePad::DoRumble(motor, port);
|
GamePad::DoRumble(motor, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pad::stop_vibrate_all()
|
void Pad::stop_vibrate_all()
|
||||||
|
@ -132,24 +135,24 @@ void Pad::stop_vibrate_all()
|
||||||
SetVibrate(i&1, i>>1, 1, 0);
|
SetVibrate(i&1, i>>1, 1, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// FIXME equivalent ?
|
// FIXME equivalent ?
|
||||||
for (int port = 0; port < 2; port++)
|
for (int port = 0; port < 2; port++)
|
||||||
for (int slot = 0; slot < 4; slot++)
|
for (int slot = 0; slot < 4; slot++)
|
||||||
pads[port][slot].reset_vibrate();
|
pads[port][slot].reset_vibrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pad::reset_all()
|
void Pad::reset_all()
|
||||||
{
|
{
|
||||||
for (int port = 0; port < 2; port++)
|
for (int port = 0; port < 2; port++)
|
||||||
for (int slot = 0; slot < 4; slot++)
|
for (int slot = 0; slot < 4; slot++)
|
||||||
pads[port][slot].reset();
|
pads[port][slot].reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pad::rumble_all()
|
void Pad::rumble_all()
|
||||||
{
|
{
|
||||||
for (unsigned port = 0; port < 2; port++)
|
for (unsigned port = 0; port < 2; port++)
|
||||||
for (unsigned slot = 0; slot < 4; slot++)
|
for (unsigned slot = 0; slot < 4; slot++)
|
||||||
pads[port][slot].rumble(port);
|
pads[port][slot].rumble(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
@ -163,41 +166,47 @@ inline bool IsDualshock2()
|
||||||
return config.padConfigs[query.port][query.slot].type == Dualshock2Pad ||
|
return config.padConfigs[query.port][query.slot].type == Dualshock2Pad ||
|
||||||
(config.padConfigs[query.port][query.slot].type == GuitarPad && config.GH2);
|
(config.padConfigs[query.port][query.slot].type == GuitarPad && config.GH2);
|
||||||
#else
|
#else
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 pad_start_poll(u8 pad)
|
u8 pad_start_poll(u8 pad)
|
||||||
{
|
{
|
||||||
return query.start_poll(pad - 1);
|
return query.start_poll(pad - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 pad_poll(u8 value)
|
u8 pad_poll(u8 value)
|
||||||
{
|
{
|
||||||
if (query.lastByte + 1 >= query.numBytes) {
|
if (query.lastByte + 1 >= query.numBytes)
|
||||||
return 0;
|
{
|
||||||
}
|
return 0;
|
||||||
if (query.lastByte && query.queryDone) {
|
}
|
||||||
return query.response[++query.lastByte];
|
if (query.lastByte && query.queryDone)
|
||||||
}
|
{
|
||||||
|
return query.response[++query.lastByte];
|
||||||
|
}
|
||||||
|
|
||||||
Pad *pad = &pads[query.port][query.slot];
|
Pad* pad = &pads[query.port][query.slot];
|
||||||
|
|
||||||
if (query.lastByte == 0) {
|
if (query.lastByte == 0)
|
||||||
query.lastByte++;
|
{
|
||||||
query.currentCommand = value;
|
query.lastByte++;
|
||||||
|
query.currentCommand = value;
|
||||||
|
|
||||||
switch (value) {
|
switch (value)
|
||||||
case CMD_CONFIG_MODE:
|
{
|
||||||
if (pad->config) {
|
case CMD_CONFIG_MODE:
|
||||||
// In config mode. Might not actually be leaving it.
|
if (pad->config)
|
||||||
query.set_result(ConfigExit);
|
{
|
||||||
return 0xF3;
|
// In config mode. Might not actually be leaving it.
|
||||||
}
|
query.set_result(ConfigExit);
|
||||||
[[fallthrough]]; // fallthrough on purpose (but I don't know why)
|
return 0xF3;
|
||||||
|
}
|
||||||
|
[[fallthrough]]; // fallthrough on purpose (but I don't know why)
|
||||||
|
|
||||||
case CMD_READ_DATA_AND_VIBRATE: {
|
case CMD_READ_DATA_AND_VIBRATE:
|
||||||
query.response[2] = 0x5A;
|
{
|
||||||
|
query.response[2] = 0x5A;
|
||||||
#if 0
|
#if 0
|
||||||
int i;
|
int i;
|
||||||
Update(query.port, query.slot);
|
Update(query.port, query.slot);
|
||||||
|
@ -234,39 +243,41 @@ u8 pad_poll(u8 value)
|
||||||
b1=b1 & 0x1f;
|
b1=b1 & 0x1f;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint16_t buttons = g_key_status.get(query.port);
|
uint16_t buttons = g_key_status.get(query.port);
|
||||||
|
|
||||||
query.numBytes = 5;
|
query.numBytes = 5;
|
||||||
|
|
||||||
query.response[3] = (buttons >> 8) & 0xFF;
|
query.response[3] = (buttons >> 8) & 0xFF;
|
||||||
query.response[4] = (buttons >> 0) & 0xFF;
|
query.response[4] = (buttons >> 0) & 0xFF;
|
||||||
|
|
||||||
if (pad->mode != MODE_DIGITAL) { // ANALOG || DS2 native
|
if (pad->mode != MODE_DIGITAL)
|
||||||
query.numBytes = 9;
|
{ // ANALOG || DS2 native
|
||||||
|
query.numBytes = 9;
|
||||||
|
|
||||||
query.response[5] = g_key_status.get(query.port, PAD_R_RIGHT);
|
query.response[5] = g_key_status.get(query.port, PAD_R_RIGHT);
|
||||||
query.response[6] = g_key_status.get(query.port, PAD_R_UP);
|
query.response[6] = g_key_status.get(query.port, PAD_R_UP);
|
||||||
query.response[7] = g_key_status.get(query.port, PAD_L_RIGHT);
|
query.response[7] = g_key_status.get(query.port, PAD_L_RIGHT);
|
||||||
query.response[8] = g_key_status.get(query.port, PAD_L_UP);
|
query.response[8] = g_key_status.get(query.port, PAD_L_UP);
|
||||||
|
|
||||||
if (pad->mode != MODE_ANALOG) { // DS2 native
|
if (pad->mode != MODE_ANALOG)
|
||||||
query.numBytes = 21;
|
{ // DS2 native
|
||||||
|
query.numBytes = 21;
|
||||||
|
|
||||||
query.response[9] = !test_bit(buttons, 13) ? g_key_status.get(query.port, PAD_RIGHT) : 0;
|
query.response[9] = !test_bit(buttons, 13) ? g_key_status.get(query.port, PAD_RIGHT) : 0;
|
||||||
query.response[10] = !test_bit(buttons, 15) ? g_key_status.get(query.port, PAD_LEFT) : 0;
|
query.response[10] = !test_bit(buttons, 15) ? g_key_status.get(query.port, PAD_LEFT) : 0;
|
||||||
query.response[11] = !test_bit(buttons, 12) ? g_key_status.get(query.port, PAD_UP) : 0;
|
query.response[11] = !test_bit(buttons, 12) ? g_key_status.get(query.port, PAD_UP) : 0;
|
||||||
query.response[12] = !test_bit(buttons, 14) ? g_key_status.get(query.port, PAD_DOWN) : 0;
|
query.response[12] = !test_bit(buttons, 14) ? g_key_status.get(query.port, PAD_DOWN) : 0;
|
||||||
|
|
||||||
query.response[13] = !test_bit(buttons, 4) ? g_key_status.get(query.port, PAD_TRIANGLE) : 0;
|
query.response[13] = !test_bit(buttons, 4) ? g_key_status.get(query.port, PAD_TRIANGLE) : 0;
|
||||||
query.response[14] = !test_bit(buttons, 5) ? g_key_status.get(query.port, PAD_CIRCLE) : 0;
|
query.response[14] = !test_bit(buttons, 5) ? g_key_status.get(query.port, PAD_CIRCLE) : 0;
|
||||||
query.response[15] = !test_bit(buttons, 6) ? g_key_status.get(query.port, PAD_CROSS) : 0;
|
query.response[15] = !test_bit(buttons, 6) ? g_key_status.get(query.port, PAD_CROSS) : 0;
|
||||||
query.response[16] = !test_bit(buttons, 7) ? g_key_status.get(query.port, PAD_SQUARE) : 0;
|
query.response[16] = !test_bit(buttons, 7) ? g_key_status.get(query.port, PAD_SQUARE) : 0;
|
||||||
query.response[17] = !test_bit(buttons, 2) ? g_key_status.get(query.port, PAD_L1) : 0;
|
query.response[17] = !test_bit(buttons, 2) ? g_key_status.get(query.port, PAD_L1) : 0;
|
||||||
query.response[18] = !test_bit(buttons, 3) ? g_key_status.get(query.port, PAD_R1) : 0;
|
query.response[18] = !test_bit(buttons, 3) ? g_key_status.get(query.port, PAD_R1) : 0;
|
||||||
query.response[19] = !test_bit(buttons, 0) ? g_key_status.get(query.port, PAD_L2) : 0;
|
query.response[19] = !test_bit(buttons, 0) ? g_key_status.get(query.port, PAD_L2) : 0;
|
||||||
query.response[20] = !test_bit(buttons, 1) ? g_key_status.get(query.port, PAD_R2) : 0;
|
query.response[20] = !test_bit(buttons, 1) ? g_key_status.get(query.port, PAD_R2) : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
query.response[3] = b1;
|
query.response[3] = b1;
|
||||||
|
@ -303,160 +314,184 @@ u8 pad_poll(u8 value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
query.lastByte = 1;
|
query.lastByte = 1;
|
||||||
return pad->mode;
|
return pad->mode;
|
||||||
|
|
||||||
case CMD_SET_VREF_PARAM:
|
case CMD_SET_VREF_PARAM:
|
||||||
query.set_final_result(noclue);
|
query.set_final_result(noclue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_QUERY_DS2_ANALOG_MODE:
|
case CMD_QUERY_DS2_ANALOG_MODE:
|
||||||
// Right? Wrong? No clue.
|
// Right? Wrong? No clue.
|
||||||
if (pad->mode == MODE_DIGITAL) {
|
if (pad->mode == MODE_DIGITAL)
|
||||||
queryMaskMode[1] = queryMaskMode[2] = queryMaskMode[3] = 0;
|
{
|
||||||
queryMaskMode[6] = 0x00;
|
queryMaskMode[1] = queryMaskMode[2] = queryMaskMode[3] = 0;
|
||||||
} else {
|
queryMaskMode[6] = 0x00;
|
||||||
queryMaskMode[1] = pad->umask[0];
|
}
|
||||||
queryMaskMode[2] = pad->umask[1];
|
else
|
||||||
queryMaskMode[3] = 0x03;
|
{
|
||||||
// Not entirely sure about this.
|
queryMaskMode[1] = pad->umask[0];
|
||||||
//queryMaskMode[3] = 0x01 | (pad->mode == MODE_DS2_NATIVE)*2;
|
queryMaskMode[2] = pad->umask[1];
|
||||||
queryMaskMode[6] = 0x5A;
|
queryMaskMode[3] = 0x03;
|
||||||
}
|
// Not entirely sure about this.
|
||||||
query.set_final_result(queryMaskMode);
|
//queryMaskMode[3] = 0x01 | (pad->mode == MODE_DS2_NATIVE)*2;
|
||||||
break;
|
queryMaskMode[6] = 0x5A;
|
||||||
|
}
|
||||||
|
query.set_final_result(queryMaskMode);
|
||||||
|
break;
|
||||||
|
|
||||||
case CMD_SET_MODE_AND_LOCK:
|
case CMD_SET_MODE_AND_LOCK:
|
||||||
query.set_result(setMode);
|
query.set_result(setMode);
|
||||||
pad->reset_vibrate();
|
pad->reset_vibrate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_QUERY_MODEL_AND_MODE:
|
case CMD_QUERY_MODEL_AND_MODE:
|
||||||
if (IsDualshock2()) {
|
if (IsDualshock2())
|
||||||
query.set_final_result(queryModelDS2);
|
{
|
||||||
} else {
|
query.set_final_result(queryModelDS2);
|
||||||
query.set_final_result(queryModelDS1);
|
}
|
||||||
}
|
else
|
||||||
// Not digital mode.
|
{
|
||||||
query.response[5] = (pad->mode & 0xF) != 1;
|
query.set_final_result(queryModelDS1);
|
||||||
break;
|
}
|
||||||
|
// Not digital mode.
|
||||||
|
query.response[5] = (pad->mode & 0xF) != 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case CMD_QUERY_ACT:
|
case CMD_QUERY_ACT:
|
||||||
query.set_result(queryAct[0]);
|
query.set_result(queryAct[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_QUERY_COMB:
|
case CMD_QUERY_COMB:
|
||||||
query.set_final_result(queryComb);
|
query.set_final_result(queryComb);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_QUERY_MODE:
|
case CMD_QUERY_MODE:
|
||||||
query.set_result(queryMode);
|
query.set_result(queryMode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_VIBRATION_TOGGLE:
|
case CMD_VIBRATION_TOGGLE:
|
||||||
memcpy(query.response + 2, pad->vibrate, 7);
|
memcpy(query.response + 2, pad->vibrate, 7);
|
||||||
query.numBytes = 9;
|
query.numBytes = 9;
|
||||||
//query.set_result(pad->vibrate); // warning copy 7b not 8 (but it is really important?)
|
//query.set_result(pad->vibrate); // warning copy 7b not 8 (but it is really important?)
|
||||||
pad->reset_vibrate();
|
pad->reset_vibrate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SET_DS2_NATIVE_MODE:
|
case CMD_SET_DS2_NATIVE_MODE:
|
||||||
if (IsDualshock2()) {
|
if (IsDualshock2())
|
||||||
query.set_result(setNativeMode);
|
{
|
||||||
} else {
|
query.set_result(setNativeMode);
|
||||||
query.set_final_result(setNativeMode);
|
}
|
||||||
}
|
else
|
||||||
break;
|
{
|
||||||
|
query.set_final_result(setNativeMode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
query.numBytes = 0;
|
query.numBytes = 0;
|
||||||
query.queryDone = 1;
|
query.queryDone = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0xF3;
|
return 0xF3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
query.lastByte++;
|
||||||
|
|
||||||
} else {
|
switch (query.currentCommand)
|
||||||
query.lastByte++;
|
{
|
||||||
|
case CMD_READ_DATA_AND_VIBRATE:
|
||||||
|
if (query.lastByte == pad->vibrateI[0])
|
||||||
|
pad->set_vibrate(1, 255 * (value & 1));
|
||||||
|
else if (query.lastByte == pad->vibrateI[1])
|
||||||
|
pad->set_vibrate(0, value);
|
||||||
|
|
||||||
switch (query.currentCommand) {
|
break;
|
||||||
case CMD_READ_DATA_AND_VIBRATE:
|
|
||||||
if (query.lastByte == pad->vibrateI[0])
|
|
||||||
pad->set_vibrate(1, 255 * (value & 1));
|
|
||||||
else if (query.lastByte == pad->vibrateI[1])
|
|
||||||
pad->set_vibrate(0, value);
|
|
||||||
|
|
||||||
break;
|
case CMD_CONFIG_MODE:
|
||||||
|
if (query.lastByte == 3)
|
||||||
|
{
|
||||||
|
query.queryDone = 1;
|
||||||
|
pad->config = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case CMD_CONFIG_MODE:
|
case CMD_SET_MODE_AND_LOCK:
|
||||||
if (query.lastByte == 3) {
|
if (query.lastByte == 3 && value < 2)
|
||||||
query.queryDone = 1;
|
{
|
||||||
pad->config = value;
|
pad->set_mode(value ? MODE_ANALOG : MODE_DIGITAL);
|
||||||
}
|
}
|
||||||
break;
|
else if (query.lastByte == 4)
|
||||||
|
{
|
||||||
|
if (value == 3)
|
||||||
|
pad->modeLock = 3;
|
||||||
|
else
|
||||||
|
pad->modeLock = 0;
|
||||||
|
|
||||||
case CMD_SET_MODE_AND_LOCK:
|
query.queryDone = 1;
|
||||||
if (query.lastByte == 3 && value < 2) {
|
}
|
||||||
pad->set_mode(value ? MODE_ANALOG : MODE_DIGITAL);
|
break;
|
||||||
} else if (query.lastByte == 4) {
|
|
||||||
if (value == 3)
|
|
||||||
pad->modeLock = 3;
|
|
||||||
else
|
|
||||||
pad->modeLock = 0;
|
|
||||||
|
|
||||||
query.queryDone = 1;
|
case CMD_QUERY_ACT:
|
||||||
}
|
if (query.lastByte == 3)
|
||||||
break;
|
{
|
||||||
|
if (value < 2)
|
||||||
|
query.set_result(queryAct[value]);
|
||||||
|
// bunch of 0's
|
||||||
|
// else query.set_result(setMode);
|
||||||
|
query.queryDone = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case CMD_QUERY_ACT:
|
case CMD_QUERY_MODE:
|
||||||
if (query.lastByte == 3) {
|
if (query.lastByte == 3 && value < 2)
|
||||||
if (value < 2)
|
{
|
||||||
query.set_result(queryAct[value]);
|
query.response[6] = 4 + value * 3;
|
||||||
// bunch of 0's
|
query.queryDone = 1;
|
||||||
// else query.set_result(setMode);
|
}
|
||||||
query.queryDone = 1;
|
// bunch of 0's
|
||||||
}
|
//else data = setMode;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_QUERY_MODE:
|
case CMD_VIBRATION_TOGGLE:
|
||||||
if (query.lastByte == 3 && value < 2) {
|
if (query.lastByte >= 3)
|
||||||
query.response[6] = 4 + value * 3;
|
{
|
||||||
query.queryDone = 1;
|
if (value == 0)
|
||||||
}
|
{
|
||||||
// bunch of 0's
|
pad->vibrateI[0] = (u8)query.lastByte;
|
||||||
//else data = setMode;
|
}
|
||||||
break;
|
else if (value == 1)
|
||||||
|
{
|
||||||
|
pad->vibrateI[1] = (u8)query.lastByte;
|
||||||
|
}
|
||||||
|
pad->vibrate[query.lastByte - 2] = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case CMD_VIBRATION_TOGGLE:
|
case CMD_SET_DS2_NATIVE_MODE:
|
||||||
if (query.lastByte >= 3) {
|
if (query.lastByte == 3 || query.lastByte == 4)
|
||||||
if (value == 0) {
|
{
|
||||||
pad->vibrateI[0] = (u8)query.lastByte;
|
pad->umask[query.lastByte - 3] = value;
|
||||||
} else if (value == 1) {
|
}
|
||||||
pad->vibrateI[1] = (u8)query.lastByte;
|
else if (query.lastByte == 5)
|
||||||
}
|
{
|
||||||
pad->vibrate[query.lastByte - 2] = value;
|
if (!(value & 1))
|
||||||
}
|
pad->set_mode(MODE_DIGITAL);
|
||||||
break;
|
else if (!(value & 2))
|
||||||
|
pad->set_mode(MODE_ANALOG);
|
||||||
|
else
|
||||||
|
pad->set_mode(MODE_DS2_NATIVE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case CMD_SET_DS2_NATIVE_MODE:
|
default:
|
||||||
if (query.lastByte == 3 || query.lastByte == 4) {
|
return 0;
|
||||||
pad->umask[query.lastByte - 3] = value;
|
}
|
||||||
} else if (query.lastByte == 5) {
|
|
||||||
if (!(value & 1))
|
|
||||||
pad->set_mode(MODE_DIGITAL);
|
|
||||||
else if (!(value & 2))
|
|
||||||
pad->set_mode(MODE_ANALOG);
|
|
||||||
else
|
|
||||||
pad->set_mode(MODE_DS2_NATIVE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
return query.response[query.lastByte];
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return query.response[query.lastByte];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,87 +22,87 @@
|
||||||
// The state of the PS2 bus
|
// The state of the PS2 bus
|
||||||
struct QueryInfo
|
struct QueryInfo
|
||||||
{
|
{
|
||||||
u8 port;
|
u8 port;
|
||||||
u8 slot;
|
u8 slot;
|
||||||
u8 lastByte;
|
u8 lastByte;
|
||||||
u8 currentCommand;
|
u8 currentCommand;
|
||||||
u8 numBytes;
|
u8 numBytes;
|
||||||
u8 queryDone;
|
u8 queryDone;
|
||||||
u8 response[42];
|
u8 response[42];
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
u8 start_poll(int port);
|
u8 start_poll(int port);
|
||||||
|
|
||||||
template <size_t S>
|
template <size_t S>
|
||||||
void set_result(const u8 (&rsp)[S])
|
void set_result(const u8 (&rsp)[S])
|
||||||
{
|
{
|
||||||
memcpy(response + 2, rsp, S);
|
memcpy(response + 2, rsp, S);
|
||||||
numBytes = 2 + S;
|
numBytes = 2 + S;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t S>
|
template <size_t S>
|
||||||
void set_final_result(const u8 (&rsp)[S])
|
void set_final_result(const u8 (&rsp)[S])
|
||||||
{
|
{
|
||||||
set_result(rsp);
|
set_result(rsp);
|
||||||
queryDone = 1;
|
queryDone = 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Freeze data, for a single pad. Basically has all pad state that
|
// Freeze data, for a single pad. Basically has all pad state that
|
||||||
// a PS2 can set.
|
// a PS2 can set.
|
||||||
struct PadFreezeData
|
struct PadFreezeData
|
||||||
{
|
{
|
||||||
// Digital / Analog / DS2 Native
|
// Digital / Analog / DS2 Native
|
||||||
u8 mode;
|
u8 mode;
|
||||||
|
|
||||||
u8 modeLock;
|
u8 modeLock;
|
||||||
|
|
||||||
// In config mode
|
// In config mode
|
||||||
u8 config;
|
u8 config;
|
||||||
|
|
||||||
u8 vibrate[8];
|
u8 vibrate[8];
|
||||||
u8 umask[2];
|
u8 umask[2];
|
||||||
|
|
||||||
// Vibration indices.
|
// Vibration indices.
|
||||||
u8 vibrateI[2];
|
u8 vibrateI[2];
|
||||||
|
|
||||||
// Last vibration value sent to controller.
|
// Last vibration value sent to controller.
|
||||||
// Only used so as not to call vibration
|
// Only used so as not to call vibration
|
||||||
// functions when old and new values are both 0.
|
// functions when old and new values are both 0.
|
||||||
u8 currentVibrate[2];
|
u8 currentVibrate[2];
|
||||||
|
|
||||||
// Next vibrate val to send to controller. If next and current are
|
// Next vibrate val to send to controller. If next and current are
|
||||||
// both 0, nothing is sent to the controller. Otherwise, it's sent
|
// both 0, nothing is sent to the controller. Otherwise, it's sent
|
||||||
// on every update.
|
// on every update.
|
||||||
u8 nextVibrate[2];
|
u8 nextVibrate[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
class Pad : public PadFreezeData
|
class Pad : public PadFreezeData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Lilypad store here the state of PC pad
|
// Lilypad store here the state of PC pad
|
||||||
|
|
||||||
void rumble(unsigned port);
|
void rumble(unsigned port);
|
||||||
void set_vibrate(int motor, u8 val);
|
void set_vibrate(int motor, u8 val);
|
||||||
void reset_vibrate();
|
void reset_vibrate();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
void set_mode(int mode);
|
void set_mode(int mode);
|
||||||
|
|
||||||
static void reset_all();
|
static void reset_all();
|
||||||
static void stop_vibrate_all();
|
static void stop_vibrate_all();
|
||||||
static void rumble_all();
|
static void rumble_all();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Full state to manage save state
|
// Full state to manage save state
|
||||||
struct PadPluginFreezeData
|
struct PadPluginFreezeData
|
||||||
{
|
{
|
||||||
char format[8];
|
char format[8];
|
||||||
u32 version;
|
u32 version;
|
||||||
// active slot for port
|
// active slot for port
|
||||||
u8 slot[2];
|
u8 slot[2];
|
||||||
PadFreezeData padData[2][4];
|
PadFreezeData padData[2][4];
|
||||||
QueryInfo query;
|
QueryInfo query;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern QueryInfo query;
|
extern QueryInfo query;
|
||||||
|
|
|
@ -15,49 +15,50 @@
|
||||||
|
|
||||||
#include "GamepadConfiguration.h"
|
#include "GamepadConfiguration.h"
|
||||||
|
|
||||||
GamepadConfiguration::GamepadConfiguration(int pad, wxWindow *parent)
|
GamepadConfiguration::GamepadConfiguration(int pad, wxWindow* parent)
|
||||||
: wxDialog(parent, wxID_ANY, _T("Gamepad"), wxDefaultPosition, wxDefaultSize,
|
: wxDialog(parent, wxID_ANY, _T("Gamepad"), wxDefaultPosition, wxDefaultSize,
|
||||||
wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN)
|
wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN)
|
||||||
{
|
{
|
||||||
m_pad_id = pad;
|
m_pad_id = pad;
|
||||||
|
|
||||||
wxBoxSizer *gamepad_box = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* gamepad_box = new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
wxArrayString choices;
|
wxArrayString choices;
|
||||||
for (const auto &j : s_vgamePad) {
|
for (const auto& j : s_vgamePad)
|
||||||
choices.Add(j->GetName());
|
{
|
||||||
}
|
choices.Add(j->GetName());
|
||||||
|
}
|
||||||
|
|
||||||
m_joy_map = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
|
m_joy_map = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
|
||||||
m_cb_rumble = new wxCheckBox(this, enable_rumble_id, _T("&Enable rumble"));
|
m_cb_rumble = new wxCheckBox(this, enable_rumble_id, _T("&Enable rumble"));
|
||||||
|
|
||||||
wxStaticBoxSizer *rumble_box = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Rumble intensity"));
|
wxStaticBoxSizer* rumble_box = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Rumble intensity"));
|
||||||
m_sl_rumble_intensity = new wxSlider(this, rumble_slider_id, 0, 0, 0x7FFF, wxDefaultPosition, wxDefaultSize,
|
m_sl_rumble_intensity = new wxSlider(this, rumble_slider_id, 0, 0, 0x7FFF, wxDefaultPosition, wxDefaultSize,
|
||||||
wxSL_HORIZONTAL | wxSL_LABELS | wxSL_BOTTOM);
|
wxSL_HORIZONTAL | wxSL_LABELS | wxSL_BOTTOM);
|
||||||
|
|
||||||
wxStaticBoxSizer *joy_box = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Joystick sensibility"));
|
wxStaticBoxSizer* joy_box = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Joystick sensibility"));
|
||||||
m_sl_joystick_sensibility = new wxSlider(this, joy_slider_id, 0, 0, 200, wxDefaultPosition, wxDefaultSize,
|
m_sl_joystick_sensibility = new wxSlider(this, joy_slider_id, 0, 0, 200, wxDefaultPosition, wxDefaultSize,
|
||||||
wxSL_HORIZONTAL | wxSL_LABELS | wxSL_BOTTOM);
|
wxSL_HORIZONTAL | wxSL_LABELS | wxSL_BOTTOM);
|
||||||
|
|
||||||
gamepad_box->Add(m_joy_map, wxSizerFlags().Expand().Border(wxALL, 5));
|
gamepad_box->Add(m_joy_map, wxSizerFlags().Expand().Border(wxALL, 5));
|
||||||
gamepad_box->Add(m_cb_rumble, wxSizerFlags().Expand());
|
gamepad_box->Add(m_cb_rumble, wxSizerFlags().Expand());
|
||||||
|
|
||||||
rumble_box->Add(m_sl_rumble_intensity, wxSizerFlags().Expand().Border(wxALL, 5));
|
rumble_box->Add(m_sl_rumble_intensity, wxSizerFlags().Expand().Border(wxALL, 5));
|
||||||
joy_box->Add(m_sl_joystick_sensibility, wxSizerFlags().Expand().Border(wxALL, 5));
|
joy_box->Add(m_sl_joystick_sensibility, wxSizerFlags().Expand().Border(wxALL, 5));
|
||||||
|
|
||||||
gamepad_box->Add(rumble_box, wxSizerFlags().Expand().Border(wxALL, 5));
|
gamepad_box->Add(rumble_box, wxSizerFlags().Expand().Border(wxALL, 5));
|
||||||
gamepad_box->Add(joy_box, wxSizerFlags().Expand().Border(wxALL, 5));
|
gamepad_box->Add(joy_box, wxSizerFlags().Expand().Border(wxALL, 5));
|
||||||
|
|
||||||
gamepad_box->Add(CreateSeparatedButtonSizer(wxOK), wxSizerFlags().Right().Border(wxALL, 5));
|
gamepad_box->Add(CreateSeparatedButtonSizer(wxOK), wxSizerFlags().Right().Border(wxALL, 5));
|
||||||
|
|
||||||
Bind(wxEVT_BUTTON, &GamepadConfiguration::OnOk, this, wxID_OK);
|
Bind(wxEVT_BUTTON, &GamepadConfiguration::OnOk, this, wxID_OK);
|
||||||
Bind(wxEVT_SCROLL_THUMBRELEASE, &GamepadConfiguration::OnSliderReleased, this);
|
Bind(wxEVT_SCROLL_THUMBRELEASE, &GamepadConfiguration::OnSliderReleased, this);
|
||||||
Bind(wxEVT_CHECKBOX, &GamepadConfiguration::OnCheckboxChange, this);
|
Bind(wxEVT_CHECKBOX, &GamepadConfiguration::OnCheckboxChange, this);
|
||||||
Bind(wxEVT_CHOICE, &GamepadConfiguration::OnChoiceChange, this);
|
Bind(wxEVT_CHOICE, &GamepadConfiguration::OnChoiceChange, this);
|
||||||
|
|
||||||
repopulate();
|
repopulate();
|
||||||
|
|
||||||
SetSizerAndFit(gamepad_box);
|
SetSizerAndFit(gamepad_box);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,37 +68,40 @@ GamepadConfiguration::GamepadConfiguration(int pad, wxWindow *parent)
|
||||||
*/
|
*/
|
||||||
void GamepadConfiguration::InitGamepadConfiguration()
|
void GamepadConfiguration::InitGamepadConfiguration()
|
||||||
{
|
{
|
||||||
repopulate(); // Set label and fit simulated key array
|
repopulate(); // Set label and fit simulated key array
|
||||||
/*
|
/*
|
||||||
* Check if there exist at least one pad available
|
* Check if there exist at least one pad available
|
||||||
* if the pad id is 0, you need at least 1 gamepad connected,
|
* if the pad id is 0, you need at least 1 gamepad connected,
|
||||||
* if the pad id is 1, you need at least 2 gamepads connected,
|
* if the pad id is 1, you need at least 2 gamepads connected,
|
||||||
* Prevent to use a none initialized value on s_vgamePad (core dump)
|
* Prevent to use a none initialized value on s_vgamePad (core dump)
|
||||||
*/
|
*/
|
||||||
if (s_vgamePad.size() >= m_pad_id + 1) {
|
if (s_vgamePad.size() >= m_pad_id + 1)
|
||||||
/*
|
{
|
||||||
|
/*
|
||||||
* Determine if the device can use rumble
|
* Determine if the device can use rumble
|
||||||
* Use TestForce with a very low strength (can't be felt)
|
* Use TestForce with a very low strength (can't be felt)
|
||||||
* May be better to create a new function in order to check only that
|
* May be better to create a new function in order to check only that
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Bad idea. Some connected devices might support rumble but not all connected devices.
|
// Bad idea. Some connected devices might support rumble but not all connected devices.
|
||||||
// if (!s_vgamePad[m_pad_id]->TestForce(0.001f)) {
|
// if (!s_vgamePad[m_pad_id]->TestForce(0.001f)) {
|
||||||
// wxMessageBox(L"Rumble is not available for your device.");
|
// wxMessageBox(L"Rumble is not available for your device.");
|
||||||
// m_cb_rumble->Disable(); // disable the rumble checkbox
|
// m_cb_rumble->Disable(); // disable the rumble checkbox
|
||||||
// m_sl_rumble_intensity->Disable(); // disable the rumble intensity slider
|
// m_sl_rumble_intensity->Disable(); // disable the rumble intensity slider
|
||||||
// }
|
// }
|
||||||
} else {
|
}
|
||||||
wxMessageBox(L"No gamepad detected.");
|
else
|
||||||
m_sl_joystick_sensibility->Disable(); // disable the joystick sensibility slider
|
{
|
||||||
m_cb_rumble->Disable(); // disable the rumble checkbox
|
wxMessageBox(L"No gamepad detected.");
|
||||||
m_sl_rumble_intensity->Disable(); // disable the rumble intensity slider
|
m_sl_joystick_sensibility->Disable(); // disable the joystick sensibility slider
|
||||||
}
|
m_cb_rumble->Disable(); // disable the rumble checkbox
|
||||||
|
m_sl_rumble_intensity->Disable(); // disable the rumble intensity slider
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GamepadConfiguration::OnOk(wxCommandEvent &event)
|
void GamepadConfiguration::OnOk(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,59 +109,59 @@ void GamepadConfiguration::OnOk(wxCommandEvent &event)
|
||||||
* @FIXME The current solution can't change the joystick sensibility and the rumble intensity
|
* @FIXME The current solution can't change the joystick sensibility and the rumble intensity
|
||||||
* for a specific gamepad. The same value is used for both
|
* for a specific gamepad. The same value is used for both
|
||||||
*/
|
*/
|
||||||
void GamepadConfiguration::OnSliderReleased(wxCommandEvent &event)
|
void GamepadConfiguration::OnSliderReleased(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
wxSlider *sl_tmp = (wxSlider *)event.GetEventObject();
|
wxSlider* sl_tmp = (wxSlider*)event.GetEventObject();
|
||||||
int sl_id = sl_tmp->GetId();
|
int sl_id = sl_tmp->GetId();
|
||||||
|
|
||||||
if (sl_id == rumble_slider_id)
|
if (sl_id == rumble_slider_id)
|
||||||
{
|
{
|
||||||
g_conf.set_ff_intensity(m_sl_rumble_intensity->GetValue());
|
g_conf.set_ff_intensity(m_sl_rumble_intensity->GetValue());
|
||||||
|
|
||||||
// convert in a float value between 0 and 1, and run rumble feedback.
|
// convert in a float value between 0 and 1, and run rumble feedback.
|
||||||
// 0 to 1 scales to 0x0 to 0x7FFF
|
// 0 to 1 scales to 0x0 to 0x7FFF
|
||||||
s_vgamePad[m_pad_id]->TestForce(m_sl_rumble_intensity->GetValue() / 0x7FFF);
|
s_vgamePad[m_pad_id]->TestForce(m_sl_rumble_intensity->GetValue() / 0x7FFF);
|
||||||
}
|
}
|
||||||
else if (sl_id == joy_slider_id)
|
else if (sl_id == joy_slider_id)
|
||||||
{
|
{
|
||||||
g_conf.set_sensibility(m_sl_joystick_sensibility->GetValue());
|
g_conf.set_sensibility(m_sl_joystick_sensibility->GetValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checkbox event, called when the value of the checkbox change
|
* Checkbox event, called when the value of the checkbox change
|
||||||
*/
|
*/
|
||||||
void GamepadConfiguration::OnCheckboxChange(wxCommandEvent &event)
|
void GamepadConfiguration::OnCheckboxChange(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
wxCheckBox *cb_tmp = (wxCheckBox *)event.GetEventObject(); // get the slider object
|
wxCheckBox* cb_tmp = (wxCheckBox*)event.GetEventObject(); // get the slider object
|
||||||
int cb_id = cb_tmp->GetId();
|
int cb_id = cb_tmp->GetId();
|
||||||
|
|
||||||
if (cb_id == enable_rumble_id)
|
if (cb_id == enable_rumble_id)
|
||||||
{
|
{
|
||||||
g_conf.pad_options[m_pad_id].forcefeedback = (m_cb_rumble->GetValue()) ? (u32)1 : (u32)0;
|
g_conf.pad_options[m_pad_id].forcefeedback = (m_cb_rumble->GetValue()) ? (u32)1 : (u32)0;
|
||||||
if (m_cb_rumble->GetValue())
|
if (m_cb_rumble->GetValue())
|
||||||
{
|
{
|
||||||
s_vgamePad[m_pad_id]->TestForce();
|
s_vgamePad[m_pad_id]->TestForce();
|
||||||
m_sl_rumble_intensity->Enable();
|
m_sl_rumble_intensity->Enable();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_sl_rumble_intensity->Disable();
|
m_sl_rumble_intensity->Disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Checkbox event, called when the value of the choice box change
|
* Checkbox event, called when the value of the choice box change
|
||||||
*/
|
*/
|
||||||
void GamepadConfiguration::OnChoiceChange(wxCommandEvent &event)
|
void GamepadConfiguration::OnChoiceChange(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
wxChoice *choice_tmp = (wxChoice *)event.GetEventObject();
|
wxChoice* choice_tmp = (wxChoice*)event.GetEventObject();
|
||||||
int id = choice_tmp->GetSelection();
|
int id = choice_tmp->GetSelection();
|
||||||
if (id != wxNOT_FOUND)
|
if (id != wxNOT_FOUND)
|
||||||
{
|
{
|
||||||
g_conf.set_joy_uid(m_pad_id, GamePad::index_to_uid(id));
|
g_conf.set_joy_uid(m_pad_id, GamePad::index_to_uid(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************/
|
/****************************************/
|
||||||
|
@ -167,15 +171,15 @@ void GamepadConfiguration::OnChoiceChange(wxCommandEvent &event)
|
||||||
// Set button values
|
// Set button values
|
||||||
void GamepadConfiguration::repopulate()
|
void GamepadConfiguration::repopulate()
|
||||||
{
|
{
|
||||||
m_cb_rumble->SetValue(g_conf.pad_options[m_pad_id].forcefeedback);
|
m_cb_rumble->SetValue(g_conf.pad_options[m_pad_id].forcefeedback);
|
||||||
|
|
||||||
m_sl_rumble_intensity->SetValue(g_conf.get_ff_intensity());
|
m_sl_rumble_intensity->SetValue(g_conf.get_ff_intensity());
|
||||||
m_sl_joystick_sensibility->SetValue(g_conf.get_sensibility());
|
m_sl_joystick_sensibility->SetValue(g_conf.get_sensibility());
|
||||||
|
|
||||||
u32 joyid = GamePad::uid_to_index(m_pad_id);
|
u32 joyid = GamePad::uid_to_index(m_pad_id);
|
||||||
if (joyid < m_joy_map->GetCount() && !m_joy_map->IsEmpty())
|
if (joyid < m_joy_map->GetCount() && !m_joy_map->IsEmpty())
|
||||||
m_joy_map->SetSelection(joyid);
|
m_joy_map->SetSelection(joyid);
|
||||||
|
|
||||||
// enable rumble intensity slider if the checkbox is checked
|
// enable rumble intensity slider if the checkbox is checked
|
||||||
m_sl_rumble_intensity->Enable(m_cb_rumble->GetValue());
|
m_sl_rumble_intensity->Enable(m_cb_rumble->GetValue());
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,24 +30,24 @@ static const s32 enable_rumble_id = wxID_HIGHEST + 200 + 3;
|
||||||
|
|
||||||
class GamepadConfiguration : public wxDialog
|
class GamepadConfiguration : public wxDialog
|
||||||
{
|
{
|
||||||
wxCheckBox *m_cb_rumble;
|
wxCheckBox* m_cb_rumble;
|
||||||
wxSlider *m_sl_rumble_intensity, *m_sl_joystick_sensibility;
|
wxSlider *m_sl_rumble_intensity, *m_sl_joystick_sensibility;
|
||||||
wxChoice *m_joy_map;
|
wxChoice* m_joy_map;
|
||||||
|
|
||||||
u32 m_pad_id;
|
u32 m_pad_id;
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
void repopulate();
|
void repopulate();
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
void OnOk(wxCommandEvent &);
|
void OnOk(wxCommandEvent&);
|
||||||
void OnSliderReleased(wxCommandEvent &);
|
void OnSliderReleased(wxCommandEvent&);
|
||||||
void OnCheckboxChange(wxCommandEvent &);
|
void OnCheckboxChange(wxCommandEvent&);
|
||||||
void OnChoiceChange(wxCommandEvent &);
|
void OnChoiceChange(wxCommandEvent&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GamepadConfiguration(int, wxWindow *);
|
GamepadConfiguration(int, wxWindow*);
|
||||||
void InitGamepadConfiguration();
|
void InitGamepadConfiguration();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __GAMEPADCONFIGURATION_H__
|
#endif // __GAMEPADCONFIGURATION_H__
|
||||||
|
|
|
@ -16,52 +16,51 @@
|
||||||
#include "JoystickConfiguration.h"
|
#include "JoystickConfiguration.h"
|
||||||
|
|
||||||
// Constructor of JoystickConfiguration
|
// Constructor of JoystickConfiguration
|
||||||
JoystickConfiguration::JoystickConfiguration(int pad, bool left, wxWindow *parent)
|
JoystickConfiguration::JoystickConfiguration(int pad, bool left, wxWindow* parent)
|
||||||
: wxDialog(parent, wxID_ANY, _T("Joystick configuration"), wxDefaultPosition, wxDefaultSize,
|
: wxDialog(parent, wxID_ANY, _T("Joystick configuration"), wxDefaultPosition, wxDefaultSize,
|
||||||
wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN)
|
wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN)
|
||||||
{
|
{
|
||||||
m_init_reverse_Lx = m_init_reverse_Ly =
|
m_init_reverse_Lx = m_init_reverse_Ly =
|
||||||
m_init_reverse_Rx = m_init_reverse_Ry =
|
m_init_reverse_Rx = m_init_reverse_Ry =
|
||||||
m_init_mouse_Ljoy = m_init_mouse_Rjoy = false;
|
m_init_mouse_Ljoy = m_init_mouse_Rjoy = false;
|
||||||
|
|
||||||
m_pad_id = pad;
|
m_pad_id = pad;
|
||||||
m_isForLeftJoystick = left;
|
m_isForLeftJoystick = left;
|
||||||
|
|
||||||
wxBoxSizer *joy_conf_box = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* joy_conf_box = new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
if (m_isForLeftJoystick)
|
if (m_isForLeftJoystick)
|
||||||
{
|
{
|
||||||
m_cb_reverse_Lx = new wxCheckBox(this, Lx_check_id, _T("Reverse Lx"));
|
m_cb_reverse_Lx = new wxCheckBox(this, Lx_check_id, _T("Reverse Lx"));
|
||||||
m_cb_reverse_Ly = new wxCheckBox(this, Ly_check_id, _T("Reverse Ly"));
|
m_cb_reverse_Ly = new wxCheckBox(this, Ly_check_id, _T("Reverse Ly"));
|
||||||
m_cb_mouse_Ljoy = new wxCheckBox(this, Ljoy_check_id, _T("Use mouse for left analog joystick"));
|
m_cb_mouse_Ljoy = new wxCheckBox(this, Ljoy_check_id, _T("Use mouse for left analog joystick"));
|
||||||
|
|
||||||
joy_conf_box->Add(m_cb_reverse_Lx, wxSizerFlags().Expand().Border(wxLEFT | wxRIGHT, 5));
|
joy_conf_box->Add(m_cb_reverse_Lx, wxSizerFlags().Expand().Border(wxLEFT | wxRIGHT, 5));
|
||||||
joy_conf_box->Add(m_cb_reverse_Ly, wxSizerFlags().Expand().Border(wxLEFT | wxRIGHT, 5));
|
joy_conf_box->Add(m_cb_reverse_Ly, wxSizerFlags().Expand().Border(wxLEFT | wxRIGHT, 5));
|
||||||
joy_conf_box->Add(m_cb_mouse_Ljoy, wxSizerFlags().Expand().Border(wxLEFT | wxRIGHT, 5));
|
joy_conf_box->Add(m_cb_mouse_Ljoy, wxSizerFlags().Expand().Border(wxLEFT | wxRIGHT, 5));
|
||||||
|
|
||||||
m_cb_reverse_Rx = m_cb_reverse_Ry = m_cb_mouse_Rjoy = nullptr;
|
m_cb_reverse_Rx = m_cb_reverse_Ry = m_cb_mouse_Rjoy = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_cb_reverse_Rx = new wxCheckBox(this, Rx_check_id, _T("Reverse Rx"));
|
||||||
|
m_cb_reverse_Ry = new wxCheckBox(this, Ry_check_id, _T("Reverse Ry"));
|
||||||
|
m_cb_mouse_Rjoy = new wxCheckBox(this, Rjoy_check_id, _T("Use mouse for right analog joystick"));
|
||||||
|
|
||||||
}
|
joy_conf_box->Add(m_cb_reverse_Rx, wxSizerFlags().Expand().Border(wxLEFT | wxRIGHT, 5));
|
||||||
else
|
joy_conf_box->Add(m_cb_reverse_Ry, wxSizerFlags().Expand().Border(wxLEFT | wxRIGHT, 5));
|
||||||
{
|
joy_conf_box->Add(m_cb_mouse_Rjoy, wxSizerFlags().Expand().Border(wxLEFT | wxRIGHT, 5));
|
||||||
m_cb_reverse_Rx = new wxCheckBox(this, Rx_check_id, _T("Reverse Rx"));
|
|
||||||
m_cb_reverse_Ry = new wxCheckBox(this, Ry_check_id, _T("Reverse Ry"));
|
|
||||||
m_cb_mouse_Rjoy = new wxCheckBox(this, Rjoy_check_id, _T("Use mouse for right analog joystick"));
|
|
||||||
|
|
||||||
joy_conf_box->Add(m_cb_reverse_Rx, wxSizerFlags().Expand().Border(wxLEFT | wxRIGHT, 5));
|
m_cb_reverse_Lx = m_cb_reverse_Ly = m_cb_mouse_Ljoy = nullptr;
|
||||||
joy_conf_box->Add(m_cb_reverse_Ry, wxSizerFlags().Expand().Border(wxLEFT | wxRIGHT, 5));
|
}
|
||||||
joy_conf_box->Add(m_cb_mouse_Rjoy, wxSizerFlags().Expand().Border(wxLEFT | wxRIGHT, 5));
|
|
||||||
|
|
||||||
m_cb_reverse_Lx = m_cb_reverse_Ly = m_cb_mouse_Ljoy = nullptr;
|
joy_conf_box->Add(CreateSeparatedButtonSizer(wxOK | wxCANCEL), wxSizerFlags().Border(wxALL, 5).Right());
|
||||||
}
|
|
||||||
|
|
||||||
joy_conf_box->Add(CreateSeparatedButtonSizer(wxOK | wxCANCEL), wxSizerFlags().Border(wxALL, 5).Right());
|
Bind(wxEVT_BUTTON, &JoystickConfiguration::OnOk, this, wxID_OK);
|
||||||
|
Bind(wxEVT_BUTTON, &JoystickConfiguration::OnCancel, this, wxID_CANCEL);
|
||||||
|
Bind(wxEVT_CHECKBOX, &JoystickConfiguration::OnCheckboxChange, this);
|
||||||
|
|
||||||
Bind(wxEVT_BUTTON, &JoystickConfiguration::OnOk, this, wxID_OK);
|
SetSizerAndFit(joy_conf_box);
|
||||||
Bind(wxEVT_BUTTON, &JoystickConfiguration::OnCancel, this, wxID_CANCEL);
|
|
||||||
Bind(wxEVT_CHECKBOX, &JoystickConfiguration::OnCheckboxChange, this);
|
|
||||||
|
|
||||||
SetSizerAndFit(joy_conf_box);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,92 +69,93 @@ JoystickConfiguration::JoystickConfiguration(int pad, bool left, wxWindow *paren
|
||||||
*/
|
*/
|
||||||
void JoystickConfiguration::InitJoystickConfiguration()
|
void JoystickConfiguration::InitJoystickConfiguration()
|
||||||
{
|
{
|
||||||
repopulate(); // Set label and fit simulated key array
|
repopulate(); // Set label and fit simulated key array
|
||||||
/*
|
/*
|
||||||
* Check if there exist at least one pad available
|
* Check if there exist at least one pad available
|
||||||
* if the pad id is 0, you need at least 1 gamepad connected,
|
* if the pad id is 0, you need at least 1 gamepad connected,
|
||||||
* if the pad id is 1, you need at least 2 gamepads connected,
|
* if the pad id is 1, you need at least 2 gamepads connected,
|
||||||
* Prevent to use a none initialized value on s_vgamePad (core dump)
|
* Prevent to use a none initialized value on s_vgamePad (core dump)
|
||||||
*/
|
*/
|
||||||
if (s_vgamePad.size() < m_pad_id + 1) {
|
if (s_vgamePad.size() < m_pad_id + 1)
|
||||||
if (s_vgamePad.empty())
|
{
|
||||||
wxMessageBox(L"No gamepad detected.");
|
if (s_vgamePad.empty())
|
||||||
else
|
wxMessageBox(L"No gamepad detected.");
|
||||||
wxMessageBox(L"No second gamepad detected.");
|
else
|
||||||
|
wxMessageBox(L"No second gamepad detected.");
|
||||||
|
|
||||||
// disable all checkboxes
|
// disable all checkboxes
|
||||||
if (m_isForLeftJoystick)
|
if (m_isForLeftJoystick)
|
||||||
{
|
{
|
||||||
m_cb_reverse_Lx->Disable();
|
m_cb_reverse_Lx->Disable();
|
||||||
m_cb_reverse_Ly->Disable();
|
m_cb_reverse_Ly->Disable();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_cb_reverse_Rx->Disable();
|
m_cb_reverse_Rx->Disable();
|
||||||
m_cb_reverse_Ry->Disable();
|
m_cb_reverse_Ry->Disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoystickConfiguration::OnOk(wxCommandEvent &event)
|
void JoystickConfiguration::OnOk(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoystickConfiguration::OnCancel(wxCommandEvent &event)
|
void JoystickConfiguration::OnCancel(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checkbox event, called when the value of the checkbox change
|
* Checkbox event, called when the value of the checkbox change
|
||||||
*/
|
*/
|
||||||
void JoystickConfiguration::OnCheckboxChange(wxCommandEvent &event)
|
void JoystickConfiguration::OnCheckboxChange(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
wxCheckBox *cb_tmp = (wxCheckBox *)event.GetEventObject(); // get the slider object
|
wxCheckBox* cb_tmp = (wxCheckBox*)event.GetEventObject(); // get the slider object
|
||||||
int cb_id = cb_tmp->GetId();
|
int cb_id = cb_tmp->GetId();
|
||||||
|
|
||||||
if (m_isForLeftJoystick)
|
if (m_isForLeftJoystick)
|
||||||
{
|
{
|
||||||
switch (cb_id)
|
switch (cb_id)
|
||||||
{
|
{
|
||||||
case Lx_check_id:
|
case Lx_check_id:
|
||||||
g_conf.pad_options[m_pad_id].reverse_lx = m_cb_reverse_Lx->GetValue();
|
g_conf.pad_options[m_pad_id].reverse_lx = m_cb_reverse_Lx->GetValue();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Ly_check_id:
|
case Ly_check_id:
|
||||||
g_conf.pad_options[m_pad_id].reverse_ly = m_cb_reverse_Ly->GetValue();
|
g_conf.pad_options[m_pad_id].reverse_ly = m_cb_reverse_Ly->GetValue();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Ljoy_check_id:
|
case Ljoy_check_id:
|
||||||
g_conf.pad_options[m_pad_id].mouse_l = m_cb_mouse_Ljoy->GetValue();
|
g_conf.pad_options[m_pad_id].mouse_l = m_cb_mouse_Ljoy->GetValue();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (cb_id)
|
switch (cb_id)
|
||||||
{
|
{
|
||||||
case Rx_check_id:
|
case Rx_check_id:
|
||||||
g_conf.pad_options[m_pad_id].reverse_rx = m_cb_reverse_Rx->GetValue();
|
g_conf.pad_options[m_pad_id].reverse_rx = m_cb_reverse_Rx->GetValue();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Ry_check_id:
|
case Ry_check_id:
|
||||||
g_conf.pad_options[m_pad_id].reverse_ry = m_cb_reverse_Ry->GetValue();
|
g_conf.pad_options[m_pad_id].reverse_ry = m_cb_reverse_Ry->GetValue();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Rjoy_check_id:
|
case Rjoy_check_id:
|
||||||
g_conf.pad_options[m_pad_id].mouse_r = m_cb_mouse_Rjoy->GetValue();
|
g_conf.pad_options[m_pad_id].mouse_r = m_cb_mouse_Rjoy->GetValue();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************/
|
/****************************************/
|
||||||
|
@ -165,43 +165,43 @@ void JoystickConfiguration::OnCheckboxChange(wxCommandEvent &event)
|
||||||
// Reset checkbox and slider values
|
// Reset checkbox and slider values
|
||||||
void JoystickConfiguration::reset()
|
void JoystickConfiguration::reset()
|
||||||
{
|
{
|
||||||
if (m_isForLeftJoystick)
|
if (m_isForLeftJoystick)
|
||||||
{
|
{
|
||||||
m_cb_reverse_Lx->SetValue(m_init_reverse_Lx);
|
m_cb_reverse_Lx->SetValue(m_init_reverse_Lx);
|
||||||
m_cb_reverse_Ly->SetValue(m_init_reverse_Ly);
|
m_cb_reverse_Ly->SetValue(m_init_reverse_Ly);
|
||||||
m_cb_mouse_Ljoy->SetValue(m_init_mouse_Ljoy);
|
m_cb_mouse_Ljoy->SetValue(m_init_mouse_Ljoy);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_cb_reverse_Rx->SetValue(m_init_reverse_Rx);
|
m_cb_reverse_Rx->SetValue(m_init_reverse_Rx);
|
||||||
m_cb_reverse_Ry->SetValue(m_init_reverse_Ry);
|
m_cb_reverse_Ry->SetValue(m_init_reverse_Ry);
|
||||||
m_cb_mouse_Rjoy->SetValue(m_init_mouse_Rjoy);
|
m_cb_mouse_Rjoy->SetValue(m_init_mouse_Rjoy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set button values
|
// Set button values
|
||||||
void JoystickConfiguration::repopulate()
|
void JoystickConfiguration::repopulate()
|
||||||
{
|
{
|
||||||
if (m_isForLeftJoystick)
|
if (m_isForLeftJoystick)
|
||||||
{
|
{
|
||||||
m_init_reverse_Lx = g_conf.pad_options[m_pad_id].reverse_lx;
|
m_init_reverse_Lx = g_conf.pad_options[m_pad_id].reverse_lx;
|
||||||
m_cb_reverse_Lx->SetValue(m_init_reverse_Lx);
|
m_cb_reverse_Lx->SetValue(m_init_reverse_Lx);
|
||||||
|
|
||||||
m_init_reverse_Ly = g_conf.pad_options[m_pad_id].reverse_ly;
|
m_init_reverse_Ly = g_conf.pad_options[m_pad_id].reverse_ly;
|
||||||
m_cb_reverse_Ly->SetValue(m_init_reverse_Ly);
|
m_cb_reverse_Ly->SetValue(m_init_reverse_Ly);
|
||||||
|
|
||||||
m_init_mouse_Ljoy = g_conf.pad_options[m_pad_id].mouse_l;
|
m_init_mouse_Ljoy = g_conf.pad_options[m_pad_id].mouse_l;
|
||||||
m_cb_mouse_Ljoy->SetValue(m_init_mouse_Ljoy);
|
m_cb_mouse_Ljoy->SetValue(m_init_mouse_Ljoy);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_init_reverse_Rx = g_conf.pad_options[m_pad_id].reverse_rx;
|
m_init_reverse_Rx = g_conf.pad_options[m_pad_id].reverse_rx;
|
||||||
m_cb_reverse_Rx->SetValue(m_init_reverse_Rx);
|
m_cb_reverse_Rx->SetValue(m_init_reverse_Rx);
|
||||||
|
|
||||||
m_init_reverse_Ry = g_conf.pad_options[m_pad_id].reverse_ry;
|
m_init_reverse_Ry = g_conf.pad_options[m_pad_id].reverse_ry;
|
||||||
m_cb_reverse_Ry->SetValue(m_init_reverse_Ry);
|
m_cb_reverse_Ry->SetValue(m_init_reverse_Ry);
|
||||||
|
|
||||||
m_init_mouse_Rjoy = g_conf.pad_options[m_pad_id].mouse_r;
|
m_init_mouse_Rjoy = g_conf.pad_options[m_pad_id].mouse_r;
|
||||||
m_cb_mouse_Rjoy->SetValue(m_init_mouse_Rjoy);
|
m_cb_mouse_Rjoy->SetValue(m_init_mouse_Rjoy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,27 +34,27 @@ static const s32 Rjoy_check_id = wxID_HIGHEST + 100 + 6;
|
||||||
|
|
||||||
class JoystickConfiguration : public wxDialog
|
class JoystickConfiguration : public wxDialog
|
||||||
{
|
{
|
||||||
wxCheckBox *m_cb_reverse_Lx, *m_cb_reverse_Ly, *m_cb_reverse_Rx, *m_cb_reverse_Ry,
|
wxCheckBox *m_cb_reverse_Lx, *m_cb_reverse_Ly, *m_cb_reverse_Rx, *m_cb_reverse_Ry,
|
||||||
*m_cb_mouse_Ljoy, // Use mouse for left joystick
|
*m_cb_mouse_Ljoy, // Use mouse for left joystick
|
||||||
*m_cb_mouse_Rjoy; // Use mouse for right joystick
|
*m_cb_mouse_Rjoy; // Use mouse for right joystick
|
||||||
|
|
||||||
u32 m_pad_id;
|
u32 m_pad_id;
|
||||||
// isForLeftJoystick -> true is for Left Joystick, false is for Right Joystick
|
// isForLeftJoystick -> true is for Left Joystick, false is for Right Joystick
|
||||||
bool m_init_reverse_Lx, m_init_reverse_Ly, m_init_reverse_Rx, m_init_reverse_Ry,
|
bool m_init_reverse_Lx, m_init_reverse_Ly, m_init_reverse_Rx, m_init_reverse_Ry,
|
||||||
m_init_mouse_Ljoy, m_init_mouse_Rjoy, m_isForLeftJoystick;
|
m_init_mouse_Ljoy, m_init_mouse_Rjoy, m_isForLeftJoystick;
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
void repopulate();
|
void repopulate();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
void OnCheckboxChange(wxCommandEvent &);
|
void OnCheckboxChange(wxCommandEvent&);
|
||||||
void OnOk(wxCommandEvent &);
|
void OnOk(wxCommandEvent&);
|
||||||
void OnCancel(wxCommandEvent &);
|
void OnCancel(wxCommandEvent&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JoystickConfiguration(int, bool, wxWindow *);
|
JoystickConfiguration(int, bool, wxWindow*);
|
||||||
void InitJoystickConfiguration();
|
void InitJoystickConfiguration();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __JOYSTICKCONFIGURATION_H__
|
#endif // __JOYSTICKCONFIGURATION_H__
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -43,15 +43,16 @@
|
||||||
// e.g L2 → 0, triangle → 4, ...
|
// e.g L2 → 0, triangle → 4, ...
|
||||||
// see PAD.h for more details about gamepad button id
|
// see PAD.h for more details about gamepad button id
|
||||||
|
|
||||||
enum gui_buttons {
|
enum gui_buttons
|
||||||
Analog = PAD_R_LEFT + 1, // Analog button (not yet supported ?)
|
{
|
||||||
JoyL_config, // Left Joystick Configuration
|
Analog = PAD_R_LEFT + 1, // Analog button (not yet supported ?)
|
||||||
JoyR_config, // Right Joystick Configuration
|
JoyL_config, // Left Joystick Configuration
|
||||||
Gamepad_config, // Gamepad Configuration
|
JoyR_config, // Right Joystick Configuration
|
||||||
Set_all, // Set all buttons
|
Gamepad_config, // Gamepad Configuration
|
||||||
Apply, // Apply modifications without exit
|
Set_all, // Set all buttons
|
||||||
Ok, // Apply modifications and exit
|
Apply, // Apply modifications without exit
|
||||||
Cancel // Exit without apply modificatons
|
Ok, // Apply modifications and exit
|
||||||
|
Cancel // Exit without apply modificatons
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BUTTONS_LENGHT 32 // numbers of buttons on the gamepad
|
#define BUTTONS_LENGHT 32 // numbers of buttons on the gamepad
|
||||||
|
@ -61,32 +62,32 @@ enum gui_buttons {
|
||||||
|
|
||||||
class PADDialog : public wxDialog
|
class PADDialog : public wxDialog
|
||||||
{
|
{
|
||||||
// Panels
|
// Panels
|
||||||
opPanel *m_pan_tabs[GAMEPAD_NUMBER]; // Gamepad Tabs box
|
opPanel* m_pan_tabs[GAMEPAD_NUMBER]; // Gamepad Tabs box
|
||||||
// Notebooks
|
// Notebooks
|
||||||
wxNotebook *m_tab_gamepad; // Joysticks Tabs
|
wxNotebook* m_tab_gamepad; // Joysticks Tabs
|
||||||
// Buttons
|
// Buttons
|
||||||
wxButton *m_bt_gamepad[GAMEPAD_NUMBER][BUTTONS_LENGHT]; // Joystick button use to modify the button mapping
|
wxButton* m_bt_gamepad[GAMEPAD_NUMBER][BUTTONS_LENGHT]; // Joystick button use to modify the button mapping
|
||||||
// Contain all simulated key
|
// Contain all simulated key
|
||||||
u32 m_simulatedKeys[GAMEPAD_NUMBER][MAX_KEYS];
|
u32 m_simulatedKeys[GAMEPAD_NUMBER][MAX_KEYS];
|
||||||
// Timer
|
// Timer
|
||||||
wxTimer m_time_update_gui;
|
wxTimer m_time_update_gui;
|
||||||
// Check if the gui must display feddback image
|
// Check if the gui must display feddback image
|
||||||
bool m_pressed[GAMEPAD_NUMBER][NB_IMG];
|
bool m_pressed[GAMEPAD_NUMBER][NB_IMG];
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
void config_key(int, int);
|
void config_key(int, int);
|
||||||
void clear_key(int, int);
|
void clear_key(int, int);
|
||||||
void repopulate();
|
void repopulate();
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
void OnButtonClicked(wxCommandEvent &);
|
void OnButtonClicked(wxCommandEvent&);
|
||||||
void JoystickEvent(wxTimerEvent &);
|
void JoystickEvent(wxTimerEvent&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PADDialog();
|
PADDialog();
|
||||||
void InitDialog();
|
void InitDialog();
|
||||||
void show();
|
void show();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void DisplayDialog(); // Main function
|
extern void DisplayDialog(); // Main function
|
||||||
|
|
|
@ -38,196 +38,206 @@
|
||||||
#include "ImgHeader/arrow_bottom.h"
|
#include "ImgHeader/arrow_bottom.h"
|
||||||
#include "ImgHeader/arrow_left.h"
|
#include "ImgHeader/arrow_left.h"
|
||||||
|
|
||||||
opPanel::opPanel(wxWindow *parent,
|
opPanel::opPanel(wxWindow* parent,
|
||||||
wxWindowID id = wxID_ANY,
|
wxWindowID id = wxID_ANY,
|
||||||
const wxPoint &pos = wxDefaultPosition,
|
const wxPoint& pos = wxDefaultPosition,
|
||||||
const wxSize &size = wxDefaultSize)
|
const wxSize& size = wxDefaultSize)
|
||||||
: wxPanel(parent, id, pos, size)
|
: wxPanel(parent, id, pos, size)
|
||||||
{
|
{
|
||||||
m_picture[img_background] = EmbeddedImage<res_dualshock2>().Get();
|
m_picture[img_background] = EmbeddedImage<res_dualshock2>().Get();
|
||||||
|
|
||||||
m_picture[img_start] = EmbeddedImage<res_start>().Get();
|
m_picture[img_start] = EmbeddedImage<res_start>().Get();
|
||||||
m_picture[img_select] = EmbeddedImage<res_select>().Get();
|
m_picture[img_select] = EmbeddedImage<res_select>().Get();
|
||||||
m_picture[img_analog] = EmbeddedImage<res_analog>().Get();
|
m_picture[img_analog] = EmbeddedImage<res_analog>().Get();
|
||||||
|
|
||||||
m_picture[img_dp_left] = EmbeddedImage<res_dp_left>().Get();
|
m_picture[img_dp_left] = EmbeddedImage<res_dp_left>().Get();
|
||||||
m_picture[img_dp_right] = EmbeddedImage<res_dp_right>().Get();
|
m_picture[img_dp_right] = EmbeddedImage<res_dp_right>().Get();
|
||||||
m_picture[img_dp_up] = EmbeddedImage<res_dp_up>().Get();
|
m_picture[img_dp_up] = EmbeddedImage<res_dp_up>().Get();
|
||||||
m_picture[img_dp_bottom] = EmbeddedImage<res_dp_bottom>().Get();
|
m_picture[img_dp_bottom] = EmbeddedImage<res_dp_bottom>().Get();
|
||||||
|
|
||||||
m_picture[img_square] = EmbeddedImage<res_square>().Get();
|
m_picture[img_square] = EmbeddedImage<res_square>().Get();
|
||||||
m_picture[img_circle] = EmbeddedImage<res_circle>().Get();
|
m_picture[img_circle] = EmbeddedImage<res_circle>().Get();
|
||||||
m_picture[img_cross] = EmbeddedImage<res_cross>().Get();
|
m_picture[img_cross] = EmbeddedImage<res_cross>().Get();
|
||||||
m_picture[img_triangle] = EmbeddedImage<res_triangle>().Get();
|
m_picture[img_triangle] = EmbeddedImage<res_triangle>().Get();
|
||||||
|
|
||||||
m_picture[img_l1] = EmbeddedImage<res_l1>().Get();
|
m_picture[img_l1] = EmbeddedImage<res_l1>().Get();
|
||||||
m_picture[img_l3] = EmbeddedImage<res_l3>().Get();
|
m_picture[img_l3] = EmbeddedImage<res_l3>().Get();
|
||||||
m_picture[img_l2] = EmbeddedImage<res_l2>().Get();
|
m_picture[img_l2] = EmbeddedImage<res_l2>().Get();
|
||||||
|
|
||||||
m_picture[img_r1] = EmbeddedImage<res_r1>().Get();
|
m_picture[img_r1] = EmbeddedImage<res_r1>().Get();
|
||||||
m_picture[img_r3] = EmbeddedImage<res_r3>().Get();
|
m_picture[img_r3] = EmbeddedImage<res_r3>().Get();
|
||||||
m_picture[img_r2] = EmbeddedImage<res_r2>().Get();
|
m_picture[img_r2] = EmbeddedImage<res_r2>().Get();
|
||||||
|
|
||||||
m_picture[img_left_cursor] = EmbeddedImage<res_joystick_cursor>().Get();
|
m_picture[img_left_cursor] = EmbeddedImage<res_joystick_cursor>().Get();
|
||||||
m_picture[img_right_cursor] = EmbeddedImage<res_joystick_cursor>().Get();
|
m_picture[img_right_cursor] = EmbeddedImage<res_joystick_cursor>().Get();
|
||||||
|
|
||||||
m_picture[img_l_arrow_up] = EmbeddedImage<res_arrow_up>().Get();
|
m_picture[img_l_arrow_up] = EmbeddedImage<res_arrow_up>().Get();
|
||||||
m_picture[img_l_arrow_right] = EmbeddedImage<res_arrow_right>().Get();
|
m_picture[img_l_arrow_right] = EmbeddedImage<res_arrow_right>().Get();
|
||||||
m_picture[img_l_arrow_bottom] = EmbeddedImage<res_arrow_bottom>().Get();
|
m_picture[img_l_arrow_bottom] = EmbeddedImage<res_arrow_bottom>().Get();
|
||||||
m_picture[img_l_arrow_left] = EmbeddedImage<res_arrow_left>().Get();
|
m_picture[img_l_arrow_left] = EmbeddedImage<res_arrow_left>().Get();
|
||||||
|
|
||||||
m_picture[img_r_arrow_up] = EmbeddedImage<res_arrow_up>().Get();
|
m_picture[img_r_arrow_up] = EmbeddedImage<res_arrow_up>().Get();
|
||||||
m_picture[img_r_arrow_right] = EmbeddedImage<res_arrow_right>().Get();
|
m_picture[img_r_arrow_right] = EmbeddedImage<res_arrow_right>().Get();
|
||||||
m_picture[img_r_arrow_bottom] = EmbeddedImage<res_arrow_bottom>().Get();
|
m_picture[img_r_arrow_bottom] = EmbeddedImage<res_arrow_bottom>().Get();
|
||||||
m_picture[img_r_arrow_left] = EmbeddedImage<res_arrow_left>().Get();
|
m_picture[img_r_arrow_left] = EmbeddedImage<res_arrow_left>().Get();
|
||||||
|
|
||||||
for (int i = 0; i < NB_IMG; ++i) {
|
for (int i = 0; i < NB_IMG; ++i)
|
||||||
m_show_image[i] = false;
|
{
|
||||||
HideImg(i);
|
m_show_image[i] = false;
|
||||||
}
|
HideImg(i);
|
||||||
ShowImg(img_background);
|
}
|
||||||
m_show_image[img_background] = true;
|
ShowImg(img_background);
|
||||||
|
m_show_image[img_background] = true;
|
||||||
|
|
||||||
m_left_cursor_x = 0;
|
m_left_cursor_x = 0;
|
||||||
m_left_cursor_y = 0;
|
m_left_cursor_y = 0;
|
||||||
m_right_cursor_x = 0;
|
m_right_cursor_x = 0;
|
||||||
m_right_cursor_y = 0;
|
m_right_cursor_y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void opPanel::HideImg(int id)
|
void opPanel::HideImg(int id)
|
||||||
{
|
{
|
||||||
if (id < NB_IMG) {
|
if (id < NB_IMG)
|
||||||
m_show_image[id] = false;
|
{
|
||||||
Refresh();
|
m_show_image[id] = false;
|
||||||
}
|
Refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void opPanel::ShowImg(int id)
|
void opPanel::ShowImg(int id)
|
||||||
{
|
{
|
||||||
if (id < NB_IMG) {
|
if (id < NB_IMG)
|
||||||
m_show_image[id] = true;
|
{
|
||||||
Refresh();
|
m_show_image[id] = true;
|
||||||
}
|
Refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void opPanel::MoveJoystick(int axe, int value)
|
void opPanel::MoveJoystick(int axe, int value)
|
||||||
{
|
{
|
||||||
if (axe == 0) {
|
if (axe == 0)
|
||||||
m_left_cursor_x = value * 30 / 40000;
|
{
|
||||||
} else if (axe == 1) {
|
m_left_cursor_x = value * 30 / 40000;
|
||||||
m_left_cursor_y = value * 30 / 40000;
|
}
|
||||||
} else if (axe == 2) {
|
else if (axe == 1)
|
||||||
m_right_cursor_x = value * 30 / 40000;
|
{
|
||||||
} else {
|
m_left_cursor_y = value * 30 / 40000;
|
||||||
m_right_cursor_y = value * 30 / 40000;
|
}
|
||||||
}
|
else if (axe == 2)
|
||||||
|
{
|
||||||
|
m_right_cursor_x = value * 30 / 40000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_right_cursor_y = value * 30 / 40000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxBEGIN_EVENT_TABLE(opPanel, wxPanel)
|
wxBEGIN_EVENT_TABLE(opPanel, wxPanel)
|
||||||
EVT_PAINT(opPanel::OnPaint)
|
EVT_PAINT(opPanel::OnPaint)
|
||||||
wxEND_EVENT_TABLE()
|
wxEND_EVENT_TABLE()
|
||||||
|
|
||||||
void opPanel::OnPaint(wxPaintEvent &event)
|
void opPanel::OnPaint(wxPaintEvent& event)
|
||||||
{
|
{
|
||||||
wxPaintDC dc(this);
|
wxPaintDC dc(this);
|
||||||
|
|
||||||
wxMemoryDC temp_background, temp_start, temp_select, temp_analog, temp_dp_left,
|
wxMemoryDC temp_background, temp_start, temp_select, temp_analog, temp_dp_left,
|
||||||
temp_dp_right, temp_dp_up, temp_dp_bottom, temp_l1, temp_r1, temp_L3, temp_l2_2,
|
temp_dp_right, temp_dp_up, temp_dp_bottom, temp_l1, temp_r1, temp_L3, temp_l2_2,
|
||||||
temp_R3, temp_r2_2, temp_square, temp_circle, temp_cross, temp_triangle,
|
temp_R3, temp_r2_2, temp_square, temp_circle, temp_cross, temp_triangle,
|
||||||
temp_left_cursor, temp_right_cursor, temp_l_arrow_up, temp_l_arrow_right,
|
temp_left_cursor, temp_right_cursor, temp_l_arrow_up, temp_l_arrow_right,
|
||||||
temp_l_arrow_bottom, temp_l_arrow_left, temp_r_arrow_up, temp_r_arrow_right,
|
temp_l_arrow_bottom, temp_l_arrow_left, temp_r_arrow_up, temp_r_arrow_right,
|
||||||
temp_r_arrow_bottom, temp_r_arrow_left;
|
temp_r_arrow_bottom, temp_r_arrow_left;
|
||||||
|
|
||||||
temp_background.SelectObject(m_picture[img_background]);
|
temp_background.SelectObject(m_picture[img_background]);
|
||||||
temp_start.SelectObject(m_picture[img_start]);
|
temp_start.SelectObject(m_picture[img_start]);
|
||||||
temp_select.SelectObject(m_picture[img_select]);
|
temp_select.SelectObject(m_picture[img_select]);
|
||||||
temp_analog.SelectObject(m_picture[img_analog]);
|
temp_analog.SelectObject(m_picture[img_analog]);
|
||||||
temp_dp_left.SelectObject(m_picture[img_dp_left]);
|
temp_dp_left.SelectObject(m_picture[img_dp_left]);
|
||||||
|
|
||||||
temp_dp_right.SelectObject(m_picture[img_dp_right]);
|
temp_dp_right.SelectObject(m_picture[img_dp_right]);
|
||||||
temp_dp_up.SelectObject(m_picture[img_dp_up]);
|
temp_dp_up.SelectObject(m_picture[img_dp_up]);
|
||||||
temp_dp_bottom.SelectObject(m_picture[img_dp_bottom]);
|
temp_dp_bottom.SelectObject(m_picture[img_dp_bottom]);
|
||||||
temp_l1.SelectObject(m_picture[img_l1]);
|
temp_l1.SelectObject(m_picture[img_l1]);
|
||||||
temp_r1.SelectObject(m_picture[img_r1]);
|
temp_r1.SelectObject(m_picture[img_r1]);
|
||||||
temp_L3.SelectObject(m_picture[img_l3]);
|
temp_L3.SelectObject(m_picture[img_l3]);
|
||||||
temp_l2_2.SelectObject(m_picture[img_l2]);
|
temp_l2_2.SelectObject(m_picture[img_l2]);
|
||||||
|
|
||||||
temp_R3.SelectObject(m_picture[img_r3]);
|
temp_R3.SelectObject(m_picture[img_r3]);
|
||||||
temp_r2_2.SelectObject(m_picture[img_r2]);
|
temp_r2_2.SelectObject(m_picture[img_r2]);
|
||||||
temp_square.SelectObject(m_picture[img_square]);
|
temp_square.SelectObject(m_picture[img_square]);
|
||||||
temp_circle.SelectObject(m_picture[img_circle]);
|
temp_circle.SelectObject(m_picture[img_circle]);
|
||||||
temp_cross.SelectObject(m_picture[img_cross]);
|
temp_cross.SelectObject(m_picture[img_cross]);
|
||||||
temp_triangle.SelectObject(m_picture[img_triangle]);
|
temp_triangle.SelectObject(m_picture[img_triangle]);
|
||||||
|
|
||||||
temp_left_cursor.SelectObject(m_picture[img_left_cursor]);
|
temp_left_cursor.SelectObject(m_picture[img_left_cursor]);
|
||||||
temp_right_cursor.SelectObject(m_picture[img_right_cursor]);
|
temp_right_cursor.SelectObject(m_picture[img_right_cursor]);
|
||||||
|
|
||||||
temp_l_arrow_up.SelectObject(m_picture[img_l_arrow_up]);
|
temp_l_arrow_up.SelectObject(m_picture[img_l_arrow_up]);
|
||||||
temp_l_arrow_right.SelectObject(m_picture[img_l_arrow_right]);
|
temp_l_arrow_right.SelectObject(m_picture[img_l_arrow_right]);
|
||||||
temp_l_arrow_bottom.SelectObject(m_picture[img_l_arrow_bottom]);
|
temp_l_arrow_bottom.SelectObject(m_picture[img_l_arrow_bottom]);
|
||||||
temp_l_arrow_left.SelectObject(m_picture[img_l_arrow_left]);
|
temp_l_arrow_left.SelectObject(m_picture[img_l_arrow_left]);
|
||||||
|
|
||||||
temp_r_arrow_up.SelectObject(m_picture[img_r_arrow_up]);
|
temp_r_arrow_up.SelectObject(m_picture[img_r_arrow_up]);
|
||||||
temp_r_arrow_right.SelectObject(m_picture[img_r_arrow_right]);
|
temp_r_arrow_right.SelectObject(m_picture[img_r_arrow_right]);
|
||||||
temp_r_arrow_bottom.SelectObject(m_picture[img_r_arrow_bottom]);
|
temp_r_arrow_bottom.SelectObject(m_picture[img_r_arrow_bottom]);
|
||||||
temp_r_arrow_left.SelectObject(m_picture[img_r_arrow_left]);
|
temp_r_arrow_left.SelectObject(m_picture[img_r_arrow_left]);
|
||||||
|
|
||||||
if (m_show_image[img_background])
|
if (m_show_image[img_background])
|
||||||
dc.Blit(wxPoint(0, 0), temp_background.GetSize(), &temp_background, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(0, 0), temp_background.GetSize(), &temp_background, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_start])
|
if (m_show_image[img_start])
|
||||||
dc.Blit(wxPoint(526, 296), temp_start.GetSize(), &temp_start, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(526, 296), temp_start.GetSize(), &temp_start, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_select])
|
if (m_show_image[img_select])
|
||||||
dc.Blit(wxPoint(450, 297), temp_select.GetSize(), &temp_select, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(450, 297), temp_select.GetSize(), &temp_select, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_analog])
|
if (m_show_image[img_analog])
|
||||||
dc.Blit(wxPoint(489, 358), temp_analog.GetSize(), &temp_analog, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(489, 358), temp_analog.GetSize(), &temp_analog, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_dp_left])
|
if (m_show_image[img_dp_left])
|
||||||
dc.Blit(wxPoint(334, 292), temp_dp_left.GetSize(), &temp_dp_left, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(334, 292), temp_dp_left.GetSize(), &temp_dp_left, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_dp_right])
|
if (m_show_image[img_dp_right])
|
||||||
dc.Blit(wxPoint(378, 292), temp_dp_right.GetSize(), &temp_dp_right, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(378, 292), temp_dp_right.GetSize(), &temp_dp_right, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_dp_up])
|
if (m_show_image[img_dp_up])
|
||||||
dc.Blit(wxPoint(358, 269), temp_dp_up.GetSize(), &temp_dp_up, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(358, 269), temp_dp_up.GetSize(), &temp_dp_up, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_dp_bottom])
|
if (m_show_image[img_dp_bottom])
|
||||||
dc.Blit(wxPoint(358, 312), temp_dp_bottom.GetSize(), &temp_dp_bottom, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(358, 312), temp_dp_bottom.GetSize(), &temp_dp_bottom, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_l1])
|
if (m_show_image[img_l1])
|
||||||
dc.Blit(wxPoint(343, 186), temp_l1.GetSize(), &temp_l1, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(343, 186), temp_l1.GetSize(), &temp_l1, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_r1])
|
if (m_show_image[img_r1])
|
||||||
dc.Blit(wxPoint(593, 186), temp_r1.GetSize(), &temp_r1, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(593, 186), temp_r1.GetSize(), &temp_r1, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_l3])
|
if (m_show_image[img_l3])
|
||||||
dc.Blit(wxPoint(409, 344), temp_L3.GetSize(), &temp_L3, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(409, 344), temp_L3.GetSize(), &temp_L3, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_l2])
|
if (m_show_image[img_l2])
|
||||||
dc.Blit(wxPoint(346, 158), temp_l2_2.GetSize(), &temp_l2_2, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(346, 158), temp_l2_2.GetSize(), &temp_l2_2, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_r3])
|
if (m_show_image[img_r3])
|
||||||
dc.Blit(wxPoint(525, 344), temp_R3.GetSize(), &temp_R3, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(525, 344), temp_R3.GetSize(), &temp_R3, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_r2])
|
if (m_show_image[img_r2])
|
||||||
dc.Blit(wxPoint(582, 158), temp_r2_2.GetSize(), &temp_r2_2, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(582, 158), temp_r2_2.GetSize(), &temp_r2_2, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_square])
|
if (m_show_image[img_square])
|
||||||
dc.Blit(wxPoint(573, 287), temp_square.GetSize(), &temp_square, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(573, 287), temp_square.GetSize(), &temp_square, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_circle])
|
if (m_show_image[img_circle])
|
||||||
dc.Blit(wxPoint(647, 287), temp_circle.GetSize(), &temp_circle, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(647, 287), temp_circle.GetSize(), &temp_circle, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_cross])
|
if (m_show_image[img_cross])
|
||||||
dc.Blit(wxPoint(610, 324), temp_cross.GetSize(), &temp_cross, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(610, 324), temp_cross.GetSize(), &temp_cross, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_triangle])
|
if (m_show_image[img_triangle])
|
||||||
dc.Blit(wxPoint(610, 250), temp_triangle.GetSize(), &temp_triangle, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(610, 250), temp_triangle.GetSize(), &temp_triangle, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_left_cursor])
|
if (m_show_image[img_left_cursor])
|
||||||
dc.Blit(wxPoint(439 + m_left_cursor_x, 374 + m_left_cursor_y), temp_left_cursor.GetSize(), &temp_left_cursor, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(439 + m_left_cursor_x, 374 + m_left_cursor_y), temp_left_cursor.GetSize(), &temp_left_cursor, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_right_cursor])
|
if (m_show_image[img_right_cursor])
|
||||||
dc.Blit(wxPoint(555 + m_right_cursor_x, 374 + m_right_cursor_y), temp_right_cursor.GetSize(), &temp_right_cursor, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(555 + m_right_cursor_x, 374 + m_right_cursor_y), temp_right_cursor.GetSize(), &temp_right_cursor, wxPoint(0, 0), wxCOPY, true);
|
||||||
|
|
||||||
if (m_show_image[img_l_arrow_up])
|
if (m_show_image[img_l_arrow_up])
|
||||||
dc.Blit(wxPoint(433, 357), temp_l_arrow_up.GetSize(), &temp_l_arrow_up, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(433, 357), temp_l_arrow_up.GetSize(), &temp_l_arrow_up, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_l_arrow_right])
|
if (m_show_image[img_l_arrow_right])
|
||||||
dc.Blit(wxPoint(423, 368), temp_l_arrow_right.GetSize(), &temp_l_arrow_right, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(423, 368), temp_l_arrow_right.GetSize(), &temp_l_arrow_right, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_l_arrow_bottom])
|
if (m_show_image[img_l_arrow_bottom])
|
||||||
dc.Blit(wxPoint(433, 357), temp_l_arrow_bottom.GetSize(), &temp_l_arrow_bottom, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(433, 357), temp_l_arrow_bottom.GetSize(), &temp_l_arrow_bottom, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_l_arrow_left])
|
if (m_show_image[img_l_arrow_left])
|
||||||
dc.Blit(wxPoint(423, 368), temp_l_arrow_left.GetSize(), &temp_l_arrow_left, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(423, 368), temp_l_arrow_left.GetSize(), &temp_l_arrow_left, wxPoint(0, 0), wxCOPY, true);
|
||||||
|
|
||||||
if (m_show_image[img_r_arrow_up])
|
if (m_show_image[img_r_arrow_up])
|
||||||
dc.Blit(wxPoint(548, 357), temp_r_arrow_up.GetSize(), &temp_r_arrow_up, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(548, 357), temp_r_arrow_up.GetSize(), &temp_r_arrow_up, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_r_arrow_right])
|
if (m_show_image[img_r_arrow_right])
|
||||||
dc.Blit(wxPoint(539, 368), temp_r_arrow_right.GetSize(), &temp_r_arrow_right, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(539, 368), temp_r_arrow_right.GetSize(), &temp_r_arrow_right, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_r_arrow_bottom])
|
if (m_show_image[img_r_arrow_bottom])
|
||||||
dc.Blit(wxPoint(548, 357), temp_r_arrow_bottom.GetSize(), &temp_r_arrow_bottom, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(548, 357), temp_r_arrow_bottom.GetSize(), &temp_r_arrow_bottom, wxPoint(0, 0), wxCOPY, true);
|
||||||
if (m_show_image[img_r_arrow_left])
|
if (m_show_image[img_r_arrow_left])
|
||||||
dc.Blit(wxPoint(539, 368), temp_r_arrow_left.GetSize(), &temp_r_arrow_left, wxPoint(0, 0), wxCOPY, true);
|
dc.Blit(wxPoint(539, 368), temp_r_arrow_left.GetSize(), &temp_r_arrow_left, wxPoint(0, 0), wxCOPY, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,52 +22,53 @@
|
||||||
|
|
||||||
#include "EmbeddedImage.h"
|
#include "EmbeddedImage.h"
|
||||||
|
|
||||||
enum gui_img {
|
enum gui_img
|
||||||
img_l2,
|
{
|
||||||
img_r2,
|
img_l2,
|
||||||
img_l1,
|
img_r2,
|
||||||
img_r1,
|
img_l1,
|
||||||
img_triangle,
|
img_r1,
|
||||||
img_circle,
|
img_triangle,
|
||||||
img_cross,
|
img_circle,
|
||||||
img_square,
|
img_cross,
|
||||||
img_select,
|
img_square,
|
||||||
img_l3,
|
img_select,
|
||||||
img_r3,
|
img_l3,
|
||||||
img_start,
|
img_r3,
|
||||||
img_dp_up,
|
img_start,
|
||||||
img_dp_right,
|
img_dp_up,
|
||||||
img_dp_bottom,
|
img_dp_right,
|
||||||
img_dp_left,
|
img_dp_bottom,
|
||||||
img_left_cursor,
|
img_dp_left,
|
||||||
img_right_cursor,
|
img_left_cursor,
|
||||||
img_analog,
|
img_right_cursor,
|
||||||
img_background, // background pic
|
img_analog,
|
||||||
img_l_arrow_up,
|
img_background, // background pic
|
||||||
img_l_arrow_right,
|
img_l_arrow_up,
|
||||||
img_l_arrow_bottom,
|
img_l_arrow_right,
|
||||||
img_l_arrow_left,
|
img_l_arrow_bottom,
|
||||||
img_r_arrow_up,
|
img_l_arrow_left,
|
||||||
img_r_arrow_right,
|
img_r_arrow_up,
|
||||||
img_r_arrow_bottom,
|
img_r_arrow_right,
|
||||||
img_r_arrow_left
|
img_r_arrow_bottom,
|
||||||
|
img_r_arrow_left
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NB_IMG 28
|
#define NB_IMG 28
|
||||||
|
|
||||||
class opPanel : public wxPanel
|
class opPanel : public wxPanel
|
||||||
{
|
{
|
||||||
wxBitmap m_picture[NB_IMG];
|
wxBitmap m_picture[NB_IMG];
|
||||||
bool m_show_image[NB_IMG];
|
bool m_show_image[NB_IMG];
|
||||||
int m_left_cursor_x, m_left_cursor_y, m_right_cursor_x, m_right_cursor_y;
|
int m_left_cursor_x, m_left_cursor_y, m_right_cursor_x, m_right_cursor_y;
|
||||||
wxDECLARE_EVENT_TABLE();
|
wxDECLARE_EVENT_TABLE();
|
||||||
void OnPaint(wxPaintEvent &event);
|
void OnPaint(wxPaintEvent& event);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
opPanel(wxWindow *, wxWindowID, const wxPoint &, const wxSize &);
|
opPanel(wxWindow*, wxWindowID, const wxPoint&, const wxSize&);
|
||||||
void HideImg(int);
|
void HideImg(int);
|
||||||
void ShowImg(int);
|
void ShowImg(int);
|
||||||
void MoveJoystick(int, int);
|
void MoveJoystick(int, int);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __OPPANEL_H__
|
#endif // __OPPANEL_H__
|
||||||
|
|
Loading…
Reference in New Issue