From 5e5e507121d28ede384273811808cc948c2ff1f6 Mon Sep 17 00:00:00 2001 From: John Peterson Date: Sun, 28 Dec 2008 18:50:24 +0000 Subject: [PATCH] nJoy: Enabled keyboard input (only for buttons so far) through wxWidgets in the main application. It only works when you render to the main window. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1706 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/Common.h | 53 ++++++-- Source/Core/Common/Src/MsgHandler.cpp | 94 ++++++++------ Source/Core/Core/Src/Plugins/Plugin_PAD.cpp | 6 +- Source/Core/Core/Src/Plugins/Plugin_PAD.h | 2 + Source/Core/DolphinWX/Src/Frame.cpp | 21 ++- Source/Core/DolphinWX/Src/Frame.h | 2 +- Source/Core/DolphinWX/Src/Main.cpp | 31 +++-- Source/PluginSpecs/pluginspecs_pad.h | 8 ++ .../Plugin_PadSimple/Src/PadSimple.cpp | 6 + .../Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj | 6 +- Source/Plugins/Plugin_nJoy_SDL/Src/Config.cpp | 121 ++++++++++++++---- Source/Plugins/Plugin_nJoy_SDL/Src/Config.h | 6 +- .../Src/GUI/ConfigAdvanced.cpp | 13 +- .../Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp | 100 +++++++++++---- .../Plugin_nJoy_SDL/Src/GUI/ConfigBox.h | 8 +- .../Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp | 62 +++++++-- Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp | 36 +++++- Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h | 16 ++- .../Plugin_nJoy_Testing/Src/GUI/ConfigBox.h | 4 +- .../Plugins/Plugin_nJoy_Testing/Src/nJoy.cpp | 18 ++- 20 files changed, 460 insertions(+), 153 deletions(-) diff --git a/Source/Core/Common/Src/Common.h b/Source/Core/Common/Src/Common.h index 107bee2a8b..0c323f51d4 100644 --- a/Source/Core/Common/Src/Common.h +++ b/Source/Core/Common/Src/Common.h @@ -189,24 +189,45 @@ inline u64 swap64(u64 data) {return(((u64)swap32(data) << 32) | swap32(data >> 3 } // end of namespace Common -// Utility functions -// Msg Alert +////////////////////////////////////////////////////////////////////////////////////////// +// Utility functions +// ŻŻŻŻŻŻŻŻŻ + + +/////////////////////////// +// Message alerts +// ŻŻŻŻŻŻŻŻŻ +enum MSG_TYPE +{ + INFORMATION, + QUESTION, + WARNING, +}; + typedef bool (*MsgAlertHandler)(const char* caption, const char* text, - bool yes_no); + bool yes_no, int Style); void RegisterMsgAlertHandler(MsgAlertHandler handler); -extern bool MsgAlert(const char* caption, bool yes_no, const char* format, ...); +extern bool MsgAlert(const char* caption, bool yes_no, int Style, const char* format, ...); + #ifdef _WIN32 -#define SuccessAlert(format, ...) MsgAlert("SUCCESS", false, format, __VA_ARGS__) -#define PanicAlert(format, ...) MsgAlert("PANIC", false, format, __VA_ARGS__) -#define PanicYesNo(format, ...) MsgAlert("PANIC", true, format, __VA_ARGS__) -#define AskYesNo(format, ...) MsgAlert("ASK", true, format, __VA_ARGS__) + #define SuccessAlert(format, ...) MsgAlert("Information", false, INFORMATION, format, __VA_ARGS__) + #define PanicAlert(format, ...) MsgAlert("Warning", false, WARNING, format, __VA_ARGS__) + #define PanicYesNo(format, ...) MsgAlert("Warning", true, WARNING, format, __VA_ARGS__) + #define AskYesNo(format, ...) MsgAlert("Question", true, QUESTION, format, __VA_ARGS__) #else -#define SuccessAlert(format, ...) MsgAlert("SUCCESS", false, format, ##__VA_ARGS__) -#define PanicAlert(format, ...) MsgAlert("PANIC", false, format, ##__VA_ARGS__) -#define PanicYesNo(format, ...) MsgAlert("PANIC", true, format, ##__VA_ARGS__) -#define AskYesNo(format, ...) MsgAlert("ASK", true, format, ##__VA_ARGS__) + #define SuccessAlert(format, ...) MsgAlert("SUCCESS", false, INFORMATION, format, ##__VA_ARGS__) + #define PanicAlert(format, ...) MsgAlert("PANIC", false, WARNING, format, ##__VA_ARGS__) + #define PanicYesNo(format, ...) MsgAlert("PANIC", true, WARNING, format, ##__VA_ARGS__) + #define AskYesNo(format, ...) MsgAlert("ASK", true, QUESTION, format, ##__VA_ARGS__) #endif + + + +/////////////////////////// +// Logging +// ŻŻŻŻŻŻŻŻŻ + extern void __Log(int logNumber, const char* text, ...); extern void __Logv(int log, int v, const char *format, ...); @@ -298,7 +319,10 @@ void Host_UpdateLogDisplay(); #define _assert_msg_(...) #endif -// compile time asserts + +////////////////////////////////////////////////////////////////////////////////////////// +// Compile time asserts +// ŻŻŻŻŻŻŻŻŻ namespace { @@ -313,8 +337,9 @@ namespace CompileTimeAssert<_SECURE_SCL==0> x; #endif #endif - } +////////////////////////////////// + #endif // #ifndef _COMMON_H diff --git a/Source/Core/Common/Src/MsgHandler.cpp b/Source/Core/Common/Src/MsgHandler.cpp index c3a9cae59d..fdb8ad97b2 100644 --- a/Source/Core/Common/Src/MsgHandler.cpp +++ b/Source/Core/Common/Src/MsgHandler.cpp @@ -15,53 +15,71 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include -#include "Common.h" +////////////////////////////////////////////////////////////////////////////////////// +// Include and declarations +// ŻŻŻŻŻŻŻŻŻ +#include // System + +#include "Common.h" // Local #include "StringUtil.h" -bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no); - +bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style); static MsgAlertHandler msg_handler = DefaultMsgHandler; +///////////////////////////// + +/* Select which of these functions that are used for message boxes. If wxWidgets is enabled + we will use wxMsgAlert() that is defined in main.cpp */ void RegisterMsgAlertHandler(MsgAlertHandler handler) { - msg_handler = handler; + msg_handler = handler; } -bool MsgAlert(const char* caption, bool yes_no, const char* format, ...) -{ - char buffer[2048]; - va_list args; - bool ret = false; - - va_start(args, format); - CharArrayFromFormatV(buffer, 2048, format, args); - - LOG(MASTER_LOG, "%s: %s", caption, buffer); - - if (msg_handler) - { - ret = msg_handler(caption, buffer, yes_no); - } - - va_end(args); - return ret; -} - -bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no) +///////////////////////////////////////////////////////////// +/* This is the first stop for messages where the log is updated and the correct windows + is shown */ +// ŻŻŻŻŻŻŻŻŻ +bool MsgAlert(const char* caption, bool yes_no, int Style, const char* format, ...) { -#ifdef _WIN32 - if (yes_no) - return IDYES == MessageBox(0, text, caption, - MB_ICONQUESTION | MB_YESNO); - else { - MessageBox(0, text, caption, MB_ICONWARNING); - return true; - } -#else - printf("%s\n", text); - return true; -#endif + // --------------------------------- + // Read message and write it to the log + // ----------- + char buffer[2048]; + va_list args; + bool ret = false; + + va_start(args, format); + CharArrayFromFormatV(buffer, 2048, format, args); + + LOG(MASTER_LOG, "%s: %s", caption, buffer); + // ----------- + + if (msg_handler) { + ret = msg_handler(caption, buffer, yes_no, Style); + } + + va_end(args); + return ret; +} + +///////////////////////////////////////////////////////////// +/* This is used in the No-GUI build */ +// ŻŻŻŻŻŻŻŻŻ +bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style) +{ + #ifdef _WIN32 + if (yes_no) + // Return true for IDYES + return IDYES == MessageBox(0, "Why is there no icon", caption, + MB_ICONQUESTION | MB_YESNO); + else { + MessageBox(0, text, caption, MB_ICONWARNING); + return true; + } + #else + printf("%s\n", text); + return true; + #endif } diff --git a/Source/Core/Core/Src/Plugins/Plugin_PAD.cpp b/Source/Core/Core/Src/Plugins/Plugin_PAD.cpp index 2402d002cf..6416ceeab2 100644 --- a/Source/Core/Core/Src/Plugins/Plugin_PAD.cpp +++ b/Source/Core/Core/Src/Plugins/Plugin_PAD.cpp @@ -27,6 +27,7 @@ TPAD_Shutdown PAD_Shutdown = 0; TDllConfig DllConfig = 0; TPAD_Initialize PAD_Initialize = 0; TPAD_GetStatus PAD_GetStatus = 0; +TPAD_Input PAD_Input = 0; TPAD_Rumble PAD_Rumble = 0; TPAD_GetAttachedPads PAD_GetAttachedPads = 0; @@ -47,6 +48,7 @@ void UnloadPlugin() DllConfig = 0; PAD_Initialize = 0; PAD_GetStatus = 0; + PAD_Input = 0; PAD_Rumble = 0; } @@ -59,6 +61,7 @@ bool LoadPlugin(const char *_Filename) PAD_Initialize = reinterpret_cast (plugin.Get("PAD_Initialize")); PAD_Shutdown = reinterpret_cast (plugin.Get("PAD_Shutdown")); PAD_GetStatus = reinterpret_cast (plugin.Get("PAD_GetStatus")); + PAD_Input = reinterpret_cast (plugin.Get("PAD_Input")); PAD_Rumble = reinterpret_cast (plugin.Get("PAD_Rumble")); PAD_GetAttachedPads = reinterpret_cast(plugin.Get("PAD_GetAttachedPads")); @@ -66,7 +69,8 @@ bool LoadPlugin(const char *_Filename) (DllConfig != 0) && (PAD_Initialize != 0) && (PAD_Shutdown != 0) && - (PAD_GetStatus != 0)) + (PAD_GetStatus != 0) && + (PAD_Input != 0)) { return true; } diff --git a/Source/Core/Core/Src/Plugins/Plugin_PAD.h b/Source/Core/Core/Src/Plugins/Plugin_PAD.h index d4fc1ca630..6b2725144c 100644 --- a/Source/Core/Core/Src/Plugins/Plugin_PAD.h +++ b/Source/Core/Core/Src/Plugins/Plugin_PAD.h @@ -33,6 +33,7 @@ typedef void (__cdecl* TDllConfig)(HWND); typedef void (__cdecl* TPAD_Initialize)(SPADInitialize); typedef void (__cdecl* TPAD_Shutdown)(); typedef void (__cdecl* TPAD_GetStatus)(u8, SPADStatus*); +typedef void (__cdecl* TPAD_Input)(u8, u8); typedef void (__cdecl* TPAD_Rumble)(u8, unsigned int, unsigned int); typedef unsigned int (__cdecl* TPAD_GetAttachedPads)(); @@ -42,6 +43,7 @@ extern TPAD_Shutdown PAD_Shutdown; extern TDllConfig DllConfig; extern TPAD_Initialize PAD_Initialize; extern TPAD_GetStatus PAD_GetStatus; +extern TPAD_Input PAD_Input; extern TPAD_Rumble PAD_Rumble; extern TPAD_GetAttachedPads PAD_GetAttachedPads; diff --git a/Source/Core/DolphinWX/Src/Frame.cpp b/Source/Core/DolphinWX/Src/Frame.cpp index 5c6a0cb6e7..3eb124a549 100644 --- a/Source/Core/DolphinWX/Src/Frame.cpp +++ b/Source/Core/DolphinWX/Src/Frame.cpp @@ -31,6 +31,7 @@ #include "Config.h" // Core #include "Core.h" #include "HW/DVDInterface.h" +#include "Plugins/Plugin_PAD.h" #include "State.h" #include "VolumeHandler.h" @@ -172,6 +173,10 @@ CFrame::CFrame(wxFrame* parent, wxKeyEventHandler(CFrame::OnKeyDown), (wxObject*)0, this); + wxTheApp->Connect(wxID_ANY, wxEVT_KEY_UP, + wxKeyEventHandler(CFrame::OnKeyUp), + (wxObject*)0, this); + UpdateGUI(); } @@ -506,7 +511,7 @@ void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event)) void CFrame::OnStop(wxCommandEvent& WXUNUSED (event)) { // Ask for confirmation in case the user accidently clicked Stop - int answer; + bool answer; if(SConfig::GetInstance().m_LocalCoreStartupParameter.bConfirmStop) { answer = AskYesNo("Are you sure you want to stop the current emulation?", @@ -514,10 +519,10 @@ void CFrame::OnStop(wxCommandEvent& WXUNUSED (event)) } else { - answer = wxYES; + answer = true; } - if (answer == wxYES && Core::GetState() != Core::CORE_UNINITIALIZED) + if (answer && Core::GetState() != Core::CORE_UNINITIALIZED) { Core::Stop(); UpdateGUI(); @@ -690,8 +695,18 @@ void CFrame::OnKeyDown(wxKeyEvent& event) #endif else { + if(Core::GetState() != Core::CORE_UNINITIALIZED) + PluginPAD::PAD_Input(event.GetKeyCode(), 1); // 1 = Down event.Skip(); } + //if(event.GetKeyCode() == 80) PanicAlert("Core 80"); +} + +void CFrame::OnKeyUp(wxKeyEvent& event) +{ + if(Core::GetState() != Core::CORE_UNINITIALIZED) + PluginPAD::PAD_Input(event.GetKeyCode(), 0); // 0 = Up + event.Skip(); } diff --git a/Source/Core/DolphinWX/Src/Frame.h b/Source/Core/DolphinWX/Src/Frame.h index 3432e903db..e884eef89c 100644 --- a/Source/Core/DolphinWX/Src/Frame.h +++ b/Source/Core/DolphinWX/Src/Frame.h @@ -117,7 +117,7 @@ class CFrame : public wxFrame void OnResize(wxSizeEvent& event); void OnToggleToolbar(wxCommandEvent& event); void OnToggleStatusbar(wxCommandEvent& event); - void OnKeyDown(wxKeyEvent& event); + void OnKeyDown(wxKeyEvent& event); void OnKeyUp(wxKeyEvent& event); void OnHostMessage(wxCommandEvent& event); void OnMemcard(wxCommandEvent& event); // Misc diff --git a/Source/Core/DolphinWX/Src/Main.cpp b/Source/Core/DolphinWX/Src/Main.cpp index f984408b2c..b8844ddffe 100644 --- a/Source/Core/DolphinWX/Src/Main.cpp +++ b/Source/Core/DolphinWX/Src/Main.cpp @@ -46,7 +46,7 @@ IMPLEMENT_APP(DolphinApp) #if defined(HAVE_WX) && HAVE_WX -bool wxMsgAlert(const char*, const char*, bool); + bool wxMsgAlert(const char*, const char*, bool, int); #endif CFrame* main_frame = NULL; @@ -278,18 +278,27 @@ void DolphinApp::OnEndSession() SConfig::GetInstance().SaveSettings(); } +///////////////////////////////////////////////////////////// +/* We declare this here instead of in Common/MsgHandler.cpp because we want to keep Common + free of wxWidget functions */ +// ŻŻŻŻŻŻŻŻŻ +bool wxMsgAlert(const char* caption, const char* text, bool yes_no, int Style) +{ + #ifdef _WIN32 + /* In Windows we use a MessageBox isntead of a wxMessageBox to don't block + the debug window */ + int STYLE = MB_ICONINFORMATION; + if(Style == QUESTION) STYLE = MB_ICONQUESTION; + if(Style == WARNING) STYLE = MB_ICONWARNING; -bool wxMsgAlert(const char* caption, const char* text, - bool yes_no) { -#ifdef _WIN32 - // I like parentless messageboxes - don't block the debug window. - return IDYES == MessageBox(0, text, caption, yes_no?MB_YESNO:MB_OK); -#else - return wxYES == wxMessageBox(wxString::FromAscii(text), - wxString::FromAscii(caption), - (yes_no)?wxYES_NO:wxOK); -#endif + return IDYES == MessageBox(0, text, caption, STYLE | (yes_no ? MB_YESNO : MB_OK)); + #else + return wxYES == wxMessageBox(wxString::FromAscii(text), + wxString::FromAscii(caption), + (yes_no)?wxYES_NO:wxOK); + #endif } +////////////////////////////////// // OK, this thread boundary is DANGEROUS on linux diff --git a/Source/PluginSpecs/pluginspecs_pad.h b/Source/PluginSpecs/pluginspecs_pad.h index 131451a6cf..bf205cd1cd 100644 --- a/Source/PluginSpecs/pluginspecs_pad.h +++ b/Source/PluginSpecs/pluginspecs_pad.h @@ -108,6 +108,14 @@ EXPORT void CALL PAD_Shutdown(); // EXPORT void CALL PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus); +// __________________________________________________________________________________________________ +// Function: Send keyboard input to the plugin +// Purpose: +// input: The key and if it's pressed or released +// output: None +// +EXPORT void CALL PAD_Input(u8 _Key, u8 _UpDown); + // __________________________________________________________________________________________________ // Function: PAD_Rumble // Purpose: Pad rumble! diff --git a/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp b/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp index 6aab0c92e9..2efacdb632 100644 --- a/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp +++ b/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp @@ -473,6 +473,12 @@ void X11_Read(int _numPAD, SPADStatus* _pPADStatus) #endif + +// Set buttons status from wxWidgets in the main application +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +void PAD_Input(u8 _Key, u8 _UpDown) {} + + void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) { // Check if all is okay diff --git a/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj b/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj index 9465280776..87a6548d6b 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj +++ b/Source/Plugins/Plugin_nJoy_SDL/Plugin_nJoy_SDL.vcproj @@ -51,7 +51,7 @@ RuntimeLibrary="1" UsePrecompiledHeader="0" WarningLevel="3" - WarnAsError="true" + WarnAsError="false" DebugInformationFormat="4" /> &Duplicates) +int Config::CheckForDuplicateJoypads(bool OK) { // Count the number of duplicate names - int NumDuplicates = 0; - for(u32 i = 0; i < Duplicates.size(); i++) - if(_Name == Duplicates.at(i)) NumDuplicates++; + int NumDuplicates = 0, Duplicate; + for(u32 i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + // Avoid potential crash + if(joysticks[i].ID >= SDL_NumJoysticks() || joysticks[j].ID >= SDL_NumJoysticks()) continue; - Duplicates.push_back(_Name); // Add the name + if (i == j) continue; // Don't compare to itself + if (! memcmp(&joyinfo[joysticks[i].ID], &joyinfo[joysticks[j].ID], sizeof(joyinfo))) + { + // If one of them is not enabled, then there is no problem + if(!joysticks[i].enabled || !joysticks[j].enabled) continue; - // Return an amended name if we found a duplicate + // If oen of them don't save by ID, then there is no problem + if(!g_Config.bSaveByID.at(i) || !g_Config.bSaveByID.at(j)) continue; + + //PanicAlert("%i %i", i, j); + NumDuplicates++; + Duplicate = i; + } + } + } + + ///////////////////////////////////////////////////////////////////////// + // Notify the user about the multiple devices + // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ + int ReturnMessage; if(NumDuplicates > 0) - return StringFromFormat("%s (%i)", _Name.c_str(), NumDuplicates); + { + wxString ExtendedText; + wxString MainText = wxString::Format(wxT( + "You have selected SaveByID for several identical joypads with the name '%s', because nJoy" + " has no way of separating between them the settings for the last one will now be saved." + " This may not be the settings you have intended to save. It is therefore recommended" + " that you either unselect SaveByID for all but one of the identical joypads" + " or disable them entirely." + " If you are aware of this issue and want to keep the same settings for the identical" + " pads you can ignore this message.") + , joyinfo[joysticks[Duplicate].ID].Name); + if (OK) // We got here from the OK button + { + ExtendedText = wxString::Format(wxT( + "\n\n[Select 'OK' to return to the configuration window. Select 'Cancel' to ignore this" + " message and close the configuration window and don't show this message again.]")); + + ReturnMessage = wxMessageBox(wxString::Format + (wxT("%s%s"), MainText , ExtendedText), wxT("Notice"), + (wxOK | wxCANCEL) | wxICON_INFORMATION, 0, 100); + if (ReturnMessage == wxCANCEL) g_Config.bSaveByIDNotice = false; + } + else + { + ExtendedText = wxString::Format(wxT( + "\n\n[Select 'Cancel' if you don't want to see this information again.]")); + + ReturnMessage = wxMessageBox(wxString::Format + (wxT("%s%s"), MainText , ExtendedText), wxT("Notice"), + (wxOK | wxCANCEL) | wxICON_INFORMATION, 0, 100); + if (ReturnMessage == wxCANCEL) g_Config.bSaveByIDNotice = false; + } + } else - return _Name; + { + ReturnMessage = -1; + } + + return ReturnMessage; + ////////////////////////////////////// } // Save settings to file // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ -void Config::Save() +void Config::Save(bool CheckedForDuplicates) { IniFile file; file.Load("nJoy.ini"); - std::vector Duplicates; - file.Set("General", "SaveByID", g_Config.bSaveByID); + // Show potential warning + if(!CheckedForDuplicates && g_Config.bSaveByIDNotice) CheckForDuplicateJoypads(false); + file.Set("General", "ShowAdvanced", g_Config.bShowAdvanced); + file.Set("General", "SaveByIDNotice", g_Config.bSaveByIDNotice); for (int i = 0; i < 4; i++) { std::string SectionName = StringFromFormat("PAD%i", i+1); - file.Set(SectionName.c_str(), "joy_id", joysticks[i].ID); - file.Set(SectionName.c_str(), "enabled", joysticks[i].enabled); + file.Set(SectionName.c_str(), "enabled", joysticks[i].enabled); + + // Save the physical device ID + file.Set(SectionName.c_str(), "joy_id", joysticks[i].ID); + file.Set(SectionName.c_str(), "SaveByID", g_Config.bSaveByID.at(i)); + + /* Don't save anything more from the disabled joypads, if a joypad is enabled we can run + this again after any settings are changed for it */ + if(!joysticks[i].enabled) continue; ////////////////////////////////////// // Save joypad specific settings // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ // Current joypad device ID: joysticks[i].ID - // Current joypad name: joyinfo[joysticks[i].ID].Name - if(g_Config.bSaveByID) + // Current joypad name: joyinfo[joysticks[i].ID].Name + if(g_Config.bSaveByID.at(i)) { /* Save joypad specific settings. Check for "joysticks[i].ID < SDL_NumJoysticks()" to avoid reading a joyinfo that does't exist */ @@ -136,8 +202,8 @@ void Config::Save() //if(i == 0) PanicAlert("%i", joysticks[i].buttons[CTL_START]); //PanicAlert("%s", joyinfo[joysticks[i].ID].Name); - // Create a section name - SectionName = CheckForDuplicateNames(joyinfo[joysticks[i].ID].Name, Duplicates); + // Create a new section name after the joypad name + SectionName = joyinfo[joysticks[i].ID].Name; } file.Set(SectionName.c_str(), "l_shoulder", joysticks[i].buttons[CTL_L_SHOULDER]); @@ -179,9 +245,8 @@ void Config::Load(bool config) file.Load("nJoy.ini"); std::vector Duplicates; - file.Get("General", "SaveByID", &g_Config.bSaveByID, false); file.Get("General", "ShowAdvanced", &g_Config.bShowAdvanced, false); - + file.Get("General", "SaveByIDNotice", &g_Config.bSaveByIDNotice, true); for (int i = 0; i < 4; i++) { @@ -193,13 +258,17 @@ void Config::Load(bool config) file.Get(SectionName.c_str(), "joy_id", &joysticks[i].ID, 0); file.Get(SectionName.c_str(), "enabled", &joysticks[i].enabled, 1); } - + + bool Tmp; + file.Get(SectionName.c_str(), "SaveByID", &Tmp, false); + g_Config.bSaveByID.at(i) = Tmp; + ////////////////////////////////////// // Load joypad specific settings // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ // Current joypad device ID: joysticks[i].ID // Current joypad name: joyinfo[joysticks[i].ID].Name - if(g_Config.bSaveByID) + if(g_Config.bSaveByID.at(i)) { /* Prevent a crash from illegal access to joyinfo that will only have values for the current amount of connected joysticks */ @@ -209,7 +278,7 @@ void Config::Load(bool config) //PanicAlert("%s", joyinfo[joysticks[i].ID].Name); // Create a section name - SectionName = CheckForDuplicateNames(joyinfo[joysticks[i].ID].Name, Duplicates); + SectionName = joyinfo[joysticks[i].ID].Name; } file.Get(SectionName.c_str(), "l_shoulder", &joysticks[i].buttons[CTL_L_SHOULDER], 4); diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/Config.h b/Source/Plugins/Plugin_nJoy_SDL/Src/Config.h index 09232a1571..211adce329 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/Config.h +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/Config.h @@ -22,12 +22,12 @@ struct Config { Config(); void Load(bool Config = false); - void Save(); - std::string CheckForDuplicateNames(std::string _Name, std::vector &Duplicates); + void Save(bool CheckedForDuplicates = false); + int CheckForDuplicateJoypads(bool OK); // General bool bShowAdvanced; // Only allow one of these - bool bSaveByID; + std::vector bSaveByID; bool bSaveByIDNotice; // Joystick std::string SDiagonal; diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp index 78eb1389c7..9056899370 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigAdvanced.cpp @@ -49,10 +49,19 @@ bool StrangeHack = true; // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void ConfigBox::PadGetStatus() { + // Return if it's not detected + if(joysticks[notebookpage].ID >= SDL_NumJoysticks()) + { + m_TStatusIn[notebookpage]->SetLabel(wxT("Not connected")); + m_TStatusOut[notebookpage]->SetLabel(wxT("Not connected")); + return; + } + // Return if it's not enabled if (!joysticks[notebookpage].enabled) { m_TStatusIn[notebookpage]->SetLabel(wxT("Not enabled")); + m_TStatusOut[notebookpage]->SetLabel(wxT("Not enabled")); return; } @@ -128,8 +137,8 @@ void ConfigBox::Update() /* m_pStatusBar->SetLabel(wxString::Format( - "ID: %i %i %i", - m_Joyname[0]->GetSelection(), (int)StrangeHack, (int)g_Config.bShowAdvanced + "Id: %i", + joysticks[0].ID ));*/ } diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp index e8950ac21c..e3833db171 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.cpp @@ -67,6 +67,7 @@ BEGIN_EVENT_TABLE(ConfigBox,wxDialog) EVT_NOTEBOOK_PAGE_CHANGED(ID_NOTEBOOK, ConfigBox::NotebookPageChanged) EVT_CHECKBOX(IDC_SAVEBYID, ConfigBox::ChangeSettings) // Settings + EVT_CHECKBOX(IDC_SAVEBYIDNOTICE, ConfigBox::ChangeSettings) EVT_CHECKBOX(IDC_SHOWADVANCED, ConfigBox::ChangeSettings) EVT_COMBOBOX(IDCB_MAINSTICK_DIAGONAL, ConfigBox::ChangeSettings) EVT_CHECKBOX(IDCB_MAINSTICK_S_TO_C, ConfigBox::ChangeSettings) @@ -102,14 +103,20 @@ ConfigBox::ConfigBox(wxWindow *parent, wxWindowID id, const wxString &title, , m_timer(this) #endif { - + // Define values notebookpage = 0; + g_Pressed = 0; + + // Create controls CreateGUIControls(); #if wxUSE_TIMER m_timer.Start( floor((double)(1000 / 30)) ); #endif + wxTheApp->Connect(wxID_ANY, wxEVT_KEY_DOWN, + wxKeyEventHandler(ConfigBox::OnKeyDown), + (wxObject*)0, this); } @@ -118,6 +125,14 @@ ConfigBox::~ConfigBox() // empty } +void ConfigBox::OnKeyDown(wxKeyEvent& event) +{ + /*m_pStatusBar->SetLabel(wxString::Format( + "Key: %i", event.GetKeyCode() + ));*/ + g_Pressed = event.GetKeyCode(); +} + // Close window // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void ConfigBox::OnClose(wxCloseEvent& /*event*/) @@ -152,8 +167,15 @@ void ConfigBox::OKClick(wxCommandEvent& event) { if (event.GetId() == ID_OK) { + // Check for duplicate joypads + if(g_Config.bSaveByIDNotice) + { + int Tmp = g_Config.CheckForDuplicateJoypads(true); + if (Tmp == wxOK) return; else if (Tmp == wxNO) g_Config.bSaveByIDNotice = false; + } + for(int i=0; i<4 ;i++) GetControllerAll(i); // Update joysticks array - g_Config.Save(); // Save settings + g_Config.Save(true); // Save settings g_Config.Load(); // Reload settings Close(); // Call OnClose() } @@ -179,8 +201,11 @@ void ConfigBox::ChangeSettings( wxCommandEvent& event ) switch(event.GetId()) { case IDC_SAVEBYID: - g_Config.bSaveByID = m_CBSaveByID[notebookpage]->IsChecked(); + g_Config.bSaveByID.at(notebookpage) = m_CBSaveByID[notebookpage]->IsChecked(); break; + case IDC_SAVEBYIDNOTICE: + g_Config.bSaveByIDNotice = m_CBSaveByIDNotice[notebookpage]->IsChecked(); + break; case IDC_SHOWADVANCED: g_Config.bShowAdvanced = m_CBShowAdvanced[notebookpage]->IsChecked(); @@ -205,16 +230,20 @@ void ConfigBox::ChangeSettings( wxCommandEvent& event ) // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void ConfigBox::EnableDisable(wxCommandEvent& event) { + // First save the settings as they are now, disabled controls will not be saved later + g_Config.Save(); + // Update the enable / disable status DoEnableDisable(notebookpage); } void ConfigBox::DoEnableDisable(int _notebookpage) { -#ifdef _WIN32 // There is no FindItem in linux so this doesn't work + // Update the enable / disable status joysticks[_notebookpage].enabled = m_Joyattach[_notebookpage]->GetValue(); +#ifdef _WIN32 // There is no FindItem in linux so this doesn't work // Enable or disable all buttons for(int i = IDB_SHOULDER_L; i < (IDB_SHOULDER_L + 13 + 4); i++) { @@ -224,9 +253,11 @@ void ConfigBox::DoEnableDisable(int _notebookpage) // Enable or disable settings controls m_Controller[_notebookpage]->FindItem(IDC_DEADZONE)->Enable(joysticks[_notebookpage].enabled); m_Controller[_notebookpage]->FindItem(IDC_CONTROLTYPE)->Enable(joysticks[_notebookpage].enabled); +#endif // General settings - m_CBSaveByID[_notebookpage]->SetValue(g_Config.bSaveByID); + m_CBSaveByID[_notebookpage]->SetValue(g_Config.bSaveByID.at(_notebookpage)); + m_CBSaveByIDNotice[_notebookpage]->SetValue(g_Config.bSaveByIDNotice); m_CBShowAdvanced[_notebookpage]->SetValue(g_Config.bShowAdvanced); // Advanced settings @@ -234,7 +265,7 @@ void ConfigBox::DoEnableDisable(int _notebookpage) m_CBS_to_C[notebookpage]->SetValue(g_Config.bSquareToCircle); m_Controller[_notebookpage]->Refresh(); // Repaint the background -#endif + } @@ -250,14 +281,11 @@ void ConfigBox::NotebookPageChanged(wxNotebookEvent& event) // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void ConfigBox::ChangeJoystick(wxCommandEvent& event) { - // Save potential changes - if(g_Config.bSaveByID) - { - int Tmp = joysticks[notebookpage].ID; // Don't update the ID - GetControllerAll(notebookpage); - joysticks[notebookpage].ID = Tmp; - g_Config.Save(); - } + // Save potential changes to support SaveByID + int Tmp = joysticks[notebookpage].ID; // Don't update the ID + GetControllerAll(notebookpage); + joysticks[notebookpage].ID = Tmp; + g_Config.Save(); //PanicAlert("%i", m_Joyname[notebookpage]->GetSelection()); @@ -266,12 +294,10 @@ void ConfigBox::ChangeJoystick(wxCommandEvent& event) //PanicAlert("%i %i", joysticks[notebookpage].ID, notebookpage); - // Load device settings - if(g_Config.bSaveByID) - { - g_Config.Load(true); // Then load the current - SetControllerAll(notebookpage); - } + // Load device settings to support SaveByID + g_Config.Load(true); // Then load the current + SetControllerAll(notebookpage); // Update joystick dialog items + DoEnableDisable(notebookpage); // Update other dialog items // Remap the controller to if (joysticks[notebookpage].enabled) @@ -279,7 +305,6 @@ void ConfigBox::ChangeJoystick(wxCommandEvent& event) if (SDL_JoystickOpened(notebookpage)) SDL_JoystickClose(joystate[notebookpage].joy); joystate[notebookpage].joy = SDL_JoystickOpen(joysticks[notebookpage].ID); } - } @@ -322,6 +347,12 @@ void ConfigBox::CreateGUIControls() m_About = new wxButton(this, ID_ABOUT, wxT("About"), wxDefaultPosition, wxSize(75, 25), 0, wxDefaultValidator, wxT("About")); m_OK = new wxButton(this, ID_OK, wxT("OK"), wxDefaultPosition, wxSize(75, 25), 0, wxDefaultValidator, wxT("OK")); m_Cancel = new wxButton(this, ID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(75, 25), 0, wxDefaultValidator, wxT("Cancel")); + m_OK->SetToolTip( + wxT("Save your settings and close this window.") + ); + m_Cancel->SetToolTip( + wxT("Close this window without saving your changes.") + ); // Notebook m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize); @@ -515,6 +546,9 @@ void ConfigBox::CreateGUIControls() m_gJoyname[i]->Add(m_Joyname[i], 0, (wxLEFT | wxRIGHT), 5); m_gJoyname[i]->Add(m_Joyattach[i], 0, (wxRIGHT | wxLEFT | wxBOTTOM), 1); + m_Joyname[i]->SetToolTip(wxT("Save your settings and configure another joypad")); + + // -------------------------------------------------------------------- // Populate settings sizer // ----------------------------- @@ -525,11 +559,11 @@ void ConfigBox::CreateGUIControls() m_JoyButtonHalfpress[i]->Enable(false); m_bJoyButtonHalfpress[i] = new wxButton(m_Controller[i], IDB_BUTTONHALFPRESS, wxEmptyString, wxPoint(231, 426), wxSize(21, 14), 0, wxDefaultValidator, wxEmptyString); #ifdef _WIN32 - m_Deadzone[i] = new wxComboBox(m_Controller[i], IDC_DEADZONE, wxEmptyString, wxDefaultPosition, wxSize(59, 21), arrayStringFor_Deadzone, 0, wxDefaultValidator, wxT("m_Deadzone")); + m_Deadzone[i] = new wxComboBox(m_Controller[i], IDC_DEADZONE, wxEmptyString, wxDefaultPosition, wxSize(59, 21), arrayStringFor_Deadzone, wxCB_READONLY, wxDefaultValidator, wxT("m_Deadzone")); m_textDeadzone[i] = new wxStaticText(m_Controller[i], IDT_DEADZONE, wxT("Deadzone"), wxDefaultPosition, wxDefaultSize, 0, wxT("Deadzone")); m_textHalfpress[i] = new wxStaticText(m_Controller[i], IDT_BUTTONHALFPRESS, wxT("Half press"), wxDefaultPosition, wxDefaultSize, 0, wxT("Half press")); #else - m_Deadzone[i] = new wxComboBox(m_Controller[i], IDC_DEADZONE, wxEmptyString, wxPoint(167, 398), wxSize(80, 25), arrayStringFor_Deadzone, 0, wxDefaultValidator, wxT("m_Deadzone")); + m_Deadzone[i] = new wxComboBox(m_Controller[i], IDC_DEADZONE, wxEmptyString, wxPoint(167, 398), wxSize(80, 25), arrayStringFor_Deadzone, wxCB_READONLY, wxDefaultValidator, wxT("m_Deadzone")); m_textDeadzone[i] = new wxStaticText(m_Controller[i], IDT_DEADZONE, wxT("Deadzone"), wxPoint(105, 404), wxDefaultSize, 0, wxT("Deadzone")); m_textHalfpress[i] = new wxStaticText(m_Controller[i], IDT_BUTTONHALFPRESS, wxT("Half press"), wxPoint(105, 428), wxDefaultSize, 0, wxT("Half press")); #endif @@ -548,18 +582,29 @@ void ConfigBox::CreateGUIControls() m_Controltype[i] = new wxComboBox(m_Controller[i], IDC_CONTROLTYPE, arrayStringFor_Controltype[0], wxDefaultPosition, wxDefaultSize, arrayStringFor_Controltype, wxCB_READONLY); m_gControllertype[i]->Add(m_Controltype[i], 0, wxEXPAND | wxALL, 3); - // Populate general settings + // Create objects for general settings m_gGenSettings[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_CBSaveByIDNotice[i] = new wxCheckBox(m_Controller[i], IDC_SAVEBYIDNOTICE, wxT("Notice"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_CBShowAdvanced[i] = new wxCheckBox(m_Controller[i], IDC_SHOWADVANCED, wxT("Show advanced settings"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); - m_gGenSettings[i]->Add(m_CBSaveByID[i], 0, wxEXPAND | wxALL, 3); + + // Populate general settings + m_sSaveByID[i] = new wxBoxSizer(wxHORIZONTAL); + m_sSaveByID[i]->Add(m_CBSaveByID[i], 0, wxEXPAND | wxALL, 0); + m_sSaveByID[i]->Add(m_CBSaveByIDNotice[i], 0, wxEXPAND | wxLEFT, 2); + m_gGenSettings[i]->Add(m_sSaveByID[i], 0, wxEXPAND | wxALL, 3); m_gGenSettings[i]->Add(m_CBShowAdvanced[i], 0, wxEXPAND | wxALL, 3); + + // Create tooltips m_CBSaveByID[i]->SetToolTip(wxString::Format(wxT( "Map these settings to the selected controller device instead of to the" "\nselected controller number (%i). This may be a more convenient way" "\nto save your settings if you have multiple controllers.") , i+1 )); + m_CBSaveByIDNotice[i]->SetToolTip(wxString::Format(wxT( + "Show a notification message if you have selected this option for multiple identical joypads.") + )); // Populate settings m_sSettings[i] = new wxBoxSizer ( wxHORIZONTAL ); @@ -618,7 +663,6 @@ void ConfigBox::CreateGUIControls() m_gStatusInSettingsH[i]->Add(m_STDiagonal[i], 0, wxTOP, 3); m_gStatusInSettingsH[i]->Add(m_CoBDiagonal[i], 0, wxLEFT, 3); - ////////////////////////////////////// @@ -688,8 +732,8 @@ void ConfigBox::CreateGUIControls() // -------------------------------------------------------------------- // Debugging // ----------------------------- - //m_pStatusBar = new wxStaticText(this, IDT_DEBUGGING, wxT("Debugging"), wxPoint(100, 510), wxDefaultSize); - //m_pStatusBar2 = new wxStaticText(this, IDT_DEBUGGING2, wxT("Debugging2"), wxPoint(100, 530), wxDefaultSize); + m_pStatusBar = new wxStaticText(this, IDT_DEBUGGING, wxT("Debugging"), wxPoint(100, 510), wxDefaultSize); + m_pStatusBar2 = new wxStaticText(this, IDT_DEBUGGING2, wxT("Debugging2"), wxPoint(100, 530), 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 1aaf0910e3..1b1c2e6163 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigBox.h @@ -103,8 +103,8 @@ class ConfigBox : public wxDialog wxStaticBoxSizer *m_gExtrasettings[4]; wxGridBagSizer * m_gGBExtrasettings[4]; // Extra settings wxStaticBoxSizer *m_gControllertype[4]; - wxStaticBoxSizer *m_gGenSettings[4]; // General settings - wxCheckBox *m_CBSaveByID[4], *m_CBShowAdvanced[4]; + wxBoxSizer *m_sSaveByID[4]; wxStaticBoxSizer *m_gGenSettings[4]; // General settings + wxCheckBox *m_CBSaveByID[4], *m_CBSaveByIDNotice[4], *m_CBShowAdvanced[4]; wxStaticBoxSizer *m_gStatusIn[4], *m_gStatusInSettings[4]; // Advanced settings wxBoxSizer *m_gStatusInSettingsH[4]; @@ -116,6 +116,7 @@ class ConfigBox : public wxDialog ///////////////////////////// // Keys // ŻŻŻŻŻŻŻŻŻ + int g_Pressed; // Keyboard input wxTextCtrl *m_JoyShoulderL[4]; wxTextCtrl *m_JoyShoulderR[4]; @@ -197,7 +198,7 @@ class ConfigBox : public wxDialog IDG_CONTROLLERTYPE, IDC_CONTROLTYPE, // Controller type - IDC_SAVEBYID, IDC_SHOWADVANCED, // Settings + IDC_SAVEBYID, IDC_SAVEBYIDNOTICE, IDC_SHOWADVANCED, // Settings ID_INSTATUS1, ID_INSTATUS2, ID_INSTATUS3, ID_INSTATUS4, // Advanced status ID_STATUSBMP1, ID_STATUSBMP2, ID_STATUSBMP3, ID_STATUSBMP4, @@ -304,6 +305,7 @@ class ConfigBox : public wxDialog void OnPaint(wxPaintEvent &event); void SetButtonText(int id, char text[128]); + void OnKeyDown(wxKeyEvent& event); }; #endif diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp index fd8e45ac54..7ddf6d1c6c 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp @@ -94,7 +94,7 @@ void ConfigBox::SetControllerAll(int controller) } } -/* Populate the CONTROLLER_MAPPING joysticks array with the dialog items settings, for example +/* Populate the joysticks array with the dialog items settings, for example selected joystick, enabled or disabled status and so on */ // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void ConfigBox::GetControllerAll(int controller) @@ -331,7 +331,7 @@ void ConfigBox::GetButtons(wxCommandEvent& event) bool succeed = false; int pressed = 0; int counter1 = 0; // Waiting limits - int counter2 = 10; + int counter2 = 30; // Iterations to wait for sprintf(format, "[%d]", counter2); SetButtonText(ID, format); @@ -339,6 +339,7 @@ void ConfigBox::GetButtons(wxCommandEvent& event) while(waiting) { + // Go through all axes and read out their values SDL_JoystickUpdate(); for(int b = 0; b < buttons; b++) { @@ -351,29 +352,66 @@ void ConfigBox::GetButtons(wxCommandEvent& event) } } + // Check for keyboard action + if (g_Pressed) + { + // Todo: Add a separate keyboard vector to remove this restriction + if(g_Pressed >= buttons) + { + pressed = g_Pressed; + waiting = false; + succeed = true; + g_Pressed = 0; + break; + } + else + { + wxMessageBox(wxString::Format(wxT( + "You selected a key with a to low key code (%i), please" + " select another key with a higher key code."), g_Pressed) + , wxT("Notice"), wxICON_INFORMATION); + + pressed = g_Pressed; + waiting = false; + succeed = false; + g_Pressed = 0; + break; + } + } + // Stop waiting for a button counter1++; - if(counter1 == 100) + if(counter1 == 25) { - counter1=0; + counter1 = 0; counter2--; sprintf(format, "[%d]", counter2); SetButtonText(ID, format); wxWindow::Update(); // win only? doesnt seem to work in linux... - - if(counter2<0) - waiting = false; - } + wxYieldIfNeeded(); // Let through the keyboard input event + if(counter2 < 0) waiting = false; + } + + // Sleep for 10 ms then poll for keys again SLEEP(10); + + // Debugging + /* + m_pStatusBar->SetLabel(wxString::Format( + "ID: %i %i", + counter1, NumKeys + )); + */ } // Write the number of the pressed button to the text box sprintf(format, "%d", succeed ? pressed : -1); SetButtonText(ID, format); - - if(SDL_JoystickOpened(joysticks[controller].ID)) - SDL_JoystickClose(joy); + + // We don't need this any more + if(SDL_JoystickOpened(joysticks[controller].ID)) SDL_JoystickClose(joy); + } // Wait for D-Pad @@ -383,7 +421,7 @@ void ConfigBox::GetHats(int ID) int controller = notebookpage; SDL_Joystick *joy; - joy=SDL_JoystickOpen(joysticks[controller].ID); + joy = SDL_JoystickOpen(joysticks[controller].ID); char format[128]; int hats = SDL_JoystickNumHats(joy); diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp index b8b471c7d9..3af5ef4dc7 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp @@ -31,6 +31,18 @@ +//////////////////////////////////////////////////////////////////////////////////////// +// Issues +/* ŻŻŻŻŻŻŻŻŻ + + The StrangeHack in ConfigAdvanced.cpp doesn't work in Linux, it still wont resize the + window correctly. So currently in Linux you have to have advanced controls enabled when + you open the window to see them. + +////////////////////////*/ + + + //////////////////////////////////////////////////////////////////////////////////////// // Variables guide /* ŻŻŻŻŻŻŻŻŻ @@ -164,7 +176,7 @@ void GetDllInfo(PLUGIN_INFO* _PluginInfo) // Call config dialog // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void DllConfig(HWND _hParent) -{ +{ #ifdef _WIN32 if (SDL_Init(SDL_INIT_JOYSTICK ) < 0) { @@ -348,6 +360,22 @@ void PAD_Shutdown() } +// Set buttons status from wxWidgets in the main application +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +void PAD_Input(u8 _Key, u8 _UpDown) +{ + // Check if the keys are interesting, and then update it + for(int i = 0; i < 4; i++) + { + for(int j = CTL_L_SHOULDER; j <= CTL_START; j++) + { + if (joysticks[i].buttons[j] == _Key) + { joystate[i].buttons[j] = _UpDown; break; } + } + } +} + + // Set PAD status. This is called from SerialInterface_Devices.cpp // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) @@ -590,7 +618,9 @@ unsigned int PAD_GetAttachedPads() ////////////////////////////////////////////////////////////////////////////////////////// // Read current joystick status -// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +/* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ + The value joystate[].buttons[] is first the number of the assigned joupad button + then it becomes 0 (no pressed) or 1 (pressed) */ // Read buttons status. Called from GetJoyState(). // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ @@ -640,4 +670,4 @@ void GetJoyState(int controller) joystate[controller].dpad2[CTL_D_PAD_RIGHT] = SDL_JoystickGetButton(joystate[controller].joy, joysticks[controller].dpad2[CTL_D_PAD_RIGHT]); } } -////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file +////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h index 973b38d722..97dc764b8c 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h @@ -94,7 +94,10 @@ ////////////////////////////////////////////////////////////////////////////////////////// // Structures -// ŻŻŻŻŻŻŻŻŻŻ +/* ŻŻŻŻŻŻŻŻŻŻ + CONTROLLER_STATE buttons (joystate) = 0 or 1 + CONTROLLER_MAPPING buttons (joystick) = 0 or 1, 2, 3, 4, a certain joypad button + */ 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 @@ -165,6 +168,17 @@ enum }; +////////////////////////////////////////////////////////////////////////////////////////// +// Input vector. Todo: Save the configured keys here instead of in joystick +// ŻŻŻŻŻŻŻŻŻ +/* +#ifndef _CONTROLLER_STATE_H +extern std::vector Keys; +#endif +*/ + + + ////////////////////////////////////////////////////////////////////////////////////////// // Variables // ŻŻŻŻŻŻŻŻŻ diff --git a/Source/Plugins/Plugin_nJoy_Testing/Src/GUI/ConfigBox.h b/Source/Plugins/Plugin_nJoy_Testing/Src/GUI/ConfigBox.h index dffd9694ee..ece3386dd0 100644 --- a/Source/Plugins/Plugin_nJoy_Testing/Src/GUI/ConfigBox.h +++ b/Source/Plugins/Plugin_nJoy_Testing/Src/GUI/ConfigBox.h @@ -55,7 +55,7 @@ class ConfigBox : public wxDialog public: ConfigBox(wxWindow *parent, wxWindowID id = 1, const wxString &title = wxT("Configure: nJoy Input Plugin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE); - virtual ~ConfigBox(); + virtual ~ConfigBox(); private: wxButton *m_About; @@ -235,7 +235,7 @@ class ConfigBox : public wxDialog void GetInputs(wxCommandEvent& event); void GetHats(int ID); - void SetButtonText(int id, char text[128]); + void SetButtonText(int id, char text[128]); }; #endif diff --git a/Source/Plugins/Plugin_nJoy_Testing/Src/nJoy.cpp b/Source/Plugins/Plugin_nJoy_Testing/Src/nJoy.cpp index eb6726e962..b05f3af394 100644 --- a/Source/Plugins/Plugin_nJoy_Testing/Src/nJoy.cpp +++ b/Source/Plugins/Plugin_nJoy_Testing/Src/nJoy.cpp @@ -255,6 +255,14 @@ void PAD_Shutdown() #endif } + + +// Set buttons status from wxWidgets in the main application +// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ +void PAD_Input(u8 _Key, u8 _UpDown) {} + + + // Set PAD status // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) @@ -336,8 +344,12 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) int triggervalue = 255; if (joystate[_numPAD].halfpress) triggervalue = 100; - int ButtonArray[] = {PAD_TRIGGER_L, PAD_TRIGGER_R, PAD_BUTTON_A, PAD_BUTTON_B, PAD_BUTTON_X, PAD_BUTTON_Y, PAD_TRIGGER_Z, PAD_BUTTON_START, PAD_BUTTON_UP, PAD_BUTTON_DOWN, PAD_BUTTON_LEFT, PAD_BUTTON_RIGHT}; - for(int a = 0;a <= CTL_D_PAD_RIGHT;a++) + int ButtonArray[] = {PAD_TRIGGER_L, PAD_TRIGGER_R, + PAD_BUTTON_A, PAD_BUTTON_B, + PAD_BUTTON_X, PAD_BUTTON_Y, PAD_TRIGGER_Z, + PAD_BUTTON_START, + PAD_BUTTON_UP, PAD_BUTTON_DOWN, PAD_BUTTON_LEFT, PAD_BUTTON_RIGHT}; + for(int a = 0; a <= CTL_D_PAD_RIGHT; a++) { switch(joysticks[_numPAD].buttons[a].c_str()[0]) { @@ -385,6 +397,7 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) if(joystate[_numPAD].buttons[a] <= 0) TriggerValue = abs((255.0f / joysticks[_numPAD].sData[JoyNum].Min) * joystate[_numPAD].buttons[a]); } + // Analog L and R if(a == CTL_L_SHOULDER) { if(TriggerValue == 255) @@ -417,6 +430,7 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) if(joystate[_numPAD].buttons[a]) { _pPADStatus->button |= ButtonArray[a]; + // Digital L and R if(a == CTL_L_SHOULDER) _pPADStatus->triggerLeft = 255; //TODO: Do half press with these else if(a == CTL_R_SHOULDER)