mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 16:28:18 +00:00
winmm: Reimplement joystick APIs on top of dinput.
Based on a patch from Zebediah Figura <zfigura@codeweavers.com>. Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Andrew Eikum <aeikum@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
591dcfda01
commit
4f1095a0ee
|
@ -9756,10 +9756,6 @@ static void test_winmm_joystick(void)
|
||||||
ok( ret == 16, "joyGetNumDevs returned %u\n", ret );
|
ok( ret == 16, "joyGetNumDevs returned %u\n", ret );
|
||||||
|
|
||||||
ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) );
|
ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) );
|
||||||
/* FIXME: Marvin somehow manages to get a device, ignore it */
|
|
||||||
if (!strcmp( winetest_platform, "wine") && ret == 0 &&
|
|
||||||
!wcscmp( caps.szPname, L"QEMU Virtio Tablet" ))
|
|
||||||
return;
|
|
||||||
ok( ret == JOYERR_PARMS, "joyGetDevCapsW returned %u\n", ret );
|
ok( ret == JOYERR_PARMS, "joyGetDevCapsW returned %u\n", ret );
|
||||||
|
|
||||||
memset( &caps, 0xcd, sizeof(caps) );
|
memset( &caps, 0xcd, sizeof(caps) );
|
||||||
|
@ -9803,7 +9799,6 @@ static void test_winmm_joystick(void)
|
||||||
ret = joyGetPosEx( 0, &infoex );
|
ret = joyGetPosEx( 0, &infoex );
|
||||||
/* first call for an index sometimes fail */
|
/* first call for an index sometimes fail */
|
||||||
if (ret == JOYERR_PARMS) ret = joyGetPosEx( 0, &infoex );
|
if (ret == JOYERR_PARMS) ret = joyGetPosEx( 0, &infoex );
|
||||||
todo_wine
|
|
||||||
ok( ret == 0, "joyGetPosEx returned %u\n", ret );
|
ok( ret == 0, "joyGetPosEx returned %u\n", ret );
|
||||||
|
|
||||||
ret = joyGetDevCapsW( 1, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) );
|
ret = joyGetDevCapsW( 1, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) );
|
||||||
|
@ -9811,43 +9806,29 @@ static void test_winmm_joystick(void)
|
||||||
|
|
||||||
memset( &caps, 0xcd, sizeof(caps) );
|
memset( &caps, 0xcd, sizeof(caps) );
|
||||||
ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(caps) );
|
ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(caps) );
|
||||||
todo_wine
|
|
||||||
ok( ret == 0, "joyGetDevCapsW returned %u\n", ret );
|
ok( ret == 0, "joyGetDevCapsW returned %u\n", ret );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%#x", wMid );
|
check_member( caps, expect_caps, "%#x", wMid );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%#x", wPid );
|
check_member( caps, expect_caps, "%#x", wPid );
|
||||||
todo_wine
|
todo_wine
|
||||||
check_member_wstr( caps, expect_caps, szPname );
|
check_member_wstr( caps, expect_caps, szPname );
|
||||||
check_member( caps, expect_caps, "%#x", wXmin );
|
check_member( caps, expect_caps, "%#x", wXmin );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%#x", wXmax );
|
check_member( caps, expect_caps, "%#x", wXmax );
|
||||||
check_member( caps, expect_caps, "%#x", wYmin );
|
check_member( caps, expect_caps, "%#x", wYmin );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%#x", wYmax );
|
check_member( caps, expect_caps, "%#x", wYmax );
|
||||||
check_member( caps, expect_caps, "%#x", wZmin );
|
check_member( caps, expect_caps, "%#x", wZmin );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%#x", wZmax );
|
check_member( caps, expect_caps, "%#x", wZmax );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%#x", wNumButtons );
|
check_member( caps, expect_caps, "%#x", wNumButtons );
|
||||||
check_member( caps, expect_caps, "%#x", wPeriodMin );
|
check_member( caps, expect_caps, "%#x", wPeriodMin );
|
||||||
check_member( caps, expect_caps, "%#x", wPeriodMax );
|
check_member( caps, expect_caps, "%#x", wPeriodMax );
|
||||||
check_member( caps, expect_caps, "%#x", wRmin );
|
check_member( caps, expect_caps, "%#x", wRmin );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%#x", wRmax );
|
check_member( caps, expect_caps, "%#x", wRmax );
|
||||||
check_member( caps, expect_caps, "%#x", wUmin );
|
check_member( caps, expect_caps, "%#x", wUmin );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%#x", wUmax );
|
check_member( caps, expect_caps, "%#x", wUmax );
|
||||||
check_member( caps, expect_caps, "%#x", wVmin );
|
check_member( caps, expect_caps, "%#x", wVmin );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%#x", wVmax );
|
check_member( caps, expect_caps, "%#x", wVmax );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%#x", wCaps );
|
check_member( caps, expect_caps, "%#x", wCaps );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%#x", wMaxAxes );
|
check_member( caps, expect_caps, "%#x", wMaxAxes );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%#x", wNumAxes );
|
check_member( caps, expect_caps, "%#x", wNumAxes );
|
||||||
todo_wine
|
|
||||||
check_member( caps, expect_caps, "%#x", wMaxButtons );
|
check_member( caps, expect_caps, "%#x", wMaxButtons );
|
||||||
check_member_wstr( caps, expect_caps, szRegKey );
|
check_member_wstr( caps, expect_caps, szRegKey );
|
||||||
check_member_wstr( caps, expect_caps, szOEMVxD );
|
check_member_wstr( caps, expect_caps, szOEMVxD );
|
||||||
|
@ -9856,7 +9837,6 @@ static void test_winmm_joystick(void)
|
||||||
check_member_guid( caps, expect_caps, NameGuid );
|
check_member_guid( caps, expect_caps, NameGuid );
|
||||||
|
|
||||||
ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) );
|
ret = joyGetDevCapsW( 0, (JOYCAPSW *)&caps, sizeof(JOYCAPSW) );
|
||||||
todo_wine
|
|
||||||
ok( ret == 0, "joyGetDevCapsW returned %u\n", ret );
|
ok( ret == 0, "joyGetDevCapsW returned %u\n", ret );
|
||||||
ret = joyGetDevCapsW( 0, NULL, sizeof(JOYCAPSW) );
|
ret = joyGetDevCapsW( 0, NULL, sizeof(JOYCAPSW) );
|
||||||
ok( ret == MMSYSERR_INVALPARAM, "joyGetDevCapsW returned %u\n", ret );
|
ok( ret == MMSYSERR_INVALPARAM, "joyGetDevCapsW returned %u\n", ret );
|
||||||
|
@ -9878,29 +9858,19 @@ static void test_winmm_joystick(void)
|
||||||
infoex.dwSize = sizeof(JOYINFOEX);
|
infoex.dwSize = sizeof(JOYINFOEX);
|
||||||
infoex.dwFlags = JOY_RETURNALL;
|
infoex.dwFlags = JOY_RETURNALL;
|
||||||
ret = joyGetPosEx( 0, &infoex );
|
ret = joyGetPosEx( 0, &infoex );
|
||||||
todo_wine
|
|
||||||
ok( ret == 0, "joyGetPosEx returned %u\n", ret );
|
ok( ret == 0, "joyGetPosEx returned %u\n", ret );
|
||||||
check_member( infoex, expect_infoex[0], "%#x", dwSize );
|
check_member( infoex, expect_infoex[0], "%#x", dwSize );
|
||||||
check_member( infoex, expect_infoex[0], "%#x", dwFlags );
|
check_member( infoex, expect_infoex[0], "%#x", dwFlags );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[0], "%#x", dwXpos );
|
check_member( infoex, expect_infoex[0], "%#x", dwXpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[0], "%#x", dwYpos );
|
check_member( infoex, expect_infoex[0], "%#x", dwYpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[0], "%#x", dwZpos );
|
check_member( infoex, expect_infoex[0], "%#x", dwZpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[0], "%#x", dwRpos );
|
check_member( infoex, expect_infoex[0], "%#x", dwRpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[0], "%#x", dwUpos );
|
check_member( infoex, expect_infoex[0], "%#x", dwUpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[0], "%#x", dwVpos );
|
check_member( infoex, expect_infoex[0], "%#x", dwVpos );
|
||||||
check_member( infoex, expect_infoex[0], "%#x", dwButtons );
|
check_member( infoex, expect_infoex[0], "%#x", dwButtons );
|
||||||
check_member( infoex, expect_infoex[0], "%#x", dwButtonNumber );
|
check_member( infoex, expect_infoex[0], "%#x", dwButtonNumber );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[0], "%#x", dwPOV );
|
check_member( infoex, expect_infoex[0], "%#x", dwPOV );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[0], "%#x", dwReserved1 );
|
check_member( infoex, expect_infoex[0], "%#x", dwReserved1 );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[0], "%#x", dwReserved2 );
|
check_member( infoex, expect_infoex[0], "%#x", dwReserved2 );
|
||||||
|
|
||||||
infoex.dwSize = sizeof(JOYINFOEX) - 4;
|
infoex.dwSize = sizeof(JOYINFOEX) - 4;
|
||||||
|
@ -9913,13 +9883,9 @@ static void test_winmm_joystick(void)
|
||||||
ok( ret == JOYERR_PARMS, "joyGetPos returned %u\n", ret );
|
ok( ret == JOYERR_PARMS, "joyGetPos returned %u\n", ret );
|
||||||
memset( &info, 0xcd, sizeof(info) );
|
memset( &info, 0xcd, sizeof(info) );
|
||||||
ret = joyGetPos( 0, &info );
|
ret = joyGetPos( 0, &info );
|
||||||
todo_wine
|
|
||||||
ok( ret == 0, "joyGetPos returned %u\n", ret );
|
ok( ret == 0, "joyGetPos returned %u\n", ret );
|
||||||
todo_wine
|
|
||||||
check_member( info, expect_info, "%#x", wXpos );
|
check_member( info, expect_info, "%#x", wXpos );
|
||||||
todo_wine
|
|
||||||
check_member( info, expect_info, "%#x", wYpos );
|
check_member( info, expect_info, "%#x", wYpos );
|
||||||
todo_wine
|
|
||||||
check_member( info, expect_info, "%#x", wZpos );
|
check_member( info, expect_info, "%#x", wZpos );
|
||||||
check_member( info, expect_info, "%#x", wButtons );
|
check_member( info, expect_info, "%#x", wButtons );
|
||||||
|
|
||||||
|
@ -9953,24 +9919,16 @@ static void test_winmm_joystick(void)
|
||||||
infoex.dwSize = sizeof(JOYINFOEX);
|
infoex.dwSize = sizeof(JOYINFOEX);
|
||||||
infoex.dwFlags = JOY_RETURNALL;
|
infoex.dwFlags = JOY_RETURNALL;
|
||||||
ret = joyGetPosEx( 0, &infoex );
|
ret = joyGetPosEx( 0, &infoex );
|
||||||
todo_wine
|
|
||||||
ok( ret == 0, "joyGetPosEx returned %u\n", ret );
|
ok( ret == 0, "joyGetPosEx returned %u\n", ret );
|
||||||
check_member( infoex, expect_infoex[1], "%#x", dwSize );
|
check_member( infoex, expect_infoex[1], "%#x", dwSize );
|
||||||
check_member( infoex, expect_infoex[1], "%#x", dwFlags );
|
check_member( infoex, expect_infoex[1], "%#x", dwFlags );
|
||||||
check_member( infoex, expect_infoex[1], "%#x", dwXpos );
|
check_member( infoex, expect_infoex[1], "%#x", dwXpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[1], "%#x", dwYpos );
|
check_member( infoex, expect_infoex[1], "%#x", dwYpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[1], "%#x", dwZpos );
|
check_member( infoex, expect_infoex[1], "%#x", dwZpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[1], "%#x", dwRpos );
|
check_member( infoex, expect_infoex[1], "%#x", dwRpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[1], "%#x", dwUpos );
|
check_member( infoex, expect_infoex[1], "%#x", dwUpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[1], "%#x", dwVpos );
|
check_member( infoex, expect_infoex[1], "%#x", dwVpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[1], "%#x", dwButtons );
|
check_member( infoex, expect_infoex[1], "%#x", dwButtons );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[1], "%#x", dwButtonNumber );
|
check_member( infoex, expect_infoex[1], "%#x", dwButtonNumber );
|
||||||
check_member( infoex, expect_infoex[1], "%#x", dwPOV );
|
check_member( infoex, expect_infoex[1], "%#x", dwPOV );
|
||||||
|
|
||||||
|
@ -9983,26 +9941,17 @@ static void test_winmm_joystick(void)
|
||||||
infoex.dwSize = sizeof(JOYINFOEX);
|
infoex.dwSize = sizeof(JOYINFOEX);
|
||||||
infoex.dwFlags = JOY_RETURNALL;
|
infoex.dwFlags = JOY_RETURNALL;
|
||||||
ret = joyGetPosEx( 0, &infoex );
|
ret = joyGetPosEx( 0, &infoex );
|
||||||
todo_wine
|
|
||||||
ok( ret == 0, "joyGetPosEx returned %u\n", ret );
|
ok( ret == 0, "joyGetPosEx returned %u\n", ret );
|
||||||
check_member( infoex, expect_infoex[2], "%#x", dwSize );
|
check_member( infoex, expect_infoex[2], "%#x", dwSize );
|
||||||
check_member( infoex, expect_infoex[2], "%#x", dwFlags );
|
check_member( infoex, expect_infoex[2], "%#x", dwFlags );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[2], "%#x", dwXpos );
|
check_member( infoex, expect_infoex[2], "%#x", dwXpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[2], "%#x", dwYpos );
|
check_member( infoex, expect_infoex[2], "%#x", dwYpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[2], "%#x", dwZpos );
|
check_member( infoex, expect_infoex[2], "%#x", dwZpos );
|
||||||
check_member( infoex, expect_infoex[2], "%#x", dwRpos );
|
check_member( infoex, expect_infoex[2], "%#x", dwRpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[2], "%#x", dwUpos );
|
check_member( infoex, expect_infoex[2], "%#x", dwUpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[2], "%#x", dwVpos );
|
check_member( infoex, expect_infoex[2], "%#x", dwVpos );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[2], "%#x", dwButtons );
|
check_member( infoex, expect_infoex[2], "%#x", dwButtons );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[2], "%#x", dwButtonNumber );
|
check_member( infoex, expect_infoex[2], "%#x", dwButtonNumber );
|
||||||
todo_wine
|
|
||||||
check_member( infoex, expect_infoex[2], "%#x", dwPOV );
|
check_member( infoex, expect_infoex[2], "%#x", dwPOV );
|
||||||
|
|
||||||
ret = IDirectInputDevice8_Release( device );
|
ret = IDirectInputDevice8_Release( device );
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
EXTRADEFS = -D_WINMM_
|
EXTRADEFS = -D_WINMM_
|
||||||
MODULE = winmm.dll
|
MODULE = winmm.dll
|
||||||
IMPORTLIB = winmm
|
IMPORTLIB = winmm
|
||||||
IMPORTS = uuid user32 advapi32 ole32 msacm32
|
IMPORTS = uuid user32 advapi32 ole32 msacm32 dinput8
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
driver.c \
|
driver.c \
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
|
||||||
/*
|
/*
|
||||||
* joystick functions
|
* joystick functions
|
||||||
*
|
*
|
||||||
* Copyright 1997 Andreas Mohr
|
* Copyright 1997 Andreas Mohr
|
||||||
* 2000 Wolfgang Schwotzer
|
* Copyright 2000 Wolfgang Schwotzer
|
||||||
* Eric Pouech
|
* Copyright 2000 Eric Pouech
|
||||||
|
* Copyright 2020 Zebediah Figura for CodeWeavers
|
||||||
|
* Copyright 2021 Rémi Bernon for CodeWeavers
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -30,11 +32,11 @@
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "mmsystem.h"
|
#include "mmsystem.h"
|
||||||
#include "wingdi.h"
|
|
||||||
#include "winuser.h"
|
|
||||||
#include "winnls.h"
|
|
||||||
|
|
||||||
#include "mmddk.h"
|
#include "initguid.h"
|
||||||
|
#include "dinput.h"
|
||||||
|
|
||||||
|
#include "winemm.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
@ -49,19 +51,185 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||||
};
|
};
|
||||||
static CRITICAL_SECTION joystick_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
|
static CRITICAL_SECTION joystick_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
struct joystick_state
|
||||||
|
{
|
||||||
|
LONG x;
|
||||||
|
LONG y;
|
||||||
|
LONG z;
|
||||||
|
LONG u;
|
||||||
|
LONG v;
|
||||||
|
LONG r;
|
||||||
|
LONG pov;
|
||||||
|
BYTE buttons[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
static const DIOBJECTDATAFORMAT object_formats[] =
|
||||||
|
{
|
||||||
|
{ &GUID_XAxis, offsetof(struct joystick_state, x), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION },
|
||||||
|
{ &GUID_YAxis, offsetof(struct joystick_state, y), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION },
|
||||||
|
{ &GUID_ZAxis, offsetof(struct joystick_state, z), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION },
|
||||||
|
{ &GUID_RzAxis, offsetof(struct joystick_state, r), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION },
|
||||||
|
{ &GUID_Slider, offsetof(struct joystick_state, u), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION },
|
||||||
|
{ &GUID_RxAxis, offsetof(struct joystick_state, v), DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION },
|
||||||
|
{ &GUID_POV, offsetof(struct joystick_state, pov), DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[0]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[1]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[2]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[3]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[4]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[5]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[6]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[7]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[8]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[9]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[10]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[11]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[12]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[13]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[14]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[15]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[16]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[17]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[18]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[19]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[20]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[21]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[22]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[23]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[24]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[25]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[26]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[27]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[28]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[29]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[30]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
{ NULL, offsetof(struct joystick_state, buttons[31]), DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const DIDATAFORMAT data_format =
|
||||||
|
{
|
||||||
|
.dwSize = sizeof(DIDATAFORMAT),
|
||||||
|
.dwObjSize = sizeof(DIOBJECTDATAFORMAT),
|
||||||
|
.dwFlags = DIDF_ABSAXIS,
|
||||||
|
.dwDataSize = sizeof(struct joystick_state),
|
||||||
|
.dwNumObjs = ARRAY_SIZE(object_formats),
|
||||||
|
.rgodf = (DIOBJECTDATAFORMAT *)object_formats,
|
||||||
|
};
|
||||||
|
|
||||||
#define JOY_PERIOD_MIN (10) /* min Capture time period */
|
#define JOY_PERIOD_MIN (10) /* min Capture time period */
|
||||||
#define JOY_PERIOD_MAX (1000) /* max Capture time period */
|
#define JOY_PERIOD_MAX (1000) /* max Capture time period */
|
||||||
|
|
||||||
typedef struct tagWINE_JOYSTICK {
|
struct joystick
|
||||||
|
{
|
||||||
|
DIDEVICEINSTANCEW instance;
|
||||||
|
IDirectInputDevice8W *device;
|
||||||
|
struct joystick_state state;
|
||||||
|
HANDLE event;
|
||||||
|
|
||||||
JOYINFO info;
|
JOYINFO info;
|
||||||
HWND capture;
|
HWND capture;
|
||||||
UINT timer;
|
UINT timer;
|
||||||
DWORD threshold;
|
DWORD threshold;
|
||||||
BOOL changed;
|
BOOL changed;
|
||||||
HDRVR driver;
|
ULONG last_check;
|
||||||
} WINE_JOYSTICK;
|
};
|
||||||
|
|
||||||
static WINE_JOYSTICK joysticks[16];
|
static DIDEVICEINSTANCEW instances[16];
|
||||||
|
static struct joystick joysticks[16];
|
||||||
|
static IDirectInput8W *dinput;
|
||||||
|
|
||||||
|
static BOOL CALLBACK enum_instances( const DIDEVICEINSTANCEW *instance, void *context )
|
||||||
|
{
|
||||||
|
ULONG index = *(ULONG *)context;
|
||||||
|
BYTE type = instance->dwDevType;
|
||||||
|
|
||||||
|
if (type == DI8DEVTYPE_MOUSE) return DIENUM_CONTINUE;
|
||||||
|
if (type == DI8DEVTYPE_KEYBOARD) return DIENUM_CONTINUE;
|
||||||
|
|
||||||
|
instances[index++] = *instance;
|
||||||
|
if (index >= ARRAY_SIZE(instances)) return DIENUM_STOP;
|
||||||
|
*(ULONG *)context = index;
|
||||||
|
return DIENUM_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void joystick_load( HINSTANCE instance )
|
||||||
|
{
|
||||||
|
HRESULT hr = DirectInput8Create( instance, DIRECTINPUT_VERSION, &IID_IDirectInput8W,
|
||||||
|
(void **)&dinput, NULL );
|
||||||
|
if (FAILED(hr)) WARN( "could not create dinput instance, hr %#x\n", hr );
|
||||||
|
}
|
||||||
|
|
||||||
|
void joystick_unload()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!dinput) return;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(joysticks); i++)
|
||||||
|
{
|
||||||
|
if (!joysticks[i].device) continue;
|
||||||
|
IDirectInputDevice8_Release( joysticks[i].device );
|
||||||
|
CloseHandle( joysticks[i].event );
|
||||||
|
}
|
||||||
|
|
||||||
|
IDirectInput8_Release( dinput );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void find_joysticks(void)
|
||||||
|
{
|
||||||
|
IDirectInputDevice8W *device;
|
||||||
|
HANDLE event;
|
||||||
|
DWORD index;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (!dinput) return;
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
IDirectInput8_EnumDevices( dinput, DI8DEVCLASS_ALL, enum_instances, &index, DIEDFL_ATTACHEDONLY );
|
||||||
|
TRACE( "found %u device instances\n", index );
|
||||||
|
|
||||||
|
while (index--)
|
||||||
|
{
|
||||||
|
if (!memcmp( &joysticks[index].instance, &instances[index], sizeof(DIDEVICEINSTANCEW) ))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (joysticks[index].device)
|
||||||
|
{
|
||||||
|
IDirectInputDevice8_Release( joysticks[index].device );
|
||||||
|
CloseHandle( joysticks[index].event );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(event = CreateEventW( NULL, FALSE, FALSE, NULL )))
|
||||||
|
WARN( "could not event for device, error %u\n", GetLastError() );
|
||||||
|
else if (FAILED(hr = IDirectInput8_CreateDevice( dinput, &instances[index].guidInstance, &device, NULL )))
|
||||||
|
WARN( "could not create device %s instance, hr %#x\n",
|
||||||
|
debugstr_guid( &instances[index].guidInstance ), hr );
|
||||||
|
else if (FAILED(hr = IDirectInputDevice8_SetEventNotification( device, event )))
|
||||||
|
WARN( "SetEventNotification device %p hr %#x\n", device, hr );
|
||||||
|
else if (FAILED(hr = IDirectInputDevice8_SetCooperativeLevel( device, NULL, DISCL_NONEXCLUSIVE|DISCL_BACKGROUND )))
|
||||||
|
WARN( "SetCooperativeLevel device %p hr %#x\n", device, hr );
|
||||||
|
else if (FAILED(hr = IDirectInputDevice8_SetDataFormat( device, &data_format )))
|
||||||
|
WARN( "SetDataFormat device %p hr %#x\n", device, hr );
|
||||||
|
else if (FAILED(hr = IDirectInputDevice8_Acquire( device )))
|
||||||
|
WARN( "Acquire device %p hr %#x\n", device, hr );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE( "opened device %p event %p\n", device, event );
|
||||||
|
|
||||||
|
memset( &joysticks[index], 0, sizeof(struct joystick) );
|
||||||
|
joysticks[index].instance = instances[index];
|
||||||
|
joysticks[index].device = device;
|
||||||
|
joysticks[index].event = event;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle( event );
|
||||||
|
if (device) IDirectInputDevice8_Release( device );
|
||||||
|
memmove( joysticks + index, joysticks + index + 1,
|
||||||
|
(ARRAY_SIZE(joysticks) - index - 1) * sizeof(struct joystick) );
|
||||||
|
memset( &joysticks[ARRAY_SIZE(joysticks) - 1], 0, sizeof(struct joystick) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
|
static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
|
||||||
{
|
{
|
||||||
|
@ -69,29 +237,6 @@ static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
|
||||||
return diff <= max_diff;
|
return diff <= max_diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* JOY_LoadDriver [internal]
|
|
||||||
*/
|
|
||||||
static BOOL JOY_LoadDriver(DWORD dwJoyID)
|
|
||||||
{
|
|
||||||
static BOOL winejoystick_missing = FALSE;
|
|
||||||
|
|
||||||
if (dwJoyID >= ARRAY_SIZE(joysticks) || winejoystick_missing) return FALSE;
|
|
||||||
if (joysticks[dwJoyID].driver) return TRUE;
|
|
||||||
|
|
||||||
joysticks[dwJoyID].driver = OpenDriverA( "winejoystick.drv", 0, dwJoyID );
|
|
||||||
|
|
||||||
if (!joysticks[dwJoyID].driver)
|
|
||||||
{
|
|
||||||
WARN("OpenDriverA(\"winejoystick.drv\") failed\n");
|
|
||||||
|
|
||||||
/* The default driver is missing, don't attempt to load it again */
|
|
||||||
winejoystick_missing = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (joysticks[dwJoyID].driver != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CALLBACK joystick_timer( HWND hwnd, UINT msg, UINT_PTR timer, DWORD time )
|
static void CALLBACK joystick_timer( HWND hwnd, UINT msg, UINT_PTR timer, DWORD time )
|
||||||
{
|
{
|
||||||
MMRESULT res;
|
MMRESULT res;
|
||||||
|
@ -163,6 +308,22 @@ UINT WINAPI DECLSPEC_HOTPATCH joyGetNumDevs(void)
|
||||||
*/
|
*/
|
||||||
MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, UINT size )
|
MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, UINT size )
|
||||||
{
|
{
|
||||||
|
DIDEVICEOBJECTINSTANCEW instance = {.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW)};
|
||||||
|
DIDEVCAPS dicaps = {.dwSize = sizeof(DIDEVCAPS)};
|
||||||
|
DIPROPDWORD diprop =
|
||||||
|
{
|
||||||
|
.diph =
|
||||||
|
{
|
||||||
|
.dwSize = sizeof(DIPROPDWORD),
|
||||||
|
.dwHeaderSize = sizeof(DIPROPHEADER),
|
||||||
|
.dwHow = DIPH_DEVICE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
MMRESULT res = JOYERR_NOERROR;
|
||||||
|
IDirectInputDevice8W *device;
|
||||||
|
ULONG ticks = GetTickCount();
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "id %d, caps %p, size %u.\n", (int)id, caps, size );
|
TRACE( "id %d, caps %p, size %u.\n", (int)id, caps, size );
|
||||||
|
|
||||||
if (!caps) return MMSYSERR_INVALPARAM;
|
if (!caps) return MMSYSERR_INVALPARAM;
|
||||||
|
@ -173,12 +334,67 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsW( UINT_PTR id, JOYCAPSW *caps, U
|
||||||
if (id == ~(UINT_PTR)0) return JOYERR_NOERROR;
|
if (id == ~(UINT_PTR)0) return JOYERR_NOERROR;
|
||||||
|
|
||||||
if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
|
if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
|
||||||
if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
|
|
||||||
|
|
||||||
caps->wPeriodMin = JOY_PERIOD_MIN; /* FIXME */
|
EnterCriticalSection( &joystick_cs );
|
||||||
caps->wPeriodMax = JOY_PERIOD_MAX; /* FIXME (same as MS Joystick Driver) */
|
|
||||||
|
|
||||||
return SendDriverMessage( joysticks[id].driver, JDD_GETDEVCAPS, (LPARAM)caps, size );
|
if (!(device = joysticks[id].device) && (ticks - joysticks[id].last_check) >= 2000)
|
||||||
|
{
|
||||||
|
joysticks[id].last_check = ticks;
|
||||||
|
find_joysticks();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(device = joysticks[id].device)) res = JOYERR_PARMS;
|
||||||
|
else if (FAILED(hr = IDirectInputDevice8_GetCapabilities( device, &dicaps )))
|
||||||
|
{
|
||||||
|
WARN( "GetCapabilities device %p returned %#x\n", device, hr );
|
||||||
|
res = JOYERR_PARMS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = IDirectInputDevice8_GetProperty( device, DIPROP_VIDPID, &diprop.diph );
|
||||||
|
if (FAILED(hr)) WARN( "GetProperty device %p returned %#x\n", device, hr );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
caps->wMid = LOWORD(diprop.dwData);
|
||||||
|
caps->wPid = HIWORD(diprop.dwData);
|
||||||
|
}
|
||||||
|
|
||||||
|
wcscpy( caps->szPname, L"Wine joystick driver" );
|
||||||
|
caps->wXmin = 0;
|
||||||
|
caps->wXmax = 0xffff;
|
||||||
|
caps->wYmin = 0;
|
||||||
|
caps->wYmax = 0xffff;
|
||||||
|
caps->wZmin = 0;
|
||||||
|
caps->wZmax = 0xffff;
|
||||||
|
caps->wNumButtons = dicaps.dwButtons;
|
||||||
|
caps->wPeriodMin = JOY_PERIOD_MIN;
|
||||||
|
caps->wPeriodMax = JOY_PERIOD_MAX;
|
||||||
|
caps->wRmin = 0;
|
||||||
|
caps->wRmax = 0xffff;
|
||||||
|
caps->wUmin = 0;
|
||||||
|
caps->wUmax = 0xffff;
|
||||||
|
caps->wVmin = 0;
|
||||||
|
caps->wVmax = 0xffff;
|
||||||
|
caps->wCaps = 0;
|
||||||
|
caps->wMaxAxes = 6;
|
||||||
|
caps->wNumAxes = min( dicaps.dwAxes, caps->wMaxAxes );
|
||||||
|
caps->wMaxButtons = 32;
|
||||||
|
|
||||||
|
hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, z), DIPH_BYOFFSET );
|
||||||
|
if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASZ;
|
||||||
|
hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, r), DIPH_BYOFFSET );
|
||||||
|
if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASR;
|
||||||
|
hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, u), DIPH_BYOFFSET );
|
||||||
|
if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASU;
|
||||||
|
hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, v), DIPH_BYOFFSET );
|
||||||
|
if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASV;
|
||||||
|
hr = IDirectInputDevice8_GetObjectInfo( device, &instance, offsetof(struct joystick_state, pov), DIPH_BYOFFSET );
|
||||||
|
if (SUCCEEDED(hr)) caps->wCaps |= JOYCAPS_HASPOV|JOYCAPS_POV4DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection( &joystick_cs );
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -243,25 +459,60 @@ MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetDevCapsA( UINT_PTR id, JOYCAPSA *caps, U
|
||||||
*/
|
*/
|
||||||
MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx( UINT id, JOYINFOEX *info )
|
MMRESULT WINAPI DECLSPEC_HOTPATCH joyGetPosEx( UINT id, JOYINFOEX *info )
|
||||||
{
|
{
|
||||||
|
DWORD i, ticks = GetTickCount();
|
||||||
|
MMRESULT res = JOYERR_NOERROR;
|
||||||
|
IDirectInputDevice8W *device;
|
||||||
|
struct joystick_state state;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE( "id %u, info %p.\n", id, info );
|
TRACE( "id %u, info %p.\n", id, info );
|
||||||
|
|
||||||
if (!info) return MMSYSERR_INVALPARAM;
|
if (!info) return MMSYSERR_INVALPARAM;
|
||||||
if (id >= ARRAY_SIZE(joysticks) || info->dwSize < sizeof(JOYINFOEX)) return JOYERR_PARMS;
|
if (id >= ARRAY_SIZE(joysticks) || info->dwSize < sizeof(JOYINFOEX)) return JOYERR_PARMS;
|
||||||
if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
|
|
||||||
|
|
||||||
info->dwXpos = 0;
|
EnterCriticalSection( &joystick_cs );
|
||||||
info->dwYpos = 0;
|
|
||||||
info->dwZpos = 0;
|
|
||||||
info->dwRpos = 0;
|
|
||||||
info->dwUpos = 0;
|
|
||||||
info->dwVpos = 0;
|
|
||||||
info->dwButtons = 0;
|
|
||||||
info->dwButtonNumber = 0;
|
|
||||||
info->dwPOV = 0;
|
|
||||||
info->dwReserved1 = 0;
|
|
||||||
info->dwReserved2 = 0;
|
|
||||||
|
|
||||||
return SendDriverMessage( joysticks[id].driver, JDD_GETPOSEX, (LPARAM)info, 0 );
|
if (!(device = joysticks[id].device) && (ticks - joysticks[id].last_check) >= 2000)
|
||||||
|
{
|
||||||
|
joysticks[id].last_check = ticks;
|
||||||
|
find_joysticks();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(device = joysticks[id].device))
|
||||||
|
res = JOYERR_PARMS;
|
||||||
|
else if (FAILED(hr = IDirectInputDevice8_GetDeviceState( device, sizeof(struct joystick_state), &state )))
|
||||||
|
{
|
||||||
|
WARN( "GetDeviceState device %p returned %#x\n", device, hr );
|
||||||
|
res = JOYERR_PARMS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (info->dwFlags & JOY_RETURNX) info->dwXpos = state.x;
|
||||||
|
if (info->dwFlags & JOY_RETURNY) info->dwYpos = state.y;
|
||||||
|
if (info->dwFlags & JOY_RETURNZ) info->dwZpos = state.z;
|
||||||
|
if (info->dwFlags & JOY_RETURNR) info->dwRpos = state.r;
|
||||||
|
if (info->dwFlags & JOY_RETURNU) info->dwUpos = state.u;
|
||||||
|
if (info->dwFlags & JOY_RETURNV) info->dwVpos = state.v;
|
||||||
|
if (info->dwFlags & JOY_RETURNPOV)
|
||||||
|
{
|
||||||
|
if (state.pov == ~0) info->dwPOV = 0xffff;
|
||||||
|
else info->dwPOV = state.pov;
|
||||||
|
}
|
||||||
|
if (info->dwFlags & JOY_RETURNBUTTONS)
|
||||||
|
{
|
||||||
|
info->dwButtonNumber = info->dwButtons = 0;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(state.buttons); ++i)
|
||||||
|
{
|
||||||
|
if (!state.buttons[i]) continue;
|
||||||
|
info->dwButtonNumber++;
|
||||||
|
info->dwButtons |= 1 << i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection( &joystick_cs );
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -313,7 +564,6 @@ MMRESULT WINAPI joyReleaseCapture( UINT id )
|
||||||
TRACE( "id %u.\n", id );
|
TRACE( "id %u.\n", id );
|
||||||
|
|
||||||
if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
|
if (id >= ARRAY_SIZE(joysticks)) return JOYERR_PARMS;
|
||||||
if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
|
|
||||||
|
|
||||||
EnterCriticalSection( &joystick_cs );
|
EnterCriticalSection( &joystick_cs );
|
||||||
|
|
||||||
|
@ -343,7 +593,6 @@ MMRESULT WINAPI joySetCapture( HWND hwnd, UINT id, UINT period, BOOL changed )
|
||||||
if (id >= ARRAY_SIZE(joysticks) || hwnd == 0) return JOYERR_PARMS;
|
if (id >= ARRAY_SIZE(joysticks) || hwnd == 0) return JOYERR_PARMS;
|
||||||
if (period < JOY_PERIOD_MIN) period = JOY_PERIOD_MIN;
|
if (period < JOY_PERIOD_MIN) period = JOY_PERIOD_MIN;
|
||||||
else if (period > JOY_PERIOD_MAX) period = JOY_PERIOD_MAX;
|
else if (period > JOY_PERIOD_MAX) period = JOY_PERIOD_MAX;
|
||||||
if (!JOY_LoadDriver( id )) return MMSYSERR_NODRIVER;
|
|
||||||
|
|
||||||
EnterCriticalSection( &joystick_cs );
|
EnterCriticalSection( &joystick_cs );
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,9 @@ MMRESULT WINMM_CheckCallback(DWORD_PTR dwCallback, DWORD fdwOpen, BOOL mixer) DE
|
||||||
|
|
||||||
void WINMM_DeleteWaveform(void) DECLSPEC_HIDDEN;
|
void WINMM_DeleteWaveform(void) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
void joystick_load( HMODULE instance ) DECLSPEC_HIDDEN;
|
||||||
|
void joystick_unload( void ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
extern CRITICAL_SECTION WINMM_cs DECLSPEC_HIDDEN;
|
extern CRITICAL_SECTION WINMM_cs DECLSPEC_HIDDEN;
|
||||||
extern HINSTANCE hWinMM32Instance DECLSPEC_HIDDEN;
|
extern HINSTANCE hWinMM32Instance DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -145,11 +145,13 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
||||||
if (!WINMM_CreateIData(hInstDLL))
|
if (!WINMM_CreateIData(hInstDLL))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
joystick_load( hInstDLL );
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
if(fImpLoad)
|
if(fImpLoad)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
joystick_unload();
|
||||||
MCI_SendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_WAIT, 0L);
|
MCI_SendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, MCI_WAIT, 0L);
|
||||||
MMDRV_Exit();
|
MMDRV_Exit();
|
||||||
DRIVER_UnloadAll();
|
DRIVER_UnloadAll();
|
||||||
|
|
Loading…
Reference in a new issue