From 7c7257b8252df13e33d22f91254c40c6b592c285 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 15 Aug 2010 20:33:07 +0000 Subject: [PATCH] New Wiimote Plugin: Give each real wiimote an individual thread.(eliminates multi-wiimote delay)(fixes issue 3037 for the new plugin) Fix a mem-leak in the input config dialog.(GCPad/NewWiimote) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6096 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/InputUICommon/Src/ConfigDiag.cpp | 12 +- Source/Core/InputUICommon/Src/ConfigDiag.h | 9 +- .../Src/WiimoteEmu/EmuSubroutines.cpp | 2 +- .../Src/WiimoteEmu/WiimoteEmu.cpp | 5 - .../Src/WiimoteReal/WiimoteReal.cpp | 204 ++++++++---------- .../Src/WiimoteReal/WiimoteReal.h | 11 +- 6 files changed, 115 insertions(+), 128 deletions(-) diff --git a/Source/Core/InputUICommon/Src/ConfigDiag.cpp b/Source/Core/InputUICommon/Src/ConfigDiag.cpp index ec4ee31a2b..251aa23c52 100644 --- a/Source/Core/InputUICommon/Src/ConfigDiag.cpp +++ b/Source/Core/InputUICommon/Src/ConfigDiag.cpp @@ -670,11 +670,20 @@ void GamepadPage::RefreshDevices( wxCommandEvent& event ) m_plugin.controls_crit.Leave(); // leave } +ControlGroupBox::~ControlGroupBox() +{ + std::vector::const_iterator + i = options.begin(), + e = options.end(); + for (; i!=e; ++i) + delete *i; +} + ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWindow* const parent, wxWindow* const eventsink ) : wxStaticBoxSizer(wxVERTICAL, parent, wxString::FromAscii(group->name)) + , control_group(group) { - control_group = group; static_bitmap = NULL; wxFont m_SmallFont(7, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); @@ -689,7 +698,6 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi ControlButton* const control_button = new ControlButton(parent, (*ci)->control_ref, 80); control_button->SetFont(m_SmallFont); - controls.push_back(control_button); control_buttons.push_back(control_button); if ((*ci)->control_ref->is_input) diff --git a/Source/Core/InputUICommon/Src/ConfigDiag.h b/Source/Core/InputUICommon/Src/ConfigDiag.h index 56ac9c4ac0..ae236bc56a 100644 --- a/Source/Core/InputUICommon/Src/ConfigDiag.h +++ b/Source/Core/InputUICommon/Src/ConfigDiag.h @@ -161,12 +161,13 @@ class ControlGroupBox : public wxStaticBoxSizer { public: ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWindow* const parent, wxWindow* const eventsink ); + ~ControlGroupBox(); - ControllerEmu::ControlGroup* control_group; + std::vector options; + + ControllerEmu::ControlGroup* const control_group; wxStaticBitmap* static_bitmap; - std::vector< PadSetting* > options; - std::vector< wxButton* > controls; - std::vector control_buttons; + std::vector control_buttons; }; class ControlGroupsSizer : public wxBoxSizer diff --git a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/EmuSubroutines.cpp b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/EmuSubroutines.cpp index 5279ae07d5..441d642671 100644 --- a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/EmuSubroutines.cpp +++ b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/EmuSubroutines.cpp @@ -71,7 +71,7 @@ void Wiimote::ReportMode(const wm_report_mode* const dr) if (false == m_reporting_auto) PanicAlert("Wiimote: Reporting is set to OFF! Everything should be fine, but games never do this."); - if (dr->mode >= WM_REPORT_INTERLEAVE1) + if (dr->mode > 0x37) PanicAlert("Wiimote: Unsupported Reporting mode."); else if (dr->mode < WM_REPORT_CORE) PanicAlert("Wiimote: Reporting mode < 0x30."); diff --git a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/WiimoteEmu.cpp b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/WiimoteEmu.cpp index 15460c3d42..966f8c106f 100644 --- a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/WiimoteEmu.cpp @@ -58,11 +58,6 @@ const ReportFeatures reporting_mode_features[] = { 2, 0, 4, 14, 23 }, //0x37: Core Buttons and Accelerometer with 10 IR bytes and 6 Extension Bytes { 2, 4, 7, 17, 23 }, - //0x3d: 21 Extension Bytes - { 0, 0, 0, 2, 23 }, - //0x3e / 0x3f: Interleaved Core Buttons and Accelerometer with 36 IR bytes - // UNSUPPORTED - { 0, 0, 0, 0, 23 }, }; void EmulateShake( u8* const accel diff --git a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.cpp b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.cpp index d15466631f..50ebc64ac8 100644 --- a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.cpp +++ b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.cpp @@ -39,62 +39,42 @@ unsigned int g_wiimotes_found = 0; volatile unsigned int g_wiimotes_lastfound = 0; volatile bool g_run_wiimote_thread = false; -Common::Thread *g_wiimote_thread = NULL; -Common::CriticalSection g_refresh_critsec, g_wiimote_critsec; +Common::Thread *g_wiimote_threads[MAX_WIIMOTES] = {}; +Common::CriticalSection g_refresh_critsec; + THREAD_RETURN WiimoteThreadFunc(void* arg); +void StartWiimoteThreads(); +void StopWiimoteThreads(); -Wiimote *g_wiimotes[4]; +Wiimote *g_wiimotes[MAX_WIIMOTES]; -Wiimote::Wiimote(wiimote_t* const wm, const unsigned int index) - : m_last_data_report(NULL) +Wiimote::Wiimote(wiimote_t* const _wiimote, const unsigned int _index) + : wiimote(_wiimote) + , index(_index) + , m_last_data_report(NULL) , m_channel(0) - , m_wiimote(wm) - , m_index(index) { // disable reporting DisableDataReporting(); - // clear all msgs, silly maybe - // - cleared on first InterruptChannel call - //while (wiiuse_io_read(m_wiimote)); - - //{ - // LEDs test - //wm_leds rpt = wm_leds(); - //rpt.leds = 1 << i; - //SendPacket(g_wiimotes_from_wiiuse[i], WM_LEDS, &rpt, sizeof(rpt)); - //} - - // Rumble briefly, this is a bad spot for the rumble - wiiuse_rumble(m_wiimote, 1); - SLEEP(200); - wiiuse_rumble(m_wiimote, 0); - // set LEDs - wiiuse_set_leds(m_wiimote, WIIMOTE_LED_1 << m_index); + wiiuse_set_leds(wiimote, WIIMOTE_LED_1 << index); // TODO: make Dolphin connect wiimote, maybe } Wiimote::~Wiimote() { - ClearReports(); + ClearReadQueue(); + + // clear write queue + Report rpt; + while (m_write_reports.Pop(rpt)) + delete[] rpt.first; // disable reporting / wiiuse might do this on shutdown anyway, o well, don't know for sure DisableDataReporting(); - - // send disconnect message to wii, maybe, i hope, naw shit messes up on emu-stop - //if (g_WiimoteInitialize.pWiimoteInterruptChannel) - //{ - // //u8* const rpt = new u8[2]; - // //rpt[0] = 0XA1; rpt[1] = 0x15; - // //m_read_reports.push(rpt); - // //Update(); - - // const u8 rpt[] = { 0xA1, 0x15 }; - // g_WiimoteInitialize.pWiimoteInterruptChannel(m_index, m_channel, rpt, sizeof(rpt)); - //} } // silly, copying data n stuff, o well, don't use this too often @@ -119,18 +99,20 @@ void Wiimote::DisableDataReporting() SendPacket(WM_REPORT_MODE, &rpt, sizeof(rpt)); } -void Wiimote::ClearReports() +void Wiimote::ClearReadQueue() { + // might be silly + while (wiiuse_io_read(wiimote)) {}; + if (m_last_data_report) { delete[] m_last_data_report; m_last_data_report = NULL; } - Report rpt; - while (m_write_reports.Pop(rpt)) - delete rpt.first; - while (m_read_reports.Pop(rpt.first)) - delete rpt.first; + + u8 *rpt; + while (m_read_reports.Pop(rpt)) + delete[] rpt; } void Wiimote::ControlChannel(const u16 channel, const void* const data, const u32 size) @@ -146,8 +128,7 @@ void Wiimote::InterruptChannel(const u16 channel, const void* const data, const { if (0 == m_channel) // first interrupt/control channel sent { - // clear all msgs, silly maybe - while (wiiuse_io_read(m_wiimote)) {}; + ClearReadQueue(); // request status wm_request_status rpt; @@ -182,29 +163,36 @@ void Wiimote::InterruptChannel(const u16 channel, const void* const data, const m_write_reports.Push(rpt); } -void Wiimote::Read() +bool Wiimote::Read() { - // if not connected to Dolphin, don't do anything, to keep sanchez happy :p - if (0 == m_channel) - return; - - if (wiiuse_io_read(m_wiimote)) + if (wiiuse_io_read(wiimote)) { - // add it to queue - u8* const rpt = new u8[MAX_PAYLOAD]; - memcpy(rpt, m_wiimote->event_buf, MAX_PAYLOAD); - m_read_reports.Push(rpt); + if (m_channel) + { + // add it to queue + u8* const rpt = new u8[MAX_PAYLOAD]; + memcpy(rpt, wiimote->event_buf, MAX_PAYLOAD); + m_read_reports.Push(rpt); + } + + return true; } + + return false; } -void Wiimote::Write() +bool Wiimote::Write() { Report rpt; if (m_write_reports.Pop(rpt)) { - wiiuse_io_write(m_wiimote, rpt.first, rpt.second); + wiiuse_io_write(wiimote, rpt.first, rpt.second); delete[] rpt.first; + + return true; } + + return false; } // returns the next report that should be sent @@ -232,8 +220,8 @@ void Wiimote::Update() u8* const rpt = ProcessReadQueue(); // send the report - if (rpt) - g_WiimoteInitialize.pWiimoteInterruptChannel(m_index, m_channel, rpt, MAX_PAYLOAD); + if (rpt && m_channel) + g_WiimoteInitialize.pWiimoteInterruptChannel(index, m_channel, rpt, MAX_PAYLOAD); // delete the data if it isn't also the last data rpt if (rpt != m_last_data_report) @@ -246,14 +234,6 @@ void Wiimote::Disconnect() // disable reporting DisableDataReporting(); - - // clear queue - u8 *rpt; - while (m_read_reports.Pop(rpt)) - delete rpt; - - // clear out wiiuse queue, or maybe not, silly? idk - while (wiiuse_io_read(m_wiimote)) {}; } void LoadSettings() @@ -297,7 +277,6 @@ unsigned int Initialize() // initialized g_real_wiimotes_initialized = true; - #ifdef WIN32 // Alloc memory for wiimote structure only if we're starting fresh if(!g_wiimotes_from_wiiuse) @@ -310,15 +289,14 @@ unsigned int Initialize() g_wiimotes_found = wiiuse_find(g_wiimotes_from_wiiuse, wanted_wiimotes, 5); #endif g_wiimotes_lastfound = g_wiimotes_found; - DEBUG_LOG(WIIMOTE, "Found %i Real Wiimotes, %i wanted and %i previously found", g_wiimotes_found, wanted_wiimotes, g_wiimotes_lastfound); + DEBUG_LOG(WIIMOTE, "Found %i Real Wiimotes, %i wanted and %i previously found", + g_wiimotes_found, wanted_wiimotes, g_wiimotes_lastfound); g_wiimotes_found = wiiuse_connect(g_wiimotes_from_wiiuse, g_wiimotes_found); DEBUG_LOG(WIIMOTE, "Connected to %i Real Wiimotes", g_wiimotes_found); - g_wiimote_critsec.Enter(); // enter - // create real wiimote class instances, assign wiimotes for (unsigned int i = 0, w = 0; iWaitForDeath(); - delete g_wiimote_thread; - g_wiimote_thread = NULL; - } - - g_wiimote_critsec.Enter(); // enter + StopWiimoteThreads(); // delete wiimotes for (unsigned int i=0; iWaitForDeath(); + delete g_wiimote_threads[i]; + g_wiimote_threads[i] = NULL; + } } THREAD_RETURN WiimoteThreadFunc(void* arg) { - Common::SetCurrentThreadName("Wiimote Thread"); + Wiimote* const wiimote = (Wiimote*)arg; + { + char thname[] = "Wiimote # Thread"; + thname[8] = (char)('1' + wiimote->index); + Common::SetCurrentThreadName(thname); + } + + // rumble briefly + wiiuse_rumble(wiimote->wiimote, 1); + SLEEP(200); + wiiuse_rumble(wiimote->wiimote, 0); + + // main loop while (g_run_wiimote_thread) { - g_wiimote_critsec.Enter(); // enter - - for (unsigned int i=0; iRead(); - g_wiimotes[i]->Write(); - } - - g_wiimote_critsec.Leave(); // leave - - Common::SleepCurrentThread(1); + wiimote->Write(); + if (false == wiimote->Read()) + Common::SleepCurrentThread(1); // sleep if there was nothing to read } return 0; diff --git a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.h b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.h index d557afa8b0..a2b9458223 100644 --- a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.h +++ b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.h @@ -57,8 +57,8 @@ public: u8* ProcessReadQueue(); - void Read(); - void Write(); + bool Read(); + bool Write(); void Disconnect(); void DisableDataReporting(); @@ -67,15 +67,16 @@ public: // pointer to data, and size of data typedef std::pair Report; + const unsigned int index; + wiimote_t* const wiimote; + protected: u8 *m_last_data_report; u16 m_channel; private: - void ClearReports(); + void ClearReadQueue(); - wiimote_t* const m_wiimote; - const unsigned int m_index; Common::FifoQueue m_read_reports; Common::FifoQueue m_write_reports; };