mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-26 15:55:31 +01:00
Merge pull request #3455 from Sonicadvance1/GC_adapter_android
[Android] Add support for the Wii U Gamecube adapter under Android.
This commit is contained in:
commit
342496563d
@ -0,0 +1,91 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.utils;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.hardware.usb.UsbConfiguration;
|
||||||
|
import android.hardware.usb.UsbConstants;
|
||||||
|
import android.hardware.usb.UsbDevice;
|
||||||
|
import android.hardware.usb.UsbDeviceConnection;
|
||||||
|
import android.hardware.usb.UsbEndpoint;
|
||||||
|
import android.hardware.usb.UsbInterface;
|
||||||
|
import android.hardware.usb.UsbManager;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
public class Java_GCAdapter {
|
||||||
|
public static UsbManager manager;
|
||||||
|
public static Activity our_activity;
|
||||||
|
static byte[] controller_payload = new byte[37];
|
||||||
|
static byte HasRead;
|
||||||
|
|
||||||
|
static UsbDeviceConnection usb_con;
|
||||||
|
static UsbInterface usb_intf;
|
||||||
|
static UsbEndpoint usb_in;
|
||||||
|
static UsbEndpoint usb_out;
|
||||||
|
|
||||||
|
public static void Shutdown()
|
||||||
|
{
|
||||||
|
usb_con.close();
|
||||||
|
}
|
||||||
|
public static int GetFD() { return usb_con.getFileDescriptor(); }
|
||||||
|
|
||||||
|
public static boolean QueryAdapter()
|
||||||
|
{
|
||||||
|
HashMap<String, UsbDevice> devices = manager.getDeviceList();
|
||||||
|
Iterator it = devices.entrySet().iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
HashMap.Entry pair = (HashMap.Entry) it.next();
|
||||||
|
UsbDevice dev = (UsbDevice) pair.getValue();
|
||||||
|
if (dev.getProductId() == 0x0337 && dev.getVendorId() == 0x057e)
|
||||||
|
if (manager.hasPermission(dev))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InitAdapter()
|
||||||
|
{
|
||||||
|
byte[] init = { 0x13 };
|
||||||
|
usb_con.bulkTransfer(usb_in, init, init.length, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int Input() {
|
||||||
|
int read = usb_con.bulkTransfer(usb_in, controller_payload, controller_payload.length, 16);
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int Output(byte[] rumble) {
|
||||||
|
int size = usb_con.bulkTransfer(usb_out, rumble, 5, 16);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OpenAdapter()
|
||||||
|
{
|
||||||
|
HashMap<String, UsbDevice> devices = manager.getDeviceList();
|
||||||
|
Iterator it = devices.entrySet().iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
HashMap.Entry pair = (HashMap.Entry)it.next();
|
||||||
|
UsbDevice dev = (UsbDevice)pair.getValue();
|
||||||
|
if (dev.getProductId() == 0x0337 && dev.getVendorId() == 0x057e) {
|
||||||
|
if (manager.hasPermission(dev))
|
||||||
|
{
|
||||||
|
usb_con = manager.openDevice(dev);
|
||||||
|
UsbConfiguration conf = dev.getConfiguration(0);
|
||||||
|
usb_intf = conf.getInterface(0);
|
||||||
|
usb_con.claimInterface(usb_intf, true);
|
||||||
|
for (int i = 0; i < usb_intf.getEndpointCount(); ++i)
|
||||||
|
if (usb_intf.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN)
|
||||||
|
usb_in = usb_intf.getEndpoint(i);
|
||||||
|
else
|
||||||
|
usb_out = usb_intf.getEndpoint(i);
|
||||||
|
|
||||||
|
InitAdapter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -113,6 +113,7 @@ set(SRCS ActionReplay.cpp
|
|||||||
HW/SI_Device.cpp
|
HW/SI_Device.cpp
|
||||||
HW/SI_DeviceDanceMat.cpp
|
HW/SI_DeviceDanceMat.cpp
|
||||||
HW/SI_DeviceGBA.cpp
|
HW/SI_DeviceGBA.cpp
|
||||||
|
HW/SI_DeviceGCAdapter.cpp
|
||||||
HW/SI_DeviceGCController.cpp
|
HW/SI_DeviceGCController.cpp
|
||||||
HW/SI_DeviceGCSteeringWheel.cpp
|
HW/SI_DeviceGCSteeringWheel.cpp
|
||||||
HW/SI_DeviceKeyboard.cpp
|
HW/SI_DeviceKeyboard.cpp
|
||||||
@ -239,8 +240,7 @@ set(LIBS
|
|||||||
if(LIBUSB_FOUND)
|
if(LIBUSB_FOUND)
|
||||||
# Using shared LibUSB
|
# Using shared LibUSB
|
||||||
set(LIBS ${LIBS} ${LIBUSB_LIBRARIES})
|
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)
|
endif(LIBUSB_FOUND)
|
||||||
|
|
||||||
set(LIBS ${LIBS} ${MBEDTLS_LIBRARIES})
|
set(LIBS ${LIBS} ${MBEDTLS_LIBRARIES})
|
||||||
|
@ -254,6 +254,8 @@ void SConfig::SaveCoreSettings(IniFile& ini)
|
|||||||
for (int i = 0; i < MAX_SI_CHANNELS; ++i)
|
for (int i = 0; i < MAX_SI_CHANNELS; ++i)
|
||||||
{
|
{
|
||||||
core->Set(StringFromFormat("SIDevice%i", i), m_SIDevice[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("WiiSDCard", m_WiiSDCard);
|
||||||
core->Set("WiiKeyboard", m_WiiKeyboard);
|
core->Set("WiiKeyboard", m_WiiKeyboard);
|
||||||
@ -267,8 +269,6 @@ void SConfig::SaveCoreSettings(IniFile& ini)
|
|||||||
core->Set("OverclockEnable", m_OCEnable);
|
core->Set("OverclockEnable", m_OCEnable);
|
||||||
core->Set("GFXBackend", m_strVideoBackend);
|
core->Set("GFXBackend", m_strVideoBackend);
|
||||||
core->Set("GPUDeterminismMode", m_strGPUDeterminismMode);
|
core->Set("GPUDeterminismMode", m_strGPUDeterminismMode);
|
||||||
core->Set("GameCubeAdapter", m_GameCubeAdapter);
|
|
||||||
core->Set("AdapterRumble", m_AdapterRumble);
|
|
||||||
core->Set("PerfMapDir", m_perfDir);
|
core->Set("PerfMapDir", m_perfDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,6 +509,8 @@ void SConfig::LoadCoreSettings(IniFile& ini)
|
|||||||
for (int i = 0; i < MAX_SI_CHANNELS; ++i)
|
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("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("WiiSDCard", &m_WiiSDCard, false);
|
||||||
core->Get("WiiKeyboard", &m_WiiKeyboard, false);
|
core->Get("WiiKeyboard", &m_WiiKeyboard, false);
|
||||||
@ -532,8 +534,6 @@ void SConfig::LoadCoreSettings(IniFile& ini)
|
|||||||
core->Get("FrameSkip", &m_FrameSkip, 0);
|
core->Get("FrameSkip", &m_FrameSkip, 0);
|
||||||
core->Get("GFXBackend", &m_strVideoBackend, "");
|
core->Get("GFXBackend", &m_strVideoBackend, "");
|
||||||
core->Get("GPUDeterminismMode", &m_strGPUDeterminismMode, "auto");
|
core->Get("GPUDeterminismMode", &m_strGPUDeterminismMode, "auto");
|
||||||
core->Get("GameCubeAdapter", &m_GameCubeAdapter, false);
|
|
||||||
core->Get("AdapterRumble", &m_AdapterRumble, true);
|
|
||||||
core->Get("PerfMapDir", &m_perfDir, "");
|
core->Get("PerfMapDir", &m_perfDir, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,8 +264,8 @@ struct SConfig : NonCopyable
|
|||||||
|
|
||||||
// Input settings
|
// Input settings
|
||||||
bool m_BackgroundInput;
|
bool m_BackgroundInput;
|
||||||
bool m_GameCubeAdapter;
|
bool m_AdapterRumble[4];
|
||||||
bool m_AdapterRumble;
|
bool m_AdapterKonga[4];
|
||||||
|
|
||||||
SysConf* m_SYSCONF;
|
SysConf* m_SYSCONF;
|
||||||
|
|
||||||
|
@ -48,9 +48,6 @@
|
|||||||
#include "Core/HW/HW.h"
|
#include "Core/HW/HW.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/HW/ProcessorInterface.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/SystemTimers.h"
|
||||||
#include "Core/HW/VideoInterface.h"
|
#include "Core/HW/VideoInterface.h"
|
||||||
#include "Core/HW/Wiimote.h"
|
#include "Core/HW/Wiimote.h"
|
||||||
@ -65,6 +62,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "DiscIO/FileMonitor.h"
|
#include "DiscIO/FileMonitor.h"
|
||||||
|
#include "InputCommon/GCAdapter.h"
|
||||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||||
#include "VideoCommon/OnScreenDisplay.h"
|
#include "VideoCommon/OnScreenDisplay.h"
|
||||||
#include "VideoCommon/VideoBackendBase.h"
|
#include "VideoCommon/VideoBackendBase.h"
|
||||||
@ -285,7 +283,7 @@ void Stop() // - Hammertime!
|
|||||||
g_video_backend->Video_ExitLoop();
|
g_video_backend->Video_ExitLoop();
|
||||||
}
|
}
|
||||||
#if defined(__LIBUSB__) || defined(_WIN32)
|
#if defined(__LIBUSB__) || defined(_WIN32)
|
||||||
SI_GCAdapter::ResetRumble();
|
GCAdapter::ResetRumble();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_MEMORYWATCHER
|
#ifdef USE_MEMORYWATCHER
|
||||||
@ -630,7 +628,7 @@ void SetState(EState _State)
|
|||||||
CPU::EnableStepping(true); // Break
|
CPU::EnableStepping(true); // Break
|
||||||
Wiimote::Pause();
|
Wiimote::Pause();
|
||||||
#if defined(__LIBUSB__) || defined(_WIN32)
|
#if defined(__LIBUSB__) || defined(_WIN32)
|
||||||
SI_GCAdapter::ResetRumble();
|
GCAdapter::ResetRumble();
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case CORE_RUN:
|
case CORE_RUN:
|
||||||
@ -741,7 +739,7 @@ bool PauseAndLock(bool doLock, bool unpauseOnUnlock)
|
|||||||
g_video_backend->PauseAndLock(doLock, unpauseOnUnlock);
|
g_video_backend->PauseAndLock(doLock, unpauseOnUnlock);
|
||||||
|
|
||||||
#if defined(__LIBUSB__) || defined(_WIN32)
|
#if defined(__LIBUSB__) || defined(_WIN32)
|
||||||
SI_GCAdapter::ResetRumble();
|
GCAdapter::ResetRumble();
|
||||||
#endif
|
#endif
|
||||||
return wasUnpaused;
|
return wasUnpaused;
|
||||||
}
|
}
|
||||||
|
@ -145,16 +145,10 @@
|
|||||||
<ClCompile Include="HW\SI_DeviceAMBaseboard.cpp" />
|
<ClCompile Include="HW\SI_DeviceAMBaseboard.cpp" />
|
||||||
<ClCompile Include="HW\SI_DeviceDanceMat.cpp" />
|
<ClCompile Include="HW\SI_DeviceDanceMat.cpp" />
|
||||||
<ClCompile Include="HW\SI_DeviceGBA.cpp" />
|
<ClCompile Include="HW\SI_DeviceGBA.cpp" />
|
||||||
|
<ClCompile Include="HW\SI_DeviceGCAdapter.cpp" />
|
||||||
<ClCompile Include="HW\SI_DeviceGCController.cpp" />
|
<ClCompile Include="HW\SI_DeviceGCController.cpp" />
|
||||||
<ClCompile Include="HW\SI_DeviceGCSteeringWheel.cpp" />
|
<ClCompile Include="HW\SI_DeviceGCSteeringWheel.cpp" />
|
||||||
<ClCompile Include="HW\SI_DeviceKeyboard.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\Sram.cpp" />
|
||||||
<ClCompile Include="HW\StreamADPCM.cpp" />
|
<ClCompile Include="HW\StreamADPCM.cpp" />
|
||||||
<ClCompile Include="HW\SystemTimers.cpp" />
|
<ClCompile Include="HW\SystemTimers.cpp" />
|
||||||
@ -357,10 +351,10 @@
|
|||||||
<ClInclude Include="HW\SI_DeviceAMBaseboard.h" />
|
<ClInclude Include="HW\SI_DeviceAMBaseboard.h" />
|
||||||
<ClInclude Include="HW\SI_DeviceDanceMat.h" />
|
<ClInclude Include="HW\SI_DeviceDanceMat.h" />
|
||||||
<ClInclude Include="HW\SI_DeviceGBA.h" />
|
<ClInclude Include="HW\SI_DeviceGBA.h" />
|
||||||
|
<ClInclude Include="HW\SI_DeviceGCAdapter.h" />
|
||||||
<ClInclude Include="HW\SI_DeviceGCController.h" />
|
<ClInclude Include="HW\SI_DeviceGCController.h" />
|
||||||
<ClInclude Include="HW\SI_DeviceGCSteeringWheel.h" />
|
<ClInclude Include="HW\SI_DeviceGCSteeringWheel.h" />
|
||||||
<ClInclude Include="HW\SI_DeviceKeyboard.h" />
|
<ClInclude Include="HW\SI_DeviceKeyboard.h" />
|
||||||
<ClInclude Include="HW\SI_GCAdapter.h" />
|
|
||||||
<ClInclude Include="HW\Sram.h" />
|
<ClInclude Include="HW\Sram.h" />
|
||||||
<ClInclude Include="HW\StreamADPCM.h" />
|
<ClInclude Include="HW\StreamADPCM.h" />
|
||||||
<ClInclude Include="HW\SystemTimers.h" />
|
<ClInclude Include="HW\SystemTimers.h" />
|
||||||
|
@ -447,6 +447,9 @@
|
|||||||
<ClCompile Include="HW\SI_DeviceGBA.cpp">
|
<ClCompile Include="HW\SI_DeviceGBA.cpp">
|
||||||
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
|
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="HW\SI_DeviceGCAdapter.cpp">
|
||||||
|
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="HW\SI_DeviceGCController.cpp">
|
<ClCompile Include="HW\SI_DeviceGCController.cpp">
|
||||||
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
|
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -720,9 +723,6 @@
|
|||||||
<ClCompile Include="PowerPC\MMU.cpp">
|
<ClCompile Include="PowerPC\MMU.cpp">
|
||||||
<Filter>PowerPC</Filter>
|
<Filter>PowerPC</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="HW\SI_GCAdapter.cpp">
|
|
||||||
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="PowerPC\JitCommon\JitBackpatch.cpp">
|
<ClCompile Include="PowerPC\JitCommon\JitBackpatch.cpp">
|
||||||
<Filter>PowerPC\JitCommon</Filter>
|
<Filter>PowerPC\JitCommon</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -991,6 +991,9 @@
|
|||||||
<ClInclude Include="HW\SI_DeviceGBA.h">
|
<ClInclude Include="HW\SI_DeviceGBA.h">
|
||||||
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
|
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="HW\SI_DeviceGCAdapter.h">
|
||||||
|
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="HW\SI_DeviceGCController.h">
|
<ClInclude Include="HW\SI_DeviceGCController.h">
|
||||||
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
|
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -1241,9 +1244,6 @@
|
|||||||
<ClInclude Include="HW\GCKeyboard.h">
|
<ClInclude Include="HW\GCKeyboard.h">
|
||||||
<Filter>HW %28Flipper/Hollywood%29\GCKeyboard</Filter>
|
<Filter>HW %28Flipper/Hollywood%29\GCKeyboard</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="HW\SI_GCAdapter.h">
|
|
||||||
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="PowerPC\Jit64Common\Jit64AsmCommon.h">
|
<ClInclude Include="PowerPC\Jit64Common\Jit64AsmCommon.h">
|
||||||
<Filter>PowerPC\Jit64Common</Filter>
|
<Filter>PowerPC\Jit64Common</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "Core/HW/SI_DeviceAMBaseboard.h"
|
#include "Core/HW/SI_DeviceAMBaseboard.h"
|
||||||
#include "Core/HW/SI_DeviceDanceMat.h"
|
#include "Core/HW/SI_DeviceDanceMat.h"
|
||||||
#include "Core/HW/SI_DeviceGBA.h"
|
#include "Core/HW/SI_DeviceGBA.h"
|
||||||
|
#include "Core/HW/SI_DeviceGCAdapter.h"
|
||||||
#include "Core/HW/SI_DeviceGCController.h"
|
#include "Core/HW/SI_DeviceGCController.h"
|
||||||
#include "Core/HW/SI_DeviceGCSteeringWheel.h"
|
#include "Core/HW/SI_DeviceGCSteeringWheel.h"
|
||||||
#include "Core/HW/SI_DeviceKeyboard.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:
|
case SIDEVICE_GC_CONTROLLER:
|
||||||
return std::make_unique<CSIDevice_GCController>(device, port_number);
|
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:
|
case SIDEVICE_DANCEMAT:
|
||||||
return std::make_unique<CSIDevice_DanceMat>(device, port_number);
|
return std::make_unique<CSIDevice_DanceMat>(device, port_number);
|
||||||
|
|
||||||
|
@ -61,7 +61,8 @@ enum SIDevices : int
|
|||||||
SIDEVICE_GC_STEERING,
|
SIDEVICE_GC_STEERING,
|
||||||
SIDEVICE_DANCEMAT,
|
SIDEVICE_DANCEMAT,
|
||||||
SIDEVICE_GC_TARUKONGA,
|
SIDEVICE_GC_TARUKONGA,
|
||||||
SIDEVICE_AM_BASEBOARD
|
SIDEVICE_AM_BASEBOARD,
|
||||||
|
SIDEVICE_WIIU_ADAPTER,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
150
Source/Core/Core/HW/SI_DeviceGCAdapter.cpp
Normal file
150
Source/Core/Core/HW/SI_DeviceGCAdapter.cpp
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
20
Source/Core/Core/HW/SI_DeviceGCAdapter.h
Normal file
20
Source/Core/Core/HW/SI_DeviceGCAdapter.h
Normal file
@ -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;
|
||||||
|
};
|
@ -13,9 +13,6 @@
|
|||||||
#include "Core/HW/SI.h"
|
#include "Core/HW/SI.h"
|
||||||
#include "Core/HW/SI_Device.h"
|
#include "Core/HW/SI_Device.h"
|
||||||
#include "Core/HW/SI_DeviceGCController.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 "Core/HW/SystemTimers.h"
|
||||||
#include "InputCommon/GCPadStatus.h"
|
#include "InputCommon/GCPadStatus.h"
|
||||||
|
|
||||||
@ -119,6 +116,30 @@ int CSIDevice_GCController::RunBuffer(u8* _pBuffer, int _iLength)
|
|||||||
return _iLength;
|
return _iLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSIDevice_GCController::HandleMoviePadStatus(GCPadStatus* PadStatus)
|
||||||
|
{
|
||||||
|
Movie::CallGCInputManip(PadStatus, ISIDevice::m_iDeviceNumber);
|
||||||
|
|
||||||
|
Movie::SetPolledDevice();
|
||||||
|
if (NetPlay_GetInput(ISIDevice::m_iDeviceNumber, PadStatus))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (Movie::IsPlayingInput())
|
||||||
|
{
|
||||||
|
Movie::PlayController(PadStatus, ISIDevice::m_iDeviceNumber);
|
||||||
|
Movie::InputUpdate();
|
||||||
|
}
|
||||||
|
else if (Movie::IsRecordingInput())
|
||||||
|
{
|
||||||
|
Movie::RecordInput(PadStatus, ISIDevice::m_iDeviceNumber);
|
||||||
|
Movie::InputUpdate();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Movie::CheckPadStatus(PadStatus, ISIDevice::m_iDeviceNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GCPadStatus CSIDevice_GCController::GetPadStatus()
|
GCPadStatus CSIDevice_GCController::GetPadStatus()
|
||||||
{
|
{
|
||||||
GCPadStatus PadStatus;
|
GCPadStatus PadStatus;
|
||||||
@ -126,31 +147,7 @@ GCPadStatus CSIDevice_GCController::GetPadStatus()
|
|||||||
|
|
||||||
Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus);
|
Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus);
|
||||||
|
|
||||||
#if defined(__LIBUSB__) || defined (_WIN32)
|
HandleMoviePadStatus(&PadStatus);
|
||||||
SI_GCAdapter::Input(ISIDevice::m_iDeviceNumber, &PadStatus);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Movie::CallGCInputManip(&PadStatus, ISIDevice::m_iDeviceNumber);
|
|
||||||
|
|
||||||
Movie::SetPolledDevice();
|
|
||||||
if (NetPlay_GetInput(ISIDevice::m_iDeviceNumber, &PadStatus))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else if (Movie::IsPlayingInput())
|
|
||||||
{
|
|
||||||
Movie::PlayController(&PadStatus, ISIDevice::m_iDeviceNumber);
|
|
||||||
Movie::InputUpdate();
|
|
||||||
}
|
|
||||||
else if (Movie::IsRecordingInput())
|
|
||||||
{
|
|
||||||
Movie::RecordInput(&PadStatus, ISIDevice::m_iDeviceNumber);
|
|
||||||
Movie::InputUpdate();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
return PadStatus;
|
return PadStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +160,8 @@ GCPadStatus CSIDevice_GCController::GetPadStatus()
|
|||||||
bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
||||||
{
|
{
|
||||||
GCPadStatus PadStatus = GetPadStatus();
|
GCPadStatus PadStatus = GetPadStatus();
|
||||||
|
if (HandleButtonCombos(PadStatus) == COMBO_ORIGIN)
|
||||||
|
PadStatus.button |= PAD_GET_ORIGIN;
|
||||||
|
|
||||||
_Hi = MapPadStatus(PadStatus);
|
_Hi = MapPadStatus(PadStatus);
|
||||||
|
|
||||||
@ -211,7 +210,12 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
|||||||
_Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits
|
_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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,7 +229,7 @@ u32 CSIDevice_GCController::MapPadStatus(const GCPadStatus& pad_status)
|
|||||||
return _Hi;
|
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... :( )
|
// Keep track of the special button combos (embedded in controller hardware... :( )
|
||||||
EButtonCombo tempCombo;
|
EButtonCombo tempCombo;
|
||||||
@ -258,8 +262,11 @@ void CSIDevice_GCController::HandleButtonCombos(const GCPadStatus& pad_status)
|
|||||||
m_Origin.uTrigger_R = pad_status.triggerRight;
|
m_Origin.uTrigger_R = pad_status.triggerRight;
|
||||||
}
|
}
|
||||||
m_LastButtonCombo = COMBO_NONE;
|
m_LastButtonCombo = COMBO_NONE;
|
||||||
|
return tempCombo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return COMBO_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendCommand
|
// 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
|
// get the correct pad number that should rumble locally when using netplay
|
||||||
const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber);
|
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 (numPAD < 4)
|
||||||
{
|
{
|
||||||
if (uType == 1 && uStrength > 2)
|
if (uType == 1 && uStrength > 2)
|
||||||
|
@ -79,6 +79,9 @@ protected:
|
|||||||
// Type of button combo from the last/current poll
|
// Type of button combo from the last/current poll
|
||||||
EButtonCombo m_LastButtonCombo;
|
EButtonCombo m_LastButtonCombo;
|
||||||
|
|
||||||
|
// Set this if we want to simulate the "TaruKonga" DK Bongo controller
|
||||||
|
bool m_simulate_konga = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
@ -98,14 +101,15 @@ public:
|
|||||||
|
|
||||||
virtual GCPadStatus GetPadStatus();
|
virtual GCPadStatus GetPadStatus();
|
||||||
virtual u32 MapPadStatus(const GCPadStatus& pad_status);
|
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
|
// Send and Receive pad input from network
|
||||||
static bool NetPlay_GetInput(u8 numPAD, GCPadStatus* status);
|
static bool NetPlay_GetInput(u8 numPAD, GCPadStatus* status);
|
||||||
static u8 NetPlay_InGamePadToLocalPad(u8 numPAD);
|
static u8 NetPlay_InGamePadToLocalPad(u8 numPAD);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
void Calibrate();
|
void Calibrate();
|
||||||
|
void HandleMoviePadStatus(GCPadStatus* PadStatus);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -113,16 +117,8 @@ private:
|
|||||||
class CSIDevice_TaruKonga : public CSIDevice_GCController
|
class CSIDevice_TaruKonga : public CSIDevice_GCController
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CSIDevice_TaruKonga(SIDevices device, int _iDeviceNumber) : CSIDevice_GCController(device, _iDeviceNumber) { }
|
CSIDevice_TaruKonga(SIDevices device, int _iDeviceNumber) : CSIDevice_GCController(device, _iDeviceNumber)
|
||||||
|
|
||||||
bool GetData(u32& _Hi, u32& _Low) override
|
|
||||||
{
|
{
|
||||||
CSIDevice_GCController::GetData(_Hi, _Low);
|
m_simulate_konga = true;
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -10,6 +10,7 @@ set(GUI_SRCS
|
|||||||
Config/AudioConfigPane.cpp
|
Config/AudioConfigPane.cpp
|
||||||
Config/ConfigMain.cpp
|
Config/ConfigMain.cpp
|
||||||
Config/GameCubeConfigPane.cpp
|
Config/GameCubeConfigPane.cpp
|
||||||
|
Config/GCAdapterConfigDiag.cpp
|
||||||
Config/GeneralConfigPane.cpp
|
Config/GeneralConfigPane.cpp
|
||||||
Config/InterfaceConfigPane.cpp
|
Config/InterfaceConfigPane.cpp
|
||||||
Config/PathConfigPane.cpp
|
Config/PathConfigPane.cpp
|
||||||
|
77
Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp
Normal file
77
Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp
Normal file
@ -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);
|
||||||
|
}
|
40
Source/Core/DolphinWX/Config/GCAdapterConfigDiag.h
Normal file
40
Source/Core/DolphinWX/Config/GCAdapterConfigDiag.h
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
};
|
@ -26,26 +26,24 @@
|
|||||||
#include "Core/HW/GCKeyboard.h"
|
#include "Core/HW/GCKeyboard.h"
|
||||||
#include "Core/HW/GCPad.h"
|
#include "Core/HW/GCPad.h"
|
||||||
#include "Core/HW/SI.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/Wiimote.h"
|
||||||
#include "Core/HW/WiimoteReal/WiimoteReal.h"
|
#include "Core/HW/WiimoteReal/WiimoteReal.h"
|
||||||
#include "DolphinWX/ControllerConfigDiag.h"
|
#include "DolphinWX/ControllerConfigDiag.h"
|
||||||
#include "DolphinWX/InputConfigDiag.h"
|
#include "DolphinWX/InputConfigDiag.h"
|
||||||
|
#include "DolphinWX/Config/GCAdapterConfigDiag.h"
|
||||||
|
#include "InputCommon/GCAdapter.h"
|
||||||
|
|
||||||
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
||||||
#include "DolphinWX/X11Utils.h"
|
#include "DolphinWX/X11Utils.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wxDEFINE_EVENT(wxEVT_ADAPTER_UPDATE, wxCommandEvent);
|
|
||||||
|
|
||||||
ControllerConfigDiag::ControllerConfigDiag(wxWindow* const parent)
|
ControllerConfigDiag::ControllerConfigDiag(wxWindow* const parent)
|
||||||
: wxDialog(parent, wxID_ANY, _("Dolphin Controller Configuration"))
|
: wxDialog(parent, wxID_ANY, _("Dolphin Controller Configuration"))
|
||||||
{
|
{
|
||||||
m_gc_pad_type_strs = {{
|
m_gc_pad_type_strs = {{
|
||||||
_("None"),
|
_("None"),
|
||||||
_("Standard Controller"),
|
_("Standard Controller"),
|
||||||
|
_("GameCube Adapter for Wii U"),
|
||||||
_("Steering Wheel"),
|
_("Steering Wheel"),
|
||||||
_("Dance Mat"),
|
_("Dance Mat"),
|
||||||
_("TaruKonga (Bongos)"),
|
_("TaruKonga (Bongos)"),
|
||||||
@ -70,7 +68,6 @@ ControllerConfigDiag::ControllerConfigDiag(wxWindow* const parent)
|
|||||||
SetLayoutAdaptationMode(wxDIALOG_ADAPTATION_MODE_ENABLED);
|
SetLayoutAdaptationMode(wxDIALOG_ADAPTATION_MODE_ENABLED);
|
||||||
SetSizerAndFit(main_sizer);
|
SetSizerAndFit(main_sizer);
|
||||||
Center();
|
Center();
|
||||||
Bind(wxEVT_ADAPTER_UPDATE, &ControllerConfigDiag::UpdateAdapter, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer()
|
wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer()
|
||||||
@ -113,24 +110,27 @@ wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer()
|
|||||||
case SIDEVICE_GC_CONTROLLER:
|
case SIDEVICE_GC_CONTROLLER:
|
||||||
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[1]);
|
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[1]);
|
||||||
break;
|
break;
|
||||||
case SIDEVICE_GC_STEERING:
|
case SIDEVICE_WIIU_ADAPTER:
|
||||||
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[2]);
|
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[2]);
|
||||||
break;
|
break;
|
||||||
case SIDEVICE_DANCEMAT:
|
case SIDEVICE_GC_STEERING:
|
||||||
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[3]);
|
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[3]);
|
||||||
break;
|
break;
|
||||||
case SIDEVICE_GC_TARUKONGA:
|
case SIDEVICE_DANCEMAT:
|
||||||
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[4]);
|
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[4]);
|
||||||
break;
|
break;
|
||||||
case SIDEVICE_GC_GBA:
|
case SIDEVICE_GC_TARUKONGA:
|
||||||
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[5]);
|
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();
|
gamecube_configure_bt[i]->Disable();
|
||||||
break;
|
break;
|
||||||
case SIDEVICE_GC_KEYBOARD:
|
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;
|
break;
|
||||||
case SIDEVICE_AM_BASEBOARD:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[0]);
|
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->Add(gamecube_flex_sizer, 1, wxEXPAND, 5);
|
||||||
gamecube_static_sizer->AddSpacer(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;
|
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()
|
wxStaticBoxSizer* ControllerConfigDiag::CreateWiimoteConfigSizer()
|
||||||
{
|
{
|
||||||
wxStaticText* wiimote_label[4];
|
wxStaticText* wiimote_label[4];
|
||||||
@ -504,30 +446,35 @@ void ControllerConfigDiag::OnGameCubePortChanged(wxCommandEvent& event)
|
|||||||
}
|
}
|
||||||
else if (device_name == m_gc_pad_type_strs[2])
|
else if (device_name == m_gc_pad_type_strs[2])
|
||||||
{
|
{
|
||||||
tempType = SIDEVICE_GC_STEERING;
|
tempType = SIDEVICE_WIIU_ADAPTER;
|
||||||
gamecube_configure_bt[device_num]->Enable();
|
gamecube_configure_bt[device_num]->Enable();
|
||||||
}
|
}
|
||||||
else if (device_name == m_gc_pad_type_strs[3])
|
else if (device_name == m_gc_pad_type_strs[3])
|
||||||
{
|
{
|
||||||
tempType = SIDEVICE_DANCEMAT;
|
tempType = SIDEVICE_GC_STEERING;
|
||||||
gamecube_configure_bt[device_num]->Enable();
|
gamecube_configure_bt[device_num]->Enable();
|
||||||
}
|
}
|
||||||
else if (device_name == m_gc_pad_type_strs[4])
|
else if (device_name == m_gc_pad_type_strs[4])
|
||||||
{
|
{
|
||||||
tempType = SIDEVICE_GC_TARUKONGA;
|
tempType = SIDEVICE_DANCEMAT;
|
||||||
gamecube_configure_bt[device_num]->Enable();
|
gamecube_configure_bt[device_num]->Enable();
|
||||||
}
|
}
|
||||||
else if (device_name == m_gc_pad_type_strs[5])
|
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;
|
tempType = SIDEVICE_GC_GBA;
|
||||||
gamecube_configure_bt[device_num]->Disable();
|
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;
|
tempType = SIDEVICE_GC_KEYBOARD;
|
||||||
gamecube_configure_bt[device_num]->Enable();
|
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;
|
tempType = SIDEVICE_AM_BASEBOARD;
|
||||||
gamecube_configure_bt[device_num]->Enable();
|
gamecube_configure_bt[device_num]->Enable();
|
||||||
@ -540,6 +487,11 @@ void ControllerConfigDiag::OnGameCubePortChanged(wxCommandEvent& event)
|
|||||||
|
|
||||||
SConfig::GetInstance().m_SIDevice[device_num] = tempType;
|
SConfig::GetInstance().m_SIDevice[device_num] = tempType;
|
||||||
|
|
||||||
|
if (GCAdapter::UseAdapter())
|
||||||
|
GCAdapter::StartScanThread();
|
||||||
|
else
|
||||||
|
GCAdapter::StopScanThread();
|
||||||
|
|
||||||
if (Core::IsRunning())
|
if (Core::IsRunning())
|
||||||
SerialInterface::ChangeDevice(tempType, device_num);
|
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);
|
InputConfigDialog m_ConfigFrame(this, *key_plugin, _("GameCube Controller Configuration"), port_num);
|
||||||
m_ConfigFrame.ShowModal();
|
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
|
else
|
||||||
{
|
{
|
||||||
InputConfigDialog m_ConfigFrame(this, *pad_plugin, _("GameCube Controller Configuration"), port_num);
|
InputConfigDialog m_ConfigFrame(this, *pad_plugin, _("GameCube Controller Configuration"), port_num);
|
||||||
@ -565,10 +522,3 @@ void ControllerConfigDiag::OnGameCubeConfigButton(wxCommandEvent& event)
|
|||||||
|
|
||||||
HotkeyManagerEmu::Enable(true);
|
HotkeyManagerEmu::Enable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerConfigDiag::~ControllerConfigDiag()
|
|
||||||
{
|
|
||||||
#if defined(__LIBUSB__) || defined (_WIN32)
|
|
||||||
SI_GCAdapter::SetAdapterCallback(nullptr);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
#include "Common/SysConf.h"
|
#include "Common/SysConf.h"
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
#include "Core/HW/SI_GCAdapter.h"
|
|
||||||
#include "Core/HW/Wiimote.h"
|
#include "Core/HW/Wiimote.h"
|
||||||
|
#include "InputCommon/GCAdapter.h"
|
||||||
|
|
||||||
class InputConfig;
|
class InputConfig;
|
||||||
class wxButton;
|
class wxButton;
|
||||||
@ -21,7 +21,6 @@ class ControllerConfigDiag : public wxDialog
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ControllerConfigDiag(wxWindow* const parent);
|
ControllerConfigDiag(wxWindow* const parent);
|
||||||
~ControllerConfigDiag();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RefreshRealWiimotes(wxCommandEvent& event);
|
void RefreshRealWiimotes(wxCommandEvent& event);
|
||||||
@ -70,23 +69,6 @@ private:
|
|||||||
event.Skip();
|
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* CreateGamecubeSizer();
|
||||||
wxStaticBoxSizer* CreateWiimoteConfigSizer();
|
wxStaticBoxSizer* CreateWiimoteConfigSizer();
|
||||||
wxStaticBoxSizer* CreateBalanceBoardSizer();
|
wxStaticBoxSizer* CreateBalanceBoardSizer();
|
||||||
@ -96,17 +78,14 @@ private:
|
|||||||
void Cancel(wxCommandEvent& event);
|
void Cancel(wxCommandEvent& event);
|
||||||
void OnGameCubePortChanged(wxCommandEvent& event);
|
void OnGameCubePortChanged(wxCommandEvent& event);
|
||||||
void OnGameCubeConfigButton(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_choice_ids;
|
||||||
std::map<wxWindowID, unsigned int> m_gc_port_config_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;
|
std::map<wxWindowID, unsigned int> m_wiimote_index_from_ctrl_id;
|
||||||
unsigned int m_orig_wiimote_sources[MAX_BBMOTES];
|
unsigned int m_orig_wiimote_sources[MAX_BBMOTES];
|
||||||
|
|
||||||
wxStaticText* m_adapter_status;
|
|
||||||
wxButton* wiimote_configure_bt[MAX_WIIMOTES];
|
wxButton* wiimote_configure_bt[MAX_WIIMOTES];
|
||||||
wxButton* gamecube_configure_bt[4];
|
wxButton* gamecube_configure_bt[4];
|
||||||
std::map<wxWindowID, unsigned int> m_wiimote_index_from_conf_bt_id;
|
std::map<wxWindowID, unsigned int> m_wiimote_index_from_conf_bt_id;
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
<ClCompile Include="Config\AudioConfigPane.cpp" />
|
<ClCompile Include="Config\AudioConfigPane.cpp" />
|
||||||
<ClCompile Include="Config\ConfigMain.cpp" />
|
<ClCompile Include="Config\ConfigMain.cpp" />
|
||||||
<ClCompile Include="Config\GameCubeConfigPane.cpp" />
|
<ClCompile Include="Config\GameCubeConfigPane.cpp" />
|
||||||
|
<ClCompile Include="Config\GCAdapterConfigDiag.cpp" />
|
||||||
<ClCompile Include="Config\GeneralConfigPane.cpp" />
|
<ClCompile Include="Config\GeneralConfigPane.cpp" />
|
||||||
<ClCompile Include="Config\InterfaceConfigPane.cpp" />
|
<ClCompile Include="Config\InterfaceConfigPane.cpp" />
|
||||||
<ClCompile Include="Config\PathConfigPane.cpp" />
|
<ClCompile Include="Config\PathConfigPane.cpp" />
|
||||||
@ -113,6 +114,7 @@
|
|||||||
<ClInclude Include="Config\AdvancedConfigPane.h" />
|
<ClInclude Include="Config\AdvancedConfigPane.h" />
|
||||||
<ClInclude Include="Config\AudioConfigPane.h" />
|
<ClInclude Include="Config\AudioConfigPane.h" />
|
||||||
<ClInclude Include="Config\GameCubeConfigPane.h" />
|
<ClInclude Include="Config\GameCubeConfigPane.h" />
|
||||||
|
<ClInclude Include="Config\GCAdapterConfigDiag.h" />
|
||||||
<ClInclude Include="Config\GeneralConfigPane.h" />
|
<ClInclude Include="Config\GeneralConfigPane.h" />
|
||||||
<ClInclude Include="Config\InterfaceConfigPane.h" />
|
<ClInclude Include="Config\InterfaceConfigPane.h" />
|
||||||
<ClInclude Include="Config\PathConfigPane.h" />
|
<ClInclude Include="Config\PathConfigPane.h" />
|
||||||
@ -246,4 +248,4 @@
|
|||||||
<Message Text="Copy: @(BinaryFiles) -> $(BinaryOutputDir)" Importance="High" />
|
<Message Text="Copy: @(BinaryFiles) -> $(BinaryOutputDir)" Importance="High" />
|
||||||
<Copy SourceFiles="@(BinaryFiles)" DestinationFolder="$(BinaryOutputDir)" />
|
<Copy SourceFiles="@(BinaryFiles)" DestinationFolder="$(BinaryOutputDir)" />
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -178,6 +178,9 @@
|
|||||||
<ClCompile Include="Config\GameCubeConfigPane.cpp">
|
<ClCompile Include="Config\GameCubeConfigPane.cpp">
|
||||||
<Filter>GUI\Config</Filter>
|
<Filter>GUI\Config</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Config\GCAdapterConfigDiag.cpp">
|
||||||
|
<Filter>GUI\Config</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="Config\WiiConfigPane.cpp">
|
<ClCompile Include="Config\WiiConfigPane.cpp">
|
||||||
<Filter>GUI\Config</Filter>
|
<Filter>GUI\Config</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -339,6 +342,9 @@
|
|||||||
<ClInclude Include="Config\GameCubeConfigPane.h">
|
<ClInclude Include="Config\GameCubeConfigPane.h">
|
||||||
<Filter>GUI\Config</Filter>
|
<Filter>GUI\Config</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Config\GCAdapterConfigDiag.h">
|
||||||
|
<Filter>GUI\Config</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="Config\WiiConfigPane.h">
|
<ClInclude Include="Config\WiiConfigPane.h">
|
||||||
<Filter>GUI\Config</Filter>
|
<Filter>GUI\Config</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -369,4 +375,4 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="$(CoreDir)..\..\Installer\Dolphin.ico" />
|
<Image Include="$(CoreDir)..\..\Installer\Dolphin.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -3,8 +3,6 @@ set(SRCS ControllerEmu.cpp
|
|||||||
ControllerInterface/ControllerInterface.cpp
|
ControllerInterface/ControllerInterface.cpp
|
||||||
ControllerInterface/Device.cpp
|
ControllerInterface/Device.cpp
|
||||||
ControllerInterface/ExpressionParser.cpp)
|
ControllerInterface/ExpressionParser.cpp)
|
||||||
|
|
||||||
|
|
||||||
set(LIBS common)
|
set(LIBS common)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
@ -33,10 +31,18 @@ elseif(X11_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
set(LIBS ${LIBS} ${X11_LIBRARIES} ${XINPUT2_LIBRARIES})
|
set(LIBS ${LIBS} ${X11_LIBRARIES} ${XINPUT2_LIBRARIES})
|
||||||
elseif(ANDROID)
|
elseif(ANDROID)
|
||||||
set(SRCS ${SRCS}
|
set(SRCS ${SRCS}
|
||||||
ControllerInterface/Android/Android.cpp)
|
ControllerInterface/Android/Android.cpp)
|
||||||
endif()
|
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)
|
if(LIBEVDEV_FOUND AND LIBUDEV_FOUND)
|
||||||
set(SRCS ${SRCS} ControllerInterface/evdev/evdev.cpp)
|
set(SRCS ${SRCS} ControllerInterface/evdev/evdev.cpp)
|
||||||
set(LIBS ${LIBS} ${LIBEVDEV_LIBRARY} ${LIBUDEV_LIBRARY})
|
set(LIBS ${LIBS} ${LIBEVDEV_LIBRARY} ${LIBUDEV_LIBRARY})
|
||||||
|
@ -8,29 +8,24 @@
|
|||||||
|
|
||||||
#include "Common/Flag.h"
|
#include "Common/Flag.h"
|
||||||
#include "Common/Thread.h"
|
#include "Common/Thread.h"
|
||||||
|
#include "Common/Logging/Log.h"
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/CoreTiming.h"
|
#include "Core/CoreTiming.h"
|
||||||
#include "Core/HW/SI.h"
|
#include "Core/HW/SI.h"
|
||||||
#include "Core/HW/SI_GCAdapter.h"
|
|
||||||
#include "Core/HW/SystemTimers.h"
|
#include "Core/HW/SystemTimers.h"
|
||||||
|
|
||||||
|
#include "InputCommon/GCAdapter.h"
|
||||||
#include "InputCommon/GCPadStatus.h"
|
#include "InputCommon/GCPadStatus.h"
|
||||||
|
|
||||||
namespace SI_GCAdapter
|
namespace GCAdapter
|
||||||
{
|
{
|
||||||
enum ControllerTypes
|
|
||||||
{
|
|
||||||
CONTROLLER_NONE = 0,
|
|
||||||
CONTROLLER_WIRED = 1,
|
|
||||||
CONTROLLER_WIRELESS = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool CheckDeviceAccess(libusb_device* device);
|
static bool CheckDeviceAccess(libusb_device* device);
|
||||||
static void AddGCAdapter(libusb_device* device);
|
static void AddGCAdapter(libusb_device* device);
|
||||||
|
|
||||||
static bool s_detected = false;
|
static bool s_detected = false;
|
||||||
static libusb_device_handle* s_handle = nullptr;
|
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 u8 s_controller_rumble[4];
|
||||||
|
|
||||||
static std::mutex s_mutex;
|
static std::mutex s_mutex;
|
||||||
@ -158,13 +153,16 @@ void Init()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (SConfig::GetInstance().m_GameCubeAdapter)
|
if (UseAdapter())
|
||||||
StartScanThread();
|
StartScanThread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartScanThread()
|
void StartScanThread()
|
||||||
{
|
{
|
||||||
|
if (s_adapter_detect_thread_running.IsSet())
|
||||||
|
return;
|
||||||
|
|
||||||
s_adapter_detect_thread_running.Set(true);
|
s_adapter_detect_thread_running.Set(true);
|
||||||
s_adapter_detect_thread = std::thread(ScanThreadFunc);
|
s_adapter_detect_thread = std::thread(ScanThreadFunc);
|
||||||
}
|
}
|
||||||
@ -184,7 +182,7 @@ void Setup()
|
|||||||
|
|
||||||
for (int i = 0; i < MAX_SI_CHANNELS; i++)
|
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;
|
s_controller_rumble[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,7 +332,7 @@ void Reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < MAX_SI_CHANNELS; i++)
|
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;
|
s_detected = false;
|
||||||
|
|
||||||
@ -351,7 +349,7 @@ void Reset()
|
|||||||
|
|
||||||
void Input(int chan, GCPadStatus* pad)
|
void Input(int chan, GCPadStatus* pad)
|
||||||
{
|
{
|
||||||
if (!SConfig::GetInstance().m_GameCubeAdapter)
|
if (!UseAdapter())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (s_handle == nullptr || !s_detected)
|
if (s_handle == nullptr || !s_detected)
|
||||||
@ -371,15 +369,19 @@ void Input(int chan, GCPadStatus* pad)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
bool get_origin = false;
|
||||||
u8 type = controller_payload_copy[1 + (9 * chan)] >> 4;
|
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)]);
|
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;
|
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 b1 = controller_payload_copy[1 + (9 * chan) + 1];
|
||||||
u8 b2 = controller_payload_copy[1 + (9 * chan) + 2];
|
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 << 2)) pad->button |= PAD_TRIGGER_R;
|
||||||
if (b2 & (1 << 3)) pad->button |= PAD_TRIGGER_L;
|
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->stickX = controller_payload_copy[1 + (9 * chan) + 3];
|
||||||
pad->stickY = controller_payload_copy[1 + (9 * chan) + 4];
|
pad->stickY = controller_payload_copy[1 + (9 * chan) + 4];
|
||||||
pad->substickX = controller_payload_copy[1 + (9 * chan) + 5];
|
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->triggerLeft = controller_payload_copy[1 + (9 * chan) + 7];
|
||||||
pad->triggerRight = controller_payload_copy[1 + (9 * chan) + 8];
|
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()
|
void ResetRumble()
|
||||||
{
|
{
|
||||||
if (!SConfig::GetInstance().m_GameCubeAdapter)
|
if (!UseAdapter())
|
||||||
return;
|
return;
|
||||||
if (s_handle == nullptr || !s_detected)
|
if (s_handle == nullptr || !s_detected)
|
||||||
return;
|
return;
|
||||||
@ -427,11 +448,11 @@ void ResetRumble()
|
|||||||
|
|
||||||
void Output(int chan, u8 rumble_command)
|
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;
|
return;
|
||||||
|
|
||||||
// Skip over rumble commands if it has not changed or the controller is wireless
|
// 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;
|
s_controller_rumble[chan] = rumble_command;
|
||||||
|
|
||||||
@ -458,4 +479,4 @@ bool IsDriverDetected()
|
|||||||
return !s_libusb_driver_not_supported;
|
return !s_libusb_driver_not_supported;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace SI_GCAdapter
|
} // end of namespace GCAdapter
|
@ -8,9 +8,14 @@
|
|||||||
|
|
||||||
struct GCPadStatus;
|
struct GCPadStatus;
|
||||||
|
|
||||||
namespace SI_GCAdapter
|
namespace GCAdapter
|
||||||
{
|
{
|
||||||
|
enum ControllerTypes
|
||||||
|
{
|
||||||
|
CONTROLLER_NONE = 0,
|
||||||
|
CONTROLLER_WIRED = 1,
|
||||||
|
CONTROLLER_WIRELESS = 2
|
||||||
|
};
|
||||||
void Init();
|
void Init();
|
||||||
void Reset();
|
void Reset();
|
||||||
void ResetRumble();
|
void ResetRumble();
|
||||||
@ -23,5 +28,7 @@ void Input(int chan, GCPadStatus* pad);
|
|||||||
void Output(int chan, u8 rumble_command);
|
void Output(int chan, u8 rumble_command);
|
||||||
bool IsDetected();
|
bool IsDetected();
|
||||||
bool IsDriverDetected();
|
bool IsDriverDetected();
|
||||||
|
bool DeviceConnected(int chan);
|
||||||
|
bool UseAdapter();
|
||||||
|
|
||||||
} // end of namespace SI_GCAdapter
|
} // end of namespace GCAdapter
|
353
Source/Core/InputCommon/GCAdapter_Android.cpp
Normal file
353
Source/Core/InputCommon/GCAdapter_Android.cpp
Normal file
@ -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
|
23
Source/Core/InputCommon/GCAdapter_Null.cpp
Normal file
23
Source/Core/InputCommon/GCAdapter_Null.cpp
Normal file
@ -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
|
@ -17,6 +17,8 @@ enum PadError
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PAD_USE_ORIGIN = 0x0080,
|
PAD_USE_ORIGIN = 0x0080,
|
||||||
|
PAD_GET_ORIGIN = 0x2000,
|
||||||
|
PAD_ERR_STATUS = 0x8000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PadButton
|
enum PadButton
|
||||||
|
@ -52,6 +52,13 @@
|
|||||||
<ClCompile Include="ControllerInterface\ExpressionParser.cpp" />
|
<ClCompile Include="ControllerInterface\ExpressionParser.cpp" />
|
||||||
<ClCompile Include="ControllerInterface\ForceFeedback\ForceFeedbackDevice.cpp" />
|
<ClCompile Include="ControllerInterface\ForceFeedback\ForceFeedbackDevice.cpp" />
|
||||||
<ClCompile Include="ControllerInterface\XInput\XInput.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" />
|
<ClCompile Include="InputConfig.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -66,6 +73,7 @@
|
|||||||
<ClInclude Include="ControllerInterface\ExpressionParser.h" />
|
<ClInclude Include="ControllerInterface\ExpressionParser.h" />
|
||||||
<ClInclude Include="ControllerInterface\ForceFeedback\ForceFeedbackDevice.h" />
|
<ClInclude Include="ControllerInterface\ForceFeedback\ForceFeedbackDevice.h" />
|
||||||
<ClInclude Include="ControllerInterface\XInput\XInput.h" />
|
<ClInclude Include="ControllerInterface\XInput\XInput.h" />
|
||||||
|
<ClInclude Include="GCAdapter.h" />
|
||||||
<ClInclude Include="GCPadStatus.h" />
|
<ClInclude Include="GCPadStatus.h" />
|
||||||
<ClInclude Include="InputConfig.h" />
|
<ClInclude Include="InputConfig.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -80,4 +88,4 @@
|
|||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="ControllerEmu.cpp" />
|
<ClCompile Include="ControllerEmu.cpp" />
|
||||||
|
<ClCompile Include="GCAdapter.cpp" />
|
||||||
<ClCompile Include="InputConfig.cpp" />
|
<ClCompile Include="InputConfig.cpp" />
|
||||||
<ClCompile Include="ControllerInterface\DInput\DInput.cpp">
|
<ClCompile Include="ControllerInterface\DInput\DInput.cpp">
|
||||||
<Filter>ControllerInterface\DInput</Filter>
|
<Filter>ControllerInterface\DInput</Filter>
|
||||||
@ -47,6 +48,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="ControllerEmu.h" />
|
<ClInclude Include="ControllerEmu.h" />
|
||||||
|
<ClCompile Include="GCAdapter.h" />
|
||||||
<ClInclude Include="GCPadStatus.h" />
|
<ClInclude Include="GCPadStatus.h" />
|
||||||
<ClInclude Include="InputConfig.h" />
|
<ClInclude Include="InputConfig.h" />
|
||||||
<ClInclude Include="ControllerInterface\DInput\DInput.h">
|
<ClInclude Include="ControllerInterface\DInput\DInput.h">
|
||||||
@ -83,4 +85,4 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Text Include="CMakeLists.txt" />
|
<Text Include="CMakeLists.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -11,11 +11,10 @@
|
|||||||
#include "Common/Logging/LogManager.h"
|
#include "Common/Logging/LogManager.h"
|
||||||
|
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
#if defined(__LIBUSB__) || defined (_WIN32)
|
|
||||||
#include "Core/HW/SI_GCAdapter.h"
|
|
||||||
#endif
|
|
||||||
#include "Core/HW/Wiimote.h"
|
#include "Core/HW/Wiimote.h"
|
||||||
|
|
||||||
|
#include "InputCommon/GCAdapter.h"
|
||||||
|
|
||||||
#include "UICommon/UICommon.h"
|
#include "UICommon/UICommon.h"
|
||||||
|
|
||||||
#include "VideoCommon/VideoBackendBase.h"
|
#include "VideoCommon/VideoBackendBase.h"
|
||||||
@ -29,9 +28,7 @@ void Init()
|
|||||||
SConfig::Init();
|
SConfig::Init();
|
||||||
VideoBackend::PopulateList();
|
VideoBackend::PopulateList();
|
||||||
WiimoteReal::LoadSettings();
|
WiimoteReal::LoadSettings();
|
||||||
#if defined(__LIBUSB__) || defined (_WIN32)
|
GCAdapter::Init();
|
||||||
SI_GCAdapter::Init();
|
|
||||||
#endif
|
|
||||||
VideoBackend::ActivateBackend(SConfig::GetInstance().m_strVideoBackend);
|
VideoBackend::ActivateBackend(SConfig::GetInstance().m_strVideoBackend);
|
||||||
|
|
||||||
SetEnableAlert(SConfig::GetInstance().bUsePanicHandlers);
|
SetEnableAlert(SConfig::GetInstance().bUsePanicHandlers);
|
||||||
@ -39,9 +36,7 @@ void Init()
|
|||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
#if defined(__LIBUSB__) || defined (_WIN32)
|
GCAdapter::Shutdown();
|
||||||
SI_GCAdapter::Shutdown();
|
|
||||||
#endif
|
|
||||||
WiimoteReal::Shutdown();
|
WiimoteReal::Shutdown();
|
||||||
VideoBackend::ClearList();
|
VideoBackend::ClearList();
|
||||||
SConfig::Shutdown();
|
SConfig::Shutdown();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user