Skip to content

Commit

Permalink
can detect all 4 xbox slots now. improve crash problem when hid gamep…
Browse files Browse the repository at this point in the history
…ad suspend/resume
  • Loading branch information
duchuule committed Aug 20, 2015
1 parent 9c5c675 commit a0dc0d1
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 33 deletions.
20 changes: 17 additions & 3 deletions CXBOXController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ namespace VBA10
{
CXBOXController::CXBOXController(int playerNumber)
: controllerNumber(playerNumber - 1)
{ }
{

}

XINPUT_STATE CXBOXController::GetState(void)
{
Expand All @@ -18,10 +20,22 @@ namespace VBA10
bool CXBOXController::IsConnected(void)
{
//ZeroMemory(&this->state, sizeof(XINPUT_STATE));
bool connected = false;
for (int i = 0; i <= 3; i++)
{
int cNumber = (this->controllerNumber + i) % 4; //try from the current controller number first

if (XInputGetState(cNumber, &this->state) == ERROR_SUCCESS)
{
controllerNumber = cNumber;
connected = true;
break;
}
}


DWORD result = XInputGetState(this->controllerNumber, &this->state);

return (result == ERROR_SUCCESS);
return connected;
}

void CXBOXController::Vibrate(int leftVal, int rightVal)
Expand Down
19 changes: 16 additions & 3 deletions DirectXPage.xaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,9 @@ DirectXPage::DirectXPage():
//then the next call in settings will return the true status.
XINPUT_STATE state;
ZeroMemory(&state,sizeof(XINPUT_STATE));
XInputGetState(0, &state);

for (int i = 0; i <= 3; i++)
XInputGetState(i, &state);



Expand Down Expand Up @@ -428,13 +430,18 @@ void DirectXPage::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEvent
else
m_main->emulator->Unpause();

//m_main->emulator->HidInput->StartListening();

m_main->emulator->HidInput->StartListening();


}
else
{
//m_main->StopRenderLoop();
m_main->emulator->Pause();
//m_main->emulator->HidInput->StopListening();

m_main->emulator->HidInput->UnregisterFromInputReportEvent();

}
}

Expand Down Expand Up @@ -583,10 +590,14 @@ void DirectXPage::TogglePaneButton_UnChecked(Platform::Object^ sender, Windows::

//unpause emulator
m_main->emulator->Unpause();

m_main->emulator->HidInput->StartListening();
}

void DirectXPage::TogglePaneButton_Checked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
m_main->emulator->HidInput->UnregisterFromInputReportEvent();

//pause emulator
m_main->emulator->Pause();

Expand Down Expand Up @@ -667,6 +678,8 @@ void DirectXPage::AppShell_KeyDown(Object^ sender, KeyRoutedEventArgs^ e)

void DirectXPage::CloseMenu()
{


RootSplitView->IsPaneOpen = false; //this will toggle the hamburger menu because of the 2-way binding
m_main->emulator->GetVirtualController()->Reset();
}
Expand Down
75 changes: 51 additions & 24 deletions HIDControllerInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
using namespace Windows::Devices::HumanInterfaceDevice;
using namespace Platform::Collections;
using namespace Windows::Foundation;
using namespace Windows::Devices::Enumeration;

