DInputSource: Use W variants of APIs

This commit is contained in:
Connor McLaughlin 2022-10-21 00:29:03 +10:00
parent 107bff0e7f
commit 0b0e910892
2 changed files with 30 additions and 24 deletions

View file

@ -74,7 +74,7 @@ bool DInputSource::Initialize(SettingsInterface& si, std::unique_lock<std::mutex
return false; return false;
} }
HRESULT hr = create(GetModuleHandleA(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8A, HRESULT hr = create(GetModuleHandleA(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8W,
reinterpret_cast<LPVOID*>(m_dinput.GetAddressOf()), nullptr); reinterpret_cast<LPVOID*>(m_dinput.GetAddressOf()), nullptr);
m_joystick_data_format = get_joystick_data_format(); m_joystick_data_format = get_joystick_data_format();
if (FAILED(hr) || !m_joystick_data_format) if (FAILED(hr) || !m_joystick_data_format)
@ -106,20 +106,20 @@ void DInputSource::Shutdown()
} }
} }
static BOOL CALLBACK EnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) static BOOL CALLBACK EnumCallback(LPCDIDEVICEINSTANCEW lpddi, LPVOID pvRef)
{ {
static_cast<std::vector<DIDEVICEINSTANCE>*>(pvRef)->push_back(*lpddi); static_cast<std::vector<DIDEVICEINSTANCEW>*>(pvRef)->push_back(*lpddi);
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
void DInputSource::AddDevices(HWND toplevel_window) void DInputSource::AddDevices(HWND toplevel_window)
{ {
std::vector<DIDEVICEINSTANCE> devices; std::vector<DIDEVICEINSTANCEW> devices;
m_dinput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumCallback, &devices, DIEDFL_ATTACHEDONLY); m_dinput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumCallback, &devices, DIEDFL_ATTACHEDONLY);
Log_InfoPrintf("Enumerated %zu devices", devices.size()); Log_InfoPrintf("Enumerated %zu devices", devices.size());
for (DIDEVICEINSTANCE inst : devices) for (DIDEVICEINSTANCEW inst : devices)
{ {
ControllerData cd; ControllerData cd;
HRESULT hr = m_dinput->CreateDevice(inst.guidInstance, cd.device.GetAddressOf(), nullptr); HRESULT hr = m_dinput->CreateDevice(inst.guidInstance, cd.device.GetAddressOf(), nullptr);
@ -129,12 +129,17 @@ void DInputSource::AddDevices(HWND toplevel_window)
continue; continue;
} }
if (AddDevice(cd, toplevel_window, inst.tszProductName)) const std::string name(StringUtil::WideStringToUTF8String(inst.tszProductName));
if (AddDevice(cd, toplevel_window, name))
{
const u32 index = static_cast<u32>(m_controllers.size());
m_controllers.push_back(std::move(cd)); m_controllers.push_back(std::move(cd));
Host::OnInputDeviceConnected(GetDeviceIdentifier(index), name);
}
} }
} }
bool DInputSource::AddDevice(ControllerData& cd, HWND toplevel_window, const char* name) bool DInputSource::AddDevice(ControllerData& cd, HWND toplevel_window, const std::string& name)
{ {
HRESULT hr = cd.device->SetCooperativeLevel(toplevel_window, DISCL_BACKGROUND | DISCL_EXCLUSIVE); HRESULT hr = cd.device->SetCooperativeLevel(toplevel_window, DISCL_BACKGROUND | DISCL_EXCLUSIVE);
if (FAILED(hr)) if (FAILED(hr))
@ -142,24 +147,24 @@ bool DInputSource::AddDevice(ControllerData& cd, HWND toplevel_window, const cha
hr = cd.device->SetCooperativeLevel(toplevel_window, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE); hr = cd.device->SetCooperativeLevel(toplevel_window, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
if (FAILED(hr)) if (FAILED(hr))
{ {
Log_ErrorPrintf("Failed to set cooperative level for '%s'", name); Log_ErrorPrintf("Failed to set cooperative level for '%s'", name.c_str());
return false; return false;
} }
Log_WarningPrintf("Failed to set exclusive mode for '%s'", name); Log_WarningPrintf("Failed to set exclusive mode for '%s'", name.c_str());
} }
hr = cd.device->SetDataFormat(m_joystick_data_format); hr = cd.device->SetDataFormat(m_joystick_data_format);
if (FAILED(hr)) if (FAILED(hr))
{ {
Log_ErrorPrintf("Failed to set data format for '%s'", name); Log_ErrorPrintf("Failed to set data format for '%s'", name.c_str());
return false; return false;
} }
hr = cd.device->Acquire(); hr = cd.device->Acquire();
if (FAILED(hr)) if (FAILED(hr))
{ {
Log_ErrorPrintf("Failed to acquire device '%s'", name); Log_ErrorPrintf("Failed to acquire device '%s'", name.c_str());
return false; return false;
} }
@ -168,7 +173,7 @@ bool DInputSource::AddDevice(ControllerData& cd, HWND toplevel_window, const cha
hr = cd.device->GetCapabilities(&caps); hr = cd.device->GetCapabilities(&caps);
if (FAILED(hr)) if (FAILED(hr))
{ {
Log_ErrorPrintf("Failed to get capabilities for '%s'", name); Log_ErrorPrintf("Failed to get capabilities for '%s'", name.c_str());
return false; return false;
} }
@ -203,21 +208,21 @@ bool DInputSource::AddDevice(ControllerData& cd, HWND toplevel_window, const cha
if (hr == DI_NOEFFECT) if (hr == DI_NOEFFECT)
cd.needs_poll = false; cd.needs_poll = false;
else if (hr != DI_OK) else if (hr != DI_OK)
Log_WarningPrintf("Polling device '%s' failed: %08X", name, hr); Log_WarningPrintf("Polling device '%s' failed: %08X", name.c_str(), hr);
hr = cd.device->GetDeviceState(sizeof(cd.last_state), &cd.last_state); hr = cd.device->GetDeviceState(sizeof(cd.last_state), &cd.last_state);
if (hr != DI_OK) if (hr != DI_OK)
Log_WarningPrintf("GetDeviceState() for '%s' failed: %08X", name, hr); Log_WarningPrintf("GetDeviceState() for '%s' failed: %08X", name.c_str(), hr);
Log_InfoPrintf("%s has %u buttons, %u axes, %u hats", name, cd.num_buttons, static_cast<u32>(cd.axis_offsets.size()), Log_InfoPrintf("%s has %u buttons, %u axes, %u hats", name.c_str(), cd.num_buttons,
cd.num_hats); static_cast<u32>(cd.axis_offsets.size()), cd.num_hats);
return (cd.num_buttons > 0 || !cd.axis_offsets.empty() || cd.num_hats > 0); return (cd.num_buttons > 0 || !cd.axis_offsets.empty() || cd.num_hats > 0);
} }
void DInputSource::PollEvents() void DInputSource::PollEvents()
{ {
for (size_t i = 0; i < m_controllers.size(); i++) for (size_t i = 0; i < m_controllers.size();)
{ {
ControllerData& cd = m_controllers[i]; ControllerData& cd = m_controllers[i];
if (!cd.device) if (!cd.device)
@ -236,19 +241,20 @@ void DInputSource::PollEvents()
if (hr != DI_OK) if (hr != DI_OK)
{ {
// TODO: This should remove from the list instead.
cd = {};
Host::OnInputDeviceDisconnected(GetDeviceIdentifier(static_cast<u32>(i))); Host::OnInputDeviceDisconnected(GetDeviceIdentifier(static_cast<u32>(i)));
m_controllers.erase(m_controllers.begin() + i);
continue; continue;
} }
} }
else if (hr != DI_OK) else if (hr != DI_OK)
{ {
Log_WarningPrintf("GetDeviceState() failed: %08X", hr); Log_WarningPrintf("GetDeviceState() failed: %08X", hr);
i++;
continue; continue;
} }
CheckForStateChanges(i, js); CheckForStateChanges(i, js);
i++;
} }
} }
@ -257,10 +263,10 @@ std::vector<std::pair<std::string, std::string>> DInputSource::EnumerateDevices(
std::vector<std::pair<std::string, std::string>> ret; std::vector<std::pair<std::string, std::string>> ret;
for (size_t i = 0; i < m_controllers.size(); i++) for (size_t i = 0; i < m_controllers.size(); i++)
{ {
DIDEVICEINSTANCEA dii = {sizeof(DIDEVICEINSTANCEA)}; DIDEVICEINSTANCEW dii = {sizeof(DIDEVICEINSTANCEW)};
std::string name; std::string name;
if (SUCCEEDED(m_controllers[i].device->GetDeviceInfo(&dii))) if (SUCCEEDED(m_controllers[i].device->GetDeviceInfo(&dii)))
name = dii.tszProductName; name = StringUtil::WideStringToUTF8String(dii.tszProductName);
if (name.empty()) if (name.empty())
name = "Unknown"; name = "Unknown";

View file

@ -52,7 +52,7 @@ private:
struct ControllerData struct ControllerData
{ {
ComPtr<IDirectInputDevice8> device; ComPtr<IDirectInputDevice8W> device;
DIJOYSTATE last_state = {}; DIJOYSTATE last_state = {};
std::vector<u32> axis_offsets; std::vector<u32> axis_offsets;
u32 num_buttons = 0; u32 num_buttons = 0;
@ -69,7 +69,7 @@ private:
static std::string GetDeviceIdentifier(u32 index); static std::string GetDeviceIdentifier(u32 index);
void AddDevices(HWND toplevel_window); void AddDevices(HWND toplevel_window);
bool AddDevice(ControllerData& cd, HWND toplevel_window, const char* name); bool AddDevice(ControllerData& cd, HWND toplevel_window, const std::string& name);
void CheckForStateChanges(size_t index, const DIJOYSTATE& new_state); void CheckForStateChanges(size_t index, const DIJOYSTATE& new_state);
@ -77,5 +77,5 @@ private:
HMODULE m_dinput_module{}; HMODULE m_dinput_module{};
LPCDIDATAFORMAT m_joystick_data_format{}; LPCDIDATAFORMAT m_joystick_data_format{};
ComPtr<IDirectInput8> m_dinput; ComPtr<IDirectInput8W> m_dinput;
}; };