ReactOS 0.4.15-dev-7788-g1ad9096
joystick.c
Go to the documentation of this file.
1/* DirectInput Generic Joystick device
2 *
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998,1999 Lionel Ulmer
5 * Copyright 2000-2001 TransGaming Technologies Inc.
6 * Copyright 2009 Aric Stewart, CodeWeavers
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23/*
24 * To Do:
25 * dead zone
26 * force feedback
27 */
28
29#include <stdio.h>
30
31#include "device_private.h"
32#include "joystick_private.h"
33#include "wine/debug.h"
34#include "wine/heap.h"
35#include "winreg.h"
36
38
39#define VID_MICROSOFT 0x045e
40
41static const WORD PID_XBOX_CONTROLLERS[] = {
42 0x0202, /* Xbox Controller */
43 0x0285, /* Xbox Controller S */
44 0x0289, /* Xbox Controller S */
45 0x028e, /* Xbox360 Controller */
46 0x028f, /* Xbox360 Wireless Controller */
47 0x02d1, /* Xbox One Controller */
48 0x02dd, /* Xbox One Controller (Covert Forces/Firmware 2015) */
49 0x02e0, /* Xbox One X Controller */
50 0x02e3, /* Xbox One Elite Controller */
51 0x02e6, /* Wireless XBox Controller Dongle */
52 0x02ea, /* Xbox One S Controller */
53 0x02fd, /* Xbox One S Controller (Firmware 2017) */
54 0x0719, /* Xbox 360 Wireless Adapter */
55};
56
57/* Windows uses this GUID for guidProduct on non-keyboard/mouse devices.
58 * Data1 contains the device VID (low word) and PID (high word).
59 * Data4 ends with the ASCII bytes "PIDVID".
60 */
61const GUID DInput_PIDVID_Product_GUID = { /* device_pidvid-0000-0000-0000-504944564944 */
62 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44}
63};
64
65static inline JoystickGenericImpl *impl_from_IDirectInputDevice8A(IDirectInputDevice8A *iface)
66{
67 return CONTAINING_RECORD(CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8A_iface), JoystickGenericImpl, base);
68}
69static inline JoystickGenericImpl *impl_from_IDirectInputDevice8W(IDirectInputDevice8W *iface)
70{
71 return CONTAINING_RECORD(CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8W_iface), JoystickGenericImpl, base);
72}
73static inline IDirectInputDevice8A *IDirectInputDevice8A_from_impl(JoystickGenericImpl *This)
74{
75 return &This->base.IDirectInputDevice8A_iface;
76}
77static inline IDirectInputDevice8W *IDirectInputDevice8W_from_impl(JoystickGenericImpl *This)
78{
79 return &This->base.IDirectInputDevice8W_iface;
80}
81
83{
84 if (IsEqualGUID(guid, &GUID_ConstantForce)) {
86 } else if (IsEqualGUID(guid, &GUID_Square)
87 || IsEqualGUID(guid, &GUID_Sine)
88 || IsEqualGUID(guid, &GUID_Triangle)
89 || IsEqualGUID(guid, &GUID_SawtoothUp)
90 || IsEqualGUID(guid, &GUID_SawtoothDown)) {
91 return DIEFT_PERIODIC;
92 } else if (IsEqualGUID(guid, &GUID_RampForce)) {
93 return DIEFT_RAMPFORCE;
94 } else if (IsEqualGUID(guid, &GUID_Spring)
95 || IsEqualGUID(guid, &GUID_Damper)
96 || IsEqualGUID(guid, &GUID_Inertia)
97 || IsEqualGUID(guid, &GUID_Friction)) {
98 return DIEFT_CONDITION;
99 } else if (IsEqualGUID(guid, &GUID_CustomForce)) {
100 return DIEFT_CUSTOMFORCE;
101 } else {
102 WARN("GUID (%s) is not a known force type\n", _dump_dinput_GUID(guid));
103 return 0;
104 }
105}
106
108{
109 if (is_joystick)
110 return version >= 0x0800 ? DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8) :
112
113 return version >= 0x0800 ? DI8DEVTYPE_GAMEPAD | (DI8DEVTYPEJOYSTICK_STANDARD << 8) :
115}
116
118{
119 if (TRACE_ON(dinput)) {
120 unsigned int i;
121 static const struct {
122 DWORD mask;
123 const char *name;
124 } flags[] = {
125#define FE(x) { x, #x}
131#undef FE
132 };
133 for (i = 0; i < ARRAY_SIZE(flags); i++)
134 if (flags[i].mask & dwFlags)
135 TRACE("%s ", flags[i].name);
136 TRACE("\n");
137 }
138}
139
141{
142 if (env->dwSize != sizeof(DIENVELOPE)) {
143 WARN("Non-standard DIENVELOPE structure size %d.\n", env->dwSize);
144 }
145 TRACE("Envelope has attack (level: %d time: %d), fade (level: %d time: %d)\n",
146 env->dwAttackLevel, env->dwAttackTime, env->dwFadeLevel, env->dwFadeTime);
147}
148
150{
151 TRACE("Constant force has magnitude %d\n", frc->lMagnitude);
152}
153
155{
156 TRACE("Periodic force has magnitude %d, offset %d, phase %d, period %d\n",
157 frc->dwMagnitude, frc->lOffset, frc->dwPhase, frc->dwPeriod);
158}
159
161{
162 TRACE("Ramp force has start %d, end %d\n",
163 frc->lStart, frc->lEnd);
164}
165
167{
168 TRACE("Condition has offset %d, pos/neg coefficients %d and %d, pos/neg saturations %d and %d, deadband %d\n",
171}
172
174{
175 unsigned int i;
176 TRACE("Custom force uses %d channels, sample period %d. Has %d samples at %p.\n",
177 frc->cChannels, frc->dwSamplePeriod, frc->cSamples, frc->rglForceData);
178 if (frc->cSamples % frc->cChannels != 0)
179 WARN("Custom force has a non-integral samples-per-channel count!\n");
180 if (TRACE_ON(dinput)) {
181 TRACE("Custom force data (time aligned, axes in order):\n");
182 for (i = 1; i <= frc->cSamples; ++i) {
183 TRACE("%d ", frc->rglForceData[i]);
184 if (i % frc->cChannels == 0)
185 TRACE("\n");
186 }
187 }
188}
189
191{
193 unsigned int i;
194
195 TRACE("Dumping DIEFFECT structure:\n");
196 TRACE(" - dwSize: %d\n", eff->dwSize);
197 if ((eff->dwSize != sizeof(DIEFFECT)) && (eff->dwSize != sizeof(DIEFFECT_DX5))) {
198 WARN("Non-standard DIEFFECT structure size %d\n", eff->dwSize);
199 }
200 TRACE(" - dwFlags: %d\n", eff->dwFlags);
201 TRACE(" ");
203 TRACE(" - dwDuration: %d\n", eff->dwDuration);
204 TRACE(" - dwGain: %d\n", eff->dwGain);
205
206 if (eff->dwGain > 10000)
207 WARN("dwGain is out of range (>10,000)\n");
208
209 TRACE(" - dwTriggerButton: %d\n", eff->dwTriggerButton);
210 TRACE(" - dwTriggerRepeatInterval: %d\n", eff->dwTriggerRepeatInterval);
211 TRACE(" - rglDirection: %p\n", eff->rglDirection);
212 TRACE(" - cbTypeSpecificParams: %d\n", eff->cbTypeSpecificParams);
213 TRACE(" - lpvTypeSpecificParams: %p\n", eff->lpvTypeSpecificParams);
214
215 /* Only trace some members if dwFlags indicates they have data */
216 if (dwFlags & DIEP_AXES) {
217 TRACE(" - cAxes: %d\n", eff->cAxes);
218 TRACE(" - rgdwAxes: %p\n", eff->rgdwAxes);
219
220 if (TRACE_ON(dinput) && eff->rgdwAxes) {
221 TRACE(" ");
222 for (i = 0; i < eff->cAxes; ++i)
223 TRACE("%d ", eff->rgdwAxes[i]);
224 TRACE("\n");
225 }
226 }
227
228 if (dwFlags & DIEP_ENVELOPE) {
229 TRACE(" - lpEnvelope: %p\n", eff->lpEnvelope);
230 if (eff->lpEnvelope != NULL)
232 }
233
234 if (eff->dwSize > sizeof(DIEFFECT_DX5))
235 TRACE(" - dwStartDelay: %d\n", eff->dwStartDelay);
236
237 if (type == DIEFT_CONSTANTFORCE) {
238 if (eff->cbTypeSpecificParams != sizeof(DICONSTANTFORCE)) {
239 WARN("Effect claims to be a constant force but the type-specific params are the wrong size!\n");
240 } else {
242 }
243 } else if (type == DIEFT_PERIODIC) {
244 if (eff->cbTypeSpecificParams != sizeof(DIPERIODIC)) {
245 WARN("Effect claims to be a periodic force but the type-specific params are the wrong size!\n");
246 } else {
248 }
249 } else if (type == DIEFT_RAMPFORCE) {
250 if (eff->cbTypeSpecificParams != sizeof(DIRAMPFORCE)) {
251 WARN("Effect claims to be a ramp force but the type-specific params are the wrong size!\n");
252 } else {
254 }
255 } else if (type == DIEFT_CONDITION) {
256 if (eff->cbTypeSpecificParams == sizeof(DICONDITION)) {
258 } else if (eff->cbTypeSpecificParams == 2 * sizeof(DICONDITION)) {
262 } else {
263 WARN("Effect claims to be a condition but the type-specific params are the wrong size!\n");
264 }
265 } else if (type == DIEFT_CUSTOMFORCE) {
266 if (eff->cbTypeSpecificParams != sizeof(DICUSTOMFORCE)) {
267 WARN("Effect claims to be a custom force but the type-specific params are the wrong size!\n");
268 } else {
270 }
271 }
272}
273
275{
276 static const char disabled_str[] = "disabled";
277 static const char joystick_key[] = "Joysticks";
278 char buffer[MAX_PATH];
279 HKEY hkey, appkey, temp;
280 BOOL do_disable = FALSE;
281
282 get_app_key(&hkey, &appkey);
283
284 /* Joystick settings are in the 'joysticks' subkey */
285 if (appkey)
286 {
287 if (RegOpenKeyA(appkey, joystick_key, &temp)) temp = 0;
288 RegCloseKey(appkey);
289 appkey = temp;
290 }
291 if (hkey)
292 {
293 if (RegOpenKeyA(hkey, joystick_key, &temp)) temp = 0;
294 RegCloseKey(hkey);
295 hkey = temp;
296 }
297
298 /* Look for the "controllername"="disabled" key */
299 if (!get_config_key(hkey, appkey, name, buffer, sizeof(buffer)))
300 if (!strcmp(disabled_str, buffer))
301 {
302 TRACE("Disabling joystick '%s' based on registry key.\n", name);
303 do_disable = TRUE;
304 }
305
306 if (appkey) RegCloseKey(appkey);
307 if (hkey) RegCloseKey(hkey);
308
309 return do_disable;
310}
311
313{
314 int i;
315
316 if (vid == VID_MICROSOFT)
317 {
318 for (i = 0; i < ARRAY_SIZE(PID_XBOX_CONTROLLERS); i++)
319 if (pid == PID_XBOX_CONTROLLERS[i]) return TRUE;
320 }
321
322 return (devcaps->dwAxes == 6 && devcaps->dwButtons >= 14);
323}
324
325static void remap_init(JoystickGenericImpl *This, int obj, ObjProps *remap_props)
326{
327 /* Configure as if nothing changed so the helper functions can only change
328 * what they need, thus reducing code duplication. */
329 remap_props->lDevMin = remap_props->lMin = This->props[obj].lMin;
330 remap_props->lDevMax = remap_props->lMax = This->props[obj].lMax;
331
332 remap_props->lDeadZone = This->props[obj].lDeadZone;
333 remap_props->lSaturation = This->props[obj].lSaturation;
334}
335
336static void remap_apply(JoystickGenericImpl *This, int obj, ObjProps *remap_props)
337{
338 /* Many games poll the joystick immediately after setting the range
339 * for calibration purposes, so the old values need to be remapped
340 * to the new range before it does so */
341 switch (This->base.data_format.wine_df->rgodf[obj].dwOfs){
342 case DIJOFS_X : This->js.lX = joystick_map_axis(remap_props, This->js.lX); break;
343 case DIJOFS_Y : This->js.lY = joystick_map_axis(remap_props, This->js.lY); break;
344 case DIJOFS_Z : This->js.lZ = joystick_map_axis(remap_props, This->js.lZ); break;
345 case DIJOFS_RX : This->js.lRx = joystick_map_axis(remap_props, This->js.lRx); break;
346 case DIJOFS_RY : This->js.lRy = joystick_map_axis(remap_props, This->js.lRy); break;
347 case DIJOFS_RZ : This->js.lRz = joystick_map_axis(remap_props, This->js.lRz); break;
348 case DIJOFS_SLIDER(0): This->js.rglSlider[0] = joystick_map_axis(remap_props, This->js.rglSlider[0]); break;
349 case DIJOFS_SLIDER(1): This->js.rglSlider[1] = joystick_map_axis(remap_props, This->js.rglSlider[1]); break;
350 default: break;
351 }
352}
353
355{
356 ObjProps remap_props;
357 remap_init(This, obj, &remap_props);
358
359 remap_props.lMin = pr->lMin;
360 remap_props.lMax = pr->lMax;
361
362 remap_apply(This, obj, &remap_props);
363
364 /* Store new values */
365 This->props[obj].lMin = pr->lMin;
366 This->props[obj].lMax = pr->lMax;
367}
368
370{
371 ObjProps remap_props;
372 remap_init(This, obj, &remap_props);
373
374 remap_props.lDeadZone = pd->dwData;
375
376 remap_apply(This, obj, &remap_props);
377
378 /* Store new value */
379 This->props[obj].lDeadZone = pd->dwData;
380}
381
383{
384 ObjProps remap_props;
385 remap_init(This, obj, &remap_props);
386
387 remap_props.lSaturation = pd->dwData;
388
389 remap_apply(This, obj, &remap_props);
390
391 /* Store new value */
392 This->props[obj].lSaturation = pd->dwData;
393}
394
395/******************************************************************************
396 * SetProperty : change input device properties
397 */
399{
401 DWORD i;
402
403 TRACE("(%p,%s,%p)\n",This,debugstr_guid(rguid),ph);
404
405 if (ph == NULL) {
406 WARN("invalid parameter: ph == NULL\n");
407 return DIERR_INVALIDPARAM;
408 }
409
410 if (TRACE_ON(dinput))
412
413 if (IS_DIPROP(rguid)) {
414 switch (LOWORD(rguid)) {
415 case (DWORD_PTR)DIPROP_RANGE: {
417 if (ph->dwHow == DIPH_DEVICE) {
418 TRACE("proprange(%d,%d) all\n", pr->lMin, pr->lMax);
419 for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++)
420 remap_range(This, i, pr);
421 } else {
422 int obj = find_property(&This->base.data_format, ph);
423
424 TRACE("proprange(%d,%d) obj=%d\n", pr->lMin, pr->lMax, obj);
425 if (obj >= 0)
426 remap_range(This, obj, pr);
427 }
428 break;
429 }
432 if (ph->dwHow == DIPH_DEVICE) {
433 TRACE("deadzone(%d) all\n", pd->dwData);
434 for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++)
435 remap_deadzone(This, i, pd);
436 } else {
437 int obj = find_property(&This->base.data_format, ph);
438
439 TRACE("deadzone(%d) obj=%d\n", pd->dwData, obj);
440 if (obj >= 0)
441 remap_deadzone(This, obj, pd);
442 }
443 break;
444 }
447 if (ph->dwHow == DIPH_DEVICE) {
448 TRACE("saturation(%d) all\n", pd->dwData);
449 for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++)
450 remap_saturation(This, i, pd);
451 } else {
452 int obj = find_property(&This->base.data_format, ph);
453
454 TRACE("saturation(%d) obj=%d\n", pd->dwData, obj);
455 if (obj >= 0)
457 }
458 break;
459 }
462 FIXME("DIPROP_CALIBRATIONMODE(%d)\n", pd->dwData);
463 break;
464 }
465 default:
466 return IDirectInputDevice2WImpl_SetProperty(iface, rguid, ph);
467 }
468 }
469
470 return DI_OK;
471}
472
474{
477}
478
479#define DEBUG_TYPE(x) case (x): str = #x; break
480void _dump_DIDEVCAPS(const DIDEVCAPS *lpDIDevCaps)
481{
482 int type = GET_DIDEVICE_TYPE(lpDIDevCaps->dwDevType);
483 const char *str, *hid = "";
484 TRACE("dwSize: %d\n", lpDIDevCaps->dwSize);
485 TRACE("dwFlags: %08x\n", lpDIDevCaps->dwFlags);
486 switch(type)
487 {
488 /* Direct X <= 7 definitions */
493 /* Direct X >= 8 definitions */
506 default: str = "UNKNOWN";
507 }
508
509 if (lpDIDevCaps->dwDevType & DIDEVTYPE_HID)
510 hid = " (HID)";
511
512 TRACE("dwDevType: %08x %s%s\n", lpDIDevCaps->dwDevType, str, hid);
513 TRACE("dwAxes: %d\n", lpDIDevCaps->dwAxes);
514 TRACE("dwButtons: %d\n", lpDIDevCaps->dwButtons);
515 TRACE("dwPOVs: %d\n", lpDIDevCaps->dwPOVs);
516 if (lpDIDevCaps->dwSize > sizeof(DIDEVCAPS_DX3)) {
517 TRACE("dwFFSamplePeriod: %d\n", lpDIDevCaps->dwFFSamplePeriod);
518 TRACE("dwFFMinTimeResolution: %d\n", lpDIDevCaps->dwFFMinTimeResolution);
519 TRACE("dwFirmwareRevision: %d\n", lpDIDevCaps->dwFirmwareRevision);
520 TRACE("dwHardwareRevision: %d\n", lpDIDevCaps->dwHardwareRevision);
521 TRACE("dwFFDriverVersion: %d\n", lpDIDevCaps->dwFFDriverVersion);
522 }
523}
524#undef DEBUG_TYPE
525
527{
529 int size;
530
531 TRACE("%p->(%p)\n",This,lpDIDevCaps);
532
533 if (lpDIDevCaps == NULL) {
534 WARN("invalid pointer\n");
535 return E_POINTER;
536 }
537
538 size = lpDIDevCaps->dwSize;
539
540 if (!(size == sizeof(DIDEVCAPS) || size == sizeof(DIDEVCAPS_DX3))) {
541 WARN("invalid parameter\n");
542 return DIERR_INVALIDPARAM;
543 }
544
545 CopyMemory(lpDIDevCaps, &This->devcaps, size);
546 lpDIDevCaps->dwSize = size;
547
548 if (TRACE_ON(dinput))
549 _dump_DIDEVCAPS(lpDIDevCaps);
550
551 return DI_OK;
552}
553
555{
558}
559
560/******************************************************************************
561 * GetObjectInfo : get object info
562 */
564 LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow)
565{
566 static const WCHAR axisW[] = {'A','x','i','s',' ','%','d',0};
567 static const WCHAR povW[] = {'P','O','V',' ','%','d',0};
568 static const WCHAR buttonW[] = {'B','u','t','t','o','n',' ','%','d',0};
569 HRESULT res;
570
571 res = IDirectInputDevice2WImpl_GetObjectInfo(iface, pdidoi, dwObj, dwHow);
572 if (res != DI_OK) return res;
573
574 if (pdidoi->dwType & DIDFT_AXIS) {
575 sprintfW(pdidoi->tszName, axisW, DIDFT_GETINSTANCE(pdidoi->dwType));
576 pdidoi->dwFlags |= DIDOI_ASPECTPOSITION;
577 } else if (pdidoi->dwType & DIDFT_POV)
578 sprintfW(pdidoi->tszName, povW, DIDFT_GETINSTANCE(pdidoi->dwType));
579 else if (pdidoi->dwType & DIDFT_BUTTON)
580 sprintfW(pdidoi->tszName, buttonW, DIDFT_GETINSTANCE(pdidoi->dwType));
581
582 _dump_OBJECTINSTANCEW(pdidoi);
583 return res;
584}
585
587 LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow)
588{
590 HRESULT res;
592 DWORD dwSize = pdidoi->dwSize;
593
594 didoiW.dwSize = sizeof(didoiW);
596 if (res != DI_OK) return res;
597
598 memset(pdidoi, 0, pdidoi->dwSize);
599 memcpy(pdidoi, &didoiW, FIELD_OFFSET(DIDEVICEOBJECTINSTANCEW, tszName));
600 pdidoi->dwSize = dwSize;
601 WideCharToMultiByte(CP_ACP, 0, didoiW.tszName, -1, pdidoi->tszName,
602 sizeof(pdidoi->tszName), NULL, NULL);
603
604 return res;
605}
606
607/******************************************************************************
608 * GetProperty : get input device properties
609 */
611{
613
614 TRACE("(%p,%s,%p)\n", This, debugstr_guid(rguid), pdiph);
615
616 if (TRACE_ON(dinput))
617 _dump_DIPROPHEADER(pdiph);
618
619 if (IS_DIPROP(rguid)) {
620 switch (LOWORD(rguid)) {
621 case (DWORD_PTR) DIPROP_RANGE: {
622 LPDIPROPRANGE pr = (LPDIPROPRANGE)pdiph;
623 int obj = find_property(&This->base.data_format, pdiph);
624
625 /* The app is querying the current range of the axis
626 * return the lMin and lMax values */
627 if (obj >= 0) {
628 pr->lMin = This->props[obj].lMin;
629 pr->lMax = This->props[obj].lMax;
630 TRACE("range(%d, %d) obj=%d\n", pr->lMin, pr->lMax, obj);
631 return DI_OK;
632 }
633 break;
634 }
635 case (DWORD_PTR) DIPROP_DEADZONE: {
636 LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
637 int obj = find_property(&This->base.data_format, pdiph);
638
639 if (obj >= 0) {
640 pd->dwData = This->props[obj].lDeadZone;
641 TRACE("deadzone(%d) obj=%d\n", pd->dwData, obj);
642 return DI_OK;
643 }
644 break;
645 }
647 LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
648 int obj = find_property(&This->base.data_format, pdiph);
649
650 if (obj >= 0) {
651 pd->dwData = This->props[obj].lSaturation;
652 TRACE("saturation(%d) obj=%d\n", pd->dwData, obj);
653 return DI_OK;
654 }
655 break;
656 }
659 DIPROPSTRING *ps = (DIPROPSTRING*) pdiph;
660 DIDEVICEINSTANCEW didev;
661
662 didev.dwSize = sizeof(didev);
663
665 if (LOWORD(rguid) == (DWORD_PTR) DIPROP_PRODUCTNAME)
667 else
669
670 return DI_OK;
671 }
672 default:
673 return IDirectInputDevice2WImpl_GetProperty(iface, rguid, pdiph);
674 }
675 }
676
677 return DI_OK;
678}
679
681{
684}
685
686/******************************************************************************
687 * GetDeviceInfo : get information about a device's identity
688 */
692{
694 DIPROPDWORD pd;
695 DWORD index = 0;
696
697 TRACE("(%p,%p)\n", This, pdidi);
698
699 if (pdidi == NULL) {
700 WARN("invalid pointer\n");
701 return E_POINTER;
702 }
703
704 if ((pdidi->dwSize != sizeof(DIDEVICEINSTANCE_DX3A)) &&
705 (pdidi->dwSize != sizeof(DIDEVICEINSTANCEA))) {
706 WARN("invalid parameter: pdidi->dwSize = %d\n", pdidi->dwSize);
707 return DIERR_INVALIDPARAM;
708 }
709
710 /* Try to get joystick index */
711 pd.diph.dwSize = sizeof(pd);
712 pd.diph.dwHeaderSize = sizeof(pd.diph);
713 pd.diph.dwObj = 0;
716 index = pd.dwData;
717
718 /* Return joystick */
719 pdidi->guidInstance = This->guidInstance;
720 pdidi->guidProduct = This->guidProduct;
721 /* we only support traditional joysticks for now */
722 pdidi->dwDevType = This->devcaps.dwDevType;
723 snprintf(pdidi->tszInstanceName, MAX_PATH, "Joystick %d", index);
724 lstrcpynA(pdidi->tszProductName, This->name, MAX_PATH);
725 if (pdidi->dwSize > sizeof(DIDEVICEINSTANCE_DX3A)) {
726 pdidi->guidFFDriver = GUID_NULL;
727 pdidi->wUsagePage = 0;
728 pdidi->wUsage = 0;
729 }
730
731 return DI_OK;
732}
733
734/******************************************************************************
735 * GetDeviceInfo : get information about a device's identity
736 */
740{
743 DIPROPDWORD pd;
744 DWORD index = 0;
745
746 TRACE("(%p,%p)\n", iface, pdidi);
747
748 if ((pdidi->dwSize != sizeof(DIDEVICEINSTANCE_DX3W)) &&
749 (pdidi->dwSize != sizeof(DIDEVICEINSTANCEW))) {
750 WARN("invalid parameter: pdidi->dwSize = %d\n", pdidi->dwSize);
751 return DIERR_INVALIDPARAM;
752 }
753
754 /* Try to get joystick index */
755 pd.diph.dwSize = sizeof(pd);
756 pd.diph.dwHeaderSize = sizeof(pd.diph);
757 pd.diph.dwObj = 0;
760 index = pd.dwData;
761
762 /* Return joystick */
763 pdidi->guidInstance = This->guidInstance;
764 pdidi->guidProduct = This->guidProduct;
765 /* we only support traditional joysticks for now */
766 pdidi->dwDevType = This->devcaps.dwDevType;
767 snprintf(buffer, sizeof(buffer), "Joystick %d", index);
769 MultiByteToWideChar(CP_ACP, 0, This->name, -1, pdidi->tszProductName, MAX_PATH);
770 if (pdidi->dwSize > sizeof(DIDEVICEINSTANCE_DX3W)) {
771 pdidi->guidFFDriver = GUID_NULL;
772 pdidi->wUsagePage = 0;
773 pdidi->wUsage = 0;
774 }
775
776 return DI_OK;
777}
778
780{
782
783 TRACE("(%p)\n",This);
784
785 if (!This->base.acquired) {
786 WARN("not acquired\n");
787 return DIERR_NOTACQUIRED;
788 }
789
791 return DI_OK;
792}
793
795{
798}
799
800/******************************************************************************
801 * GetDeviceState : returns the "state" of the joystick.
802 *
803 */
805{
807
808 TRACE("(%p,0x%08x,%p)\n", This, len, ptr);
809
810 if (!This->base.acquired) {
811 WARN("not acquired\n");
812 return DIERR_NOTACQUIRED;
813 }
814
815 /* update joystick state */
817
818 /* convert and copy data to user supplied buffer */
819 fill_DataFormat(ptr, len, &This->js, &This->base.data_format);
820
821 return DI_OK;
822}
823
825{
828}
829
830
832 LPDIACTIONFORMATW lpdiaf,
833 LPCWSTR lpszUserName,
835{
836 static const DWORD object_types[] = { DIDFT_AXIS, DIDFT_BUTTON };
837 static const DWORD type_map[] = { DIDFT_RELAXIS, DIDFT_PSHBUTTON };
839 unsigned int i, j;
840 BOOL has_actions = FALSE;
842 DWORD size;
843 BOOL load_success = FALSE;
844
845 FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", This, lpdiaf, debugstr_w(lpszUserName), dwFlags);
846
847 /* Unless asked the contrary by these flags, try to load a previous mapping */
848 if (!(dwFlags & DIDBAM_HWDEFAULTS))
849 {
850 if (!lpszUserName)
852 else
853 size = lstrlenW(lpszUserName) + 1;
854
855 username = heap_alloc(size * sizeof(WCHAR));
856 if (!lpszUserName)
858 else
859 lstrcpynW(username, lpszUserName, size);
860
861 load_success = load_mapping_settings(&This->base, lpdiaf, username);
863 }
864
865 if (load_success) return DI_OK;
866
867 for (i=0; i < lpdiaf->dwNumActions; i++)
868 {
869 DWORD inst = (0x000000ff & (lpdiaf->rgoAction[i].dwSemantic)) - 1;
870 DWORD type = 0x000000ff & (lpdiaf->rgoAction[i].dwSemantic >> 8);
871 DWORD genre = 0xff000000 & lpdiaf->rgoAction[i].dwSemantic;
872
873 /* Don't touch a user configured action */
874 if (lpdiaf->rgoAction[i].dwHow == DIAH_USERCONFIG) continue;
875
876 /* Only consider actions of the right genre */
877 if (lpdiaf->dwGenre != genre && genre != DIGENRE_ANY) continue;
878
879 for (j = 0; j < ARRAY_SIZE(object_types); j++)
880 {
881 if (type & object_types[j])
882 {
883 /* Ensure that the object exists */
884 LPDIOBJECTDATAFORMAT odf = dataformat_to_odf_by_type(This->base.data_format.wine_df, inst, object_types[j]);
885
886 if (odf != NULL)
887 {
888 lpdiaf->rgoAction[i].dwObjID = type_map[j] | (0x0000ff00 & (inst << 8));
889 lpdiaf->rgoAction[i].guidInstance = This->base.guid;
890 lpdiaf->rgoAction[i].dwHow = DIAH_DEFAULT;
891
892 has_actions = TRUE;
893
894 /* No need to try other types if the action was already mapped */
895 break;
896 }
897 }
898 }
899 }
900
901 if (!has_actions) return DI_NOEFFECT;
902
903 return IDirectInputDevice8WImpl_BuildActionMap(iface, lpdiaf, lpszUserName, dwFlags);
904}
905
907 LPDIACTIONFORMATA lpdiaf,
908 LPCSTR lpszUserName,
910{
912 DIACTIONFORMATW diafW;
913 HRESULT hr;
914 WCHAR *lpszUserNameW = NULL;
915 int username_size;
916
917 diafW.rgoAction = HeapAlloc(GetProcessHeap(), 0, sizeof(DIACTIONW)*lpdiaf->dwNumActions);
918 _copy_diactionformatAtoW(&diafW, lpdiaf);
919
920 if (lpszUserName != NULL)
921 {
922 username_size = MultiByteToWideChar(CP_ACP, 0, lpszUserName, -1, NULL, 0);
923 lpszUserNameW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*username_size);
924 MultiByteToWideChar(CP_ACP, 0, lpszUserName, -1, lpszUserNameW, username_size);
925 }
926
927 hr = JoystickWGenericImpl_BuildActionMap(&This->base.IDirectInputDevice8W_iface, &diafW, lpszUserNameW, dwFlags);
928
929 _copy_diactionformatWtoA(lpdiaf, &diafW);
930 HeapFree(GetProcessHeap(), 0, diafW.rgoAction);
931 HeapFree(GetProcessHeap(), 0, lpszUserNameW);
932
933 return hr;
934}
935
937 LPDIACTIONFORMATW lpdiaf,
938 LPCWSTR lpszUserName,
940{
942
943 FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", This, lpdiaf, debugstr_w(lpszUserName), dwFlags);
944
945 return _set_action_map(iface, lpdiaf, lpszUserName, dwFlags, This->base.data_format.wine_df);
946}
947
949 LPDIACTIONFORMATA lpdiaf,
950 LPCSTR lpszUserName,
952{
954 DIACTIONFORMATW diafW;
955 HRESULT hr;
956 WCHAR *lpszUserNameW = NULL;
957 int username_size;
958
959 diafW.rgoAction = HeapAlloc(GetProcessHeap(), 0, sizeof(DIACTIONW)*lpdiaf->dwNumActions);
960 _copy_diactionformatAtoW(&diafW, lpdiaf);
961
962 if (lpszUserName != NULL)
963 {
964 username_size = MultiByteToWideChar(CP_ACP, 0, lpszUserName, -1, NULL, 0);
965 lpszUserNameW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*username_size);
966 MultiByteToWideChar(CP_ACP, 0, lpszUserName, -1, lpszUserNameW, username_size);
967 }
968
969 hr = JoystickWGenericImpl_SetActionMap(&This->base.IDirectInputDevice8W_iface, &diafW, lpszUserNameW, dwFlags);
970
971 lpdiaf->dwCRC = diafW.dwCRC;
972
973 HeapFree(GetProcessHeap(), 0, diafW.rgoAction);
974 HeapFree(GetProcessHeap(), 0, lpszUserNameW);
975
976 return hr;
977}
978
979/*
980 * This maps the read value (from the input event) to a value in the
981 * 'wanted' range.
982 * Notes:
983 * Dead zone is in % multiplied by a 100 (range 0..10000)
984 */
986{
987 LONG ret;
988 LONG dead_zone = MulDiv( props->lDeadZone, props->lDevMax - props->lDevMin, 10000 );
989 LONG dev_range = props->lDevMax - props->lDevMin - dead_zone;
990
991 /* Center input */
992 val -= (props->lDevMin + props->lDevMax) / 2;
993
994 /* Remove dead zone */
995 if (abs( val ) <= dead_zone / 2)
996 val = 0;
997 else
998 val = val < 0 ? val + dead_zone / 2 : val - dead_zone / 2;
999
1000 /* Scale and map the value from the device range into the required range */
1001 ret = MulDiv( val, props->lMax - props->lMin, dev_range ) +
1002 (props->lMin + props->lMax) / 2;
1003
1004 /* Clamp in case or rounding errors */
1005 if (ret > props->lMax) ret = props->lMax;
1006 else if (ret < props->lMin) ret = props->lMin;
1007
1008 TRACE( "(%d <%d> %d) -> (%d <%d> %d): val=%d ret=%d\n",
1009 props->lDevMin, dead_zone, props->lDevMax,
1010 props->lMin, props->lDeadZone, props->lMax,
1011 val, ret );
1012
1013 return ret;
1014}
1015
1016/*
1017 * Maps POV x & y event values to a DX "clock" position:
1018 * 0
1019 * 31500 4500
1020 * 27000 -1 9000
1021 * 22500 13500
1022 * 18000
1023 */
1025{
1026 if (p->x > 0)
1027 return p->y < 0 ? 4500 : !p->y ? 9000 : 13500;
1028 else if (p->x < 0)
1029 return p->y < 0 ? 31500 : !p->y ? 27000 : 22500;
1030 else
1031 return p->y < 0 ? 0 : !p->y ? -1 : 18000;
1032}
1033
1034/*
1035 * Setup the dinput options.
1036 */
1037
1039{
1040 char buffer[MAX_PATH+16];
1041 HKEY hkey, appkey;
1042 int tokens = 0;
1043 int axis = 0;
1044 int pov = 0;
1045 int button;
1046
1047 get_app_key(&hkey, &appkey);
1048
1049 /* get options */
1050
1051 if (!get_config_key(hkey, appkey, "DefaultDeadZone", buffer, sizeof(buffer)))
1052 {
1053 This->deadzone = atoi(buffer);
1054 TRACE("setting default deadzone to: \"%s\" %d\n", buffer, This->deadzone);
1055 }
1056
1057 for (button = 0; button < MAX_MAP_BUTTONS; button++)
1058 This->button_map[button] = button;
1059
1060 if (!get_config_key(hkey, appkey, "ButtonMap", buffer, sizeof(buffer)))
1061 {
1062 static const char *delim = ",";
1063 int button = 0;
1064 char *token;
1065
1066 TRACE("ButtonMap = \"%s\"\n", buffer);
1067 for (token = strtok(buffer, delim);
1069 token = strtok(NULL, delim), button++)
1070 {
1071 char *s;
1072 int value = strtol(token, &s, 10);
1073 if (value < 0 || *s != '\0')
1074 {
1075 ERR("invalid button number: \"%s\"", token);
1076 }
1077 else
1078 {
1079 TRACE("mapping physical button %d to DInput button %d", value, button);
1080 This->button_map[value] = button;
1081 }
1082 }
1083 }
1084
1085 This->axis_map = HeapAlloc(GetProcessHeap(), 0, This->device_axis_count * sizeof(int));
1086 if (!This->axis_map) return DIERR_OUTOFMEMORY;
1087
1088 if (!get_config_key(hkey, appkey, This->name, buffer, sizeof(buffer)))
1089 {
1090 static const char *axis_names[] = {"X", "Y", "Z", "Rx", "Ry", "Rz",
1091 "Slider1", "Slider2",
1092 "POV1", "POV2", "POV3", "POV4"};
1093 const char *delim = ",";
1094 char * ptr;
1095 TRACE("\"%s\" = \"%s\"\n", This->name, buffer);
1096
1097 if ((ptr = strtok(buffer, delim)) != NULL)
1098 {
1099 do
1100 {
1101 int i;
1102
1103 for (i = 0; i < ARRAY_SIZE(axis_names); i++)
1104 {
1105 if (!strcmp(ptr, axis_names[i]))
1106 {
1107 if (!strncmp(ptr, "POV", 3))
1108 {
1109 if (pov >= 4)
1110 {
1111 WARN("Only 4 POVs supported - ignoring extra\n");
1112 i = -1;
1113 }
1114 else
1115 {
1116 /* Pov takes two axes */
1117 This->axis_map[tokens++] = i;
1118 pov++;
1119 }
1120 }
1121 else
1122 {
1123 if (axis >= 8)
1124 {
1125 FIXME("Only 8 Axes supported - ignoring extra\n");
1126 i = -1;
1127 }
1128 else
1129 axis++;
1130 }
1131 break;
1132 }
1133 }
1134
1135 if (i == ARRAY_SIZE(axis_names))
1136 {
1137 ERR("invalid joystick axis type: \"%s\"\n", ptr);
1138 i = -1;
1139 }
1140
1141 This->axis_map[tokens] = i;
1142 tokens++;
1143 } while ((ptr = strtok(NULL, delim)) != NULL);
1144
1145 if (tokens != This->device_axis_count)
1146 {
1147 ERR("not all joystick axes mapped: %d axes(%d,%d), %d arguments\n",
1148 This->device_axis_count, axis, pov, tokens);
1149 while (tokens < This->device_axis_count)
1150 {
1151 This->axis_map[tokens] = -1;
1152 tokens++;
1153 }
1154 }
1155 }
1156 }
1157 else
1158 {
1159 int i;
1160
1161 if (default_axis_map)
1162 {
1163 /* Use default mapping from the driver */
1164 for (i = 0; i < This->device_axis_count; i++)
1165 {
1166 This->axis_map[i] = default_axis_map[i];
1167 tokens = default_axis_map[i];
1168 if (tokens < 0)
1169 continue;
1170 if (tokens < 8)
1171 axis++;
1172 else if (tokens < 15)
1173 {
1174 i++;
1175 pov++;
1176 This->axis_map[i] = default_axis_map[i];
1177 }
1178 }
1179 }
1180 else
1181 {
1182 /* No config - set default mapping. */
1183 for (i = 0; i < This->device_axis_count; i++)
1184 {
1185 if (i < 8)
1186 This->axis_map[i] = axis++;
1187 else if (i < 15)
1188 {
1189 This->axis_map[i++] = 8 + pov;
1190 This->axis_map[i ] = 8 + pov++;
1191 }
1192 else
1193 This->axis_map[i] = -1;
1194 }
1195 }
1196 }
1197 This->devcaps.dwAxes = axis;
1198 This->devcaps.dwPOVs = pov;
1199
1200 if (appkey) RegCloseKey(appkey);
1201 if (hkey) RegCloseKey(hkey);
1202
1203 return DI_OK;
1204}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strtok(char *String, const char *Delimiters)
Definition: utclib.c:338
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:33
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
#define RegCloseKey(hKey)
Definition: registry.h:49
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:170
#define DI8DEVTYPE_DEVICE
Definition: dinput.h:209
#define DIPROP_CALIBRATIONMODE
Definition: dinput.h:902
#define DIPROP_RANGE
Definition: dinput.h:892
struct DIPROPDWORD * LPDIPROPDWORD
#define DI8DEVTYPE_1STPERSON
Definition: dinput.h:216
#define DIEFT_CONDITION
Definition: dinput.h:996
#define DIPROP_INSTANCENAME
Definition: dinput.h:910
#define DIEFF_OBJECTIDS
Definition: dinput.h:1008
#define DIDEVTYPE_JOYSTICK
Definition: dinput.h:200
#define DI8DEVTYPE_SUPPLEMENTAL
Definition: dinput.h:220
#define DIDEVTYPE_KEYBOARD
Definition: dinput.h:199
#define DIEFT_CUSTOMFORCE
Definition: dinput.h:997
#define DIERR_INVALIDPARAM
Definition: dinput.h:152
#define DIEFT_PERIODIC
Definition: dinput.h:995
#define DIJOFS_SLIDER(n)
Definition: dinput.h:1211
#define DIDFT_POV
Definition: dinput.h:757
const DIPROPRANGE * LPCDIPROPRANGE
Definition: dinput.h:853
#define DIEFT_CONSTANTFORCE
Definition: dinput.h:993
#define DIDBAM_HWDEFAULTS
Definition: dinput.h:1355
struct IDirectInputDevice8A * LPDIRECTINPUTDEVICE8A
Definition: dinput.h:105
#define DIDEVTYPE_HID
Definition: dinput.h:201
#define DIPROP_SATURATION
Definition: dinput.h:894
#define DIEP_ENVELOPE
Definition: dinput.h:1021
#define DIPROP_JOYSTICKID
Definition: dinput.h:912
#define DIJOFS_X
Definition: dinput.h:1205
#define DIPROP_PRODUCTNAME
Definition: dinput.h:911
#define DIDFT_RELAXIS
Definition: dinput.h:751
#define DIEFF_OBJECTOFFSETS
Definition: dinput.h:1009
#define DIJOFS_Y
Definition: dinput.h:1206
#define DI8DEVTYPE_GAMEPAD
Definition: dinput.h:213
#define DI8DEVTYPE_REMOTE
Definition: dinput.h:219
#define DIERR_NOTACQUIRED
Definition: dinput.h:167
#define DIEFT_RAMPFORCE
Definition: dinput.h:994
#define IDirectInputDevice_GetDeviceInfo(p, a)
Definition: dinput.h:1616
const DIPROPDWORD * LPCDIPROPDWORD
Definition: dinput.h:846
#define DIDEVTYPE_MOUSE
Definition: dinput.h:198
#define DIAH_DEFAULT
Definition: dinput.h:1304
#define DIDFT_PSHBUTTON
Definition: dinput.h:754
#define DI8DEVTYPE_DEVICECTRL
Definition: dinput.h:217
#define DIDFT_AXIS
Definition: dinput.h:753
#define DIEP_AXES
Definition: dinput.h:1019
#define DIERR_OUTOFMEMORY
Definition: dinput.h:155
#define DIDOI_ASPECTPOSITION
Definition: dinput.h:820
#define DI_OK
Definition: dinput.h:128
#define DIEFF_SPHERICAL
Definition: dinput.h:1012
#define DIDEVTYPE_DEVICE
Definition: dinput.h:197
#define DIJOFS_RX
Definition: dinput.h:1208
#define DI8DEVTYPE_DRIVING
Definition: dinput.h:214
#define DIEFF_POLAR
Definition: dinput.h:1011
#define DIPROP_DEADZONE
Definition: dinput.h:893
#define DI_NOEFFECT
Definition: dinput.h:132
#define DIJOFS_Z
Definition: dinput.h:1207
#define DIDFT_GETINSTANCE(n)
Definition: dinput.h:764
#define DIDEVTYPEJOYSTICK_TRADITIONAL
Definition: dinput.h:243
#define IDirectInputDevice2_GetProperty(p, a, b)
Definition: dinput.h:1729
#define DIEFF_CARTESIAN
Definition: dinput.h:1010
#define DI8DEVTYPE_FLIGHT
Definition: dinput.h:215
#define DIPH_DEVICE
Definition: dinput.h:835
#define DIDEVTYPEJOYSTICK_GAMEPAD
Definition: dinput.h:245
#define DI8DEVTYPE_JOYSTICK
Definition: dinput.h:212
#define GET_DIDEVICE_TYPE(dwDevType)
Definition: dinput.h:320
#define DI8DEVTYPE_SCREENPOINTER
Definition: dinput.h:218
struct IDirectInputDevice8W * LPDIRECTINPUTDEVICE8W
Definition: dinput.h:106
#define DI8DEVTYPE_MOUSE
Definition: dinput.h:210
#define DIJOFS_RZ
Definition: dinput.h:1210
#define DIAH_USERCONFIG
Definition: dinput.h:1300
#define DI8DEVTYPEJOYSTICK_STANDARD
Definition: dinput.h:274
struct DIPROPRANGE * LPDIPROPRANGE
#define DIJOFS_RY
Definition: dinput.h:1209
#define DI8DEVTYPE_KEYBOARD
Definition: dinput.h:211
#define DIDFT_BUTTON
Definition: dinput.h:756
void _copy_diactionformatWtoA(LPDIACTIONFORMATA to, LPDIACTIONFORMATW from)
Definition: dinput_main.c:366
void _copy_diactionformatAtoW(LPDIACTIONFORMATW to, LPDIACTIONFORMATA from)
Definition: dinput_main.c:339
#define IS_DIPROP(x)
#define DIGENRE_ANY
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LPDIOBJECTDATAFORMAT dataformat_to_odf_by_type(LPCDIDATAFORMAT df, int n, DWORD type)
Definition: device.c:412
void _dump_DIPROPHEADER(LPCDIPROPHEADER diph)
Definition: device.c:176
BOOL get_app_key(HKEY *defkey, HKEY *appkey)
Definition: device.c:278
const char * _dump_dinput_GUID(const GUID *guid)
Definition: device.c:197
int find_property(const DataFormat *df, LPCDIPROPHEADER ph)
Definition: device.c:607
HRESULT _set_action_map(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags, LPCDIDATAFORMAT df)
Definition: device.c:866
DWORD get_config_key(HKEY defkey, HKEY appkey, const char *name, char *buffer, DWORD size)
Definition: device.c:313
HRESULT WINAPI IDirectInputDevice2WImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPDIPROPHEADER pdiph)
Definition: device.c:1386
void fill_DataFormat(void *out, DWORD size, const void *in, const DataFormat *df)
Definition: device.c:326
HRESULT WINAPI IDirectInputDevice2WImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPCDIPROPHEADER pdiph)
Definition: device.c:1450
void _dump_OBJECTINSTANCEW(const DIDEVICEOBJECTINSTANCEW *ddoi)
Definition: device.c:191
HRESULT WINAPI IDirectInputDevice8WImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags)
Definition: device.c:1924
BOOL load_mapping_settings(IDirectInputDeviceImpl *This, LPDIACTIONFORMATW lpdiaf, const WCHAR *username)
Definition: device.c:740
HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow)
Definition: device.c:1576
HRESULT WINAPI JoystickWGenericImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEINSTANCEW pdidi)
Definition: joystick.c:737
DWORD typeFromGUID(REFGUID guid)
Definition: joystick.c:82
HRESULT WINAPI JoystickWGenericImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow)
Definition: joystick.c:563
HRESULT setup_dinput_options(JoystickGenericImpl *This, const int *default_axis_map)
Definition: joystick.c:1038
static void _dump_DIENVELOPE(LPCDIENVELOPE env)
Definition: joystick.c:140
#define VID_MICROSOFT
Definition: joystick.c:39
LONG joystick_map_axis(ObjProps *props, int val)
Definition: joystick.c:985
static JoystickGenericImpl * impl_from_IDirectInputDevice8A(IDirectInputDevice8A *iface)
Definition: joystick.c:65
HRESULT WINAPI JoystickAGenericImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface, LPDIACTIONFORMATA lpdiaf, LPCSTR lpszUserName, DWORD dwFlags)
Definition: joystick.c:906
BOOL is_xinput_device(const DIDEVCAPS *devcaps, WORD vid, WORD pid)
Definition: joystick.c:312
BOOL device_disabled_registry(const char *name)
Definition: joystick.c:274
HRESULT WINAPI JoystickWGenericImpl_GetCapabilities(LPDIRECTINPUTDEVICE8W iface, LPDIDEVCAPS lpDIDevCaps)
Definition: joystick.c:526
HRESULT WINAPI JoystickWGenericImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPDIPROPHEADER pdiph)
Definition: joystick.c:610
void _dump_DIDEVCAPS(const DIDEVCAPS *lpDIDevCaps)
Definition: joystick.c:480
static void remap_saturation(JoystickGenericImpl *This, int obj, LPCDIPROPDWORD pd)
Definition: joystick.c:382
static void remap_init(JoystickGenericImpl *This, int obj, ObjProps *remap_props)
Definition: joystick.c:325
static void _dump_DIPERIODIC(LPCDIPERIODIC frc)
Definition: joystick.c:154
static void _dump_DIEFFECT_flags(DWORD dwFlags)
Definition: joystick.c:117
HRESULT WINAPI JoystickAGenericImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPCDIPROPHEADER ph)
Definition: joystick.c:473
static JoystickGenericImpl * impl_from_IDirectInputDevice8W(IDirectInputDevice8W *iface)
Definition: joystick.c:69
HRESULT WINAPI JoystickWGenericImpl_SetProperty(LPDIRECTINPUTDEVICE8W iface, REFGUID rguid, LPCDIPROPHEADER ph)
Definition: joystick.c:398
static void _dump_DICONSTANTFORCE(LPCDICONSTANTFORCE frc)
Definition: joystick.c:149
static IDirectInputDevice8W * IDirectInputDevice8W_from_impl(JoystickGenericImpl *This)
Definition: joystick.c:77
HRESULT WINAPI JoystickWGenericImpl_Poll(LPDIRECTINPUTDEVICE8W iface)
Definition: joystick.c:779
HRESULT WINAPI JoystickWGenericImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags)
Definition: joystick.c:831
static const WORD PID_XBOX_CONTROLLERS[]
Definition: joystick.c:41
DWORD get_device_type(DWORD version, BOOL is_joystick)
Definition: joystick.c:107
static void remap_apply(JoystickGenericImpl *This, int obj, ObjProps *remap_props)
Definition: joystick.c:336
static void remap_range(JoystickGenericImpl *This, int obj, LPCDIPROPRANGE pr)
Definition: joystick.c:354
HRESULT WINAPI JoystickAGenericImpl_GetDeviceState(LPDIRECTINPUTDEVICE8A iface, DWORD len, LPVOID ptr)
Definition: joystick.c:824
static void _dump_DICUSTOMFORCE(LPCDICUSTOMFORCE frc)
Definition: joystick.c:173
static void remap_deadzone(JoystickGenericImpl *This, int obj, LPCDIPROPDWORD pd)
Definition: joystick.c:369
HRESULT WINAPI JoystickWGenericImpl_GetDeviceState(LPDIRECTINPUTDEVICE8W iface, DWORD len, LPVOID ptr)
Definition: joystick.c:804
#define DEBUG_TYPE(x)
Definition: joystick.c:479
void dump_DIEFFECT(LPCDIEFFECT eff, REFGUID guid, DWORD dwFlags)
Definition: joystick.c:190
DWORD joystick_map_pov(const POINTL *p)
Definition: joystick.c:1024
#define FE(x)
HRESULT WINAPI JoystickWGenericImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface, LPDIACTIONFORMATW lpdiaf, LPCWSTR lpszUserName, DWORD dwFlags)
Definition: joystick.c:936
HRESULT WINAPI JoystickAGenericImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8A iface, LPDIDEVICEOBJECTINSTANCEA pdidoi, DWORD dwObj, DWORD dwHow)
Definition: joystick.c:586
HRESULT WINAPI JoystickAGenericImpl_Poll(LPDIRECTINPUTDEVICE8A iface)
Definition: joystick.c:794
static void _dump_DICONDITION(LPCDICONDITION frc)
Definition: joystick.c:166
HRESULT WINAPI JoystickAGenericImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8A iface, LPDIDEVICEINSTANCEA pdidi)
Definition: joystick.c:689
const GUID DInput_PIDVID_Product_GUID
Definition: joystick.c:61
static void _dump_DIRAMPFORCE(LPCDIRAMPFORCE frc)
Definition: joystick.c:160
HRESULT WINAPI JoystickAGenericImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface, LPDIACTIONFORMATA lpdiaf, LPCSTR lpszUserName, DWORD dwFlags)
Definition: joystick.c:948
HRESULT WINAPI JoystickAGenericImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPDIPROPHEADER pdiph)
Definition: joystick.c:680
HRESULT WINAPI JoystickAGenericImpl_GetCapabilities(LPDIRECTINPUTDEVICE8A iface, LPDIDEVCAPS lpDIDevCaps)
Definition: joystick.c:554
static IDirectInputDevice8A * IDirectInputDevice8A_from_impl(JoystickGenericImpl *This)
Definition: joystick.c:73
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3263
BOOL WINAPI GetUserNameW(LPWSTR lpszName, LPDWORD lpSize)
Definition: misc.c:291
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define lstrcpynA
Definition: compat.h:751
#define HeapAlloc
Definition: compat.h:733
#define TRACE_ON(x)
Definition: compat.h:75
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
static const WCHAR version[]
Definition: asmname.c:66
#define abs(i)
Definition: fconv.c:206
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLenum condition
Definition: glext.h:9255
GLuint index
Definition: glext.h:6031
GLenum GLint GLuint mask
Definition: glext.h:6028
GLbitfield flags
Definition: glext.h:7161
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static const WCHAR buttonW[]
Definition: htmlelem.c:24
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define MAX_MAP_BUTTONS
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#define GUID_NULL
Definition: ks.h:106
if(dx< 0)
Definition: linetemp.h:194
const GUID * guid
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static PVOID ptr
Definition: dispmode.c:27
DWORD button
Definition: button.c:166
static WCHAR username[]
Definition: url.c:32
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
#define LOWORD(l)
Definition: pedump.c:82
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define sprintfW
Definition: unicode.h:58
const WCHAR * str
static calc_node_t temp
Definition: rpn_ieee.c:38
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
LONG lOffset
Definition: dinput.h:1061
DWORD dwPositiveSaturation
Definition: dinput.h:1064
DWORD dwNegativeSaturation
Definition: dinput.h:1065
LONG lNegativeCoefficient
Definition: dinput.h:1063
LONG lPositiveCoefficient
Definition: dinput.h:1062
LONG lDeadBand
Definition: dinput.h:1066
LONG lMagnitude
Definition: dinput.h:1042
DWORD dwSamplePeriod
Definition: dinput.h:1072
LPLONG rglForceData
Definition: dinput.h:1074
DWORD cChannels
Definition: dinput.h:1071
DWORD cSamples
Definition: dinput.h:1073
DWORD dwHardwareRevision
Definition: dinput.h:941
DWORD dwAxes
Definition: dinput.h:935
DWORD dwFFSamplePeriod
Definition: dinput.h:938
DWORD dwButtons
Definition: dinput.h:936
DWORD dwPOVs
Definition: dinput.h:937
DWORD dwSize
Definition: dinput.h:932
DWORD dwFlags
Definition: dinput.h:933
DWORD dwFFDriverVersion
Definition: dinput.h:942
DWORD dwFirmwareRevision
Definition: dinput.h:940
DWORD dwDevType
Definition: dinput.h:934
DWORD dwFFMinTimeResolution
Definition: dinput.h:939
GUID guidProduct
Definition: dinput.h:414
GUID guidFFDriver
Definition: dinput.h:418
GUID guidInstance
Definition: dinput.h:413
CHAR tszInstanceName[MAX_PATH]
Definition: dinput.h:416
CHAR tszProductName[MAX_PATH]
Definition: dinput.h:417
DWORD dwDevType
Definition: dinput.h:415
DWORD dwDevType
Definition: dinput.h:428
WCHAR tszProductName[MAX_PATH]
Definition: dinput.h:430
GUID guidFFDriver
Definition: dinput.h:431
GUID guidProduct
Definition: dinput.h:427
WCHAR tszInstanceName[MAX_PATH]
Definition: dinput.h:429
GUID guidInstance
Definition: dinput.h:426
CHAR tszName[MAX_PATH]
Definition: dinput.h:352
WCHAR tszName[MAX_PATH]
Definition: dinput.h:371
DWORD cAxes
Definition: dinput.h:1112
DWORD dwTriggerButton
Definition: dinput.h:1110
LPDIENVELOPE lpEnvelope
Definition: dinput.h:1115
DWORD dwDuration
Definition: dinput.h:1107
DWORD dwGain
Definition: dinput.h:1109
DWORD dwFlags
Definition: dinput.h:1106
DWORD dwTriggerRepeatInterval
Definition: dinput.h:1111
DWORD dwSize
Definition: dinput.h:1105
LPVOID lpvTypeSpecificParams
Definition: dinput.h:1117
LPLONG rglDirection
Definition: dinput.h:1114
DWORD dwStartDelay
Definition: dinput.h:1118
DWORD cbTypeSpecificParams
Definition: dinput.h:1116
LPDWORD rgdwAxes
Definition: dinput.h:1113
DWORD dwPeriod
Definition: dinput.h:1056
LONG lOffset
Definition: dinput.h:1054
DWORD dwMagnitude
Definition: dinput.h:1053
DWORD dwPhase
Definition: dinput.h:1055
DIPROPHEADER diph
Definition: dinput.h:843
DWORD dwData
Definition: dinput.h:844
DWORD dwObj
Definition: dinput.h:830
DWORD dwSize
Definition: dinput.h:828
DWORD dwHeaderSize
Definition: dinput.h:829
DWORD dwHow
Definition: dinput.h:831
LONG lMin
Definition: dinput.h:850
LONG lMax
Definition: dinput.h:851
WCHAR wsz[MAX_PATH]
Definition: dinput.h:875
LONG lEnd
Definition: dinput.h:1048
LONG lStart
Definition: dinput.h:1047
LONG lDeadZone
LONG lSaturation
DWORD dwNumActions
Definition: dinput.h:1311
LPDIACTIONW rgoAction
Definition: dinput.h:1330
DWORD dwNumActions
Definition: dinput.h:1329
GUID guidInstance
Definition: dinput.h:1283
DWORD dwHow
Definition: dinput.h:1285
DWORD dwSemantic
Definition: dinput.h:1277
DWORD dwObjID
Definition: dinput.h:1284
Definition: scsiwmi.h:51
Definition: name.c:39
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
Definition: pdh_main.c:94
static const WCHAR props[]
Definition: wbemdisp.c:288
int ret
#define CopyMemory
Definition: winbase.h:1710
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
#define WINAPI
Definition: msvc.h:6
#define E_POINTER
Definition: winerror.h:2365
#define snprintf
Definition: wintirpc.h:48
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175