From 382b4af74b132454baaa7026013c3da792d55b8f Mon Sep 17 00:00:00 2001 From: John Peterson Date: Sat, 7 Feb 2009 04:19:52 +0000 Subject: [PATCH] Wiimote: Fixed the dual mode bug I mentioned in the last commit, now the Nunchuck should not get stuck when switching between the real and emulated Nunchuck. The only important problem left is disconnect problem that occurs about one in five times you switch to the real wiimote. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2130 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp | 44 +++++++++++---- Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h | 8 +-- .../Plugin_Wiimote/Src/ConfigRecording.cpp | 8 --- Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp | 55 +++++++++++-------- Source/Plugins/Plugin_Wiimote/Src/EmuMain.h | 7 ++- Source/Plugins/Plugin_Wiimote/Src/main.cpp | 17 +++++- 6 files changed, 88 insertions(+), 51 deletions(-) diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp index 1a58af50b8..7d13639a76 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp @@ -98,6 +98,7 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog) EVT_BUTTON(IDB_RECORD + 15, ConfigDialog::RecordMovement) EVT_TIMER(IDTM_UPDATE, ConfigDialog::Update) + EVT_TIMER(IDTM_UPDATE_ONCE, ConfigDialog::UpdateOnce) EVT_TIMER(IDTM_SHUTDOWN, ConfigDialog::ShutDown) END_EVENT_TABLE() ////////////////////////////////////// @@ -113,13 +114,14 @@ ConfigDialog::ConfigDialog(wxWindow *parent, wxWindowID id, const wxString &titl #if wxUSE_TIMER m_TimeoutTimer = new wxTimer(this, IDTM_UPDATE); m_ShutDownTimer = new wxTimer(this, IDTM_SHUTDOWN); - m_TimeoutATimer = new wxTimer(this, IDTM_UPDATEA); + m_TimeoutOnce = new wxTimer(this, IDTM_UPDATE_ONCE); // Reset values m_bWaitForRecording = false; m_bRecording = false; #endif ControlsCreated = false; + m_bEnableUseRealWiimote = true; Page = 0; m_vRecording.resize(RECORDING_ROWS + 1); @@ -201,6 +203,20 @@ void ConfigDialog::CloseClick(wxCommandEvent& event) void ConfigDialog::AboutClick(wxCommandEvent& WXUNUSED (event)) { } + +// Execute a delayed function +void ConfigDialog::UpdateOnce(wxTimerEvent& event) +{ + switch(event.GetId()) + { + case IDTM_UPDATE_ONCE: + // Reenable the checkbox + m_bEnableUseRealWiimote = true; + SetCursor(wxCursor(wxCURSOR_ARROW)); + UpdateGUI(); + break; + } +} ////////////////////////////////////// @@ -811,13 +827,21 @@ void ConfigDialog::DoUseReal() Console::Print("\nDoUseReal() Connect extension: %i\n", !UsingExtension); DoExtensionConnectedDisconnected(UsingExtension ? 0 : 1); - // Sleep this thread - sleep(100); + + // Disable the checkbox for a moment + SetCursor(wxCursor(wxCURSOR_WAIT)); + m_bEnableUseRealWiimote = false; + // We don't need this, there is already a message queue that allows the nessesary timeout + //sleep(100); + UsingExtension = !UsingExtension; Console::Print("\nDoUseReal() Connect extension: %i\n", !UsingExtension); DoExtensionConnectedDisconnected(UsingExtension ? 1 : 0); - // Sleep again, to allow the approximate time it takes for the Wiimote to come online - sleep(200); + + /* Start the timer to allow the approximate time it takes for the Wiimote to come online + it would simpler to use sleep(1000) but that doesn't work because we need the functions in main.cpp + to work */ + m_TimeoutOnce->Start(1000, true); } // =================================================== @@ -880,9 +904,7 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) g_Config.bNunchuckConnected = m_NunchuckConnected[Page]->IsChecked(); // Copy the calibration data - memcpy(WiiMoteEmu::g_RegExt + 0x20, WiiMoteEmu::nunchuck_calibration, sizeof(WiiMoteEmu::nunchuck_calibration)); - memcpy(WiiMoteEmu::g_RegExt + 0x30, WiiMoteEmu::nunchuck_calibration, sizeof(WiiMoteEmu::nunchuck_calibration)); - memcpy(WiiMoteEmu::g_RegExt + 0xfa, WiiMoteEmu::nunchuck_id, sizeof(WiiMoteEmu::nunchuck_id)); + WiiMoteEmu::SetDefaultExtensionRegistry(); // Generate connect/disconnect status event DoExtensionConnectedDisconnected(); @@ -900,9 +922,7 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) g_Config.bClassicControllerConnected = m_ClassicControllerConnected[Page]->IsChecked(); // Copy the calibration data - memcpy(WiiMoteEmu::g_RegExt + 0x20, WiiMoteEmu::classic_calibration, sizeof(WiiMoteEmu::classic_calibration)); - memcpy(WiiMoteEmu::g_RegExt + 0x30, WiiMoteEmu::classic_calibration, sizeof(WiiMoteEmu::classic_calibration)); - memcpy(WiiMoteEmu::g_RegExt + 0xfa, WiiMoteEmu::classic_id, sizeof(WiiMoteEmu::classic_id)); + WiiMoteEmu::SetDefaultExtensionRegistry(); // Generate connect/disconnect status event DoExtensionConnectedDisconnected(); break; @@ -977,7 +997,7 @@ void ConfigDialog::UpdateGUI() has been initialized. Functions for that are basically already in place so these two options could possibly be simplified to one option. */ m_ConnectRealWiimote[Page]->Enable(!g_EmulatorRunning); - m_UseRealWiimote[Page]->Enable((g_RealWiiMotePresent && g_Config.bConnectRealWiimote) || !g_EmulatorRunning); + m_UseRealWiimote[Page]->Enable((m_bEnableUseRealWiimote && g_RealWiiMotePresent && g_Config.bConnectRealWiimote) || !g_EmulatorRunning); // Linux has no FindItem() #ifdef _WIN32 diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h index b8eb634be4..29960f4e1d 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h @@ -60,15 +60,15 @@ class ConfigDialog : public wxDialog void DoRecordMovement(u8 _x, u8 _y, u8 _z, const u8 *_IR, int IRBytes); void DoRecordA(bool Pressed); void ConvertToString(); - wxTimer *m_TimeoutTimer, *m_ShutDownTimer, *m_TimeoutATimer; + wxTimer *m_TimeoutTimer, *m_ShutDownTimer, *m_TimeoutOnce; void Update(wxTimerEvent& WXUNUSED(event)); void ShutDown(wxTimerEvent& WXUNUSED(event)); - void UpdateA(wxTimerEvent& WXUNUSED(event)); + void UpdateOnce(wxTimerEvent& event); private: DECLARE_EVENT_TABLE(); - bool ControlsCreated; int Page, BoxW, BoxH; + bool ControlsCreated, m_bEnableUseRealWiimote; int Page, BoxW, BoxH; wxNotebook *m_Notebook; wxPanel *m_Controller[4], *m_PageRecording; @@ -131,7 +131,7 @@ class ConfigDialog : public wxDialog ID_CLOSE = 1000, ID_APPLY, ID_ABOUTOGL, - IDTM_EXIT, IDTM_UPDATE, IDTM_SHUTDOWN, IDTM_UPDATEA, // Timer + IDTM_EXIT, IDTM_UPDATE, IDTM_SHUTDOWN, IDTM_UPDATE_ONCE, // Timer ID_NOTEBOOK, ID_CONTROLLERPAGE1, ID_CONTROLLERPAGE2, ID_CONTROLLERPAGE3, ID_CONTROLLERPAGE4, ID_PAGE_RECORDING, diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp index c125ca3d5f..06195ef474 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp @@ -424,13 +424,6 @@ void ConfigDialog::Update(wxTimerEvent& WXUNUSED(event)) UpdateGUI(); } -// One second timeout for another A press -void ConfigDialog::UpdateA(wxTimerEvent& WXUNUSED(event)) -{ - m_bAllowA = true; - Console::Print("A allowed again"); -} - void ConfigDialog::RecordMovement(wxCommandEvent& event) { m_iRecordTo = event.GetId() - 2000; @@ -460,7 +453,6 @@ void ConfigDialog::RecordMovement(wxCommandEvent& event) UpdateGUI(); m_TimeoutTimer->Start(5000, true); - //m_TimeoutATimer->Start(500, true); } void ConfigDialog::DoRecordA(bool Pressed) diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp index f2d54f94e1..02034743f9 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp @@ -234,7 +234,7 @@ void UpdateEeprom() g_nu.cal_zero.x = g_RegExt[0x20]; g_nu.cal_zero.y = g_RegExt[0x21]; - g_nu.cal_zero.z = g_RegExt[0x22]; + g_nu.cal_zero.z = g_RegExt[0x26]; // Including the g-force g_nu.jx.max = g_RegExt[0x28]; g_nu.jx.min = g_RegExt[0x29]; g_nu.jx.center = g_RegExt[0x2a]; @@ -242,8 +242,12 @@ void UpdateEeprom() g_nu.jy.min = g_RegExt[0x2c]; g_nu.jy.center = g_RegExt[0x2d]; - Console::Print("UpdateEeprom: %i %i %i\n", + Console::Print("\nUpdateEeprom: %i %i %i\n", WiiMoteEmu::g_Eeprom[22], WiiMoteEmu::g_Eeprom[23], WiiMoteEmu::g_Eeprom[27]); + + Console::Print("UpdateExtension: %i %i %i %i %i\n\n", + WiiMoteEmu::g_RegExt[0x2a], WiiMoteEmu::g_RegExt[0x2d], + WiiMoteEmu::g_RegExt[20], WiiMoteEmu::g_RegExt[21], WiiMoteEmu::g_RegExt[26]); } // Calculate checksum for the nunchuck calibration. The last two bytes. @@ -274,6 +278,26 @@ void ResetVariables() g_EmulatedWiiMoteInitialized = false; } +// Update the extension calibration values with our default values +void SetDefaultExtensionRegistry() +{ + // Copy extension id and calibration to its register + if(g_Config.bNunchuckConnected) + { + memcpy(g_RegExt + 0x20, nunchuck_calibration, sizeof(nunchuck_calibration)); + memcpy(g_RegExt + 0x30, nunchuck_calibration, sizeof(nunchuck_calibration)); + memcpy(g_RegExt + 0xfa, nunchuck_id, sizeof(nunchuck_id)); + } + else if(g_Config.bClassicControllerConnected) + { + memcpy(g_RegExt + 0x20, classic_calibration, sizeof(classic_calibration)); + memcpy(g_RegExt + 0x30, classic_calibration, sizeof(classic_calibration)); + memcpy(g_RegExt + 0xfa, classic_id, sizeof(classic_id)); + } + + UpdateEeprom(); +} + // =================================================== /* Write initial values to Eeprom and registers. */ // ---------------- @@ -289,27 +313,8 @@ void Initialize() memcpy(g_Eeprom, EepromData_0, sizeof(EepromData_0)); memcpy(g_Eeprom + 0x16D0, EepromData_16D0, sizeof(EepromData_16D0)); - // Write default accelerometer neutral values - UpdateEeprom(); - - /* Extension data for homebrew applications that use the 0x00000000 key. This - writes 0x0000 in encrypted form (0xfefe) to 0xfe in the extension register. */ - //WriteCrypted16(g_RegExt, 0xfe, 0x0000); // Fully inserted Nunchuk - - // Copy extension id and calibration to its register - if(g_Config.bNunchuckConnected) - { - memcpy(g_RegExt + 0x20, nunchuck_calibration, sizeof(nunchuck_calibration)); - memcpy(g_RegExt + 0x30, nunchuck_calibration, sizeof(nunchuck_calibration)); - memcpy(g_RegExt + 0xfa, nunchuck_id, sizeof(nunchuck_id)); - } - else if(g_Config.bClassicControllerConnected) - { - memcpy(g_RegExt + 0x20, classic_calibration, sizeof(classic_calibration)); - memcpy(g_RegExt + 0x30, classic_calibration, sizeof(classic_calibration)); - memcpy(g_RegExt + 0xfa, classic_id, sizeof(classic_id)); - } + SetDefaultExtensionRegistry(); g_ReportingMode = 0; g_EmulatedWiiMoteInitialized = true; @@ -327,7 +332,11 @@ void Initialize() g_RecordingCurrentTime[i] = 0; } - // I forgot what these were for? + /* The Nuncheck extension ID for homebrew applications that use the zero key. This writes 0x0000 + in encrypted form (0xfefe) to 0xfe in the extension register. */ + //WriteCrypted16(g_RegExt, 0xfe, 0x0000); // Fully inserted Nunchuk + + // I forgot what these were for? Is this the zero key encrypted 0xa420? // g_RegExt[0xfd] = 0x1e; // g_RegExt[0xfc] = 0x9a; } diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h index 76e1ec6924..f5b5a2035b 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h @@ -28,7 +28,7 @@ u32 convert24bit(const u8* src); u16 convert16bit(const u8* src); void GetMousePos(float& x, float& y); -void UpdateEeprom(); +// General functions void Initialize(); void DoState(void* ptr, int mode); void Shutdown(void); @@ -36,8 +36,13 @@ void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size); void ControlChannel(u16 _channelID, const void* _pData, u32 _Size) ; void Update(); +// Recordings void LoadRecordedMovements(); +// Registers and calibration values +void UpdateEeprom(); +void SetDefaultExtensionRegistry(); + }; #endif diff --git a/Source/Plugins/Plugin_Wiimote/Src/main.cpp b/Source/Plugins/Plugin_Wiimote/Src/main.cpp index 176569054e..cc3323c9ea 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/main.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/main.cpp @@ -517,10 +517,21 @@ void ReadDebugging(bool Emu, const void* _pData, int Size) Console::Print("JS.Center.y: %i\n\n", data[7 + 13]); // Save the values - if (!Emu && data[7 + 0] != 0xff) + if (!Emu) { - memcpy(WiiMoteEmu::g_RegExt + 0x20, &data[7], 0x10); - memcpy(WiiMoteEmu::g_RegExt + 0x30, &data[7], 0x10); + // Save the values from the Nunchuck + if(data[7 + 0] != 0xff) + { + memcpy(WiiMoteEmu::g_RegExt + 0x20, &data[7], 0x10); + memcpy(WiiMoteEmu::g_RegExt + 0x30, &data[7], 0x10); + + } + // Save the default values that should work with Wireless Nunchucks + else + { + WiiMoteEmu::SetDefaultExtensionRegistry(); + } + WiiMoteEmu::UpdateEeprom(); } // We got a third party nunchuck else if(data[7 + 0] == 0xff)