mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 13:57:57 -07:00
4b47997cf8
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).
555 lines
21 KiB
C++
555 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);
|
|
}
|