222 lines
5.7 KiB
C++
222 lines
5.7 KiB
C++
// Copyright 2010 Dolphin Emulator Project
|
|
// Licensed under GPLv2+
|
|
// Refer to the license.txt file included.
|
|
|
|
#include "Core/HW/Wiimote.h"
|
|
|
|
#include "Common/ChunkFile.h"
|
|
#include "Common/CommonTypes.h"
|
|
|
|
#include "Core/ConfigManager.h"
|
|
#include "Core/Core.h"
|
|
#include "Core/HW/WiimoteEmu/WiimoteEmu.h"
|
|
#include "Core/HW/WiimoteReal/WiimoteReal.h"
|
|
#include "Core/IOS/IOS.h"
|
|
#include "Core/IOS/USB/Bluetooth/BTEmu.h"
|
|
#include "Core/IOS/USB/Bluetooth/WiimoteDevice.h"
|
|
#include "Core/Movie.h"
|
|
#include "Core/NetPlayClient.h"
|
|
|
|
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
|
|
#include "InputCommon/InputConfig.h"
|
|
|
|
// Limit the amount of wiimote connect requests, when a button is pressed in disconnected state
|
|
static std::array<u8, MAX_BBMOTES> s_last_connect_request_counter;
|
|
|
|
namespace WiimoteCommon
|
|
{
|
|
static std::array<std::atomic<WiimoteSource>, MAX_BBMOTES> s_wiimote_sources;
|
|
|
|
WiimoteSource GetSource(unsigned int index)
|
|
{
|
|
return s_wiimote_sources[index];
|
|
}
|
|
|
|
void SetSource(unsigned int index, WiimoteSource source)
|
|
{
|
|
const WiimoteSource previous_source = s_wiimote_sources[index].exchange(source);
|
|
|
|
if (previous_source == source)
|
|
{
|
|
// No change. Do nothing.
|
|
return;
|
|
}
|
|
|
|
WiimoteReal::HandleWiimoteSourceChange(index);
|
|
|
|
Core::RunAsCPUThread([index] { UpdateSource(index); });
|
|
}
|
|
|
|
void UpdateSource(unsigned int index)
|
|
{
|
|
const auto ios = IOS::HLE::GetIOS();
|
|
if (!ios)
|
|
return;
|
|
|
|
if (s_wiimote_sources[index] != WiimoteSource::Emulated)
|
|
return;
|
|
|
|
const auto bluetooth = std::static_pointer_cast<IOS::HLE::BluetoothEmuDevice>(
|
|
ios->GetDeviceByName("/dev/usb/oh1/57e/305"));
|
|
if (!bluetooth)
|
|
return;
|
|
|
|
bluetooth->AccessWiimoteByIndex(index)->SetSource(GetHIDWiimoteSource(index));
|
|
}
|
|
|
|
HIDWiimote* GetHIDWiimoteSource(unsigned int index)
|
|
{
|
|
HIDWiimote* hid_source = nullptr;
|
|
|
|
switch (GetSource(index))
|
|
{
|
|
case WiimoteSource::Emulated:
|
|
hid_source = static_cast<WiimoteEmu::Wiimote*>(::Wiimote::GetConfig()->GetController(index));
|
|
break;
|
|
|
|
case WiimoteSource::Real:
|
|
hid_source = WiimoteReal::g_wiimotes[index].get();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return hid_source;
|
|
}
|
|
|
|
} // namespace WiimoteCommon
|
|
|
|
namespace Wiimote
|
|
{
|
|
static InputConfig s_config(WIIMOTE_INI_NAME, _trans("Wii Remote"), "Wiimote");
|
|
|
|
InputConfig* GetConfig()
|
|
{
|
|
return &s_config;
|
|
}
|
|
|
|
ControllerEmu::ControlGroup* GetWiimoteGroup(int number, WiimoteEmu::WiimoteGroup group)
|
|
{
|
|
return static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))->GetWiimoteGroup(group);
|
|
}
|
|
|
|
ControllerEmu::ControlGroup* GetNunchukGroup(int number, WiimoteEmu::NunchukGroup group)
|
|
{
|
|
return static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))->GetNunchukGroup(group);
|
|
}
|
|
|
|
ControllerEmu::ControlGroup* GetClassicGroup(int number, WiimoteEmu::ClassicGroup group)
|
|
{
|
|
return static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))->GetClassicGroup(group);
|
|
}
|
|
|
|
ControllerEmu::ControlGroup* GetGuitarGroup(int number, WiimoteEmu::GuitarGroup group)
|
|
{
|
|
return static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))->GetGuitarGroup(group);
|
|
}
|
|
|
|
ControllerEmu::ControlGroup* GetDrumsGroup(int number, WiimoteEmu::DrumsGroup group)
|
|
{
|
|
return static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))->GetDrumsGroup(group);
|
|
}
|
|
|
|
ControllerEmu::ControlGroup* GetTurntableGroup(int number, WiimoteEmu::TurntableGroup group)
|
|
{
|
|
return static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))
|
|
->GetTurntableGroup(group);
|
|
}
|
|
|
|
ControllerEmu::ControlGroup* GetUDrawTabletGroup(int number, WiimoteEmu::UDrawTabletGroup group)
|
|
{
|
|
return static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))
|
|
->GetUDrawTabletGroup(group);
|
|
}
|
|
|
|
ControllerEmu::ControlGroup* GetDrawsomeTabletGroup(int number,
|
|
WiimoteEmu::DrawsomeTabletGroup group)
|
|
{
|
|
return static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))
|
|
->GetDrawsomeTabletGroup(group);
|
|
}
|
|
|
|
ControllerEmu::ControlGroup* GetTaTaConGroup(int number, WiimoteEmu::TaTaConGroup group)
|
|
{
|
|
return static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))->GetTaTaConGroup(group);
|
|
}
|
|
|
|
void Shutdown()
|
|
{
|
|
s_config.UnregisterHotplugCallback();
|
|
|
|
s_config.ClearControllers();
|
|
|
|
WiimoteReal::Stop();
|
|
}
|
|
|
|
void Initialize(InitializeMode init_mode)
|
|
{
|
|
if (s_config.ControllersNeedToBeCreated())
|
|
{
|
|
for (unsigned int i = WIIMOTE_CHAN_0; i < MAX_BBMOTES; ++i)
|
|
s_config.CreateController<WiimoteEmu::Wiimote>(i);
|
|
}
|
|
|
|
s_config.RegisterHotplugCallback();
|
|
|
|
LoadConfig();
|
|
|
|
WiimoteReal::Initialize(init_mode);
|
|
|
|
// Reload Wiimotes with our settings
|
|
if (Movie::IsMovieActive())
|
|
Movie::ChangeWiiPads();
|
|
}
|
|
|
|
void ResetAllWiimotes()
|
|
{
|
|
for (int i = WIIMOTE_CHAN_0; i < MAX_BBMOTES; ++i)
|
|
static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(i))->Reset();
|
|
}
|
|
|
|
void LoadConfig()
|
|
{
|
|
s_config.LoadConfig(false);
|
|
s_last_connect_request_counter.fill(0);
|
|
}
|
|
|
|
void Resume()
|
|
{
|
|
WiimoteReal::Resume();
|
|
}
|
|
|
|
void Pause()
|
|
{
|
|
WiimoteReal::Pause();
|
|
}
|
|
|
|
void DoState(PointerWrap& p)
|
|
{
|
|
for (int i = 0; i < MAX_BBMOTES; ++i)
|
|
{
|
|
const WiimoteSource source = WiimoteCommon::GetSource(i);
|
|
auto state_wiimote_source = u8(source);
|
|
p.Do(state_wiimote_source);
|
|
|
|
if (WiimoteSource(state_wiimote_source) == WiimoteSource::Emulated)
|
|
{
|
|
// Sync complete state of emulated wiimotes.
|
|
static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(i))->DoState(p);
|
|
}
|
|
|
|
if (p.GetMode() == PointerWrap::MODE_READ)
|
|
{
|
|
// If using a real wiimote or the save-state source does not match the current source,
|
|
// then force a reconnection on load.
|
|
if (source == WiimoteSource::Real || source != WiimoteSource(state_wiimote_source))
|
|
WiimoteCommon::UpdateSource(i);
|
|
}
|
|
}
|
|
}
|
|
} // namespace Wiimote
|