dolphin/Source/Core/DolphinWX/ControllerConfigDiag.cpp
Léo Lam 4b47997cf8 Add ability to passthrough a Bluetooth adapter
This adds the ability to passthrough a whole Bluetooth adapter and skip
the majority of the Bluetooth emulation code. We use libusb to send HCI
commands, receive HCI events and transfer ACL data directly to the
first adapter that is found or to a specific adapter (if configured to)

This is possible because the Wii's Bluetooth module is actually just
a pretty standard Bluetooth adapter…

…except for two vendor-specific commands, for which replies are faked,
and also for the sync button. This adds a hotkey that works in the
exact same way as the sync button would on a Wii: it triggers an HCI
event, which emulated software interpret as a command to perform
a BT inquiry.

This commit also changes the UI code to expose passthrough mode
and WII_IPC_HLE to be a bit more thread safe (for the device map).
2016-10-03 23:06:23 +02:00

554 lines
21 KiB
C++

// Copyright 2010 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <array>
#include <map>
#include <string>
#include <utility>
#include <wx/button.h>
#include <wx/checkbox.h>
#include <wx/choice.h>
#include <wx/dialog.h>
#include <wx/sizer.h>
#include <wx/slider.h>
#include <wx/stattext.h>
#include "Common/CommonTypes.h"
#include "Common/FileUtil.h"
#include "Common/IniFile.h"
#include "Common/SysConf.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/HW/GCKeyboard.h"
#include "Core/HW/GCPad.h"
#include "Core/HW/SI.h"
#include "Core/HW/Wiimote.h"
#include "Core/HW/WiimoteReal/WiimoteReal.h"
#include "Core/HotkeyManager.h"
#include "Core/Movie.h"
#include "Core/NetPlayProto.h"
#include "DolphinWX/Config/GCAdapterConfigDiag.h"
#include "DolphinWX/ControllerConfigDiag.h"
#include "DolphinWX/InputConfigDiag.h"
#include "InputCommon/GCAdapter.h"
#if defined(HAVE_XRANDR) && HAVE_XRANDR
#include "DolphinWX/X11Utils.h"
#endif
ControllerConfigDiag::ControllerConfigDiag(wxWindow* const parent)
: wxDialog(parent, wxID_ANY, _("Dolphin Controller Configuration"))
{
m_gc_pad_type_strs = {{_("None"), _("Standard Controller"), _("GameCube Adapter for Wii U"),
_("Steering Wheel"), _("Dance Mat"), _("DK Bongos"), _("GBA"),
_("Keyboard")}};
wxBoxSizer* const main_sizer = new wxBoxSizer(wxVERTICAL);
// Combine all UI controls into their own encompassing sizer.
wxBoxSizer* control_sizer = new wxBoxSizer(wxVERTICAL);
control_sizer->Add(CreateGamecubeSizer(), 0, wxEXPAND | wxALL, 5);
control_sizer->Add(CreateWiimoteConfigSizer(), 0, wxEXPAND | wxALL, 5);
main_sizer->Add(control_sizer, 0, wxEXPAND);
main_sizer->Add(CreateButtonSizer(wxCLOSE), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
Bind(wxEVT_CLOSE_WINDOW, &ControllerConfigDiag::OnClose, this);
Bind(wxEVT_BUTTON, &ControllerConfigDiag::OnCloseButton, this, wxID_CLOSE);
SetLayoutAdaptationMode(wxDIALOG_ADAPTATION_MODE_ENABLED);
SetSizerAndFit(main_sizer);
Center();
UpdateUI();
}
wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer()
{
wxStaticBoxSizer* const gamecube_static_sizer =
new wxStaticBoxSizer(wxVERTICAL, this, _("GameCube Controllers"));
wxFlexGridSizer* const gamecube_flex_sizer = new wxFlexGridSizer(3, 5, 5);
wxStaticText* pad_labels[4];
wxChoice* pad_type_choices[4];
for (int i = 0; i < 4; i++)
{
pad_labels[i] = new wxStaticText(this, wxID_ANY, wxString::Format(_("Port %i"), i + 1));
// Create an ID for the config button.
const wxWindowID button_id = wxWindow::NewControlId();
m_gc_port_from_config_id.emplace(button_id, i);
m_gc_port_configure_button[i] =
new wxButton(this, button_id, _("Configure"), wxDefaultPosition, wxSize(100, 25));
m_gc_port_configure_button[i]->Bind(wxEVT_BUTTON, &ControllerConfigDiag::OnGameCubeConfigButton,
this);
// Create a control ID for the choice boxes on the fly.
const wxWindowID choice_id = wxWindow::NewControlId();
m_gc_port_from_choice_id.emplace(choice_id, i);
pad_type_choices[i] = new wxChoice(this, choice_id, wxDefaultPosition, wxDefaultSize,
m_gc_pad_type_strs.size(), m_gc_pad_type_strs.data());
pad_type_choices[i]->Bind(wxEVT_CHOICE, &ControllerConfigDiag::OnGameCubePortChanged, this);
// Disable controller type selection for certain circumstances.
if (Core::g_want_determinism)
pad_type_choices[i]->Disable();
// Set the saved pad type as the default choice.
switch (SConfig::GetInstance().m_SIDevice[i])
{
case SIDEVICE_GC_CONTROLLER:
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[1]);
break;
case SIDEVICE_WIIU_ADAPTER:
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[2]);
break;
case SIDEVICE_GC_STEERING:
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[3]);
break;
case SIDEVICE_DANCEMAT:
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[4]);
break;
case SIDEVICE_GC_TARUKONGA:
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[5]);
break;
case SIDEVICE_GC_GBA:
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[6]);
m_gc_port_configure_button[i]->Disable();
break;
case SIDEVICE_GC_KEYBOARD:
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[7]);
break;
default:
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[0]);
m_gc_port_configure_button[i]->Disable();
break;
}
// Add to the sizer
gamecube_flex_sizer->Add(pad_labels[i], 0, wxALIGN_CENTER_VERTICAL);
gamecube_flex_sizer->Add(pad_type_choices[i], 0, wxALIGN_CENTER_VERTICAL);
gamecube_flex_sizer->Add(m_gc_port_configure_button[i], 1, wxEXPAND);
}
gamecube_static_sizer->Add(gamecube_flex_sizer, 1, wxEXPAND, 5);
gamecube_static_sizer->AddSpacer(5);
return gamecube_static_sizer;
}
wxStaticBoxSizer* ControllerConfigDiag::CreateWiimoteConfigSizer()
{
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
{
wxString wiimote_str = wxString::Format(_("Wiimote %i"), i + 1);
static const std::array<wxString, 4> src_choices = {
{_("None"), _("Emulated Wiimote"), _("Real Wiimote"), _("Hybrid Wiimote")}};
// reserve four ids, so that we can calculate the index from the ids later on
// Stupid wx 2.8 doesn't support reserving sequential IDs, so we need to do that more
// complicated..
int source_ctrl_id = wxWindow::NewControlId();
m_wiimote_index_from_choice_id.emplace(source_ctrl_id, i);
int config_bt_id = wxWindow::NewControlId();
m_wiimote_index_from_config_id.emplace(config_bt_id, i);
m_wiimote_labels[i] = new wxStaticText(this, wxID_ANY, wiimote_str);
m_wiimote_sources[i] = new wxChoice(this, source_ctrl_id, wxDefaultPosition, wxDefaultSize,
src_choices.size(), src_choices.data());
m_wiimote_sources[i]->Bind(wxEVT_CHOICE, &ControllerConfigDiag::OnWiimoteSourceChanged, this);
m_wiimote_configure_button[i] =
new wxButton(this, config_bt_id, _("Configure"), wxDefaultPosition, wxSize(80, 25));
m_wiimote_configure_button[i]->Bind(wxEVT_BUTTON, &ControllerConfigDiag::OnWiimoteConfigButton,
this);
// Disable controller type selection for certain circumstances.
bool wii_game_started =
SConfig::GetInstance().bWii || Core::GetState() == Core::CORE_UNINITIALIZED;
if (Core::g_want_determinism || !wii_game_started)
m_wiimote_sources[i]->Disable();
m_wiimote_sources[i]->Select(g_wiimote_sources[i]);
if (!wii_game_started ||
(g_wiimote_sources[i] != WIIMOTE_SRC_EMU && g_wiimote_sources[i] != WIIMOTE_SRC_HYBRID))
m_wiimote_configure_button[i]->Disable();
}
// "Wiimotes" layout
wxStaticBoxSizer* const wiimote_group = new wxStaticBoxSizer(wxVERTICAL, this, _("Wiimotes"));
wxBoxSizer* const wiimote_control_section = new wxBoxSizer(wxHORIZONTAL);
wxFlexGridSizer* const wiimote_sizer = new wxFlexGridSizer(3, 5, 5);
for (unsigned int i = 0; i < 4; ++i)
{
wiimote_sizer->Add(m_wiimote_labels[i], 0, wxALIGN_CENTER_VERTICAL);
wiimote_sizer->Add(m_wiimote_sources[i], 0, wxALIGN_CENTER_VERTICAL);
wiimote_sizer->Add(m_wiimote_configure_button[i]);
}
wiimote_control_section->Add(wiimote_sizer, 1, wxEXPAND, 5);
// Disable some controls when emulation is running
if (Core::GetState() != Core::CORE_UNINITIALIZED && NetPlay::IsNetPlayRunning())
{
for (int i = 0; i < 4; ++i)
{
m_wiimote_labels[i]->Disable();
m_wiimote_sources[i]->Disable();
}
}
wiimote_group->Add(wiimote_control_section, 0, wxEXPAND);
wiimote_group->AddSpacer(5);
wiimote_group->Add(CreateBalanceBoardSizer(), 0, wxEXPAND);
wiimote_group->AddSpacer(5);
wiimote_group->Add(CreateRealWiimoteSizer(), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM);
wiimote_group->AddSpacer(5);
m_general_wm_settings = CreateGeneralWiimoteSettingsSizer();
wiimote_group->Add(m_general_wm_settings, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM);
return wiimote_group;
}
wxStaticBoxSizer* ControllerConfigDiag::CreateBalanceBoardSizer()
{
m_balance_board_group = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Balance Board"));
wxFlexGridSizer* const bb_sizer = new wxFlexGridSizer(1, 5, 5);
int source_ctrl_id = wxWindow::NewControlId();
m_wiimote_index_from_choice_id.emplace(source_ctrl_id, WIIMOTE_BALANCE_BOARD);
static const std::array<wxString, 2> src_choices = {{_("None"), _("Real Balance Board")}};
wxChoice* const bb_source = new wxChoice(this, source_ctrl_id, wxDefaultPosition, wxDefaultSize,
src_choices.size(), src_choices.data());
bb_source->Bind(wxEVT_CHOICE, &ControllerConfigDiag::OnWiimoteSourceChanged, this);
bb_source->Select(g_wiimote_sources[WIIMOTE_BALANCE_BOARD] ? 1 : 0);
bb_sizer->Add(bb_source, 0, wxALIGN_CENTER_VERTICAL);
m_balance_board_group->Add(bb_sizer, 1, wxEXPAND, 5);
// Disable when emulation is running.
if (Core::GetState() != Core::CORE_UNINITIALIZED)
bb_source->Disable();
return m_balance_board_group;
}
wxStaticBoxSizer* ControllerConfigDiag::CreateRealWiimoteSizer()
{
auto* const real_wiimotes_group = new wxStaticBoxSizer(wxVERTICAL, this, _("Real Wiimotes"));
m_unsupported_bt_text =
new wxStaticText(this, wxID_ANY, _("A supported Bluetooth device could not be found.\n"
"You must manually connect your Wiimotes."));
real_wiimotes_group->Add(m_unsupported_bt_text, 0, wxALIGN_CENTER | wxALL, 5);
m_unsupported_bt_text->Show(!WiimoteReal::g_wiimote_scanner.IsReady());
// Bluetooth adapter passthrough
m_bt_passthrough_text = new wxStaticText(
this, wxID_ANY, _("A Bluetooth adapter will be passed through to the game.\n"
"Only real Wiimotes will be usable.\n"
"Wiimotes can be synced to Dolphin with the sync hotkey."));
real_wiimotes_group->Add(m_bt_passthrough_text, 0, wxALIGN_CENTER | wxALL, 5);
auto* const enable_passthrough =
new wxCheckBox(this, wxID_ANY, _("Enable Bluetooth Adapter Passthrough"));
enable_passthrough->Bind(wxEVT_CHECKBOX, &ControllerConfigDiag::OnPassthroughMode, this);
enable_passthrough->SetValue(SConfig::GetInstance().m_bt_passthrough_enabled);
auto* const wm_bt_sync_button = new wxButton(this, wxID_ANY, _("Sync Wiimotes"));
wm_bt_sync_button->Bind(wxEVT_BUTTON, &ControllerConfigDiag::OnPassthroughScanButton, this);
auto* const wm_bt_reset_button = new wxButton(this, wxID_ANY, _("Reset pairings"));
wm_bt_reset_button->Bind(wxEVT_BUTTON, &ControllerConfigDiag::OnPassthroughResetButton, this);
if (Core::GetState() != Core::CORE_UNINITIALIZED)
{
enable_passthrough->Disable();
if (!SConfig::GetInstance().bWii)
m_bt_passthrough_text->Disable();
}
if (!SConfig::GetInstance().bWii || Core::GetState() == Core::CORE_UNINITIALIZED)
{
wm_bt_sync_button->Disable();
wm_bt_reset_button->Disable();
}
m_bt_passthrough_sizer = new wxBoxSizer(wxHORIZONTAL);
m_bt_passthrough_sizer->Add(wm_bt_sync_button, 0, wxALIGN_CENTER_VERTICAL);
m_bt_passthrough_sizer->Add(wm_bt_reset_button, 0, wxALL | wxALIGN_CENTER, 5);
// Regular real Wiimotes controls
auto* const continuous_scanning = new wxCheckBox(this, wxID_ANY, _("Continuous Scanning"));
continuous_scanning->Bind(wxEVT_CHECKBOX, &ControllerConfigDiag::OnContinuousScanning, this);
continuous_scanning->SetValue(SConfig::GetInstance().m_WiimoteContinuousScanning);
auto* const wm_refresh_button = new wxButton(this, wxID_ANY, _("Refresh"));
wm_refresh_button->Bind(wxEVT_BUTTON, &ControllerConfigDiag::OnWiimoteRefreshButton, this);
m_real_wiimotes_sizer = new wxBoxSizer(wxHORIZONTAL);
m_real_wiimotes_sizer->Add(continuous_scanning, 0, wxALIGN_CENTER_VERTICAL);
m_real_wiimotes_sizer->AddStretchSpacer();
m_real_wiimotes_sizer->Add(wm_refresh_button, 0, wxALL | wxALIGN_CENTER, 5);
real_wiimotes_group->Add(enable_passthrough, 0);
real_wiimotes_group->Add(m_bt_passthrough_sizer, 0, wxEXPAND);
real_wiimotes_group->Add(m_real_wiimotes_sizer, 0, wxEXPAND);
return real_wiimotes_group;
}
wxStaticBoxSizer* ControllerConfigDiag::CreateGeneralWiimoteSettingsSizer()
{
const wxString str[] = {_("Bottom"), _("Top")};
wxChoice* const WiiSensBarPos =
new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 2, str);
wxSlider* const WiiSensBarSens = new wxSlider(this, wxID_ANY, 0, 0, 4);
wxSlider* const WiimoteSpkVolume = new wxSlider(this, wxID_ANY, 0, 0, 127);
wxCheckBox* const WiimoteMotor = new wxCheckBox(this, wxID_ANY, _("Wiimote Motor"));
m_enable_speaker_data = new wxCheckBox(this, wxID_ANY, _("Enable Speaker Data"));
m_enable_speaker_data->Bind(wxEVT_CHECKBOX, &ControllerConfigDiag::OnEnableSpeaker, this);
m_enable_speaker_data->SetValue(SConfig::GetInstance().m_WiimoteEnableSpeaker);
wxStaticText* const WiiSensBarPosText =
new wxStaticText(this, wxID_ANY, _("Sensor Bar Position:"));
wxStaticText* const WiiSensBarSensText = new wxStaticText(this, wxID_ANY, _("IR Sensitivity:"));
wxStaticText* const WiiSensBarSensMinText = new wxStaticText(this, wxID_ANY, _("Min"));
wxStaticText* const WiiSensBarSensMaxText = new wxStaticText(this, wxID_ANY, _("Max"));
wxStaticText* const WiimoteSpkVolumeText = new wxStaticText(this, wxID_ANY, _("Speaker Volume:"));
wxStaticText* const WiimoteSpkVolumeMinText = new wxStaticText(this, wxID_ANY, _("Min"));
wxStaticText* const WiimoteSpkVolumeMaxText = new wxStaticText(this, wxID_ANY, _("Max"));
// With some GTK themes, no minimum size will be applied - so do this manually here
WiiSensBarSens->SetMinSize(wxSize(100, -1));
WiimoteSpkVolume->SetMinSize(wxSize(100, -1));
// Disable some controls when emulation is running
if (Core::GetState() != Core::CORE_UNINITIALIZED)
{
WiiSensBarPos->Disable();
WiiSensBarSens->Disable();
WiimoteSpkVolume->Disable();
WiimoteMotor->Disable();
WiiSensBarPosText->Disable();
WiiSensBarSensText->Disable();
WiiSensBarSensMinText->Disable();
WiiSensBarSensMaxText->Disable();
WiimoteSpkVolumeText->Disable();
WiimoteSpkVolumeMinText->Disable();
WiimoteSpkVolumeMaxText->Disable();
}
// "General Settings" initialization
WiiSensBarPos->SetSelection(SConfig::GetInstance().m_SYSCONF->GetData<u8>("BT.BAR"));
WiiSensBarSens->SetValue(SConfig::GetInstance().m_SYSCONF->GetData<u32>("BT.SENS"));
WiimoteSpkVolume->SetValue(SConfig::GetInstance().m_SYSCONF->GetData<u8>("BT.SPKV"));
WiimoteMotor->SetValue(SConfig::GetInstance().m_SYSCONF->GetData<bool>("BT.MOT"));
WiiSensBarPos->Bind(wxEVT_CHOICE, &ControllerConfigDiag::OnSensorBarPos, this);
WiiSensBarSens->Bind(wxEVT_SLIDER, &ControllerConfigDiag::OnSensorBarSensitivity, this);
WiimoteSpkVolume->Bind(wxEVT_SLIDER, &ControllerConfigDiag::OnSpeakerVolume, this);
WiimoteMotor->Bind(wxEVT_CHECKBOX, &ControllerConfigDiag::OnMotor, this);
// "General Settings" layout
wxStaticBoxSizer* const general_sizer =
new wxStaticBoxSizer(wxVERTICAL, this, _("General Settings"));
wxFlexGridSizer* const choice_sizer = new wxFlexGridSizer(2, 5, 5);
wxBoxSizer* const sensbarsens_sizer = new wxBoxSizer(wxHORIZONTAL);
sensbarsens_sizer->Add(WiiSensBarSensMinText, 0, wxALIGN_CENTER_VERTICAL);
sensbarsens_sizer->Add(WiiSensBarSens);
sensbarsens_sizer->Add(WiiSensBarSensMaxText, 0, wxALIGN_CENTER_VERTICAL);
wxBoxSizer* const spkvol_sizer = new wxBoxSizer(wxHORIZONTAL);
spkvol_sizer->Add(WiimoteSpkVolumeMinText, 0, wxALIGN_CENTER_VERTICAL);
spkvol_sizer->Add(WiimoteSpkVolume);
spkvol_sizer->Add(WiimoteSpkVolumeMaxText, 0, wxALIGN_CENTER_VERTICAL);
choice_sizer->Add(WiiSensBarPosText, 0, wxALIGN_CENTER_VERTICAL);
choice_sizer->Add(WiiSensBarPos);
choice_sizer->Add(WiiSensBarSensText, 0, wxALIGN_CENTER_VERTICAL);
choice_sizer->Add(sensbarsens_sizer);
choice_sizer->Add(WiimoteSpkVolumeText, 0, wxALIGN_CENTER_VERTICAL);
choice_sizer->Add(spkvol_sizer);
wxGridSizer* const general_wiimote_sizer = new wxGridSizer(1, 5, 5);
general_wiimote_sizer->Add(WiimoteMotor);
general_wiimote_sizer->Add(m_enable_speaker_data);
general_sizer->Add(choice_sizer);
general_sizer->Add(general_wiimote_sizer);
return general_sizer;
}
void ControllerConfigDiag::OnClose(wxCloseEvent& event)
{
// Save all settings
SConfig::GetInstance().SaveSettings();
SaveWiimoteSource();
EndModal(wxID_OK);
}
void ControllerConfigDiag::OnCloseButton(wxCommandEvent& event)
{
Close();
}
void ControllerConfigDiag::OnGameCubePortChanged(wxCommandEvent& event)
{
const unsigned int device_num = m_gc_port_from_choice_id[event.GetId()];
const wxString device_name = event.GetString();
SIDevices tempType;
if (device_name == m_gc_pad_type_strs[1])
{
tempType = SIDEVICE_GC_CONTROLLER;
m_gc_port_configure_button[device_num]->Enable();
}
else if (device_name == m_gc_pad_type_strs[2])
{
tempType = SIDEVICE_WIIU_ADAPTER;
m_gc_port_configure_button[device_num]->Enable();
}
else if (device_name == m_gc_pad_type_strs[3])
{
tempType = SIDEVICE_GC_STEERING;
m_gc_port_configure_button[device_num]->Enable();
}
else if (device_name == m_gc_pad_type_strs[4])
{
tempType = SIDEVICE_DANCEMAT;
m_gc_port_configure_button[device_num]->Enable();
}
else if (device_name == m_gc_pad_type_strs[5])
{
tempType = SIDEVICE_GC_TARUKONGA;
m_gc_port_configure_button[device_num]->Enable();
}
else if (device_name == m_gc_pad_type_strs[6])
{
tempType = SIDEVICE_GC_GBA;
m_gc_port_configure_button[device_num]->Disable();
}
else if (device_name == m_gc_pad_type_strs[7])
{
tempType = SIDEVICE_GC_KEYBOARD;
m_gc_port_configure_button[device_num]->Enable();
}
else
{
tempType = SIDEVICE_NONE;
m_gc_port_configure_button[device_num]->Disable();
}
SConfig::GetInstance().m_SIDevice[device_num] = tempType;
if (GCAdapter::UseAdapter())
GCAdapter::StartScanThread();
else
GCAdapter::StopScanThread();
if (Core::IsRunning())
SerialInterface::ChangeDevice(tempType, device_num);
}
void ControllerConfigDiag::OnGameCubeConfigButton(wxCommandEvent& event)
{
InputConfig* const pad_plugin = Pad::GetConfig();
InputConfig* const key_plugin = Keyboard::GetConfig();
const int port_num = m_gc_port_from_config_id[event.GetId()];
HotkeyManagerEmu::Enable(false);
if (SConfig::GetInstance().m_SIDevice[port_num] == SIDEVICE_GC_KEYBOARD)
{
InputConfigDialog m_ConfigFrame(this, *key_plugin, _("GameCube Controller Configuration"),
port_num);
m_ConfigFrame.ShowModal();
}
else if (SConfig::GetInstance().m_SIDevice[port_num] == SIDEVICE_WIIU_ADAPTER)
{
GCAdapterConfigDiag m_ConfigFramg(this, _("Wii U Gamecube Controller Adapter Configuration"),
port_num);
m_ConfigFramg.ShowModal();
}
else
{
InputConfigDialog m_ConfigFrame(this, *pad_plugin, _("GameCube Controller Configuration"),
port_num);
m_ConfigFrame.ShowModal();
}
HotkeyManagerEmu::Enable(true);
}
void ControllerConfigDiag::OnWiimoteSourceChanged(wxCommandEvent& event)
{
// This needs to be changed now in order for refresh to work right.
// Revert if the dialog is canceled.
int index = m_wiimote_index_from_choice_id[event.GetId()];
if (index != WIIMOTE_BALANCE_BOARD)
{
WiimoteReal::ChangeWiimoteSource(index, event.GetInt());
if (g_wiimote_sources[index] != WIIMOTE_SRC_EMU &&
g_wiimote_sources[index] != WIIMOTE_SRC_HYBRID)
m_wiimote_configure_button[index]->Disable();
else
m_wiimote_configure_button[index]->Enable();
}
else
{
WiimoteReal::ChangeWiimoteSource(index, event.GetInt() ? WIIMOTE_SRC_REAL : WIIMOTE_SRC_NONE);
}
}
void ControllerConfigDiag::OnWiimoteConfigButton(wxCommandEvent& ev)
{
InputConfig* const wiimote_plugin = Wiimote::GetConfig();
HotkeyManagerEmu::Enable(false);
InputConfigDialog m_ConfigFrame(this, *wiimote_plugin,
_("Dolphin Emulated Wiimote Configuration"),
m_wiimote_index_from_config_id[ev.GetId()]);
m_ConfigFrame.ShowModal();
HotkeyManagerEmu::Enable(true);
}
void ControllerConfigDiag::OnWiimoteRefreshButton(wxCommandEvent&)
{
WiimoteReal::Refresh();
}
void ControllerConfigDiag::SaveWiimoteSource()
{
std::string ini_filename = File::GetUserPath(D_CONFIG_IDX) + WIIMOTE_INI_NAME ".ini";
IniFile inifile;
inifile.Load(ini_filename);
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
{
std::string secname("Wiimote");
secname += (char)('1' + i);
IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
sec.Set("Source", (int)g_wiimote_sources[i]);
}
std::string secname("BalanceBoard");
IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
sec.Set("Source", (int)g_wiimote_sources[WIIMOTE_BALANCE_BOARD]);
inifile.Save(ini_filename);
}