ReactOS 0.4.15-dev-7931-gfd331f1
joystick.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2004-2005 Robert Reif
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#define DIRECTINPUT_VERSION 0x0700
20
21#define COBJMACROS
22#include <windows.h>
23
24#include <math.h>
25#include <stdio.h>
26#include <stdlib.h>
27
28#include "wine/test.h"
29#include "windef.h"
30#include "wingdi.h"
31#include "dinput.h"
32
33typedef struct tagUserData {
34 IDirectInputA *pDI;
37
56};
57
59 sizeof(DIDATAFORMAT),
60 sizeof(DIOBJECTDATAFORMAT),
62 sizeof(DIJOYSTATE2),
65};
66
67static HWND get_hwnd(void)
68{
70 if (!hwnd)
72 return hwnd;
73}
74
75typedef struct tagJoystickInfo
76{
77 IDirectInputDeviceA *pJoystick;
84
85static int get_refcount(IUnknown *object)
86{
87 IUnknown_AddRef( object );
88 return IUnknown_Release( object );
89}
90
91static BOOL CALLBACK EnumAxes(const DIDEVICEOBJECTINSTANCEA *pdidoi, void *pContext)
92{
93 HRESULT hr;
94 JoystickInfo * info = pContext;
95
96 if (IsEqualIID(&pdidoi->guidType, &GUID_XAxis) ||
97 IsEqualIID(&pdidoi->guidType, &GUID_YAxis) ||
98 IsEqualIID(&pdidoi->guidType, &GUID_ZAxis) ||
99 IsEqualIID(&pdidoi->guidType, &GUID_RxAxis) ||
100 IsEqualIID(&pdidoi->guidType, &GUID_RyAxis) ||
101 IsEqualIID(&pdidoi->guidType, &GUID_RzAxis) ||
102 IsEqualIID(&pdidoi->guidType, &GUID_Slider))
103 {
104 DIPROPRANGE diprg;
105 DIPROPDWORD dipdw;
106
107 diprg.diph.dwSize = sizeof(DIPROPRANGE);
108 diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
109 diprg.diph.dwHow = DIPH_BYID;
110 diprg.diph.dwObj = pdidoi->dwType;
111
112 dipdw.diph.dwSize = sizeof(dipdw);
113 dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
114 dipdw.diph.dwHow = DIPH_BYID;
115 dipdw.diph.dwObj = pdidoi->dwType;
116
118 ok(SUCCEEDED(hr), "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
119 ok(info->lMin == diprg.lMin && info->lMax == diprg.lMax, "Min/Max range invalid: "
120 "expected %d..%d got %d..%d\n", info->lMin, info->lMax, diprg.lMin, diprg.lMax);
121
122 diprg.lMin = -2000;
123 diprg.lMax = +2000;
124
126 ok(hr==E_INVALIDARG,"IDirectInputDevice_SetProperty() should have returned "
127 "E_INVALIDARG, returned: %08x\n", hr);
128
130 ok(hr==DI_OK,"IDirectInputDevice_SetProperty() failed: %08x\n", hr);
131
132 /* dead zone */
134 ok(SUCCEEDED(hr), "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
135 ok(info->dZone == dipdw.dwData, "deadzone invalid: expected %d got %d\n",
136 info->dZone, dipdw.dwData);
137
138 dipdw.dwData = 123;
139
141 ok(hr==DI_OK,"IDirectInputDevice_SetProperty() failed: %08x\n", hr);
142
143 /* ensure DIDOI_ASPECTPOSITION is set for axes objects */
144 ok(pdidoi->dwFlags & DIDOI_ASPECTPOSITION, "Missing DIDOI_ASPECTPOSITION, flags are 0x%x\n",
145 pdidoi->dwFlags);
146
147 info->axis++;
148 } else if (IsEqualIID(&pdidoi->guidType, &GUID_POV))
149 info->pov++;
150 else if (IsEqualIID(&pdidoi->guidType, &GUID_Button))
151 info->button++;
152
153 return DIENUM_CONTINUE;
154}
155
156static const struct effect_id
157{
158 const GUID *guid;
159 int dieft;
160 const char *name;
161} effect_conversion[] = {
162 {&GUID_ConstantForce, DIEFT_CONSTANTFORCE, "Constant"},
163 {&GUID_RampForce, DIEFT_RAMPFORCE, "Ramp"},
164 {&GUID_Square, DIEFT_PERIODIC, "Square"},
165 {&GUID_Sine, DIEFT_PERIODIC, "Sine"},
166 {&GUID_Triangle, DIEFT_PERIODIC, "Triangle"},
167 {&GUID_SawtoothUp, DIEFT_PERIODIC, "Saw Tooth Up"},
168 {&GUID_SawtoothDown, DIEFT_PERIODIC, "Saw Tooth Down"},
169 {&GUID_Spring, DIEFT_CONDITION, "Spring"},
170 {&GUID_Damper, DIEFT_CONDITION, "Damper"},
171 {&GUID_Inertia, DIEFT_CONDITION, "Inertia"},
172 {&GUID_Friction, DIEFT_CONDITION, "Friction"},
173 {&GUID_CustomForce, DIEFT_CUSTOMFORCE, "Custom"}
175
176static const struct effect_id* effect_from_guid(const GUID *guid)
177{
178 unsigned int i;
179 for (i = 0; i < ARRAY_SIZE(effect_conversion); i++)
181 return &effect_conversion[i];
182 return NULL;
183}
184
186{
190 const char *effect_name;
191};
192
193/* The last enumerated effect will be used for force feedback testing */
194static BOOL CALLBACK EnumEffects(const DIEFFECTINFOA *lpef, void *ref)
195{
196 const struct effect_id *id = effect_from_guid(&lpef->guid);
197 static union
198 {
200 DIPERIODIC periodic;
203 } specific;
204 struct effect_enum *data = ref;
205 int type = DIDFT_GETTYPE(lpef->dwEffType);
206
207 /* Insanity check */
208 if (!id)
209 {
210 ok(0, "unsupported effect enumerated, GUID %s!\n", wine_dbgstr_guid(&lpef->guid));
211 return DIENUM_CONTINUE;
212 }
213 trace("controller supports '%s' effect\n", id->name);
214 ok(type == id->dieft, "Invalid effect type, expected 0x%x, got 0x%x\n",
215 id->dieft, lpef->dwEffType);
216
217 /* Can't use custom for test as we don't know the data format */
218 if (type == DIEFT_CUSTOMFORCE)
219 return DIENUM_CONTINUE;
220
221 data->effect_count++;
222 data->effect_name = id->name;
223 data->guid = *id->guid;
224
225 ZeroMemory(&specific, sizeof(specific));
226 switch (type)
227 {
228 case DIEFT_PERIODIC:
229 data->eff.cbTypeSpecificParams = sizeof(specific.periodic);
230 data->eff.lpvTypeSpecificParams = &specific.periodic;
231 specific.periodic.dwMagnitude = DI_FFNOMINALMAX / 2;
232 specific.periodic.dwPeriod = DI_SECONDS; /* 1 second */
233 break;
235 data->eff.cbTypeSpecificParams = sizeof(specific.constant);
236 data->eff.lpvTypeSpecificParams = &specific.constant;
237 specific.constant.lMagnitude = DI_FFNOMINALMAX / 2;
238 break;
239 case DIEFT_RAMPFORCE:
240 data->eff.cbTypeSpecificParams = sizeof(specific.ramp);
241 data->eff.lpvTypeSpecificParams = &specific.ramp;
242 specific.ramp.lStart = -DI_FFNOMINALMAX / 2;
243 specific.ramp.lEnd = +DI_FFNOMINALMAX / 2;
244 break;
245 case DIEFT_CONDITION:
246 {
247 int i;
248 data->eff.cbTypeSpecificParams = sizeof(specific.condition);
249 data->eff.lpvTypeSpecificParams = specific.condition;
250 for (i = 0; i < 2; i++)
251 {
252 specific.condition[i].lNegativeCoefficient = -DI_FFNOMINALMAX / 2;
253 specific.condition[i].lPositiveCoefficient = +DI_FFNOMINALMAX / 2;
254 }
255 break;
256 }
257 }
258 return DIENUM_CONTINUE;
259}
260
261static const HRESULT SetCoop_null_window[16] = {
266
267static const HRESULT SetCoop_real_window[16] = {
272
273static BOOL CALLBACK EnumAllFeedback(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
274{
275 trace("---- Device Information ----\n"
276 "Product Name : %s\n"
277 "Instance Name : %s\n"
278 "devType : 0x%08x\n"
279 "GUID Product : %s\n"
280 "GUID Instance : %s\n"
281 "HID Page : 0x%04x\n"
282 "HID Usage : 0x%04x\n",
283 lpddi->tszProductName,
284 lpddi->tszInstanceName,
285 lpddi->dwDevType,
288 lpddi->wUsagePage,
289 lpddi->wUsage);
290
291 ok(!(IsEqualGUID(&GUID_SysMouse, &lpddi->guidProduct) || IsEqualGUID(&GUID_SysKeyboard, &lpddi->guidProduct)), "Invalid device returned.\n");
292
293 return DIENUM_CONTINUE;
294}
295
296static BOOL CALLBACK EnumJoysticks(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
297{
298 HRESULT hr;
299 UserData * data = pvRef;
300 IDirectInputDeviceA *pJoystick;
302 DIDEVCAPS caps;
303 DIJOYSTATE2 js;
305 int i, count;
306 ULONG ref;
309 DIPROPDWORD dipw;
310 DIPROPSTRING dps;
312 WCHAR nameBuffer[MAX_PATH];
313 HWND hWnd = get_hwnd();
314 char oldstate[248], curstate[248];
315 DWORD axes[2] = {DIJOFS_X, DIJOFS_Y};
316 LONG direction[2] = {0, 0};
317 LPDIRECTINPUTEFFECT effect = NULL;
318 LONG cnt1, cnt2;
319 HWND real_hWnd;
321 DIPROPDWORD dip_gain_set, dip_gain_get;
322 struct effect_enum effect_data;
323
324 ok(data->version >= 0x0300, "Joysticks not supported in version 0x%04x\n", data->version);
325
327 ok(hr==E_POINTER,"IDirectInput_CreateDevice() should have returned "
328 "E_POINTER, returned: %08x\n", hr);
329
330 hr = IDirectInput_CreateDevice(data->pDI, NULL, &pJoystick, NULL);
331 ok(hr==E_POINTER,"IDirectInput_CreateDevice() should have returned "
332 "E_POINTER, returned: %08x\n", hr);
333
335 ok(hr==E_POINTER,"IDirectInput_CreateDevice() should have returned "
336 "E_POINTER, returned: %08x\n", hr);
337
339 &pJoystick, NULL);
340 ok(hr==DI_OK,"IDirectInput_CreateDevice() failed: %08x\n", hr);
341 if (hr!=DI_OK)
342 goto DONE;
343
344 trace("---- Controller Information ----\n"
345 "Product Name : %s\n"
346 "Instance Name : %s\n"
347 "devType : 0x%08x\n"
348 "GUID Product : %s\n"
349 "GUID Instance : %s\n"
350 "HID Page : 0x%04x\n"
351 "HID Usage : 0x%04x\n",
352 lpddi->tszProductName,
353 lpddi->tszInstanceName,
354 lpddi->dwDevType,
357 lpddi->wUsagePage,
358 lpddi->wUsage);
359
360 /* Check if this is a HID device */
361 if (lpddi->dwDevType & DIDEVTYPE_HID)
362 ok(lpddi->wUsagePage == 0x01 && (lpddi->wUsage == 0x04 || lpddi->wUsage == 0x05),
363 "Expected a game controller HID UsagePage and Usage, got page 0x%x usage 0x%x\n",
364 lpddi->wUsagePage, lpddi->wUsage);
365
366 /* Test for joystick ID property */
367 ZeroMemory(&dipw, sizeof(dipw));
368 dipw.diph.dwSize = sizeof(DIPROPDWORD);
369 dipw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
370 dipw.diph.dwObj = 0;
371 dipw.diph.dwHow = DIPH_DEVICE;
372
374 ok(SUCCEEDED(hr), "IDirectInputDevice_GetProperty() for DIPROP_JOYSTICKID failed\n");
375
376 /* Test for INSTANCENAME property */
377 memset(&dps, 0, sizeof(dps));
378 dps.diph.dwSize = sizeof(DIPROPSTRING);
379 dps.diph.dwHeaderSize = sizeof(DIPROPHEADER);
380 dps.diph.dwHow = DIPH_DEVICE;
381
383 ok(SUCCEEDED(hr), "IDirectInput_GetProperty() for DIPROP_INSTANCENAME failed: %08x\n", hr);
384
385 /* Test if instance name is the same as present in DIDEVICEINSTANCE */
386 MultiByteToWideChar(CP_ACP, 0, lpddi->tszInstanceName, -1, nameBuffer, MAX_PATH);
387 ok(!lstrcmpW(nameBuffer, dps.wsz), "DIPROP_INSTANCENAME returned is wrong. Expected: %s Got: %s\n",
388 wine_dbgstr_w(nameBuffer), wine_dbgstr_w(dps.wsz));
389
391 ok(SUCCEEDED(hr), "IDirectInput_GetProperty() for DIPROP_PRODUCTNAME failed: %08x\n", hr);
392
393 /* Test if product name is the same as present in DIDEVICEINSTANCE */
394 MultiByteToWideChar(CP_ACP, 0, lpddi->tszProductName, -1, nameBuffer, MAX_PATH);
395 ok(!lstrcmpW(nameBuffer, dps.wsz), "DIPROP_PRODUCTNAME returned is wrong. Expected: %s Got: %s\n",
396 wine_dbgstr_w(nameBuffer), wine_dbgstr_w(dps.wsz));
397
398 /* Test for GUIDPATH properties */
399 memset(&dpg, 0, sizeof(dpg));
400 dpg.diph.dwSize = sizeof(DIPROPGUIDANDPATH);
401 dpg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
402 dpg.diph.dwHow = DIPH_DEVICE;
403
405 ok(SUCCEEDED(hr), "IDirectInput_GetProperty() for DIPROP_GUIDANDPATH failed: %08x\n", hr);
406
407 {
408 static const WCHAR formatW[] = {'\\','\\','?','\\','%','*','[','^','#',']','#','v','i','d','_',
409 '%','0','4','x','&','p','i','d','_','%','0','4','x',0};
410 static const WCHAR miW[] = {'m','i','_',0};
411 static const WCHAR igW[] = {'i','g','_',0};
412 int vid, pid;
413
414 _wcslwr(dpg.wszPath);
415 count = swscanf(dpg.wszPath, formatW, &vid, &pid);
416 ok(count == 2, "DIPROP_GUIDANDPATH path has wrong format. Expected count: 2 Got: %i Path: %s\n",
418 ok(wcsstr(dpg.wszPath, miW) != 0 || wcsstr(dpg.wszPath, igW) != 0,
419 "DIPROP_GUIDANDPATH path should contain either 'ig_' or 'mi_' substring. Path: %s\n",
421 }
422
424 ok(hr==E_POINTER,"IDirectInputDevice_SetDataFormat() should have returned "
425 "E_POINTER, returned: %08x\n", hr);
426
427 ZeroMemory(&format, sizeof(format));
429 ok(hr==DIERR_INVALIDPARAM,"IDirectInputDevice_SetDataFormat() should have "
430 "returned DIERR_INVALIDPARAM, returned: %08x\n", hr);
431
432 /* try the default formats */
434 ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
435
437 ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
438
439 /* try an alternate format */
441 ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
442
444 ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
445 if (hr != DI_OK)
446 goto RELEASE;
447
448 for (i=0; i<16; i++)
449 {
451 ok(hr == SetCoop_null_window[i], "SetCooperativeLevel(NULL, %d): %08x\n", i, hr);
452 }
453 for (i=0; i<16; i++)
454 {
456 ok(hr == SetCoop_real_window[i], "SetCooperativeLevel(hwnd, %d): %08x\n", i, hr);
457 }
458
461 ok(hr==DI_OK,"IDirectInputDevice_SetCooperativeLevel() failed: %08x\n", hr);
462
463 /* get capabilities */
465 ok(hr==E_POINTER,"IDirectInputDevice_GetCapabilities() "
466 "should have returned E_POINTER, returned: %08x\n", hr);
467
468 ZeroMemory(&caps, sizeof(caps));
469 hr = IDirectInputDevice_GetCapabilities(pJoystick, &caps);
470 ok(hr==DIERR_INVALIDPARAM,"IDirectInputDevice_GetCapabilities() "
471 "should have returned DIERR_INVALIDPARAM, returned: %08x\n", hr);
472
473 caps.dwSize = sizeof(caps);
474 hr = IDirectInputDevice_GetCapabilities(pJoystick, &caps);
475 ok(hr==DI_OK,"IDirectInputDevice_GetCapabilities() failed: %08x\n", hr);
476
477 ZeroMemory(&info, sizeof(info));
478 info.pJoystick = pJoystick;
479
480 /* default min/max limits */
481 info.lMin = 0;
482 info.lMax = 0xffff;
483 /* enumerate objects */
485 ok(hr==DI_OK,"IDirectInputDevice_EnumObjects() failed: %08x\n", hr);
486
487 ok(caps.dwAxes == info.axis, "Number of enumerated axes (%d) doesn't match capabilities (%d)\n", info.axis, caps.dwAxes);
488 ok(caps.dwButtons == info.button, "Number of enumerated buttons (%d) doesn't match capabilities (%d)\n", info.button, caps.dwButtons);
489 ok(caps.dwPOVs == info.pov, "Number of enumerated POVs (%d) doesn't match capabilities (%d)\n", info.pov, caps.dwPOVs);
490
491 /* Set format and check limits again */
493 ok(hr==DI_OK,"IDirectInputDevice_SetDataFormat() failed: %08x\n", hr);
494 info.lMin = -2000;
495 info.lMax = +2000;
496 info.dZone= 123;
498 ok(hr==DI_OK,"IDirectInputDevice_EnumObjects() failed: %08x\n", hr);
499
500 hr = IDirectInputDevice_GetDeviceInfo(pJoystick, 0);
501 ok(hr==E_POINTER, "IDirectInputDevice_GetDeviceInfo() "
502 "should have returned E_POINTER, returned: %08x\n", hr);
503
504 ZeroMemory(&inst, sizeof(inst));
505 ZeroMemory(&inst3, sizeof(inst3));
506
507 hr = IDirectInputDevice_GetDeviceInfo(pJoystick, &inst);
508 ok(hr==DIERR_INVALIDPARAM, "IDirectInputDevice_GetDeviceInfo() "
509 "should have returned DIERR_INVALIDPARAM, returned: %08x\n", hr);
510
511 inst.dwSize = sizeof(inst);
512 hr = IDirectInputDevice_GetDeviceInfo(pJoystick, &inst);
513 ok(hr==DI_OK,"IDirectInputDevice_GetDeviceInfo() failed: %08x\n", hr);
514
515 inst3.dwSize = sizeof(inst3);
517 ok(hr==DI_OK,"IDirectInputDevice_GetDeviceInfo() failed: %08x\n", hr);
518
519 hr = IDirectInputDevice_Unacquire(pJoystick);
520 ok(hr == S_FALSE, "IDirectInputDevice_Unacquire() should have returned S_FALSE, got: %08x\n", hr);
521
522 hr = IDirectInputDevice_Acquire(pJoystick);
523 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
524 if (hr != DI_OK)
525 goto RELEASE;
526
527 hr = IDirectInputDevice_Acquire(pJoystick);
528 ok(hr == S_FALSE, "IDirectInputDevice_Acquire() should have returned S_FALSE, got: %08x\n", hr);
529
530 if (info.pov < 4)
531 {
532 hr = IDirectInputDevice_GetDeviceState(pJoystick, sizeof(DIJOYSTATE2), &js);
533 ok(hr == DI_OK, "IDirectInputDevice_GetDeviceState() failed: %08x\n", hr);
534 ok(js.rgdwPOV[3] == -1, "Default for unassigned POV should be -1 not: %d\n", js.rgdwPOV[3]);
535 }
536
537 trace("Testing force feedback\n");
538 ZeroMemory(&effect_data, sizeof(effect_data));
539 effect_data.eff.dwSize = sizeof(effect_data.eff);
541 effect_data.eff.dwDuration = INFINITE;
542 effect_data.eff.dwGain = DI_FFNOMINALMAX;
543 effect_data.eff.dwTriggerButton = DIEB_NOTRIGGER;
544 effect_data.eff.cAxes = ARRAY_SIZE(axes);
545 effect_data.eff.rgdwAxes = axes;
546 effect_data.eff.rglDirection = direction;
547
548 /* Sending effects to joystick requires
549 * calling IDirectInputEffect_Initialize, which requires
550 * having exclusive access to the device, which requires
551 * - not having acquired the joystick when calling
552 * IDirectInputDevice_SetCooperativeLevel
553 * - a visible window
554 */
555 real_hWnd = CreateWindowExA(0, "EDIT", "Test text", 0, 10, 10, 300, 300, NULL, NULL,
556 hInstance, NULL);
557 ok(real_hWnd!=0,"CreateWindowExA failed: %p\n", real_hWnd);
558 ShowWindow(real_hWnd, SW_SHOW);
559 hr = IDirectInputDevice_Unacquire(pJoystick);
560 ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
561 hr = IDirectInputDevice_SetCooperativeLevel(pJoystick, real_hWnd,
563 ok(hr==DI_OK,"IDirectInputDevice_SetCooperativeLevel() failed: %08x\n", hr);
564 hr = IDirectInputDevice_Acquire(pJoystick);
565 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
566
567 cnt1 = get_refcount((IUnknown*)pJoystick);
568
569 hr = IDirectInputDevice2_EnumEffects((IDirectInputDevice2A*)pJoystick, EnumEffects, &effect_data, DIEFT_ALL);
570 ok(hr==DI_OK,"IDirectInputDevice2_EnumEffects() failed: %08x\n", hr);
571
572 /* If the controller does not support ANY effect use the constant effect to make
573 * CreateEffect fail but with the unsupported reason instead of invalid parameters. */
574 if (!effect_data.effect_count)
575 {
577 effect_data.guid = GUID_ConstantForce;
578 effect_data.eff.cbTypeSpecificParams = sizeof(constant);
579 effect_data.eff.lpvTypeSpecificParams = &constant;
580 effect_data.effect_name = "Constant";
581 constant.lMagnitude = DI_FFNOMINALMAX / 2;
582
583 ok(!(caps.dwFlags & DIDC_FORCEFEEDBACK), "effect count is zero but controller supports force feedback?\n");
584 }
585
586 effect = (void *)0xdeadbeef;
587 hr = IDirectInputDevice2_CreateEffect((IDirectInputDevice2A*)pJoystick, &effect_data.guid,
588 &effect_data.eff, &effect, NULL);
589 if (caps.dwFlags & DIDC_FORCEFEEDBACK)
590 {
591 trace("force feedback supported with %d effects, using '%s' for test\n",
592 effect_data.effect_count, effect_data.effect_name);
593 ok(hr == DI_OK, "IDirectInputDevice_CreateEffect() failed: %08x\n", hr);
594 cnt2 = get_refcount((IUnknown*)pJoystick);
595 ok(cnt1 == cnt2, "Ref count is wrong %d != %d\n", cnt1, cnt2);
596
597 if (effect)
598 {
599 DWORD effect_status;
600 struct DIPROPDWORD diprop_word;
601 GUID guid = {0};
602
604 &effect_data.guid);
605 ok(hr==DI_OK,"IDirectInputEffect_Initialize failed: %08x\n", hr);
608 ok(hr==DI_OK,"IDirectInputEffect_SetParameters failed: %08x\n", hr);
609 if (hr==DI_OK) {
610 /* Test that upload, unacquire, acquire still permits updating
611 * uploaded effect. */
612 hr = IDirectInputDevice_Unacquire(pJoystick);
613 ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
614 hr = IDirectInputDevice_Acquire(pJoystick);
615 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
616 hr = IDirectInputEffect_SetParameters(effect, &effect_data.eff, DIEP_GAIN);
617 ok(hr==DI_OK,"IDirectInputEffect_SetParameters failed: %08x\n", hr);
618 }
619
620 /* Check effect status.
621 * State: initially stopped
622 * start
623 * State: started
624 * unacquire, acquire, download
625 * State: stopped
626 * start
627 * State: started
628 *
629 * Shows that:
630 * - effects are stopped after Unacquire + Acquire
631 * - effects are preserved (Download + Start doesn't complain
632 * about incomplete effect)
633 */
635 ok(hr==E_POINTER,"IDirectInputEffect_GetEffectStatus() must fail with E_POINTER, got: %08x\n", hr);
636 effect_status = 0xdeadbeef;
637 hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
638 ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
639 ok(effect_status==0,"IDirectInputEffect_GetEffectStatus() reported effect as started\n");
640 hr = IDirectInputEffect_SetParameters(effect, &effect_data.eff, DIEP_START);
641 ok(hr==DI_OK,"IDirectInputEffect_SetParameters failed: %08x\n", hr);
642 hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
643 ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
644 todo_wine ok(effect_status!=0,"IDirectInputEffect_GetEffectStatus() reported effect as stopped\n");
645 hr = IDirectInputDevice_Unacquire(pJoystick);
646 ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
647 hr = IDirectInputDevice_Acquire(pJoystick);
648 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
650 ok(hr==DI_OK,"IDirectInputEffect_Download() failed: %08x\n", hr);
651 hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
652 ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
653 ok(effect_status==0,"IDirectInputEffect_GetEffectStatus() reported effect as started\n");
654 hr = IDirectInputEffect_Start(effect, 1, 0);
655 ok(hr==DI_OK,"IDirectInputEffect_Start() failed: %08x\n", hr);
656 hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
657 ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
658 Sleep(250); /* feel the magic */
659 todo_wine ok(effect_status!=0,"IDirectInputEffect_GetEffectStatus() reported effect as stopped\n");
661 ok(hr==DI_OK,"IDirectInputEffect_GetEffectGuid() failed: %08x\n", hr);
662 ok(IsEqualGUID(&effect_data.guid, &guid), "Wrong guid returned\n");
663
664 /* Check autocenter status
665 * State: initially stopped
666 * enable
667 * State: enabled
668 * acquire
669 * State: enabled
670 * unacquire
671 * State: enabled
672 *
673 * IDirectInputDevice2_SetProperty(DIPROP_AUTOCENTER) can only be
674 * executed when the device is released.
675 *
676 * If Executed interactively, user can feel that autocenter is
677 * only disabled when the joystick is acquired.
678 */
679 diprop_word.diph.dwSize = sizeof(diprop_word);
680 diprop_word.diph.dwHeaderSize = sizeof(diprop_word.diph);
681 diprop_word.diph.dwObj = 0;
682 diprop_word.diph.dwHow = DIPH_DEVICE;
683 hr = IDirectInputDevice_Unacquire(pJoystick);
684 ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
685 hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
686 ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);
687 ok(diprop_word.dwData==DIPROPAUTOCENTER_ON,"IDirectInputDevice2_GetProperty() reported autocenter as disabled\n");
688 diprop_word.dwData = DIPROPAUTOCENTER_OFF;
689 hr = IDirectInputDevice2_SetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
690 ok(hr==DI_OK,"IDirectInputDevice2_SetProperty() failed: %08x\n", hr);
691 hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
692 ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);
693 ok(diprop_word.dwData==DIPROPAUTOCENTER_OFF,"IDirectInputDevice2_GetProperty() reported autocenter as enabled\n");
695 trace("Acquiring in 2s, autocenter will be disabled.\n");
696 Sleep(2000);
697 }
698 hr = IDirectInputDevice_Acquire(pJoystick);
699 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
701 trace("Acquired.\n");
702 hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
703 ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);
704 ok(diprop_word.dwData==DIPROPAUTOCENTER_OFF,"IDirectInputDevice2_GetProperty() reported autocenter as enabled\n");
706 trace("Releasing in 2s, autocenter will be re-enabled.\n");
707 Sleep(2000);
708 }
709 hr = IDirectInputDevice_Unacquire(pJoystick);
710 ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
712 trace("Released\n");
713 hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
714 ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);
715 ok(diprop_word.dwData==DIPROPAUTOCENTER_OFF,"IDirectInputDevice2_GetProperty() reported autocenter as enabled\n");
716 hr = IDirectInputDevice_Acquire(pJoystick);
717 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
718 hr = IDirectInputDevice2_GetProperty(pJoystick, DIPROP_AUTOCENTER, &diprop_word.diph);
719 ok(hr==DI_OK,"IDirectInputDevice2_GetProperty() failed: %08x\n", hr);
720
721 /* Device gain (DIPROP_FFGAIN).
722 * From MSDN:
723 * 0..10000 range, otherwise DIERR_INVALIDPARAM.
724 * Can be changed even if device is acquired.
725 * Difference found by tests:
726 * <0 is refused, >10000 is accepted
727 */
728 dip_gain_set.diph.dwSize = sizeof(DIPROPDWORD);
729 dip_gain_set.diph.dwHeaderSize = sizeof(DIPROPHEADER);
730 dip_gain_set.diph.dwObj = 0;
731 dip_gain_set.diph.dwHow = DIPH_DEVICE;
732 dip_gain_get.diph.dwSize = sizeof(DIPROPDWORD);
733 dip_gain_get.diph.dwHeaderSize = sizeof(DIPROPHEADER);
734 dip_gain_get.diph.dwObj = 0;
735 dip_gain_get.diph.dwHow = DIPH_DEVICE;
736 dip_gain_get.dwData = 0;
737
738 /* Test device is acquisition (non)impact. */
739 hr = IDirectInputDevice_Unacquire(pJoystick);
740 ok(hr == DI_OK, "IDirectInputDevice_Unacquire() should have returned S_FALSE, got: %08x\n", hr);
741 dip_gain_set.dwData = 1;
742 hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
743 ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
744 hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
745 ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
746 ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);
747 hr = IDirectInputDevice_Acquire(pJoystick);
748 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
749 dip_gain_set.dwData = 2;
750 hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
751 ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
752 hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
753 ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
754 ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);
755 /* Test range and internal clamping. */
756 dip_gain_set.dwData = -1;
757 hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
758 todo_wine ok(hr==DIERR_INVALIDPARAM, "IDirectInputDevice_SetProperty() should have returned %08x: %08x\n", DIERR_INVALIDPARAM, hr);
759 dip_gain_set.dwData = 0;
760 hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
761 ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
762 hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
763 ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
764 ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);
765 dip_gain_set.dwData = 10000;
766 hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
767 ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
768 hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
769 ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
770 ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);
771 /* WARNING: This call succeeds, on the contrary of what is stated on MSDN. */
772 dip_gain_set.dwData = 10001;
773 hr = IDirectInputDevice_SetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_set.diph);
774 ok(hr==DI_OK, "IDirectInputDevice_SetProperty() failed: %08x\n", hr);
775 hr = IDirectInputDevice_GetProperty(pJoystick, DIPROP_FFGAIN, &dip_gain_get.diph);
776 ok(hr==DI_OK, "IDirectInputDevice_GetProperty() failed: %08x\n", hr);
777 ok(dip_gain_get.dwData==dip_gain_set.dwData, "Gain not updated: %i\n", dip_gain_get.dwData);
778
779 /* Test SendForceFeedbackCommand
780 * DISFFC_STOPALL - Should stop effects only
781 * DISFFC_RESET - Should stop effects and unload them (NOT release them)
782 * Tests for game Odallus (bug 41623) */
783 hr = IDirectInputDevice2_SendForceFeedbackCommand((IDirectInputDevice2A*)pJoystick, 0);
784 ok(hr==DIERR_INVALIDPARAM, "IDirectInputDevice_SendForceFeedbackCommand() failed: %08x\n", hr);
785 hr = IDirectInputDevice2_SendForceFeedbackCommand((IDirectInputDevice2A*)pJoystick, 0xFF);
786 ok(hr==DIERR_INVALIDPARAM, "IDirectInputDevice_SendForceFeedbackCommand() failed: %08x\n", hr);
787
789 ok(hr==DI_OK,"IDirectInputEffect_Download() failed: %08x\n", hr);
790
791 /* Send STOPALL and prove that the effect can still be started */
792 hr = IDirectInputDevice2_SendForceFeedbackCommand((IDirectInputDevice2A*)pJoystick, DISFFC_STOPALL);
793 ok(hr==DI_OK, "IDirectInputDevice_SendForceFeedbackCommand() failed: %08x\n", hr);
794 hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
795 ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
796 ok(effect_status==0,"IDirectInputEffect_GetEffectStatus() reported effect as started\n");
797 hr = IDirectInputEffect_Start(effect, 1, 0);
798 ok(hr==DI_OK,"IDirectInputEffect_Start() failed: %08x\n", hr);
800 ok(hr==DI_OK,"IDirectInputEffect_GetEffectGuid() failed: %08x\n", hr);
801 ok(IsEqualGUID(&effect_data.guid, &guid), "Wrong guid returned\n");
802
803 /* Send RESET and prove that we can still manipulate the effect, thus not released */
804 hr = IDirectInputDevice2_SendForceFeedbackCommand((IDirectInputDevice2A*)pJoystick, DISFFC_RESET);
805 ok(hr==DI_OK, "IDirectInputDevice_SendForceFeedbackCommand() failed: %08x\n", hr);
806 hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
807 ok(hr==DIERR_NOTDOWNLOADED,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
809 ok(hr==DI_OK,"IDirectInputEffect_Download() failed: %08x\n", hr);
810 hr = IDirectInputEffect_GetEffectStatus(effect, &effect_status);
811 ok(hr==DI_OK,"IDirectInputEffect_GetEffectStatus() failed: %08x\n", hr);
812 ok(effect_status==0,"IDirectInputEffect_GetEffectStatus() reported effect as started\n");
813 hr = IDirectInputEffect_Start(effect, 1, 0);
814 ok(hr==DI_OK,"IDirectInputEffect_Start() failed: %08x\n", hr);
816 ok(hr==DI_OK,"IDirectInputEffect_GetEffectGuid() failed: %08x\n", hr);
817 ok(IsEqualGUID(&effect_data.guid, &guid), "Wrong guid returned\n");
818
819 ref = IUnknown_Release(effect);
820 ok(ref == 0, "IDirectInputDevice_Release() reference count = %d\n", ref);
821 }
822 cnt1 = get_refcount((IUnknown*)pJoystick);
823 ok(cnt1 == cnt2, "Ref count is wrong %d != %d\n", cnt1, cnt2);
824 }
825 /* No force feedback support, CreateEffect is supposed to fail. Fairy Bloom Freesia
826 * calls CreateEffect without checking the DIDC_FORCEFEEDBACK. It expects the correct
827 * error return to determine if force feedback is unsupported. */
828 else
829 {
830 trace("No force feedback support\n");
831 ok(hr==DIERR_UNSUPPORTED, "IDirectInputDevice_CreateEffect() must fail with DIERR_UNSUPPORTED, got: %08x\n", hr);
832 ok(effect == NULL, "effect must be NULL, got %p\n", effect);
833 }
834
835 /* Before destroying the window, release joystick to revert to
836 * non-exclusive, background cooperative level. */
837 hr = IDirectInputDevice_Unacquire(pJoystick);
838 ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
841 ok(hr==DI_OK,"IDirectInputDevice_SetCooperativeLevel() failed: %08x\n", hr);
842 DestroyWindow (real_hWnd);
843 hr = IDirectInputDevice_Acquire(pJoystick);
844 ok(hr==DI_OK,"IDirectInputDevice_Acquire() failed: %08x\n", hr);
845
847 trace("You have 30 seconds to test all axes, sliders, POVs and buttons\n");
848 count = 300;
849 } else
850 count = 1;
851
852 trace("\n");
853 oldstate[0]='\0';
854 for (i = 0; i < count; i++) {
855 hr = IDirectInputDevice_GetDeviceState(pJoystick, sizeof(DIJOYSTATE2), &js);
856 ok(hr==DI_OK,"IDirectInputDevice_GetDeviceState() failed: %08x\n", hr);
857 if (hr != DI_OK)
858 break;
859 sprintf(curstate, "X%5d Y%5d Z%5d Rx%5d Ry%5d Rz%5d "
860 "S0%5d S1%5d POV0%5d POV1%5d POV2%5d POV3%5d "
861 "B %d %d %d %d %d %d %d %d %d %d %d %d\n",
862 js.lX, js.lY, js.lZ, js.lRx, js.lRy, js.lRz,
863 js.rglSlider[0], js.rglSlider[1],
864 js.rgdwPOV[0], js.rgdwPOV[1], js.rgdwPOV[2], js.rgdwPOV[3],
865 js.rgbButtons[0]>>7, js.rgbButtons[1]>>7, js.rgbButtons[2]>>7,
866 js.rgbButtons[3]>>7, js.rgbButtons[4]>>7, js.rgbButtons[5]>>7,
867 js.rgbButtons[6]>>7, js.rgbButtons[7]>>7, js.rgbButtons[8]>>7,
868 js.rgbButtons[9]>>7, js.rgbButtons[10]>>7, js.rgbButtons[11]>>7);
869 if (strcmp(oldstate, curstate) != 0)
870 {
871 trace("%s\n", curstate);
872 strcpy(oldstate, curstate);
873 }
874 Sleep(100);
875 }
876 trace("\n");
877
878 hr = IDirectInputDevice_Unacquire(pJoystick);
879 ok(hr==DI_OK,"IDirectInputDevice_Unacquire() failed: %08x\n", hr);
880
881RELEASE:
882 ref = IDirectInputDevice_Release(pJoystick);
883 ok(ref==0,"IDirectInputDevice_Release() reference count = %d\n", ref);
884
885DONE:
886 return DIENUM_CONTINUE;
887}
888
890{
891 HRESULT hr;
892 IDirectInputA *pDI;
893 ULONG ref;
895
896 trace("-- Testing Direct Input Version 0x%04x --\n", version);
898 ok(hr==DI_OK||hr==DIERR_OLDDIRECTINPUTVERSION, "DirectInputCreateA() failed: %08x\n", hr);
899 if (hr==DI_OK && pDI!=0) {
901 data.pDI = pDI;
902 data.version = version;
905 ok(hr==DI_OK,"IDirectInput_EnumDevices() failed: %08x\n", hr);
907 ok(ref==0,"IDirectInput_Release() reference count = %d\n", ref);
909 trace(" Version Not Supported\n");
910}
911
912static void test_enum_feedback(void)
913{
914 HRESULT hr;
915 IDirectInputA *pDI;
916 ULONG ref;
918
919 hr = DirectInputCreateA(hInstance, 0x0700, &pDI, NULL);
920 ok(hr==DI_OK||hr==DIERR_OLDDIRECTINPUTVERSION, "DirectInputCreateA() failed: %08x\n", hr);
921 if (hr==DI_OK && pDI!=0) {
923 ok(hr==DI_OK,"IDirectInput_EnumDevices() failed: %08x\n", hr);
925 ok(ref==0,"IDirectInput_Release() reference count = %d\n", ref);
927 trace(" Version Not Supported\n");
928}
929
930START_TEST(joystick)
931{
933
934 joystick_tests(0x0700);
935 joystick_tests(0x0500);
936 joystick_tests(0x0300);
937
939
941}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
HWND hWnd
Definition: settings.c:17
#define ARRAY_SIZE(A)
Definition: main.h:33
HINSTANCE hInstance
Definition: charmap.c:19
const DIDATAFORMAT c_dfDIJoystick2
Definition: data_formats.c:251
const DIDATAFORMAT c_dfDIJoystick
Definition: data_formats.c:75
#define E_INVALIDARG
Definition: ddrawi.h:101
#define DIEP_TYPESPECIFICPARAMS
Definition: dinput.h:1022
#define IDirectInputDevice_EnumObjects(p, a, b, c)
Definition: dinput.h:1605
#define DIPROP_GUIDANDPATH
Definition: dinput.h:908
#define IDirectInputDevice2_SetProperty(p, a, b)
Definition: dinput.h:1730
#define IDirectInputEffect_GetEffectStatus(p, a)
Definition: dinput.h:1517
#define DIPROP_RANGE
Definition: dinput.h:892
#define IDirectInputDevice_Acquire(p)
Definition: dinput.h:1608
#define DIEFT_CONDITION
Definition: dinput.h:996
#define DIPROP_INSTANCENAME
Definition: dinput.h:910
#define DIDEVTYPE_JOYSTICK
Definition: dinput.h:200
#define DISCL_FOREGROUND
Definition: dinput.h:965
#define DIEFT_CUSTOMFORCE
Definition: dinput.h:997
#define IDirectInputDevice_SetDataFormat(p, a)
Definition: dinput.h:1612
struct _DIDATAFORMAT DIDATAFORMAT
#define DIERR_INVALIDPARAM
Definition: dinput.h:152
#define DIEFT_PERIODIC
Definition: dinput.h:995
#define DIENUM_CONTINUE
Definition: dinput.h:188
#define DIEFT_CONSTANTFORCE
Definition: dinput.h:993
#define DIEDFL_ALLDEVICES
Definition: dinput.h:190
#define DIEDFL_ATTACHEDONLY
Definition: dinput.h:191
#define IDirectInputDevice_SetCooperativeLevel(p, a, b)
Definition: dinput.h:1614
#define DIDEVTYPE_HID
Definition: dinput.h:201
#define DI_FFNOMINALMAX
Definition: dinput.h:1038
#define DIPROP_FFGAIN
Definition: dinput.h:895
#define DIPROP_AUTOCENTER
Definition: dinput.h:897
#define DIPROP_JOYSTICKID
Definition: dinput.h:912
#define DIDFT_ALL
Definition: dinput.h:750
#define IDirectInputEffect_GetEffectGuid(p, a)
Definition: dinput.h:1512
#define DISCL_BACKGROUND
Definition: dinput.h:966
#define DIERR_NOTDOWNLOADED
Definition: dinput.h:177
#define DIEP_START
Definition: dinput.h:1026
#define DIEB_NOTRIGGER
Definition: dinput.h:1029
#define IDirectInputDevice2_CreateEffect(p, a, b, c, d)
Definition: dinput.h:1743
#define DIJOFS_X
Definition: dinput.h:1205
#define DIDC_FORCEFEEDBACK
Definition: dinput.h:949
#define IDirectInputEffect_Initialize(p, a, b, c)
Definition: dinput.h:1511
#define IDirectInputEffect_Start(p, a, b)
Definition: dinput.h:1515
#define DIPROP_PRODUCTNAME
Definition: dinput.h:911
#define DIEFF_OBJECTOFFSETS
Definition: dinput.h:1009
#define DIJOFS_Y
Definition: dinput.h:1206
#define IDirectInputDevice_GetCapabilities(p, a)
Definition: dinput.h:1604
#define IDirectInputDevice_GetProperty(p, a, b)
Definition: dinput.h:1606
#define DIEFT_RAMPFORCE
Definition: dinput.h:994
#define DIPROPAUTOCENTER_ON
Definition: dinput.h:900
#define IDirectInputDevice_GetDeviceInfo(p, a)
Definition: dinput.h:1616
#define DISFFC_RESET
Definition: dinput.h:970
#define IDirectInputEffect_SetParameters(p, a, b)
Definition: dinput.h:1514
#define DIERR_UNSUPPORTED
Definition: dinput.h:156
#define DIDFT_GETTYPE(n)
Definition: dinput.h:763
#define IDirectInput_CreateDevice(p, a, b, c)
Definition: dinput.h:2296
#define DIPH_BYID
Definition: dinput.h:837
#define IDirectInputDevice2_SendForceFeedbackCommand(p, a)
Definition: dinput.h:1747
#define IDirectInputDevice2_EnumEffects(p, a, b, c)
Definition: dinput.h:1744
#define DIDFT_AXIS
Definition: dinput.h:753
#define DIERR_OLDDIRECTINPUTVERSION
Definition: dinput.h:141
#define DIEP_AXES
Definition: dinput.h:1019
#define DIDOI_ASPECTPOSITION
Definition: dinput.h:820
#define DI_OK
Definition: dinput.h:128
#define IDirectInput_EnumDevices(p, a, b, c, d)
Definition: dinput.h:2297
#define DISFFC_STOPALL
Definition: dinput.h:971
#define DIJOFS_RX
Definition: dinput.h:1208
#define DIDFT_OPTIONAL
Definition: dinput.h:771
#define DIEDFL_FORCEFEEDBACK
Definition: dinput.h:192
#define DIEFT_ALL
Definition: dinput.h:991
#define DI_SECONDS
Definition: dinput.h:1039
#define IDirectInputDevice_SetProperty(p, a, b)
Definition: dinput.h:1607
#define DIPROP_DEADZONE
Definition: dinput.h:893
#define IDirectInput_Release(p)
Definition: dinput.h:2294
struct IDirectInputEffect * LPDIRECTINPUTEFFECT
Definition: dinput.h:107
#define DIJOFS_Z
Definition: dinput.h:1207
struct _DIOBJECTDATAFORMAT * LPDIOBJECTDATAFORMAT
#define DIEP_GAIN
Definition: dinput.h:1016
#define DIJOFS_BUTTON(n)
Definition: dinput.h:1215
#define IDirectInputDevice2_GetProperty(p, a, b)
Definition: dinput.h:1729
#define DIPROPAUTOCENTER_OFF
Definition: dinput.h:899
#define IDirectInputDevice_Unacquire(p)
Definition: dinput.h:1609
#define DIDFT_ANYINSTANCE
Definition: dinput.h:760
#define DISCL_NONEXCLUSIVE
Definition: dinput.h:964
#define IDirectInputDevice_Release(p)
Definition: dinput.h:1602
#define DIEFF_CARTESIAN
Definition: dinput.h:1010
#define DIDF_ABSAXIS
Definition: dinput.h:775
#define IDirectInputEffect_Download(p)
Definition: dinput.h:1518
#define DIPH_DEVICE
Definition: dinput.h:835
#define IDirectInputDevice_GetDeviceState(p, a, b)
Definition: dinput.h:1610
#define DIJOFS_RZ
Definition: dinput.h:1210
#define DISCL_EXCLUSIVE
Definition: dinput.h:963
#define DIEP_DIRECTION
Definition: dinput.h:1020
#define DIJOFS_RY
Definition: dinput.h:1209
#define DIDFT_BUTTON
Definition: dinput.h:756
HRESULT WINAPI DECLSPEC_HOTPATCH DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
Definition: dinput_main.c:229
#define NULL
Definition: types.h:112
#define CP_ACP
Definition: compat.h:109
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
#define MultiByteToWideChar
Definition: compat.h:110
static const WCHAR version[]
Definition: asmname.c:66
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define RELEASE(_tag)
Definition: fxobject.hpp:50
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLenum condition
Definition: glext.h:9255
GLuint id
Definition: glext.h:5910
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
_Check_return_ _CRTIMP int __cdecl swscanf(_In_z_ const wchar_t *_Src, _In_z_ _Scanf_format_string_ const wchar_t *_Format,...)
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define wine_dbgstr_w
Definition: kernel32.h:34
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
const GUID * guid
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static BOOL CALLBACK EnumAxes(const DIDEVICEOBJECTINSTANCEA *pdidoi, void *pContext)
Definition: joystick.c:91
static const struct effect_id * effect_from_guid(const GUID *guid)
Definition: joystick.c:176
static void test_enum_feedback(void)
Definition: joystick.c:912
struct tagUserData UserData
static const DIOBJECTDATAFORMAT dfDIJoystickTest[]
Definition: joystick.c:38
static const struct effect_id effect_conversion[]
static BOOL CALLBACK EnumJoysticks(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
Definition: joystick.c:296
static void joystick_tests(DWORD version)
Definition: joystick.c:889
static HWND get_hwnd(void)
Definition: joystick.c:67
static int get_refcount(IUnknown *object)
Definition: joystick.c:85
static const HRESULT SetCoop_null_window[16]
Definition: joystick.c:261
static const DIDATAFORMAT c_dfDIJoystickTest
Definition: joystick.c:58
static const HRESULT SetCoop_real_window[16]
Definition: joystick.c:267
static BOOL CALLBACK EnumAllFeedback(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
Definition: joystick.c:273
struct tagJoystickInfo JoystickInfo
static BOOL CALLBACK EnumEffects(const DIEFFECTINFOA *lpef, void *ref)
Definition: joystick.c:194
static const BYTE ramp[17]
Definition: dib.c:2709
#define todo_wine
Definition: custom.c:79
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define DONE
Definition: rnr20lib.h:14
_CRTIMP wchar_t *__cdecl _wcslwr(_Inout_z_ wchar_t *_String)
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
int winetest_interactive
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
DWORD dwAxes
Definition: dinput.h:935
DWORD dwButtons
Definition: dinput.h:936
DWORD dwPOVs
Definition: dinput.h:937
DWORD dwSize
Definition: dinput.h:932
DWORD dwFlags
Definition: dinput.h:933
GUID guidProduct
Definition: dinput.h:414
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 dwEffType
Definition: dinput.h:1127
DWORD cAxes
Definition: dinput.h:1112
DWORD dwTriggerButton
Definition: dinput.h:1110
DWORD dwDuration
Definition: dinput.h:1107
DWORD dwGain
Definition: dinput.h:1109
DWORD dwFlags
Definition: dinput.h:1106
DWORD dwSize
Definition: dinput.h:1105
LPVOID lpvTypeSpecificParams
Definition: dinput.h:1117
LPLONG rglDirection
Definition: dinput.h:1114
DWORD cbTypeSpecificParams
Definition: dinput.h:1116
LPDWORD rgdwAxes
Definition: dinput.h:1113
LONG lRy
Definition: dinput.h:1177
LONG lRx
Definition: dinput.h:1176
LONG lZ
Definition: dinput.h:1175
DWORD rgdwPOV[4]
Definition: dinput.h:1180
LONG lRz
Definition: dinput.h:1178
LONG lX
Definition: dinput.h:1173
LONG rglSlider[2]
Definition: dinput.h:1179
BYTE rgbButtons[128]
Definition: dinput.h:1181
LONG lY
Definition: dinput.h:1174
DIPROPHEADER diph
Definition: dinput.h:843
DWORD dwData
Definition: dinput.h:844
WCHAR wszPath[MAX_PATH]
Definition: dinput.h:869
DIPROPHEADER diph
Definition: dinput.h:867
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
DIPROPHEADER diph
Definition: dinput.h:849
DIPROPHEADER diph
Definition: dinput.h:874
WCHAR wsz[MAX_PATH]
Definition: dinput.h:875
char * name
Definition: compiler.c:66
int effect_count
Definition: joystick.c:189
GUID guid
Definition: joystick.c:188
const char * effect_name
Definition: joystick.c:190
DIEFFECT eff
Definition: joystick.c:187
const char * name
Definition: joystick.c:160
int dieft
Definition: joystick.c:159
const GUID * guid
Definition: joystick.c:158
Definition: send.c:48
DWORD button
Definition: joystick.c:80
IDirectInputDeviceA * pJoystick
Definition: joystick.c:77
DWORD version
Definition: joystick.c:35
IDirectInputA * pDI
Definition: joystick.c:34
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
uint32_t ULONG
Definition: typedefs.h:59
#define ZeroMemory
Definition: winbase.h:1712
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
#define S_FALSE
Definition: winerror.h:2357
#define E_HANDLE
Definition: winerror.h:2850
#define E_POINTER
Definition: winerror.h:2365
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656
#define SW_SHOW
Definition: winuser.h:775
BOOL WINAPI DestroyWindow(_In_ HWND)
__wchar_t WCHAR
Definition: xmlstorage.h:180