Fix crazy svn changing trunk on last commit

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2206 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
nakeee 2009-02-10 14:02:01 +00:00
parent 49937a640b
commit 4d57101e29
15 changed files with 594 additions and 856 deletions

View File

@ -590,6 +590,7 @@
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="true" SuppressStartupBanner="true"
GenerateManifest="false" GenerateManifest="false"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb" ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
RandomizedBaseAddress="1" RandomizedBaseAddress="1"
DataExecutionPrevention="0" DataExecutionPrevention="0"

View File

@ -30,11 +30,17 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
EVT_CLOSE(ConfigDialog::OnClose) EVT_CLOSE(ConfigDialog::OnClose)
EVT_BUTTON(ID_CLOSE,ConfigDialog::OnCloseClick) EVT_BUTTON(ID_CLOSE,ConfigDialog::OnCloseClick)
EVT_BUTTON(ID_PAD_ABOUT,ConfigDialog::DllAbout) EVT_BUTTON(ID_PAD_ABOUT,ConfigDialog::DllAbout)
EVT_CHECKBOX(ID_ATTACHED,ConfigDialog::ControllerSettingsChanged) EVT_CHECKBOX(ID_ATTACHED,ConfigDialog::ControllerSettingsChanged)
EVT_CHECKBOX(ID_X360PAD,ConfigDialog::ControllerSettingsChanged) EVT_CHECKBOX(ID_X360PAD,ConfigDialog::ControllerSettingsChanged)
EVT_CHOICE(ID_X360PAD_CHOICE,ConfigDialog::ControllerSettingsChanged) EVT_CHOICE(ID_X360PAD_CHOICE,ConfigDialog::ControllerSettingsChanged)
EVT_CHECKBOX(ID_RUMBLE,ConfigDialog::ControllerSettingsChanged) EVT_CHECKBOX(ID_RUMBLE,ConfigDialog::ControllerSettingsChanged)
EVT_CHECKBOX(ID_DISABLE,ConfigDialog::ControllerSettingsChanged) EVT_CHECKBOX(ID_DISABLE,ConfigDialog::ControllerSettingsChanged)
//Recording
EVT_CHECKBOX(ID_RECORDING,ConfigDialog::ControllerSettingsChanged)
EVT_CHECKBOX(ID_PLAYBACK,ConfigDialog::ControllerSettingsChanged)
EVT_BUTTON(ID_SAVE_RECORDING,ConfigDialog::ControllerSettingsChanged)
EVT_BUTTON(CTL_A,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_A,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_B,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_B,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_X,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_X,ConfigDialog::OnButtonClick)
@ -145,18 +151,62 @@ void ConfigDialog::CreateGUIControls()
#endif #endif
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
{ {
sbDevice[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Controller Settings")); // --------------------------------------------------------------------
// Settings
// -----------------------------
// Main horizontal container
sDevice[i] = new wxBoxSizer(wxHORIZONTAL); sDevice[i] = new wxBoxSizer(wxHORIZONTAL);
sbDevice[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Controller Settings"));
m_Attached[i] = new wxCheckBox(m_Controller[i], ID_ATTACHED, wxT("Controller attached"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_Attached[i] = new wxCheckBox(m_Controller[i], ID_ATTACHED, wxT("Controller attached"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_Disable[i] = new wxCheckBox(m_Controller[i], ID_DISABLE, wxT("Disable when Dolphin is not in focus"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
sbDevice[i]->Add(m_Attached[i], 0, wxEXPAND|wxALL, 1);
sbDevice[i]->Add(m_Disable[i], 0, wxEXPAND|wxALL, 1);
#ifdef _WIN32 #ifdef _WIN32
m_SizeXInput[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("XInput Pad"));
m_X360Pad[i] = new wxCheckBox(m_Controller[i], ID_X360PAD, wxT("Enable X360Pad"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_X360Pad[i] = new wxCheckBox(m_Controller[i], ID_X360PAD, wxT("Enable X360Pad"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_X360PadC[i] = new wxChoice(m_Controller[i], ID_X360PAD_CHOICE, wxDefaultPosition, wxDefaultSize, arrayStringFor_X360Pad, 0, wxDefaultValidator); m_X360PadC[i] = new wxChoice(m_Controller[i], ID_X360PAD_CHOICE, wxDefaultPosition, wxDefaultSize, arrayStringFor_X360Pad, 0, wxDefaultValidator);
m_Rumble[i] = new wxCheckBox(m_Controller[i], ID_RUMBLE, wxT("Enable rumble"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_Rumble[i] = new wxCheckBox(m_Controller[i], ID_RUMBLE, wxT("Enable rumble"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_SizeXInput[i]->Add(m_X360Pad[i], 0, wxEXPAND | wxALL, 1);
m_SizeXInput[i]->Add(m_X360PadC[i], 0, wxEXPAND | wxALL, 1);
m_SizeXInput[i]->Add(m_Rumble[i], 0, wxEXPAND | wxALL, 1);
#endif #endif
m_Disable[i] = new wxCheckBox(m_Controller[i], ID_DISABLE, wxT("Disable when Dolphin is not in focus"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_SizeRecording[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Input Recording"));
m_CheckRecording[i] = new wxCheckBox(m_Controller[i], ID_RECORDING, wxT("Record input"));
m_CheckPlayback[i] = new wxCheckBox(m_Controller[i], ID_PLAYBACK, wxT("Play back input"));
m_BtnSaveRecording[i] = new wxButton(m_Controller[i], ID_SAVE_RECORDING, wxT("Save recording"), wxDefaultPosition, wxDefaultSize);
// Tool tips
m_CheckRecording[i]->SetToolTip(wxT("Your recording will be saved to pad-record.bin in the Dolphin dir when you stop the game"));
m_CheckPlayback[i]->SetToolTip(wxT("Play back the pad-record.bin file from the Dolphin dir"));
m_BtnSaveRecording[i]->SetToolTip(wxT(
"This will save the current recording to pad-record.bin. Your recording will\n"
"also be automatically saved every 60 * 10 frames. And when you shut down the\n"
"game."));
m_SizeRecording[i]->Add(m_CheckRecording[i], 0, wxEXPAND | wxALL, 1);
m_SizeRecording[i]->Add(m_CheckPlayback[i], 0, wxEXPAND | wxALL, 1);
m_SizeRecording[i]->Add(m_BtnSaveRecording[i], 0, wxEXPAND | wxALL, 1);
// Set values
m_Attached[i]->SetValue(pad[i].bAttached); m_Attached[i]->SetValue(pad[i].bAttached);
m_Disable[i]->SetValue(pad[i].bDisable);
m_CheckRecording[i]->SetValue(pad[i].bRecording);
m_CheckPlayback[i]->SetValue(pad[i].bPlayback);
// Only enable these options for pad 0
m_CheckRecording[i]->Enable(false); m_CheckRecording[0]->Enable(true);
m_CheckPlayback[i]->Enable(false); m_CheckPlayback[0]->Enable(true);
m_BtnSaveRecording[i]->Enable(false); m_BtnSaveRecording[0]->Enable(true);
// Don't allow saving when we are not recording
m_BtnSaveRecording[i]->Enable(g_EmulatorRunning && pad[0].bRecording);
#ifdef _WIN32 #ifdef _WIN32
// Check if any XInput pad was found
if (arrayStringFor_X360Pad.IsEmpty()) if (arrayStringFor_X360Pad.IsEmpty())
{ {
m_X360Pad[i]->SetLabel(wxT("Enable X360Pad - No pad connected")); m_X360Pad[i]->SetLabel(wxT("Enable X360Pad - No pad connected"));
@ -175,19 +225,21 @@ void ConfigDialog::CreateGUIControls()
m_Rumble[i]->Enable(m_X360Pad[i]->IsChecked()); m_Rumble[i]->Enable(m_X360Pad[i]->IsChecked());
} }
#endif #endif
m_Disable[i]->SetValue(pad[i].bDisable);
// Sizers
sDevice[i]->Add(m_Attached[i], 0, wxEXPAND|wxALL, 1); sDevice[i]->Add(sbDevice[i], 0, wxEXPAND | wxALL, 1);
sDevice[i]->AddStretchSpacer(); //sDevice[i]->AddStretchSpacer();
#ifdef _WIN32 #ifdef _WIN32
sDevice[i]->Add(m_X360Pad[i], 0, wxEXPAND|wxALL, 1); sDevice[i]->Add(m_SizeXInput[i], 0, wxEXPAND | wxALL, 1);
sDevice[i]->Add(m_X360PadC[i], 0, wxEXPAND|wxALL, 1); sDevice[i]->Add(m_SizeRecording[i], 0, wxEXPAND | wxALL, 1);
sDevice[i]->Add(m_Rumble[i], 0, wxEXPAND|wxALL, 1);
sDevice[i]->AddStretchSpacer();
#endif #endif
sDevice[i]->Add(m_Disable[i], 0, wxEXPAND|wxALL, 1); // -----------------------------------
sbDevice[i]->Add(sDevice[i], 0, wxEXPAND|wxALL, 1);
// --------------------------------------------------------------------
// Buttons
// -----------------------------
sButtons[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Buttons")); sButtons[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Buttons"));
AddControl(m_Controller[i], &(m_ButtonA[i]), sButtons[i], "A: ", CTL_A, i); AddControl(m_Controller[i], &(m_ButtonA[i]), sButtons[i], "A: ", CTL_A, i);
@ -227,10 +279,13 @@ void ConfigDialog::CreateGUIControls()
AddControl(m_Controller[i], &(m_CStickLeft[i]), sCStick[i], "Left: ", CTL_SUBLEFT, i); AddControl(m_Controller[i], &(m_CStickLeft[i]), sCStick[i], "Left: ", CTL_SUBLEFT, i);
AddControl(m_Controller[i], &(m_CStickRight[i]), sCStick[i], "Right: ", CTL_SUBRIGHT, i); AddControl(m_Controller[i], &(m_CStickRight[i]), sCStick[i], "Right: ", CTL_SUBRIGHT, i);
// --------------------------------------------------------------------
// Sizers
// -----------------------------
sPage[i] = new wxGridBagSizer(0, 0); sPage[i] = new wxGridBagSizer(0, 0);
sPage[i]->SetFlexibleDirection(wxBOTH); sPage[i]->SetFlexibleDirection(wxBOTH);
sPage[i]->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); sPage[i]->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
sPage[i]->Add(sbDevice[i], wxGBPosition(0, 0), wxGBSpan(1, 5), wxEXPAND|wxALL, 1); sPage[i]->Add(sDevice[i], wxGBPosition(0, 0), wxGBSpan(1, 5), wxEXPAND|wxALL, 1);
sPage[i]->Add(sButtons[i], wxGBPosition(1, 0), wxGBSpan(2, 1), wxALL, 1); sPage[i]->Add(sButtons[i], wxGBPosition(1, 0), wxGBSpan(2, 1), wxALL, 1);
sPage[i]->Add(sTriggers[i], wxGBPosition(1, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 1); sPage[i]->Add(sTriggers[i], wxGBPosition(1, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 1);
sPage[i]->Add(sModifiers[i], wxGBPosition(2, 1), wxGBSpan(1, 1), wxALL, 1); sPage[i]->Add(sModifiers[i], wxGBPosition(2, 1), wxGBSpan(1, 1), wxALL, 1);
@ -291,9 +346,15 @@ void ConfigDialog::ControllerSettingsChanged(wxCommandEvent& event)
switch (event.GetId()) switch (event.GetId())
{ {
// General settings
case ID_ATTACHED: case ID_ATTACHED:
pad[page].bAttached = m_Attached[page]->GetValue(); pad[page].bAttached = m_Attached[page]->GetValue();
break; break;
case ID_DISABLE:
pad[page].bDisable = m_Disable[page]->GetValue();
break;
// XInput
case ID_X360PAD: case ID_X360PAD:
pad[page].bEnableXPad = event.IsChecked(); pad[page].bEnableXPad = event.IsChecked();
m_Rumble[page]->Enable(event.IsChecked()); m_Rumble[page]->Enable(event.IsChecked());
@ -305,9 +366,22 @@ void ConfigDialog::ControllerSettingsChanged(wxCommandEvent& event)
case ID_RUMBLE: case ID_RUMBLE:
pad[page].bRumble = m_Rumble[page]->GetValue(); pad[page].bRumble = m_Rumble[page]->GetValue();
break; break;
case ID_DISABLE:
pad[page].bDisable = m_Disable[page]->GetValue(); case ID_RECORDING:
pad[page].bRecording = m_CheckRecording[page]->GetValue();
// Turn off the other option
pad[page].bPlayback = false; m_CheckPlayback[page]->SetValue(false);
break; break;
case ID_PLAYBACK:
pad[page].bPlayback = m_CheckPlayback[page]->GetValue();
// Turn off the other option
pad[page].bRecording = false; m_CheckRecording[page]->SetValue(false);
break;
case ID_SAVE_RECORDING:
// Double check again that we are still running a game
if (g_EmulatorRunning) SaveRecord();
break;
} }
} }

View File

@ -50,7 +50,7 @@ class ConfigDialog : public wxDialog
wxButton *m_About; wxButton *m_About;
wxButton *m_Close; wxButton *m_Close;
wxStaticBoxSizer *sbDevice[4]; wxStaticBoxSizer *sbDevice[4], *m_SizeXInput[4], *m_SizeRecording[4];
wxBoxSizer *sDevice[4]; wxBoxSizer *sDevice[4];
wxGridBagSizer *sPage[4]; wxGridBagSizer *sPage[4];
wxStaticBoxSizer *sButtons[4]; wxStaticBoxSizer *sButtons[4];
@ -67,6 +67,11 @@ class ConfigDialog : public wxDialog
wxCheckBox *m_Disable[4]; wxCheckBox *m_Disable[4];
wxCheckBox *m_Rumble[4]; wxCheckBox *m_Rumble[4];
// Recording
wxCheckBox *m_CheckRecording[4];
wxCheckBox *m_CheckPlayback[4];
wxButton *m_BtnSaveRecording[4];
wxButton *m_ButtonA[4]; wxButton *m_ButtonA[4];
wxButton *m_ButtonB[4]; wxButton *m_ButtonB[4];
wxButton *m_ButtonX[4]; wxButton *m_ButtonX[4];
@ -99,11 +104,19 @@ class ConfigDialog : public wxDialog
ID_CONTROLLERPAGE3, ID_CONTROLLERPAGE3,
ID_CONTROLLERPAGE4, ID_CONTROLLERPAGE4,
// XInput pad
ID_X360PAD_CHOICE, ID_X360PAD_CHOICE,
ID_X360PAD, ID_X360PAD,
ID_RUMBLE,
// Input recording
ID_RECORDING,
ID_PLAYBACK,
ID_SAVE_RECORDING,
// General settings
ID_ATTACHED, ID_ATTACHED,
ID_DISABLE, ID_DISABLE,
ID_RUMBLE,
ID_PAD_ABOUT ID_PAD_ABOUT
}; };

View File

@ -15,6 +15,10 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
@ -22,43 +26,69 @@
#include "pluginspecs_pad.h" #include "pluginspecs_pad.h"
#include "PadSimple.h" #include "PadSimple.h"
#include "IniFile.h" #include "IniFile.h"
#include "ConsoleWindow.h"
#include "StringUtil.h"
#include "ChunkFile.h"
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
#include "GUI/ConfigDlg.h" #include "GUI/ConfigDlg.h"
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
#include "XInput.h" #include "XInput.h"
#include "DirectInputBase.h" #include "DirectInputBase.h"
DInput dinput; DInput dinput;
//#elif defined(USE_SDL) && USE_SDL //#elif defined(USE_SDL) && USE_SDL
//#include <SDL.h> //#include <SDL.h>
#elif defined(HAVE_X11) && HAVE_X11 #elif defined(HAVE_X11) && HAVE_X11
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#include <X11/XKBlib.h> #include <X11/XKBlib.h>
Display* GXdsp; Display* GXdsp;
bool KeyStatus[NUMCONTROLS]; bool KeyStatus[NUMCONTROLS];
#elif defined(HAVE_COCOA) && HAVE_COCOA #elif defined(HAVE_COCOA) && HAVE_COCOA
#include <Cocoa/Cocoa.h> #include <Cocoa/Cocoa.h>
bool KeyStatus[NUMCONTROLS]; bool KeyStatus[NUMCONTROLS];
#endif #endif
////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Declarations
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
SPads pad[4]; SPads pad[4];
HINSTANCE g_hInstance; HINSTANCE g_hInstance;
SPADInitialize g_PADInitialize; SPADInitialize g_PADInitialize;
////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Input Recording
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
// Enable these to record or play back
//#define RECORD_REPLAY
//#define RECORD_STORE
// Pre defined maxium storage limit
#define RECORD_SIZE (1024 * 128) #define RECORD_SIZE (1024 * 128)
SPADStatus recordBuffer[RECORD_SIZE]; SPADStatus recordBuffer[RECORD_SIZE];
int count = 0; int count = 0;
bool g_EmulatorRunning = false;
////////////////////////////////
// TODO: fix this dirty hack to stop missing symbols
void __Log(int log, const char *format, ...) {}
void __Logv(int log, int v, const char *format, ...) {}
//****************************************************************************** //******************************************************************************
// Supporting functions // Supporting functions
@ -66,46 +96,68 @@ int count = 0;
void RecordInput(const SPADStatus& _rPADStatus) void RecordInput(const SPADStatus& _rPADStatus)
{ {
if (count >= RECORD_SIZE) if (count >= RECORD_SIZE) return;
{
return;
}
recordBuffer[count++] = _rPADStatus; recordBuffer[count++] = _rPADStatus;
}
// Logging
//u8 TmpData[sizeof(SPADStatus)];
//memcpy(TmpData, &recordBuffer[count - 1], sizeof(SPADStatus));
//Console::Print("RecordInput(%i): %s\n", count, ArrayToString(TmpData, sizeof(SPADStatus), 0, 30).c_str());
// Auto save every ten seconds
if (count % (60 * 10) == 0) SaveRecord();
}
const SPADStatus& PlayRecord() const SPADStatus& PlayRecord()
{ {
if (count >= RECORD_SIZE){return(recordBuffer[0]);} // Logging
//Console::Print("PlayRecord(%i)\n", count);
if (count >= RECORD_SIZE)
{
// Todo: Make the recording size unlimited?
//PanicAlert("The recording reached its end");
return(recordBuffer[0]);
}
return(recordBuffer[count++]); return(recordBuffer[count++]);
} }
void LoadRecord() void LoadRecord()
{ {
FILE* pStream = fopen("c:\\pad-record.bin", "rb"); FILE* pStream = fopen("pad-record.bin", "rb");
if (pStream != NULL) if (pStream != NULL)
{ {
fread(recordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream); fread(recordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream);
fclose(pStream); fclose(pStream);
} }
} else
{
PanicAlert("SimplePad: Could not open pad-record.bin");
}
//Console::Print("LoadRecord()");
}
void SaveRecord() void SaveRecord()
{ {
FILE* pStream = fopen("c:\\pad-record.bin", "wb"); // Open the file in a way that clears all old data
FILE* pStream = fopen("pad-record.bin", "wb");
if (pStream != NULL) if (pStream != NULL)
{ {
fwrite(recordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream); fwrite(recordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream);
fclose(pStream); fclose(pStream);
} }
else
{
PanicAlert("SimplePad: Could not save pad-record.bin");
}
//PanicAlert("SaveRecord()");
//Console::Print("SaveRecord()");
} }
// Check if Dolphin is in focus // Check if Dolphin is in focus
bool IsFocus() bool IsFocus()
{ {
@ -167,89 +219,6 @@ BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle
#endif #endif
//******************************************************************************
// Plugin specification functions
//******************************************************************************
void GetDllInfo(PLUGIN_INFO* _PluginInfo)
{
_PluginInfo->Version = 0x0100;
_PluginInfo->Type = PLUGIN_TYPE_PAD;
#ifdef DEBUGFAST
sprintf(_PluginInfo->Name, "Dolphin KB/X360pad (DebugFast)");
#else
#ifndef _DEBUG
sprintf(_PluginInfo->Name, "Dolphin KB/X360pad");
#else
sprintf(_PluginInfo->Name, "Dolphin KB/X360pad (Debug)");
#endif
#endif
}
void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals) {
}
void DllConfig(HWND _hParent)
{
LoadConfig();
#ifdef _WIN32
wxWindow win;
win.SetHWND(_hParent);
ConfigDialog frame(&win);
frame.ShowModal();
win.SetHWND(0);
#elif defined(HAVE_WX) && HAVE_WX
ConfigDialog frame(NULL);
frame.ShowModal();
#endif
SaveConfig();
}
void DllDebugger(HWND _hParent, bool Show) {
}
void Initialize(void *init)
{
#ifdef RECORD_REPLAY
LoadRecord();
#endif
g_PADInitialize = *(SPADInitialize*)init;
#ifdef _WIN32
dinput.Init((HWND)g_PADInitialize.hWnd);
#elif defined(HAVE_X11) && HAVE_X11
GXdsp = (Display*)g_PADInitialize.hWnd;
#elif defined(HAVE_COCOA) && HAVE_COCOA
#endif
LoadConfig();
}
void DoState(unsigned char **ptr, int mode) {
}
void Shutdown()
{
#ifdef RECORD_STORE
SaveRecord();
#endif
#ifdef _WIN32
dinput.Free();
// Kill xpad rumble
XINPUT_VIBRATION vib;
vib.wLeftMotorSpeed = 0;
vib.wRightMotorSpeed = 0;
for (int i = 0; i < 4; i++)
if (pad[i].bRumble)
XInputSetState(pad[i].XPadPlayer, &vib);
#endif
SaveConfig();
}
const float kDeadZone = 0.1f; const float kDeadZone = 0.1f;
// Implement circular deadzone // Implement circular deadzone
@ -283,6 +252,9 @@ void ScaleStickValues(unsigned char* outx,
*outy = 0x80 + iy; *outy = 0x80 + iy;
} }
//******************************************************************************
// Input
//******************************************************************************
#ifdef _WIN32 #ifdef _WIN32
void DInput_Read(int _numPAD, SPADStatus* _pPADStatus) void DInput_Read(int _numPAD, SPADStatus* _pPADStatus)
@ -334,6 +306,8 @@ void DInput_Read(int _numPAD, SPADStatus* _pPADStatus)
if (dinput.diks[pad[_numPAD].keyForControl[CTL_DPADLEFT]] & 0xFF){_pPADStatus->button |= PAD_BUTTON_LEFT;} if (dinput.diks[pad[_numPAD].keyForControl[CTL_DPADLEFT]] & 0xFF){_pPADStatus->button |= PAD_BUTTON_LEFT;}
if (dinput.diks[pad[_numPAD].keyForControl[CTL_DPADRIGHT]]& 0xFF){_pPADStatus->button |= PAD_BUTTON_RIGHT;} if (dinput.diks[pad[_numPAD].keyForControl[CTL_DPADRIGHT]]& 0xFF){_pPADStatus->button |= PAD_BUTTON_RIGHT;}
if (dinput.diks[pad[_numPAD].keyForControl[CTL_START]] & 0xFF){_pPADStatus->button |= PAD_BUTTON_START;} if (dinput.diks[pad[_numPAD].keyForControl[CTL_START]] & 0xFF){_pPADStatus->button |= PAD_BUTTON_START;}
_pPADStatus->MicButton = (dinput.diks[pad[_numPAD].keyForControl[CTL_MIC]] & 0xFF) ? true : false;
} }
bool XInput_Read(int XPadPlayer, SPADStatus* _pPADStatus) bool XInput_Read(int XPadPlayer, SPADStatus* _pPADStatus)
@ -381,6 +355,8 @@ bool XInput_Read(int XPadPlayer, SPADStatus* _pPADStatus)
if (xpad.wButtons & XINPUT_GAMEPAD_DPAD_UP) {_pPADStatus->button |= PAD_BUTTON_UP;} if (xpad.wButtons & XINPUT_GAMEPAD_DPAD_UP) {_pPADStatus->button |= PAD_BUTTON_UP;}
if (xpad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) {_pPADStatus->button |= PAD_BUTTON_DOWN;} if (xpad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) {_pPADStatus->button |= PAD_BUTTON_DOWN;}
//_pPADStatus->MicButton = (xpad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? true : false;
return true; return true;
} }
else else
@ -610,25 +586,124 @@ void cocoa_Read(int _numPAD, SPADStatus* _pPADStatus)
} }
#endif #endif
//******************************************************************************
// Plugin specification functions
//******************************************************************************
void GetDllInfo(PLUGIN_INFO* _PluginInfo)
{
_PluginInfo->Version = 0x0100;
_PluginInfo->Type = PLUGIN_TYPE_PAD;
#ifdef DEBUGFAST
sprintf(_PluginInfo->Name, "Dolphin KB/X360pad (DebugFast)");
#else
#ifndef _DEBUG
sprintf(_PluginInfo->Name, "Dolphin KB/X360pad");
#else
sprintf(_PluginInfo->Name, "Dolphin KB/X360pad (Debug)");
#endif
#endif
}
void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals) {}
void DllConfig(HWND _hParent)
{
LoadConfig();
#ifdef _WIN32
wxWindow win;
win.SetHWND(_hParent);
ConfigDialog frame(&win);
frame.ShowModal();
win.SetHWND(0);
#elif defined(HAVE_WX) && HAVE_WX
ConfigDialog frame(NULL);
frame.ShowModal();
#endif
SaveConfig();
}
void DllDebugger(HWND _hParent, bool Show) {}
void Initialize(void *init)
{
//Console::Open(70, 5000);
// We are now running a game
g_EmulatorRunning = true;
// Load configuration
LoadConfig();
// Load recorded input if we are to play it back, otherwise begin with a blank recording
if (pad[0].bPlayback) LoadRecord();
g_PADInitialize = *(SPADInitialize*)init;
#ifdef _WIN32
dinput.Init((HWND)g_PADInitialize.hWnd);
#elif defined(HAVE_X11) && HAVE_X11
GXdsp = (Display*)g_PADInitialize.hWnd;
#elif defined(HAVE_COCOA) && HAVE_COCOA
#endif
}
void DoState(unsigned char **ptr, int mode)
{
// Load or save the counter
PointerWrap p(ptr, mode);
p.Do(count);
}
void Shutdown()
{
//Console::Print("ShutDown()\n");
// Save recording
if (pad[0].bRecording) SaveRecord();
// Reset the counter
count = 0;
// We have stopped the game
g_EmulatorRunning = false;
#ifdef _WIN32
dinput.Free();
// Kill xpad rumble
XINPUT_VIBRATION vib;
vib.wLeftMotorSpeed = 0;
vib.wRightMotorSpeed = 0;
for (int i = 0; i < 4; i++)
if (pad[i].bRumble)
XInputSetState(pad[i].XPadPlayer, &vib);
#endif
SaveConfig();
}
// Set buttons status from wxWidgets in the main application // Set buttons status from wxWidgets in the main application
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void PAD_Input(u16 _Key, u8 _UpDown) { void PAD_Input(u16 _Key, u8 _UpDown) {}
}
void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
{ {
// Check if all is okay // Check if all is okay
if ((_pPADStatus == NULL)) if (_pPADStatus == NULL) return;
// Play back input instead of accepting any user input
if (pad[0].bPlayback)
{ {
*_pPADStatus = PlayRecord();
return; return;
} }
#ifdef RECORD_REPLAY
*_pPADStatus = PlayRecord();
return;
#endif
const int base = 0x80; const int base = 0x80;
// Clear pad // Clear pad
memset(_pPADStatus, 0, sizeof(SPADStatus)); memset(_pPADStatus, 0, sizeof(SPADStatus));
@ -639,15 +714,18 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
_pPADStatus->substickY = base; _pPADStatus->substickY = base;
_pPADStatus->button |= PAD_USE_ORIGIN; _pPADStatus->button |= PAD_USE_ORIGIN;
#ifdef _WIN32 #ifdef _WIN32
// Just update pad on focus // Only update pad on focus, don't do this when recording
if (pad[_numPAD].bDisable) if (pad[_numPAD].bDisable && !pad[0].bRecording && !IsFocus()) return;
{
if (!IsFocus()) return;
}
// Dolphin doesn't really care about the pad error codes anyways... // Dolphin doesn't really care about the pad error codes anyways...
_pPADStatus->err = PAD_ERR_NONE; _pPADStatus->err = PAD_ERR_NONE;
// Read XInput
if (pad[_numPAD].bEnableXPad) XInput_Read(pad[_numPAD].XPadPlayer, _pPADStatus); if (pad[_numPAD].bEnableXPad) XInput_Read(pad[_numPAD].XPadPlayer, _pPADStatus);
// Read Direct Input
DInput_Read(_numPAD, _pPADStatus); DInput_Read(_numPAD, _pPADStatus);
#elif defined(HAVE_X11) && HAVE_X11 #elif defined(HAVE_X11) && HAVE_X11
_pPADStatus->err = PAD_ERR_NONE; _pPADStatus->err = PAD_ERR_NONE;
X11_Read(_numPAD, _pPADStatus); X11_Read(_numPAD, _pPADStatus);
@ -656,9 +734,8 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
cocoa_Read(_numPAD, _pPADStatus); cocoa_Read(_numPAD, _pPADStatus);
#endif #endif
#ifdef RECORD_STORE // Record input
RecordInput(*_pPADStatus); if (pad[0].bRecording) RecordInput(*_pPADStatus);
#endif
} }
@ -742,7 +819,8 @@ void LoadConfig()
DIK_G, DIK_G,
DIK_F, DIK_F,
DIK_H, DIK_H,
DIK_LSHIFT DIK_LSHIFT, //halfpress
DIK_M //Mic
}; };
#elif defined(HAVE_X11) && HAVE_X11 #elif defined(HAVE_X11) && HAVE_X11
const int defaultKeyForControl[NUMCONTROLS] = const int defaultKeyForControl[NUMCONTROLS] =
@ -768,7 +846,7 @@ void LoadConfig()
XK_f, XK_f,
XK_h, XK_h,
XK_Shift_L, //halfpress XK_Shift_L, //halfpress
XK_p XK_p //Mic
}; };
#elif defined(HAVE_COCOA) && HAVE_COCOA #elif defined(HAVE_COCOA) && HAVE_COCOA
const int defaultKeyForControl[NUMCONTROLS] = const int defaultKeyForControl[NUMCONTROLS] =
@ -794,7 +872,7 @@ void LoadConfig()
3, 3,
4, 4,
56, //halfpress 56, //halfpress
35 35 //Mic
}; };
#endif #endif
IniFile file; IniFile file;
@ -811,6 +889,9 @@ void LoadConfig()
file.Get(SectionName, "Rumble", &pad[i].bRumble, true); file.Get(SectionName, "Rumble", &pad[i].bRumble, true);
file.Get(SectionName, "XPad#", &pad[i].XPadPlayer); file.Get(SectionName, "XPad#", &pad[i].XPadPlayer);
file.Get(SectionName, "Recording", &pad[i].bRecording, false);
file.Get(SectionName, "Playback", &pad[i].bPlayback, false);
for (int x = 0; x < NUMCONTROLS; x++) for (int x = 0; x < NUMCONTROLS; x++)
{ {
file.Get(SectionName, controlNames[x], &pad[i].keyForControl[x], file.Get(SectionName, controlNames[x], &pad[i].keyForControl[x],
@ -840,6 +921,9 @@ void SaveConfig()
file.Set(SectionName, "DisableOnBackground", pad[i].bDisable); file.Set(SectionName, "DisableOnBackground", pad[i].bDisable);
file.Set(SectionName, "Rumble", pad[i].bRumble); file.Set(SectionName, "Rumble", pad[i].bRumble);
file.Set(SectionName, "XPad#", pad[i].XPadPlayer); file.Set(SectionName, "XPad#", pad[i].XPadPlayer);
// Recording
file.Set(SectionName, "Recording", pad[i].bRecording);
file.Set(SectionName, "Playback", pad[i].bPlayback);
for (int x = 0; x < NUMCONTROLS; x++) for (int x = 0; x < NUMCONTROLS; x++)
{ {

View File

@ -73,19 +73,26 @@ static const char* controlNames[] =
"Mic-button", "Mic-button",
}; };
struct SPads { struct SPads
{
bool bEnableXPad; // Use an XPad in addition to the keyboard? bool bEnableXPad; // Use an XPad in addition to the keyboard?
bool bAttached; // Pad is "attached" to the gamecube/wii bool bAttached; // Pad is "attached" to the gamecube/wii
bool bDisable; // Disabled when dolphin isn't in focus bool bDisable; // Disabled when dolphin isn't in focus
bool bRumble; // Rumble for xpad bool bRumble; // Rumble for xpad
bool bRecording;
bool bPlayback;
int XPadPlayer; // Player# of the xpad int XPadPlayer; // Player# of the xpad
unsigned int keyForControl[NUMCONTROLS];// Keyboard mapping unsigned int keyForControl[NUMCONTROLS];// Keyboard mapping
}; };
extern SPads pad[]; extern SPads pad[];
extern bool g_EmulatorRunning;
void LoadConfig(); void LoadConfig();
void SaveConfig(); void SaveConfig();
bool IsFocus(); bool IsFocus();
// Input Recording
void SaveRecord();
#endif #endif

View File

@ -522,14 +522,6 @@
RelativePath=".\Src\Rumble.cpp" RelativePath=".\Src\Rumble.cpp"
> >
</File> </File>
<File
RelativePath=".\Src\XInput.cpp"
>
</File>
<File
RelativePath=".\Src\XInput.h"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="GUI" Name="GUI"

View File

@ -109,6 +109,7 @@ void Config::Save(int Slot)
file.Set("General", "ShowAdvanced", g_Config.bShowAdvanced); file.Set("General", "ShowAdvanced", g_Config.bShowAdvanced);
file.Set("General", "SaveByID", g_Config.bSaveByID); file.Set("General", "SaveByID", g_Config.bSaveByID);
file.Set("General", "CheckForFocus", g_Config.bCheckFocus); file.Set("General", "CheckForFocus", g_Config.bCheckFocus);
file.Set("General", "NoTriggerFilter", g_Config.bNoTriggerFilter);
// ======================== // ========================
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
@ -141,23 +142,23 @@ void Config::Save(int Slot)
SectionName = joyinfo[PadMapping[i].ID].Name; SectionName = joyinfo[PadMapping[i].ID].Name;
} }
file.Set(SectionName.c_str(), "l_shoulder", PadMapping[i].buttons[CTL_L_SHOULDER]); file.Set(SectionName.c_str(), "l_shoulder", PadMapping[i].buttons[InputCommon::CTL_L_SHOULDER]);
file.Set(SectionName.c_str(), "r_shoulder", PadMapping[i].buttons[CTL_R_SHOULDER]); file.Set(SectionName.c_str(), "r_shoulder", PadMapping[i].buttons[InputCommon::CTL_R_SHOULDER]);
file.Set(SectionName.c_str(), "a_button", PadMapping[i].buttons[CTL_A_BUTTON]); file.Set(SectionName.c_str(), "a_button", PadMapping[i].buttons[InputCommon::CTL_A_BUTTON]);
file.Set(SectionName.c_str(), "b_button", PadMapping[i].buttons[CTL_B_BUTTON]); file.Set(SectionName.c_str(), "b_button", PadMapping[i].buttons[InputCommon::CTL_B_BUTTON]);
file.Set(SectionName.c_str(), "x_button", PadMapping[i].buttons[CTL_X_BUTTON]); file.Set(SectionName.c_str(), "x_button", PadMapping[i].buttons[InputCommon::CTL_X_BUTTON]);
file.Set(SectionName.c_str(), "y_button", PadMapping[i].buttons[CTL_Y_BUTTON]); file.Set(SectionName.c_str(), "y_button", PadMapping[i].buttons[InputCommon::CTL_Y_BUTTON]);
file.Set(SectionName.c_str(), "z_trigger", PadMapping[i].buttons[CTL_Z_TRIGGER]); file.Set(SectionName.c_str(), "z_trigger", PadMapping[i].buttons[InputCommon::CTL_Z_TRIGGER]);
file.Set(SectionName.c_str(), "start_button", PadMapping[i].buttons[CTL_START]); file.Set(SectionName.c_str(), "start_button", PadMapping[i].buttons[InputCommon::CTL_START]);
file.Set(SectionName.c_str(), "dpad", PadMapping[i].dpad); file.Set(SectionName.c_str(), "dpad", PadMapping[i].dpad);
file.Set(SectionName.c_str(), "dpad_up", PadMapping[i].dpad2[CTL_D_PAD_UP]); file.Set(SectionName.c_str(), "dpad_up", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_UP]);
file.Set(SectionName.c_str(), "dpad_down", PadMapping[i].dpad2[CTL_D_PAD_DOWN]); file.Set(SectionName.c_str(), "dpad_down", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_DOWN]);
file.Set(SectionName.c_str(), "dpad_left", PadMapping[i].dpad2[CTL_D_PAD_LEFT]); file.Set(SectionName.c_str(), "dpad_left", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_LEFT]);
file.Set(SectionName.c_str(), "dpad_right", PadMapping[i].dpad2[CTL_D_PAD_RIGHT]); file.Set(SectionName.c_str(), "dpad_right", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_RIGHT]);
file.Set(SectionName.c_str(), "main_x", PadMapping[i].axis[CTL_MAIN_X]); file.Set(SectionName.c_str(), "main_x", PadMapping[i].axis[InputCommon::CTL_MAIN_X]);
file.Set(SectionName.c_str(), "main_y", PadMapping[i].axis[CTL_MAIN_Y]); file.Set(SectionName.c_str(), "main_y", PadMapping[i].axis[InputCommon::CTL_MAIN_Y]);
file.Set(SectionName.c_str(), "sub_x", PadMapping[i].axis[CTL_SUB_X]); file.Set(SectionName.c_str(), "sub_x", PadMapping[i].axis[InputCommon::CTL_SUB_X]);
file.Set(SectionName.c_str(), "sub_y", PadMapping[i].axis[CTL_SUB_Y]); file.Set(SectionName.c_str(), "sub_y", PadMapping[i].axis[InputCommon::CTL_SUB_Y]);
file.Set(SectionName.c_str(), "deadzone", PadMapping[i].deadzone); file.Set(SectionName.c_str(), "deadzone", PadMapping[i].deadzone);
file.Set(SectionName.c_str(), "halfpress", PadMapping[i].halfpress); file.Set(SectionName.c_str(), "halfpress", PadMapping[i].halfpress);
@ -167,7 +168,7 @@ void Config::Save(int Slot)
file.Set(SectionName.c_str(), "eventnum", PadMapping[i].eventnum); file.Set(SectionName.c_str(), "eventnum", PadMapping[i].eventnum);
file.Set(SectionName.c_str(), "Diagonal", PadMapping[i].SDiagonal); file.Set(SectionName.c_str(), "Diagonal", PadMapping[i].SDiagonal);
file.Set(SectionName.c_str(), "SquareToCircle", PadMapping[i].bSquareToCircle); file.Set(SectionName.c_str(), "SquareToCircle", PadMapping[i].bSquareToCircle);
// ====================================== // ======================================
// Debugging // Debugging
@ -196,6 +197,8 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
file.Get("General", "ShowAdvanced", &g_Config.bShowAdvanced, false); file.Get("General", "ShowAdvanced", &g_Config.bShowAdvanced, false);
file.Get("General", "CheckForFocus", &g_Config.bCheckFocus, false); file.Get("General", "CheckForFocus", &g_Config.bCheckFocus, false);
file.Get("General", "NoTriggerFilter", &g_Config.bNoTriggerFilter, false);
if(!ChangeSaveByID) if(!ChangeSaveByID)
{ {
file.Get("General", "SaveByID", &Tmp, false); g_Config.bSaveByID = Tmp; file.Get("General", "SaveByID", &Tmp, false); g_Config.bSaveByID = Tmp;
@ -228,23 +231,23 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
SectionName = joyinfo[PadMapping[i].ID].Name; SectionName = joyinfo[PadMapping[i].ID].Name;
} }
file.Get(SectionName.c_str(), "l_shoulder", &PadMapping[i].buttons[CTL_L_SHOULDER], 4); file.Get(SectionName.c_str(), "l_shoulder", &PadMapping[i].buttons[InputCommon::CTL_L_SHOULDER], 4);
file.Get(SectionName.c_str(), "r_shoulder", &PadMapping[i].buttons[CTL_R_SHOULDER], 5); file.Get(SectionName.c_str(), "r_shoulder", &PadMapping[i].buttons[InputCommon::CTL_R_SHOULDER], 5);
file.Get(SectionName.c_str(), "a_button", &PadMapping[i].buttons[CTL_A_BUTTON], 0); file.Get(SectionName.c_str(), "a_button", &PadMapping[i].buttons[InputCommon::CTL_A_BUTTON], 0);
file.Get(SectionName.c_str(), "b_button", &PadMapping[i].buttons[CTL_B_BUTTON], 1); file.Get(SectionName.c_str(), "b_button", &PadMapping[i].buttons[InputCommon::CTL_B_BUTTON], 1);
file.Get(SectionName.c_str(), "x_button", &PadMapping[i].buttons[CTL_X_BUTTON], 3); file.Get(SectionName.c_str(), "x_button", &PadMapping[i].buttons[InputCommon::CTL_X_BUTTON], 3);
file.Get(SectionName.c_str(), "y_button", &PadMapping[i].buttons[CTL_Y_BUTTON], 2); file.Get(SectionName.c_str(), "y_button", &PadMapping[i].buttons[InputCommon::CTL_Y_BUTTON], 2);
file.Get(SectionName.c_str(), "z_trigger", &PadMapping[i].buttons[CTL_Z_TRIGGER], 7); file.Get(SectionName.c_str(), "z_trigger", &PadMapping[i].buttons[InputCommon::CTL_Z_TRIGGER], 7);
file.Get(SectionName.c_str(), "start_button", &PadMapping[i].buttons[CTL_START], 9); file.Get(SectionName.c_str(), "start_button", &PadMapping[i].buttons[InputCommon::CTL_START], 9);
file.Get(SectionName.c_str(), "dpad", &PadMapping[i].dpad, 0); file.Get(SectionName.c_str(), "dpad", &PadMapping[i].dpad, 0);
file.Get(SectionName.c_str(), "dpad_up", &PadMapping[i].dpad2[CTL_D_PAD_UP], 0); file.Get(SectionName.c_str(), "dpad_up", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_UP], 0);
file.Get(SectionName.c_str(), "dpad_down", &PadMapping[i].dpad2[CTL_D_PAD_DOWN], 0); file.Get(SectionName.c_str(), "dpad_down", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_DOWN], 0);
file.Get(SectionName.c_str(), "dpad_left", &PadMapping[i].dpad2[CTL_D_PAD_LEFT], 0); file.Get(SectionName.c_str(), "dpad_left", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_LEFT], 0);
file.Get(SectionName.c_str(), "dpad_right", &PadMapping[i].dpad2[CTL_D_PAD_RIGHT], 0); file.Get(SectionName.c_str(), "dpad_right", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_RIGHT], 0);
file.Get(SectionName.c_str(), "main_x", &PadMapping[i].axis[CTL_MAIN_X], 0); file.Get(SectionName.c_str(), "main_x", &PadMapping[i].axis[InputCommon::CTL_MAIN_X], 0);
file.Get(SectionName.c_str(), "main_y", &PadMapping[i].axis[CTL_MAIN_Y], 1); file.Get(SectionName.c_str(), "main_y", &PadMapping[i].axis[InputCommon::CTL_MAIN_Y], 1);
file.Get(SectionName.c_str(), "sub_x", &PadMapping[i].axis[CTL_SUB_X], 2); file.Get(SectionName.c_str(), "sub_x", &PadMapping[i].axis[InputCommon::CTL_SUB_X], 2);
file.Get(SectionName.c_str(), "sub_y", &PadMapping[i].axis[CTL_SUB_Y], 3); file.Get(SectionName.c_str(), "sub_y", &PadMapping[i].axis[InputCommon::CTL_SUB_Y], 3);
file.Get(SectionName.c_str(), "deadzone", &PadMapping[i].deadzone, 9); file.Get(SectionName.c_str(), "deadzone", &PadMapping[i].deadzone, 9);
file.Get(SectionName.c_str(), "halfpress", &PadMapping[i].halfpress, -1); file.Get(SectionName.c_str(), "halfpress", &PadMapping[i].halfpress, -1);

