summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/GCAdapter.cpp
diff options
context:
space:
mode:
authorRyan Houdek <Sonicadvance1@gmail.com>2015-12-31 11:09:47 -0600
committerRyan Houdek <Sonicadvance1@gmail.com>2016-01-05 13:44:37 -0600
commit49410576e945ba7bf762b83a474005f1babc5b54 (patch)
treeca7f2ad240e8059db6d7ee5e6372efd31245e30a /Source/Core/InputCommon/GCAdapter.cpp
parent6e932af8312650a7373630742776979440bebb9c (diff)
Make the Wii U Gamecube adapter work with less magic.
The Wii U Gamecube controller adapter setup has always been a bit weird. It tries to be as automatic as possible to make the user experience as easy as possible. The problem with this approach is that it brings a large disconnect in the user experience because you have the Gamecube controller setup with regular gamepads and then for some reason below that you have a "direct connect" option which will cause the Gamecube Adapter to overwrite the regular inputs if something was connected. While this works and allows the user to only click one checkbox to get the device working, it breaks the user's experience because they don't really know what "direct connect" means and won't look it up to figure out what it is. Just expecting the device to work (At least one occurence of this in the IRC channel in the last week). This way around also had the terrible nature of making the code more filthy than it needed to be. The GCAdapter namespace was parasitic and hooked in to the regular GC Controller SI class to overwrite the data that it was getting from the default configuration. Now instead we have a specific SIDevice class for the Wii U Gamecube adapter. This class is fairly simple and is a child of the regular SI Gamecube Pad device and only reimplements what it needs to. This also gives the ability to configure controllers individually, which allows the user to configure rumble individually per pad input. Overall the code is cleaner, and it fits more in line with how the rest of Dolphin works.
Diffstat (limited to 'Source/Core/InputCommon/GCAdapter.cpp')
-rw-r--r--Source/Core/InputCommon/GCAdapter.cpp48
1 files changed, 40 insertions, 8 deletions
diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp
index b6b12bcfdb..d357952f4f 100644
--- a/Source/Core/InputCommon/GCAdapter.cpp
+++ b/Source/Core/InputCommon/GCAdapter.cpp
@@ -8,15 +8,17 @@
#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
+namespace GCAdapter
{
enum ControllerTypes
{
@@ -158,13 +160,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);
}
@@ -351,7 +356,11 @@ void Reset()
void Input(int chan, GCPadStatus* pad)
{
- if (!SConfig::GetInstance().m_GameCubeAdapter)
+ bool use_adapter = 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;
+ if (!use_adapter)
return;
if (s_handle == nullptr || !s_detected)
@@ -371,15 +380,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)
+ {
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;
+ memset(pad, 0, sizeof(*pad));
if (s_controller_type[chan] != 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 +411,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 +420,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] != 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,7 +459,7 @@ 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)
return;
// Skip over rumble commands if it has not changed or the controller is wireless
@@ -458,4 +490,4 @@ bool IsDriverDetected()
return !s_libusb_driver_not_supported;
}
-} // end of namespace SI_GCAdapter
+} // end of namespace GCAdapter