diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 536acd73f7..4824bc8b7e 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -247,7 +247,8 @@ set(LIBS if(LIBUSB_FOUND) # Using shared LibUSB set(LIBS ${LIBS} ${LIBUSB_LIBRARIES}) - set(SRCS ${SRCS} IPC_HLE/WII_IPC_HLE_Device_hid.cpp) + set(SRCS ${SRCS} IPC_HLE/WII_IPC_HLE_Device_hid.cpp + HW/SI_GCAdapter.cpp) endif(LIBUSB_FOUND) set(LIBS ${LIBS} ${POLARSSL_LIBRARY}) diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index 0305746cf4..7afb655a44 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -341,6 +341,7 @@ void SConfig::SaveCoreSettings(IniFile& ini) core->Set("FrameSkip", m_FrameSkip); core->Set("GFXBackend", m_LocalCoreStartupParameter.m_strVideoBackend); core->Set("GPUDeterminismMode", m_LocalCoreStartupParameter.m_strGPUDeterminismMode); + core->Set("GameCubeAdapter", m_GameCubeAdapter); } void SConfig::SaveMovieSettings(IniFile& ini) @@ -574,6 +575,7 @@ void SConfig::LoadCoreSettings(IniFile& ini) core->Get("FrameSkip", &m_FrameSkip, 0); core->Get("GFXBackend", &m_LocalCoreStartupParameter.m_strVideoBackend, ""); core->Get("GPUDeterminismMode", &m_LocalCoreStartupParameter.m_strGPUDeterminismMode, "auto"); + core->Get("GameCubeAdapter", &m_GameCubeAdapter, true); } void SConfig::LoadMovieSettings(IniFile& ini) diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h index 7c14d9dfb8..badf3fe04b 100644 --- a/Source/Core/Core/ConfigManager.h +++ b/Source/Core/Core/ConfigManager.h @@ -107,6 +107,7 @@ struct SConfig : NonCopyable // Input settings bool m_BackgroundInput; + bool m_GameCubeAdapter; SysConf* m_SYSCONF; diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index 611658f65f..ae775bcc5a 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -147,6 +147,13 @@ + + + 4200;%(DisableSpecificWarnings) + @@ -176,7 +183,7 @@ 4200;%(DisableSpecificWarnings) @@ -345,6 +352,7 @@ + diff --git a/Source/Core/Core/HW/SI.cpp b/Source/Core/Core/HW/SI.cpp index 0f6b14917c..736853b06b 100644 --- a/Source/Core/Core/HW/SI.cpp +++ b/Source/Core/Core/HW/SI.cpp @@ -15,6 +15,9 @@ #include "Core/HW/ProcessorInterface.h" #include "Core/HW/SI.h" #include "Core/HW/SI_DeviceGBA.h" +#if defined(__LIBUSB__) || defined (_WIN32) +#include "Core/HW/SI_GCAdapter.h" +#endif #include "Core/HW/SystemTimers.h" #include "Core/HW/VideoInterface.h" @@ -56,56 +59,6 @@ enum SI_EXI_CLOCK_COUNT = 0x3C, }; -// SI Channel Output -union USIChannelOut -{ - u32 Hex; - struct - { - u32 OUTPUT1 : 8; - u32 OUTPUT0 : 8; - u32 CMD : 8; - u32 : 8; - }; -}; - -// SI Channel Input High u32 -union USIChannelIn_Hi -{ - u32 Hex; - struct - { - u32 INPUT3 : 8; - u32 INPUT2 : 8; - u32 INPUT1 : 8; - u32 INPUT0 : 6; - u32 ERRLATCH : 1; // 0: no error 1: Error latched. Check SISR. - u32 ERRSTAT : 1; // 0: no error 1: error on last transfer - }; -}; - -// SI Channel Input Low u32 -union USIChannelIn_Lo -{ - u32 Hex; - struct - { - u32 INPUT7 : 8; - u32 INPUT6 : 8; - u32 INPUT5 : 8; - u32 INPUT4 : 8; - }; -}; - -// SI Channel -struct SSIChannel -{ - USIChannelOut m_Out; - USIChannelIn_Hi m_InHi; - USIChannelIn_Lo m_InLo; - ISIDevice* m_pDevice; -}; - // SI Poll: Controls how often a device is polled union USIPoll { @@ -384,7 +337,9 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) g_Channel[1].m_pDevice->SendCommand(g_Channel[1].m_Out.Hex, g_Poll.EN1); g_Channel[2].m_pDevice->SendCommand(g_Channel[2].m_Out.Hex, g_Poll.EN2); g_Channel[3].m_pDevice->SendCommand(g_Channel[3].m_Out.Hex, g_Poll.EN3); - +#if defined(__LIBUSB__) || defined (_WIN32) + SI_GCAdapter::Output(g_Channel); +#endif g_StatusReg.WR = 0; g_StatusReg.WRST0 = 0; g_StatusReg.WRST1 = 0; @@ -473,22 +428,30 @@ static void SetNoResponse(u32 channel) void ChangeDeviceCallback(u64 userdata, int cyclesLate) { u8 channel = (u8)(userdata >> 32); + SIDevices device = (SIDevices)(u32)userdata; - g_Channel[channel].m_Out.Hex = 0; - g_Channel[channel].m_InHi.Hex = 0; - g_Channel[channel].m_InLo.Hex = 0; + // Skip redundant (spammed) device changes + if (GetDeviceType(channel) != device) + { + g_Channel[channel].m_Out.Hex = 0; + g_Channel[channel].m_InHi.Hex = 0; + g_Channel[channel].m_InLo.Hex = 0; - SetNoResponse(channel); + SetNoResponse(channel); - AddDevice((SIDevices)(u32)userdata, channel); + AddDevice(device, channel); + } } void ChangeDevice(SIDevices device, int channel) { // Called from GUI, so we need to make it thread safe. // Let the hardware see no device for .5b cycles - CoreTiming::ScheduleEvent_Threadsafe(0, changeDevice, ((u64)channel << 32) | SIDEVICE_NONE); - CoreTiming::ScheduleEvent_Threadsafe(500000000, changeDevice, ((u64)channel << 32) | device); + if (GetDeviceType(channel) != device) + { + CoreTiming::ScheduleEvent_Threadsafe(0, changeDevice, ((u64)channel << 32) | SIDEVICE_NONE); + CoreTiming::ScheduleEvent_Threadsafe(500000000, changeDevice, ((u64)channel << 32) | device); + } } void UpdateDevices() @@ -499,6 +462,29 @@ void UpdateDevices() g_StatusReg.RDST2 = !!g_Channel[2].m_pDevice->GetData(g_Channel[2].m_InHi.Hex, g_Channel[2].m_InLo.Hex); g_StatusReg.RDST3 = !!g_Channel[3].m_pDevice->GetData(g_Channel[3].m_InHi.Hex, g_Channel[3].m_InLo.Hex); + // Check for connected GC Adapter +#if defined(__LIBUSB__) || defined (_WIN32) + if (SConfig::GetInstance().m_GameCubeAdapter) + { + g_StatusReg.RDST0 |= (SI_GCAdapter::GetDeviceType(0) != SIDEVICE_NONE); + g_StatusReg.RDST1 |= (SI_GCAdapter::GetDeviceType(1) != SIDEVICE_NONE); + g_StatusReg.RDST2 |= (SI_GCAdapter::GetDeviceType(2) != SIDEVICE_NONE); + g_StatusReg.RDST3 |= (SI_GCAdapter::GetDeviceType(3) != SIDEVICE_NONE); + + for (int chan = 0; chan < MAX_SI_CHANNELS; chan++) + { + SIDevices connected_device = SI_GCAdapter::GetDeviceType(chan); + SIDevices configured_device = SConfig::GetInstance().m_SIDevice[chan]; + + if (connected_device != SIDEVICE_NONE) + ChangeDevice(connected_device, chan); + else + ChangeDevice(configured_device, chan); + } + + SI_GCAdapter::Input(g_Channel); + } +#endif UpdateInterrupts(); } diff --git a/Source/Core/Core/HW/SI.h b/Source/Core/Core/HW/SI.h index 2e06b269a1..2f22996e6e 100644 --- a/Source/Core/Core/HW/SI.h +++ b/Source/Core/Core/HW/SI.h @@ -20,6 +20,56 @@ enum namespace SerialInterface { +// SI Channel Output +union USIChannelOut +{ + u32 Hex; + struct + { + u32 OUTPUT1 : 8; + u32 OUTPUT0 : 8; + u32 CMD : 8; + u32 : 8; + }; +}; + +// SI Channel Input High u32 +union USIChannelIn_Hi +{ + u32 Hex; + struct + { + u32 INPUT3 : 8; + u32 INPUT2 : 8; + u32 INPUT1 : 8; + u32 INPUT0 : 6; + u32 ERRLATCH : 1; // 0: no error 1: Error latched. Check SISR. + u32 ERRSTAT : 1; // 0: no error 1: error on last transfer + }; +}; + +// SI Channel Input Low u32 +union USIChannelIn_Lo +{ + u32 Hex; + struct + { + u32 INPUT7 : 8; + u32 INPUT6 : 8; + u32 INPUT5 : 8; + u32 INPUT4 : 8; + }; +}; + +// SI Channel +struct SSIChannel +{ + USIChannelOut m_Out; + USIChannelIn_Hi m_InHi; + USIChannelIn_Lo m_InLo; + ISIDevice* m_pDevice; +}; + void Init(); void Shutdown(); void DoState(PointerWrap &p); diff --git a/Source/Core/Core/HW/SI_GCAdapter.cpp b/Source/Core/Core/HW/SI_GCAdapter.cpp new file mode 100644 index 0000000000..dad95b3eb2 --- /dev/null +++ b/Source/Core/Core/HW/SI_GCAdapter.cpp @@ -0,0 +1,284 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include + +#include "Core/ConfigManager.h" +#include "Core/HW/SI_GCAdapter.h" +#include "InputCommon/GCPadStatus.h" + +static const u8 ENDPOINT_IN = 0x81; +static const u8 ENDPOINT_OUT = 0x02; + +namespace SI_GCAdapter +{ + +static libusb_device_handle* handle = nullptr; +static bool controller_connected[MAX_SI_CHANNELS] = { false, false, false, false }; +static u8 controller_payload[37]; +static u8 controller_last_rumble[4]; +static int controller_payload_size = 0; + +static std::thread adapter_thread; +static bool adapter_thread_running; + +static bool libusb_driver_not_supported = false; + +void Read() +{ + while (adapter_thread_running) + { + libusb_interrupt_transfer(handle, ENDPOINT_IN, controller_payload, sizeof(controller_payload), &controller_payload_size, 0); + Common::YieldCPU(); + } +} + +void Init() +{ + if (handle != nullptr) + return; + + libusb_driver_not_supported = false; + + for (int i = 0; i < MAX_SI_CHANNELS; i++) + { + controller_connected[i] = false; + controller_last_rumble[i] = 0; + } + + int ret = libusb_init(nullptr); + + if (ret) + { + ERROR_LOG(SERIALINTERFACE, "libusb_init failed with error: %d", ret); + Shutdown(); + } + else + { + libusb_device** list; + ssize_t cnt = libusb_get_device_list(nullptr, &list); + for (int d = 0; d < cnt; d++) + { + libusb_device* device = list[d]; + libusb_device_descriptor desc; + int dRet = libusb_get_device_descriptor(device, &desc); + if (dRet) + { + // could not aquire the descriptor, no point in trying to use it. + ERROR_LOG(SERIALINTERFACE, "libusb_get_device_descriptor failed with error: %d", dRet); + continue; + } + + if (desc.idVendor == 0x057e && desc.idProduct == 0x0337) + { + NOTICE_LOG(SERIALINTERFACE, "Found GC Adapter with Vendor: %X Product: %X Devnum: %d", desc.idVendor, desc.idProduct, 1); + + u8 bus = libusb_get_bus_number(device); + u8 port = libusb_get_device_address(device); + ret = libusb_open(device, &handle); + if (ret) + { + if (ret == LIBUSB_ERROR_ACCESS) + { + if (dRet) + { + ERROR_LOG(SERIALINTERFACE, "Dolphin does not have access to this device: Bus %03d Device %03d: ID ????:???? (couldn't get id).", + bus, + port + ); + } + else + { + ERROR_LOG(SERIALINTERFACE, "Dolphin does not have access to this device: Bus %03d Device %03d: ID %04X:%04X.", + bus, + port, + desc.idVendor, + desc.idProduct + ); + } + } + else + { + ERROR_LOG(SERIALINTERFACE, "libusb_open failed to open device with error = %d", ret); + if (ret == LIBUSB_ERROR_NOT_SUPPORTED) + libusb_driver_not_supported = true; + } + Shutdown(); + } + else if ((ret = libusb_kernel_driver_active(handle, 0)) == 1) + { + if ((ret = libusb_detach_kernel_driver(handle, 0)) && ret != LIBUSB_ERROR_NOT_SUPPORTED) + { + ERROR_LOG(SERIALINTERFACE, "libusb_detach_kernel_driver failed with error: %d", ret); + Shutdown(); + } + } + else if (ret != 0 && ret != LIBUSB_ERROR_NOT_SUPPORTED) + { + ERROR_LOG(SERIALINTERFACE, "libusb_kernel_driver_active error ret = %d", ret); + Shutdown(); + } + else if ((ret = libusb_claim_interface(handle, 0))) + { + ERROR_LOG(SERIALINTERFACE, "libusb_claim_interface failed with error: %d", ret); + Shutdown(); + } + else + { + int tmp = 0; + unsigned char payload = 0x13; + libusb_interrupt_transfer(handle, ENDPOINT_OUT, &payload, sizeof(payload), &tmp, 0); + + RefreshConnectedDevices(); + + adapter_thread_running = true; + adapter_thread = std::thread(Read); + } + } + } + + libusb_free_device_list(list, 1); + } +} + +void Shutdown() +{ + if (handle == nullptr || !SConfig::GetInstance().m_GameCubeAdapter) + return; + + if (adapter_thread_running) + { + adapter_thread_running = false; + adapter_thread.join(); + } + + libusb_close(handle); + libusb_driver_not_supported = false; + + for (int i = 0; i < MAX_SI_CHANNELS; i++) + controller_connected[i] = false; + + handle = nullptr; +} + +void Input(SerialInterface::SSIChannel* g_Channel) +{ + if (handle == nullptr || !SConfig::GetInstance().m_GameCubeAdapter) + return; + + if (controller_payload_size != 0x25 || controller_payload[0] != 0x21) + { + ERROR_LOG(SERIALINTERFACE, "error reading payload (size: %d)", controller_payload_size); + Shutdown(); + } + else + { + for (int chan = 0; chan < MAX_SI_CHANNELS; chan++) + { + bool connected = (controller_payload[1 + (9 * chan)] > 0); + if (connected && !controller_connected[chan]) + NOTICE_LOG(SERIALINTERFACE, "New device connected to Port %d of Type: %02x", chan + 1, controller_payload[1 + (9 * chan)]); + + controller_connected[chan] = connected; + + if (controller_connected[chan]) + { + g_Channel[chan].m_InHi.Hex = 0; + g_Channel[chan].m_InLo.Hex = 0; + for (int j = 0; j < 4; j++) + { + g_Channel[chan].m_InHi.Hex |= (controller_payload[2 + chan + j + (8 * chan) + 0] << (8 * (3 - j))); + g_Channel[chan].m_InLo.Hex |= (controller_payload[2 + chan + j + (8 * chan) + 4] << (8 * (3 - j))); + } + + u8 buttons_0 = ((g_Channel[chan].m_InHi.Hex >> 24) & 0xf0) >> 4; + u8 buttons_1 = (g_Channel[chan].m_InHi.Hex >> 24) & 0x0f; + u8 buttons_2 = ((g_Channel[chan].m_InHi.Hex >> 16) & 0xf0) >> 4; + u8 buttons_3 = (g_Channel[chan].m_InHi.Hex >> 16) & 0x0f; + g_Channel[chan].m_InHi.Hex = buttons_3 << 28 | buttons_1 << 24 | (buttons_2) << 20 | buttons_0 << 16 | (g_Channel[chan].m_InHi.Hex & 0x0000ffff); + + if (controller_payload[1 + (9 * chan)] == 0x10) + g_Channel[chan].m_InHi.Hex |= (PAD_USE_ORIGIN << 16); + } + } + } +} + +void Output(SerialInterface::SSIChannel* g_Channel) +{ + if (handle == nullptr || !SConfig::GetInstance().m_GameCubeAdapter) + return; + + bool rumble_update = false; + for (int chan = 0; chan < MAX_SI_CHANNELS; chan++) + { + u8 current_rumble = g_Channel[chan].m_Out.Hex & 0xff; + if (current_rumble != controller_last_rumble[chan]) + rumble_update = true; + + controller_last_rumble[chan] = current_rumble; + } + + if (rumble_update) + { + unsigned char rumble[5] = { 0x11, static_cast(g_Channel[0].m_Out.Hex & 0xff), static_cast(g_Channel[1].m_Out.Hex & 0xff), static_cast(g_Channel[2].m_Out.Hex & 0xff), static_cast(g_Channel[3].m_Out.Hex & 0xff) }; + int size = 0; + libusb_interrupt_transfer(handle, ENDPOINT_OUT, rumble, sizeof(rumble), &size, 0); + + if (size != 0x05) + { + WARN_LOG(SERIALINTERFACE, "error reading rumble (size: %d)", size); + Shutdown(); + } + } +} + +SIDevices GetDeviceType(int channel) +{ + if (handle == nullptr || !SConfig::GetInstance().m_GameCubeAdapter) + return SIDEVICE_NONE; + + if (controller_connected[channel]) + return SIDEVICE_GC_CONTROLLER; + else + return SIDEVICE_NONE; +} + +void RefreshConnectedDevices() +{ + if (handle == nullptr || !SConfig::GetInstance().m_GameCubeAdapter) + return; + + int size = 0; + libusb_interrupt_transfer(handle, ENDPOINT_IN, controller_payload, sizeof(controller_payload), &size, 0); + + if (size != 0x25 || controller_payload[0] != 0x21) + { + WARN_LOG(SERIALINTERFACE, "error reading payload (size: %d)", size); + Shutdown(); + } + else + { + for (int chan = 0; chan < MAX_SI_CHANNELS; chan++) + { + bool connected = (controller_payload[1 + (9 * chan)] > 0); + if (connected && !controller_connected[chan]) + NOTICE_LOG(SERIALINTERFACE, "New device connected to Port %d of Type: %02x", chan + 1, controller_payload[1 + (9 * chan)]); + + controller_connected[chan] = connected; + } + } +} + +bool IsDetected() +{ + return handle != nullptr; +} + +bool IsDriverDetected() +{ + return !libusb_driver_not_supported; +} + +} // end of namespace SI_GCAdapter diff --git a/Source/Core/Core/HW/SI_GCAdapter.h b/Source/Core/Core/HW/SI_GCAdapter.h new file mode 100644 index 0000000000..5095d3fbe8 --- /dev/null +++ b/Source/Core/Core/HW/SI_GCAdapter.h @@ -0,0 +1,29 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "Common/Thread.h" +#include "Core/HW/SI.h" + +struct libusb_device_handle; +struct libusb_device_descriptor; +struct libusb_config_descriptor; +struct libusb_interface_descriptor; +struct libusb_endpoint_descriptor; +struct libusb_transfer; + +namespace SI_GCAdapter +{ + +void Init(); +void Shutdown(); +void Input(SerialInterface::SSIChannel* g_Channel); +void Output(SerialInterface::SSIChannel* g_Channel); +SIDevices GetDeviceType(int channel); +void RefreshConnectedDevices(); +bool IsDetected(); +bool IsDriverDetected(); + +} // end of namespace SI_GCAdapter diff --git a/Source/Core/DolphinWX/ControllerConfigDiag.cpp b/Source/Core/DolphinWX/ControllerConfigDiag.cpp index da7cc6145a..9e3607b438 100644 --- a/Source/Core/DolphinWX/ControllerConfigDiag.cpp +++ b/Source/Core/DolphinWX/ControllerConfigDiag.cpp @@ -27,6 +27,9 @@ #include "Core/NetPlayProto.h" #include "Core/HW/GCPad.h" #include "Core/HW/SI.h" +#if defined(__LIBUSB__) || defined (_WIN32) +#include "Core/HW/SI_GCAdapter.h" +#endif #include "Core/HW/Wiimote.h" #include "Core/HW/WiimoteReal/WiimoteReal.h" #include "DolphinWX/ControllerConfigDiag.h" @@ -68,7 +71,7 @@ ControllerConfigDiag::ControllerConfigDiag(wxWindow* const parent) wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer() { - wxStaticBoxSizer* const gamecube_static_sizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("GameCube Controllers")); + 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]; @@ -101,8 +104,22 @@ wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer() if (NetPlay::IsNetPlayRunning() || Movie::IsMovieActive()) pad_type_choices[i]->Disable(); + SIDevices selected_device = SConfig::GetInstance().m_SIDevice[i]; + +#if defined(__LIBUSB__) || defined (_WIN32) + if (Core::GetState() != Core::CORE_UNINITIALIZED) + { + SI_GCAdapter::RefreshConnectedDevices(); + if (SI_GCAdapter::GetDeviceType(i) != SIDEVICE_NONE) + { + pad_type_choices[i]->Disable(); + selected_device = SI_GCAdapter::GetDeviceType(i); + } + } +#endif + // Set the saved pad type as the default choice. - switch (SConfig::GetInstance().m_SIDevice[i]) + switch (selected_device) { case SIDEVICE_GC_CONTROLLER: pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[1]); @@ -134,6 +151,36 @@ wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer() } gamecube_static_sizer->Add(gamecube_flex_sizer, 1, wxEXPAND, 5); + gamecube_static_sizer->AddSpacer(5); + + wxStaticBoxSizer* const gamecube_adapter_group = new wxStaticBoxSizer(wxHORIZONTAL, this, _("GameCube Adapter")); + wxBoxSizer* const gamecube_adapter_sizer = new wxBoxSizer(wxHORIZONTAL); + + wxCheckBox* const gamecube_adapter = new wxCheckBox(this, wxID_ANY, _("Direct Connect")); + gamecube_adapter->Bind(wxEVT_CHECKBOX, &ControllerConfigDiag::OnGameCubeAdapter, this); + + gamecube_adapter_sizer->Add(gamecube_adapter, 0, wxEXPAND); + gamecube_adapter_group->Add(gamecube_adapter_sizer, 0, wxEXPAND); + gamecube_static_sizer->Add(gamecube_adapter_group, 0, wxEXPAND); + +#if defined(__LIBUSB__) || defined (_WIN32) + if (!SI_GCAdapter::IsDetected()) + { + if (!SI_GCAdapter::IsDriverDetected()) + gamecube_adapter->SetLabelText(_("Driver Not Detected")); + else + gamecube_adapter->SetLabelText(_("Adapter Not Detected")); + gamecube_adapter->SetValue(false); + gamecube_adapter->Disable(); + } + else + { + gamecube_adapter->SetValue(SConfig::GetInstance().m_GameCubeAdapter); + if (Core::GetState() != Core::CORE_UNINITIALIZED) + gamecube_adapter->Disable(); + } +#endif + return gamecube_static_sizer; } diff --git a/Source/Core/DolphinWX/ControllerConfigDiag.h b/Source/Core/DolphinWX/ControllerConfigDiag.h index 3fbc56fb76..1c5df13f4f 100644 --- a/Source/Core/DolphinWX/ControllerConfigDiag.h +++ b/Source/Core/DolphinWX/ControllerConfigDiag.h @@ -59,6 +59,11 @@ public: SConfig::GetInstance().m_WiimoteEnableSpeaker = event.IsChecked(); event.Skip(); } + void OnGameCubeAdapter(wxCommandEvent& event) + { + SConfig::GetInstance().m_GameCubeAdapter = event.IsChecked(); + event.Skip(); + } private: wxStaticBoxSizer* CreateGamecubeSizer(); diff --git a/Source/Core/UICommon/UICommon.cpp b/Source/Core/UICommon/UICommon.cpp index f54b1a9c76..8e260f582d 100644 --- a/Source/Core/UICommon/UICommon.cpp +++ b/Source/Core/UICommon/UICommon.cpp @@ -7,6 +7,9 @@ #include "Common/Logging/LogManager.h" #include "Core/ConfigManager.h" +#if defined(__LIBUSB__) || defined (_WIN32) +#include "Core/HW/SI_GCAdapter.h" +#endif #include "Core/HW/Wiimote.h" #include "UICommon/UICommon.h" @@ -22,7 +25,9 @@ void Init() SConfig::Init(); VideoBackend::PopulateList(); WiimoteReal::LoadSettings(); - +#if defined(__LIBUSB__) || defined (_WIN32) + SI_GCAdapter::Init(); +#endif VideoBackend::ActivateBackend(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoBackend); SetEnableAlert(SConfig::GetInstance().m_LocalCoreStartupParameter.bUsePanicHandlers); @@ -30,6 +35,9 @@ void Init() void Shutdown() { +#if defined(__LIBUSB__) || defined (_WIN32) + SI_GCAdapter::Shutdown(); +#endif WiimoteReal::Shutdown(); VideoBackend::ClearList(); SConfig::Shutdown();