View File

@ -29,6 +29,7 @@ struct Config
bool bShowAdvanced; // Only allow one of these bool bShowAdvanced; // Only allow one of these
bool bSaveByID; bool bSaveByID;
bool bCheckFocus; bool bCheckFocus;
bool bNoTriggerFilter;
}; };
extern Config g_Config; extern Config g_Config;

View File

@ -37,7 +37,7 @@
#include "../nJoy.h" #include "../nJoy.h"
#include "Images/controller.xpm" #include "Images/controller.xpm"
extern bool emulator_running; extern bool g_EmulatorRunning;
//////////////////////// ////////////////////////
/* If we don't use this hack m_MainSizer->GetMinSize().GetWidth() will not change /* If we don't use this hack m_MainSizer->GetMinSize().GetWidth() will not change
@ -70,8 +70,10 @@ void ConfigBox::PadGetStatus()
int PhysicalDevice = PadMapping[notebookpage].ID; int PhysicalDevice = PadMapping[notebookpage].ID;
int TriggerType = PadMapping[notebookpage].triggertype; int TriggerType = PadMapping[notebookpage].triggertype;
// Get pad status // Check that Dolphin is in focus, otherwise don't update the pad status
GetJoyState(notebookpage); if (!g_Config.bCheckFocus && IsFocus())
InputCommon::GetJoyState(PadState[notebookpage], PadMapping[notebookpage], notebookpage, joyinfo[PadMapping[notebookpage].ID].NumButtons);
////////////////////////////////////// //////////////////////////////////////
// Analog stick // Analog stick
@ -81,8 +83,8 @@ void ConfigBox::PadGetStatus()
//int deadzone2 = (int)(((float)(-128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1)); //int deadzone2 = (int)(((float)(-128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1));
// Get original values // Get original values
int main_x = PadState[notebookpage].axis[CTL_MAIN_X]; int main_x = PadState[notebookpage].axis[InputCommon::CTL_MAIN_X];
int main_y = PadState[notebookpage].axis[CTL_MAIN_Y]; int main_y = PadState[notebookpage].axis[InputCommon::CTL_MAIN_Y];
//int sub_x = (PadState[_numPAD].axis[CTL_SUB_X]; //int sub_x = (PadState[_numPAD].axis[CTL_SUB_X];
//int sub_y = -(PadState[_numPAD].axis[CTL_SUB_Y]; //int sub_y = -(PadState[_numPAD].axis[CTL_SUB_Y];
@ -90,7 +92,7 @@ void ConfigBox::PadGetStatus()
int main_x_after = main_x, main_y_after = main_y; int main_x_after = main_x, main_y_after = main_y;
if(PadMapping[notebookpage].bSquareToCircle) if(PadMapping[notebookpage].bSquareToCircle)
{ {
std::vector<int> main_xy = Pad_Square_to_Circle(main_x, main_y, notebookpage); std::vector<int> main_xy = InputCommon::Pad_Square_to_Circle(main_x, main_y, notebookpage, PadMapping[notebookpage]);
main_x_after = main_xy.at(0); main_x_after = main_xy.at(0);
main_y_after = main_xy.at(1); main_y_after = main_xy.at(1);
} }
@ -138,14 +140,14 @@ void ConfigBox::PadGetStatus()
m_JoyShoulderR[notebookpage]->GetValue().ToLong(&Right); m_JoyShoulderR[notebookpage]->GetValue().ToLong(&Right);
// Get the trigger values // Get the trigger values
int TriggerLeft = PadState[notebookpage].axis[CTL_L_SHOULDER]; int TriggerLeft = PadState[notebookpage].axis[InputCommon::CTL_L_SHOULDER];
int TriggerRight = PadState[notebookpage].axis[CTL_R_SHOULDER]; int TriggerRight = PadState[notebookpage].axis[InputCommon::CTL_R_SHOULDER];
// Convert the triggers values // Convert the triggers values
if (PadMapping[notebookpage].triggertype == CTL_TRIGGER_SDL) if (PadMapping[notebookpage].triggertype == InputCommon::CTL_TRIGGER_SDL)
{ {
TriggerLeft = Pad_Convert(TriggerLeft); TriggerLeft = InputCommon::Pad_Convert(TriggerLeft);
TriggerRight = Pad_Convert(TriggerRight); TriggerRight = InputCommon::Pad_Convert(TriggerRight);
} }
// If we don't have any axis selected for the shoulder buttons // If we don't have any axis selected for the shoulder buttons
@ -153,8 +155,8 @@ void ConfigBox::PadGetStatus()
if(Right < 1000) TriggerRight = 0; if(Right < 1000) TriggerRight = 0;
// Get the digital values // Get the digital values
if(Left < 1000 && PadState[notebookpage].buttons[CTL_L_SHOULDER]) TriggerLeft = TriggerValue; if(Left < 1000 && PadState[notebookpage].buttons[InputCommon::CTL_L_SHOULDER]) TriggerLeft = TriggerValue;
if(Right < 1000 && PadState[notebookpage].buttons[CTL_R_SHOULDER]) TriggerRight = TriggerValue; if(Right < 1000 && PadState[notebookpage].buttons[InputCommon::CTL_R_SHOULDER]) TriggerRight = TriggerValue;
m_TStatusTriggers[notebookpage]->SetLabel(wxString::Format( m_TStatusTriggers[notebookpage]->SetLabel(wxString::Format(
wxT("Left:%03i Right:%03i"), wxT("Left:%03i Right:%03i"),
@ -192,6 +194,10 @@ std::string ShowStatus(int VirtualController)
int Hats = joyinfo[PhysicalDevice].NumHats; int Hats = joyinfo[PhysicalDevice].NumHats;
int Buttons = joyinfo[PhysicalDevice].NumButtons; int Buttons = joyinfo[PhysicalDevice].NumButtons;
// Get version
//SDL_version Version;
//SDL_GetVersion(&Version);
// Update the internal values // Update the internal values
SDL_JoystickUpdate(); SDL_JoystickUpdate();
@ -213,7 +219,7 @@ std::string ShowStatus(int VirtualController)
} }
return StringFromFormat( return StringFromFormat(
"PadMapping\n" //"Version: %i.%i.%i\n"
"Enabled: %i %i %i %i\n" "Enabled: %i %i %i %i\n"
"ID: %i %i %i %i\n" "ID: %i %i %i %i\n"
"Controllertype: %i %i %i %i\n" "Controllertype: %i %i %i %i\n"
@ -225,6 +231,7 @@ std::string ShowStatus(int VirtualController)
"Hats: %s\n" "Hats: %s\n"
"But: %s\n" "But: %s\n"
"Device: Ax: %i Balls:%i Hats:%i But:%i", "Device: Ax: %i Balls:%i Hats:%i But:%i",
//Version.major, Version.minor, Version.patch,
PadMapping[0].enabled, PadMapping[1].enabled, PadMapping[2].enabled, PadMapping[3].enabled, PadMapping[0].enabled, PadMapping[1].enabled, PadMapping[2].enabled, PadMapping[3].enabled,
PadMapping[0].ID, PadMapping[1].ID, PadMapping[2].ID, PadMapping[3].ID, PadMapping[0].ID, PadMapping[1].ID, PadMapping[2].ID, PadMapping[3].ID,
PadMapping[0].controllertype, PadMapping[1].controllertype, PadMapping[2].controllertype, PadMapping[3].controllertype, PadMapping[0].controllertype, PadMapping[1].controllertype, PadMapping[2].controllertype, PadMapping[3].controllertype,
@ -233,7 +240,7 @@ std::string ShowStatus(int VirtualController)
//PadState[PadMapping[0].ID].joy, PadState[PadMapping[1].ID].joy, PadState[PadMapping[2].ID].joy, PadState[PadMapping[3].ID].joy, //PadState[PadMapping[0].ID].joy, PadState[PadMapping[1].ID].joy, PadState[PadMapping[2].ID].joy, PadState[PadMapping[3].ID].joy,
#ifdef _WIN32 #ifdef _WIN32
XInput::IsConnected(0), XInput::GetXI(0, XI_TRIGGER_L), XInput::GetXI(0, XI_TRIGGER_R), XInput::IsConnected(0), XInput::GetXI(0, InputCommon::XI_TRIGGER_L), XInput::GetXI(0, InputCommon::XI_TRIGGER_R),
#endif #endif
StrAxes.c_str(), StrHats.c_str(), StrBut.c_str(), StrAxes.c_str(), StrHats.c_str(), StrBut.c_str(),
Axes, Balls, Hats, Buttons Axes, Balls, Hats, Buttons
@ -245,10 +252,12 @@ std::string ShowStatus(int VirtualController)
void ConfigBox::Update() void ConfigBox::Update()
{ {
// Show the current status // Show the current status
/* /**/
m_pStatusBar->SetLabel(wxString::Format( #ifdef SHOW_PAD_STATUS
"%s", ShowStatus(notebookpage).c_str() m_pStatusBar->SetLabel(wxString::Format(
));*/ "%s", ShowStatus(notebookpage).c_str()
));
#endif
//LogMsg("Abc%s\n", ShowStatus(notebookpage).c_str()); //LogMsg("Abc%s\n", ShowStatus(notebookpage).c_str());
@ -261,6 +270,10 @@ void ConfigBox::Update()
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void ConfigBox::CreateAdvancedControls(int i) void ConfigBox::CreateAdvancedControls(int i)
{ {
m_TStatusIn[i] = new wxStaticText(m_Controller[i], IDT_STATUS_IN, wxT("In"));
m_TStatusOut[i] = new wxStaticText(m_Controller[i], IDT_STATUS_OUT, wxT("Out"));
m_gStatusIn[i] = new wxStaticBoxSizer( wxHORIZONTAL, m_Controller[i], wxT("Main-stick (In) (Out)"));
m_pInStatus[i] = new wxPanel(m_Controller[i], ID_INSTATUS1 + i, wxDefaultPosition, wxDefaultSize); m_pInStatus[i] = new wxPanel(m_Controller[i], ID_INSTATUS1 + i, wxDefaultPosition, wxDefaultSize);
m_bmpSquare[i] = new wxStaticBitmap(m_pInStatus[i], ID_STATUSBMP1 + i, CreateBitmap(), m_bmpSquare[i] = new wxStaticBitmap(m_pInStatus[i], ID_STATUSBMP1 + i, CreateBitmap(),
//wxPoint(4, 15), wxSize(70,70)); //wxPoint(4, 15), wxSize(70,70));

View File

@ -39,7 +39,7 @@
#include "../nJoy.h" #include "../nJoy.h"
#include "Images/controller.xpm" #include "Images/controller.xpm"
extern bool emulator_running; extern bool g_EmulatorRunning;
// D-Pad type // D-Pad type
static const char* DPadType[] = static const char* DPadType[] =
@ -74,7 +74,7 @@ BEGIN_EVENT_TABLE(ConfigBox,wxDialog)
// Other settings // Other settings
EVT_CHECKBOX(IDC_SAVEBYID, ConfigBox::ChangeSettings) EVT_CHECKBOX(IDC_SAVEBYID, ConfigBox::ChangeSettings)
EVT_CHECKBOX(IDC_SHOWADVANCED, ConfigBox::ChangeSettings) EVT_CHECKBOX(IDC_SHOWADVANCED, ConfigBox::ChangeSettings)
EVT_CHECKBOX(IDC_CHECKFOCUS, ConfigBox::ChangeSettings) EVT_CHECKBOX(IDCB_CHECKFOCUS, ConfigBox::ChangeSettings)
EVT_COMBOBOX(IDCB_MAINSTICK_DIAGONAL, ConfigBox::ChangeSettings) EVT_COMBOBOX(IDCB_MAINSTICK_DIAGONAL, ConfigBox::ChangeSettings)
EVT_COMBOBOX(IDC_CONTROLTYPE, ConfigBox::ChangeSettings) EVT_COMBOBOX(IDC_CONTROLTYPE, ConfigBox::ChangeSettings)
EVT_COMBOBOX(IDC_TRIGGERTYPE, ConfigBox::ChangeSettings) EVT_COMBOBOX(IDC_TRIGGERTYPE, ConfigBox::ChangeSettings)
@ -83,6 +83,7 @@ BEGIN_EVENT_TABLE(ConfigBox,wxDialog)
// Advanced settings // Advanced settings
EVT_COMBOBOX(IDCB_MAINSTICK_DIAGONAL, ConfigBox::ChangeSettings) EVT_COMBOBOX(IDCB_MAINSTICK_DIAGONAL, ConfigBox::ChangeSettings)
EVT_CHECKBOX(IDCB_MAINSTICK_S_TO_C, ConfigBox::ChangeSettings) EVT_CHECKBOX(IDCB_MAINSTICK_S_TO_C, ConfigBox::ChangeSettings)
EVT_CHECKBOX(IDCB_FILTER_SETTINGS, ConfigBox::ChangeSettings)
EVT_BUTTON(IDB_SHOULDER_L, ConfigBox::GetButtons) EVT_BUTTON(IDB_SHOULDER_L, ConfigBox::GetButtons)
EVT_BUTTON(IDB_SHOULDER_R, ConfigBox::GetButtons) EVT_BUTTON(IDB_SHOULDER_R, ConfigBox::GetButtons)
@ -161,7 +162,7 @@ void ConfigBox::OnKeyDown(wxKeyEvent& event)
void ConfigBox::OnClose(wxCloseEvent& /*event*/) void ConfigBox::OnClose(wxCloseEvent& /*event*/)
{ {
EndModal(0); EndModal(0);
if(!emulator_running) Shutdown(); // Close pads, unless we are running a game if(!g_EmulatorRunning) Shutdown(); // Close pads, unless we are running a game
} }
// Call about dialog // Call about dialog
@ -291,7 +292,8 @@ void ConfigBox::OnSaveById()
// Change Joystick // Change Joystick
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Function: When changing the joystick we save and load the settings and update the PadMapping /* Function: When changing the joystick we save and load the settings and update the PadMapping
and PadState array */ and PadState array. PadState[].joy is the gamepad handle that is used to access the pad throughout
the plugin. Joyinfo[].joy is only used the first time the pads are checked. */
void ConfigBox::DoChangeJoystick() void ConfigBox::DoChangeJoystick()
{ {
// Close the current pad, unless it's used by another slot // Close the current pad, unless it's used by another slot
@ -425,16 +427,34 @@ void ConfigBox::ChangeSettings( wxCommandEvent& event )
} }
SizeWindow(); SizeWindow();
break; break;
case IDC_CHECKFOCUS: // Advanced settings
case IDCB_CHECKFOCUS:
g_Config.bCheckFocus = m_CBCheckFocus[notebookpage]->IsChecked(); g_Config.bCheckFocus = m_CBCheckFocus[notebookpage]->IsChecked();
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
{ {
m_CBCheckFocus[i]->SetValue(g_Config.bCheckFocus); m_CBCheckFocus[i]->SetValue(g_Config.bCheckFocus);
} }
break; break;
case IDCB_FILTER_SETTINGS:
g_Config.bNoTriggerFilter = m_AdvancedMapFilter[notebookpage]->IsChecked();
for(int i = 0; i < 4; i++)
{
m_AdvancedMapFilter[i]->SetValue(g_Config.bNoTriggerFilter);
}
break;
case IDC_CONTROLTYPE: case IDC_CONTROLTYPE:
if(!g_Config.bSaveByID)
{
PadMapping[notebookpage].controllertype = m_ControlType[notebookpage]->GetSelection();
UpdateGUI(notebookpage);
}
case IDC_TRIGGERTYPE: case IDC_TRIGGERTYPE:
//UpdateGUI(notebookpage); if(!g_Config.bSaveByID)
{
PadMapping[notebookpage].triggertype = m_TriggerType[notebookpage]->GetSelection();
UpdateGUI(notebookpage);
}
break; break;
case IDC_JOYNAME: case IDC_JOYNAME:
@ -472,10 +492,10 @@ void ConfigBox::UpdateGUI(int _notebookpage)
} }
// Update the GUI from PadMapping[] // Update the GUI from PadMapping[]
UpdateGUIKeys(_notebookpage); UpdateGUIButtonMapping(_notebookpage);
// Collect status // Collect status
bool Hat = (PadMapping[_notebookpage].controllertype == CTL_DPAD_HAT); bool Hat = (PadMapping[_notebookpage].controllertype == InputCommon::CTL_DPAD_HAT);
long Left, Right; long Left, Right;
m_JoyShoulderL[_notebookpage]->GetValue().ToLong(&Left); m_JoyShoulderL[_notebookpage]->GetValue().ToLong(&Left);
m_JoyShoulderR[_notebookpage]->GetValue().ToLong(&Right); m_JoyShoulderR[_notebookpage]->GetValue().ToLong(&Right);
@ -505,6 +525,7 @@ void ConfigBox::UpdateGUI(int _notebookpage)
m_CBSaveByID[_notebookpage]->SetValue(g_Config.bSaveByID); m_CBSaveByID[_notebookpage]->SetValue(g_Config.bSaveByID);
m_CBShowAdvanced[_notebookpage]->SetValue(g_Config.bShowAdvanced); m_CBShowAdvanced[_notebookpage]->SetValue(g_Config.bShowAdvanced);
m_CBCheckFocus[_notebookpage]->SetValue(g_Config.bCheckFocus); m_CBCheckFocus[_notebookpage]->SetValue(g_Config.bCheckFocus);
m_AdvancedMapFilter[_notebookpage]->SetValue(g_Config.bNoTriggerFilter);
LogMsg("Update: %i\n", g_Config.bSaveByID); LogMsg("Update: %i\n", g_Config.bSaveByID);
@ -520,7 +541,8 @@ void ConfigBox::UpdateGUI(int _notebookpage)
m_Controller[_notebookpage]->FindItem(IDC_CONTROLTYPE)->Enable(Enabled); m_Controller[_notebookpage]->FindItem(IDC_CONTROLTYPE)->Enable(Enabled);
m_Controller[_notebookpage]->FindItem(IDC_TRIGGERTYPE)->Enable(Enabled && XInput); m_Controller[_notebookpage]->FindItem(IDC_TRIGGERTYPE)->Enable(Enabled && XInput);
m_Controller[_notebookpage]->FindItem(IDCB_MAINSTICK_DIAGONAL)->Enable(Enabled); m_Controller[_notebookpage]->FindItem(IDCB_MAINSTICK_DIAGONAL)->Enable(Enabled);
m_Controller[_notebookpage]->FindItem(IDCB_MAINSTICK_S_TO_C)->Enable(Enabled); m_Controller[_notebookpage]->FindItem(IDCB_MAINSTICK_S_TO_C)->Enable(Enabled);
m_Controller[_notebookpage]->FindItem(IDCB_FILTER_SETTINGS)->Enable(Enabled);
#endif #endif
// Replace the harder to understand -1 with "" for the sake of user friendliness // Replace the harder to understand -1 with "" for the sake of user friendliness
@ -619,12 +641,12 @@ void ConfigBox::CreateGUIControls()
// Populate the DPad type and Trigger type list // Populate the DPad type and Trigger type list
// ----------------------------- // -----------------------------
wxArrayString wxAS_DPadType; wxArrayString wxAS_DPadType;
wxAS_DPadType.Add(wxString::FromAscii(DPadType[CTL_DPAD_HAT])); wxAS_DPadType.Add(wxString::FromAscii(DPadType[InputCommon::CTL_DPAD_HAT]));
wxAS_DPadType.Add(wxString::FromAscii(DPadType[CTL_DPAD_CUSTOM])); wxAS_DPadType.Add(wxString::FromAscii(DPadType[InputCommon::CTL_DPAD_CUSTOM]));
wxArrayString wxAS_TriggerType; wxArrayString wxAS_TriggerType;
wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[CTL_TRIGGER_SDL])); wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[InputCommon::CTL_TRIGGER_SDL]));
wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[CTL_TRIGGER_XINPUT])); wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[InputCommon::CTL_TRIGGER_XINPUT]));
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Populate the deadzone list // Populate the deadzone list
@ -820,12 +842,10 @@ void ConfigBox::CreateGUIControls()
m_gGenSettingsID[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Settings") ); m_gGenSettingsID[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Settings") );
m_CBSaveByID[i] = new wxCheckBox(m_Controller[i], IDC_SAVEBYID, wxT("Save by ID"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_CBSaveByID[i] = new wxCheckBox(m_Controller[i], IDC_SAVEBYID, wxT("Save by ID"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_CBShowAdvanced[i] = new wxCheckBox(m_Controller[i], IDC_SHOWADVANCED, wxT("Show advanced settings"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_CBShowAdvanced[i] = new wxCheckBox(m_Controller[i], IDC_SHOWADVANCED, wxT("Show advanced settings"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_CBCheckFocus[i] = new wxCheckBox(m_Controller[i], IDC_CHECKFOCUS, wxT("Allow out of focus input"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
// Populate general settings 3 // Populate general settings 3
m_gGenSettingsID[i]->Add(m_CBSaveByID[i], 0, wxEXPAND | wxALL, 3); m_gGenSettingsID[i]->Add(m_CBSaveByID[i], 0, wxEXPAND | wxALL, 3);
m_gGenSettingsID[i]->Add(m_CBShowAdvanced[i], 0, wxEXPAND | wxALL, 3); m_gGenSettingsID[i]->Add(m_CBShowAdvanced[i], 0, wxEXPAND | wxALL, 3);
m_gGenSettingsID[i]->Add(m_CBCheckFocus[i], 0, wxEXPAND | wxALL, 3);
// Create tooltips // Create tooltips
m_ControlType[i]->SetToolTip(wxT( m_ControlType[i]->SetToolTip(wxT(
@ -840,8 +860,6 @@ void ConfigBox::CreateGUIControls()
"\nto save your settings if you have multiple controllers.") "\nto save your settings if you have multiple controllers.")
, i+1 , i+1
)); ));
m_CBCheckFocus[i]->SetToolTip(wxT(
"Allow gamepad input even when Dolphin is not in focus. Out of focus keyboard input is never allowed."));
// Populate settings // Populate settings
m_sSettings[i] = new wxBoxSizer ( wxHORIZONTAL ); m_sSettings[i] = new wxBoxSizer ( wxHORIZONTAL );
@ -857,17 +875,13 @@ void ConfigBox::CreateGUIControls()
// Advanced settings // Advanced settings
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Populate input status // Input status controls
/**/
// Input status text // Input status text
m_TStatusIn[i] = new wxStaticText(m_Controller[i], IDT_STATUS_IN, wxT("In"));
m_TStatusOut[i] = new wxStaticText(m_Controller[i], IDT_STATUS_OUT, wxT("Out"));
m_gStatusIn[i] = new wxStaticBoxSizer( wxHORIZONTAL, m_Controller[i], wxT("Main-stick (In) (Out)"));
CreateAdvancedControls(i); CreateAdvancedControls(i);
m_GBAdvancedMainStick[i] = new wxGridBagSizer(0, 0);
// Sizers
m_GBAdvancedMainStick[i] = new wxGridBagSizer(0, 0);
m_GBAdvancedMainStick[i]->Add(m_pInStatus[i], wxGBPosition(0, 0), wxGBSpan(1, 1), wxALL, 0); m_GBAdvancedMainStick[i]->Add(m_pInStatus[i], wxGBPosition(0, 0), wxGBSpan(1, 1), wxALL, 0);
m_GBAdvancedMainStick[i]->Add(m_pOutStatus[i], wxGBPosition(0, 1), wxGBSpan(1, 1), wxLEFT, 5); m_GBAdvancedMainStick[i]->Add(m_pOutStatus[i], wxGBPosition(0, 1), wxGBSpan(1, 1), wxLEFT, 5);
m_GBAdvancedMainStick[i]->Add(m_TStatusIn[i], wxGBPosition(1, 0), wxGBSpan(1, 1), wxALL, 0); m_GBAdvancedMainStick[i]->Add(m_TStatusIn[i], wxGBPosition(1, 0), wxGBSpan(1, 1), wxALL, 0);
@ -911,6 +925,20 @@ void ConfigBox::CreateGUIControls()
m_gStatusTriggers[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Trigger values")); m_gStatusTriggers[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Trigger values"));
m_TStatusTriggers[i] = new wxStaticText(m_Controller[i], IDT_TRIGGERS, wxT("Left: Right:")); m_TStatusTriggers[i] = new wxStaticText(m_Controller[i], IDT_TRIGGERS, wxT("Left: Right:"));
m_gStatusTriggers[i]->Add(m_TStatusTriggers[i], 0, (wxALL), 4); m_gStatusTriggers[i]->Add(m_TStatusTriggers[i], 0, (wxALL), 4);
m_gStatusAdvancedSettings[i] = new wxStaticBoxSizer( wxVERTICAL, m_Controller[i], wxT("Advanced settings"));
m_CBCheckFocus[i] = new wxCheckBox(m_Controller[i], IDCB_CHECKFOCUS, wxT("Allow out of focus input"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_AdvancedMapFilter[i] = new wxCheckBox(m_Controller[i], IDCB_FILTER_SETTINGS , wxT("No trigger filter"));
m_gStatusAdvancedSettings[i]->Add(m_CBCheckFocus[i], 0, (wxALL), 4);
m_gStatusAdvancedSettings[i]->Add(m_AdvancedMapFilter[i], 0, (wxALL), 4);
// Tool tips
m_CBCheckFocus[i]->SetToolTip(wxT(
"Allow gamepad input even when Dolphin is not in focus. Out of focus keyboard input is never allowed."));
m_AdvancedMapFilter[i]->SetToolTip(wxT(
"This will allow you to map a digital axis to the main stick or the C-stick. If you don't have"
" any analog triggers that will be automatically set when the trigger filter is off."
));
////////////////////////// Advanced settings ////////////////////////// Advanced settings
@ -933,6 +961,7 @@ void ConfigBox::CreateGUIControls()
m_sMainRight[i]->Add(m_gStatusIn[i], 0, wxEXPAND | (wxLEFT), 2); m_sMainRight[i]->Add(m_gStatusIn[i], 0, wxEXPAND | (wxLEFT), 2);
m_sMainRight[i]->Add(m_gStatusInSettings[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2); m_sMainRight[i]->Add(m_gStatusInSettings[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2);
m_sMainRight[i]->Add(m_gStatusTriggers[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2); m_sMainRight[i]->Add(m_gStatusTriggers[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2);
m_sMainRight[i]->Add(m_gStatusAdvancedSettings[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2);
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Populate main sizer // Populate main sizer
@ -946,7 +975,7 @@ void ConfigBox::CreateGUIControls()
m_sMainRight[i]->Show(g_Config.bShowAdvanced); m_sMainRight[i]->Show(g_Config.bShowAdvanced);
// Don't allow these changes when running // Don't allow these changes when running
if(emulator_running) if(g_EmulatorRunning)
{ {
m_Joyname[i]->Enable(false); m_Joyname[i]->Enable(false);
m_Joyattach[i]->Enable(false); m_Joyattach[i]->Enable(false);
@ -979,7 +1008,9 @@ void ConfigBox::CreateGUIControls()
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Debugging // Debugging
// ----------------------------- // -----------------------------
//m_pStatusBar = new wxStaticText(this, IDT_DEBUGGING, wxT("Debugging"), wxPoint(135, 100), wxDefaultSize); #ifdef SHOW_PAD_STATUS
m_pStatusBar = new wxStaticText(this, IDT_DEBUGGING, wxT("Debugging"), wxPoint(135, 100), wxDefaultSize);
#endif
//m_pStatusBar2 = new wxStaticText(this, IDT_DEBUGGING2, wxT("Debugging2"), wxPoint(125, 200), wxDefaultSize); //m_pStatusBar2 = new wxStaticText(this, IDT_DEBUGGING2, wxT("Debugging2"), wxPoint(125, 200), wxDefaultSize);
//m_pStatusBar->SetLabel(wxString::Format("Debugging text")); //m_pStatusBar->SetLabel(wxString::Format("Debugging text"));

View File

@ -48,6 +48,7 @@
#include <wx/statbmp.h> #include <wx/statbmp.h>
#include <wx/gbsizer.h> #include <wx/gbsizer.h>
#include "../nJoy.h"
class ConfigBox : public wxDialog class ConfigBox : public wxDialog
{ {
@ -112,14 +113,15 @@ class ConfigBox : public wxDialog
wxStaticBoxSizer *m_gGenSettingsID[4]; wxStaticBoxSizer *m_gGenSettingsID[4];
wxGridBagSizer * m_gGBGenSettings[4]; wxGridBagSizer * m_gGBGenSettings[4];
wxCheckBox *m_CBSaveByID[4], *m_CBShowAdvanced[4], *m_CBCheckFocus[4]; wxCheckBox *m_CBSaveByID[4], *m_CBShowAdvanced[4];
wxStaticText *m_TSControltype[4], *m_TSTriggerType[4]; wxStaticText *m_TSControltype[4], *m_TSTriggerType[4];
wxStaticBoxSizer *m_gStatusIn[4], *m_gStatusInSettings[4]; // Advanced settings wxStaticBoxSizer *m_gStatusIn[4], *m_gStatusInSettings[4], *m_gStatusAdvancedSettings[4]; // Advanced settings
wxBoxSizer *m_gStatusInSettingsH[4]; wxBoxSizer *m_gStatusInSettingsH[4];
wxGridBagSizer * m_GBAdvancedMainStick[4]; wxGridBagSizer * m_GBAdvancedMainStick[4];
wxStaticText *m_TStatusIn[4], *m_TStatusOut[4], *m_STDiagonal[4]; wxStaticText *m_TStatusIn[4], *m_TStatusOut[4], *m_STDiagonal[4];
wxComboBox *m_CoBDiagonal[4]; wxCheckBox *m_CBS_to_C[4]; wxComboBox *m_CoBDiagonal[4]; wxCheckBox *m_CBS_to_C[4];
wxCheckBox *m_CBCheckFocus[4], *m_AdvancedMapFilter[4];
wxStaticBoxSizer *m_gStatusTriggers[4]; // Triggers wxStaticBoxSizer *m_gStatusTriggers[4]; // Triggers
wxStaticText *m_TStatusTriggers[4]; wxStaticText *m_TStatusTriggers[4];
@ -210,7 +212,7 @@ class ConfigBox : public wxDialog
IDG_CONTROLLERTYPE, IDC_CONTROLTYPE, IDC_TRIGGERTYPE, // Controller type IDG_CONTROLLERTYPE, IDC_CONTROLTYPE, IDC_TRIGGERTYPE, // Controller type
IDC_SAVEBYID, IDC_SHOWADVANCED, IDC_CHECKFOCUS, // Settings IDC_SAVEBYID, IDC_SHOWADVANCED, // Settings
ID_INSTATUS1, ID_INSTATUS2, ID_INSTATUS3, ID_INSTATUS4, // Advanced status ID_INSTATUS1, ID_INSTATUS2, ID_INSTATUS3, ID_INSTATUS4, // Advanced status
ID_STATUSBMP1, ID_STATUSBMP2, ID_STATUSBMP3, ID_STATUSBMP4, ID_STATUSBMP1, ID_STATUSBMP2, ID_STATUSBMP3, ID_STATUSBMP4,
@ -218,7 +220,7 @@ class ConfigBox : public wxDialog
IDT_STATUS_IN, IDT_STATUS_OUT, IDT_STATUS_IN, IDT_STATUS_OUT,
// Advaced settings // Advaced settings
IDCB_MAINSTICK_DIAGONAL, IDCB_MAINSTICK_S_TO_C, IDT_MAINSTICK_DIAGONAL, IDT_TRIGGERS, IDCB_MAINSTICK_DIAGONAL, IDCB_MAINSTICK_S_TO_C, IDT_MAINSTICK_DIAGONAL, IDT_TRIGGERS, IDCB_CHECKFOCUS, IDCB_FILTER_SETTINGS,
// Timers // Timers
IDTM_CONSTANT, IDTM_BUTTON, IDTM_CONSTANT, IDTM_BUTTON,
@ -317,7 +319,7 @@ class ConfigBox : public wxDialog
wxBitmap CreateBitmap(); wxBitmap CreateBitmapDot(); wxBitmap CreateBitmap(); wxBitmap CreateBitmapDot();
void PadGetStatus(); void Update(); void PadGetStatus(); void Update();
void UpdateGUIKeys(int controller); void UpdateGUIButtonMapping(int controller);
void SaveButtonMapping(int controller, bool DontChangeId = false, int FromSlot = -1); void SaveButtonMapping(int controller, bool DontChangeId = false, int FromSlot = -1);
void SaveButtonMappingAll(int Slot); void SaveButtonMappingAll(int Slot);
void UpdateGUIAll(int Slot); void UpdateGUIAll(int Slot);

View File

@ -39,13 +39,13 @@
#include "../nJoy.h" #include "../nJoy.h"
#include "Images/controller.xpm" #include "Images/controller.xpm"
extern bool emulator_running; extern bool g_EmulatorRunning;
//////////////////////// ////////////////////////
// Set dialog items from saved values // Set dialog items from saved values
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void ConfigBox::UpdateGUIKeys(int controller) void ConfigBox::UpdateGUIButtonMapping(int controller)
{ {
// http://wiki.wxwidgets.org/Converting_everything_to_and_from_wxString // http://wiki.wxwidgets.org/Converting_everything_to_and_from_wxString
wxString tmp; wxString tmp;
@ -56,22 +56,22 @@ void ConfigBox::UpdateGUIKeys(int controller)
// Update the enabled checkbox // Update the enabled checkbox
m_Joyattach[controller]->SetValue(PadMapping[controller].enabled == 1 ? true : false); m_Joyattach[controller]->SetValue(PadMapping[controller].enabled == 1 ? true : false);
tmp << PadMapping[controller].buttons[CTL_L_SHOULDER]; m_JoyShoulderL[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_L_SHOULDER]; m_JoyShoulderL[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_R_SHOULDER]; m_JoyShoulderR[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_R_SHOULDER]; m_JoyShoulderR[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_A_BUTTON]; m_JoyButtonA[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_A_BUTTON]; m_JoyButtonA[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_B_BUTTON]; m_JoyButtonB[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_B_BUTTON]; m_JoyButtonB[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_X_BUTTON]; m_JoyButtonX[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_X_BUTTON]; m_JoyButtonX[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_Y_BUTTON]; m_JoyButtonY[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_Y_BUTTON]; m_JoyButtonY[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_Z_TRIGGER]; m_JoyButtonZ[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_Z_TRIGGER]; m_JoyButtonZ[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[CTL_START]; m_JoyButtonStart[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_START]; m_JoyButtonStart[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].halfpress; m_JoyButtonHalfpress[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].halfpress; m_JoyButtonHalfpress[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[CTL_MAIN_X]; m_JoyAnalogMainX[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].axis[InputCommon::CTL_MAIN_X]; m_JoyAnalogMainX[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[CTL_MAIN_Y]; m_JoyAnalogMainY[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].axis[InputCommon::CTL_MAIN_Y]; m_JoyAnalogMainY[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[CTL_SUB_X]; m_JoyAnalogSubX[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].axis[InputCommon::CTL_SUB_X]; m_JoyAnalogSubX[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[CTL_SUB_Y]; m_JoyAnalogSubY[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].axis[InputCommon::CTL_SUB_Y]; m_JoyAnalogSubY[controller]->SetValue(tmp); tmp.clear();
// Update the deadzone and controller type controls // Update the deadzone and controller type controls
m_ControlType[controller]->SetSelection(PadMapping[controller].controllertype); m_ControlType[controller]->SetSelection(PadMapping[controller].controllertype);
@ -79,20 +79,21 @@ void ConfigBox::UpdateGUIKeys(int controller)
m_Deadzone[controller]->SetSelection(PadMapping[controller].deadzone); m_Deadzone[controller]->SetSelection(PadMapping[controller].deadzone);
m_CoBDiagonal[controller]->SetValue(wxString::FromAscii(PadMapping[controller].SDiagonal.c_str())); m_CoBDiagonal[controller]->SetValue(wxString::FromAscii(PadMapping[controller].SDiagonal.c_str()));
m_CBS_to_C[controller]->SetValue(PadMapping[controller].bSquareToCircle); m_CBS_to_C[controller]->SetValue(PadMapping[controller].bSquareToCircle);
m_AdvancedMapFilter[controller]->SetValue(g_Config.bNoTriggerFilter);
//LogMsg("m_TriggerType[%i] = %i\n", controller, PadMapping[controller].triggertype); //LogMsg("m_TriggerType[%i] = %i\n", controller, PadMapping[controller].triggertype);
// Update D-Pad // Update D-Pad
if(PadMapping[controller].controllertype == CTL_DPAD_HAT) if(PadMapping[controller].controllertype == InputCommon::CTL_DPAD_HAT)
{ {
tmp << PadMapping[controller].dpad; m_JoyDpadUp[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].dpad; m_JoyDpadDown[controller]->SetValue(tmp); tmp.clear();
} }
else else
{ {
tmp << PadMapping[controller].dpad2[CTL_D_PAD_UP]; m_JoyDpadUp[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_UP]; m_JoyDpadUp[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad2[CTL_D_PAD_DOWN]; m_JoyDpadDown[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_DOWN]; m_JoyDpadDown[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad2[CTL_D_PAD_LEFT]; m_JoyDpadLeft[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_LEFT]; m_JoyDpadLeft[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad2[CTL_D_PAD_RIGHT]; m_JoyDpadRight[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_RIGHT]; m_JoyDpadRight[controller]->SetValue(tmp); tmp.clear();
} }
// Replace "-1" with "" in the GUI controls // Replace "-1" with "" in the GUI controls
@ -121,25 +122,25 @@ void ConfigBox::SaveButtonMapping(int controller, bool DontChangeId, int FromSlo
PadMapping[controller].triggertype = m_TriggerType[FromSlot]->GetSelection(); PadMapping[controller].triggertype = m_TriggerType[FromSlot]->GetSelection();
PadMapping[controller].deadzone = m_Deadzone[FromSlot]->GetSelection(); PadMapping[controller].deadzone = m_Deadzone[FromSlot]->GetSelection();
PadMapping[controller].SDiagonal = m_CoBDiagonal[FromSlot]->GetLabel().mb_str(); PadMapping[controller].SDiagonal = m_CoBDiagonal[FromSlot]->GetLabel().mb_str();
PadMapping[controller].bSquareToCircle = m_CBS_to_C[FromSlot]->IsChecked(); PadMapping[controller].bSquareToCircle = m_CBS_to_C[FromSlot]->IsChecked();
// The analog buttons // The analog buttons
m_JoyAnalogMainX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[CTL_MAIN_X] = value; tmp.clear(); m_JoyAnalogMainX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_MAIN_X] = value; tmp.clear();
m_JoyAnalogMainY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[CTL_MAIN_Y] = value; tmp.clear(); m_JoyAnalogMainY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_MAIN_Y] = value; tmp.clear();
m_JoyAnalogSubX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[CTL_SUB_X] = value; tmp.clear(); m_JoyAnalogSubX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_SUB_X] = value; tmp.clear();
m_JoyAnalogSubY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[CTL_SUB_Y] = value; tmp.clear(); m_JoyAnalogSubY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_SUB_Y] = value; tmp.clear();
// The shoulder buttons // The shoulder buttons
m_JoyShoulderL[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_L_SHOULDER] = value; m_JoyShoulderL[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_L_SHOULDER] = value;
m_JoyShoulderR[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_R_SHOULDER] = value; m_JoyShoulderR[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_R_SHOULDER] = value;
// The digital buttons // The digital buttons
m_JoyButtonA[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_A_BUTTON] = value; tmp.clear(); m_JoyButtonA[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_A_BUTTON] = value; tmp.clear();
m_JoyButtonB[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_B_BUTTON] = value; tmp.clear(); m_JoyButtonB[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_B_BUTTON] = value; tmp.clear();
m_JoyButtonX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_X_BUTTON] = value; tmp.clear(); m_JoyButtonX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_X_BUTTON] = value; tmp.clear();
m_JoyButtonY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_Y_BUTTON] = value; tmp.clear(); m_JoyButtonY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_Y_BUTTON] = value; tmp.clear();
m_JoyButtonZ[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_Z_TRIGGER] = value; tmp.clear(); m_JoyButtonZ[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_Z_TRIGGER] = value; tmp.clear();
m_JoyButtonStart[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_START] = value; tmp.clear(); m_JoyButtonStart[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_START] = value; tmp.clear();
//LogMsg("PadMapping[%i].triggertype = %i, m_TriggerType[%i]->GetSelection() = %i\n", //LogMsg("PadMapping[%i].triggertype = %i, m_TriggerType[%i]->GetSelection() = %i\n",
// controller, PadMapping[controller].triggertype, FromSlot, m_TriggerType[FromSlot]->GetSelection()); // controller, PadMapping[controller].triggertype, FromSlot, m_TriggerType[FromSlot]->GetSelection());
@ -148,16 +149,16 @@ void ConfigBox::SaveButtonMapping(int controller, bool DontChangeId, int FromSlo
m_JoyButtonHalfpress[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].halfpress = value; tmp.clear(); m_JoyButtonHalfpress[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].halfpress = value; tmp.clear();
// The digital pad // The digital pad
if(PadMapping[controller].controllertype == CTL_DPAD_HAT) if(PadMapping[controller].controllertype == InputCommon::CTL_DPAD_HAT)
{ {
m_JoyDpadUp[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad = value; tmp.clear(); m_JoyDpadDown[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad = value; tmp.clear();
} }
else else
{ {
m_JoyDpadUp[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[CTL_D_PAD_UP] = value; tmp.clear(); m_JoyDpadUp[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_UP] = value; tmp.clear();
m_JoyDpadDown[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[CTL_D_PAD_DOWN] = value; tmp.clear(); m_JoyDpadDown[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_DOWN] = value; tmp.clear();
m_JoyDpadLeft[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[CTL_D_PAD_LEFT] = value; tmp.clear(); m_JoyDpadLeft[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_LEFT] = value; tmp.clear();
m_JoyDpadRight[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[CTL_D_PAD_RIGHT] = value; tmp.clear(); m_JoyDpadRight[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_RIGHT] = value; tmp.clear();
} }
// Replace "-1" with "" // Replace "-1" with ""
@ -244,21 +245,6 @@ wxString ConfigBox::GetButtonText(int id, int Page)
// ¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯
// Avoid extreme axis values
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Function: We have to avoid very big values to becuse some triggers are -0x8000 in the
unpressed state (and then go from -0x8000 to 0x8000 as they are fully pressed) */
bool AvoidValues(int value)
{
// Avoid detecting very small or very big (for triggers) values
if( (value > -0x2000 && value < 0x2000) // Small values
|| (value < -0x6000 || value > 0x6000)) // Big values
return true; // Avoid
else
return false; // Keep
}
// Wait for button press // Wait for button press
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Loop or timer: There are basically two ways to do this. With a while() or for() loop, or with a /* Loop or timer: There are basically two ways to do this. With a while() or for() loop, or with a
@ -271,6 +257,7 @@ void ConfigBox::GetButtons(wxCommandEvent& event)
{ {
DoGetButtons(event.GetId()); DoGetButtons(event.GetId());
} }
void ConfigBox::DoGetButtons(int GetId) void ConfigBox::DoGetButtons(int GetId)
{ {
// ============================================= // =============================================
@ -279,6 +266,17 @@ void ConfigBox::DoGetButtons(int GetId)
// Get the current controller // Get the current controller
int Controller = notebookpage; int Controller = notebookpage;
int PadID = PadMapping[Controller].ID;
// Create a shortcut for the pad handle
SDL_Joystick *joy = PadState[Controller].joy;
// Get the number of axes, hats and buttons
int Buttons = SDL_JoystickNumButtons(joy);
int Axes = SDL_JoystickNumAxes(joy);
int Hats = SDL_JoystickNumHats(joy);
Console::Print("PadID: %i Axes: %i\n", PadID, joyinfo[PadID].NumAxes, joyinfo[PadID].joy);
// Get the controller and trigger type // Get the controller and trigger type
int ControllerType = PadMapping[Controller].controllertype; int ControllerType = PadMapping[Controller].controllertype;
@ -288,35 +286,30 @@ void ConfigBox::DoGetButtons(int GetId)
bool LeftRight = (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R); bool LeftRight = (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R);
bool Axis = (GetId >= IDB_ANALOG_MAIN_X && GetId <= IDB_SHOULDER_R) bool Axis = (GetId >= IDB_ANALOG_MAIN_X && GetId <= IDB_SHOULDER_R)
&& !(TriggerType == CTL_TRIGGER_XINPUT && (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) ); // Don't allow SDL here && !(TriggerType == InputCommon::CTL_TRIGGER_XINPUT && (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) ); // Don't allow SDL here
bool XInput = (TriggerType == CTL_TRIGGER_XINPUT); bool XInput = (TriggerType == InputCommon::CTL_TRIGGER_XINPUT);
bool Button = (GetId >= IDB_BUTTON_A && GetId <= IDB_BUTTONHALFPRESS) // All digital buttons bool Button = (GetId >= IDB_BUTTON_A && GetId <= IDB_BUTTONHALFPRESS) // All digital buttons
|| (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) // both shoulder buttons || (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) // both shoulder buttons
|| (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT && ControllerType == CTL_DPAD_CUSTOM); // Or the custom hat mode || (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT && ControllerType == InputCommon::CTL_DPAD_CUSTOM); // Or the custom hat mode
bool Hat = (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT) // All DPads bool Hat = (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT) // All DPads
&& (PadMapping[Controller].controllertype == CTL_DPAD_HAT); // Not with the hat option defined && (PadMapping[Controller].controllertype == InputCommon::CTL_DPAD_HAT); // Not with the hat option defined
/* Open a new joystick. Joysticks[controller].GetId is the system GetId of the physical joystick bool NoTriggerFilter = g_Config.bNoTriggerFilter;
that is mapped to controller, for example 0, 1, 2, 3 for the first four PadMapping */
SDL_Joystick *joy = SDL_JoystickOpen(PadMapping[Controller].ID);
// Get the number of axes, hats and buttons // Values used in this function
int buttons = SDL_JoystickNumButtons(joy);
int axes = SDL_JoystickNumAxes(joy);
int hats = SDL_JoystickNumHats(joy);
// Declare values
char format[128]; char format[128];
int value; // Axis value
int type; // Button type
bool Succeed = false;
bool Stop = false; // Stop the timer
int pressed = 0;
int Seconds = 4; // Seconds to wait for int Seconds = 4; // Seconds to wait for
int TimesPerSecond = 40; // How often to run the check int TimesPerSecond = 40; // How often to run the check
// Values returned from InputCommon::GetButton()
int value; // Axis value
int type; // Button type
int pressed = 0;
bool Succeed = false;
bool Stop = false; // Stop the timer
// ======================= // =======================
//Console::Print("Before (%i) Id:%i %i IsRunning:%i\n", //Console::Print("Before (%i) Id:%i %i IsRunning:%i\n",
@ -357,90 +350,10 @@ void ConfigBox::DoGetButtons(int GetId)
// If there is a timer but we should not create a new one // If there is a timer but we should not create a new one
else else
{ {
// Update the internal status InputCommon::GetButton(
SDL_JoystickUpdate(); joy, PadID, Buttons, Axes, Hats,
g_Pressed, value, type, pressed, Succeed, Stop,
// For the triggers we accept both a digital or an analog button LeftRight, Axis, XInput, Button, Hat, NoTriggerFilter);
if(Axis)
{
for(int i = 0; i < axes; i++)
{
value = SDL_JoystickGetAxis(joy, i);
if(AvoidValues(value)) continue; // Avoid values
pressed = i + (LeftRight ? 1000 : 0); // Identify the analog triggers
type = CTL_AXIS;
Succeed = true;
}
}
// Check for a hat
if(Hat)
{
for(int i = 0; i < hats; i++)
{
if(SDL_JoystickGetHat(joy, i))
{
pressed = i;
type = CTL_HAT;
Succeed = true;
}
}
}
// Check for a button
if(Button)
{
for(int i = 0; i < buttons; i++)
{
// Some kind of bug in SDL 1.3 would give button 9 and 10 (nonexistent) the value 48 on the 360 pad
if (SDL_JoystickGetButton(joy, i) > 1) continue;
if(SDL_JoystickGetButton(joy, i))
{
pressed = i;
type = CTL_BUTTON;
Succeed = true;
}
}
}
// Check for a XInput trigger
#ifdef _WIN32
if(XInput)
{
for(int i = 0; i <= XI_TRIGGER_R; i++)
{
if(XInput::GetXI(0, i))
{
pressed = i + 1000;
type = CTL_AXIS;
Succeed = true;
}
}
}
#endif
// Check for keyboard action
if (g_Pressed && Button)
{
// Todo: Add a separate keyboard vector to remove this restriction
if(g_Pressed >= buttons)
{
pressed = g_Pressed;
type = CTL_BUTTON;
Succeed = true;
g_Pressed = 0;
if(pressed == WXK_ESCAPE) pressed = -1; // Check for the exape key
}
else
{
pressed = g_Pressed;
g_Pressed = -1;
Stop = true;
}
}
} }
// ========================= Check for keys // ========================= Check for keys
@ -507,9 +420,6 @@ void ConfigBox::DoGetButtons(int GetId)
} }
// ======================== Process results // ======================== Process results
// We don't need this gamepad handle any more
if(SDL_JoystickOpened(PadMapping[Controller].ID)) SDL_JoystickClose(joy);
// Debugging // Debugging
/* /*
Console::Print("Change: %i %i %i %i '%s' '%s' '%s' '%s'\n", Console::Print("Change: %i %i %i %i '%s' '%s' '%s' '%s'\n",
@ -517,5 +427,4 @@ void ConfigBox::DoGetButtons(int GetId)
m_JoyButtonHalfpress[0]->GetValue().c_str(), m_JoyButtonHalfpress[1]->GetValue().c_str(), m_JoyButtonHalfpress[2]->GetValue().c_str(), m_JoyButtonHalfpress[3]->GetValue().c_str() m_JoyButtonHalfpress[0]->GetValue().c_str(), m_JoyButtonHalfpress[1]->GetValue().c_str(), m_JoyButtonHalfpress[2]->GetValue().c_str(), m_JoyButtonHalfpress[3]->GetValue().c_str()
);*/ );*/
} }
/////////////////////////////////////////////////////////// Configure button mapping /////////////////////////////////////////////////////////// Configure button mapping

View File

@ -25,7 +25,7 @@ if padenv['HAVE_WX']:
padenv.Append( padenv.Append(
CXXFLAGS = [ '-fPIC' ], CXXFLAGS = [ '-fPIC' ],
LIBS = [ 'common' ], LIBS = [ 'common', 'inputcommon' ],
) )
padenv.SharedLibrary(env['plugin_dir']+name, files) padenv.SharedLibrary(env['plugin_dir']+name, files)

View File

@ -81,13 +81,13 @@
// ¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯
// Rumble in windows // Rumble in windows
#define _CONTROLLER_STATE_H // Avoid certain declarations in nJoy.h #define _EXCLUDE_MAIN_ // Avoid certain declarations in nJoy.h
FILE *pFile; FILE *pFile;
HINSTANCE nJoy_hInst = NULL; HINSTANCE nJoy_hInst = NULL;
std::vector<CONTROLLER_INFO> joyinfo; std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
CONTROLLER_STATE PadState[4]; InputCommon::CONTROLLER_STATE PadState[4];
CONTROLLER_MAPPING PadMapping[4]; InputCommon::CONTROLLER_MAPPING PadMapping[4];
bool emulator_running = false; bool g_EmulatorRunning = false;
int NumPads = 0, NumGoodPads = 0; int NumPads = 0, NumGoodPads = 0;
HWND m_hWnd; // Handle to window HWND m_hWnd; // Handle to window
SPADInitialize *g_PADInitialize = NULL; SPADInitialize *g_PADInitialize = NULL;
@ -191,9 +191,9 @@ void DllConfig(HWND _hParent)
#ifdef _WIN32 #ifdef _WIN32
// Start the pads so we can use them in the configuration and advanced controls // Start the pads so we can use them in the configuration and advanced controls
if(!emulator_running) if(!g_EmulatorRunning)
{ {
NumPads = Search_Devices(); // Populate joyinfo for all attached devices Search_Devices(joyinfo, NumPads, NumGoodPads); // Populate joyinfo for all attached devices
} }
m_frame = new ConfigBox(NULL); m_frame = new ConfigBox(NULL);
@ -232,7 +232,7 @@ void DllDebugger(HWND _hParent, bool Show) {}
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Information: This function can not be run twice without a Shutdown in between. If /* Information: This function can not be run twice without a Shutdown in between. If
it's run twice the SDL_Init() will cause a crash. One solution to this is to keep a it's run twice the SDL_Init() will cause a crash. One solution to this is to keep a
global function that remembers the SDL_Init() and SDL_Quit() (emulator_running does global function that remembers the SDL_Init() and SDL_Quit() (g_EmulatorRunning does
not do that since we can open and close this without any game running). But I would not do that since we can open and close this without any game running). But I would
suggest that avoiding to run this twice from the Core is better. */ suggest that avoiding to run this twice from the Core is better. */
void Initialize(void *init) void Initialize(void *init)
@ -241,7 +241,7 @@ void Initialize(void *init)
//Console::Open(); //Console::Open();
Console::Print("Initialize: %i\n", SDL_WasInit(0)); Console::Print("Initialize: %i\n", SDL_WasInit(0));
g_PADInitialize = (SPADInitialize*)init; g_PADInitialize = (SPADInitialize*)init;
emulator_running = true; g_EmulatorRunning = true;
#ifdef _DEBUG #ifdef _DEBUG
DEBUG_INIT(); DEBUG_INIT();
@ -251,7 +251,7 @@ void Initialize(void *init)
m_hWnd = (HWND)g_PADInitialize->hWnd; m_hWnd = (HWND)g_PADInitialize->hWnd;
#endif #endif
NumPads = Search_Devices(); // Populate joyinfo for all attached devices Search_Devices(joyinfo, NumPads, NumGoodPads); // Populate joyinfo for all attached devices
/* Check if any of the pads failed to open. In Windows there is a strange "IDirectInputDevice2:: /* Check if any of the pads failed to open. In Windows there is a strange "IDirectInputDevice2::
SetDataFormat() DirectX error -2147024809" after a few Open and Close */ SetDataFormat() DirectX error -2147024809" after a few Open and Close */
@ -265,79 +265,15 @@ void Initialize(void *init)
} }
} }
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
// Search attached devices. Populate joyinfo for all attached physical devices.
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
int Search_Devices()
{ {
// Load config bool Success = InputCommon::SearchDevices(_joyinfo, _NumPads, _NumGoodPads);
#ifdef _DEBUG
DEBUG_INIT();
#endif
/* SDL 1.3 use DirectInput instead of the old Microsoft Multimeda API, and with this we need
the SDL_INIT_VIDEO flag to */
if (!SDL_WasInit(0))
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0)
{
PanicAlert("Could not initialize SDL: %s", SDL_GetError());
return 0;
}
#ifdef _DEBUG
fprintf(pFile, "Scanning for devices\n");
fprintf(pFile, "¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n");
#endif
// Get device status
int numjoy = SDL_NumJoysticks();
for (int i = 0; i < numjoy; i++ )
{
CONTROLLER_INFO Tmp;
Tmp.joy = SDL_JoystickOpen(i);
Tmp.ID = i;
Tmp.NumAxes = SDL_JoystickNumAxes(Tmp.joy);
Tmp.NumButtons = SDL_JoystickNumButtons(Tmp.joy);
Tmp.NumBalls = SDL_JoystickNumBalls(Tmp.joy);
Tmp.NumHats = SDL_JoystickNumHats(Tmp.joy);
Tmp.Name = SDL_JoystickName(i);
// Check if the device is okay
if ( Tmp.NumAxes == 0
&& Tmp.NumBalls == 0
&& Tmp.NumButtons == 0
&& Tmp.NumHats == 0
)
{
Tmp.Good = false;
}
else
{
NumGoodPads++;
Tmp.Good = true;
}
joyinfo.push_back(Tmp);
#ifdef _DEBUG
fprintf(pFile, "ID: %d\n", i);
fprintf(pFile, "Name: %s\n", joyinfo[i].Name);
fprintf(pFile, "Buttons: %d\n", joyinfo[i].NumButtons);
fprintf(pFile, "Axes: %d\n", joyinfo[i].NumAxes);
fprintf(pFile, "Hats: %d\n", joyinfo[i].NumHats);
fprintf(pFile, "Balls: %d\n\n", joyinfo[i].NumBalls);
#endif
// We have now read the values we need so we close the device
if (SDL_JoystickOpened(i)) SDL_JoystickClose(joyinfo[i].joy);
}
// Warn the user if no gamepads are detected // Warn the user if no gamepads are detected
if (NumGoodPads == 0 && emulator_running) if (_NumGoodPads == 0 && g_EmulatorRunning)
{ {
PanicAlert("nJoy: No Gamepad Detected"); PanicAlert("nJoy: No Gamepad Detected");
return joyinfo.size(); return false;
} }
// Load PadMapping[] etc // Load PadMapping[] etc
@ -351,7 +287,7 @@ int Search_Devices()
PadState[i].joy = SDL_JoystickOpen(PadMapping[i].ID); PadState[i].joy = SDL_JoystickOpen(PadMapping[i].ID);
} }
return joyinfo.size(); return Success;
} }
// Shutdown PAD (stop emulation) // Shutdown PAD (stop emulation)
@ -372,18 +308,17 @@ void Shutdown()
if(SDL_JoystickOpened(PadMapping[i].ID)) SDL_JoystickClose(PadState[i].joy); if(SDL_JoystickOpened(PadMapping[i].ID)) SDL_JoystickClose(PadState[i].joy);
} }
SDL_Quit(); // Clear the physical device info
joyinfo.clear();
// Finally close SDL
if (SDL_WasInit(0)) SDL_Quit();
#ifdef _DEBUG #ifdef _DEBUG
DEBUG_QUIT(); DEBUG_QUIT();
#endif #endif
// Clear the physical device info g_EmulatorRunning = false;
//delete [] joyinfo;
//joyinfo = NULL;
joyinfo.clear();
emulator_running = false;
#ifdef _WIN32 #ifdef _WIN32
#ifdef USE_RUMBLE_DINPUT_HACK #ifdef USE_RUMBLE_DINPUT_HACK
@ -405,13 +340,13 @@ void PAD_Input(u16 _Key, u8 _UpDown)
// Check if the keys are interesting, and then update it // Check if the keys are interesting, and then update it
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
{ {
for(int j = CTL_L_SHOULDER; j <= CTL_START; j++) for(int j = InputCommon::CTL_L_SHOULDER; j <= InputCommon::CTL_START; j++)
{ {
if (PadMapping[i].buttons[j] == _Key) if (PadMapping[i].buttons[j] == _Key)
{ PadState[i].buttons[j] = _UpDown; break; } { PadState[i].buttons[j] = _UpDown; break; }
} }
for(int j = CTL_D_PAD_UP; j <= CTL_D_PAD_RIGHT; j++) for(int j = InputCommon::CTL_D_PAD_UP; j <= InputCommon::CTL_D_PAD_RIGHT; j++)
{ {
if (PadMapping[i].dpad2[j] == _Key) if (PadMapping[i].dpad2[j] == _Key)
{ PadState[i].dpad2[j] = _UpDown; break; } { PadState[i].dpad2[j] = _UpDown; break; }
@ -461,8 +396,9 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
// Clear pad status // Clear pad status
memset(_pPADStatus, 0, sizeof(SPADStatus)); memset(_pPADStatus, 0, sizeof(SPADStatus));
// Update the pad status // Check that Dolphin is in focus, otherwise don't update the pad status
GetJoyState(_numPAD); if (!g_Config.bCheckFocus && IsFocus())
GetJoyState(PadState[_numPAD], PadMapping[_numPAD], _numPAD, joyinfo[PadMapping[_numPAD].ID].NumButtons);
// Get type // Get type
int TriggerType = PadMapping[_numPAD].triggertype; int TriggerType = PadMapping[_numPAD].triggertype;
@ -472,32 +408,32 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
// ----------- // -----------
// Read axis values // Read axis values
int i_main_stick_x = PadState[_numPAD].axis[CTL_MAIN_X]; int i_main_stick_x = PadState[_numPAD].axis[InputCommon::CTL_MAIN_X];
int i_main_stick_y = -PadState[_numPAD].axis[CTL_MAIN_Y]; int i_main_stick_y = -PadState[_numPAD].axis[InputCommon::CTL_MAIN_Y];
int i_sub_stick_x = PadState[_numPAD].axis[CTL_SUB_X]; int i_sub_stick_x = PadState[_numPAD].axis[InputCommon::CTL_SUB_X];
int i_sub_stick_y = -PadState[_numPAD].axis[CTL_SUB_Y]; int i_sub_stick_y = -PadState[_numPAD].axis[InputCommon::CTL_SUB_Y];
int TriggerLeft = PadState[_numPAD].axis[CTL_L_SHOULDER]; int TriggerLeft = PadState[_numPAD].axis[InputCommon::CTL_L_SHOULDER];
int TriggerRight = PadState[_numPAD].axis[CTL_R_SHOULDER]; int TriggerRight = PadState[_numPAD].axis[InputCommon::CTL_R_SHOULDER];
// Check if we should make adjustments // Check if we should make adjustments
if(PadMapping[_numPAD].bSquareToCircle) if(PadMapping[_numPAD].bSquareToCircle)
{ {
std::vector<int> main_xy = Pad_Square_to_Circle(i_main_stick_x, i_main_stick_y, _numPAD); std::vector<int> main_xy = InputCommon::Pad_Square_to_Circle(i_main_stick_x, i_main_stick_y, _numPAD, PadMapping[_numPAD]);
i_main_stick_x = main_xy.at(0); i_main_stick_x = main_xy.at(0);
i_main_stick_y = main_xy.at(1); i_main_stick_y = main_xy.at(1);
} }
// Convert axis values // Convert axis values
u8 main_stick_x = Pad_Convert(i_main_stick_x); u8 main_stick_x = InputCommon::Pad_Convert(i_main_stick_x);
u8 main_stick_y = Pad_Convert(i_main_stick_y); u8 main_stick_y = InputCommon::Pad_Convert(i_main_stick_y);
u8 sub_stick_x = Pad_Convert(i_sub_stick_x); u8 sub_stick_x = InputCommon::Pad_Convert(i_sub_stick_x);
u8 sub_stick_y = Pad_Convert(i_sub_stick_y); u8 sub_stick_y = InputCommon::Pad_Convert(i_sub_stick_y);
// Convert the triggers values, if we are using analog triggers at all // Convert the triggers values, if we are using analog triggers at all
if(PadMapping[_numPAD].triggertype == CTL_TRIGGER_SDL) if(PadMapping[_numPAD].triggertype == InputCommon::CTL_TRIGGER_SDL)
{ {
if(PadMapping[_numPAD].buttons[CTL_L_SHOULDER] >= 1000) TriggerLeft = Pad_Convert(TriggerLeft); if(PadMapping[_numPAD].buttons[InputCommon::CTL_L_SHOULDER] >= 1000) TriggerLeft = InputCommon::Pad_Convert(TriggerLeft);
if(PadMapping[_numPAD].buttons[CTL_R_SHOULDER] >= 1000) TriggerRight = Pad_Convert(TriggerRight); if(PadMapping[_numPAD].buttons[InputCommon::CTL_R_SHOULDER] >= 1000) TriggerRight = InputCommon::Pad_Convert(TriggerRight);
} }
// Set Deadzones (perhaps out of function?) // Set Deadzones (perhaps out of function?)
@ -520,7 +456,7 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
_pPADStatus->button |= PAD_USE_ORIGIN; // Neutral value, no button pressed _pPADStatus->button |= PAD_USE_ORIGIN; // Neutral value, no button pressed
// Check if the digital L button is pressed // Check if the digital L button is pressed
if (PadState[_numPAD].buttons[CTL_L_SHOULDER]) if (PadState[_numPAD].buttons[InputCommon::CTL_L_SHOULDER])
{ {
_pPADStatus->button |= PAD_TRIGGER_L; _pPADStatus->button |= PAD_TRIGGER_L;
_pPADStatus->triggerLeft = TriggerValue; _pPADStatus->triggerLeft = TriggerValue;
@ -529,7 +465,7 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
_pPADStatus->triggerLeft = TriggerLeft; _pPADStatus->triggerLeft = TriggerLeft;
// Check if the digital R button is pressed // Check if the digital R button is pressed
if (PadState[_numPAD].buttons[CTL_R_SHOULDER]) if (PadState[_numPAD].buttons[InputCommon::CTL_R_SHOULDER])
{ {
_pPADStatus->button |= PAD_TRIGGER_R; _pPADStatus->button |= PAD_TRIGGER_R;
_pPADStatus->triggerRight = TriggerValue; _pPADStatus->triggerRight = TriggerValue;
@ -545,26 +481,26 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
// The digital buttons // The digital buttons
// ----------- // -----------
if (PadState[_numPAD].buttons[CTL_A_BUTTON]) if (PadState[_numPAD].buttons[InputCommon::CTL_A_BUTTON])
{ {
_pPADStatus->button |= PAD_BUTTON_A; _pPADStatus->button |= PAD_BUTTON_A;
_pPADStatus->analogA = 255; // Perhaps support pressure? _pPADStatus->analogA = 255; // Perhaps support pressure?
} }
if (PadState[_numPAD].buttons[CTL_B_BUTTON]) if (PadState[_numPAD].buttons[InputCommon::CTL_B_BUTTON])
{ {
_pPADStatus->button |= PAD_BUTTON_B; _pPADStatus->button |= PAD_BUTTON_B;
_pPADStatus->analogB = 255; // Perhaps support pressure? _pPADStatus->analogB = 255; // Perhaps support pressure?
} }
if (PadState[_numPAD].buttons[CTL_X_BUTTON]) _pPADStatus->button|=PAD_BUTTON_X; if (PadState[_numPAD].buttons[InputCommon::CTL_X_BUTTON]) _pPADStatus->button|=PAD_BUTTON_X;
if (PadState[_numPAD].buttons[CTL_Y_BUTTON]) _pPADStatus->button|=PAD_BUTTON_Y; if (PadState[_numPAD].buttons[InputCommon::CTL_Y_BUTTON]) _pPADStatus->button|=PAD_BUTTON_Y;
if (PadState[_numPAD].buttons[CTL_Z_TRIGGER]) _pPADStatus->button|=PAD_TRIGGER_Z; if (PadState[_numPAD].buttons[InputCommon::CTL_Z_TRIGGER]) _pPADStatus->button|=PAD_TRIGGER_Z;
if (PadState[_numPAD].buttons[CTL_START]) _pPADStatus->button|=PAD_BUTTON_START; if (PadState[_numPAD].buttons[InputCommon::CTL_START]) _pPADStatus->button|=PAD_BUTTON_START;
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
// The D-pad // The D-pad
// ----------- // -----------
if (PadMapping[_numPAD].controllertype == CTL_DPAD_HAT) if (PadMapping[_numPAD].controllertype == InputCommon::CTL_DPAD_HAT)
{ {
if (PadState[_numPAD].dpad == SDL_HAT_LEFTUP || PadState[_numPAD].dpad == SDL_HAT_UP || PadState[_numPAD].dpad == SDL_HAT_RIGHTUP ) _pPADStatus->button|=PAD_BUTTON_UP; if (PadState[_numPAD].dpad == SDL_HAT_LEFTUP || PadState[_numPAD].dpad == SDL_HAT_UP || PadState[_numPAD].dpad == SDL_HAT_RIGHTUP ) _pPADStatus->button|=PAD_BUTTON_UP;
if (PadState[_numPAD].dpad == SDL_HAT_LEFTUP || PadState[_numPAD].dpad == SDL_HAT_LEFT || PadState[_numPAD].dpad == SDL_HAT_LEFTDOWN ) _pPADStatus->button|=PAD_BUTTON_LEFT; if (PadState[_numPAD].dpad == SDL_HAT_LEFTUP || PadState[_numPAD].dpad == SDL_HAT_LEFT || PadState[_numPAD].dpad == SDL_HAT_LEFTDOWN ) _pPADStatus->button|=PAD_BUTTON_LEFT;
@ -573,13 +509,13 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
} }
else else
{ {
if (PadState[_numPAD].dpad2[CTL_D_PAD_UP]) if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_UP])
_pPADStatus->button |= PAD_BUTTON_UP; _pPADStatus->button |= PAD_BUTTON_UP;
if (PadState[_numPAD].dpad2[CTL_D_PAD_DOWN]) if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_DOWN])
_pPADStatus->button |= PAD_BUTTON_DOWN; _pPADStatus->button |= PAD_BUTTON_DOWN;
if (PadState[_numPAD].dpad2[CTL_D_PAD_LEFT]) if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_LEFT])
_pPADStatus->button |= PAD_BUTTON_LEFT; _pPADStatus->button |= PAD_BUTTON_LEFT;
if (PadState[_numPAD].dpad2[CTL_D_PAD_RIGHT]) if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_RIGHT])
_pPADStatus->button |= PAD_BUTTON_RIGHT; _pPADStatus->button |= PAD_BUTTON_RIGHT;
} }
@ -645,226 +581,7 @@ bool IsFocus()
} }
//////////////////////////////////////////////////////////////////////////////////////////
// Convert stick values
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Convert stick values.
The value returned by SDL_JoystickGetAxis is a signed integer s16
(-32768 to 32767). The value used for the gamecube controller is an unsigned
char u8 (0 to 255) with neutral at 0x80 (128), so that it's equivalent to a signed
-128 to 127.
*/
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
int Pad_Convert(int _val)
{
/* If the limits on PadState[].axis[] actually is a u16 then we don't need this
but if it's not actually limited to that we need to apply these limits */
if(_val > 32767) _val = 32767; // upper limit
if(_val < -32768) _val = -32768; // lower limit
// Convert the range (-0x8000 to 0x7fff) to (0 to 0xffff)
_val = 0x8000 +_val;
// Convert the range (-32768 to 32767) to (-128 to 127)
_val = _val >> 8;
//Console::Print("0x%04x %06i\n\n", _val, _val);
return _val;
}
/* Convert the stick raidus from a circular to a square. I don't know what input values
the actual GC controller produce for the GC, it may be a square, a circle or something
in between. But one thing that is certain is that PC pads differ in their output (as
shown in the list below), so it may be beneficiary to convert whatever radius they
produce to the radius the GC games expect. This is the first implementation of this
that convert a square radius to a circual radius. Use the advanced settings to enable
and calibrate it.
Observed diagonals:
Perfect circle: 71% = sin(45)
Logitech Dual Action: 100%
Dual Shock 2 (Original) with Super Dual Box Pro: 90%
XBox 360 Wireless: 85%
GameCube Controller (Third Party) with EMS TrioLinker Plus II: 60%
*/
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
float SquareDistance(float deg)
{
// See if we have to adjust the angle
deg = abs(deg);
if( (deg > 45 && deg < 135) ) deg = deg - 90;
float rad = deg * M_PI / 180;
float val = abs(cos(rad));
float dist = 1 / val; // Calculate distance from center
//m_frame->m_pStatusBar2->SetLabel(wxString::Format("Deg:%f Val:%f Dist:%f", deg, val, dist));
return dist;
}
std::vector<int> Pad_Square_to_Circle(int _x, int _y, int _pad)
{
/* Do we need this? */
if(_x > 32767) _x = 32767; if(_y > 32767) _y = 32767; // upper limit
if(_x < -32768) _x = -32768; if(_y > 32767) _y = 32767; // lower limit
// ====================================
// Convert to circle
// -----------
int Tmp = atoi (PadMapping[_pad].SDiagonal.substr(0, PadMapping[_pad].SDiagonal.length() - 1).c_str());
float Diagonal = Tmp / 100.0;
// First make a perfect square in case we don't have one already
float OrigDist = sqrt( pow((float)_y, 2) + pow((float)_x, 2) ); // Get current distance
float rad = atan2((float)_y, (float)_x); // Get current angle
float deg = rad * 180 / M_PI;
// A diagonal of 85% means a distance of 1.20
float corner_circle_dist = ( Diagonal / sin(45 * M_PI / 180) );
float SquareDist = SquareDistance(deg);
float adj_ratio1; // The original-to-square distance adjustment
float adj_ratio2 = SquareDist; // The circle-to-square distance adjustment
// float final_ratio; // The final adjustment to the current distance //TODO: This is not used
float result_dist; // The resulting distance
// Calculate the corner-to-square adjustment ratio
if(corner_circle_dist < SquareDist) adj_ratio1 = SquareDist / corner_circle_dist;
else adj_ratio1 = 1;
// Calculate the resulting distance
result_dist = OrigDist * adj_ratio1 / adj_ratio2;
float x = result_dist * cos(rad); // calculate x
float y = result_dist * sin(rad); // calculate y
int int_x = (int)floor(x);
int int_y = (int)floor(y);
// Debugging
//m_frame->m_pStatusBar2->SetLabel(wxString::Format("%f %f %i", corner_circle_dist, Diagonal, Tmp));
std::vector<int> vec;
vec.push_back(int_x);
vec.push_back(int_y);
return vec;
}
///////////////////////////////////////////////////////////////////// Convert stick values
//////////////////////////////////////////////////////////////////////////////////////////
// Supporting functions
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Read current joystick status
/* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
The value PadMapping[].buttons[] is the number of the assigned joypad button,
PadState[].buttons[] is the status of the button, it becomes 0 (no pressed) or 1 (pressed) */
// Read buttons status. Called from GetJoyState().
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void ReadButton(int controller, int button)
{
int ctl_button = PadMapping[controller].buttons[button];
if (ctl_button < joyinfo[PadMapping[controller].ID].NumButtons)
{
PadState[controller].buttons[button] = SDL_JoystickGetButton(PadState[controller].joy, ctl_button);
}
}
// Request joystick state.
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Called from: PAD_GetStatus()
Input: The virtual device 0, 1, 2 or 3
Function: Updates the PadState struct with the current pad status. The input value "controller" is
for a virtual controller 0 to 3. */
void GetJoyState(int controller)
{
// Check that Dolphin is in focus, otherwise don't update the pad status
if (!g_Config.bCheckFocus && !IsFocus()) return;
// Update the gamepad status
SDL_JoystickUpdate();
// Save the number of buttons
int Buttons = joyinfo[PadMapping[controller].ID].NumButtons;
// Update axis states. It doesn't hurt much if we happen to ask for nonexisting axises here.
PadState[controller].axis[CTL_MAIN_X] = SDL_JoystickGetAxis(PadState[controller].joy, PadMapping[controller].axis[CTL_MAIN_X]);
PadState[controller].axis[CTL_MAIN_Y] = SDL_JoystickGetAxis(PadState[controller].joy, PadMapping[controller].axis[CTL_MAIN_Y]);
PadState[controller].axis[CTL_SUB_X] = SDL_JoystickGetAxis(PadState[controller].joy, PadMapping[controller].axis[CTL_SUB_X]);
PadState[controller].axis[CTL_SUB_Y] = SDL_JoystickGetAxis(PadState[controller].joy, PadMapping[controller].axis[CTL_SUB_Y]);
// Update the analog trigger axis values
#ifdef _WIN32
if (PadMapping[controller].triggertype == CTL_TRIGGER_SDL)
{
#endif
// If we are using SDL analog triggers the buttons have to be mapped as 1000 or up, otherwise they are not used
if(PadMapping[controller].buttons[CTL_L_SHOULDER] >= 1000) PadState[controller].axis[CTL_L_SHOULDER] = SDL_JoystickGetAxis(PadState[controller].joy, PadMapping[controller].buttons[CTL_L_SHOULDER] - 1000); else PadState[controller].axis[CTL_L_SHOULDER] = 0;
if(PadMapping[controller].buttons[CTL_R_SHOULDER] >= 1000) PadState[controller].axis[CTL_R_SHOULDER] = SDL_JoystickGetAxis(PadState[controller].joy, PadMapping[controller].buttons[CTL_R_SHOULDER] - 1000); else PadState[controller].axis[CTL_R_SHOULDER] = 0;
#ifdef _WIN32
}
else
{
PadState[controller].axis[CTL_L_SHOULDER] = XInput::GetXI(0, PadMapping[controller].buttons[CTL_L_SHOULDER] - 1000);
PadState[controller].axis[CTL_R_SHOULDER] = XInput::GetXI(0, PadMapping[controller].buttons[CTL_R_SHOULDER] - 1000);
}
#endif
// Update button states to on or off
ReadButton(controller, CTL_L_SHOULDER);
ReadButton(controller, CTL_R_SHOULDER);
ReadButton(controller, CTL_A_BUTTON);
ReadButton(controller, CTL_B_BUTTON);
ReadButton(controller, CTL_X_BUTTON);
ReadButton(controller, CTL_Y_BUTTON);
ReadButton(controller, CTL_Z_TRIGGER);
ReadButton(controller, CTL_START);
//
if (PadMapping[controller].halfpress < joyinfo[controller].NumButtons)
PadState[controller].halfpress = SDL_JoystickGetButton(PadState[controller].joy, PadMapping[controller].halfpress);
// Check if we have an analog or digital joypad
if (PadMapping[controller].controllertype == CTL_DPAD_HAT)
{
PadState[controller].dpad = SDL_JoystickGetHat(PadState[controller].joy, PadMapping[controller].dpad);
}
else
{
/* Only do this if the assigned button is in range (to allow for the current way of saving keyboard
keys in the same array) */
if(PadMapping[controller].dpad2[CTL_D_PAD_UP] <= Buttons)
PadState[controller].dpad2[CTL_D_PAD_UP] = SDL_JoystickGetButton(PadState[controller].joy, PadMapping[controller].dpad2[CTL_D_PAD_UP]);
if(PadMapping[controller].dpad2[CTL_D_PAD_DOWN] <= Buttons)
PadState[controller].dpad2[CTL_D_PAD_DOWN] = SDL_JoystickGetButton(PadState[controller].joy, PadMapping[controller].dpad2[CTL_D_PAD_DOWN]);
if(PadMapping[controller].dpad2[CTL_D_PAD_LEFT] <= Buttons)
PadState[controller].dpad2[CTL_D_PAD_LEFT] = SDL_JoystickGetButton(PadState[controller].joy, PadMapping[controller].dpad2[CTL_D_PAD_LEFT]);
if(PadMapping[controller].dpad2[CTL_D_PAD_RIGHT] <= Buttons)
PadState[controller].dpad2[CTL_D_PAD_RIGHT] = SDL_JoystickGetButton(PadState[controller].joy, PadMapping[controller].dpad2[CTL_D_PAD_RIGHT]);
}
/* Debugging
Console::ClearScreen();
Console::Print(
"Controller and handle: %i %i\n"
"Triggers:%i %i %i %i %i | HalfPress: %i Mapping: %i\n",
controller, (int)PadState[controller].joy,
PadMapping[controller].triggertype,
PadMapping[controller].buttons[CTL_L_SHOULDER], PadMapping[controller].buttons[CTL_R_SHOULDER],
PadState[controller].axis[CTL_L_SHOULDER], PadState[controller].axis[CTL_R_SHOULDER],
PadState[controller].halfpress, PadMapping[controller].halfpress
); */
}
//////////////////////////////////////////////////////////////////////////////////////////

View File

@ -35,6 +35,9 @@
// ¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯
// Set this if you want to use the rumble 'hack' for controller one // Set this if you want to use the rumble 'hack' for controller one
//#define USE_RUMBLE_DINPUT_HACK //#define USE_RUMBLE_DINPUT_HACK
// Show a status window with the detected axes, buttons and so on
//#define SHOW_PAD_STATUS
////////////////////////// //////////////////////////
@ -45,7 +48,9 @@
#include <cstdio> #include <cstdio>
#include <ctime> #include <ctime>
#include <cmath> #include <cmath>
#include <SDL.h>
#include "../../../Core/InputCommon/Src/SDL.h" // Core
#include "../../../Core/InputCommon/Src/XInput.h"
#include "Common.h" // Common #include "Common.h" // Common
#include "pluginspecs_pad.h" #include "pluginspecs_pad.h"
@ -54,7 +59,6 @@
//#include "Timer.h" //#include "Timer.h"
#include "Config.h" // Local #include "Config.h" // Local
#include "XInput.h"
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
#include "GUI/AboutBox.h" #include "GUI/AboutBox.h"
@ -102,115 +106,6 @@
#define THANKYOU "`plot`, Absolute0, Aprentice, Bositman, Brice, ChaosCode, CKemu, CoDeX, Dave2001, dn, drk||Raziel, Florin, Gent, Gigaherz, Hacktarux, JegHegy, Linker, Linuzappz, Martin64, Muad, Knuckles, Raziel, Refraction, Rudy_x, Shadowprince, Snake785, Saqib, vEX, yaz0r, Zilmar, Zenogais and ZeZu." #define THANKYOU "`plot`, Absolute0, Aprentice, Bositman, Brice, ChaosCode, CKemu, CoDeX, Dave2001, dn, drk||Raziel, Florin, Gent, Gigaherz, Hacktarux, JegHegy, Linker, Linuzappz, Martin64, Muad, Knuckles, Raziel, Refraction, Rudy_x, Shadowprince, Snake785, Saqib, vEX, yaz0r, Zilmar, Zenogais and ZeZu."
//////////////////////////////////////////////////////////////////////////////////////////
// Structures
/* ¯¯¯¯¯¯¯¯¯¯
CONTROLLER_STATE buttons (PadState) = 0 or 1
CONTROLLER_MAPPING buttons (joystick) = 0 or 1, 2, 3, 4, a certain joypad button
Please remember: The axis limit is hardcoded here, if you allow more axises (for
example for analog A and B buttons) you must first incrase the size of the axis array
size here
*/
struct CONTROLLER_STATE // GC PAD INFO/STATE
{
int buttons[8]; // Amount of buttons (A B X Y Z, L-Trigger R-Trigger Start) might need to change the triggers buttons
int dpad; // Automatic SDL D-Pad (8 directions + neutral)
int dpad2[4]; // D-pad using buttons
int axis[6]; // 2 x 2 Axes (Main & Sub)
int halfpress; // Halfpress... you know, like not fully pressed ;)...
SDL_Joystick *joy; // SDL joystick device
};
struct CONTROLLER_MAPPING // GC PAD MAPPING
{
int buttons[8]; // (See above)
int dpad; // (See above)
int dpad2[4]; // (See above)
int axis[6]; // (See above)
int halfpress; // (See above)
int enabled; // Pad attached?
int deadzone; // Deadzone... what else?
int ID; // SDL joystick device ID
int controllertype; // Hat: Hat or custom buttons
int triggertype; // Triggers range
std::string SDiagonal;
bool bSquareToCircle;
int eventnum; // Linux Event Number, Can't be found dynamically yet
};
struct CONTROLLER_INFO // CONNECTED WINDOWS DEVICES INFO
{
int NumAxes; // Amount of Axes
int NumButtons; // Amount of Buttons
int NumBalls; // Amount of Balls
int NumHats; // Amount of Hats (POV)
std::string Name; // Joypad/stickname
int ID; // SDL joystick device ID
bool Good;
SDL_Joystick *joy; // SDL joystick device
};
enum
{
// CTL_L_SHOULDER and CTL_R_SHOULDER = 0 and 1
CTL_MAIN_X = 2,
CTL_MAIN_Y,
CTL_SUB_X,
CTL_SUB_Y
};
enum
{
CTL_L_SHOULDER = 0,
CTL_R_SHOULDER,
CTL_A_BUTTON,
CTL_B_BUTTON,
CTL_X_BUTTON,
CTL_Y_BUTTON,
CTL_Z_TRIGGER,
CTL_START
};
// DPad Type
enum
{
CTL_DPAD_HAT = 0, // Automatically use the first hat that SDL finds
CTL_DPAD_CUSTOM // Custom directional pad settings
};
// Trigger Type
enum
{
CTL_TRIGGER_SDL = 0, //
CTL_TRIGGER_XINPUT // The XBox 360 pad
};
enum
{
CTL_D_PAD_UP = 0,
CTL_D_PAD_DOWN,
CTL_D_PAD_LEFT,
CTL_D_PAD_RIGHT
};
// Button type for the configuration
enum
{
CTL_AXIS = 0,
CTL_HAT,
CTL_BUTTON,
CTL_KEY
};
// XInput buttons
enum
{
XI_TRIGGER_L = 0,
XI_TRIGGER_R
};
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Input vector. Todo: Save the configured keys here instead of in joystick // Input vector. Todo: Save the configured keys here instead of in joystick
// ¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯
@ -225,11 +120,11 @@ extern std::vector<u8> Keys;
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Variables // Variables
// ¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯
#ifndef _CONTROLLER_STATE_H #ifndef _EXCLUDE_MAIN_
extern FILE *pFile; extern FILE *pFile;
extern std::vector<CONTROLLER_INFO> joyinfo; extern std::vector<InputCommon::CONTROLLER_INFO> joyinfo;
extern CONTROLLER_STATE PadState[4]; extern InputCommon::CONTROLLER_STATE PadState[4];
extern CONTROLLER_MAPPING PadMapping[4]; extern InputCommon::CONTROLLER_MAPPING PadMapping[4];
extern HWND m_hWnd; // Handle to window extern HWND m_hWnd; // Handle to window
extern int NumPads, NumGoodPads; // Number of goods pads extern int NumPads, NumGoodPads; // Number of goods pads
#endif #endif
@ -238,16 +133,12 @@ extern std::vector<u8> Keys;
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Custom Functions // Custom Functions
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads);
void GetJoyState(int controller);
int Search_Devices();
void DEBUG_INIT(); void DEBUG_INIT();
void DEBUG_QUIT(); void DEBUG_QUIT();
bool IsFocus(); bool IsFocus();
void Pad_Use_Rumble(u8 _numPAD, SPADStatus* _pPADStatus); // Rumble void Pad_Use_Rumble(u8 _numPAD, SPADStatus* _pPADStatus); // Rumble
int Pad_Convert(int _val); // Value conversion
std::vector<int> Pad_Square_to_Circle(int _x, int _y, int _pad); // Value conversion
//void SaveConfig(); //void SaveConfig();
//void LoadConfig(); //void LoadConfig();