diff --git a/Source/Plugins/Plugin_PadSimple/Plugin_PadSimple.vcproj b/Source/Plugins/Plugin_PadSimple/Plugin_PadSimple.vcproj index 3bf74a252b..8e3e8453ef 100644 --- a/Source/Plugins/Plugin_PadSimple/Plugin_PadSimple.vcproj +++ b/Source/Plugins/Plugin_PadSimple/Plugin_PadSimple.vcproj @@ -590,7 +590,6 @@ LinkIncremental="1" SuppressStartupBanner="true" GenerateManifest="false" - GenerateDebugInformation="true" ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb" RandomizedBaseAddress="1" DataExecutionPrevention="0" diff --git a/Source/Plugins/Plugin_PadSimple/Src/GUI/ConfigDlg.cpp b/Source/Plugins/Plugin_PadSimple/Src/GUI/ConfigDlg.cpp index b2b6211462..fd55019652 100644 --- a/Source/Plugins/Plugin_PadSimple/Src/GUI/ConfigDlg.cpp +++ b/Source/Plugins/Plugin_PadSimple/Src/GUI/ConfigDlg.cpp @@ -30,17 +30,11 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog) EVT_CLOSE(ConfigDialog::OnClose) EVT_BUTTON(ID_CLOSE,ConfigDialog::OnCloseClick) EVT_BUTTON(ID_PAD_ABOUT,ConfigDialog::DllAbout) - EVT_CHECKBOX(ID_ATTACHED,ConfigDialog::ControllerSettingsChanged) EVT_CHECKBOX(ID_X360PAD,ConfigDialog::ControllerSettingsChanged) EVT_CHOICE(ID_X360PAD_CHOICE,ConfigDialog::ControllerSettingsChanged) EVT_CHECKBOX(ID_RUMBLE,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_B,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_X,ConfigDialog::OnButtonClick) @@ -151,62 +145,18 @@ void ConfigDialog::CreateGUIControls() #endif for(int i = 0; i < 4; i++) - { - // -------------------------------------------------------------------- - // Settings - // ----------------------------- - // Main horizontal container - sDevice[i] = new wxBoxSizer(wxHORIZONTAL); - + { sbDevice[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Controller Settings")); + sDevice[i] = new wxBoxSizer(wxHORIZONTAL); 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 - 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_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_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 - - 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_Disable[i] = new wxCheckBox(m_Controller[i], ID_DISABLE, wxT("Disable when Dolphin is not in focus"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); 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 - // Check if any XInput pad was found if (arrayStringFor_X360Pad.IsEmpty()) { m_X360Pad[i]->SetLabel(wxT("Enable X360Pad - No pad connected")); @@ -225,21 +175,19 @@ void ConfigDialog::CreateGUIControls() m_Rumble[i]->Enable(m_X360Pad[i]->IsChecked()); } #endif - - // Sizers - sDevice[i]->Add(sbDevice[i], 0, wxEXPAND | wxALL, 1); - //sDevice[i]->AddStretchSpacer(); + m_Disable[i]->SetValue(pad[i].bDisable); + + sDevice[i]->Add(m_Attached[i], 0, wxEXPAND|wxALL, 1); + sDevice[i]->AddStretchSpacer(); #ifdef _WIN32 - sDevice[i]->Add(m_SizeXInput[i], 0, wxEXPAND | wxALL, 1); - sDevice[i]->Add(m_SizeRecording[i], 0, wxEXPAND | wxALL, 1); - + sDevice[i]->Add(m_X360Pad[i], 0, wxEXPAND|wxALL, 1); + sDevice[i]->Add(m_X360PadC[i], 0, wxEXPAND|wxALL, 1); + sDevice[i]->Add(m_Rumble[i], 0, wxEXPAND|wxALL, 1); + sDevice[i]->AddStretchSpacer(); #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")); AddControl(m_Controller[i], &(m_ButtonA[i]), sButtons[i], "A: ", CTL_A, i); @@ -279,13 +227,10 @@ void ConfigDialog::CreateGUIControls() 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); - // -------------------------------------------------------------------- - // Sizers - // ----------------------------- sPage[i] = new wxGridBagSizer(0, 0); sPage[i]->SetFlexibleDirection(wxBOTH); sPage[i]->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - sPage[i]->Add(sDevice[i], wxGBPosition(0, 0), wxGBSpan(1, 5), wxEXPAND|wxALL, 1); + sPage[i]->Add(sbDevice[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(sTriggers[i], wxGBPosition(1, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 1); sPage[i]->Add(sModifiers[i], wxGBPosition(2, 1), wxGBSpan(1, 1), wxALL, 1); @@ -346,15 +291,9 @@ void ConfigDialog::ControllerSettingsChanged(wxCommandEvent& event) switch (event.GetId()) { - // General settings case ID_ATTACHED: pad[page].bAttached = m_Attached[page]->GetValue(); break; - case ID_DISABLE: - pad[page].bDisable = m_Disable[page]->GetValue(); - break; - - // XInput case ID_X360PAD: pad[page].bEnableXPad = event.IsChecked(); m_Rumble[page]->Enable(event.IsChecked()); @@ -366,22 +305,9 @@ void ConfigDialog::ControllerSettingsChanged(wxCommandEvent& event) case ID_RUMBLE: pad[page].bRumble = m_Rumble[page]->GetValue(); break; - - case ID_RECORDING: - pad[page].bRecording = m_CheckRecording[page]->GetValue(); - // Turn off the other option - pad[page].bPlayback = false; m_CheckPlayback[page]->SetValue(false); + case ID_DISABLE: + pad[page].bDisable = m_Disable[page]->GetValue(); 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; - } } diff --git a/Source/Plugins/Plugin_PadSimple/Src/GUI/ConfigDlg.h b/Source/Plugins/Plugin_PadSimple/Src/GUI/ConfigDlg.h index e5d58d74f6..34d12ee34f 100644 --- a/Source/Plugins/Plugin_PadSimple/Src/GUI/ConfigDlg.h +++ b/Source/Plugins/Plugin_PadSimple/Src/GUI/ConfigDlg.h @@ -50,7 +50,7 @@ class ConfigDialog : public wxDialog wxButton *m_About; wxButton *m_Close; - wxStaticBoxSizer *sbDevice[4], *m_SizeXInput[4], *m_SizeRecording[4]; + wxStaticBoxSizer *sbDevice[4]; wxBoxSizer *sDevice[4]; wxGridBagSizer *sPage[4]; wxStaticBoxSizer *sButtons[4]; @@ -67,11 +67,6 @@ class ConfigDialog : public wxDialog wxCheckBox *m_Disable[4]; wxCheckBox *m_Rumble[4]; - // Recording - wxCheckBox *m_CheckRecording[4]; - wxCheckBox *m_CheckPlayback[4]; - wxButton *m_BtnSaveRecording[4]; - wxButton *m_ButtonA[4]; wxButton *m_ButtonB[4]; wxButton *m_ButtonX[4]; @@ -104,19 +99,11 @@ class ConfigDialog : public wxDialog ID_CONTROLLERPAGE3, ID_CONTROLLERPAGE4, - // XInput pad ID_X360PAD_CHOICE, ID_X360PAD, - ID_RUMBLE, - - // Input recording - ID_RECORDING, - ID_PLAYBACK, - ID_SAVE_RECORDING, - - // General settings ID_ATTACHED, ID_DISABLE, + ID_RUMBLE, ID_PAD_ABOUT }; diff --git a/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp b/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp index 74c07b6841..ffdbb23ad3 100644 --- a/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp +++ b/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp @@ -15,10 +15,6 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ - -////////////////////////////////////////////////////////////////////////////////////////// -// Include -// ŻŻŻŻŻŻŻŻŻŻŻŻŻ #include #include @@ -26,69 +22,43 @@ #include "pluginspecs_pad.h" #include "PadSimple.h" #include "IniFile.h" -#include "ConsoleWindow.h" -#include "StringUtil.h" -#include "ChunkFile.h" + + #if defined(HAVE_WX) && HAVE_WX - #include "GUI/ConfigDlg.h" +#include "GUI/ConfigDlg.h" #endif #ifdef _WIN32 - #include "XInput.h" - #include "DirectInputBase.h" +#include "XInput.h" +#include "DirectInputBase.h" - DInput dinput; - //#elif defined(USE_SDL) && USE_SDL - //#include +DInput dinput; +//#elif defined(USE_SDL) && USE_SDL +//#include #elif defined(HAVE_X11) && HAVE_X11 - #include - #include - #include - #include +#include +#include +#include +#include - Display* GXdsp; - bool KeyStatus[NUMCONTROLS]; +Display* GXdsp; +bool KeyStatus[NUMCONTROLS]; #elif defined(HAVE_COCOA) && HAVE_COCOA - #include - bool KeyStatus[NUMCONTROLS]; +#include +bool KeyStatus[NUMCONTROLS]; #endif -//////////////////////////////// - -////////////////////////////////////////////////////////////////////////////////////////// -// Declarations -// ŻŻŻŻŻŻŻŻŻŻŻŻŻ SPads pad[4]; HINSTANCE g_hInstance; 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) SPADStatus recordBuffer[RECORD_SIZE]; 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 @@ -96,68 +66,46 @@ void __Logv(int log, int v, const char *format, ...) {} void RecordInput(const SPADStatus& _rPADStatus) { - if (count >= RECORD_SIZE) return; + if (count >= RECORD_SIZE) + { + return; + } + 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() { - // Logging - //Console::Print("PlayRecord(%i)\n", count); + if (count >= RECORD_SIZE){return(recordBuffer[0]);} - if (count >= RECORD_SIZE) - { - // Todo: Make the recording size unlimited? - //PanicAlert("The recording reached its end"); - return(recordBuffer[0]); - } return(recordBuffer[count++]); } + void LoadRecord() { - FILE* pStream = fopen("pad-record.bin", "rb"); + FILE* pStream = fopen("c:\\pad-record.bin", "rb"); if (pStream != NULL) { fread(recordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream); fclose(pStream); } - else - { - PanicAlert("SimplePad: Could not open pad-record.bin"); - } - - //Console::Print("LoadRecord()"); } + void SaveRecord() { - // Open the file in a way that clears all old data - FILE* pStream = fopen("pad-record.bin", "wb"); + FILE* pStream = fopen("c:\\pad-record.bin", "wb"); if (pStream != NULL) { fwrite(recordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream); fclose(pStream); } - else - { - PanicAlert("SimplePad: Could not save pad-record.bin"); - } - //PanicAlert("SaveRecord()"); - //Console::Print("SaveRecord()"); } - // Check if Dolphin is in focus bool IsFocus() { @@ -219,6 +167,89 @@ BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle #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; // Implement circular deadzone @@ -252,9 +283,6 @@ void ScaleStickValues(unsigned char* outx, *outy = 0x80 + iy; } -//****************************************************************************** -// Input -//****************************************************************************** #ifdef _WIN32 void DInput_Read(int _numPAD, SPADStatus* _pPADStatus) @@ -306,8 +334,6 @@ 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_DPADRIGHT]]& 0xFF){_pPADStatus->button |= PAD_BUTTON_RIGHT;} 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) @@ -355,8 +381,6 @@ 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_DOWN) {_pPADStatus->button |= PAD_BUTTON_DOWN;} - //_pPADStatus->MicButton = (xpad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? true : false; - return true; } else @@ -586,124 +610,25 @@ void cocoa_Read(int _numPAD, SPADStatus* _pPADStatus) } #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 // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ -void PAD_Input(u16 _Key, u8 _UpDown) {} +void PAD_Input(u16 _Key, u8 _UpDown) { +} void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) { // Check if all is okay - if (_pPADStatus == NULL) return; - - // Play back input instead of accepting any user input - if (pad[0].bPlayback) + if ((_pPADStatus == NULL)) { - *_pPADStatus = PlayRecord(); return; } +#ifdef RECORD_REPLAY + *_pPADStatus = PlayRecord(); + return; +#endif + const int base = 0x80; // Clear pad memset(_pPADStatus, 0, sizeof(SPADStatus)); @@ -714,18 +639,15 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) _pPADStatus->substickY = base; _pPADStatus->button |= PAD_USE_ORIGIN; #ifdef _WIN32 - // Only update pad on focus, don't do this when recording - if (pad[_numPAD].bDisable && !pad[0].bRecording && !IsFocus()) return; - + // Just update pad on focus + if (pad[_numPAD].bDisable) + { + if (!IsFocus()) return; + } // Dolphin doesn't really care about the pad error codes anyways... _pPADStatus->err = PAD_ERR_NONE; - - // Read XInput if (pad[_numPAD].bEnableXPad) XInput_Read(pad[_numPAD].XPadPlayer, _pPADStatus); - - // Read Direct Input DInput_Read(_numPAD, _pPADStatus); - #elif defined(HAVE_X11) && HAVE_X11 _pPADStatus->err = PAD_ERR_NONE; X11_Read(_numPAD, _pPADStatus); @@ -734,8 +656,9 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) cocoa_Read(_numPAD, _pPADStatus); #endif - // Record input - if (pad[0].bRecording) RecordInput(*_pPADStatus); +#ifdef RECORD_STORE + RecordInput(*_pPADStatus); +#endif } @@ -819,8 +742,7 @@ void LoadConfig() DIK_G, DIK_F, DIK_H, - DIK_LSHIFT, //halfpress - DIK_M //Mic + DIK_LSHIFT }; #elif defined(HAVE_X11) && HAVE_X11 const int defaultKeyForControl[NUMCONTROLS] = @@ -846,7 +768,7 @@ void LoadConfig() XK_f, XK_h, XK_Shift_L, //halfpress - XK_p //Mic + XK_p }; #elif defined(HAVE_COCOA) && HAVE_COCOA const int defaultKeyForControl[NUMCONTROLS] = @@ -872,7 +794,7 @@ void LoadConfig() 3, 4, 56, //halfpress - 35 //Mic + 35 }; #endif IniFile file; @@ -889,9 +811,6 @@ void LoadConfig() file.Get(SectionName, "Rumble", &pad[i].bRumble, true); 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++) { file.Get(SectionName, controlNames[x], &pad[i].keyForControl[x], @@ -921,9 +840,6 @@ void SaveConfig() file.Set(SectionName, "DisableOnBackground", pad[i].bDisable); file.Set(SectionName, "Rumble", pad[i].bRumble); 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++) { diff --git a/Source/Plugins/Plugin_PadSimple/Src/PadSimple.h b/Source/Plugins/Plugin_PadSimple/Src/PadSimple.h index ee2b055659..53e82feb25 100644 --- a/Source/Plugins/Plugin_PadSimple/Src/PadSimple.h +++ b/Source/Plugins/Plugin_PadSimple/Src/PadSimple.h @@ -73,26 +73,19 @@ static const char* controlNames[] = "Mic-button", }; -struct SPads -{ +struct SPads { bool bEnableXPad; // Use an XPad in addition to the keyboard? bool bAttached; // Pad is "attached" to the gamecube/wii bool bDisable; // Disabled when dolphin isn't in focus bool bRumble; // Rumble for xpad - bool bRecording; - bool bPlayback; int XPadPlayer; // Player# of the xpad unsigned int keyForControl[NUMCONTROLS];// Keyboard mapping }; extern SPads pad[]; -extern bool g_EmulatorRunning; void LoadConfig(); void SaveConfig(); bool IsFocus(); -// Input Recording -void SaveRecord(); - #endif diff --git a/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj b/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj index 94adefdb65..b20c24766c 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj +++ b/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj @@ -522,6 +522,14 @@ RelativePath=".\Src\Rumble.cpp" > + + + + GetMinSize().GetWidth() will not change @@ -70,10 +70,8 @@ void ConfigBox::PadGetStatus() int PhysicalDevice = PadMapping[notebookpage].ID; int TriggerType = PadMapping[notebookpage].triggertype; - // Check that Dolphin is in focus, otherwise don't update the pad status - if (!g_Config.bCheckFocus && IsFocus()) - InputCommon::GetJoyState(PadState[notebookpage], PadMapping[notebookpage], notebookpage, joyinfo[PadMapping[notebookpage].ID].NumButtons); - + // Get pad status + GetJoyState(notebookpage); ////////////////////////////////////// // Analog stick @@ -83,8 +81,8 @@ void ConfigBox::PadGetStatus() //int deadzone2 = (int)(((float)(-128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1)); // Get original values - int main_x = PadState[notebookpage].axis[InputCommon::CTL_MAIN_X]; - int main_y = PadState[notebookpage].axis[InputCommon::CTL_MAIN_Y]; + int main_x = PadState[notebookpage].axis[CTL_MAIN_X]; + int main_y = PadState[notebookpage].axis[CTL_MAIN_Y]; //int sub_x = (PadState[_numPAD].axis[CTL_SUB_X]; //int sub_y = -(PadState[_numPAD].axis[CTL_SUB_Y]; @@ -92,7 +90,7 @@ void ConfigBox::PadGetStatus() int main_x_after = main_x, main_y_after = main_y; if(PadMapping[notebookpage].bSquareToCircle) { - std::vector main_xy = InputCommon::Pad_Square_to_Circle(main_x, main_y, notebookpage, PadMapping[notebookpage]); + std::vector main_xy = Pad_Square_to_Circle(main_x, main_y, notebookpage); main_x_after = main_xy.at(0); main_y_after = main_xy.at(1); } @@ -140,14 +138,14 @@ void ConfigBox::PadGetStatus() m_JoyShoulderR[notebookpage]->GetValue().ToLong(&Right); // Get the trigger values - int TriggerLeft = PadState[notebookpage].axis[InputCommon::CTL_L_SHOULDER]; - int TriggerRight = PadState[notebookpage].axis[InputCommon::CTL_R_SHOULDER]; + int TriggerLeft = PadState[notebookpage].axis[CTL_L_SHOULDER]; + int TriggerRight = PadState[notebookpage].axis[CTL_R_SHOULDER]; // Convert the triggers values - if (PadMapping[notebookpage].triggertype == InputCommon::CTL_TRIGGER_SDL) + if (PadMapping[notebookpage].triggertype == CTL_TRIGGER_SDL) { - TriggerLeft = InputCommon::Pad_Convert(TriggerLeft); - TriggerRight = InputCommon::Pad_Convert(TriggerRight); + TriggerLeft = Pad_Convert(TriggerLeft); + TriggerRight = Pad_Convert(TriggerRight); } // If we don't have any axis selected for the shoulder buttons @@ -155,8 +153,8 @@ void ConfigBox::PadGetStatus() if(Right < 1000) TriggerRight = 0; // Get the digital values - if(Left < 1000 && PadState[notebookpage].buttons[InputCommon::CTL_L_SHOULDER]) TriggerLeft = TriggerValue; - if(Right < 1000 && PadState[notebookpage].buttons[InputCommon::CTL_R_SHOULDER]) TriggerRight = TriggerValue; + if(Left < 1000 && PadState[notebookpage].buttons[CTL_L_SHOULDER]) TriggerLeft = TriggerValue; + if(Right < 1000 && PadState[notebookpage].buttons[CTL_R_SHOULDER]) TriggerRight = TriggerValue; m_TStatusTriggers[notebookpage]->SetLabel(wxString::Format( wxT("Left:%03i Right:%03i"), @@ -194,10 +192,6 @@ std::string ShowStatus(int VirtualController) int Hats = joyinfo[PhysicalDevice].NumHats; int Buttons = joyinfo[PhysicalDevice].NumButtons; - // Get version - //SDL_version Version; - //SDL_GetVersion(&Version); - // Update the internal values SDL_JoystickUpdate(); @@ -219,7 +213,7 @@ std::string ShowStatus(int VirtualController) } return StringFromFormat( - //"Version: %i.%i.%i\n" + "PadMapping\n" "Enabled: %i %i %i %i\n" "ID: %i %i %i %i\n" "Controllertype: %i %i %i %i\n" @@ -231,7 +225,6 @@ std::string ShowStatus(int VirtualController) "Hats: %s\n" "But: %s\n" "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].ID, PadMapping[1].ID, PadMapping[2].ID, PadMapping[3].ID, PadMapping[0].controllertype, PadMapping[1].controllertype, PadMapping[2].controllertype, PadMapping[3].controllertype, @@ -240,7 +233,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, #ifdef _WIN32 - XInput::IsConnected(0), XInput::GetXI(0, InputCommon::XI_TRIGGER_L), XInput::GetXI(0, InputCommon::XI_TRIGGER_R), + XInput::IsConnected(0), XInput::GetXI(0, XI_TRIGGER_L), XInput::GetXI(0, XI_TRIGGER_R), #endif StrAxes.c_str(), StrHats.c_str(), StrBut.c_str(), Axes, Balls, Hats, Buttons @@ -252,12 +245,10 @@ std::string ShowStatus(int VirtualController) void ConfigBox::Update() { // Show the current status - /**/ - #ifdef SHOW_PAD_STATUS - m_pStatusBar->SetLabel(wxString::Format( - "%s", ShowStatus(notebookpage).c_str() - )); - #endif + /* + m_pStatusBar->SetLabel(wxString::Format( + "%s", ShowStatus(notebookpage).c_str() + ));*/ //LogMsg("Abc%s\n", ShowStatus(notebookpage).c_str()); @@ -270,10 +261,6 @@ void ConfigBox::Update() // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ 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_bmpSquare[i] = new wxStaticBitmap(m_pInStatus[i], ID_STATUSBMP1 + i, CreateBitmap(), //wxPoint(4, 15), wxSize(70,70)); diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp index 076c908267..b1a2d48e53 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp @@ -39,7 +39,7 @@ #include "../nJoy.h" #include "Images/controller.xpm" -extern bool g_EmulatorRunning; +extern bool emulator_running; // D-Pad type static const char* DPadType[] = @@ -74,7 +74,7 @@ BEGIN_EVENT_TABLE(ConfigBox,wxDialog) // Other settings EVT_CHECKBOX(IDC_SAVEBYID, ConfigBox::ChangeSettings) EVT_CHECKBOX(IDC_SHOWADVANCED, ConfigBox::ChangeSettings) - EVT_CHECKBOX(IDCB_CHECKFOCUS, ConfigBox::ChangeSettings) + EVT_CHECKBOX(IDC_CHECKFOCUS, ConfigBox::ChangeSettings) EVT_COMBOBOX(IDCB_MAINSTICK_DIAGONAL, ConfigBox::ChangeSettings) EVT_COMBOBOX(IDC_CONTROLTYPE, ConfigBox::ChangeSettings) EVT_COMBOBOX(IDC_TRIGGERTYPE, ConfigBox::ChangeSettings) @@ -83,7 +83,6 @@ BEGIN_EVENT_TABLE(ConfigBox,wxDialog) // Advanced settings EVT_COMBOBOX(IDCB_MAINSTICK_DIAGONAL, 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_R, ConfigBox::GetButtons) @@ -162,7 +161,7 @@ void ConfigBox::OnKeyDown(wxKeyEvent& event) void ConfigBox::OnClose(wxCloseEvent& /*event*/) { EndModal(0); - if(!g_EmulatorRunning) Shutdown(); // Close pads, unless we are running a game + if(!emulator_running) Shutdown(); // Close pads, unless we are running a game } // Call about dialog @@ -292,8 +291,7 @@ void ConfigBox::OnSaveById() // Change Joystick // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ /* Function: When changing the joystick we save and load the settings and update the PadMapping - 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. */ + and PadState array */ void ConfigBox::DoChangeJoystick() { // Close the current pad, unless it's used by another slot @@ -427,34 +425,16 @@ void ConfigBox::ChangeSettings( wxCommandEvent& event ) } SizeWindow(); break; - // Advanced settings - case IDCB_CHECKFOCUS: + case IDC_CHECKFOCUS: g_Config.bCheckFocus = m_CBCheckFocus[notebookpage]->IsChecked(); for(int i = 0; i < 4; i++) { m_CBCheckFocus[i]->SetValue(g_Config.bCheckFocus); } 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: - if(!g_Config.bSaveByID) - { - PadMapping[notebookpage].controllertype = m_ControlType[notebookpage]->GetSelection(); - UpdateGUI(notebookpage); - } case IDC_TRIGGERTYPE: - if(!g_Config.bSaveByID) - { - PadMapping[notebookpage].triggertype = m_TriggerType[notebookpage]->GetSelection(); - UpdateGUI(notebookpage); - } + //UpdateGUI(notebookpage); break; case IDC_JOYNAME: @@ -492,10 +472,10 @@ void ConfigBox::UpdateGUI(int _notebookpage) } // Update the GUI from PadMapping[] - UpdateGUIButtonMapping(_notebookpage); + UpdateGUIKeys(_notebookpage); // Collect status - bool Hat = (PadMapping[_notebookpage].controllertype == InputCommon::CTL_DPAD_HAT); + bool Hat = (PadMapping[_notebookpage].controllertype == CTL_DPAD_HAT); long Left, Right; m_JoyShoulderL[_notebookpage]->GetValue().ToLong(&Left); m_JoyShoulderR[_notebookpage]->GetValue().ToLong(&Right); @@ -525,7 +505,6 @@ void ConfigBox::UpdateGUI(int _notebookpage) m_CBSaveByID[_notebookpage]->SetValue(g_Config.bSaveByID); m_CBShowAdvanced[_notebookpage]->SetValue(g_Config.bShowAdvanced); m_CBCheckFocus[_notebookpage]->SetValue(g_Config.bCheckFocus); - m_AdvancedMapFilter[_notebookpage]->SetValue(g_Config.bNoTriggerFilter); LogMsg("Update: %i\n", g_Config.bSaveByID); @@ -541,8 +520,7 @@ void ConfigBox::UpdateGUI(int _notebookpage) m_Controller[_notebookpage]->FindItem(IDC_CONTROLTYPE)->Enable(Enabled); m_Controller[_notebookpage]->FindItem(IDC_TRIGGERTYPE)->Enable(Enabled && XInput); 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_FILTER_SETTINGS)->Enable(Enabled); + m_Controller[_notebookpage]->FindItem(IDCB_MAINSTICK_S_TO_C)->Enable(Enabled); #endif // Replace the harder to understand -1 with "" for the sake of user friendliness @@ -641,12 +619,12 @@ void ConfigBox::CreateGUIControls() // Populate the DPad type and Trigger type list // ----------------------------- wxArrayString wxAS_DPadType; - wxAS_DPadType.Add(wxString::FromAscii(DPadType[InputCommon::CTL_DPAD_HAT])); - wxAS_DPadType.Add(wxString::FromAscii(DPadType[InputCommon::CTL_DPAD_CUSTOM])); + wxAS_DPadType.Add(wxString::FromAscii(DPadType[CTL_DPAD_HAT])); + wxAS_DPadType.Add(wxString::FromAscii(DPadType[CTL_DPAD_CUSTOM])); wxArrayString wxAS_TriggerType; - wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[InputCommon::CTL_TRIGGER_SDL])); - wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[InputCommon::CTL_TRIGGER_XINPUT])); + wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[CTL_TRIGGER_SDL])); + wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[CTL_TRIGGER_XINPUT])); // -------------------------------------------------------------------- // Populate the deadzone list @@ -842,10 +820,12 @@ void ConfigBox::CreateGUIControls() 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_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 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_CBCheckFocus[i], 0, wxEXPAND | wxALL, 3); // Create tooltips m_ControlType[i]->SetToolTip(wxT( @@ -860,6 +840,8 @@ void ConfigBox::CreateGUIControls() "\nto save your settings if you have multiple controllers.") , 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 m_sSettings[i] = new wxBoxSizer ( wxHORIZONTAL ); @@ -875,13 +857,17 @@ void ConfigBox::CreateGUIControls() // Advanced settings // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ - // Input status controls + // Populate input status + /**/ // Input status text - CreateAdvancedControls(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")); - // Sizers + m_gStatusIn[i] = new wxStaticBoxSizer( wxHORIZONTAL, m_Controller[i], wxT("Main-stick (In) (Out)")); + CreateAdvancedControls(i); 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_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); @@ -925,20 +911,6 @@ void ConfigBox::CreateGUIControls() 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_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 @@ -961,7 +933,6 @@ void ConfigBox::CreateGUIControls() 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_gStatusTriggers[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2); - m_sMainRight[i]->Add(m_gStatusAdvancedSettings[i], 0, wxEXPAND | (wxLEFT | wxTOP), 2); // -------------------------------------------------------------------- // Populate main sizer @@ -975,7 +946,7 @@ void ConfigBox::CreateGUIControls() m_sMainRight[i]->Show(g_Config.bShowAdvanced); // Don't allow these changes when running - if(g_EmulatorRunning) + if(emulator_running) { m_Joyname[i]->Enable(false); m_Joyattach[i]->Enable(false); @@ -1008,9 +979,7 @@ void ConfigBox::CreateGUIControls() // -------------------------------------------------------------------- // Debugging // ----------------------------- - #ifdef SHOW_PAD_STATUS - m_pStatusBar = new wxStaticText(this, IDT_DEBUGGING, wxT("Debugging"), wxPoint(135, 100), wxDefaultSize); - #endif + //m_pStatusBar = new wxStaticText(this, IDT_DEBUGGING, wxT("Debugging"), wxPoint(135, 100), wxDefaultSize); //m_pStatusBar2 = new wxStaticText(this, IDT_DEBUGGING2, wxT("Debugging2"), wxPoint(125, 200), wxDefaultSize); //m_pStatusBar->SetLabel(wxString::Format("Debugging text")); diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h index e47ba87b24..80823dc868 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h @@ -48,7 +48,6 @@ #include #include -#include "../nJoy.h" class ConfigBox : public wxDialog { @@ -113,15 +112,14 @@ class ConfigBox : public wxDialog wxStaticBoxSizer *m_gGenSettingsID[4]; wxGridBagSizer * m_gGBGenSettings[4]; - wxCheckBox *m_CBSaveByID[4], *m_CBShowAdvanced[4]; + wxCheckBox *m_CBSaveByID[4], *m_CBShowAdvanced[4], *m_CBCheckFocus[4]; wxStaticText *m_TSControltype[4], *m_TSTriggerType[4]; - wxStaticBoxSizer *m_gStatusIn[4], *m_gStatusInSettings[4], *m_gStatusAdvancedSettings[4]; // Advanced settings + wxStaticBoxSizer *m_gStatusIn[4], *m_gStatusInSettings[4]; // Advanced settings wxBoxSizer *m_gStatusInSettingsH[4]; wxGridBagSizer * m_GBAdvancedMainStick[4]; wxStaticText *m_TStatusIn[4], *m_TStatusOut[4], *m_STDiagonal[4]; wxComboBox *m_CoBDiagonal[4]; wxCheckBox *m_CBS_to_C[4]; - wxCheckBox *m_CBCheckFocus[4], *m_AdvancedMapFilter[4]; wxStaticBoxSizer *m_gStatusTriggers[4]; // Triggers wxStaticText *m_TStatusTriggers[4]; @@ -212,7 +210,7 @@ class ConfigBox : public wxDialog IDG_CONTROLLERTYPE, IDC_CONTROLTYPE, IDC_TRIGGERTYPE, // Controller type - IDC_SAVEBYID, IDC_SHOWADVANCED, // Settings + IDC_SAVEBYID, IDC_SHOWADVANCED, IDC_CHECKFOCUS, // Settings ID_INSTATUS1, ID_INSTATUS2, ID_INSTATUS3, ID_INSTATUS4, // Advanced status ID_STATUSBMP1, ID_STATUSBMP2, ID_STATUSBMP3, ID_STATUSBMP4, @@ -220,7 +218,7 @@ class ConfigBox : public wxDialog IDT_STATUS_IN, IDT_STATUS_OUT, // Advaced settings - IDCB_MAINSTICK_DIAGONAL, IDCB_MAINSTICK_S_TO_C, IDT_MAINSTICK_DIAGONAL, IDT_TRIGGERS, IDCB_CHECKFOCUS, IDCB_FILTER_SETTINGS, + IDCB_MAINSTICK_DIAGONAL, IDCB_MAINSTICK_S_TO_C, IDT_MAINSTICK_DIAGONAL, IDT_TRIGGERS, // Timers IDTM_CONSTANT, IDTM_BUTTON, @@ -319,7 +317,7 @@ class ConfigBox : public wxDialog wxBitmap CreateBitmap(); wxBitmap CreateBitmapDot(); void PadGetStatus(); void Update(); - void UpdateGUIButtonMapping(int controller); + void UpdateGUIKeys(int controller); void SaveButtonMapping(int controller, bool DontChangeId = false, int FromSlot = -1); void SaveButtonMappingAll(int Slot); void UpdateGUIAll(int Slot); diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp index 87b314ba22..faeadff75b 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp @@ -39,13 +39,13 @@ #include "../nJoy.h" #include "Images/controller.xpm" -extern bool g_EmulatorRunning; +extern bool emulator_running; //////////////////////// // Set dialog items from saved values // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ -void ConfigBox::UpdateGUIButtonMapping(int controller) +void ConfigBox::UpdateGUIKeys(int controller) { // http://wiki.wxwidgets.org/Converting_everything_to_and_from_wxString wxString tmp; @@ -56,22 +56,22 @@ void ConfigBox::UpdateGUIButtonMapping(int controller) // Update the enabled checkbox m_Joyattach[controller]->SetValue(PadMapping[controller].enabled == 1 ? true : false); - tmp << PadMapping[controller].buttons[InputCommon::CTL_L_SHOULDER]; m_JoyShoulderL[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_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_A_BUTTON]; m_JoyButtonA[controller]->SetValue(tmp); tmp.clear(); - tmp << PadMapping[controller].buttons[InputCommon::CTL_B_BUTTON]; m_JoyButtonB[controller]->SetValue(tmp); tmp.clear(); - tmp << PadMapping[controller].buttons[InputCommon::CTL_X_BUTTON]; m_JoyButtonX[controller]->SetValue(tmp); tmp.clear(); - tmp << PadMapping[controller].buttons[InputCommon::CTL_Y_BUTTON]; m_JoyButtonY[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_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[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[CTL_Z_TRIGGER]; m_JoyButtonZ[controller]->SetValue(tmp); tmp.clear(); - tmp << PadMapping[controller].buttons[InputCommon::CTL_START]; m_JoyButtonStart[controller]->SetValue(tmp); tmp.clear(); + tmp << PadMapping[controller].buttons[CTL_START]; m_JoyButtonStart[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].halfpress; m_JoyButtonHalfpress[controller]->SetValue(tmp); tmp.clear(); - tmp << PadMapping[controller].axis[InputCommon::CTL_MAIN_X]; m_JoyAnalogMainX[controller]->SetValue(tmp); tmp.clear(); - tmp << PadMapping[controller].axis[InputCommon::CTL_MAIN_Y]; m_JoyAnalogMainY[controller]->SetValue(tmp); tmp.clear(); - tmp << PadMapping[controller].axis[InputCommon::CTL_SUB_X]; m_JoyAnalogSubX[controller]->SetValue(tmp); tmp.clear(); - tmp << PadMapping[controller].axis[InputCommon::CTL_SUB_Y]; m_JoyAnalogSubY[controller]->SetValue(tmp); tmp.clear(); + tmp << PadMapping[controller].axis[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[CTL_SUB_X]; m_JoyAnalogSubX[controller]->SetValue(tmp); tmp.clear(); + tmp << PadMapping[controller].axis[CTL_SUB_Y]; m_JoyAnalogSubY[controller]->SetValue(tmp); tmp.clear(); // Update the deadzone and controller type controls m_ControlType[controller]->SetSelection(PadMapping[controller].controllertype); @@ -79,21 +79,20 @@ void ConfigBox::UpdateGUIButtonMapping(int controller) m_Deadzone[controller]->SetSelection(PadMapping[controller].deadzone); m_CoBDiagonal[controller]->SetValue(wxString::FromAscii(PadMapping[controller].SDiagonal.c_str())); 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); // Update D-Pad - if(PadMapping[controller].controllertype == InputCommon::CTL_DPAD_HAT) + if(PadMapping[controller].controllertype == CTL_DPAD_HAT) { - tmp << PadMapping[controller].dpad; m_JoyDpadDown[controller]->SetValue(tmp); tmp.clear(); + tmp << PadMapping[controller].dpad; m_JoyDpadUp[controller]->SetValue(tmp); tmp.clear(); } else { - tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_UP]; m_JoyDpadUp[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[InputCommon::CTL_D_PAD_LEFT]; m_JoyDpadLeft[controller]->SetValue(tmp); tmp.clear(); - tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_RIGHT]; m_JoyDpadRight[controller]->SetValue(tmp); tmp.clear(); + tmp << PadMapping[controller].dpad2[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[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(); } // Replace "-1" with "" in the GUI controls @@ -122,25 +121,25 @@ void ConfigBox::SaveButtonMapping(int controller, bool DontChangeId, int FromSlo PadMapping[controller].triggertype = m_TriggerType[FromSlot]->GetSelection(); PadMapping[controller].deadzone = m_Deadzone[FromSlot]->GetSelection(); 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 - 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[InputCommon::CTL_MAIN_Y] = 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[InputCommon::CTL_SUB_Y] = value; tmp.clear(); + m_JoyAnalogMainX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[CTL_MAIN_X] = value; tmp.clear(); + m_JoyAnalogMainY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[CTL_MAIN_Y] = value; tmp.clear(); + m_JoyAnalogSubX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[CTL_SUB_X] = value; tmp.clear(); + m_JoyAnalogSubY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[CTL_SUB_Y] = value; tmp.clear(); // The shoulder buttons - m_JoyShoulderL[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_L_SHOULDER] = value; - m_JoyShoulderR[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_R_SHOULDER] = value; + m_JoyShoulderL[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_L_SHOULDER] = value; + m_JoyShoulderR[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_R_SHOULDER] = value; // The digital buttons - 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[InputCommon::CTL_B_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[InputCommon::CTL_Y_BUTTON] = 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[InputCommon::CTL_START] = value; tmp.clear(); + m_JoyButtonA[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_A_BUTTON] = value; tmp.clear(); + m_JoyButtonB[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_B_BUTTON] = value; tmp.clear(); + m_JoyButtonX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_X_BUTTON] = value; tmp.clear(); + m_JoyButtonY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_Y_BUTTON] = value; tmp.clear(); + m_JoyButtonZ[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_Z_TRIGGER] = value; tmp.clear(); + m_JoyButtonStart[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[CTL_START] = value; tmp.clear(); //LogMsg("PadMapping[%i].triggertype = %i, m_TriggerType[%i]->GetSelection() = %i\n", // controller, PadMapping[controller].triggertype, FromSlot, m_TriggerType[FromSlot]->GetSelection()); @@ -149,16 +148,16 @@ void ConfigBox::SaveButtonMapping(int controller, bool DontChangeId, int FromSlo m_JoyButtonHalfpress[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].halfpress = value; tmp.clear(); // The digital pad - if(PadMapping[controller].controllertype == InputCommon::CTL_DPAD_HAT) + if(PadMapping[controller].controllertype == CTL_DPAD_HAT) { - m_JoyDpadDown[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad = value; tmp.clear(); + m_JoyDpadUp[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad = value; tmp.clear(); } else { - 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[InputCommon::CTL_D_PAD_DOWN] = 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[InputCommon::CTL_D_PAD_RIGHT] = value; tmp.clear(); + m_JoyDpadUp[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[CTL_D_PAD_UP] = value; tmp.clear(); + m_JoyDpadDown[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[CTL_D_PAD_DOWN] = value; tmp.clear(); + m_JoyDpadLeft[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[CTL_D_PAD_LEFT] = value; tmp.clear(); + m_JoyDpadRight[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[CTL_D_PAD_RIGHT] = value; tmp.clear(); } // Replace "-1" with "" @@ -245,6 +244,21 @@ 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 // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ /* Loop or timer: There are basically two ways to do this. With a while() or for() loop, or with a @@ -257,7 +271,6 @@ void ConfigBox::GetButtons(wxCommandEvent& event) { DoGetButtons(event.GetId()); } - void ConfigBox::DoGetButtons(int GetId) { // ============================================= @@ -266,17 +279,6 @@ void ConfigBox::DoGetButtons(int GetId) // Get the current controller 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 int ControllerType = PadMapping[Controller].controllertype; @@ -286,30 +288,35 @@ void ConfigBox::DoGetButtons(int GetId) bool LeftRight = (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R); bool Axis = (GetId >= IDB_ANALOG_MAIN_X && GetId <= IDB_SHOULDER_R) - && !(TriggerType == InputCommon::CTL_TRIGGER_XINPUT && (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) ); // Don't allow SDL here + && !(TriggerType == CTL_TRIGGER_XINPUT && (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) ); // Don't allow SDL here - bool XInput = (TriggerType == InputCommon::CTL_TRIGGER_XINPUT); + bool XInput = (TriggerType == CTL_TRIGGER_XINPUT); 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_DPAD_UP && GetId <= IDB_DPAD_RIGHT && ControllerType == InputCommon::CTL_DPAD_CUSTOM); // Or the custom hat mode + || (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT && ControllerType == CTL_DPAD_CUSTOM); // Or the custom hat mode bool Hat = (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT) // All DPads - && (PadMapping[Controller].controllertype == InputCommon::CTL_DPAD_HAT); // Not with the hat option defined + && (PadMapping[Controller].controllertype == CTL_DPAD_HAT); // Not with the hat option defined - bool NoTriggerFilter = g_Config.bNoTriggerFilter; + /* Open a new joystick. Joysticks[controller].GetId is the system GetId of the physical joystick + that is mapped to controller, for example 0, 1, 2, 3 for the first four PadMapping */ + SDL_Joystick *joy = SDL_JoystickOpen(PadMapping[Controller].ID); - // Values used in this function + // Get the number of axes, hats and buttons + int buttons = SDL_JoystickNumButtons(joy); + int axes = SDL_JoystickNumAxes(joy); + int hats = SDL_JoystickNumHats(joy); + + // Declare values char format[128]; - int Seconds = 4; // Seconds to wait for - 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 + int pressed = 0; + int Seconds = 4; // Seconds to wait for + int TimesPerSecond = 40; // How often to run the check // ======================= //Console::Print("Before (%i) Id:%i %i IsRunning:%i\n", @@ -350,10 +357,90 @@ void ConfigBox::DoGetButtons(int GetId) // If there is a timer but we should not create a new one else { - InputCommon::GetButton( - joy, PadID, Buttons, Axes, Hats, - g_Pressed, value, type, pressed, Succeed, Stop, - LeftRight, Axis, XInput, Button, Hat, NoTriggerFilter); + // Update the internal status + SDL_JoystickUpdate(); + + // For the triggers we accept both a digital or an analog button + 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 @@ -420,6 +507,9 @@ void ConfigBox::DoGetButtons(int GetId) } // ======================== Process results + // We don't need this gamepad handle any more + if(SDL_JoystickOpened(PadMapping[Controller].ID)) SDL_JoystickClose(joy); + // Debugging /* Console::Print("Change: %i %i %i %i '%s' '%s' '%s' '%s'\n", @@ -427,4 +517,5 @@ 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() );*/ } + /////////////////////////////////////////////////////////// Configure button mapping diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/SConscript b/Source/Plugins/Plugin_nJoy_SDL/Src/SConscript index 3b28332a6e..e5e96b3d71 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/SConscript +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/SConscript @@ -25,7 +25,7 @@ if padenv['HAVE_WX']: padenv.Append( CXXFLAGS = [ '-fPIC' ], - LIBS = [ 'common', 'inputcommon' ], + LIBS = [ 'common' ], ) padenv.SharedLibrary(env['plugin_dir']+name, files) diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp index 7853dfafbb..c5d9b1191e 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp @@ -81,13 +81,13 @@ // ŻŻŻŻŻŻŻŻŻ // Rumble in windows -#define _EXCLUDE_MAIN_ // Avoid certain declarations in nJoy.h +#define _CONTROLLER_STATE_H // Avoid certain declarations in nJoy.h FILE *pFile; HINSTANCE nJoy_hInst = NULL; -std::vector joyinfo; -InputCommon::CONTROLLER_STATE PadState[4]; -InputCommon::CONTROLLER_MAPPING PadMapping[4]; -bool g_EmulatorRunning = false; +std::vector joyinfo; +CONTROLLER_STATE PadState[4]; +CONTROLLER_MAPPING PadMapping[4]; +bool emulator_running = false; int NumPads = 0, NumGoodPads = 0; HWND m_hWnd; // Handle to window SPADInitialize *g_PADInitialize = NULL; @@ -191,9 +191,9 @@ void DllConfig(HWND _hParent) #ifdef _WIN32 // Start the pads so we can use them in the configuration and advanced controls - if(!g_EmulatorRunning) + if(!emulator_running) { - Search_Devices(joyinfo, NumPads, NumGoodPads); // Populate joyinfo for all attached devices + NumPads = Search_Devices(); // Populate joyinfo for all attached devices } 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 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() (g_EmulatorRunning does + global function that remembers the SDL_Init() and SDL_Quit() (emulator_running does 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. */ void Initialize(void *init) @@ -241,7 +241,7 @@ void Initialize(void *init) //Console::Open(); Console::Print("Initialize: %i\n", SDL_WasInit(0)); g_PADInitialize = (SPADInitialize*)init; - g_EmulatorRunning = true; + emulator_running = true; #ifdef _DEBUG DEBUG_INIT(); @@ -251,7 +251,7 @@ void Initialize(void *init) m_hWnd = (HWND)g_PADInitialize->hWnd; #endif - Search_Devices(joyinfo, NumPads, NumGoodPads); // Populate joyinfo for all attached devices + NumPads = Search_Devices(); // Populate joyinfo for all attached devices /* 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 */ @@ -265,15 +265,79 @@ void Initialize(void *init) } } -bool Search_Devices(std::vector &_joyinfo, int &_NumPads, int &_NumGoodPads) + +// Search attached devices. Populate joyinfo for all attached physical devices. +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +int Search_Devices() { - bool Success = InputCommon::SearchDevices(_joyinfo, _NumPads, _NumGoodPads); + // Load config + #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 - if (_NumGoodPads == 0 && g_EmulatorRunning) + if (NumGoodPads == 0 && emulator_running) { PanicAlert("nJoy: No Gamepad Detected"); - return false; + return joyinfo.size(); } // Load PadMapping[] etc @@ -287,7 +351,7 @@ bool Search_Devices(std::vector &_joyinfo, int &_N PadState[i].joy = SDL_JoystickOpen(PadMapping[i].ID); } - return Success; + return joyinfo.size(); } // Shutdown PAD (stop emulation) @@ -308,17 +372,18 @@ void Shutdown() if(SDL_JoystickOpened(PadMapping[i].ID)) SDL_JoystickClose(PadState[i].joy); } - // Clear the physical device info - joyinfo.clear(); - - // Finally close SDL - if (SDL_WasInit(0)) SDL_Quit(); + SDL_Quit(); #ifdef _DEBUG DEBUG_QUIT(); #endif - g_EmulatorRunning = false; + // Clear the physical device info + //delete [] joyinfo; + //joyinfo = NULL; + joyinfo.clear(); + + emulator_running = false; #ifdef _WIN32 #ifdef USE_RUMBLE_DINPUT_HACK @@ -340,13 +405,13 @@ void PAD_Input(u16 _Key, u8 _UpDown) // Check if the keys are interesting, and then update it for(int i = 0; i < 4; i++) { - for(int j = InputCommon::CTL_L_SHOULDER; j <= InputCommon::CTL_START; j++) + for(int j = CTL_L_SHOULDER; j <= CTL_START; j++) { if (PadMapping[i].buttons[j] == _Key) { PadState[i].buttons[j] = _UpDown; break; } } - for(int j = InputCommon::CTL_D_PAD_UP; j <= InputCommon::CTL_D_PAD_RIGHT; j++) + for(int j = CTL_D_PAD_UP; j <= CTL_D_PAD_RIGHT; j++) { if (PadMapping[i].dpad2[j] == _Key) { PadState[i].dpad2[j] = _UpDown; break; } @@ -396,9 +461,8 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) // Clear pad status memset(_pPADStatus, 0, sizeof(SPADStatus)); - // Check that Dolphin is in focus, otherwise don't update the pad status - if (!g_Config.bCheckFocus && IsFocus()) - GetJoyState(PadState[_numPAD], PadMapping[_numPAD], _numPAD, joyinfo[PadMapping[_numPAD].ID].NumButtons); + // Update the pad status + GetJoyState(_numPAD); // Get type int TriggerType = PadMapping[_numPAD].triggertype; @@ -408,32 +472,32 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) // ----------- // Read axis values - int i_main_stick_x = PadState[_numPAD].axis[InputCommon::CTL_MAIN_X]; - int i_main_stick_y = -PadState[_numPAD].axis[InputCommon::CTL_MAIN_Y]; - int i_sub_stick_x = PadState[_numPAD].axis[InputCommon::CTL_SUB_X]; - int i_sub_stick_y = -PadState[_numPAD].axis[InputCommon::CTL_SUB_Y]; - int TriggerLeft = PadState[_numPAD].axis[InputCommon::CTL_L_SHOULDER]; - int TriggerRight = PadState[_numPAD].axis[InputCommon::CTL_R_SHOULDER]; + int i_main_stick_x = PadState[_numPAD].axis[CTL_MAIN_X]; + int i_main_stick_y = -PadState[_numPAD].axis[CTL_MAIN_Y]; + int i_sub_stick_x = PadState[_numPAD].axis[CTL_SUB_X]; + int i_sub_stick_y = -PadState[_numPAD].axis[CTL_SUB_Y]; + int TriggerLeft = PadState[_numPAD].axis[CTL_L_SHOULDER]; + int TriggerRight = PadState[_numPAD].axis[CTL_R_SHOULDER]; // Check if we should make adjustments if(PadMapping[_numPAD].bSquareToCircle) { - std::vector main_xy = InputCommon::Pad_Square_to_Circle(i_main_stick_x, i_main_stick_y, _numPAD, PadMapping[_numPAD]); + std::vector main_xy = Pad_Square_to_Circle(i_main_stick_x, i_main_stick_y, _numPAD); i_main_stick_x = main_xy.at(0); i_main_stick_y = main_xy.at(1); } // Convert axis values - u8 main_stick_x = InputCommon::Pad_Convert(i_main_stick_x); - u8 main_stick_y = InputCommon::Pad_Convert(i_main_stick_y); - u8 sub_stick_x = InputCommon::Pad_Convert(i_sub_stick_x); - u8 sub_stick_y = InputCommon::Pad_Convert(i_sub_stick_y); + u8 main_stick_x = Pad_Convert(i_main_stick_x); + u8 main_stick_y = Pad_Convert(i_main_stick_y); + u8 sub_stick_x = Pad_Convert(i_sub_stick_x); + u8 sub_stick_y = Pad_Convert(i_sub_stick_y); // Convert the triggers values, if we are using analog triggers at all - if(PadMapping[_numPAD].triggertype == InputCommon::CTL_TRIGGER_SDL) + if(PadMapping[_numPAD].triggertype == CTL_TRIGGER_SDL) { - if(PadMapping[_numPAD].buttons[InputCommon::CTL_L_SHOULDER] >= 1000) TriggerLeft = InputCommon::Pad_Convert(TriggerLeft); - if(PadMapping[_numPAD].buttons[InputCommon::CTL_R_SHOULDER] >= 1000) TriggerRight = InputCommon::Pad_Convert(TriggerRight); + if(PadMapping[_numPAD].buttons[CTL_L_SHOULDER] >= 1000) TriggerLeft = Pad_Convert(TriggerLeft); + if(PadMapping[_numPAD].buttons[CTL_R_SHOULDER] >= 1000) TriggerRight = Pad_Convert(TriggerRight); } // Set Deadzones (perhaps out of function?) @@ -456,7 +520,7 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) _pPADStatus->button |= PAD_USE_ORIGIN; // Neutral value, no button pressed // Check if the digital L button is pressed - if (PadState[_numPAD].buttons[InputCommon::CTL_L_SHOULDER]) + if (PadState[_numPAD].buttons[CTL_L_SHOULDER]) { _pPADStatus->button |= PAD_TRIGGER_L; _pPADStatus->triggerLeft = TriggerValue; @@ -465,7 +529,7 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) _pPADStatus->triggerLeft = TriggerLeft; // Check if the digital R button is pressed - if (PadState[_numPAD].buttons[InputCommon::CTL_R_SHOULDER]) + if (PadState[_numPAD].buttons[CTL_R_SHOULDER]) { _pPADStatus->button |= PAD_TRIGGER_R; _pPADStatus->triggerRight = TriggerValue; @@ -481,26 +545,26 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) /////////////////////////////////////////////////// // The digital buttons // ----------- - if (PadState[_numPAD].buttons[InputCommon::CTL_A_BUTTON]) + if (PadState[_numPAD].buttons[CTL_A_BUTTON]) { _pPADStatus->button |= PAD_BUTTON_A; _pPADStatus->analogA = 255; // Perhaps support pressure? } - if (PadState[_numPAD].buttons[InputCommon::CTL_B_BUTTON]) + if (PadState[_numPAD].buttons[CTL_B_BUTTON]) { _pPADStatus->button |= PAD_BUTTON_B; _pPADStatus->analogB = 255; // Perhaps support pressure? } - if (PadState[_numPAD].buttons[InputCommon::CTL_X_BUTTON]) _pPADStatus->button|=PAD_BUTTON_X; - if (PadState[_numPAD].buttons[InputCommon::CTL_Y_BUTTON]) _pPADStatus->button|=PAD_BUTTON_Y; - if (PadState[_numPAD].buttons[InputCommon::CTL_Z_TRIGGER]) _pPADStatus->button|=PAD_TRIGGER_Z; - if (PadState[_numPAD].buttons[InputCommon::CTL_START]) _pPADStatus->button|=PAD_BUTTON_START; + if (PadState[_numPAD].buttons[CTL_X_BUTTON]) _pPADStatus->button|=PAD_BUTTON_X; + if (PadState[_numPAD].buttons[CTL_Y_BUTTON]) _pPADStatus->button|=PAD_BUTTON_Y; + if (PadState[_numPAD].buttons[CTL_Z_TRIGGER]) _pPADStatus->button|=PAD_TRIGGER_Z; + if (PadState[_numPAD].buttons[CTL_START]) _pPADStatus->button|=PAD_BUTTON_START; /////////////////////////////////////////////////// // The D-pad // ----------- - if (PadMapping[_numPAD].controllertype == InputCommon::CTL_DPAD_HAT) + if (PadMapping[_numPAD].controllertype == 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_LEFT || PadState[_numPAD].dpad == SDL_HAT_LEFTDOWN ) _pPADStatus->button|=PAD_BUTTON_LEFT; @@ -509,13 +573,13 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) } else { - if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_UP]) + if (PadState[_numPAD].dpad2[CTL_D_PAD_UP]) _pPADStatus->button |= PAD_BUTTON_UP; - if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_DOWN]) + if (PadState[_numPAD].dpad2[CTL_D_PAD_DOWN]) _pPADStatus->button |= PAD_BUTTON_DOWN; - if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_LEFT]) + if (PadState[_numPAD].dpad2[CTL_D_PAD_LEFT]) _pPADStatus->button |= PAD_BUTTON_LEFT; - if (PadState[_numPAD].dpad2[InputCommon::CTL_D_PAD_RIGHT]) + if (PadState[_numPAD].dpad2[CTL_D_PAD_RIGHT]) _pPADStatus->button |= PAD_BUTTON_RIGHT; } @@ -581,7 +645,226 @@ 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 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 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 + ); */ +} +////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h index 669d7907e4..9295304e7e 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h @@ -35,9 +35,6 @@ // ŻŻŻŻŻŻŻŻŻŻ // Set this if you want to use the rumble 'hack' for controller one //#define USE_RUMBLE_DINPUT_HACK - -// Show a status window with the detected axes, buttons and so on -//#define SHOW_PAD_STATUS ////////////////////////// @@ -48,9 +45,7 @@ #include #include #include - -#include "../../../Core/InputCommon/Src/SDL.h" // Core -#include "../../../Core/InputCommon/Src/XInput.h" +#include #include "Common.h" // Common #include "pluginspecs_pad.h" @@ -59,6 +54,7 @@ //#include "Timer.h" #include "Config.h" // Local +#include "XInput.h" #if defined(HAVE_WX) && HAVE_WX #include "GUI/AboutBox.h" @@ -106,6 +102,115 @@ #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 // ŻŻŻŻŻŻŻŻŻ @@ -120,11 +225,11 @@ extern std::vector Keys; ////////////////////////////////////////////////////////////////////////////////////////// // Variables // ŻŻŻŻŻŻŻŻŻ -#ifndef _EXCLUDE_MAIN_ +#ifndef _CONTROLLER_STATE_H extern FILE *pFile; - extern std::vector joyinfo; - extern InputCommon::CONTROLLER_STATE PadState[4]; - extern InputCommon::CONTROLLER_MAPPING PadMapping[4]; + extern std::vector joyinfo; + extern CONTROLLER_STATE PadState[4]; + extern CONTROLLER_MAPPING PadMapping[4]; extern HWND m_hWnd; // Handle to window extern int NumPads, NumGoodPads; // Number of goods pads #endif @@ -133,12 +238,16 @@ extern std::vector Keys; ////////////////////////////////////////////////////////////////////////////////////////// // Custom Functions // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ -bool Search_Devices(std::vector &_joyinfo, int &_NumPads, int &_NumGoodPads); + +void GetJoyState(int controller); +int Search_Devices(); void DEBUG_INIT(); void DEBUG_QUIT(); bool IsFocus(); void Pad_Use_Rumble(u8 _numPAD, SPADStatus* _pPADStatus); // Rumble +int Pad_Convert(int _val); // Value conversion +std::vector Pad_Square_to_Circle(int _x, int _y, int _pad); // Value conversion //void SaveConfig(); //void LoadConfig();