1 // Copyright 2010 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4 
5 #include "Core/HW/WiimoteReal/WiimoteReal.h"
6 
7 #include <algorithm>
8 #include <cstdlib>
9 #include <mutex>
10 #include <queue>
11 #include <unordered_set>
12 
13 #include "Common/ChunkFile.h"
14 #include "Common/CommonTypes.h"
15 #include "Common/FileUtil.h"
16 #include "Common/IniFile.h"
17 #include "Common/Swap.h"
18 #include "Common/Thread.h"
19 #include "Core/ConfigManager.h"
20 #include "Core/Core.h"
21 #include "Core/HW/Wiimote.h"
22 #include "Core/HW/WiimoteCommon/DataReport.h"
23 #include "Core/HW/WiimoteCommon/WiimoteHid.h"
24 #include "Core/HW/WiimoteReal/IOAndroid.h"
25 #include "Core/HW/WiimoteReal/IOLinux.h"
26 #include "Core/HW/WiimoteReal/IOWin.h"
27 #include "Core/HW/WiimoteReal/IOdarwin.h"
28 #include "Core/HW/WiimoteReal/IOhidapi.h"
29 #include "InputCommon/ControllerInterface/Wiimote/Wiimote.h"
30 #include "InputCommon/InputConfig.h"
31 
32 #include "SFML/Network.hpp"
33 
34 namespace WiimoteReal
35 {
36 using namespace WiimoteCommon;
37 
38 static void TryToConnectBalanceBoard(std::unique_ptr<Wiimote>);
39 static bool TryToConnectWiimoteToSlot(std::unique_ptr<Wiimote>&, unsigned int);
40 static void HandleWiimoteDisconnect(int index);
41 
42 static bool g_real_wiimotes_initialized = false;
43 
44 // This is used to store connected Wiimotes' IDs, so we don't connect
45 // more than once to the same device.
46 static std::unordered_set<std::string> s_known_ids;
47 static std::mutex s_known_ids_mutex;
48 
49 std::recursive_mutex g_wiimotes_mutex;
50 
51 // Real wii remotes assigned to a particular slot.
52 // Assignments must be done from the CPU thread with the above mutex held.
53 std::unique_ptr<Wiimote> g_wiimotes[MAX_BBMOTES];
54 
55 struct WiimotePoolEntry
56 {
57   using Clock = std::chrono::steady_clock;
58 
59   std::unique_ptr<Wiimote> wiimote;
60   Clock::time_point entry_time = Clock::now();
61 
IsExpiredWiimoteReal::WiimotePoolEntry62   bool IsExpired() const
63   {
64     // Keep wii remotes in the pool for a bit before disconnecting them.
65     constexpr auto POOL_TIME = std::chrono::seconds{5};
66 
67     return (Clock::now() - entry_time) > POOL_TIME;
68   }
69 };
70 
71 // Connected wii remotes are placed here when no open slot is set to "Real".
72 // They are then automatically disconnected after some time.
73 static std::vector<WiimotePoolEntry> s_wiimote_pool;
74 
75 static WiimoteScanner s_wiimote_scanner;
76 
77 // Attempt to fill a real wiimote slot from the pool or by stealing from ControllerInterface.
TryToFillWiimoteSlot(u32 index)78 static void TryToFillWiimoteSlot(u32 index)
79 {
80   std::lock_guard lk(g_wiimotes_mutex);
81 
82   if (g_wiimotes[index] || WiimoteCommon::GetSource(index) != WiimoteSource::Real)
83     return;
84 
85   // If the pool is empty, attempt to steal from ControllerInterface.
86   if (s_wiimote_pool.empty())
87   {
88     ciface::Wiimote::ReleaseDevices(1);
89 
90     // Still empty?
91     if (s_wiimote_pool.empty())
92       return;
93   }
94 
95   if (TryToConnectWiimoteToSlot(s_wiimote_pool.front().wiimote, index))
96     s_wiimote_pool.erase(s_wiimote_pool.begin());
97 }
98 
99 // Attempts to fill enabled real wiimote slots.
100 // Push/pull wiimotes to/from ControllerInterface as needed.
ProcessWiimotePool()101 void ProcessWiimotePool()
102 {
103   std::lock_guard lk(g_wiimotes_mutex);
104 
105   for (u32 index = 0; index != MAX_WIIMOTES; ++index)
106     TryToFillWiimoteSlot(index);
107 
108   if (SConfig::GetInstance().connect_wiimotes_for_ciface)
109   {
110     for (auto& entry : s_wiimote_pool)
111       ciface::Wiimote::AddDevice(std::move(entry.wiimote));
112 
113     s_wiimote_pool.clear();
114   }
115   else
116   {
117     ciface::Wiimote::ReleaseDevices();
118   }
119 }
120 
AddWiimoteToPool(std::unique_ptr<Wiimote> wiimote)121 void AddWiimoteToPool(std::unique_ptr<Wiimote> wiimote)
122 {
123   // Our real wiimote class requires an index.
124   // Within the pool it's only going to be used for logging purposes.
125   static constexpr int POOL_WIIMOTE_INDEX = 99;
126 
127   if (!wiimote->Connect(POOL_WIIMOTE_INDEX))
128   {
129     ERROR_LOG(WIIMOTE, "Failed to connect real wiimote.");
130     return;
131   }
132 
133   wiimote->EmuStop();
134 
135   std::lock_guard lk(g_wiimotes_mutex);
136   s_wiimote_pool.emplace_back(WiimotePoolEntry{std::move(wiimote)});
137 }
138 
139 Wiimote::Wiimote() = default;
140 
Shutdown()141 void Wiimote::Shutdown()
142 {
143   std::lock_guard<std::mutex> lk(s_known_ids_mutex);
144   s_known_ids.erase(GetId());
145 
146   StopThread();
147   ClearReadQueue();
148   m_write_reports.Clear();
149 
150   NOTICE_LOG(WIIMOTE, "Disconnected real wiimote.");
151 }
152 
153 // to be called from CPU thread
WriteReport(Report rpt)154 void Wiimote::WriteReport(Report rpt)
155 {
156   if (rpt.size() >= 3)
157   {
158     bool const new_rumble_state = (rpt[2] & 0x1) != 0;
159 
160     switch (WiimoteCommon::OutputReportID(rpt[1]))
161     {
162     case OutputReportID::Rumble:
163       // If this is a rumble report and the rumble state didn't change, we can drop this report.
164       if (new_rumble_state == m_rumble_state)
165         return;
166       break;
167 
168     case OutputReportID::SpeakerEnable:
169       m_speaker_enable = (rpt[2] & 0x4) != 0;
170       break;
171 
172     case OutputReportID::SpeakerMute:
173       m_speaker_mute = (rpt[2] & 0x4) != 0;
174       break;
175 
176     case OutputReportID::ReportMode:
177       // Force non-continuous reporting for less BT traffic.
178       // We duplicate reports to maintain 200hz anyways.
179       rpt[2] &= ~0x4;
180       break;
181 
182     default:
183       break;
184     }
185 
186     m_rumble_state = new_rumble_state;
187   }
188 
189   m_write_reports.Push(std::move(rpt));
190   IOWakeup();
191 }
192 
193 // to be called from CPU thread
QueueReport(WiimoteCommon::OutputReportID rpt_id,const void * data,unsigned int size)194 void Wiimote::QueueReport(WiimoteCommon::OutputReportID rpt_id, const void* data, unsigned int size)
195 {
196   auto const queue_data = static_cast<const u8*>(data);
197 
198   Report rpt(size + 2);
199   rpt[0] = WR_SET_REPORT | BT_OUTPUT;
200   rpt[1] = u8(rpt_id);
201   std::copy_n(queue_data, size, rpt.begin() + 2);
202   WriteReport(std::move(rpt));
203 }
204 
ResetDataReporting()205 void Wiimote::ResetDataReporting()
206 {
207   m_last_input_report.clear();
208 
209   // "core" reporting in non-continuous mode is a wiimote's initial state.
210   // FYI: This also disables rumble.
211   OutputReportMode rpt = {};
212   rpt.mode = InputReportID::ReportCore;
213   rpt.continuous = 0;
214   QueueReport(rpt);
215 }
216 
ClearReadQueue()217 void Wiimote::ClearReadQueue()
218 {
219   Report rpt;
220 
221   // The "Clear" function isn't thread-safe :/
222   while (m_read_reports.Pop(rpt))
223   {
224   }
225 }
226 
EventLinked()227 void Wiimote::EventLinked()
228 {
229   m_is_linked = true;
230 
231   ClearReadQueue();
232   ResetDataReporting();
233   EnablePowerAssertionInternal();
234 }
235 
EventUnlinked()236 void Wiimote::EventUnlinked()
237 {
238   if (m_really_disconnect)
239     DisconnectInternal();
240   else
241     EmuStop();
242 }
243 
InterruptDataOutput(const u8 * data,const u32 size)244 void Wiimote::InterruptDataOutput(const u8* data, const u32 size)
245 {
246   Report rpt(size + REPORT_HID_HEADER_SIZE);
247   std::copy_n(data, size, rpt.data() + REPORT_HID_HEADER_SIZE);
248 
249   // Convert output DATA packets to SET_REPORT packets.
250   // Nintendo Wiimotes work without this translation, but 3rd
251   // party ones don't.
252   rpt[0] = WR_SET_REPORT | BT_OUTPUT;
253 
254   // Disallow games from turning off all of the LEDs.
255   // It makes Wiimote connection status confusing.
256   if (rpt[1] == u8(OutputReportID::LED))
257   {
258     auto& leds_rpt = *reinterpret_cast<OutputReportLeds*>(&rpt[2]);
259     if (0 == leds_rpt.leds)
260     {
261       // Turn on ALL of the LEDs.
262       leds_rpt.leds = 0xf;
263     }
264   }
265   else if (rpt[1] == u8(OutputReportID::SpeakerData) &&
266            (!SConfig::GetInstance().m_WiimoteEnableSpeaker || !m_speaker_enable || m_speaker_mute))
267   {
268     rpt.resize(3);
269     // Translate undesired speaker data reports into rumble reports.
270     rpt[1] = u8(OutputReportID::Rumble);
271     // Keep only the rumble bit.
272     rpt[2] &= 0x1;
273   }
274 
275   WriteReport(std::move(rpt));
276 }
277 
Read()278 void Wiimote::Read()
279 {
280   Report rpt(MAX_PAYLOAD);
281   auto const result = IORead(rpt.data());
282 
283   // Drop the report if not connected.
284   if (!m_is_linked)
285     return;
286 
287   if (result > 0)
288   {
289     if (SConfig::GetInstance().iBBDumpPort > 0 && m_index == WIIMOTE_BALANCE_BOARD)
290     {
291       static sf::UdpSocket Socket;
292       Socket.send((char*)rpt.data(), rpt.size(), sf::IpAddress::LocalHost,
293                   SConfig::GetInstance().iBBDumpPort);
294     }
295 
296     // Add it to queue
297     rpt.resize(result);
298     m_read_reports.Push(std::move(rpt));
299   }
300   else if (0 == result)
301   {
302     ERROR_LOG(WIIMOTE, "Wiimote::IORead failed. Disconnecting Wii Remote %d.", m_index + 1);
303     DisconnectInternal();
304   }
305 }
306 
Write()307 bool Wiimote::Write()
308 {
309   // nothing written, but this is not an error
310   if (m_write_reports.Empty())
311     return true;
312 
313   Report const& rpt = m_write_reports.Front();
314 
315   if (SConfig::GetInstance().iBBDumpPort > 0 && m_index == WIIMOTE_BALANCE_BOARD)
316   {
317     static sf::UdpSocket Socket;
318     Socket.send((char*)rpt.data(), rpt.size(), sf::IpAddress::LocalHost,
319                 SConfig::GetInstance().iBBDumpPort);
320   }
321   int ret = IOWrite(rpt.data(), rpt.size());
322 
323   m_write_reports.Pop();
324 
325   if (!m_write_reports.Empty())
326     IOWakeup();
327 
328   return ret != 0;
329 }
330 
IsBalanceBoard()331 bool Wiimote::IsBalanceBoard()
332 {
333   if (!ConnectInternal())
334     return false;
335   // Initialise the extension by writing 0x55 to 0xa400f0, then writing 0x00 to 0xa400fb.
336   // TODO: Use the structs for building these reports..
337   static const u8 init_extension_rpt1[MAX_PAYLOAD] = {
338       WR_SET_REPORT | BT_OUTPUT, u8(OutputReportID::WriteData), 0x04, 0xa4, 0x00, 0xf0, 0x01, 0x55};
339   static const u8 init_extension_rpt2[MAX_PAYLOAD] = {
340       WR_SET_REPORT | BT_OUTPUT, u8(OutputReportID::WriteData), 0x04, 0xa4, 0x00, 0xfb, 0x01, 0x00};
341   static const u8 status_report[] = {WR_SET_REPORT | BT_OUTPUT, u8(OutputReportID::RequestStatus),
342                                      0};
343   if (!IOWrite(init_extension_rpt1, sizeof(init_extension_rpt1)) ||
344       !IOWrite(init_extension_rpt2, sizeof(init_extension_rpt2)))
345   {
346     ERROR_LOG(WIIMOTE, "IsBalanceBoard(): Failed to initialise extension.");
347     return false;
348   }
349 
350   int ret = IOWrite(status_report, sizeof(status_report));
351   u8 buf[MAX_PAYLOAD];
352   while (ret != 0)
353   {
354     ret = IORead(buf);
355     if (ret == -1)
356       continue;
357 
358     switch (InputReportID(buf[1]))
359     {
360     case InputReportID::Status:
361     {
362       const auto* status = reinterpret_cast<InputReportStatus*>(&buf[2]);
363       // A Balance Board has a Balance Board extension.
364       if (!status->extension)
365         return false;
366       // Read two bytes from 0xa400fe to identify the extension.
367       static const u8 identify_ext_rpt[] = {WR_SET_REPORT | BT_OUTPUT,
368                                             u8(OutputReportID::ReadData),
369                                             0x04,
370                                             0xa4,
371                                             0x00,
372                                             0xfe,
373                                             0x02,
374                                             0x00};
375       ret = IOWrite(identify_ext_rpt, sizeof(identify_ext_rpt));
376       break;
377     }
378     case InputReportID::ReadDataReply:
379     {
380       const auto* reply = reinterpret_cast<InputReportReadDataReply*>(&buf[2]);
381       if (Common::swap16(reply->address) != 0x00fe)
382       {
383         ERROR_LOG(WIIMOTE, "IsBalanceBoard(): Received unexpected data reply for address %X",
384                   Common::swap16(reply->address));
385         return false;
386       }
387       // A Balance Board ext can be identified by checking for 0x0402.
388       return reply->data[0] == 0x04 && reply->data[1] == 0x02;
389     }
390     case InputReportID::Ack:
391     {
392       const auto* ack = reinterpret_cast<InputReportAck*>(&buf[2]);
393       if (ack->rpt_id == OutputReportID::ReadData && ack->error_code != ErrorCode::Success)
394       {
395         WARN_LOG(WIIMOTE, "Failed to read from 0xa400fe, assuming Wiimote is not a Balance Board.");
396         return false;
397       }
398     }
399     default:
400       break;
401     }
402   }
403   return false;
404 }
405 
IsDataReport(const Report & rpt)406 static bool IsDataReport(const Report& rpt)
407 {
408   return rpt.size() >= 2 && rpt[1] >= u8(InputReportID::ReportCore);
409 }
410 
GetNextReport(Report * report)411 bool Wiimote::GetNextReport(Report* report)
412 {
413   return m_read_reports.Pop(*report);
414 }
415 
416 // Returns the next report that should be sent
ProcessReadQueue()417 Report& Wiimote::ProcessReadQueue()
418 {
419   // Pop through the queued reports
420   while (GetNextReport(&m_last_input_report))
421   {
422     if (!IsDataReport(m_last_input_report))
423     {
424       // A non-data report, use it.
425       return m_last_input_report;
426 
427       // Forget the last data report as it may be of the wrong type
428       // or contain outdated button data
429       // or it's not supposed to be sent at this time
430       // It's just easier to be correct this way and it's probably not horrible.
431     }
432   }
433 
434   // If the last report wasn't a data report it's irrelevant.
435   if (!IsDataReport(m_last_input_report))
436     m_last_input_report.clear();
437 
438   // If it was a data report, we repeat that until something else comes in.
439   return m_last_input_report;
440 }
441 
Update()442 void Wiimote::Update()
443 {
444   // Pop through the queued reports
445   const Report& rpt = ProcessReadQueue();
446 
447   // Send the report
448   if (!rpt.empty())
449     InterruptCallback(rpt.front(), rpt.data() + REPORT_HID_HEADER_SIZE,
450                       u32(rpt.size() - REPORT_HID_HEADER_SIZE));
451 }
452 
IsButtonPressed()453 bool Wiimote::IsButtonPressed()
454 {
455   Report& rpt = m_last_input_report;
456   if (rpt.size() >= 4)
457   {
458     const auto mode = InputReportID(rpt[1]);
459 
460     // TODO: Button data could also be pulled out of non-data reports if really wanted.
461     if (DataReportBuilder::IsValidMode(mode))
462     {
463       auto builder = MakeDataReportManipulator(mode, rpt.data() + 2);
464       ButtonData buttons = {};
465       builder->GetCoreData(&buttons);
466 
467       return buttons.hex != 0;
468     }
469   }
470   return false;
471 }
472 
Prepare()473 void Wiimote::Prepare()
474 {
475   m_need_prepare.Set();
476   IOWakeup();
477 }
478 
PrepareOnThread()479 bool Wiimote::PrepareOnThread()
480 {
481   // Set reporting mode to non-continuous core buttons and turn on rumble.
482   u8 static const mode_report[] = {WR_SET_REPORT | BT_OUTPUT, u8(OutputReportID::ReportMode), 1,
483                                    u8(InputReportID::ReportCore)};
484 
485   // Request status and turn off rumble.
486   u8 static const req_status_report[] = {WR_SET_REPORT | BT_OUTPUT,
487                                          u8(OutputReportID::RequestStatus), 0};
488 
489   return IOWrite(mode_report, sizeof(mode_report)) &&
490          (Common::SleepCurrentThread(200), IOWrite(req_status_report, sizeof(req_status_report)));
491 }
492 
EmuStop()493 void Wiimote::EmuStop()
494 {
495   m_is_linked = false;
496 
497   ResetDataReporting();
498   DisablePowerAssertionInternal();
499 }
500 
EmuResume()501 void Wiimote::EmuResume()
502 {
503   EnablePowerAssertionInternal();
504 }
505 
EmuPause()506 void Wiimote::EmuPause()
507 {
508   DisablePowerAssertionInternal();
509 }
510 
CalculateWantedWiimotes()511 static unsigned int CalculateWantedWiimotes()
512 {
513   std::lock_guard lk(g_wiimotes_mutex);
514   // Figure out how many real Wiimotes are required
515   unsigned int wanted_wiimotes = 0;
516   for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
517     if (WiimoteCommon::GetSource(i) == WiimoteSource::Real && !g_wiimotes[i])
518       ++wanted_wiimotes;
519   return wanted_wiimotes;
520 }
521 
CalculateWantedBB()522 static unsigned int CalculateWantedBB()
523 {
524   std::lock_guard lk(g_wiimotes_mutex);
525   unsigned int wanted_bb = 0;
526   if (WiimoteCommon::GetSource(WIIMOTE_BALANCE_BOARD) == WiimoteSource::Real &&
527       !g_wiimotes[WIIMOTE_BALANCE_BOARD])
528     ++wanted_bb;
529   return wanted_bb;
530 }
531 
StartThread()532 void WiimoteScanner::StartThread()
533 {
534   if (m_scan_thread_running.IsSet())
535     return;
536   m_scan_thread_running.Set();
537   m_scan_thread = std::thread(&WiimoteScanner::ThreadFunc, this);
538 }
539 
StopThread()540 void WiimoteScanner::StopThread()
541 {
542   if (m_scan_thread_running.TestAndClear())
543   {
544     SetScanMode(WiimoteScanMode::DO_NOT_SCAN);
545     m_scan_thread.join();
546   }
547 }
548 
SetScanMode(WiimoteScanMode scan_mode)549 void WiimoteScanner::SetScanMode(WiimoteScanMode scan_mode)
550 {
551   m_scan_mode.store(scan_mode);
552   m_scan_mode_changed_event.Set();
553 }
554 
IsReady() const555 bool WiimoteScanner::IsReady() const
556 {
557   std::lock_guard<std::mutex> lg(m_backends_mutex);
558   return std::any_of(m_backends.begin(), m_backends.end(),
559                      [](const auto& backend) { return backend->IsReady(); });
560 }
561 
CheckForDisconnectedWiimotes()562 static void CheckForDisconnectedWiimotes()
563 {
564   std::lock_guard lk(g_wiimotes_mutex);
565   for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
566     if (g_wiimotes[i] && !g_wiimotes[i]->IsConnected())
567       HandleWiimoteDisconnect(i);
568 }
569 
PoolThreadFunc()570 void WiimoteScanner::PoolThreadFunc()
571 {
572   Common::SetCurrentThreadName("Wiimote Pool Thread");
573 
574   // Toggle between 1010 and 0101.
575   u8 led_value = 0b1010;
576 
577   auto next_time = std::chrono::steady_clock::now();
578 
579   while (m_scan_thread_running.IsSet())
580   {
581     std::this_thread::sleep_until(next_time);
582     next_time += std::chrono::milliseconds(250);
583 
584     std::lock_guard lk(g_wiimotes_mutex);
585 
586     // Remove stale pool entries.
587     for (auto it = s_wiimote_pool.begin(); it != s_wiimote_pool.end();)
588     {
589       if (!it->wiimote->IsConnected())
590       {
591         INFO_LOG(WIIMOTE, "Removing disconnected wiimote pool entry.");
592         it = s_wiimote_pool.erase(it);
593       }
594       else if (it->IsExpired())
595       {
596         INFO_LOG(WIIMOTE, "Removing expired wiimote pool entry.");
597         it = s_wiimote_pool.erase(it);
598       }
599       else
600       {
601         ++it;
602       }
603     }
604 
605     // Make wiimote pool LEDs dance.
606     for (auto& wiimote : s_wiimote_pool)
607     {
608       OutputReportLeds leds = {};
609       leds.leds = led_value;
610       wiimote.wiimote->QueueReport(leds);
611     }
612 
613     led_value ^= 0b1111;
614   }
615 }
616 
ThreadFunc()617 void WiimoteScanner::ThreadFunc()
618 {
619   std::thread pool_thread(&WiimoteScanner::PoolThreadFunc, this);
620 
621   Common::SetCurrentThreadName("Wiimote Scanning Thread");
622 
623   NOTICE_LOG(WIIMOTE, "Wiimote scanning thread has started.");
624 
625   // Create and destroy scanner backends here to ensure all operations stay on the same thread. The
626   // HIDAPI backend on macOS has an error condition when IOHIDManagerCreate and IOHIDManagerClose
627   // are called on different threads (and so reference different CFRunLoops) which can cause an
628   // EXC_BAD_ACCES crash.
629   {
630     std::lock_guard<std::mutex> lg(m_backends_mutex);
631 
632     m_backends.emplace_back(std::make_unique<WiimoteScannerLinux>());
633     m_backends.emplace_back(std::make_unique<WiimoteScannerAndroid>());
634     m_backends.emplace_back(std::make_unique<WiimoteScannerWindows>());
635     m_backends.emplace_back(std::make_unique<WiimoteScannerDarwin>());
636     m_backends.emplace_back(std::make_unique<WiimoteScannerHidapi>());
637   }
638 
639   while (m_scan_thread_running.IsSet())
640   {
641     m_scan_mode_changed_event.WaitFor(std::chrono::milliseconds(500));
642 
643     // Does stuff needed to detect disconnects on Windows
644     for (const auto& backend : m_backends)
645       backend->Update();
646 
647     CheckForDisconnectedWiimotes();
648 
649     if (m_scan_mode.load() == WiimoteScanMode::DO_NOT_SCAN)
650       continue;
651 
652     // If we don't want Wiimotes in ControllerInterface, we may not need them at all.
653     if (!SConfig::GetInstance().connect_wiimotes_for_ciface)
654     {
655       // We don't want any remotes in passthrough mode or running in GC mode.
656       const bool core_running = Core::GetState() != Core::State::Uninitialized;
657       if (SConfig::GetInstance().m_bt_passthrough_enabled ||
658           (core_running && !SConfig::GetInstance().bWii))
659         continue;
660 
661       // We don't want any remotes if we already connected everything we need.
662       if (0 == CalculateWantedWiimotes() && 0 == CalculateWantedBB())
663         continue;
664     }
665 
666     for (const auto& backend : m_backends)
667     {
668       std::vector<Wiimote*> found_wiimotes;
669       Wiimote* found_board = nullptr;
670       backend->FindWiimotes(found_wiimotes, found_board);
671       {
672         std::unique_lock wm_lk(g_wiimotes_mutex);
673 
674         for (auto* wiimote : found_wiimotes)
675         {
676           {
677             std::lock_guard<std::mutex> lk(s_known_ids_mutex);
678             s_known_ids.insert(wiimote->GetId());
679           }
680 
681           AddWiimoteToPool(std::unique_ptr<Wiimote>(wiimote));
682           ProcessWiimotePool();
683         }
684 
685         if (found_board)
686         {
687           {
688             std::lock_guard<std::mutex> lk(s_known_ids_mutex);
689             s_known_ids.insert(found_board->GetId());
690           }
691 
692           TryToConnectBalanceBoard(std::unique_ptr<Wiimote>(found_board));
693         }
694       }
695     }
696 
697     // Stop scanning if not in continous mode.
698     auto scan_mode = WiimoteScanMode::SCAN_ONCE;
699     m_scan_mode.compare_exchange_strong(scan_mode, WiimoteScanMode::DO_NOT_SCAN);
700   }
701 
702   {
703     std::lock_guard<std::mutex> lg(m_backends_mutex);
704     m_backends.clear();
705   }
706 
707   pool_thread.join();
708 
709   NOTICE_LOG(WIIMOTE, "Wiimote scanning thread has stopped.");
710 }
711 
Connect(int index)712 bool Wiimote::Connect(int index)
713 {
714   m_index = index;
715 
716   if (!m_run_thread.IsSet())
717   {
718     m_need_prepare.Set();
719     m_run_thread.Set();
720     StartThread();
721     m_thread_ready_event.Wait();
722   }
723 
724   return IsConnected();
725 }
726 
StartThread()727 void Wiimote::StartThread()
728 {
729   m_wiimote_thread = std::thread(&Wiimote::ThreadFunc, this);
730 }
731 
StopThread()732 void Wiimote::StopThread()
733 {
734   if (!m_run_thread.TestAndClear())
735     return;
736   IOWakeup();
737   m_wiimote_thread.join();
738 }
739 
ThreadFunc()740 void Wiimote::ThreadFunc()
741 {
742   Common::SetCurrentThreadName("Wiimote Device Thread");
743 
744   bool ok = ConnectInternal();
745 
746   if (!ok)
747   {
748     // try again, it might take a moment to settle
749     Common::SleepCurrentThread(100);
750     ok = ConnectInternal();
751   }
752 
753   m_thread_ready_event.Set();
754 
755   if (!ok)
756   {
757     return;
758   }
759 
760   // main loop
761   while (IsConnected() && m_run_thread.IsSet())
762   {
763     if (m_need_prepare.TestAndClear() && !PrepareOnThread())
764     {
765       ERROR_LOG(WIIMOTE, "Wiimote::PrepareOnThread failed.  Disconnecting Wiimote %d.",
766                 m_index + 1);
767       break;
768     }
769     if (!Write())
770     {
771       ERROR_LOG(WIIMOTE, "Wiimote::Write failed.  Disconnecting Wiimote %d.", m_index + 1);
772       break;
773     }
774     Read();
775   }
776 
777   DisconnectInternal();
778 }
779 
GetIndex() const780 int Wiimote::GetIndex() const
781 {
782   return m_index;
783 }
784 
LoadSettings()785 void LoadSettings()
786 {
787   std::string ini_filename = File::GetUserPath(D_CONFIG_IDX) + WIIMOTE_INI_NAME ".ini";
788 
789   IniFile inifile;
790   inifile.Load(ini_filename);
791 
792   for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
793   {
794     std::string secname("Wiimote");
795     secname += static_cast<char>('1' + i);
796     IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
797 
798     unsigned int source = 0;
799     sec.Get("Source", &source, i ? int(WiimoteSource::None) : int(WiimoteSource::Emulated));
800     WiimoteCommon::SetSource(i, WiimoteSource(source));
801   }
802 
803   std::string secname("BalanceBoard");
804   IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
805 
806   unsigned int bb_source = 0;
807   sec.Get("Source", &bb_source, int(WiimoteSource::None));
808   WiimoteCommon::SetSource(WIIMOTE_BALANCE_BOARD, WiimoteSource(bb_source));
809 }
810 
811 // config dialog calls this when some settings change
Initialize(::Wiimote::InitializeMode init_mode)812 void Initialize(::Wiimote::InitializeMode init_mode)
813 {
814   if (!g_real_wiimotes_initialized)
815   {
816     s_wiimote_scanner.StartThread();
817   }
818 
819   if (SConfig::GetInstance().m_WiimoteContinuousScanning)
820     s_wiimote_scanner.SetScanMode(WiimoteScanMode::CONTINUOUSLY_SCAN);
821   else
822     s_wiimote_scanner.SetScanMode(WiimoteScanMode::DO_NOT_SCAN);
823 
824   // wait for connection because it should exist before state load
825   if (init_mode == ::Wiimote::InitializeMode::DO_WAIT_FOR_WIIMOTES)
826   {
827     int timeout = 100;
828     s_wiimote_scanner.SetScanMode(WiimoteScanMode::SCAN_ONCE);
829     while (CalculateWantedWiimotes() && timeout)
830     {
831       Common::SleepCurrentThread(100);
832       timeout--;
833     }
834   }
835 
836   if (g_real_wiimotes_initialized)
837     return;
838 
839   NOTICE_LOG(WIIMOTE, "WiimoteReal::Initialize");
840 
841   g_real_wiimotes_initialized = true;
842 }
843 
844 // called on emulation shutdown
Stop()845 void Stop()
846 {
847   for (auto& wiimote : g_wiimotes)
848     if (wiimote && wiimote->IsConnected())
849       wiimote->EmuStop();
850 }
851 
852 // called when the Dolphin app exits
Shutdown()853 void Shutdown()
854 {
855   g_real_wiimotes_initialized = false;
856   s_wiimote_scanner.StopThread();
857 
858   NOTICE_LOG(WIIMOTE, "WiimoteReal::Shutdown");
859 
860   std::lock_guard lk(g_wiimotes_mutex);
861   for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
862     HandleWiimoteDisconnect(i);
863 
864   // Release remotes from ControllerInterface and empty the pool.
865   ciface::Wiimote::ReleaseDevices();
866   s_wiimote_pool.clear();
867 }
868 
Resume()869 void Resume()
870 {
871   for (auto& wiimote : g_wiimotes)
872     if (wiimote && wiimote->IsConnected())
873       wiimote->EmuResume();
874 }
875 
Pause()876 void Pause()
877 {
878   for (auto& wiimote : g_wiimotes)
879     if (wiimote && wiimote->IsConnected())
880       wiimote->EmuPause();
881 }
882 
883 // Called from the Wiimote scanner thread (or UI thread on source change)
TryToConnectWiimoteToSlot(std::unique_ptr<Wiimote> & wm,unsigned int i)884 static bool TryToConnectWiimoteToSlot(std::unique_ptr<Wiimote>& wm, unsigned int i)
885 {
886   if (WiimoteCommon::GetSource(i) != WiimoteSource::Real || g_wiimotes[i])
887     return false;
888 
889   if (!wm->Connect(i))
890   {
891     ERROR_LOG(WIIMOTE, "Failed to connect real wiimote.");
892     return false;
893   }
894 
895   wm->Prepare();
896 
897   // Set LEDs.
898   OutputReportLeds led_report = {};
899   led_report.leds = u8(1 << (i % WIIMOTE_BALANCE_BOARD));
900   wm->QueueReport(led_report);
901 
902   Core::RunAsCPUThread([i, &wm] {
903     g_wiimotes[i] = std::move(wm);
904     WiimoteCommon::UpdateSource(i);
905   });
906 
907   NOTICE_LOG(WIIMOTE, "Connected real wiimote to slot %i.", i + 1);
908 
909   return true;
910 }
911 
TryToConnectBalanceBoard(std::unique_ptr<Wiimote> wm)912 static void TryToConnectBalanceBoard(std::unique_ptr<Wiimote> wm)
913 {
914   if (TryToConnectWiimoteToSlot(wm, WIIMOTE_BALANCE_BOARD))
915     return;
916 
917   NOTICE_LOG(WIIMOTE, "No open slot for real balance board.");
918 }
919 
HandleWiimoteDisconnect(int index)920 static void HandleWiimoteDisconnect(int index)
921 {
922   Core::RunAsCPUThread([index] {
923     g_wiimotes[index] = nullptr;
924     WiimoteCommon::UpdateSource(index);
925   });
926 }
927 
928 // This is called from the GUI thread
Refresh()929 void Refresh()
930 {
931   if (!SConfig::GetInstance().m_WiimoteContinuousScanning)
932     s_wiimote_scanner.SetScanMode(WiimoteScanMode::SCAN_ONCE);
933 }
934 
IsValidDeviceName(const std::string & name)935 bool IsValidDeviceName(const std::string& name)
936 {
937   return "Nintendo RVL-CNT-01" == name || "Nintendo RVL-CNT-01-TR" == name ||
938          IsBalanceBoardName(name);
939 }
940 
IsBalanceBoardName(const std::string & name)941 bool IsBalanceBoardName(const std::string& name)
942 {
943   return "Nintendo RVL-WBC-01" == name;
944 }
945 
946 // This is called from the scanner backends (currently on the scanner thread).
IsNewWiimote(const std::string & identifier)947 bool IsNewWiimote(const std::string& identifier)
948 {
949   std::lock_guard<std::mutex> lk(s_known_ids_mutex);
950   return s_known_ids.count(identifier) == 0;
951 }
952 
HandleWiimoteSourceChange(unsigned int index)953 void HandleWiimoteSourceChange(unsigned int index)
954 {
955   std::lock_guard wm_lk(g_wiimotes_mutex);
956 
957   Core::RunAsCPUThread([index] {
958     if (auto removed_wiimote = std::move(g_wiimotes[index]))
959       AddWiimoteToPool(std::move(removed_wiimote));
960   });
961   ProcessWiimotePool();
962 }
963 
HandleWiimotesInControllerInterfaceSettingChange()964 void HandleWiimotesInControllerInterfaceSettingChange()
965 {
966   ProcessWiimotePool();
967 }
968 
969 }  // namespace WiimoteReal
970