summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorRyan Houdek <Sonicadvance1@gmail.com>2016-01-06 15:07:09 -0500
committerRyan Houdek <Sonicadvance1@gmail.com>2016-01-06 15:07:09 -0500
commit342496563dc2fd129c6ab3831b181eb0875f46d0 (patch)
treecf10091da87c9c6c7ab3f5270bb96a7098d6052c /Source/Core
parent87e753b104375d0983071f144638f98bef6ef719 (diff)
parente62503c873833b33c63585c6f0810b824e5c6a6b (diff)
Merge pull request #3455 from Sonicadvance1/GC_adapter_android
[Android] Add support for the Wii U Gamecube adapter under Android.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/CMakeLists.txt4
-rw-r--r--Source/Core/Core/ConfigManager.cpp8
-rw-r--r--Source/Core/Core/ConfigManager.h4
-rw-r--r--Source/Core/Core/Core.cpp10
-rw-r--r--Source/Core/Core/Core.vcxproj10
-rw-r--r--Source/Core/Core/Core.vcxproj.filters12
-rw-r--r--Source/Core/Core/HW/SI_Device.cpp4
-rw-r--r--Source/Core/Core/HW/SI_Device.h3
-rw-r--r--Source/Core/Core/HW/SI_DeviceGCAdapter.cpp150
-rw-r--r--Source/Core/Core/HW/SI_DeviceGCAdapter.h20
-rw-r--r--Source/Core/Core/HW/SI_DeviceGCController.cpp56
-rw-r--r--Source/Core/Core/HW/SI_DeviceGCController.h20
-rw-r--r--Source/Core/DolphinWX/CMakeLists.txt1
-rw-r--r--Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp77
-rw-r--r--Source/Core/DolphinWX/Config/GCAdapterConfigDiag.h40
-rw-r--r--Source/Core/DolphinWX/ControllerConfigDiag.cpp114
-rw-r--r--Source/Core/DolphinWX/ControllerConfigDiag.h25
-rw-r--r--Source/Core/DolphinWX/DolphinWX.vcxproj4
-rw-r--r--Source/Core/DolphinWX/DolphinWX.vcxproj.filters8
-rw-r--r--Source/Core/InputCommon/CMakeLists.txt14
-rw-r--r--Source/Core/InputCommon/GCAdapter.cpp (renamed from Source/Core/Core/HW/SI_GCAdapter.cpp)63
-rw-r--r--Source/Core/InputCommon/GCAdapter.h (renamed from Source/Core/Core/HW/SI_GCAdapter.h)13
-rw-r--r--Source/Core/InputCommon/GCAdapter_Android.cpp353
-rw-r--r--Source/Core/InputCommon/GCAdapter_Null.cpp23
-rw-r--r--Source/Core/InputCommon/GCPadStatus.h2
-rw-r--r--Source/Core/InputCommon/InputCommon.vcxproj10
-rw-r--r--Source/Core/InputCommon/InputCommon.vcxproj.filters4
-rw-r--r--Source/Core/UICommon/UICommon.cpp13
28 files changed, 849 insertions, 216 deletions
diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index 10a51b4a65..b035b64859 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -113,6 +113,7 @@ set(SRCS ActionReplay.cpp
HW/SI_Device.cpp
HW/SI_DeviceDanceMat.cpp
HW/SI_DeviceGBA.cpp
+ HW/SI_DeviceGCAdapter.cpp
HW/SI_DeviceGCController.cpp
HW/SI_DeviceGCSteeringWheel.cpp
HW/SI_DeviceKeyboard.cpp
@@ -239,8 +240,7 @@ set(LIBS
if(LIBUSB_FOUND)
# Using shared LibUSB
set(LIBS ${LIBS} ${LIBUSB_LIBRARIES})
- set(SRCS ${SRCS} IPC_HLE/WII_IPC_HLE_Device_hid.cpp
- HW/SI_GCAdapter.cpp)
+ set(SRCS ${SRCS} IPC_HLE/WII_IPC_HLE_Device_hid.cpp)
endif(LIBUSB_FOUND)
set(LIBS ${LIBS} ${MBEDTLS_LIBRARIES})
diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp
index c4a857b82d..20c62d8f8f 100644
--- a/Source/Core/Core/ConfigManager.cpp
+++ b/Source/Core/Core/ConfigManager.cpp
@@ -254,6 +254,8 @@ void SConfig::SaveCoreSettings(IniFile& ini)
for (int i = 0; i < MAX_SI_CHANNELS; ++i)
{
core->Set(StringFromFormat("SIDevice%i", i), m_SIDevice[i]);
+ core->Set(StringFromFormat("AdapterRumble%i", i), m_AdapterRumble[i]);
+ core->Set(StringFromFormat("SimulateKonga%i", i), m_AdapterKonga[i]);
}
core->Set("WiiSDCard", m_WiiSDCard);
core->Set("WiiKeyboard", m_WiiKeyboard);
@@ -267,8 +269,6 @@ void SConfig::SaveCoreSettings(IniFile& ini)
core->Set("OverclockEnable", m_OCEnable);
core->Set("GFXBackend", m_strVideoBackend);
core->Set("GPUDeterminismMode", m_strGPUDeterminismMode);
- core->Set("GameCubeAdapter", m_GameCubeAdapter);
- core->Set("AdapterRumble", m_AdapterRumble);
core->Set("PerfMapDir", m_perfDir);
}
@@ -509,6 +509,8 @@ void SConfig::LoadCoreSettings(IniFile& ini)
for (int i = 0; i < MAX_SI_CHANNELS; ++i)
{
core->Get(StringFromFormat("SIDevice%i", i), (u32*)&m_SIDevice[i], (i == 0) ? SIDEVICE_GC_CONTROLLER : SIDEVICE_NONE);
+ core->Get(StringFromFormat("AdapterRumble%i", i), &m_AdapterRumble[i], true);
+ core->Get(StringFromFormat("SimulateKonga%i", i), &m_AdapterKonga[i], false);
}
core->Get("WiiSDCard", &m_WiiSDCard, false);
core->Get("WiiKeyboard", &m_WiiKeyboard, false);
@@ -532,8 +534,6 @@ void SConfig::LoadCoreSettings(IniFile& ini)
core->Get("FrameSkip", &m_FrameSkip, 0);
core->Get("GFXBackend", &m_strVideoBackend, "");
core->Get("GPUDeterminismMode", &m_strGPUDeterminismMode, "auto");
- core->Get("GameCubeAdapter", &m_GameCubeAdapter, false);
- core->Get("AdapterRumble", &m_AdapterRumble, true);
core->Get("PerfMapDir", &m_perfDir, "");
}
diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h
index 973f49939a..6971f5de79 100644
--- a/Source/Core/Core/ConfigManager.h
+++ b/Source/Core/Core/ConfigManager.h
@@ -264,8 +264,8 @@ struct SConfig : NonCopyable
// Input settings
bool m_BackgroundInput;
- bool m_GameCubeAdapter;
- bool m_AdapterRumble;
+ bool m_AdapterRumble[4];
+ bool m_AdapterKonga[4];
SysConf* m_SYSCONF;
diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp
index b6669b57d2..b818c5c5b1 100644
--- a/Source/Core/Core/Core.cpp
+++ b/Source/Core/Core/Core.cpp
@@ -48,9 +48,6 @@
#include "Core/HW/HW.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/ProcessorInterface.h"
-#if defined(__LIBUSB__) || defined(_WIN32)
-#include "Core/HW/SI_GCAdapter.h"
-#endif
#include "Core/HW/SystemTimers.h"
#include "Core/HW/VideoInterface.h"
#include "Core/HW/Wiimote.h"
@@ -65,6 +62,7 @@
#endif
#include "DiscIO/FileMonitor.h"
+#include "InputCommon/GCAdapter.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
#include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/VideoBackendBase.h"
@@ -285,7 +283,7 @@ void Stop() // - Hammertime!
g_video_backend->Video_ExitLoop();
}
#if defined(__LIBUSB__) || defined(_WIN32)
- SI_GCAdapter::ResetRumble();
+ GCAdapter::ResetRumble();
#endif
#ifdef USE_MEMORYWATCHER
@@ -630,7 +628,7 @@ void SetState(EState _State)
CPU::EnableStepping(true); // Break
Wiimote::Pause();
#if defined(__LIBUSB__) || defined(_WIN32)
- SI_GCAdapter::ResetRumble();
+ GCAdapter::ResetRumble();
#endif
break;
case CORE_RUN:
@@ -741,7 +739,7 @@ bool PauseAndLock(bool doLock, bool unpauseOnUnlock)
g_video_backend->PauseAndLock(doLock, unpauseOnUnlock);
#if defined(__LIBUSB__) || defined(_WIN32)
- SI_GCAdapter::ResetRumble();
+ GCAdapter::ResetRumble();
#endif
return wasUnpaused;
}
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index 05af583ed2..490e724006 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -145,16 +145,10 @@
<ClCompile Include="HW\SI_DeviceAMBaseboard.cpp" />
<ClCompile Include="HW\SI_DeviceDanceMat.cpp" />
<ClCompile Include="HW\SI_DeviceGBA.cpp" />
+ <ClCompile Include="HW\SI_DeviceGCAdapter.cpp" />
<ClCompile Include="HW\SI_DeviceGCController.cpp" />
<ClCompile Include="HW\SI_DeviceGCSteeringWheel.cpp" />
<ClCompile Include="HW\SI_DeviceKeyboard.cpp" />
- <ClCompile Include="HW\SI_GCAdapter.cpp">
- <!--
- Disable "nonstandard extension used : zero-sized array in struct/union" warning,
- which is hit in libusb.h.
- -->
- <DisableSpecificWarnings>4200;%(DisableSpecificWarnings)</DisableSpecificWarnings>
- </ClCompile>
<ClCompile Include="HW\Sram.cpp" />
<ClCompile Include="HW\StreamADPCM.cpp" />
<ClCompile Include="HW\SystemTimers.cpp" />
@@ -357,10 +351,10 @@
<ClInclude Include="HW\SI_DeviceAMBaseboard.h" />
<ClInclude Include="HW\SI_DeviceDanceMat.h" />
<ClInclude Include="HW\SI_DeviceGBA.h" />
+ <ClInclude Include="HW\SI_DeviceGCAdapter.h" />
<ClInclude Include="HW\SI_DeviceGCController.h" />
<ClInclude Include="HW\SI_DeviceGCSteeringWheel.h" />
<ClInclude Include="HW\SI_DeviceKeyboard.h" />
- <ClInclude Include="HW\SI_GCAdapter.h" />
<ClInclude Include="HW\Sram.h" />
<ClInclude Include="HW\StreamADPCM.h" />
<ClInclude Include="HW\SystemTimers.h" />
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index a374defc07..1a3df6a407 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -447,6 +447,9 @@
<ClCompile Include="HW\SI_DeviceGBA.cpp">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClCompile>
+ <ClCompile Include="HW\SI_DeviceGCAdapter.cpp">
+ <Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
+ </ClCompile>
<ClCompile Include="HW\SI_DeviceGCController.cpp">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClCompile>
@@ -720,9 +723,6 @@
<ClCompile Include="PowerPC\MMU.cpp">
<Filter>PowerPC</Filter>
</ClCompile>
- <ClCompile Include="HW\SI_GCAdapter.cpp">
- <Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
- </ClCompile>
<ClCompile Include="PowerPC\JitCommon\JitBackpatch.cpp">
<Filter>PowerPC\JitCommon</Filter>
</ClCompile>
@@ -991,6 +991,9 @@
<ClInclude Include="HW\SI_DeviceGBA.h">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClInclude>
+ <ClInclude Include="HW\SI_DeviceGCAdapter.h">
+ <Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
+ </ClInclude>
<ClInclude Include="HW\SI_DeviceGCController.h">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClInclude>
@@ -1241,9 +1244,6 @@
<ClInclude Include="HW\GCKeyboard.h">
<Filter>HW %28Flipper/Hollywood%29\GCKeyboard</Filter>
</ClInclude>
- <ClInclude Include="HW\SI_GCAdapter.h">
- <Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
- </ClInclude>
<ClInclude Include="PowerPC\Jit64Common\Jit64AsmCommon.h">
<Filter>PowerPC\Jit64Common</Filter>
</ClInclude>
diff --git a/Source/Core/Core/HW/SI_Device.cpp b/Source/Core/Core/HW/SI_Device.cpp
index 9546cba42f..fb9b9ec638 100644
--- a/Source/Core/Core/HW/SI_Device.cpp
+++ b/Source/Core/Core/HW/SI_Device.cpp
@@ -11,6 +11,7 @@
#include "Core/HW/SI_DeviceAMBaseboard.h"
#include "Core/HW/SI_DeviceDanceMat.h"
#include "Core/HW/SI_DeviceGBA.h"
+#include "Core/HW/SI_DeviceGCAdapter.h"
#include "Core/HW/SI_DeviceGCController.h"
#include "Core/HW/SI_DeviceGCSteeringWheel.h"
#include "Core/HW/SI_DeviceKeyboard.h"
@@ -73,6 +74,9 @@ std::unique_ptr<ISIDevice> SIDevice_Create(const SIDevices device, const int por
case SIDEVICE_GC_CONTROLLER:
return std::make_unique<CSIDevice_GCController>(device, port_number);
+ case SIDEVICE_WIIU_ADAPTER:
+ return std::make_unique<CSIDevice_GCAdapter>(device, port_number);
+
case SIDEVICE_DANCEMAT:
return std::make_unique<CSIDevice_DanceMat>(device, port_number);
diff --git a/Source/Core/Core/HW/SI_Device.h b/Source/Core/Core/HW/SI_Device.h
index abaf25cbd3..866ae98e2a 100644
--- a/Source/Core/Core/HW/SI_Device.h
+++ b/Source/Core/Core/HW/SI_Device.h
@@ -61,7 +61,8 @@ enum SIDevices : int
SIDEVICE_GC_STEERING,
SIDEVICE_DANCEMAT,
SIDEVICE_GC_TARUKONGA,
- SIDEVICE_AM_BASEBOARD
+ SIDEVICE_AM_BASEBOARD,
+ SIDEVICE_WIIU_ADAPTER,
};
diff --git a/Source/Core/Core/HW/SI_DeviceGCAdapter.cpp b/Source/Core/Core/HW/SI_DeviceGCAdapter.cpp
new file mode 100644
index 0000000000..0f2c55ca5d
--- /dev/null
+++ b/Source/Core/Core/HW/SI_DeviceGCAdapter.cpp
@@ -0,0 +1,150 @@
+// Copyright 2008 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "Common/MsgHandler.h"
+#include "Common/Logging/Log.h"
+#include "Core/ConfigManager.h"
+#include "Core/Movie.h"
+#include "Core/HW/SI_DeviceGCAdapter.h"
+
+CSIDevice_GCAdapter::CSIDevice_GCAdapter(SIDevices device, int _iDeviceNumber)
+ : CSIDevice_GCController(device, _iDeviceNumber)
+{
+ // get the correct pad number that should rumble locally when using netplay
+ const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber);
+ m_simulate_konga = SConfig::GetInstance().m_AdapterKonga[numPAD];
+}
+
+GCPadStatus CSIDevice_GCAdapter::GetPadStatus()
+{
+ GCPadStatus PadStatus;
+ memset(&PadStatus, 0, sizeof(PadStatus));
+
+ GCAdapter::Input(ISIDevice::m_iDeviceNumber, &PadStatus);
+
+ HandleMoviePadStatus(&PadStatus);
+
+ return PadStatus;
+}
+
+int CSIDevice_GCAdapter::RunBuffer(u8* _pBuffer, int _iLength)
+{
+ // For debug logging only
+ ISIDevice::RunBuffer(_pBuffer, _iLength);
+
+ // Read the command
+ EBufferCommands command = static_cast<EBufferCommands>(_pBuffer[3]);
+
+ // get the correct pad number that should rumble locally when using netplay
+ const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber);
+ if (!GCAdapter::DeviceConnected(numPAD))
+ {
+ reinterpret_cast<u32*>(_pBuffer)[0] = SI_NONE;
+ return 4;
+ }
+
+ // Handle it
+ switch (command)
+ {
+ case CMD_RESET:
+ case CMD_ID:
+ *(u32*)&_pBuffer[0] = SI_GC_CONTROLLER;
+ break;
+
+ case CMD_DIRECT:
+ {
+ INFO_LOG(SERIALINTERFACE, "PAD - Direct (Length: %d)", _iLength);
+ u32 high, low;
+ GetData(high, low);
+ for (int i = 0; i < (_iLength - 1) / 2; i++)
+ {
+ _pBuffer[i + 0] = (high >> (i * 8)) & 0xff;
+ _pBuffer[i + 4] = (low >> (i * 8)) & 0xff;
+ }
+ }
+ break;
+
+ case CMD_ORIGIN:
+ {
+ INFO_LOG(SERIALINTERFACE, "PAD - Get Origin");
+
+ Calibrate();
+
+ u8* pCalibration = reinterpret_cast<u8*>(&m_Origin);
+ for (int i = 0; i < (int)sizeof(SOrigin); i++)
+ {
+ _pBuffer[i ^ 3] = *pCalibration++;
+ }
+ }
+ break;
+
+ // Recalibrate (FiRES: i am not 100 percent sure about this)
+ case CMD_RECALIBRATE:
+ {
+ INFO_LOG(SERIALINTERFACE, "PAD - Recalibrate");
+
+ Calibrate();
+
+ u8* pCalibration = reinterpret_cast<u8*>(&m_Origin);
+ for (int i = 0; i < (int)sizeof(SOrigin); i++)
+ {
+ _pBuffer[i ^ 3] = *pCalibration++;
+ }
+ }
+ break;
+
+ // DEFAULT
+ default:
+ {
+ ERROR_LOG(SERIALINTERFACE, "Unknown SI command (0x%x)", command);
+ PanicAlert("SI: Unknown command (0x%x)", command);
+ }
+ break;
+ }
+
+ return _iLength;
+}
+
+void CSIDevice_GCAdapter::SendCommand(u32 _Cmd, u8 _Poll)
+{
+ UCommand command(_Cmd);
+
+ switch (command.Command)
+ {
+ // Costis sent it in some demos :)
+ case 0x00:
+ break;
+
+ case CMD_WRITE:
+ {
+ unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard
+ unsigned int uStrength = command.Parameter2;
+
+ // get the correct pad number that should rumble locally when using netplay
+ const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber);
+
+ if (numPAD < 4)
+ {
+ if (uType == 1 && uStrength > 2)
+ GCAdapter::Output(numPAD, 1);
+ else
+ GCAdapter::Output(numPAD, 0);
+ }
+ if (!_Poll)
+ {
+ m_Mode = command.Parameter2;
+ INFO_LOG(SERIALINTERFACE, "PAD %i set to mode %i", ISIDevice::m_iDeviceNumber, m_Mode);
+ }
+ }
+ break;
+
+ default:
+ {
+ ERROR_LOG(SERIALINTERFACE, "Unknown direct command (0x%x)", _Cmd);
+ PanicAlert("SI: Unknown direct command");
+ }
+ break;
+ }
+}
+
diff --git a/Source/Core/Core/HW/SI_DeviceGCAdapter.h b/Source/Core/Core/HW/SI_DeviceGCAdapter.h
new file mode 100644
index 0000000000..e171e3a5a0
--- /dev/null
+++ b/Source/Core/Core/HW/SI_DeviceGCAdapter.h
@@ -0,0 +1,20 @@
+// Copyright 2008 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "Core/HW/SI_Device.h"
+#include "Core/HW/SI_DeviceGCController.h"
+#include "InputCommon/GCAdapter.h"
+#include "InputCommon/GCPadStatus.h"
+
+class CSIDevice_GCAdapter : public CSIDevice_GCController
+{
+public:
+ CSIDevice_GCAdapter(SIDevices device, int _iDeviceNumber);
+
+ GCPadStatus GetPadStatus() override;
+ int RunBuffer(u8* _pBuffer, int _iLength) override;
+ void SendCommand(u32 _Cmd, u8 _Poll) override;
+};
diff --git a/Source/Core/Core/HW/SI_DeviceGCController.cpp b/Source/Core/Core/HW/SI_DeviceGCController.cpp
index ccf27baac4..cf6eb50ff5 100644
--- a/Source/Core/Core/HW/SI_DeviceGCController.cpp
+++ b/Source/Core/Core/HW/SI_DeviceGCController.cpp
@@ -13,9 +13,6 @@
#include "Core/HW/SI.h"
#include "Core/HW/SI_Device.h"
#include "Core/HW/SI_DeviceGCController.h"
-#if defined(__LIBUSB__) || defined (_WIN32)
-#include "Core/HW/SI_GCAdapter.h"
-#endif
#include "Core/HW/SystemTimers.h"
#include "InputCommon/GCPadStatus.h"
@@ -119,38 +116,38 @@ int CSIDevice_GCController::RunBuffer(u8* _pBuffer, int _iLength)
return _iLength;
}
-GCPadStatus CSIDevice_GCController::GetPadStatus()
+void CSIDevice_GCController::HandleMoviePadStatus(GCPadStatus* PadStatus)
{
- GCPadStatus PadStatus;
- memset(&PadStatus, 0, sizeof(PadStatus));
-
- Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus);
-
-#if defined(__LIBUSB__) || defined (_WIN32)
- SI_GCAdapter::Input(ISIDevice::m_iDeviceNumber, &PadStatus);
-#endif
-
- Movie::CallGCInputManip(&PadStatus, ISIDevice::m_iDeviceNumber);
+ Movie::CallGCInputManip(PadStatus, ISIDevice::m_iDeviceNumber);
Movie::SetPolledDevice();
- if (NetPlay_GetInput(ISIDevice::m_iDeviceNumber, &PadStatus))
+ if (NetPlay_GetInput(ISIDevice::m_iDeviceNumber, PadStatus))
{
}
else if (Movie::IsPlayingInput())
{
- Movie::PlayController(&PadStatus, ISIDevice::m_iDeviceNumber);
+ Movie::PlayController(PadStatus, ISIDevice::m_iDeviceNumber);
Movie::InputUpdate();
}
else if (Movie::IsRecordingInput())
{
- Movie::RecordInput(&PadStatus, ISIDevice::m_iDeviceNumber);
+ Movie::RecordInput(PadStatus, ISIDevice::m_iDeviceNumber);
Movie::InputUpdate();
}
else
{
- Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber);
+ Movie::CheckPadStatus(PadStatus, ISIDevice::m_iDeviceNumber);
}
+}
+
+GCPadStatus CSIDevice_GCController::GetPadStatus()
+{
+ GCPadStatus PadStatus;
+ memset(&PadStatus, 0, sizeof(PadStatus));
+
+ Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus);
+ HandleMoviePadStatus(&PadStatus);
return PadStatus;
}
@@ -163,6 +160,8 @@ GCPadStatus CSIDevice_GCController::GetPadStatus()
bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
{
GCPadStatus PadStatus = GetPadStatus();
+ if (HandleButtonCombos(PadStatus) == COMBO_ORIGIN)
+ PadStatus.button |= PAD_GET_ORIGIN;
_Hi = MapPadStatus(PadStatus);
@@ -211,7 +210,12 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
_Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits
}
- HandleButtonCombos(PadStatus);
+ // Unset all bits except those that represent
+ // A, B, X, Y, Start and the error bits, as they
+ // are not used.
+ if (m_simulate_konga)
+ _Hi &= ~0x20FFFFFF;
+
return true;
}
@@ -225,7 +229,7 @@ u32 CSIDevice_GCController::MapPadStatus(const GCPadStatus& pad_status)
return _Hi;
}
-void CSIDevice_GCController::HandleButtonCombos(const GCPadStatus& pad_status)
+CSIDevice_GCController::EButtonCombo CSIDevice_GCController::HandleButtonCombos(const GCPadStatus& pad_status)
{
// Keep track of the special button combos (embedded in controller hardware... :( )
EButtonCombo tempCombo;
@@ -258,8 +262,11 @@ void CSIDevice_GCController::HandleButtonCombos(const GCPadStatus& pad_status)
m_Origin.uTrigger_R = pad_status.triggerRight;
}
m_LastButtonCombo = COMBO_NONE;
+ return tempCombo;
}
}
+
+ return COMBO_NONE;
}
// SendCommand
@@ -281,15 +288,6 @@ void CSIDevice_GCController::SendCommand(u32 _Cmd, u8 _Poll)
// get the correct pad number that should rumble locally when using netplay
const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber);
-#if defined(__LIBUSB__) || defined (_WIN32)
- if (numPAD < 4)
- {
- if (uType == 1 && uStrength > 2)
- SI_GCAdapter::Output(numPAD, 1);
- else
- SI_GCAdapter::Output(numPAD, 0);
- }
-#endif
if (numPAD < 4)
{
if (uType == 1 && uStrength > 2)
diff --git a/Source/Core/Core/HW/SI_DeviceGCController.h b/Source/Core/Core/HW/SI_DeviceGCController.h
index 855ae89127..ca772131dc 100644
--- a/Source/Core/Core/HW/SI_DeviceGCController.h
+++ b/Source/Core/Core/HW/SI_DeviceGCController.h
@@ -79,6 +79,9 @@ protected:
// Type of button combo from the last/current poll
EButtonCombo m_LastButtonCombo;
+ // Set this if we want to simulate the "TaruKonga" DK Bongo controller
+ bool m_simulate_konga = false;
+
public:
// Constructor
@@ -98,14 +101,15 @@ public:
virtual GCPadStatus GetPadStatus();
virtual u32 MapPadStatus(const GCPadStatus& pad_status);
- virtual void HandleButtonCombos(const GCPadStatus& pad_status);
+ virtual EButtonCombo HandleButtonCombos(const GCPadStatus& pad_status);
// Send and Receive pad input from network
static bool NetPlay_GetInput(u8 numPAD, GCPadStatus* status);
static u8 NetPlay_InGamePadToLocalPad(u8 numPAD);
-private:
+protected:
void Calibrate();
+ void HandleMoviePadStatus(GCPadStatus* PadStatus);
};
@@ -113,16 +117,8 @@ private:
class CSIDevice_TaruKonga : public CSIDevice_GCController
{
public:
- CSIDevice_TaruKonga(SIDevices device, int _iDeviceNumber) : CSIDevice_GCController(device, _iDeviceNumber) { }
-
- bool GetData(u32& _Hi, u32& _Low) override
+ CSIDevice_TaruKonga(SIDevices device, int _iDeviceNumber) : CSIDevice_GCController(device, _iDeviceNumber)
{
- CSIDevice_GCController::GetData(_Hi, _Low);
-
- // Unset all bits except those that represent
- // A, B, X, Y, Start and the error bits, as they
- // are not used.
- _Hi &= ~0x20FFFFFF;
- return true;
+ m_simulate_konga = true;
}
};
diff --git a/Source/Core/DolphinWX/CMakeLists.txt b/Source/Core/DolphinWX/CMakeLists.txt
index d9cdb9bd9b..1c17ccd207 100644
--- a/Source/Core/DolphinWX/CMakeLists.txt
+++ b/Source/Core/DolphinWX/CMakeLists.txt
@@ -10,6 +10,7 @@ set(GUI_SRCS
Config/AudioConfigPane.cpp
Config/ConfigMain.cpp
Config/GameCubeConfigPane.cpp
+ Config/GCAdapterConfigDiag.cpp
Config/GeneralConfigPane.cpp
Config/InterfaceConfigPane.cpp
Config/PathConfigPane.cpp
diff --git a/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp b/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp
new file mode 100644
index 0000000000..06ef12dd80
--- /dev/null
+++ b/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp
@@ -0,0 +1,77 @@
+// Copyright 2010 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include <wx/checkbox.h>
+#include <wx/stattext.h>
+
+#include "Common/CommonTypes.h"
+#include "Core/ConfigManager.h"
+#include "Core/Core.h"
+#include "DolphinWX/Config/GCAdapterConfigDiag.h"
+#include "InputCommon/GCAdapter.h"
+
+wxDEFINE_EVENT(wxEVT_ADAPTER_UPDATE, wxCommandEvent);
+
+
+GCAdapterConfigDiag::GCAdapterConfigDiag(wxWindow* const parent, const wxString& name, const int tab_num)
+ : wxDialog(parent, wxID_ANY, name, wxPoint(128,-1)), m_pad_id(tab_num)
+{
+ wxBoxSizer* const szr = new wxBoxSizer(wxVERTICAL);
+
+
+ wxCheckBox* const gamecube_rumble = new wxCheckBox(this, wxID_ANY, _("Rumble"));
+ gamecube_rumble->SetValue(SConfig::GetInstance().m_AdapterRumble[m_pad_id]);
+ gamecube_rumble->Bind(wxEVT_CHECKBOX, &GCAdapterConfigDiag::OnAdapterRumble, this);
+
+ wxCheckBox* const gamecube_konga = new wxCheckBox(this, wxID_ANY, _("Simulate DK TaruKonga"));
+ gamecube_konga->SetValue(SConfig::GetInstance().m_AdapterKonga[m_pad_id]);
+ gamecube_konga->Bind(wxEVT_CHECKBOX, &GCAdapterConfigDiag::OnAdapterKonga, this);
+
+ m_adapter_status = new wxStaticText(this, wxID_ANY, _("Adapter Not Detected"));
+
+ if (!GCAdapter::IsDetected())
+ {
+ if (!GCAdapter::IsDriverDetected())
+ {
+ m_adapter_status->SetLabelText(_("Driver Not Detected"));
+ gamecube_rumble->Disable();
+ }
+ }
+ else
+ {
+ m_adapter_status->SetLabelText(_("Adapter Detected"));
+ }
+ GCAdapter::SetAdapterCallback(std::bind(&GCAdapterConfigDiag::ScheduleAdapterUpdate, this));
+
+ szr->Add(m_adapter_status, 0, wxEXPAND);
+ szr->Add(gamecube_rumble, 0, wxEXPAND);
+ szr->Add(gamecube_konga, 0, wxEXPAND);
+ szr->Add(CreateButtonSizer(wxOK | wxNO_DEFAULT), 0, wxEXPAND|wxALL, 5);
+
+ SetLayoutAdaptationMode(wxDIALOG_ADAPTATION_MODE_ENABLED);
+ SetSizerAndFit(szr);
+ Center();
+
+ Bind(wxEVT_ADAPTER_UPDATE, &GCAdapterConfigDiag::UpdateAdapter, this);
+}
+
+void GCAdapterConfigDiag::ScheduleAdapterUpdate()
+{
+ wxQueueEvent(this, new wxCommandEvent(wxEVT_ADAPTER_UPDATE));
+}
+
+void GCAdapterConfigDiag::UpdateAdapter(wxCommandEvent& ev)
+{
+ bool unpause = Core::PauseAndLock(true);
+ if (GCAdapter::IsDetected())
+ m_adapter_status->SetLabelText(_("Adapter Detected"));
+ else
+ m_adapter_status->SetLabelText(_("Adapter Not Detected"));
+ Core::PauseAndLock(false, unpause);
+}
+
+GCAdapterConfigDiag::~GCAdapterConfigDiag()
+{
+ GCAdapter::SetAdapterCallback(nullptr);
+}
diff --git a/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.h b/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.h
new file mode 100644
index 0000000000..4c86f55a2e
--- /dev/null
+++ b/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.h
@@ -0,0 +1,40 @@
+// Copyright 2010 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <cstddef>
+#include <string>
+#include <vector>
+#include <wx/button.h>
+#include <wx/dialog.h>
+#include <wx/eventfilter.h>
+#include <wx/panel.h>
+#include <wx/sizer.h>
+
+#include "Core/ConfigManager.h"
+
+class GCAdapterConfigDiag : public wxDialog
+{
+public:
+ GCAdapterConfigDiag(wxWindow* const parent, const wxString& name, const int tab_num = 0);
+ ~GCAdapterConfigDiag();
+
+ void ScheduleAdapterUpdate();
+ void UpdateAdapter(wxCommandEvent& ev);
+
+private:
+ wxStaticText* m_adapter_status;
+ int m_pad_id;
+
+ void OnAdapterRumble(wxCommandEvent& event)
+ {
+ SConfig::GetInstance().m_AdapterRumble[m_pad_id] = event.IsChecked();
+ }
+
+ void OnAdapterKonga(wxCommandEvent& event)
+ {
+ SConfig::GetInstance().m_AdapterKonga[m_pad_id] = event.IsChecked();
+ }
+};
diff --git a/Source/Core/DolphinWX/ControllerConfigDiag.cpp b/Source/Core/DolphinWX/ControllerConfigDiag.cpp
index 149247dd81..8bc510f7a5 100644
--- a/Source/Core/DolphinWX/ControllerConfigDiag.cpp
+++ b/Source/Core/DolphinWX/ControllerConfigDiag.cpp
@@ -26,26 +26,24 @@
#include "Core/HW/GCKeyboard.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"
#include "DolphinWX/InputConfigDiag.h"
+#include "DolphinWX/Config/GCAdapterConfigDiag.h"
+#include "InputCommon/GCAdapter.h"
#if defined(HAVE_XRANDR) && HAVE_XRANDR
#include "DolphinWX/X11Utils.h"
#endif
-wxDEFINE_EVENT(wxEVT_ADAPTER_UPDATE, wxCommandEvent);
-
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"),
_("TaruKonga (Bongos)"),
@@ -70,7 +68,6 @@ ControllerConfigDiag::ControllerConfigDiag(wxWindow* const parent)
SetLayoutAdaptationMode(wxDIALOG_ADAPTATION_MODE_ENABLED);
SetSizerAndFit(main_sizer);
Center();
- Bind(wxEVT_ADAPTER_UPDATE, &ControllerConfigDiag::UpdateAdapter, this);
}
wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer()
@@ -113,24 +110,27 @@ wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer()
case SIDEVICE_GC_CONTROLLER:
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[1]);
break;
- case SIDEVICE_GC_STEERING:
+ case SIDEVICE_WIIU_ADAPTER:
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[2]);
break;
- case SIDEVICE_DANCEMAT:
+ case SIDEVICE_GC_STEERING:
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[3]);
break;
- case SIDEVICE_GC_TARUKONGA:
+ case SIDEVICE_DANCEMAT:
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[4]);
break;
- case SIDEVICE_GC_GBA:
+ 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]);
gamecube_configure_bt[i]->Disable();
break;
case SIDEVICE_GC_KEYBOARD:
- pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[6]);
+ pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[7]);
break;
case SIDEVICE_AM_BASEBOARD:
- pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[7]);
+ pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[8]);
break;
default:
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[0]);
@@ -147,67 +147,9 @@ 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(wxVERTICAL, 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);
-
- wxCheckBox* const gamecube_rumble = new wxCheckBox(this, wxID_ANY, _("Rumble"));
- gamecube_rumble->SetValue(SConfig::GetInstance().m_AdapterRumble);
- gamecube_rumble->Bind(wxEVT_CHECKBOX, &ControllerConfigDiag::OnAdapterRumble, this);
-
- m_adapter_status = new wxStaticText(this, wxID_ANY, _("Adapter Not Detected"));
-
- gamecube_adapter_group->Add(m_adapter_status, 0, wxEXPAND);
- gamecube_adapter_sizer->Add(gamecube_adapter, 0, wxEXPAND);
- gamecube_adapter_sizer->Add(gamecube_rumble, 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)
- gamecube_adapter->SetValue(SConfig::GetInstance().m_GameCubeAdapter);
- if (!SI_GCAdapter::IsDetected())
- {
- if (!SI_GCAdapter::IsDriverDetected())
- {
- m_adapter_status->SetLabelText(_("Driver Not Detected"));
- gamecube_adapter->Disable();
- gamecube_adapter->SetValue(false);
- gamecube_rumble->Disable();
- }
- }
- else
- {
- m_adapter_status->SetLabelText(_("Adapter Detected"));
- }
- if (Core::GetState() != Core::CORE_UNINITIALIZED)
- {
- gamecube_adapter->Disable();
- }
- SI_GCAdapter::SetAdapterCallback(std::bind(&ControllerConfigDiag::ScheduleAdapterUpdate, this));
-#endif
-
return gamecube_static_sizer;
}
-void ControllerConfigDiag::ScheduleAdapterUpdate()
-{
- wxQueueEvent(this, new wxCommandEvent(wxEVT_ADAPTER_UPDATE));
-}
-
-void ControllerConfigDiag::UpdateAdapter(wxCommandEvent& ev)
-{
-#if defined(__LIBUSB__) || defined (_WIN32)
- bool unpause = Core::PauseAndLock(true);
- if (SI_GCAdapter::IsDetected())
- m_adapter_status->SetLabelText(_("Adapter Detected"));
- else
- m_adapter_status->SetLabelText(_("Adapter Not Detected"));
- Core::PauseAndLock(false, unpause);
-#endif
-}
-
wxStaticBoxSizer* ControllerConfigDiag::CreateWiimoteConfigSizer()
{
wxStaticText* wiimote_label[4];
@@ -504,30 +446,35 @@ void ControllerConfigDiag::OnGameCubePortChanged(wxCommandEvent& event)
}
else if (device_name == m_gc_pad_type_strs[2])
{
- tempType = SIDEVICE_GC_STEERING;
+ tempType = SIDEVICE_WIIU_ADAPTER;
gamecube_configure_bt[device_num]->Enable();
}
else if (device_name == m_gc_pad_type_strs[3])
{
- tempType = SIDEVICE_DANCEMAT;
+ tempType = SIDEVICE_GC_STEERING;
gamecube_configure_bt[device_num]->Enable();
}
else if (device_name == m_gc_pad_type_strs[4])
{
- tempType = SIDEVICE_GC_TARUKONGA;
+ tempType = SIDEVICE_DANCEMAT;
gamecube_configure_bt[device_num]->Enable();
}
else if (device_name == m_gc_pad_type_strs[5])
{
+ tempType = SIDEVICE_GC_TARUKONGA;
+ gamecube_configure_bt[device_num]->Enable();
+ }
+ else if (device_name == m_gc_pad_type_strs[6])
+ {
tempType = SIDEVICE_GC_GBA;
gamecube_configure_bt[device_num]->Disable();
}
- else if (device_name == m_gc_pad_type_strs[6])
+ else if (device_name == m_gc_pad_type_strs[7])
{
tempType = SIDEVICE_GC_KEYBOARD;
gamecube_configure_bt[device_num]->Enable();
}
- else if (device_name == m_gc_pad_type_strs[7])
+ else if (device_name == m_gc_pad_type_strs[8])
{
tempType = SIDEVICE_AM_BASEBOARD;
gamecube_configure_bt[device_num]->Enable();
@@ -540,6 +487,11 @@ void ControllerConfigDiag::OnGameCubePortChanged(wxCommandEvent& event)
SConfig::GetInstance().m_SIDevice[device_num] = tempType;
+ if (GCAdapter::UseAdapter())
+ GCAdapter::StartScanThread();
+ else
+ GCAdapter::StopScanThread();
+
if (Core::IsRunning())
SerialInterface::ChangeDevice(tempType, device_num);
}
@@ -557,6 +509,11 @@ void ControllerConfigDiag::OnGameCubeConfigButton(wxCommandEvent& event)
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);
@@ -565,10 +522,3 @@ void ControllerConfigDiag::OnGameCubeConfigButton(wxCommandEvent& event)
HotkeyManagerEmu::Enable(true);
}
-
-ControllerConfigDiag::~ControllerConfigDiag()
-{
-#if defined(__LIBUSB__) || defined (_WIN32)
- SI_GCAdapter::SetAdapterCallback(nullptr);
-#endif
-}
diff --git a/Source/Core/DolphinWX/ControllerConfigDiag.h b/Source/Core/DolphinWX/ControllerConfigDiag.h
index f679992b54..8646396b2b 100644
--- a/Source/Core/DolphinWX/ControllerConfigDiag.h
+++ b/Source/Core/DolphinWX/ControllerConfigDiag.h
@@ -10,8 +10,8 @@
#include "Common/SysConf.h"
#include "Core/ConfigManager.h"
-#include "Core/HW/SI_GCAdapter.h"
#include "Core/HW/Wiimote.h"
+#include "InputCommon/GCAdapter.h"
class InputConfig;
class wxButton;
@@ -21,7 +21,6 @@ class ControllerConfigDiag : public wxDialog
{
public:
ControllerConfigDiag(wxWindow* const parent);
- ~ControllerConfigDiag();
private:
void RefreshRealWiimotes(wxCommandEvent& event);
@@ -70,23 +69,6 @@ private:
event.Skip();
}
- void OnGameCubeAdapter(wxCommandEvent& event)
- {
- SConfig::GetInstance().m_GameCubeAdapter = event.IsChecked();
-#ifdef __LIBUSB__
- if (event.IsChecked())
- SI_GCAdapter::StartScanThread();
- else
- SI_GCAdapter::StopScanThread();
-#endif
- event.Skip();
- }
- void OnAdapterRumble(wxCommandEvent& event)
- {
- SConfig::GetInstance().m_AdapterRumble = event.IsChecked();
- }
-
-
wxStaticBoxSizer* CreateGamecubeSizer();
wxStaticBoxSizer* CreateWiimoteConfigSizer();
wxStaticBoxSizer* CreateBalanceBoardSizer();
@@ -96,17 +78,14 @@ private:
void Cancel(wxCommandEvent& event);
void OnGameCubePortChanged(wxCommandEvent& event);
void OnGameCubeConfigButton(wxCommandEvent& event);
- void ScheduleAdapterUpdate();
- void UpdateAdapter(wxCommandEvent& ev);
std::map<wxWindowID, unsigned int> m_gc_port_choice_ids;
std::map<wxWindowID, unsigned int> m_gc_port_config_ids;
- std::array<wxString, 8> m_gc_pad_type_strs;
+ std::array<wxString, 9> m_gc_pad_type_strs;
std::map<wxWindowID, unsigned int> m_wiimote_index_from_ctrl_id;
unsigned int m_orig_wiimote_sources[MAX_BBMOTES];
- wxStaticText* m_adapter_status;
wxButton* wiimote_configure_bt[MAX_WIIMOTES];
wxButton* gamecube_configure_bt[4];
std::map<wxWindowID, unsigned int> m_wiimote_index_from_conf_bt_id;
diff --git a/Source/Core/DolphinWX/DolphinWX.vcxproj b/Source/Core/DolphinWX/DolphinWX.vcxproj
index b4818cf162..13882b44a4 100644
--- a/Source/Core/DolphinWX/DolphinWX.vcxproj
+++ b/Source/Core/DolphinWX/DolphinWX.vcxproj
@@ -58,6 +58,7 @@
<ClCompile Include="Config\AudioConfigPane.cpp" />
<ClCompile Include="Config\ConfigMain.cpp" />
<ClCompile Include="Config\GameCubeConfigPane.cpp" />
+ <ClCompile Include="Config\GCAdapterConfigDiag.cpp" />
<ClCompile Include="Config\GeneralConfigPane.cpp" />
<ClCompile Include="Config\InterfaceConfigPane.cpp" />
<ClCompile Include="Config\PathConfigPane.cpp" />
@@ -113,6 +114,7 @@
<ClInclude Include="Config\AdvancedConfigPane.h" />
<ClInclude Include="Config\AudioConfigPane.h" />
<ClInclude Include="Config\GameCubeConfigPane.h" />
+ <ClInclude Include="Config\GCAdapterConfigDiag.h" />
<ClInclude Include="Config\GeneralConfigPane.h" />
<ClInclude Include="Config\InterfaceConfigPane.h" />
<ClInclude Include="Config\PathConfigPane.h" />
@@ -246,4 +248,4 @@
<Message Text="Copy: @(BinaryFiles) -&gt; $(BinaryOutputDir)" Importance="High" />
<Copy SourceFiles="@(BinaryFiles)" DestinationFolder="$(BinaryOutputDir)" />
</Target>
-</Project> \ No newline at end of file
+</Project>
diff --git a/Source/Core/DolphinWX/DolphinWX.vcxproj.filters b/Source/Core/DolphinWX/DolphinWX.vcxproj.filters
index 87fb5df32a..5534ec41f8 100644
--- a/Source/Core/DolphinWX/DolphinWX.vcxproj.filters
+++ b/Source/Core/DolphinWX/DolphinWX.vcxproj.filters
@@ -178,6 +178,9 @@
<ClCompile Include="Config\GameCubeConfigPane.cpp">
<Filter>GUI\Config</Filter>
</ClCompile>
+ <ClCompile Include="Config\GCAdapterConfigDiag.cpp">
+ <Filter>GUI\Config</Filter>
+ </ClCompile>
<ClCompile Include="Config\WiiConfigPane.cpp">
<Filter>GUI\Config</Filter>
</ClCompile>
@@ -339,6 +342,9 @@
<ClInclude Include="Config\GameCubeConfigPane.h">
<Filter>GUI\Config</Filter>
</ClInclude>
+ <ClInclude Include="Config\GCAdapterConfigDiag.h">
+ <Filter>GUI\Config</Filter>
+ </ClInclude>
<ClInclude Include="Config\WiiConfigPane.h">
<Filter>GUI\Config</Filter>
</ClInclude>
@@ -369,4 +375,4 @@
<ItemGroup>
<Image Include="$(CoreDir)..\..\Installer\Dolphin.ico" />
</ItemGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/Source/Core/InputCommon/CMakeLists.txt b/Source/Core/InputCommon/CMakeLists.txt
index b200625000..01eef4532c 100644
--- a/Source/Core/InputCommon/CMakeLists.txt
+++ b/Source/Core/InputCommon/CMakeLists.txt
@@ -3,8 +3,6 @@ set(SRCS ControllerEmu.cpp
ControllerInterface/ControllerInterface.cpp
ControllerInterface/Device.cpp
ControllerInterface/ExpressionParser.cpp)
-
-
set(LIBS common)
if(WIN32)
@@ -33,10 +31,18 @@ elseif(X11_FOUND)
endif()
set(LIBS ${LIBS} ${X11_LIBRARIES} ${XINPUT2_LIBRARIES})
elseif(ANDROID)
- set(SRCS ${SRCS}
- ControllerInterface/Android/Android.cpp)
+ set(SRCS ${SRCS}
+ ControllerInterface/Android/Android.cpp)
endif()
+if(LIBUSB_FOUND)
+ set(SRCS ${SRCS} GCAdapter.cpp)
+elseif(ANDROID)
+ set(SRCS ${SRCS} GCAdapter_Android.cpp)
+else()
+ set(SRCS ${SRCS} GCAdapter_Null.cpp)
+endif(LIBUSB_FOUND)
+
if(LIBEVDEV_FOUND AND LIBUDEV_FOUND)
set(SRCS ${SRCS} ControllerInterface/evdev/evdev.cpp)
set(LIBS ${LIBS} ${LIBEVDEV_LIBRARY} ${LIBUDEV_LIBRARY})
diff --git a/Source/Core/Core/HW/SI_GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp
index b6b12bcfdb..b5dc395b49 100644
--- a/Source/Core/Core/HW/SI_GCAdapter.cpp
+++ b/Source/Core/InputCommon/GCAdapter.cpp
@@ -8,29 +8,24 @@
#include "Common/Flag.h"
#include "Common/Thread.h"
+#include "Common/Logging/Log.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/CoreTiming.h"
#include "Core/HW/SI.h"
-#include "Core/HW/SI_GCAdapter.h"
#include "Core/HW/SystemTimers.h"
+
+#include "InputCommon/GCAdapter.h"
#include "InputCommon/GCPadStatus.h"
-namespace SI_GCAdapter
-{
-enum ControllerTypes
+namespace GCAdapter
{
- CONTROLLER_NONE = 0,
- CONTROLLER_WIRED = 1,
- CONTROLLER_WIRELESS = 2
-};
-
static bool CheckDeviceAccess(libusb_device* device);
static void AddGCAdapter(libusb_device* device);
static bool s_detected = false;
static libusb_device_handle* s_handle = nullptr;
-static u8 s_controller_type[MAX_SI_CHANNELS] = { CONTROLLER_NONE, CONTROLLER_NONE, CONTROLLER_NONE, CONTROLLER_NONE };
+static u8 s_controller_type[MAX_SI_CHANNELS] = { ControllerTypes::CONTROLLER_NONE, ControllerTypes::CONTROLLER_NONE, ControllerTypes::CONTROLLER_NONE, ControllerTypes::CONTROLLER_NONE };
static u8 s_controller_rumble[4];
static std::mutex s_mutex;
@@ -158,13 +153,16 @@ void Init()
}
else
{
- if (SConfig::GetInstance().m_GameCubeAdapter)
+ if (UseAdapter())
StartScanThread();
}
}
void StartScanThread()
{
+ if (s_adapter_detect_thread_running.IsSet())
+ return;
+
s_adapter_detect_thread_running.Set(true);
s_adapter_detect_thread = std::thread(ScanThreadFunc);
}
@@ -184,7 +182,7 @@ void Setup()
for (int i = 0; i < MAX_SI_CHANNELS; i++)
{
- s_controller_type[i] = CONTROLLER_NONE;
+ s_controller_type[i] = ControllerTypes::CONTROLLER_NONE;
s_controller_rumble[i] = 0;
}
@@ -334,7 +332,7 @@ void Reset()
}
for (int i = 0; i < MAX_SI_CHANNELS; i++)
- s_controller_type[i] = CONTROLLER_NONE;
+ s_controller_type[i] = ControllerTypes::CONTROLLER_NONE;
s_detected = false;
@@ -351,7 +349,7 @@ void Reset()
void Input(int chan, GCPadStatus* pad)
{
- if (!SConfig::GetInstance().m_GameCubeAdapter)
+ if (!UseAdapter())
return;
if (s_handle == nullptr || !s_detected)
@@ -371,15 +369,19 @@ void Input(int chan, GCPadStatus* pad)
}
else
{
+ bool get_origin = false;
u8 type = controller_payload_copy[1 + (9 * chan)] >> 4;
- if (type != CONTROLLER_NONE && s_controller_type[chan] == CONTROLLER_NONE)
+ if (type != ControllerTypes::CONTROLLER_NONE && s_controller_type[chan] == ControllerTypes::CONTROLLER_NONE)
+ {
NOTICE_LOG(SERIALINTERFACE, "New device connected to Port %d of Type: %02x", chan + 1, controller_payload_copy[1 + (9 * chan)]);
+ get_origin = true;
+ }
s_controller_type[chan] = type;
- if (s_controller_type[chan] != CONTROLLER_NONE)
+ memset(pad, 0, sizeof(*pad));
+ if (s_controller_type[chan] != ControllerTypes::CONTROLLER_NONE)
{
- memset(pad, 0, sizeof(*pad));
u8 b1 = controller_payload_copy[1 + (9 * chan) + 1];
u8 b2 = controller_payload_copy[1 + (9 * chan) + 2];
@@ -398,6 +400,8 @@ void Input(int chan, GCPadStatus* pad)
if (b2 & (1 << 2)) pad->button |= PAD_TRIGGER_R;
if (b2 & (1 << 3)) pad->button |= PAD_TRIGGER_L;
+ if (get_origin) pad->button |= PAD_GET_ORIGIN;
+
pad->stickX = controller_payload_copy[1 + (9 * chan) + 3];
pad->stickY = controller_payload_copy[1 + (9 * chan) + 4];
pad->substickX = controller_payload_copy[1 + (9 * chan) + 5];
@@ -405,12 +409,29 @@ void Input(int chan, GCPadStatus* pad)
pad->triggerLeft = controller_payload_copy[1 + (9 * chan) + 7];
pad->triggerRight = controller_payload_copy[1 + (9 * chan) + 8];
}
+ else
+ {
+ pad->button = PAD_ERR_STATUS;
+ }
}
}
+bool DeviceConnected(int chan)
+{
+ return s_controller_type[chan] != ControllerTypes::CONTROLLER_NONE;
+}
+
+bool UseAdapter()
+{
+ return SConfig::GetInstance().m_SIDevice[0] == SIDEVICE_WIIU_ADAPTER ||
+ SConfig::GetInstance().m_SIDevice[1] == SIDEVICE_WIIU_ADAPTER ||
+ SConfig::GetInstance().m_SIDevice[2] == SIDEVICE_WIIU_ADAPTER ||
+ SConfig::GetInstance().m_SIDevice[3] == SIDEVICE_WIIU_ADAPTER;
+}
+
void ResetRumble()
{
- if (!SConfig::GetInstance().m_GameCubeAdapter)
+ if (!UseAdapter())
return;
if (s_handle == nullptr || !s_detected)
return;
@@ -427,11 +448,11 @@ void ResetRumble()
void Output(int chan, u8 rumble_command)
{
- if (s_handle == nullptr || !SConfig::GetInstance().m_GameCubeAdapter || !SConfig::GetInstance().m_AdapterRumble)
+ if (s_handle == nullptr || !UseAdapter() || !SConfig::GetInstance().m_AdapterRumble[chan])
return;
// Skip over rumble commands if it has not changed or the controller is wireless
- if (rumble_command != s_controller_rumble[chan] && s_controller_type[chan] != CONTROLLER_WIRELESS)
+ if (rumble_command != s_controller_rumble[chan] && s_controller_type[chan] != ControllerTypes::CONTROLLER_WIRELESS)
{
s_controller_rumble[chan] = rumble_command;
@@ -458,4 +479,4 @@ bool IsDriverDetected()
return !s_libusb_driver_not_supported;
}
-} // end of namespace SI_GCAdapter
+} // end of namespace GCAdapter
diff --git a/Source/Core/Core/HW/SI_GCAdapter.h b/Source/Core/InputCommon/GCAdapter.h
index 13deb8b536..5af8f7b915 100644
--- a/Source/Core/Core/HW/SI_GCAdapter.h
+++ b/Source/Core/InputCommon/GCAdapter.h
@@ -8,9 +8,14 @@
struct GCPadStatus;
-namespace SI_GCAdapter
+namespace GCAdapter
{
-
+enum ControllerTypes
+{
+ CONTROLLER_NONE = 0,
+ CONTROLLER_WIRED = 1,
+ CONTROLLER_WIRELESS = 2
+};
void Init();
void Reset();
void ResetRumble();
@@ -23,5 +28,7 @@ void Input(int chan, GCPadStatus* pad);
void Output(int chan, u8 rumble_command);
bool IsDetected();
bool IsDriverDetected();
+bool DeviceConnected(int chan);
+bool UseAdapter();
-} // end of namespace SI_GCAdapter
+} // end of namespace GCAdapter
diff --git a/Source/Core/InputCommon/GCAdapter_Android.cpp b/Source/Core/InputCommon/GCAdapter_Android.cpp
new file mode 100644
index 0000000000..6e638e2a72
--- /dev/null
+++ b/Source/Core/InputCommon/GCAdapter_Android.cpp
@@ -0,0 +1,353 @@
+// Copyright 2014 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include <algorithm>
+#include <jni.h>
+#include <mutex>
+
+#include "Common/Event.h"
+#include "Common/Flag.h"
+#include "Common/Thread.h"
+#include "Common/Logging/Log.h"
+#include "Core/ConfigManager.h"
+#include "Core/Core.h"
+#include "Core/CoreTiming.h"
+#include "Core/HW/SI.h"
+#include "Core/HW/SystemTimers.h"
+
+#include "InputCommon/GCAdapter.h"
+#include "InputCommon/GCPadStatus.h"
+
+// Global java_vm class
+extern JavaVM* g_java_vm;
+
+namespace GCAdapter
+{
+// Java classes
+static jclass s_adapter_class;
+
+static bool s_detected = false;
+static int s_fd = 0;
+static u8 s_controller_type[MAX_SI_CHANNELS] = { ControllerTypes::CONTROLLER_NONE, ControllerTypes::CONTROLLER_NONE, ControllerTypes::CONTROLLER_NONE, ControllerTypes::CONTROLLER_NONE };
+static u8 s_controller_rumble[4];
+
+// Input handling
+static std::mutex s_read_mutex;
+static u8 s_controller_payload[37];
+static int s_controller_payload_size = 0;
+
+// Output handling
+static std::mutex s_write_mutex;
+static u8 s_controller_write_payload[5];
+
+// Adapter running thread
+static std::thread s_read_adapter_thread;
+static Common::Flag s_read_adapter_thread_running;
+
+static std::thread s_write_adapter_thread;
+static Common::Flag s_write_adapter_thread_running;
+static Common::Event s_write_happened;
+
+// Adapter scanning thread
+static std::thread s_adapter_detect_thread;
+static Common::Flag s_adapter_detect_thread_running;
+
+static u64 s_last_init = 0;
+
+static void ScanThreadFunc()
+{
+ Common::SetCurrentThreadName("GC Adapter Scanning Thread");
+ NOTICE_LOG(SERIALINTERFACE, "GC Adapter scanning thread started");
+
+ JNIEnv* env;
+ g_java_vm->AttachCurrentThread(&env, NULL);
+
+ jmethodID queryadapter_func = env->GetStaticMethodID(s_adapter_class, "QueryAdapter", "()Z");
+
+ while (s_adapter_detect_thread_running.IsSet())
+ {
+ if (!s_detected && UseAdapter() &&
+ env->CallStaticBooleanMethod(s_adapter_class, queryadapter_func))
+ Setup();
+ Common::SleepCurrentThread(1000);
+ }
+ g_java_vm->DetachCurrentThread();
+
+ NOTICE_LOG(SERIALINTERFACE, "GC Adapter scanning thread stopped");
+}
+
+static void Read()
+{
+ Common::SetCurrentThreadName("GC Adapter Read Thread");
+ NOTICE_LOG(SERIALINTERFACE, "GC Adapter read thread started");
+
+ bool first_read = true;
+ JNIEnv* env;
+ g_java_vm->AttachCurrentThread(&env, NULL);
+
+ jfieldID payload_field = env->GetStaticFieldID(s_adapter_class, "controller_payload", "[B");
+ jobject payload_object = env->GetStaticObjectField(s_adapter_class, payload_field);
+ jbyteArray* java_controller_payload = reinterpret_cast<jbyteArray*>(&payload_object);
+
+ // Get function pointers
+ jmethodID getfd_func = env->GetStaticMethodID(s_adapter_class, "GetFD", "()I");
+ jmethodID input_func = env->GetStaticMethodID(s_adapter_class, "Input", "()I");
+ jmethodID openadapter_func = env->GetStaticMethodID(s_adapter_class, "OpenAdapter", "()V");
+
+ env->CallStaticVoidMethod(s_adapter_class, openadapter_func);
+
+ // Reset rumble once on initial reading
+ ResetRumble();
+
+ while (s_read_adapter_thread_running.IsSet())
+ {
+ s_controller_payload_size = env->CallStaticIntMethod(s_adapter_class, input_func);
+
+ jbyte* java_data = env->GetByteArrayElements(*java_controller_payload, nullptr);
+ {
+ std::lock_guard<std::mutex> lk(s_read_mutex);
+ memcpy(s_controller_payload, java_data, 0x37);
+ }
+ env->ReleaseByteArrayElements(*java_controller_payload, java_data, 0);
+
+ if (first_read)
+ {
+ first_read = false;
+ s_fd = env->CallStaticIntMethod(s_adapter_class, getfd_func);
+ }
+
+ Common::YieldCPU();
+ }
+
+ g_java_vm->DetachCurrentThread();
+
+ NOTICE_LOG(SERIALINTERFACE, "GC Adapter read thread stopped");
+}
+
+static void Write()
+{
+ Common::SetCurrentThreadName("GC Adapter Write Thread");
+ NOTICE_LOG(SERIALINTERFACE, "GC Adapter write thread started");
+
+ JNIEnv* env;
+ g_java_vm->AttachCurrentThread(&env, NULL);
+ jmethodID output_func = env->GetStaticMethodID(s_adapter_class, "Output", "([B)I");
+
+ while (s_write_adapter_thread_running.IsSet())
+ {
+ jbyteArray jrumble_array = env->NewByteArray(5);
+ jbyte* jrumble = env->GetByteArrayElements(jrumble_array, NULL);
+
+ s_write_happened.Wait();
+ {
+ std::lock_guard<std::mutex> lk(s_write_mutex);
+ memcpy(jrumble, s_controller_write_payload, 5);
+ }
+
+ env->ReleaseByteArrayElements(jrumble_array, jrumble, 0);
+ int size = env->CallStaticIntMethod(s_adapter_class, output_func, jrumble_array);
+ // Netplay sends invalid data which results in size = 0x00. Ignore it.
+ if (size != 0x05 && size != 0x00)
+ {
+ ERROR_LOG(SERIALINTERFACE, "error writing rumble (size: %d)", size);
+ Reset();
+ }
+
+ Common::YieldCPU();
+ }
+
+ g_java_vm->DetachCurrentThread();
+
+ NOTICE_LOG(SERIALINTERFACE, "GC Adapter write thread stopped");
+}
+
+void Init()
+{
+ if (s_fd)
+ return;
+
+ if (Core::GetState() != Core::CORE_UNINITIALIZED)
+ {
+ if ((CoreTiming::GetTicks() - s_last_init) < SystemTimers::GetTicksPerSecond())
+ return;
+
+ s_last_init = CoreTiming::GetTicks();
+ }
+
+ JNIEnv* env;
+ g_java_vm->AttachCurrentThread(&env, NULL);
+
+ jclass adapter_class = env->FindClass("org/dolphinemu/dolphinemu/utils/Java_GCAdapter");
+ s_adapter_class = reinterpret_cast<jclass>(env->NewGlobalRef(adapter_class));
+
+ if (UseAdapter())
+ StartScanThread();
+}
+
+void Setup()
+{
+ s_read_adapter_thread_running.Set(true);
+ s_read_adapter_thread = std::thread(Read);
+
+ s_write_adapter_thread_running.Set(true);
+ s_write_adapter_thread = std::thread(Write);
+
+ s_detected = true;
+}
+
+void Reset()
+{
+ if (!s_detected)
+ return;
+
+ if (s_read_adapter_thread_running.TestAndClear())
+ s_read_adapter_thread.join();
+
+ if (s_write_adapter_thread_running.TestAndClear())
+ {
+ s_write_happened.Set(); // Kick the waiting event
+ s_write_adapter_thread.join();
+ }
+
+ for (int i = 0; i < MAX_SI_CHANNELS; i++)
+ s_controller_type[i] = ControllerTypes::CONTROLLER_NONE;
+
+ s_detected = false;
+ s_fd = 0;
+ NOTICE_LOG(SERIALINTERFACE, "GC Adapter detached");
+}
+
+void Shutdown()
+{
+ StopScanThread();
+ Reset();
+}
+
+void StartScanThread()
+{
+ if (s_adapter_detect_thread_running.IsSet())
+ return;
+
+ s_adapter_detect_thread_running.Set(true);
+ s_adapter_detect_thread = std::thread(ScanThreadFunc);
+}
+
+void StopScanThread()
+{
+ if (s_adapter_detect_thread_running.TestAndClear())
+ s_adapter_detect_thread.join();
+}
+
+void Input(int chan, GCPadStatus* pad)
+{
+ if (!UseAdapter() || !s_detected || !s_fd)
+ return;
+
+ u8 controller_payload_copy[37];
+
+ {
+ std::lock_guard<std::mutex> lk(s_read_mutex);
+ std::copy(std::begin(s_controller_payload), std::end(s_controller_payload), std::begin(controller_payload_copy));
+ }
+
+ if (s_controller_payload_size != sizeof(controller_payload_copy))
+ {
+ ERROR_LOG(SERIALINTERFACE, "error reading payload (size: %d, type: %02x)", s_controller_payload_size, controller_payload_copy[0]);
+ Reset();
+ }
+ else
+ {
+ bool get_origin = false;
+ u8 type = controller_payload_copy[1 + (9 * chan)] >> 4;
+ if (type != ControllerTypes::CONTROLLER_NONE && s_controller_type[chan] == ControllerTypes::CONTROLLER_NONE)
+ {
+ ERROR_LOG(SERIALINTERFACE, "New device connected to Port %d of Type: %02x", chan + 1, controller_payload_copy[1 + (9 * chan)]);
+ get_origin = true;
+ }
+
+ s_controller_type[chan] = type;
+
+ memset(pad, 0, sizeof(*pad));
+ if (s_controller_type[chan] != ControllerTypes::CONTROLLER_NONE)
+ {
+ u8 b1 = controller_payload_copy[1 + (9 * chan) + 1];
+ u8 b2 = controller_payload_copy[1 + (9 * chan) + 2];
+
+ if (b1 & (1 << 0)) pad->button |= PAD_BUTTON_A;
+ if (b1 & (1 << 1)) pad->button |= PAD_BUTTON_B;
+ if (b1 & (1 << 2)) pad->button |= PAD_BUTTON_X;
+ if (b1 & (1 << 3)) pad->button |= PAD_BUTTON_Y;
+
+ if (b1 & (1 << 4)) pad->button |= PAD_BUTTON_LEFT;
+ if (b1 & (1 << 5)) pad->button |= PAD_BUTTON_RIGHT;
+ if (b1 & (1 << 6)) pad->button |= PAD_BUTTON_DOWN;
+ if (b1 & (1 << 7)) pad->button |= PAD_BUTTON_UP;
+
+ if (b2 & (1 << 0)) pad->button |= PAD_BUTTON_START;
+ if (b2 & (1 << 1)) pad->button |= PAD_TRIGGER_Z;
+ if (b2 & (1 << 2)) pad->button |= PAD_TRIGGER_R;
+ if (b2 & (1 << 3)) pad->button |= PAD_TRIGGER_L;
+
+ if (get_origin) pad->button |= PAD_GET_ORIGIN;
+
+ pad->stickX = controller_payload_copy[1 + (9 * chan) + 3];
+ pad->stickY = controller_payload_copy[1 + (9 * chan) + 4];
+ pad->substickX = controller_payload_copy[1 + (9 * chan) + 5];
+ pad->substickY = controller_payload_copy[1 + (9 * chan) + 6];
+ pad->triggerLeft = controller_payload_copy[1 + (9 * chan) + 7];
+ pad->triggerRight = controller_payload_copy[1 + (9 * chan) + 8];
+ }
+ else
+ {
+ pad->button = PAD_ERR_STATUS;
+ }
+ }
+}
+
+void Output(int chan, u8 rumble_command)
+{
+ if (!UseAdapter() || !s_detected || !s_fd)
+ return;
+
+ // Skip over rumble commands if it has not changed or the controller is wireless
+ if (rumble_command != s_controller_rumble[chan] && s_controller_type[chan] != ControllerTypes::CONTROLLER_WIRELESS)
+ {
+ s_controller_rumble[chan] = rumble_command;
+ unsigned char rumble[5] = { 0x11, s_controller_rumble[0], s_controller_rumble[1], s_controller_rumble[2], s_controller_rumble[3] };
+ {
+ std::lock_guard<std::mutex> lk(s_write_mutex);
+ memcpy(s_controller_write_payload, rumble, 5);
+ }
+ s_write_happened.Set();
+ }
+}
+
+bool IsDetected() { return s_detected; }
+bool IsDriverDetected() { return true; }
+bool DeviceConnected(int chan)
+{
+ return s_controller_type[chan] != ControllerTypes::CONTROLLER_NONE;
+}
+
+bool UseAdapter()
+{
+ return SConfig::GetInstance().m_SIDevice[0] == SIDEVICE_WIIU_ADAPTER ||
+ SConfig::GetInstance().m_SIDevice[1] == SIDEVICE_WIIU_ADAPTER ||
+ SConfig::GetInstance().m_SIDevice[2] == SIDEVICE_WIIU_ADAPTER ||
+ SConfig::GetInstance().m_SIDevice[3] == SIDEVICE_WIIU_ADAPTER;
+}
+
+void ResetRumble()
+{
+ unsigned char rumble[5] = {0x11, 0, 0, 0, 0};
+ {
+ std::lock_guard<std::mutex> lk(s_read_mutex);
+ memcpy(s_controller_write_payload, rumble, 5);
+ }
+ s_write_happened.Set();
+}
+
+void SetAdapterCallback(std::function<void(void)> func) { }
+
+} // end of namespace GCAdapter
diff --git a/Source/Core/InputCommon/GCAdapter_Null.cpp b/Source/Core/InputCommon/GCAdapter_Null.cpp
new file mode 100644
index 0000000000..0936eb33f1
--- /dev/null
+++ b/Source/Core/InputCommon/GCAdapter_Null.cpp
@@ -0,0 +1,23 @@
+// Copyright 2014 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "InputCommon/GCAdapter.h"
+namespace GCAdapter
+{
+void Init() {}
+void Reset() {}
+void ResetRumble() {}
+void Setup() {}
+void Shutdown() {}
+void SetAdapterCallback(std::function<void(void)> func) {}
+void StartScanThread() {}
+void StopScanThread() {}
+void Input(int chan, GCPadStatus* pad) {}
+void Output(int chan, u8 rumble_command) {}
+bool IsDetected() { return false; }
+bool IsDriverDetected() { return false; }
+bool DeviceConnected(int chan) { return false; }
+bool UseAdapter() { return false; }
+
+} // end of namespace GCAdapter
diff --git a/Source/Core/InputCommon/GCPadStatus.h b/Source/Core/InputCommon/GCPadStatus.h
index d6bb972de1..deecb30523 100644
--- a/Source/Core/InputCommon/GCPadStatus.h
+++ b/Source/Core/InputCommon/GCPadStatus.h
@@ -17,6 +17,8 @@ enum PadError
enum
{
PAD_USE_ORIGIN = 0x0080,
+ PAD_GET_ORIGIN = 0x2000,
+ PAD_ERR_STATUS = 0x8000,
};
enum PadButton
diff --git a/Source/Core/InputCommon/InputCommon.vcxproj b/Source/Core/InputCommon/InputCommon.vcxproj
index 347c06e770..3e63243949 100644
--- a/Source/Core/InputCommon/InputCommon.vcxproj
+++ b/Source/Core/InputCommon/InputCommon.vcxproj
@@ -52,6 +52,13 @@
<ClCompile Include="ControllerInterface\ExpressionParser.cpp" />
<ClCompile Include="ControllerInterface\ForceFeedback\ForceFeedbackDevice.cpp" />
<ClCompile Include="ControllerInterface\XInput\XInput.cpp" />
+ <ClCompile Include="GCAdapter.cpp">
+ <!--
+ Disable "nonstandard extension used : zero-sized array in struct/union" warning,
+ which is hit in libusb.h.
+ -->
+ <DisableSpecificWarnings>4200;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
<ClCompile Include="InputConfig.cpp" />
</ItemGroup>
<ItemGroup>
@@ -66,6 +73,7 @@
<ClInclude Include="ControllerInterface\ExpressionParser.h" />
<ClInclude Include="ControllerInterface\ForceFeedback\ForceFeedbackDevice.h" />
<ClInclude Include="ControllerInterface\XInput\XInput.h" />
+ <ClInclude Include="GCAdapter.h" />
<ClInclude Include="GCPadStatus.h" />
<ClInclude Include="InputConfig.h" />
</ItemGroup>
@@ -80,4 +88,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/Source/Core/InputCommon/InputCommon.vcxproj.filters b/Source/Core/InputCommon/InputCommon.vcxproj.filters
index 3c16ad5f26..6a63852303 100644
--- a/Source/Core/InputCommon/InputCommon.vcxproj.filters
+++ b/Source/Core/InputCommon/InputCommon.vcxproj.filters
@@ -16,6 +16,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="ControllerEmu.cpp" />
+ <ClCompile Include="GCAdapter.cpp" />
<ClCompile Include="InputConfig.cpp" />
<ClCompile Include="ControllerInterface\DInput\DInput.cpp">
<Filter>ControllerInterface\DInput</Filter>
@@ -47,6 +48,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="ControllerEmu.h" />
+ <ClCompile Include="GCAdapter.h" />
<ClInclude Include="GCPadStatus.h" />
<ClInclude Include="InputConfig.h" />
<ClInclude Include="ControllerInterface\DInput\DInput.h">
@@ -83,4 +85,4 @@
<ItemGroup>
<Text Include="CMakeLists.txt" />
</ItemGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/Source/Core/UICommon/UICommon.cpp b/Source/Core/UICommon/UICommon.cpp
index 5ba825f5e2..10e00584a2 100644
--- a/Source/Core/UICommon/UICommon.cpp
+++ b/Source/Core/UICommon/UICommon.cpp
@@ -11,11 +11,10 @@
#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 "InputCommon/GCAdapter.h"
+
#include "UICommon/UICommon.h"
#include "VideoCommon/VideoBackendBase.h"
@@ -29,9 +28,7 @@ void Init()
SConfig::Init();
VideoBackend::PopulateList();
WiimoteReal::LoadSettings();
-#if defined(__LIBUSB__) || defined (_WIN32)
- SI_GCAdapter::Init();
-#endif
+ GCAdapter::Init();
VideoBackend::ActivateBackend(SConfig::GetInstance().m_strVideoBackend);
SetEnableAlert(SConfig::GetInstance().bUsePanicHandlers);
@@ -39,9 +36,7 @@ void Init()
void Shutdown()
{
-#if defined(__LIBUSB__) || defined (_WIN32)
- SI_GCAdapter::Shutdown();
-#endif
+ GCAdapter::Shutdown();
WiimoteReal::Shutdown();
VideoBackend::ClearList();
SConfig::Shutdown();