Connected LLE USB implementation with the rest of the emulator (untested)
This commit is contained in:
parent
4e7d4a7eda
commit
c18e2f6a38
|
@ -35,8 +35,13 @@
|
|||
// ******************************************************************
|
||||
|
||||
#include "InputConfig.h"
|
||||
#include "..\devices\usb\XidGamepad.h"
|
||||
#include "..\..\CxbxKrnl\EmuKrnl.h" // For EmuWarning
|
||||
#include <thread>
|
||||
|
||||
|
||||
InputDeviceManager* g_InputDeviceManager = nullptr;
|
||||
|
||||
InputDeviceManager::InputDeviceManager()
|
||||
{
|
||||
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) {
|
||||
|
@ -53,6 +58,7 @@ InputDeviceManager::~InputDeviceManager()
|
|||
int InputDeviceManager::EnumSdl2Devices()
|
||||
{
|
||||
int NumOfJoysticks;
|
||||
int NumInvalidJoysticks;
|
||||
SDL2Devices* pDev;
|
||||
SDL_GameController* pController;
|
||||
std::vector<SDL2Devices*>::iterator it;
|
||||
|
@ -60,16 +66,19 @@ int InputDeviceManager::EnumSdl2Devices()
|
|||
NumOfJoysticks = SDL_NumJoysticks();
|
||||
if (NumOfJoysticks < 0) {
|
||||
EmuWarning("Failed to enumerate joysticks. The error was: %s", SDL_GetError());
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
SDL_GameControllerButtonBind;
|
||||
|
||||
NumInvalidJoysticks = 0;
|
||||
|
||||
for (int i = 0; i < NumOfJoysticks; i++) {
|
||||
if (SDL_IsGameController(i)) {
|
||||
pDev = new SDL2Devices();
|
||||
pDev->m_Index = i;
|
||||
m_Sdl2Devices.push_back(pDev);
|
||||
}
|
||||
// this joystick not supported at the moment
|
||||
// this joystick is not supported at the moment
|
||||
NumInvalidJoysticks++;
|
||||
}
|
||||
|
||||
for (it = m_Sdl2Devices.begin(); it != m_Sdl2Devices.end();) {
|
||||
|
@ -78,14 +87,154 @@ int InputDeviceManager::EnumSdl2Devices()
|
|||
EmuWarning("Failed to open game controller %s. The error was %s\n", SDL_GameControllerNameForIndex((*it)->m_Index), SDL_GetError());
|
||||
delete (*it);
|
||||
it = m_Sdl2Devices.erase(it);
|
||||
NumInvalidJoysticks++;
|
||||
}
|
||||
else {
|
||||
printf("Found game controller %s\n", SDL_GameControllerName(pController));
|
||||
(*it)->m_Gamepad = pController;
|
||||
(*it)->m_jyID = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(pController));
|
||||
(*it)->m_Attached = 1;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
return NumOfJoysticks - NumInvalidJoysticks;
|
||||
}
|
||||
|
||||
int InputDeviceManager::ConnectDeviceToXbox(int port, int type)
|
||||
{
|
||||
int ret = -1;
|
||||
std::vector<SDL2Devices*>::iterator it;
|
||||
|
||||
if (port > 4 || port < 1) { return ret; };
|
||||
|
||||
for (it = m_Sdl2Devices.begin(); it != m_Sdl2Devices.end(); ++it) {
|
||||
if ((*it)->m_Index == (port - 1)) {
|
||||
--port;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (it == m_Sdl2Devices.end()) {
|
||||
EmuWarning("Attempted to connect a device not yet enumerated.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MS_CONTROLLER_DUKE: {
|
||||
if (g_HubObjArray[port] == nullptr) {
|
||||
g_HubObjArray[port] = new Hub;
|
||||
ret = g_HubObjArray[port]->Init(port);
|
||||
if (ret) {
|
||||
delete g_HubObjArray[port];
|
||||
g_HubObjArray[port] = nullptr;
|
||||
break;
|
||||
}
|
||||
if (g_XidControllerObjArray[port] == nullptr) {
|
||||
g_XidControllerObjArray[port] = new XidGamepad;
|
||||
ret = g_XidControllerObjArray[port]->Init(port);
|
||||
if (ret) {
|
||||
g_HubObjArray[port]->HubDestroy();
|
||||
delete g_HubObjArray[port];
|
||||
g_HubObjArray[port] = nullptr;
|
||||
delete g_XidControllerObjArray[port];
|
||||
g_XidControllerObjArray[port] = nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = -1;
|
||||
g_HubObjArray[port]->HubDestroy();
|
||||
delete g_HubObjArray[port];
|
||||
g_HubObjArray[port] = nullptr;
|
||||
EmuWarning("Xid controller already present at port %d.2\n", port + 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
EmuWarning("Hub already present at port %d\n", port + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MS_CONTROLLER_S:
|
||||
case LIGHT_GUN:
|
||||
case STEERING_WHEEL:
|
||||
case MEMORY_UNIT:
|
||||
case IR_DONGLE:
|
||||
case STEEL_BATTALION_CONTROLLER: {
|
||||
printf("This device type is not yet supported\n");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
EmuWarning("Attempted to attach an unknown device type\n");
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
(*it)->m_Type = type;
|
||||
(*it)->m_Attached = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void InputDeviceManager::DisconnectDeviceFromXbox(int port)
|
||||
{
|
||||
std::vector<SDL2Devices*>::iterator it;
|
||||
|
||||
if (port < 1) { return; }
|
||||
|
||||
for (it = m_Sdl2Devices.begin(); it != m_Sdl2Devices.end(); ++it) {
|
||||
if ((*it)->m_Index == (port - 1)) {
|
||||
--port;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (it == m_Sdl2Devices.end()) {
|
||||
// Not necessarily a bug. This could also be triggered by detaching an unsupported joystick
|
||||
return;
|
||||
}
|
||||
|
||||
if (port + 1 > 4) {
|
||||
delete (*it);
|
||||
m_Sdl2Devices.erase(it);
|
||||
return;
|
||||
}
|
||||
|
||||
switch ((*it)->m_Type)
|
||||
{
|
||||
case MS_CONTROLLER_DUKE: {
|
||||
if (g_HubObjArray[port] != nullptr && g_XidControllerObjArray[port] != nullptr) {
|
||||
g_HubObjArray[port]->HubDestroy();
|
||||
delete g_HubObjArray[port];
|
||||
g_HubObjArray[port] = nullptr;
|
||||
delete g_XidControllerObjArray[port];
|
||||
g_XidControllerObjArray[port] = nullptr;
|
||||
delete (*it);
|
||||
m_Sdl2Devices.erase(it);
|
||||
// Here, we could also see if there are detached devices that have a matching type and bound buttons, so that it can immediately
|
||||
// be used instead of remaining inactive (example: 5 controllers and 1st is detached -> 5th can be used if it has bindings)
|
||||
}
|
||||
else {
|
||||
EmuWarning("Attempted to disconnect a device not attached to the Xbox.\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MS_CONTROLLER_S:
|
||||
case LIGHT_GUN:
|
||||
case STEERING_WHEEL:
|
||||
case MEMORY_UNIT:
|
||||
case IR_DONGLE:
|
||||
case STEEL_BATTALION_CONTROLLER: {
|
||||
printf("This device type is not yet supported\n");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
EmuWarning("Attempted to detach an unknown device type\n");
|
||||
}
|
||||
}
|
||||
|
||||
void InputDeviceManager::StartInputThread()
|
||||
|
@ -128,6 +277,29 @@ void InputDeviceManager::InputThread(InputDeviceManager* pVoid)
|
|||
break;
|
||||
}
|
||||
|
||||
case SDL_JOYDEVICEADDED: {
|
||||
bool found = false;
|
||||
for (auto dev : pVoid->m_Sdl2Devices) {
|
||||
if (dev->m_Index == event.jdevice.which) {
|
||||
// already enumerated, skipping
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// for now we only support a single controller at port 1, more will be added later
|
||||
if (!pVoid->IsValidController(event.jdevice.which) && event.jdevice.which == 0) {
|
||||
pVoid->ConnectDeviceToXbox(1, MS_CONTROLLER_DUKE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_JOYDEVICEREMOVED: {
|
||||
pVoid->DisconnectDeviceFromXbox(event.jdevice.which + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
case SDL_CONTROLLERBUTTONDOWN: {
|
||||
pVoid->UpdateButtonState(event.cbutton.which, event.cbutton.button, event.cbutton.state);
|
||||
|
@ -139,6 +311,13 @@ void InputDeviceManager::InputThread(InputDeviceManager* pVoid)
|
|||
break;
|
||||
}
|
||||
|
||||
case SDL_CONTROLLERDEVICEADDED: {
|
||||
|
||||
}
|
||||
case SDL_CONTROLLERDEVICEREMOVED: {
|
||||
|
||||
}
|
||||
|
||||
case SDL_QUIT: {
|
||||
bContinue = false;
|
||||
break;
|
||||
|
@ -250,3 +429,51 @@ void InputDeviceManager::UpdateAxisState(SDL_JoystickID id, uint8_t axis_index,
|
|||
|
||||
ControllerObj->UpdateAxisState(xbox_button, state);
|
||||
}
|
||||
|
||||
int InputDeviceManager::IsValidController(int index)
|
||||
{
|
||||
SDL2Devices* pDev;
|
||||
SDL_GameController* pController;
|
||||
|
||||
if (SDL_IsGameController(index)) {
|
||||
pDev = new SDL2Devices();
|
||||
pDev->m_Index = index;
|
||||
m_Sdl2Devices.push_back(pDev);
|
||||
}
|
||||
else {
|
||||
// this joystick is not supported at the moment
|
||||
return -1;
|
||||
}
|
||||
|
||||
pController = SDL_GameControllerOpen(pDev->m_Index);
|
||||
if (pController == nullptr) {
|
||||
EmuWarning("Failed to open game controller %s. The error was %s\n", SDL_GameControllerNameForIndex(pDev->m_Index), SDL_GetError());
|
||||
delete pDev;
|
||||
m_Sdl2Devices.erase(m_Sdl2Devices.begin() + index);
|
||||
return -1;
|
||||
}
|
||||
else if (pDev->m_Index > 3) {
|
||||
printf("More than 4 controllers detected. Putting game controller %s in detached state\n",
|
||||
SDL_GameControllerName(pController));
|
||||
pDev->m_Attached = 0;
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
printf("Found game controller %s\n", SDL_GameControllerName(pController));
|
||||
pDev->m_Gamepad = pController;
|
||||
pDev->m_jyID = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(pController));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
SDL2Devices* InputDeviceManager::FindDeviceFromXboxPort(int port)
|
||||
{
|
||||
if (port > 4 || port < 1) { return nullptr; };
|
||||
|
||||
for (auto it = m_Sdl2Devices.begin(); it != m_Sdl2Devices.end(); ++it) {
|
||||
if ((*it)->m_Index == (port - 1)) {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include "..\..\CxbxKrnl\EmuKrnl.h" // For EmuWarning
|
||||
#include "SDL.h"
|
||||
|
||||
#define GAMEPAD_A 0
|
||||
|
@ -75,13 +73,35 @@
|
|||
#include "SDL2_Device.h"
|
||||
|
||||
|
||||
/* enum indicating the device type to attach to the virtual xbox */
|
||||
typedef enum {
|
||||
DEVICE_INVALID = 0,
|
||||
MS_CONTROLLER_DUKE,
|
||||
MS_CONTROLLER_S,
|
||||
LIGHT_GUN,
|
||||
STEERING_WHEEL,
|
||||
MEMORY_UNIT,
|
||||
IR_DONGLE,
|
||||
STEEL_BATTALION_CONTROLLER,
|
||||
};
|
||||
|
||||
|
||||
class InputDeviceManager
|
||||
{
|
||||
public:
|
||||
InputDeviceManager();
|
||||
~InputDeviceManager();
|
||||
|
||||
// enumerate all available sdl2 controllers
|
||||
int EnumSdl2Devices();
|
||||
// start input event processing thread
|
||||
void StartInputThread();
|
||||
// connect the enumerated device to the virtual xbox
|
||||
int ConnectDeviceToXbox(int port, int type);
|
||||
// disconnect a device from the emulated xbox
|
||||
void DisconnectDeviceFromXbox(int port);
|
||||
// find the device attached to the supplied xbox port
|
||||
SDL2Devices* FindDeviceFromXboxPort(int port);
|
||||
|
||||
|
||||
private:
|
||||
|
@ -90,8 +110,6 @@ class InputDeviceManager
|
|||
|
||||
// assign the button binding to the devices
|
||||
//void AssignBindings();
|
||||
// start input event processing thread
|
||||
void StartInputThread();
|
||||
// input thread
|
||||
static void InputThread(InputDeviceManager* pVoid);
|
||||
// updates the button state of a joystick
|
||||
|
@ -100,6 +118,10 @@ class InputDeviceManager
|
|||
void UpdateHatState(SDL_JoystickID id, uint8_t hat_index, uint8_t state);
|
||||
// updates the axis state of a joystick
|
||||
void UpdateAxisState(SDL_JoystickID id, uint8_t axis_index, int16_t state);
|
||||
// checks if the controller attached can be used by sdl
|
||||
int IsValidController(int index);
|
||||
};
|
||||
|
||||
extern InputDeviceManager* g_InputDeviceManager;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
// ******************************************************************
|
||||
|
||||
#include "SDL2_Device.h"
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
int SDL2Devices::GetBoundButton(int sdl_key)
|
||||
|
@ -197,3 +198,19 @@ void SDL2Devices::UpdateAxisState(uint8_t xbox_button, int16_t state)
|
|||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void SDL2Devices::ReadButtonState(uint16_t* wButtons, uint8_t* bAnalogButtons, int16_t* sThumbLX,
|
||||
int16_t* sThumbLY, int16_t* sThumbRX, int16_t* sThumbRY)
|
||||
{
|
||||
if (bStateDirty) {
|
||||
*wButtons = m_State.wButtons.load();
|
||||
*sThumbLX = m_State.sThumbLX.load();
|
||||
*sThumbLY = m_State.sThumbLY.load();
|
||||
*sThumbRX = m_State.sThumbRX.load();
|
||||
*sThumbRY = m_State.sThumbRY.load();
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
bAnalogButtons[i] = m_State.bAnalogButtons[i].load();
|
||||
}
|
||||
bStateDirty = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,10 @@ class SDL2Devices
|
|||
SDL_GameController* m_Gamepad;
|
||||
// id of this controller
|
||||
SDL_JoystickID m_jyID;
|
||||
// attach/detach state of this controller
|
||||
int m_Attached;
|
||||
// indicates the xbox device emulated by this controller
|
||||
int m_Type = DEVICE_INVALID;
|
||||
|
||||
// update analog button state
|
||||
void UpdateAnalogButtonState(uint8_t xbox_button, uint8_t state);
|
||||
|
@ -73,10 +77,13 @@ class SDL2Devices
|
|||
int GetBoundButton(int sdl_key);
|
||||
// update bBindingsChanged flag
|
||||
void SetChangedBinding(bool bFlag) { m_bBindingsChanged = bFlag; }
|
||||
// read the current button state of a device
|
||||
void ReadButtonState(uint16_t* wButtons, uint8_t* bAnalogButtons, int16_t* sThumbLX,
|
||||
int16_t* sThumbLY, int16_t* sThumbRX, int16_t* sThumbRY);
|
||||
|
||||
|
||||
private:
|
||||
// default bindings
|
||||
// default bindings (hardcoded for now)
|
||||
const int m_ButtonMap_Analog[8][2] = {
|
||||
{ GAMEPAD_A, SDL_CONTROLLER_BUTTON_A },
|
||||
{ GAMEPAD_B, SDL_CONTROLLER_BUTTON_B },
|
||||
|
|
|
@ -71,6 +71,7 @@ namespace xboxkrnl
|
|||
#include "devices\LED.h" // For LED::Sequence
|
||||
#include "EmuSha.h" // For the SHA1 functions
|
||||
#include "Timer.h" // For Timer_Init
|
||||
#include "..\Common\Input\InputConfig.h" // For the InputDeviceManager
|
||||
|
||||
/*! thread local storage */
|
||||
Xbe::TLS *CxbxKrnl_TLS = NULL;
|
||||
|
@ -1454,10 +1455,23 @@ __declspec(noreturn) void CxbxKrnlInit
|
|||
|
||||
EmuHLEIntercept(pXbeHeader);
|
||||
|
||||
if (!bLLE_USB) {
|
||||
SetupXboxDeviceTypes();
|
||||
}
|
||||
|
||||
InitXboxHardware(HardwareModel::Revision1_5); // TODO : Make configurable
|
||||
|
||||
if (bLLE_USB) {
|
||||
int ret;
|
||||
g_InputDeviceManager = new InputDeviceManager;
|
||||
ret = g_InputDeviceManager->EnumSdl2Devices();
|
||||
g_InputDeviceManager->StartInputThread();
|
||||
if (ret > 0) {
|
||||
// Temporary: the device type and bindings should be read from emushared, for now always assume one xbox controller
|
||||
g_InputDeviceManager->ConnectDeviceToXbox(1, MS_CONTROLLER_DUKE);
|
||||
}
|
||||
}
|
||||
|
||||
// Now the hardware devices exist, couple the EEPROM buffer to it's device
|
||||
g_EEPROM->SetEEPROM((uint8_t*)EEPROM);
|
||||
|
||||
|
|
|
@ -34,7 +34,9 @@
|
|||
// *
|
||||
// ******************************************************************
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include "Timer.h"
|
||||
|
@ -107,6 +109,10 @@ void ClockThread(TimerObject* Timer)
|
|||
return;
|
||||
}
|
||||
Timer->Callback(Timer->Opaque);
|
||||
if (Timer->Exit.load()) {
|
||||
Timer_Destroy(Timer);
|
||||
return;
|
||||
}
|
||||
NewExpireTime = GetNextExpireTime(Timer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
// ******************************************************************
|
||||
|
||||
#include "Xbox.h" // For HardwareModel
|
||||
#include "..\CxbxKrnl\HLEIntercept.h"
|
||||
|
||||
PCIBus* g_PCIBus;
|
||||
SMBus* g_SMBus;
|
||||
|
@ -130,8 +131,10 @@ void InitXboxHardware(HardwareModel hardwareModel)
|
|||
g_NVNet = new NVNetDevice();
|
||||
g_NV2A = new NV2ADevice();
|
||||
g_ADM1032 = new ADM1032Device();
|
||||
if (bLLE_USB) {
|
||||
g_USB0 = new USBDevice();
|
||||
g_USB1 = new USBDevice();
|
||||
}
|
||||
|
||||
// Connect devices to SM bus
|
||||
g_SMBus->ConnectDevice(SMBUS_ADDRESS_SYSTEM_MICRO_CONTROLLER, g_SMC); // W 0x20 R 0x21
|
||||
|
@ -160,8 +163,10 @@ void InitXboxHardware(HardwareModel hardwareModel)
|
|||
//g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(5, 0)), g_NVAPU);
|
||||
//g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(6, 0)), g_AC97);
|
||||
g_PCIBus->ConnectDevice(PCI_DEVID(1, PCI_DEVFN(0, 0)), g_NV2A, NV2A_ADDR);
|
||||
if (bLLE_USB) {
|
||||
g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(2, 0)), g_USB0, USB0_BASE);
|
||||
g_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(3, 0)), g_USB1, USB1_BASE);
|
||||
}
|
||||
|
||||
// TODO : Handle other SMBUS Addresses, like PIC_ADDRESS, XCALIBUR_ADDRESS
|
||||
// Resources : http://pablot.com/misc/fancontroller.cpp
|
||||
|
|
|
@ -81,6 +81,8 @@
|
|||
extern USBDevice* g_USB0;
|
||||
extern USBDevice* g_USB1;
|
||||
|
||||
Hub* g_HubObjArray[4] = { nullptr };
|
||||
|
||||
|
||||
struct USBHubPort {
|
||||
USBPort port; // downstream port status
|
||||
|
@ -689,3 +691,11 @@ void Hub::HubCleanUp()
|
|||
m_pPeripheralFuncStruct = nullptr;
|
||||
m_HubState = nullptr;
|
||||
}
|
||||
|
||||
void Hub::HubDestroy()
|
||||
{
|
||||
while (m_UsbDev->m_HostController->m_bFrameTime) {}
|
||||
m_UsbDev->m_HostController->m_bFrameTime = true;
|
||||
m_pPeripheralFuncStruct->handle_destroy();
|
||||
m_UsbDev->m_HostController->m_bFrameTime = false;
|
||||
}
|
||||
|
|
|
@ -50,10 +50,10 @@ class Hub
|
|||
// usb device this hub is attached to
|
||||
USBDevice* m_UsbDev = nullptr;
|
||||
|
||||
// initialize this peripheral
|
||||
// initialize this hub
|
||||
int Init(int port);
|
||||
// destroy hub resources
|
||||
void HubCleanUp();
|
||||
// start hub destruction
|
||||
void HubDestroy();
|
||||
|
||||
|
||||
private:
|
||||
|
@ -84,6 +84,8 @@ class Hub
|
|||
void UsbHubReleasePort(XboxDeviceState* dev);
|
||||
// retieve the name of the feature of the usb request
|
||||
std::string GetFeatureName(int feature);
|
||||
// destroy hub resources
|
||||
void HubCleanUp();
|
||||
};
|
||||
|
||||
extern Hub* g_HubObjArray[4];
|
||||
|
|
|
@ -195,6 +195,7 @@ OHCI::OHCI(int Irq, USBDevice* UsbObj)
|
|||
|
||||
m_IrqNum = Irq;
|
||||
m_UsbDevice = UsbObj;
|
||||
m_bFrameTime = false;
|
||||
ops = new USBPortOps();
|
||||
{
|
||||
using namespace std::placeholders;
|
||||
|
@ -231,9 +232,13 @@ void OHCI::OHCI_FrameBoundaryWorker()
|
|||
{
|
||||
OHCI_HCCA hcca;
|
||||
|
||||
while (m_bFrameTime) {}
|
||||
m_bFrameTime = true;
|
||||
|
||||
if (OHCI_ReadHCCA(m_Registers.HcHCCA, &hcca)) {
|
||||
EmuWarning("%s: HCCA read error at physical address 0x%X", m_Registers.HcHCCA, LOG_STR_OHCI);
|
||||
OHCI_FatalError();
|
||||
m_bFrameTime = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -258,6 +263,7 @@ void OHCI::OHCI_FrameBoundaryWorker()
|
|||
|
||||
// Stop if UnrecoverableError happened or OHCI_SOF will crash
|
||||
if (m_Registers.HcInterruptStatus & OHCI_INTR_UE) {
|
||||
m_bFrameTime = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -303,6 +309,7 @@ void OHCI::OHCI_FrameBoundaryWorker()
|
|||
EmuWarning("%s: HCCA write error at physical address 0x%X", LOG_STR_OHCI, m_Registers.HcHCCA);
|
||||
OHCI_FatalError();
|
||||
}
|
||||
m_bFrameTime = false;
|
||||
}
|
||||
|
||||
void OHCI::OHCI_FatalError()
|
||||
|
|
|
@ -140,6 +140,10 @@ struct OHCI_Registers
|
|||
class OHCI
|
||||
{
|
||||
public:
|
||||
// Indicates that the timer thread is accessing the OHCI object. Necessary because the input thread from the
|
||||
// InputDeviceManager will access us when it needs to destroy a device
|
||||
std::atomic_bool m_bFrameTime;
|
||||
|
||||
// constructor
|
||||
OHCI(int Irqn, USBDevice* UsbObj);
|
||||
// destructor
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include "XidGamepad.h"
|
||||
#include "USBDevice.h"
|
||||
#include "Common/Input/InputConfig.h"
|
||||
|
||||
#define LOG_STR_GAMEPAD "Gamepad:"
|
||||
|
||||
|
@ -47,6 +48,8 @@
|
|||
#define XID_GET_CAPABILITIES 0x01
|
||||
|
||||
|
||||
XidGamepad* g_XidControllerObjArray[4];
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
/* Class-specific xid descriptor */
|
||||
|
@ -239,9 +242,10 @@ int XidGamepad::UsbXidClaimPort(XboxDeviceState* dev, int port)
|
|||
}
|
||||
}
|
||||
if (m_UsbDev == nullptr) {
|
||||
EmuWarning("Port requested %d.%d not found (in use?)", port, 2);
|
||||
EmuWarning("Port requested %d.2 not found (in use?)", port);
|
||||
return -1;
|
||||
}
|
||||
m_Port = port;
|
||||
it = m_UsbDev->m_FreePorts.begin() + i;
|
||||
dev->Port = *it;
|
||||
(*it)->Dev = dev;
|
||||
|
@ -316,6 +320,12 @@ void XidGamepad::UsbXid_HandleControl(XboxDeviceState* dev, USBPacket* p,
|
|||
if (value == 0x100) {
|
||||
assert(m_XidState->in_state.bLength <= length);
|
||||
// m_XidState->in_state.bReportId++; /* FIXME: I'm not sure if bReportId is just a counter */
|
||||
SDL2Devices* controller = g_InputDeviceManager->FindDeviceFromXboxPort(m_Port);
|
||||
if (controller != nullptr) {
|
||||
controller->ReadButtonState(&m_XidState->in_state.wButtons, m_XidState->in_state.bAnalogButtons,
|
||||
&m_XidState->in_state.sThumbLX, &m_XidState->in_state.sThumbLY, &m_XidState->in_state.sThumbRX,
|
||||
&m_XidState->in_state.sThumbRY);
|
||||
}
|
||||
std::memcpy(data, &m_XidState->in_state, m_XidState->in_state.bLength);
|
||||
p->ActualLength = m_XidState->in_state.bLength;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
|
||||
struct USBXIDState; // forward declare
|
||||
|
||||
|
||||
/* Class which implements an xbox gamepad */
|
||||
class XidGamepad
|
||||
{
|
||||
|
@ -60,6 +59,8 @@ class XidGamepad
|
|||
USBXIDState* m_XidState = nullptr;
|
||||
// gamepad class functions
|
||||
USBDeviceClass* m_pPeripheralFuncStruct = nullptr;
|
||||
// xbox port this gamepad is attached to
|
||||
int m_Port = 0;
|
||||
|
||||
// initialize various member variables/functions
|
||||
XboxDeviceState* ClassInitFn();
|
||||
|
@ -77,4 +78,6 @@ class XidGamepad
|
|||
void UsbXid_HandleData(XboxDeviceState* dev, USBPacket* p);
|
||||
};
|
||||
|
||||
extern XidGamepad* g_XidControllerObjArray[4];
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue