[PATCH 5/6] windows.gaming.input: Implement GetCurrentReading for the RawGameController runtimeclass.
Rémi Bernon
rbernon at codeweavers.com
Thu Mar 10 03:38:43 CST 2022
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/windows.gaming.input/controller.c | 16 +++++-
dlls/windows.gaming.input/provider.c | 68 ++++++++++++++++++++++++++
dlls/windows.gaming.input/provider.idl | 11 +++++
3 files changed, 93 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.gaming.input/controller.c b/dlls/windows.gaming.input/controller.c
index 8bd95c2dead..fb2f4ab82e7 100644
--- a/dlls/windows.gaming.input/controller.c
+++ b/dlls/windows.gaming.input/controller.c
@@ -261,9 +261,21 @@ static HRESULT WINAPI raw_controller_GetCurrentReading( IRawGameController *ifac
UINT32 switches_size, enum GameControllerSwitchPosition *switches,
UINT32 axes_size, DOUBLE *axes, UINT64 *timestamp )
{
- FIXME( "iface %p, buttons_size %u, buttons %p, switches_size %u, switches %p, axes_size %u, axes %p, timestamp %p stub!\n",
+ struct controller *impl = impl_from_IRawGameController( iface );
+ WineGameControllerState state;
+ HRESULT hr;
+
+ TRACE( "iface %p, buttons_size %u, buttons %p, switches_size %u, switches %p, axes_size %u, axes %p, timestamp %p.\n",
iface, buttons_size, buttons, switches_size, switches, axes_size, axes, timestamp );
- return E_NOTIMPL;
+
+ if (FAILED(hr = IWineGameControllerProvider_get_State( impl->wine_provider, &state ))) return hr;
+
+ memcpy( axes, state.axes, axes_size * sizeof(*axes) );
+ memcpy( buttons, state.buttons, buttons_size * sizeof(*buttons) );
+ memcpy( switches, state.switches, switches_size * sizeof(*switches) );
+ *timestamp = state.timestamp;
+
+ return hr;
}
static HRESULT WINAPI raw_controller_GetSwitchKind( IRawGameController *iface, INT32 index, enum GameControllerSwitchKind *value )
diff --git a/dlls/windows.gaming.input/provider.c b/dlls/windows.gaming.input/provider.c
index 7883ec6af68..56ba005812d 100644
--- a/dlls/windows.gaming.input/provider.c
+++ b/dlls/windows.gaming.input/provider.c
@@ -182,6 +182,69 @@ static HRESULT WINAPI wine_provider_get_SwitchCount( IWineGameControllerProvider
return hr;
}
+static HRESULT WINAPI wine_provider_get_State( IWineGameControllerProvider *iface, struct WineGameControllerState *out )
+{
+ struct provider *impl = impl_from_IWineGameControllerProvider( iface );
+ DIJOYSTATE2 state;
+ UINT32 i = 0;
+ HRESULT hr;
+
+ TRACE( "iface %p, out %p.\n", iface, out );
+
+ if (FAILED(hr = IDirectInputDevice8_GetDeviceState( impl->dinput_device, sizeof(state), &state )))
+ {
+ WARN( "Failed to read device state, hr %#lx\n", hr );
+ return hr;
+ }
+
+ i = ARRAY_SIZE(state.rgbButtons);
+ while (i--) out->buttons[i] = (state.rgbButtons[i] != 0);
+
+ i = ARRAY_SIZE(state.rgdwPOV);
+ while (i--)
+ {
+ if (state.rgdwPOV[i] == ~0) out->switches[i] = GameControllerSwitchPosition_Center;
+ else out->switches[i] = state.rgdwPOV[i] * 8 / 36000 + 1;
+ }
+
+ i = 0;
+ out->axes[i++] = state.lX / 65535.;
+ out->axes[i++] = state.lY / 65535.;
+ out->axes[i++] = state.lZ / 65535.;
+ out->axes[i++] = state.lRx / 65535.;
+ out->axes[i++] = state.lRy / 65535.;
+ out->axes[i++] = state.lRz / 65535.;
+ out->axes[i++] = state.rglSlider[0] / 65535.;
+ out->axes[i++] = state.rglSlider[1] / 65535.;
+ out->axes[i++] = state.lVX / 65535.;
+ out->axes[i++] = state.lVY / 65535.;
+ out->axes[i++] = state.lVZ / 65535.;
+ out->axes[i++] = state.lVRx / 65535.;
+ out->axes[i++] = state.lVRy / 65535.;
+ out->axes[i++] = state.lVRz / 65535.;
+ out->axes[i++] = state.rglVSlider[0] / 65535.;
+ out->axes[i++] = state.rglVSlider[1] / 65535.;
+ out->axes[i++] = state.lAX / 65535.;
+ out->axes[i++] = state.lAY / 65535.;
+ out->axes[i++] = state.lAZ / 65535.;
+ out->axes[i++] = state.lARx / 65535.;
+ out->axes[i++] = state.lARy / 65535.;
+ out->axes[i++] = state.lARz / 65535.;
+ out->axes[i++] = state.rglASlider[0] / 65535.;
+ out->axes[i++] = state.rglASlider[1] / 65535.;
+ out->axes[i++] = state.lFX / 65535.;
+ out->axes[i++] = state.lFY / 65535.;
+ out->axes[i++] = state.lFZ / 65535.;
+ out->axes[i++] = state.lFRx / 65535.;
+ out->axes[i++] = state.lFRy / 65535.;
+ out->axes[i++] = state.lFRz / 65535.;
+ out->axes[i++] = state.rglFSlider[0] / 65535.;
+ out->axes[i++] = state.rglFSlider[1] / 65535.;
+ out->timestamp = GetTickCount64();
+
+ return S_OK;
+}
+
static const struct IWineGameControllerProviderVtbl wine_provider_vtbl =
{
wine_provider_QueryInterface,
@@ -196,6 +259,7 @@ static const struct IWineGameControllerProviderVtbl wine_provider_vtbl =
wine_provider_get_AxisCount,
wine_provider_get_ButtonCount,
wine_provider_get_SwitchCount,
+ wine_provider_get_State,
};
DEFINE_IINSPECTABLE( game_provider, IGameControllerProvider, struct provider, IWineGameControllerProvider_iface )
@@ -284,6 +348,10 @@ void provider_create( const WCHAR *device_path )
IDirectInput8_Release( dinput );
if (FAILED(hr)) return;
+ if (FAILED(hr = IDirectInputDevice8_SetCooperativeLevel( dinput_device, 0, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE ))) goto done;
+ if (FAILED(hr = IDirectInputDevice8_SetDataFormat( dinput_device, &c_dfDIJoystick2 ))) goto done;
+ if (FAILED(hr = IDirectInputDevice8_Acquire( dinput_device ))) goto done;
+
if (!(impl = calloc( 1, sizeof(*impl) ))) goto done;
impl->IWineGameControllerProvider_iface.lpVtbl = &wine_provider_vtbl;
impl->IGameControllerProvider_iface.lpVtbl = &game_provider_vtbl;
diff --git a/dlls/windows.gaming.input/provider.idl b/dlls/windows.gaming.input/provider.idl
index 19d5643f767..25191078721 100644
--- a/dlls/windows.gaming.input/provider.idl
+++ b/dlls/windows.gaming.input/provider.idl
@@ -32,6 +32,7 @@ import "windows.gaming.input.custom.idl";
namespace Windows.Gaming.Input.Custom {
typedef enum WineGameControllerType WineGameControllerType;
+ typedef struct WineGameControllerState WineGameControllerState;
interface IWineGameControllerProvider;
runtimeclass WineGameControllerProvider;
@@ -41,6 +42,14 @@ namespace Windows.Gaming.Input.Custom {
Gamepad = 1,
};
+ struct WineGameControllerState
+ {
+ UINT64 timestamp;
+ DOUBLE axes[32];
+ BOOLEAN buttons[128];
+ Windows.Gaming.Input.GameControllerSwitchPosition switches[4];
+ };
+
[
uuid(06e58977-7684-4dc5-bad1-cda52a4aa06d)
]
@@ -62,6 +71,8 @@ namespace Windows.Gaming.Input.Custom {
[propget] HRESULT AxisCount([out, retval] INT32 *value);
[propget] HRESULT ButtonCount([out, retval] INT32 *value);
[propget] HRESULT SwitchCount([out, retval] INT32 *value);
+
+ [propget] HRESULT State([out, retval] WineGameControllerState *state);
}
[
--
2.35.1
More information about the wine-devel
mailing list