namespace VBA10
{
HIDControllerInput::HIDControllerInput(): isListening(false)
HIDControllerInput::HIDControllerInput(): isRegisteredForInputReportEvents(false)
{
InitializeCriticalSectionEx(&inputSync, NULL, NULL);

Expand All @@ -28,32 +29,64 @@ namespace VBA10

void HIDControllerInput::StartListening()
{
//if (Device == nullptr)
// return;
if (EventHandlerForDevice::Current->IsDeviceConnected)
{
RegisterForInputReportEvents();

//if (!isListening)
//{
// // Save event registration token so we can unregisted for events
// inputReportEventToken = Device->InputReportReceived +=
// ref new TypedEventHandler<HidDevice^, HidInputReportReceivedEventArgs^>(this, &HIDControllerInput::OnInputReportEvent);
EventHandlerForDevice::Current->OnDeviceConnected =
ref new TypedEventHandler<EventHandlerForDevice^, OnDeviceConnectedEventArgs^>(this, &HIDControllerInput::OnDeviceConnected);

// isListening = true;
//}
EventHandlerForDevice::Current->OnDeviceClose =
ref new TypedEventHandler<EventHandlerForDevice^, DeviceInformation^>(this, &HIDControllerInput::OnDeviceClosing);
}
}

void HIDControllerInput::StopListening()
{
//if (Device == nullptr)
// return;
UnregisterFromInputReportEvent();

//if (isListening)
//{
// Device->InputReportReceived -= inputReportEventToken;
// isListening = false;
//}
EventHandlerForDevice::Current->OnDeviceClose = nullptr;
EventHandlerForDevice::Current->OnDeviceConnected = nullptr;

}

void HIDControllerInput::RegisterForInputReportEvents()
{
if (!isRegisteredForInputReportEvents)
{
// Remember which device we are registering the device with, in case there is a device disconnect and reconnect. We want to avoid unregistering
// a stale token. Ideally, one should remove the event token (e.g. assign to null) upon the device removal to avoid using it again.
registeredDevice = EventHandlerForDevice::Current->Device;

// Save event registration token so we can unregisted for events
inputReportEventToken = registeredDevice->InputReportReceived +=
ref new TypedEventHandler<HidDevice^, HidInputReportReceivedEventArgs^>(this, &HIDControllerInput::OnInputReportEvent);

isRegisteredForInputReportEvents = true;
}
}

void HIDControllerInput::UnregisterFromInputReportEvent(void)
{
if (isRegisteredForInputReportEvents)
{
// Don't unregister event token if the device was removed and reconnected because registration token is no longer valid
registeredDevice->InputReportReceived -= inputReportEventToken;
registeredDevice = nullptr;
isRegisteredForInputReportEvents = false;
}
}

void HIDControllerInput::OnDeviceConnected(EventHandlerForDevice^ /* sender */, OnDeviceConnectedEventArgs^ onDeviceConnectedEventArgs)
{
RegisterForInputReportEvents();
}
void HIDControllerInput::OnDeviceClosing(EventHandlerForDevice^ /* sender */, DeviceInformation^ /* deviceInformation */)
{
UnregisterFromInputReportEvent();
}


void HIDControllerInput::OnInputReportEvent(HidDevice^ sender, HidInputReportReceivedEventArgs^ eventArgs)
{

Expand Down Expand Up @@ -132,16 +165,10 @@ namespace VBA10

void HIDControllerInput::Update()
{
if (this->inputReport == nullptr)
return;





}


}

void HIDControllerInput::GetMapping(Platform::String^ tag, bool* left, bool* right, bool* up, bool* down, bool* a, bool* b, bool* l, bool* r, bool* select, bool* start, bool* turbo)
{
Expand Down
17 changes: 15 additions & 2 deletions HIDControllerInput.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <collection.h>
#include "EmulatorInput.h"
#include "EventHandlerForDevice.h"

namespace VBA10
{
Expand Down Expand Up @@ -33,25 +34,37 @@ namespace VBA10
void StartListening(); //start listening to report event
void StopListening();

void RegisterForInputReportEvents();
void UnregisterFromInputReportEvent(void);

//Windows::Devices::HumanInterfaceDevice::HidDevice ^Device;

Platform::Collections::Vector < HidNumericControlExt^>^ allNumericControls;
Platform::Collections::Map <int, Platform::String^>^ booleanControlMapping;

void OnDeviceConnected(EventHandlerForDevice^ sender, OnDeviceConnectedEventArgs^ onDeviceConnectedEventArgs);
void OnDeviceClosing(EventHandlerForDevice^ sender, Windows::Devices::Enumeration::DeviceInformation^ deviceInformation);

private:
ControllerState state;

bool isListening;
Windows::Foundation::EventRegistrationToken inputReportEventToken;
Windows::Devices::HumanInterfaceDevice::HidInputReport^ inputReport;
bool isRegisteredForInputReportEvents;

// Device that we registered for events with
Windows::Devices::HumanInterfaceDevice::HidDevice^ registeredDevice;

~HIDControllerInput(void);



void OnInputReportEvent(
Windows::Devices::HumanInterfaceDevice::HidDevice^ sender,
Windows::Devices::HumanInterfaceDevice::HidInputReportReceivedEventArgs^ eventArgs);




CRITICAL_SECTION inputSync;

void GetMapping(Platform::String^ tag, bool* left, bool* right, bool* up, bool* down, bool* a, bool* b, bool* l, bool* r, bool* select, bool* start, bool* turbo);
Expand Down
12 changes: 11 additions & 1 deletion SettingsPage.xaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,18 @@ SettingsPage::SettingsPage()
//check xbox controller connection
XINPUT_STATE state;
ZeroMemory(&state, sizeof(XINPUT_STATE));
bool xboxConnected = false;

if (XInputGetState(0, &state) == ERROR_DEVICE_NOT_CONNECTED)
for (int i = 0; i <= 3; i++)
{
if (XInputGetState(i, &state) != ERROR_DEVICE_NOT_CONNECTED)
{
xboxConnected = true;
break;
}
}

if (!xboxConnected)
{
this->txtControllerStatus->Text = "No XBox controller detected.";
}
Expand Down

0 comments on commit a0dc0d1

Please sign in to comment.