Rearranged EmuWiimote & nJoy. Wow they can share one pad at the same time, and they also can be enabled/disabled separately.

So as long as the game supports, you can toggle controller input between them on the fly.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4691 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
ayuanx
2009-12-14 02:23:14 +00:00
parent 2d10a47c2b
commit 6f1efd4873
20 changed files with 271 additions and 208 deletions

View File

@ -127,6 +127,7 @@ void Config::Save(int Slot)
// Save the physical device ID
file.Set(SectionName.c_str(), "joy_id", PadMapping[i].ID);
file.Set(SectionName.c_str(), "enable", PadMapping[i].enable);
// ===================
// ==================================================================
@ -190,7 +191,8 @@ void Config::Save(int Slot)
void Config::Load(bool ChangePad, bool ChangeSaveByID)
{
// If there are no good pads don't load
if (NumGoodPads == 0) return;
if (NumGoodPads == 0)
return;
// Load file
IniFile file;
@ -219,6 +221,7 @@ void Config::Load(bool ChangePad, bool ChangeSaveByID)
if (!ChangePad)
{
file.Get(SectionName.c_str(), "joy_id", &PadMapping[i].ID, 0);
file.Get(SectionName.c_str(), "enable", &PadMapping[i].enable, false);
}
// ==================================================================

View File

@ -58,6 +58,7 @@ BEGIN_EVENT_TABLE(PADConfigDialognJoy,wxDialog)
// Change gamepad
EVT_COMBOBOX(IDC_JOYNAME, PADConfigDialognJoy::ChangeSettings)
EVT_CHECKBOX(IDC_ENABLE, PADConfigDialognJoy::ChangeSettings)
// Other settings
EVT_CHECKBOX(IDC_SAVEBYID, PADConfigDialognJoy::ChangeSettings)
@ -130,8 +131,8 @@ PADConfigDialognJoy::PADConfigDialognJoy(wxWindow *parent, wxWindowID id, const
GetButtonWaitingID = 0; GetButtonWaitingTimer = 0;
// Start the constant timer
int TimesPerSecond = 30;
m_ConstantTimer->Start( floor((double)(1000 / TimesPerSecond)) );
int TimesPerSecond = 10;
m_ConstantTimer->Start(1000 / TimesPerSecond);
#endif
// wxEVT_KEY_DOWN is blocked for enter, tab and the directional keys
@ -157,13 +158,15 @@ void PADConfigDialognJoy::OnKeyDown(wxKeyEvent& event)
void PADConfigDialognJoy::OnClose(wxCloseEvent& event)
{
// Allow wxWidgets to close the window
event.Skip();
//event.Skip();
// Stop the timer
m_ConstantTimer->Stop();
// Close pads, unless we are running a game
if (!g_EmulatorRunning) Shutdown();
//if (!g_EmulatorRunning) Shutdown();
EndModal(wxID_CLOSE);
}
// Call about dialog
@ -252,7 +255,8 @@ void PADConfigDialognJoy::DoSave(bool ChangePad, int Slot)
if (ChangePad)
{
// Since we are selecting the pad to save to by the Id we can't update it when we change the pad
for(int i = 0; i < 4; i++) SaveButtonMapping(i, true);
for(int i = 0; i < 4; i++)
SaveButtonMapping(i, true);
g_Config.Save(Slot);
// Now we can update the ID
@ -261,7 +265,9 @@ void PADConfigDialognJoy::DoSave(bool ChangePad, int Slot)
else
{
// Update PadMapping[] from the GUI controls
for(int i = 0; i < 4; i++) SaveButtonMapping(i);
for(int i = 0; i < 4; i++)
SaveButtonMapping(i);
g_Config.Save(Slot);
}
@ -301,13 +307,15 @@ void PADConfigDialognJoy::DoChangeJoystick()
void PADConfigDialognJoy::NotebookPageChanged(wxNotebookEvent& event)
{
// Save current settings now, don't wait for OK
if (ControlsCreated && !g_Config.bSaveByID) DoSave(false, notebookpage);
if (ControlsCreated && !g_Config.bSaveByID)
DoSave(false, notebookpage);
// Update the global variable
notebookpage = event.GetSelection();
// Update GUI
if (ControlsCreated) UpdateGUI(notebookpage);
if (ControlsCreated)
UpdateGUI(notebookpage);
}
// Replace the harder to understand -1 with "" for the sake of user friendliness
@ -362,7 +370,8 @@ void PADConfigDialognJoy::UpdateGUIAll(int Slot)
{
if (Slot == -1)
{
for (int i = 0; i < 4; i++) UpdateGUI(i);
for (int i = 0; i < 4; i++)
UpdateGUI(i);
}
else
{
@ -387,11 +396,8 @@ void PADConfigDialognJoy::ChangeSettings( wxCommandEvent& event )
case IDC_SHOWADVANCED:
g_Config.bShowAdvanced = m_CBShowAdvanced[notebookpage]->IsChecked();
for(int i = 0; i < 4; i++)
{
UpdateGUI(i);
m_CBShowAdvanced[i]->SetValue(g_Config.bShowAdvanced);
m_sMainRight[i]->Show(g_Config.bShowAdvanced);
}
UpdateGUI(notebookpage);
// Resize the window without the need of any weird hack
SetSizerAndFit(m_MainSizer);
break;
@ -400,34 +406,30 @@ void PADConfigDialognJoy::ChangeSettings( wxCommandEvent& event )
case IDCB_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);
//UpdateGUI(notebookpage);
}
case IDC_TRIGGERTYPE:
if(!g_Config.bSaveByID)
{
PadMapping[notebookpage].triggertype = m_TriggerType[notebookpage]->GetSelection();
UpdateGUI(notebookpage);
//UpdateGUI(notebookpage);
}
break;
case IDC_ENABLERUMBLE:
PadMapping[notebookpage].rumble = m_Rumble[notebookpage]->IsChecked();
UpdateGUI(notebookpage);
//UpdateGUI(notebookpage);
break;
case IDC_RUMBLESTRENGTH:
g_Config.RumbleStrength = m_RStrength[notebookpage]->GetSelection();
@ -435,11 +437,17 @@ void PADConfigDialognJoy::ChangeSettings( wxCommandEvent& event )
case IDC_JOYNAME:
DoChangeJoystick();
break;
case IDC_ENABLE:
PadMapping[notebookpage].enable = m_Enable[notebookpage]->IsChecked();
UpdateGUI(notebookpage);
// Resize the window without the need of any weird hack
SetSizerAndFit(m_MainSizer);
break;
}
// Update all slots that use this device
if(g_Config.bSaveByID) SaveButtonMappingAll(notebookpage);
if(g_Config.bSaveByID) UpdateGUIAll(notebookpage);
//if(g_Config.bSaveByID) UpdateGUIAll(notebookpage);
}
@ -507,7 +515,11 @@ void PADConfigDialognJoy::UpdateGUI(int _notebookpage)
else m_CoBDiagonalC[_notebookpage]->Enable(false);
}
// Repaint the background
m_sKeys[_notebookpage]->Show(PadMapping[_notebookpage].enable);
m_sSettings[_notebookpage]->Show(PadMapping[_notebookpage].enable);
m_sMainRight[_notebookpage]->Show(g_Config.bShowAdvanced && PadMapping[_notebookpage].enable);
// Repaint the background
m_Controller[_notebookpage]->Refresh();
}
@ -525,7 +537,7 @@ void PADConfigDialognJoy::OnPaint(wxPaintEvent &event)
// Populate the config window
void PADConfigDialognJoy::CreateGUIControls()
{
INFO_LOG(PAD, "CreateGUIControls()\n");
INFO_LOG(PAD, "CreateGUIControls()");
#ifndef _DEBUG
SetTitle(wxT("Configure: nJoy Input Plugin"));
@ -721,17 +733,18 @@ void PADConfigDialognJoy::CreateGUIControls()
// Populate Controller sizer
// Groups
#ifdef _WIN32
m_Joyname[i] = new wxComboBox(m_Controller[i], IDC_JOYNAME, arrayStringFor_Joyname[0], wxDefaultPosition, wxSize(476, 21), arrayStringFor_Joyname, wxCB_READONLY);
m_Joyname[i] = new wxComboBox(m_Controller[i], IDC_JOYNAME, arrayStringFor_Joyname[0], wxDefaultPosition, wxSize(300, 25), arrayStringFor_Joyname, wxCB_READONLY);
#else
m_Joyname[i] = new wxComboBox(m_Controller[i], IDC_JOYNAME, arrayStringFor_Joyname[0], wxDefaultPosition, wxSize(450, 25), arrayStringFor_Joyname, 0, wxDefaultValidator, wxT("m_Joyname"));
m_Joyname[i] = new wxComboBox(m_Controller[i], IDC_JOYNAME, arrayStringFor_Joyname[0], wxDefaultPosition, wxSize(300, 25), arrayStringFor_Joyname, 0, wxDefaultValidator, wxT("m_Joyname"));
#endif
m_gJoyname[i] = new wxStaticBoxSizer (wxHORIZONTAL, m_Controller[i], wxT("Controller"));
m_gJoyname[i]->Add(m_Joyname[i], 0, (wxLEFT | wxRIGHT), 5);
m_Joyname[i]->SetToolTip(wxT("Save your settings and configure another joypad"));
m_Enable[i] = new wxCheckBox(m_Controller[i], IDC_ENABLE, wxT("Pad Enabled"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_Enable[i]->SetToolTip(wxT("Enable this pad to send input events to game"));
m_gJoyname[i] = new wxStaticBoxSizer (wxHORIZONTAL, m_Controller[i], wxT("Controller"));
m_gJoyname[i]->Add(m_Joyname[i], 0, wxEXPAND | (wxLEFT | wxRIGHT), 5);
m_gJoyname[i]->Add(m_Enable[i], 0, wxEXPAND | (wxLEFT | wxRIGHT), 5);
// General settings
@ -979,7 +992,14 @@ void PADConfigDialognJoy::CreateGUIControls()
#endif
// Set window size
Center();
SetSizer(m_MainSizer);
Layout();
Fit();
// Center the window if there is room for it
#ifdef _WIN32
if (GetSystemMetrics(SM_CYFULLSCREEN) > 600)
Center();
#endif
// All done
ControlsCreated = true;

View File

@ -99,6 +99,7 @@ class PADConfigDialognJoy : public wxDialog
// ---------
wxComboBox *m_Joyname[4];
wxCheckBox *m_Enable[4];
wxComboBox *m_ControlType[4], *m_TriggerType[4];
wxComboBox *m_Deadzone[4];
@ -212,7 +213,7 @@ class PADConfigDialognJoy : public wxDialog
ID_KEYSPANEL1, ID_KEYSPANEL2, ID_KEYSPANEL3, ID_KEYSPANEL4,
IDG_JOYSTICK, IDC_JOYNAME,
IDG_JOYSTICK, IDC_JOYNAME, IDC_ENABLE,
IDG_EXTRASETTINGS, IDC_DEADZONE, // Extra settings
@ -312,6 +313,7 @@ class PADConfigDialognJoy : public wxDialog
};
private:
void OnClose(wxCloseEvent& event);
void AboutClick(wxCommandEvent& event);
void OKClick(wxCommandEvent& event);
void CancelClick(wxCommandEvent& event);
@ -324,7 +326,6 @@ class PADConfigDialognJoy : public wxDialog
void ChangeSettings(wxCommandEvent& event);
void ComboChange(wxCommandEvent& event);
void OnClose(wxCloseEvent& event);
void CreateGUIControls();
void CreateAdvancedControls(int i);
wxBitmap CreateBitmap();

View File

@ -52,6 +52,7 @@ void PADConfigDialognJoy::UpdateGUIButtonMapping(int controller)
// Update selected gamepad
m_Joyname[controller]->SetSelection(PadMapping[controller].ID);
m_Enable[controller]->SetValue(PadMapping[controller].enable);
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();
@ -336,12 +337,12 @@ void PADConfigDialognJoy::DoGetButtons(int GetId)
g_Pressed = 0;
// Update the text box
sprintf(format, "[%d]", Seconds);
sprintf(format, "[ %d ]", Seconds);
SetButtonText(GetId, format);
// Start the timer
#if wxUSE_TIMER
m_ButtonMappingTimer->Start( floor((double)(1000 / TimesPerSecond)) );
m_ButtonMappingTimer->Start(1000 / TimesPerSecond);
#endif
}
@ -374,7 +375,7 @@ void PADConfigDialognJoy::DoGetButtons(int GetId)
int TmpTime = Seconds - (GetButtonWaitingTimer / TimesPerSecond);
// Update text
sprintf(format, "[%d]", TmpTime);
sprintf(format, "[ %d ]", TmpTime);
SetButtonText(GetId, format);
}

View File

@ -81,6 +81,9 @@ void Pad_Use_Rumble(u8 _numPAD)
void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength)
{
if (!PadMapping[_numPAD].enable)
return;
Pad_Use_Rumble(_numPAD);
int Strenght = 0;

View File

@ -181,7 +181,7 @@ void DllDebugger(HWND _hParent, bool Show) {}
// --------------------------
void Initialize(void *init)
{
INFO_LOG(PAD, "Initialize: %i\n", SDL_WasInit(0));
INFO_LOG(PAD, "Initialize: %i", SDL_WasInit(0));
g_PADInitialize = (SPADInitialize*)init;
g_EmulatorRunning = true;
@ -195,6 +195,30 @@ void Initialize(void *init)
// Populate joyinfo for all attached devices
Search_Devices(joyinfo, NumPads, NumGoodPads);
g_Config.Load(); // load settings
}
void Close_Devices()
{
PAD_RumbleClose();
/* Close all devices carefully. We must check that we are not accessing any undefined
vector elements or any bad devices */
for (int i = 0; i < 4; i++)
{
if (SDL_WasInit(0) && joyinfo.size() > (u32)PadMapping[i].ID)
if (PadState[i].joy && joyinfo.at(PadMapping[i].ID).Good)
if(SDL_JoystickOpened(PadMapping[i].ID))
{
SDL_JoystickClose(PadState[i].joy);
PadState[i].joy = NULL;
}
}
// Clear the physical device info
joyinfo.clear();
NumPads = 0;
NumGoodPads = 0;
}
// Shutdown PAD (stop emulation)
@ -214,25 +238,7 @@ void Shutdown()
DEBUG_QUIT();
#endif
PAD_RumbleClose();
/* Close all devices carefully. We must check that we are not accessing any undefined
vector elements or any bad devices */
for (int i = 0; i < 4; i++)
{
if (SDL_WasInit(0) && joyinfo.size() > (u32)PadMapping[i].ID)
if (PadState[i].joy && joyinfo.at(PadMapping[i].ID).Good)
if(SDL_JoystickOpened(PadMapping[i].ID))
{
SDL_JoystickClose(PadState[i].joy);
PadState[i].joy = NULL;
}
}
// Clear the physical device info
joyinfo.clear();
NumPads = 0;
NumGoodPads = 0;
Close_Devices();
// Finally close SDL
if (SDL_WasInit(0))
@ -286,7 +292,8 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
{
// Check if the pad is avaliable, currently we don't disable pads just because they are
// disconnected
if (!PadState[_numPAD].joy) return;
if (!PadState[_numPAD].joy || !PadMapping[_numPAD].enable)
return;
// Clear pad status
memset(_pPADStatus, 0, sizeof(SPADStatus));
@ -442,6 +449,9 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
// ----------------
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
{
// Close opened devices first
Close_Devices();
bool Success = InputCommon::SearchDevices(_joyinfo, _NumPads, _NumGoodPads);
// Warn the user if no gamepads are detected
@ -451,9 +461,6 @@ bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_N
return false;
}
// Load PadMapping[] etc
g_Config.Load();
// Update the PadState[].joy handle
for (int i = 0; i < 4; i++)
{
@ -486,9 +493,3 @@ return true;
return true;
#endif
}

View File

@ -101,6 +101,7 @@
// Custom Functions
// ----------------
void Close_Devices();
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads);
void DEBUG_INIT();
void DEBUG_QUIT();