PAD: clang-format

This commit is contained in:
Gauvain 'GovanifY' Roussel-Tarbouriech 2020-12-11 04:26:46 +01:00 committed by lightningterror
parent 2e0be1f75a
commit 82f7a23be4
27 changed files with 19520 additions and 19192 deletions

View File

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

View File

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

View File

@ -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);
} }

View File

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

View File

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

View File

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

View File

@ -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();
} }

View File

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

View File

@ -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));
} }

View File

@ -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));
} }

View File

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

View File

@ -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);
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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());
} }

View File

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

View File

@ -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);
} }
} }

View File

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

View File

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

View File

@ -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);
} }

View File

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