Author: akhaldi
Date: Thu Nov 17 21:57:53 2016
New Revision: 73252
URL:
http://svn.reactos.org/svn/reactos?rev=73252&view=rev
Log:
[DINPUT] Sync with Wine Staging 1.9.23. CORE-12409
Modified:
trunk/reactos/dll/directx/wine/dinput/device.c
trunk/reactos/dll/directx/wine/dinput/dinput_main.c
trunk/reactos/dll/directx/wine/dinput/effect_linuxinput.c
trunk/reactos/dll/directx/wine/dinput/joystick.c
trunk/reactos/dll/directx/wine/dinput/joystick_linux.c
trunk/reactos/dll/directx/wine/dinput/joystick_linuxinput.c
trunk/reactos/dll/directx/wine/dinput/joystick_osx.c
trunk/reactos/media/doc/README.WINE
Modified: trunk/reactos/dll/directx/wine/dinput/device.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dinput/de…
==============================================================================
--- trunk/reactos/dll/directx/wine/dinput/device.c [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/wine/dinput/device.c [iso-8859-1] Thu Nov 17 21:57:53 2016
@@ -69,6 +69,42 @@
TRACE("%s ",flags[i].name);
TRACE("\n");
}
+}
+
+static void _dump_ObjectDataFormat_flags(DWORD dwFlags) {
+ unsigned int i;
+ static const struct {
+ DWORD mask;
+ const char *name;
+ } flags[] = {
+#define FE(x) { x, #x}
+ FE(DIDOI_FFACTUATOR),
+ FE(DIDOI_FFEFFECTTRIGGER),
+ FE(DIDOI_POLLED),
+ FE(DIDOI_GUIDISUSAGE)
+#undef FE
+ };
+
+ if (!dwFlags) return;
+
+ TRACE("Flags:");
+
+ /* First the flags */
+ for (i = 0; i < (sizeof(flags) / sizeof(flags[0])); i++) {
+ if (flags[i].mask & dwFlags)
+ TRACE(" %s",flags[i].name);
+ }
+
+ /* Now specific values */
+#define FE(x) case x: TRACE(" "#x); break
+ switch (dwFlags & DIDOI_ASPECTMASK) {
+ FE(DIDOI_ASPECTACCEL);
+ FE(DIDOI_ASPECTFORCE);
+ FE(DIDOI_ASPECTPOSITION);
+ FE(DIDOI_ASPECTVELOCITY);
+ }
+#undef FE
+
}
static void _dump_EnumObjects_flags(DWORD dwFlags) {
@@ -215,6 +251,7 @@
TRACE(" * dwType: 0x%08x\n", df->rgodf[i].dwType);
TRACE(" "); _dump_EnumObjects_flags(df->rgodf[i].dwType);
TRACE("\n");
TRACE(" * dwFlags: 0x%08x\n", df->rgodf[i].dwFlags);
+ TRACE(" "); _dump_ObjectDataFormat_flags(df->rgodf[i].dwFlags);
TRACE("\n");
}
}
@@ -431,16 +468,20 @@
debugstr_guid(asked_format->rgodf[j].pguid),
_dump_dinput_GUID(asked_format->rgodf[j].pguid));
TRACE(" * Offset: %3d\n",
asked_format->rgodf[j].dwOfs);
- TRACE(" * dwType: %08x\n",
asked_format->rgodf[j].dwType);
+ TRACE(" * dwType: 0x%08x\n",
asked_format->rgodf[j].dwType);
TRACE(" ");
_dump_EnumObjects_flags(asked_format->rgodf[j].dwType); TRACE("\n");
+ TRACE(" * dwFlags: 0x%08x\n",
asked_format->rgodf[j].dwFlags);
+ TRACE(" ");
_dump_ObjectDataFormat_flags(asked_format->rgodf[j].dwFlags); TRACE("\n");
TRACE(" - Wine (%d) :\n", i);
TRACE(" * GUID: %s ('%s')\n",
debugstr_guid(format->wine_df->rgodf[i].pguid),
_dump_dinput_GUID(format->wine_df->rgodf[i].pguid));
TRACE(" * Offset: %3d\n",
format->wine_df->rgodf[i].dwOfs);
- TRACE(" * dwType: %08x\n",
format->wine_df->rgodf[i].dwType);
+ TRACE(" * dwType: 0x%08x\n",
format->wine_df->rgodf[i].dwType);
TRACE(" ");
_dump_EnumObjects_flags(format->wine_df->rgodf[i].dwType); TRACE("\n");
+ TRACE(" * dwFlags: 0x%08x\n",
format->wine_df->rgodf[i].dwFlags);
+ TRACE(" ");
_dump_ObjectDataFormat_flags(format->wine_df->rgodf[i].dwFlags);
TRACE("\n");
if (format->wine_df->rgodf[i].dwType & DIDFT_BUTTON)
dt[index].size = sizeof(BYTE);
@@ -469,8 +510,10 @@
debugstr_guid(asked_format->rgodf[j].pguid),
_dump_dinput_GUID(asked_format->rgodf[j].pguid));
TRACE(" * Offset: %3d\n", asked_format->rgodf[j].dwOfs);
- TRACE(" * dwType: %08x\n",
asked_format->rgodf[j].dwType);
+ TRACE(" * dwType: 0x%08x\n",
asked_format->rgodf[j].dwType);
TRACE(" ");
_dump_EnumObjects_flags(asked_format->rgodf[j].dwType); TRACE("\n");
+ TRACE(" * dwFlags: 0x%08x\n",
asked_format->rgodf[j].dwFlags);
+ TRACE(" ");
_dump_ObjectDataFormat_flags(asked_format->rgodf[j].dwFlags); TRACE("\n");
if (asked_format->rgodf[j].dwType & DIDFT_BUTTON)
dt[index].size = sizeof(BYTE);
@@ -1537,7 +1580,10 @@
LPDIRECTINPUTEFFECT *ppdef,
LPUNKNOWN pUnkOuter)
{
FIXME("(this=%p,%s,%p,%p,%p): stub!\n", iface, debugstr_guid(rguid), lpeff,
ppdef, pUnkOuter);
- return DI_OK;
+
+ FIXME("not available in the generic implementation\n");
+ *ppdef = NULL;
+ return DIERR_UNSUPPORTED;
}
HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(LPDIRECTINPUTDEVICE8A iface, REFGUID
rguid, LPCDIEFFECT lpeff,
Modified: trunk/reactos/dll/directx/wine/dinput/dinput_main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dinput/di…
==============================================================================
--- trunk/reactos/dll/directx/wine/dinput/dinput_main.c [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/wine/dinput/dinput_main.c [iso-8859-1] Thu Nov 17 21:57:53
2016
@@ -162,15 +162,26 @@
return DirectInputCreateEx(hinst, dwVersion, &IID_IDirectInput7W, (LPVOID *)ppDI,
punkOuter);
}
-static const char *_dump_DIDEVTYPE_value(DWORD dwDevType)
-{
- switch (dwDevType) {
- case 0: return "All devices";
- case DIDEVTYPE_MOUSE: return "DIDEVTYPE_MOUSE";
- case DIDEVTYPE_KEYBOARD: return "DIDEVTYPE_KEYBOARD";
- case DIDEVTYPE_JOYSTICK: return "DIDEVTYPE_JOYSTICK";
- case DIDEVTYPE_DEVICE: return "DIDEVTYPE_DEVICE";
- default: return "Unknown";
+static const char *_dump_DIDEVTYPE_value(DWORD dwDevType, DWORD dwVersion)
+{
+ if (dwVersion < 0x0800) {
+ switch (dwDevType) {
+ case 0: return "All devices";
+ case DIDEVTYPE_MOUSE: return "DIDEVTYPE_MOUSE";
+ case DIDEVTYPE_KEYBOARD: return "DIDEVTYPE_KEYBOARD";
+ case DIDEVTYPE_JOYSTICK: return "DIDEVTYPE_JOYSTICK";
+ case DIDEVTYPE_DEVICE: return "DIDEVTYPE_DEVICE";
+ default: return "Unknown";
+ }
+ } else {
+ switch (dwDevType) {
+ case DI8DEVCLASS_ALL: return "All devices";
+ case DI8DEVCLASS_POINTER: return "DI8DEVCLASS_POINTER";
+ case DI8DEVCLASS_KEYBOARD: return "DI8DEVCLASS_KEYBOARD";
+ case DI8DEVCLASS_DEVICE: return "DI8DEVCLASS_DEVICE";
+ case DI8DEVCLASS_GAMECTRL: return "DI8DEVCLASS_GAMECTRL";
+ default: return "Unknown";
+ }
}
}
@@ -363,10 +374,11 @@
IDirectInputImpl *This = impl_from_IDirectInput7A(iface);
DIDEVICEINSTANCEA devInstance;
unsigned int i;
- int j, r;
-
- TRACE("(this=%p,0x%04x '%s',%p,%p,%04x)\n",
- This, dwDevType, _dump_DIDEVTYPE_value(dwDevType),
+ int j;
+ HRESULT r;
+
+ TRACE("(this=%p,0x%04x '%s',%p,%p,0x%04x)\n",
+ This, dwDevType, _dump_DIDEVTYPE_value(dwDevType, This->dwVersion),
lpCallback, pvRef, dwFlags);
_dump_EnumDevices_dwFlags(dwFlags);
@@ -405,8 +417,8 @@
int j;
HRESULT r;
- TRACE("(this=%p,0x%04x '%s',%p,%p,%04x)\n",
- This, dwDevType, _dump_DIDEVTYPE_value(dwDevType),
+ TRACE("(this=%p,0x%04x '%s',%p,%p,0x%04x)\n",
+ This, dwDevType, _dump_DIDEVTYPE_value(dwDevType, This->dwVersion),
lpCallback, pvRef, dwFlags);
_dump_EnumDevices_dwFlags(dwFlags);
Modified: trunk/reactos/dll/directx/wine/dinput/effect_linuxinput.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dinput/ef…
==============================================================================
--- trunk/reactos/dll/directx/wine/dinput/effect_linuxinput.c [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/wine/dinput/effect_linuxinput.c [iso-8859-1] Thu Nov 17
21:57:53 2016
@@ -72,6 +72,93 @@
return (dir & 0xffff) * M_PI / 0x8000;
}
+static void ff_dump_effect(struct ff_effect *effect)
+{
+ const char *type = "(Unknown)", *length = "INFINITE";
+ struct ff_envelope *env = NULL;
+ double angle;
+#define FE(x) case x: type = #x; break
+ switch (effect->type)
+ {
+ FE(FF_RUMBLE);
+ FE(FF_PERIODIC);
+ FE(FF_CONSTANT);
+ FE(FF_SPRING);
+ FE(FF_FRICTION);
+ FE(FF_DAMPER);
+ FE(FF_INERTIA);
+ FE(FF_RAMP);
+ }
+#undef FE
+
+ /* rotate so 0 points right */
+ angle = 360 - ff_effect_direction_to_rad(effect->direction + 0xc000) * 180 /
M_PI;
+
+ if (effect->replay.length)
+ length = wine_dbg_sprintf("%u ms", effect->replay.length);
+
+ TRACE("type 0x%x %s, id %d, direction 0x%x (source angle %.2f), time length %s,
start delay %u ms\n",
+ effect->type, type, effect->id, effect->direction, angle, length,
effect->replay.delay);
+ if (effect->trigger.button || effect->trigger.interval)
+ TRACE(" -> trigger button %u, re-trigger interval %u ms\n",
+ effect->trigger.button, effect->trigger.interval);
+
+ if (effect->type == FF_PERIODIC)
+ {
+ struct ff_periodic_effect *per = &effect->u.periodic;
+ const char *wave = "(Unknown)";
+#define FE(x) case x: wave = #x; break
+ switch (per->waveform)
+ {
+ FE(FF_SQUARE);
+ FE(FF_TRIANGLE);
+ FE(FF_SINE);
+ FE(FF_SAW_UP);
+ FE(FF_SAW_DOWN);
+ FE(FF_CUSTOM);
+ }
+#undef FE
+ angle = ff_effect_direction_to_rad(per->phase) * 180 / M_PI;
+ TRACE(" -> waveform 0x%x %s, period %u ms, magnitude %d, offset %d, phase
0x%x (angle %.2f), custom len %d\n",
+ per->waveform, wave, per->period, per->magnitude, per->offset,
per->phase, angle, per->custom_len);
+ env = &per->envelope;
+ }
+ else if (effect->type == FF_CONSTANT)
+ {
+ struct ff_constant_effect *cons = &effect->u.constant;
+ TRACE(" -> level %d\n", cons->level);
+ env = &cons->envelope;
+ }
+ else if (effect->type == FF_RAMP)
+ {
+ struct ff_ramp_effect *ramp = &effect->u.ramp;
+ TRACE(" -> start/end level %d/%d\n", ramp->start_level,
ramp->end_level);
+ env = &ramp->envelope;
+ }
+ else if (effect->type == FF_RUMBLE)
+ {
+ struct ff_rumble_effect *rumble = &effect->u.rumble;
+ TRACE(" -> strong/weak magnitude %u/%u\n",
rumble->strong_magnitude, rumble->weak_magnitude);
+ }
+ else if (effect->type == FF_SPRING || effect->type == FF_FRICTION ||
+ effect->type == FF_DAMPER || effect->type == FF_INERTIA)
+ {
+ struct ff_condition_effect *cond = effect->u.condition;
+ int i;
+ for (i = 0; i < 2; i++)
+ {
+ /* format numbers here to make them align correctly */
+ TRACE(" -> [%d] right/left saturation %5u/%5u, right/left coefficient
%5d/%5d,"
+ " deadband %5u, center %5d\n", i, cond[i].right_saturation,
cond[i].left_saturation,
+ cond[i].right_coeff, cond[i].left_coeff, cond[i].deadband,
cond[i].center);
+ }
+ }
+
+ if (env)
+ TRACE(" -> envelope attack length(ms)/level %u/%u, fade length(ms)/level
%u/%u\n",
+ env->attack_length, env->attack_level, env->fade_length,
env->fade_level);
+}
+
/******************************************************************************
* LinuxInputEffectImpl
*/
@@ -87,19 +174,37 @@
LPDIRECTINPUTEFFECT iface)
{
LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface);
+ int ret, old_effect_id;
TRACE("(this=%p)\n", This);
-
- if (ioctl(*(This->fd), EVIOCSFF, &This->effect) == -1) {
- if (errno == ENOMEM) {
- return DIERR_DEVICEFULL;
- } else {
- FIXME("Could not upload effect. Assuming a disconnected device %d
\"%s\".\n", *This->fd, strerror(errno));
- return DIERR_INPUTLOST;
- }
- }
-
- return DI_OK;
+ ff_dump_effect(&This->effect);
+
+ old_effect_id = This->effect.id;
+ if (ioctl(*(This->fd), EVIOCSFF, &This->effect) != -1)
+ return DI_OK;
+
+ /* Linux kernel < 3.14 has a bug that incorrectly assigns an effect ID even
+ * on error, restore it here if that is the case. */
+ This->effect.id = old_effect_id;
+
+ switch (errno)
+ {
+ case EINVAL:
+ ret = DIERR_INVALIDPARAM;
+ break;
+ case ENOSPC:
+ ret = DIERR_DEVICEFULL;
+ break;
+ case ENOMEM:
+ ret = DIERR_OUTOFMEMORY;
+ break;
+ default:
+ ret = DIERR_INPUTLOST;
+ break;
+ }
+ TRACE("Could not upload effect to fd %d, errno %d \"%s\", returning
0x%x.\n",
+ *This->fd, errno, strerror(errno), ret);
+ return ret;
}
static HRESULT WINAPI LinuxInputEffectImpl_Escape(
@@ -130,6 +235,9 @@
LPDWORD pdwFlags)
{
TRACE("(this=%p,%p)\n", iface, pdwFlags);
+
+ if (!pdwFlags)
+ return E_POINTER;
/* linux sends the effect status through an event.
* that event is trapped by our parent joystick driver
@@ -195,8 +303,12 @@
}
}
- if (dwFlags & DIEP_DURATION) {
- peff->dwDuration = (DWORD)This->effect.replay.length * 1000;
+ if (dwFlags & DIEP_DURATION)
+ {
+ if (!This->effect.replay.length) /* infinite for the linux driver */
+ peff->dwDuration = INFINITE;
+ else
+ peff->dwDuration = (DWORD)This->effect.replay.length * 1000;
}
if (dwFlags & DIEP_ENVELOPE) {
@@ -227,9 +339,8 @@
peff->dwSamplePeriod = 0;
}
- if (dwFlags & DIEP_STARTDELAY) {
- peff->dwStartDelay = This->effect.replay.delay * 1000;
- }
+ if ((dwFlags & DIEP_STARTDELAY) && peff->dwSize >
sizeof(DIEFFECT_DX5))
+ peff->dwStartDelay = This->effect.replay.delay * 1000;
if (dwFlags & DIEP_TRIGGERBUTTON) {
FIXME("LinuxInput button mapping needs redoing; for now, assuming we're using
an actual joystick.\n");
@@ -409,52 +520,78 @@
/* one-axis effects must use cartesian coords */
return DIERR_INVALIDPARAM;
}
- } else { /* two axes */
- if (peff->dwFlags & DIEFF_CARTESIAN) {
- LONG x, y;
- if (This->first_axis_is_x) {
- x = peff->rglDirection[0];
- y = peff->rglDirection[1];
- } else {
- x = peff->rglDirection[1];
- y = peff->rglDirection[0];
- }
- This->effect.direction = (int)((3 * M_PI / 2 - atan2(y, x)) * -0x7FFF / M_PI);
- } else {
- /* Polar and spherical are the same for 2 axes */
- /* Precision is important here, so we do double math with exact constants */
- This->effect.direction = (int)(((double)peff->rglDirection[0] - 90) / 35999) *
0x7FFF;
- }
- }
+ }
+ /* two axes */
+ else
+ {
+ if (peff->dwFlags & DIEFF_CARTESIAN)
+ {
+ LONG x, y;
+ if (This->first_axis_is_x)
+ {
+ x = peff->rglDirection[0];
+ y = peff->rglDirection[1];
+ }
+ else
+ {
+ x = peff->rglDirection[1];
+ y = peff->rglDirection[0];
+ }
+ This->effect.direction = (unsigned int)((M_PI / 2 + atan2(y, x)) *
0x8000 / M_PI);
+ }
+ else
+ {
+ /* Polar and spherical are the same for 2 axes */
+ /* Precision is important here, so we do double math with exact constants
*/
+ This->effect.direction = (unsigned
int)(((double)peff->rglDirection[0] / 18000) * 0x8000);
+ }
+ }
}
if (dwFlags & DIEP_DURATION)
- This->effect.replay.length = peff->dwDuration / 1000;
-
- if (dwFlags & DIEP_ENVELOPE) {
+ {
+ if (peff->dwDuration == INFINITE)
+ This->effect.replay.length = 0; /* infinite for the linux driver */
+ else if(peff->dwDuration > 1000)
+ This->effect.replay.length = peff->dwDuration / 1000;
+ else
+ This->effect.replay.length = 1;
+ }
+
+ if (dwFlags & DIEP_ENVELOPE)
+ {
struct ff_envelope* env;
- if (This->effect.type == FF_CONSTANT) env =
&This->effect.u.constant.envelope;
- else if (This->effect.type == FF_PERIODIC) env =
&This->effect.u.periodic.envelope;
- else if (This->effect.type == FF_RAMP) env =
&This->effect.u.ramp.envelope;
- else env = NULL;
-
- if (peff->lpEnvelope == NULL) {
- /* if this type had an envelope, reset it */
- if (env) {
- env->attack_length = 0;
- env->attack_level = 0;
- env->fade_length = 0;
- env->fade_level = 0;
- }
- } else {
- /* did we get passed an envelope for a type that doesn't even have one? */
- if (!env) return DIERR_INVALIDPARAM;
- /* copy the envelope */
- env->attack_length = peff->lpEnvelope->dwAttackTime / 1000;
- env->attack_level = (peff->lpEnvelope->dwAttackLevel / 10) * 32;
- env->fade_length = peff->lpEnvelope->dwFadeTime / 1000;
- env->fade_level = (peff->lpEnvelope->dwFadeLevel / 10) * 32;
- }
+ if (This->effect.type == FF_CONSTANT)
+ env = &This->effect.u.constant.envelope;
+ else if (This->effect.type == FF_PERIODIC)
+ env = &This->effect.u.periodic.envelope;
+ else if (This->effect.type == FF_RAMP)
+ env = &This->effect.u.ramp.envelope;
+ else
+ env = NULL;
+
+ /* copy the envelope if it is present and the linux effect supports it */
+ if (peff->lpEnvelope && env)
+ {
+ env->attack_length = peff->lpEnvelope->dwAttackTime / 1000;
+ env->attack_level = (peff->lpEnvelope->dwAttackLevel / 10) * 32;
+ env->fade_length = peff->lpEnvelope->dwFadeTime / 1000;
+ env->fade_level = (peff->lpEnvelope->dwFadeLevel / 10) * 32;
+ }
+ /* if the dinput envelope is NULL we will clear the linux envelope */
+ else if (env)
+ {
+ env->attack_length = 0;
+ env->attack_level = 0;
+ env->fade_length = 0;
+ env->fade_level = 0;
+ }
+ else if(peff->lpEnvelope)
+ {
+ if(peff->lpEnvelope->dwAttackTime ||
peff->lpEnvelope->dwAttackLevel ||
+ peff->lpEnvelope->dwFadeTime ||
peff->lpEnvelope->dwFadeLevel)
+ WARN("Ignoring dinput envelope not supported in the linux
effect\n");
+ }
}
/* Gain and Sample Period settings are not supported by the linux
@@ -468,7 +605,8 @@
TRACE("Sample period requested but no sample period functionality
present.\n");
if (dwFlags & DIEP_STARTDELAY)
- This->effect.replay.delay = peff->dwStartDelay / 1000;
+ if ((dwFlags & DIEP_STARTDELAY) && peff->dwSize >
sizeof(DIEFFECT_DX5))
+ This->effect.replay.delay = peff->dwStartDelay / 1000;
if (dwFlags & DIEP_TRIGGERBUTTON) {
if (peff->dwTriggerButton != -1) {
@@ -481,19 +619,30 @@
if (dwFlags & DIEP_TRIGGERREPEATINTERVAL)
This->effect.trigger.interval = peff->dwTriggerRepeatInterval / 1000;
- if (dwFlags & DIEP_TYPESPECIFICPARAMS) {
- if (!(peff->lpvTypeSpecificParams))
- return DIERR_INCOMPLETEEFFECT;
- if (type == DIEFT_PERIODIC) {
- LPCDIPERIODIC tsp;
+ if (dwFlags & DIEP_TYPESPECIFICPARAMS)
+ {
+ if (!(peff->lpvTypeSpecificParams))
+ return DIERR_INCOMPLETEEFFECT;
+
+ if (type == DIEFT_PERIODIC)
+ {
+ DIPERIODIC *tsp;
if (peff->cbTypeSpecificParams != sizeof(DIPERIODIC))
return DIERR_INVALIDPARAM;
tsp = peff->lpvTypeSpecificParams;
- This->effect.u.periodic.magnitude = (tsp->dwMagnitude / 10) * 32;
- This->effect.u.periodic.offset = (tsp->lOffset / 10) * 32;
- This->effect.u.periodic.phase = (tsp->dwPhase / 9) * 8; /* == (/ 36 * 32) */
- This->effect.u.periodic.period = tsp->dwPeriod / 1000;
- } else if (type == DIEFT_CONSTANTFORCE) {
+
+ This->effect.u.periodic.magnitude = (tsp->dwMagnitude / 10) * 32;
+ This->effect.u.periodic.offset = (tsp->lOffset / 10) * 32;
+ /* phase ranges from 0 - 35999 in dinput and 0 - 65535 on linux */
+ This->effect.u.periodic.phase = (tsp->dwPhase / 36) * 65;
+ /* dinput uses microseconds, linux uses miliseconds */
+ if (tsp->dwPeriod <= 1000)
+ This->effect.u.periodic.period = 1;
+ else
+ This->effect.u.periodic.period = tsp->dwPeriod / 1000;
+ }
+ else if (type == DIEFT_CONSTANTFORCE)
+ {
LPCDICONSTANTFORCE tsp;
if (peff->cbTypeSpecificParams != sizeof(DICONSTANTFORCE))
return DIERR_INVALIDPARAM;
@@ -506,43 +655,49 @@
tsp = peff->lpvTypeSpecificParams;
This->effect.u.ramp.start_level = (tsp->lStart / 10) * 32;
This->effect.u.ramp.end_level = (tsp->lEnd / 10) * 32;
- } else if (type == DIEFT_CONDITION) {
- LPCDICONDITION tsp = peff->lpvTypeSpecificParams;
- if (peff->cbTypeSpecificParams == sizeof(DICONDITION)) {
- /* One condition block. This needs to be rotated to direction,
- * and expanded to separate x and y conditions. */
- int i;
- double factor[2], angle;
- /* rotate so 0 points right */
- angle = ff_effect_direction_to_rad(This->effect.direction + 0xc000);
- factor[0] = sin(angle);
- factor[1] = -cos(angle);
- for (i = 0; i < 2; ++i) {
- This->effect.u.condition[i].center = (int)(factor[i] *
(tsp->lOffset / 10) * 32);
- This->effect.u.condition[i].right_coeff = (int)(factor[i] *
(tsp->lPositiveCoefficient / 10) * 32);
- This->effect.u.condition[i].left_coeff = (int)(factor[i] *
(tsp->lNegativeCoefficient / 10) * 32);
- This->effect.u.condition[i].right_saturation = (int)(factor[i] *
(tsp->dwPositiveSaturation / 10) * 32);
- This->effect.u.condition[i].left_saturation = (int)(factor[i] *
(tsp->dwNegativeSaturation / 10) * 32);
- This->effect.u.condition[i].deadband = (int)(factor[i] *
(tsp->lDeadBand / 10) * 32);
- }
- } else if (peff->cbTypeSpecificParams == 2 * sizeof(DICONDITION)) {
- /* Two condition blocks. Direct parameter copy. */
- int i;
- for (i = 0; i < 2; ++i) {
- This->effect.u.condition[i].center = (tsp[i].lOffset / 10) * 32;
- This->effect.u.condition[i].right_coeff = (tsp[i].lPositiveCoefficient / 10) *
32;
- This->effect.u.condition[i].left_coeff = (tsp[i].lNegativeCoefficient / 10) *
32;
- This->effect.u.condition[i].right_saturation = (tsp[i].dwPositiveSaturation /
10) * 32;
- This->effect.u.condition[i].left_saturation = (tsp[i].dwNegativeSaturation / 10)
* 32;
- This->effect.u.condition[i].deadband = (tsp[i].lDeadBand / 10) * 32;
- }
- } else {
+ }
+ else if (type == DIEFT_CONDITION)
+ {
+ DICONDITION *tsp = peff->lpvTypeSpecificParams;
+ struct ff_condition_effect *cond = This->effect.u.condition;
+ int i, j, sources;
+ double factor[2];
+
+ if (peff->cbTypeSpecificParams == sizeof(DICONDITION))
+ {
+ /* One condition block. This needs to be rotated to direction,
+ * and expanded to separate x and y conditions. Ensures 0 points right
*/
+ double angle = ff_effect_direction_to_rad(This->effect.direction +
0xc000);
+ factor[0] = sin(angle);
+ factor[1] = -cos(angle);
+ sources = 1;
+ }
+ else if (peff->cbTypeSpecificParams == 2 * sizeof(DICONDITION))
+ {
+ /* Direct parameter copy without changes */
+ factor[0] = factor[1] = 1;
+ sources = 2;
+ }
+ else
return DIERR_INVALIDPARAM;
- }
- } else {
- FIXME("Custom force types are not supported\n");
- return DIERR_INVALIDPARAM;
- }
+
+ for (i = j = 0; i < 2; ++i)
+ {
+ cond[i].center = (int)(factor[i] * (tsp[j].lOffset / 10) * 32);
+ cond[i].right_coeff = (int)(factor[i] * (tsp[j].lPositiveCoefficient /
10) * 32);
+ cond[i].left_coeff = (int)(factor[i] * (tsp[j].lNegativeCoefficient / 10)
* 32);
+ cond[i].right_saturation = (int)(factor[i] * (tsp[j].dwPositiveSaturation
/ 10) * 65);
+ cond[i].left_saturation = (int)(factor[i] * (tsp[j].dwNegativeSaturation
/ 10) * 65);
+ cond[i].deadband = (int)(factor[i] * (tsp[j].lDeadBand / 10) * 32);
+ if (sources == 2)
+ j++;
+ }
+ }
+ else
+ {
+ FIXME("Custom force types are not supported\n");
+ return DIERR_INVALIDPARAM;
+ }
}
if (!(dwFlags & DIEP_NODOWNLOAD))
Modified: trunk/reactos/dll/directx/wine/dinput/joystick.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dinput/jo…
==============================================================================
--- trunk/reactos/dll/directx/wine/dinput/joystick.c [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/wine/dinput/joystick.c [iso-8859-1] Thu Nov 17 21:57:53
2016
@@ -213,10 +213,14 @@
_dump_DIRAMPFORCE(eff->lpvTypeSpecificParams);
}
} else if (type == DIEFT_CONDITION) {
- if (eff->cbTypeSpecificParams != sizeof(DICONDITION)) {
+ if (eff->cbTypeSpecificParams == sizeof(DICONDITION)) {
+ _dump_DICONDITION(eff->lpvTypeSpecificParams);
+ } else if (eff->cbTypeSpecificParams == 2 * sizeof(DICONDITION)) {
+ DICONDITION *condition = eff->lpvTypeSpecificParams;
+ _dump_DICONDITION(&condition[0]);
+ _dump_DICONDITION(&condition[1]);
+ } else {
WARN("Effect claims to be a condition but the type-specific params are
the wrong size!\n");
- } else {
- _dump_DICONDITION(eff->lpvTypeSpecificParams);
}
} else if (type == DIEFT_CUSTOMFORCE) {
if (eff->cbTypeSpecificParams != sizeof(DICUSTOMFORCE)) {
@@ -289,6 +293,11 @@
case (DWORD_PTR)DIPROP_RANGE: {
LPCDIPROPRANGE pr = (LPCDIPROPRANGE)ph;
if (ph->dwHow == DIPH_DEVICE) {
+
+ /* Many games poll the joystick immediately after setting the range
+ * for calibration purposes, so the old values need to be remapped
+ * to the new range before it does so */
+
TRACE("proprange(%d,%d) all\n", pr->lMin, pr->lMax);
for (i = 0; i < This->base.data_format.wine_df->dwNumObjs; i++)
{
@@ -322,8 +331,6 @@
TRACE("proprange(%d,%d) obj=%d\n", pr->lMin, pr->lMax,
obj);
if (obj >= 0) {
- /*ePSXe polls the joystick immediately after setting the range for
calibration purposes, so the old values need to be remapped to the new range before it
does so*/
-
remap_props.lDevMin = This->props[obj].lMin;
remap_props.lDevMax = This->props[obj].lMax;
@@ -333,7 +340,7 @@
remap_props.lMin = pr->lMin;
remap_props.lMax = pr->lMax;
- switch (ph->dwObj) {
+ switch (This->base.data_format.wine_df->rgodf[obj].dwOfs) {
case DIJOFS_X : This->js.lX =
joystick_map_axis(&remap_props, This->js.lX); break;
case DIJOFS_Y : This->js.lY =
joystick_map_axis(&remap_props, This->js.lY); break;
case DIJOFS_Z : This->js.lZ =
joystick_map_axis(&remap_props, This->js.lZ); break;
@@ -404,7 +411,7 @@
void _dump_DIDEVCAPS(const DIDEVCAPS *lpDIDevCaps)
{
int type = GET_DIDEVICE_TYPE(lpDIDevCaps->dwDevType);
- const char *str;
+ const char *str, *hid = "";
TRACE("dwSize: %d\n", lpDIDevCaps->dwSize);
TRACE("dwFlags: %08x\n", lpDIDevCaps->dwFlags);
switch(type)
@@ -414,7 +421,6 @@
DEBUG_TYPE(DIDEVTYPE_MOUSE);
DEBUG_TYPE(DIDEVTYPE_KEYBOARD);
DEBUG_TYPE(DIDEVTYPE_JOYSTICK);
- DEBUG_TYPE(DIDEVTYPE_HID);
/* Direct X >= 8 definitions */
DEBUG_TYPE(DI8DEVTYPE_DEVICE);
DEBUG_TYPE(DI8DEVTYPE_MOUSE);
@@ -431,7 +437,10 @@
default: str = "UNKNOWN";
}
- TRACE("dwDevType: %08x %s\n", lpDIDevCaps->dwDevType, str);
+ if (lpDIDevCaps->dwDevType & DIDEVTYPE_HID)
+ hid = " (HID)";
+
+ TRACE("dwDevType: %08x %s%s\n", lpDIDevCaps->dwDevType, str, hid);
TRACE("dwAxes: %d\n", lpDIDevCaps->dwAxes);
TRACE("dwButtons: %d\n", lpDIDevCaps->dwButtons);
TRACE("dwPOVs: %d\n", lpDIDevCaps->dwPOVs);
@@ -493,9 +502,10 @@
res = IDirectInputDevice2WImpl_GetObjectInfo(iface, pdidoi, dwObj, dwHow);
if (res != DI_OK) return res;
- if (pdidoi->dwType & DIDFT_AXIS)
+ if (pdidoi->dwType & DIDFT_AXIS) {
sprintfW(pdidoi->tszName, axisW, DIDFT_GETINSTANCE(pdidoi->dwType));
- else if (pdidoi->dwType & DIDFT_POV)
+ pdidoi->dwFlags |= DIDOI_ASPECTPOSITION;
+ } else if (pdidoi->dwType & DIDFT_POV)
sprintfW(pdidoi->tszName, povW, DIDFT_GETINSTANCE(pdidoi->dwType));
else if (pdidoi->dwType & DIDFT_BUTTON)
sprintfW(pdidoi->tszName, buttonW, DIDFT_GETINSTANCE(pdidoi->dwType));
@@ -575,6 +585,7 @@
}
break;
}
+ case (DWORD_PTR) DIPROP_PRODUCTNAME:
case (DWORD_PTR) DIPROP_INSTANCENAME: {
DIPROPSTRING *ps = (DIPROPSTRING*) pdiph;
DIDEVICEINSTANCEW didev;
@@ -582,7 +593,10 @@
didev.dwSize = sizeof(didev);
IDirectInputDevice_GetDeviceInfo(iface, &didev);
- lstrcpynW(ps->wsz, didev.tszInstanceName, MAX_PATH);
+ if (LOWORD(rguid) == (DWORD_PTR) DIPROP_PRODUCTNAME)
+ lstrcpynW(ps->wsz, didev.tszProductName, MAX_PATH);
+ else
+ lstrcpynW(ps->wsz, didev.tszInstanceName, MAX_PATH);
return DI_OK;
}
Modified: trunk/reactos/dll/directx/wine/dinput/joystick_linux.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dinput/jo…
==============================================================================
--- trunk/reactos/dll/directx/wine/dinput/joystick_linux.c [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/wine/dinput/joystick_linux.c [iso-8859-1] Thu Nov 17
21:57:53 2016
@@ -63,7 +63,7 @@
BYTE button_count;
int *dev_axes_map;
- WORD vendor_id, product_id;
+ WORD vendor_id, product_id, bus_type;
};
typedef struct JoystickImpl JoystickImpl;
@@ -122,6 +122,29 @@
static void joy_polldev(LPDIRECTINPUTDEVICE8A iface);
+#define SYS_PATH_FORMAT "/sys/class/input/js%d/device/id/%s"
+static BOOL read_sys_id_variable(int index, const char *property, WORD *value)
+{
+ char sys_path[sizeof(SYS_PATH_FORMAT) + 16], id_str[5];
+ int sys_fd;
+ BOOL ret = FALSE;
+
+ sprintf(sys_path, SYS_PATH_FORMAT, index, property);
+ if ((sys_fd = open(sys_path, O_RDONLY)) != -1)
+ {
+ if (read(sys_fd, id_str, 4) == 4)
+ {
+ id_str[4] = '\0';
+ *value = strtol(id_str, NULL, 16);
+ ret = TRUE;
+ }
+
+ close(sys_fd);
+ }
+ return ret;
+}
+#undef SYS_PATH_FORMAT
+
static INT find_joystick_devices(void)
{
INT i;
@@ -131,16 +154,15 @@
joystick_devices_count = 0;
for (i = 0; i < MAX_JOYSTICKS; i++)
{
- int fd, sys_fd;
+ int fd;
struct JoyDev joydev, *new_joydevs;
BYTE axes_map[ABS_MAX + 1];
- char sys_path[sizeof("/sys/class/input/js/device/id/product") + 10],
id_str[5];
snprintf(joydev.device, sizeof(joydev.device), "%s%d", JOYDEV_NEW, i);
- if ((fd = open(joydev.device, O_RDONLY)) < 0)
+ if ((fd = open(joydev.device, O_RDONLY)) == -1)
{
snprintf(joydev.device, sizeof(joydev.device), "%s%d", JOYDEV_OLD,
i);
- if ((fd = open(joydev.device, O_RDONLY)) < 0) continue;
+ if ((fd = open(joydev.device, O_RDONLY)) == -1) continue;
}
strcpy(joydev.name, "Wine Joystick");
@@ -205,31 +227,9 @@
joydev.vendor_id = 0;
joydev.product_id = 0;
- sprintf(sys_path, "/sys/class/input/js%d/device/id/vendor", i);
- sys_fd = open(sys_path, O_RDONLY);
- if (sys_fd > 0)
- {
- if (read(sys_fd, id_str, 4) == 4)
- {
- id_str[4] = '\0';
- joydev.vendor_id = strtol(id_str, NULL, 16);
- }
-
- close(sys_fd);
- }
-
- sprintf(sys_path, "/sys/class/input/js%d/device/id/product", i);
- sys_fd = open(sys_path, O_RDONLY);
- if (sys_fd > 0)
- {
- if (read(sys_fd, id_str, 4) == 4)
- {
- id_str[4] = '\0';
- joydev.product_id = strtol(id_str, NULL, 16);
- }
-
- close(sys_fd);
- }
+ read_sys_id_variable(i, "vendor", &joydev.vendor_id);
+ read_sys_id_variable(i, "product", &joydev.product_id);
+ read_sys_id_variable(i, "bustype", &joydev.bus_type);
if (joydev.vendor_id == 0 || joydev.product_id == 0)
{
@@ -261,7 +261,7 @@
return joystick_devices_count;
}
-static void fill_joystick_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version, int
id)
+static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version, int
id)
{
DWORD dwSize = lpddi->dwSize;
@@ -278,33 +278,45 @@
lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD <<
8);
else
lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL
<< 8);
- strcpy(lpddi->tszInstanceName, joystick_devices[id].name);
- strcpy(lpddi->tszProductName, joystick_devices[id].name);
-
- lpddi->guidFFDriver = GUID_NULL;
-}
-
-static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version, int
id)
-{
- DWORD dwSize = lpddi->dwSize;
-
- TRACE("%d %p\n", dwSize, lpddi);
- memset(lpddi, 0, dwSize);
-
- /* Return joystick */
- lpddi->dwSize = dwSize;
- lpddi->guidInstance = DInput_Wine_Joystick_GUID;
- lpddi->guidInstance.Data3 = id;
- lpddi->guidProduct = joystick_devices[id].guid_product;
- /* we only support traditional joysticks for now */
- if (version >= 0x0800)
- lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD <<
8);
- else
- lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL
<< 8);
+
+ /* Assume the joystick as HID if it is attached to USB bus and has a valid VID/PID
*/
+ if (joystick_devices[id].bus_type == BUS_USB &&
+ joystick_devices[id].vendor_id && joystick_devices[id].product_id)
+ {
+ lpddi->dwDevType |= DIDEVTYPE_HID;
+ lpddi->wUsagePage = 0x01; /* Desktop */
+ if (lpddi->dwDevType == DI8DEVTYPE_JOYSTICK || lpddi->dwDevType ==
DIDEVTYPE_JOYSTICK)
+ lpddi->wUsage = 0x04; /* Joystick */
+ else
+ lpddi->wUsage = 0x05; /* Game Pad */
+ }
MultiByteToWideChar(CP_ACP, 0, joystick_devices[id].name, -1,
lpddi->tszInstanceName, MAX_PATH);
MultiByteToWideChar(CP_ACP, 0, joystick_devices[id].name, -1,
lpddi->tszProductName, MAX_PATH);
lpddi->guidFFDriver = GUID_NULL;
+}
+
+static void fill_joystick_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version, int
id)
+{
+ DIDEVICEINSTANCEW lpddiW;
+ DWORD dwSize = lpddi->dwSize;
+
+ lpddiW.dwSize = sizeof(lpddiW);
+ fill_joystick_dideviceinstanceW(&lpddiW, version, id);
+
+ TRACE("%d %p\n", dwSize, lpddi);
+ memset(lpddi, 0, dwSize);
+
+ /* Convert W->A */
+ lpddi->dwSize = dwSize;
+ lpddi->guidInstance = lpddiW.guidInstance;
+ lpddi->guidProduct = lpddiW.guidProduct;
+ lpddi->dwDevType = lpddiW.dwDevType;
+ strcpy(lpddi->tszInstanceName, joystick_devices[id].name);
+ strcpy(lpddi->tszProductName, joystick_devices[id].name);
+ lpddi->guidFFDriver = lpddiW.guidFFDriver;
+ lpddi->wUsagePage = lpddiW.wUsagePage;
+ lpddi->wUsage = lpddiW.wUsage;
}
static HRESULT joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA
lpddi, DWORD version, int id)
@@ -322,14 +334,14 @@
((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version
< 0x0800)) ||
(((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) &&
(version >= 0x0800))) {
/* check whether we have a joystick */
- if ((fd = open(joystick_devices[id].device, O_RDONLY)) < 0)
- {
- WARN("open(%s, O_RDONLY) failed: %s\n", joystick_devices[id].name,
strerror(errno));
+ if ((fd = open(joystick_devices[id].device, O_RDONLY)) == -1)
+ {
+ WARN("open(%s, O_RDONLY) failed: %s\n",
joystick_devices[id].device, strerror(errno));
return S_FALSE;
}
fill_joystick_dideviceinstanceA( lpddi, version, id );
close(fd);
- TRACE("Enumerating the linux Joystick device: %s (%s)\n",
joystick_devices[id].device, lpddi->tszProductName);
+ TRACE("Enumerating the linux Joystick device: %s (%s)\n",
joystick_devices[id].device, joystick_devices[id].name);
return S_OK;
}
@@ -351,9 +363,9 @@
((dwDevType == DIDEVTYPE_JOYSTICK) && (version > 0x0300 && version
< 0x0800)) ||
(((dwDevType == DI8DEVCLASS_GAMECTRL) || (dwDevType == DI8DEVTYPE_JOYSTICK)) &&
(version >= 0x0800))) {
/* check whether we have a joystick */
- if ((fd = open(joystick_devices[id].device, O_RDONLY)) < 0)
- {
- WARN("open(%s,O_RDONLY) failed: %s\n", joystick_devices[id].device,
strerror(errno));
+ if ((fd = open(joystick_devices[id].device, O_RDONLY)) == -1)
+ {
+ WARN("open(%s, O_RDONLY) failed: %s\n",
joystick_devices[id].device, strerror(errno));
return S_FALSE;
}
fill_joystick_dideviceinstanceW( lpddi, version, id );
@@ -373,6 +385,7 @@
HRESULT hr;
LPDIDATAFORMAT df = NULL;
int idx = 0;
+ DIDEVICEINSTANCEW ddi;
TRACE("%s %p %p %hu\n", debugstr_guid(rguid), dinput, pdev, index);
@@ -463,10 +476,11 @@
newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
newDevice->generic.devcaps.dwFlags = DIDC_ATTACHED;
- if (newDevice->generic.base.dinput->dwVersion >= 0x0800)
- newDevice->generic.devcaps.dwDevType = DI8DEVTYPE_JOYSTICK |
(DI8DEVTYPEJOYSTICK_STANDARD << 8);
- else
- newDevice->generic.devcaps.dwDevType = DIDEVTYPE_JOYSTICK |
(DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
+
+ ddi.dwSize = sizeof(ddi);
+ fill_joystick_dideviceinstanceW(&ddi,
newDevice->generic.base.dinput->dwVersion, index);
+ newDevice->generic.devcaps.dwDevType = ddi.dwDevType;
+
newDevice->generic.devcaps.dwFFSamplePeriod = 0;
newDevice->generic.devcaps.dwFFMinTimeResolution = 0;
newDevice->generic.devcaps.dwFirmwareRevision = 0;
@@ -625,6 +639,16 @@
switch (LOWORD(rguid)) {
+ case (DWORD_PTR) DIPROP_VIDPID:
+ {
+ LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
+
+ if (!This->joydev->product_id || !This->joydev->vendor_id)
+ return DIERR_UNSUPPORTED;
+ pd->dwData = MAKELONG(This->joydev->vendor_id,
This->joydev->product_id);
+ TRACE("DIPROP_VIDPID(%08x)\n", pd->dwData);
+ break;
+ }
case (DWORD_PTR) DIPROP_JOYSTICKID:
{
LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
Modified: trunk/reactos/dll/directx/wine/dinput/joystick_linuxinput.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dinput/jo…
==============================================================================
--- trunk/reactos/dll/directx/wine/dinput/joystick_linuxinput.c [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/wine/dinput/joystick_linuxinput.c [iso-8859-1] Thu Nov 17
21:57:53 2016
@@ -91,7 +91,7 @@
/* data returned by the EVIOCGABS() ioctl */
struct wine_input_absinfo axes[ABS_MAX];
- WORD vendor_id, product_id;
+ WORD vendor_id, product_id, bus_type;
};
struct JoystickImpl
@@ -296,6 +296,7 @@
{
joydev.vendor_id = device_id.vendor;
joydev.product_id = device_id.product;
+ joydev.bus_type = device_id.bustype;
/* Concatenate product_id with vendor_id to mimic Windows behaviour */
joydev.guid_product = DInput_Wine_Joystick_Constant_Part_GUID;
@@ -320,7 +321,7 @@
}
}
-static void fill_joystick_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version, int
id)
+static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version, int
id)
{
DWORD dwSize = lpddi->dwSize;
@@ -337,29 +338,43 @@
else
lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL
<< 8);
- strcpy(lpddi->tszInstanceName, joydevs[id].name);
- strcpy(lpddi->tszProductName, joydevs[id].name);
-}
-
-static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version, int
id)
-{
+ /* Assume the joystick as HID if it is attached to USB bus and has a valid VID/PID
*/
+ if (joydevs[id].bus_type == BUS_USB &&
+ joydevs[id].vendor_id && joydevs[id].product_id)
+ {
+ lpddi->dwDevType |= DIDEVTYPE_HID;
+ lpddi->wUsagePage = 0x01; /* Desktop */
+ if (lpddi->dwDevType == DI8DEVTYPE_JOYSTICK || lpddi->dwDevType ==
DIDEVTYPE_JOYSTICK)
+ lpddi->wUsage = 0x04; /* Joystick */
+ else
+ lpddi->wUsage = 0x05; /* Game Pad */
+ }
+
+ MultiByteToWideChar(CP_ACP, 0, joydevs[id].name, -1, lpddi->tszInstanceName,
MAX_PATH);
+ MultiByteToWideChar(CP_ACP, 0, joydevs[id].name, -1, lpddi->tszProductName,
MAX_PATH);
+}
+
+static void fill_joystick_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version, int
id)
+{
+ DIDEVICEINSTANCEW lpddiW;
DWORD dwSize = lpddi->dwSize;
+
+ lpddiW.dwSize = sizeof(lpddiW);
+ fill_joystick_dideviceinstanceW(&lpddiW, version, id);
TRACE("%d %p\n", dwSize, lpddi);
memset(lpddi, 0, dwSize);
- lpddi->dwSize = dwSize;
- lpddi->guidInstance = joydevs[id].guid;
- lpddi->guidProduct = joydevs[id].guid_product;
- lpddi->guidFFDriver = GUID_NULL;
-
- if (version >= 0x0800)
- lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD <<
8);
- else
- lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL
<< 8);
-
- MultiByteToWideChar(CP_ACP, 0, joydevs[id].name, -1, lpddi->tszInstanceName,
MAX_PATH);
- MultiByteToWideChar(CP_ACP, 0, joydevs[id].name, -1, lpddi->tszProductName,
MAX_PATH);
+ /* Convert W->A */
+ lpddi->dwSize = dwSize;
+ lpddi->guidInstance = lpddiW.guidInstance;
+ lpddi->guidProduct = lpddiW.guidProduct;
+ lpddi->dwDevType = lpddiW.dwDevType;
+ strcpy(lpddi->tszInstanceName, joydevs[id].name);
+ strcpy(lpddi->tszProductName, joydevs[id].name);
+ lpddi->guidFFDriver = lpddiW.guidFFDriver;
+ lpddi->wUsagePage = lpddiW.wUsagePage;
+ lpddi->wUsage = lpddiW.wUsage;
}
static HRESULT joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA
lpddi, DWORD version, int id)
@@ -418,6 +433,7 @@
LPDIDATAFORMAT df = NULL;
int i, idx = 0;
int default_axis_map[WINE_JOYSTICK_MAX_AXES + WINE_JOYSTICK_MAX_POVS*2];
+ DIDEVICEINSTANCEW ddi;
newDevice = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(JoystickImpl));
if (!newDevice) return NULL;
@@ -537,10 +553,10 @@
/* Fill the caps */
newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
newDevice->generic.devcaps.dwFlags = DIDC_ATTACHED;
- if (newDevice->generic.base.dinput->dwVersion >= 0x0800)
- newDevice->generic.devcaps.dwDevType = DI8DEVTYPE_JOYSTICK |
(DI8DEVTYPEJOYSTICK_STANDARD << 8);
- else
- newDevice->generic.devcaps.dwDevType = DIDEVTYPE_JOYSTICK |
(DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
+
+ ddi.dwSize = sizeof(ddi);
+ fill_joystick_dideviceinstanceW(&ddi,
newDevice->generic.base.dinput->dwVersion, index);
+ newDevice->generic.devcaps.dwDevType = ddi.dwDevType;
if (newDevice->joydev->has_ff)
newDevice->generic.devcaps.dwFlags |= DIDC_FORCEFEEDBACK;
@@ -1015,10 +1031,16 @@
JoystickImpl* This = impl_from_IDirectInputDevice8W(iface);
TRACE("(this=%p,%p,%p,%p,%p)\n", This, rguid, lpeff, ppdef, pUnkOuter);
+ *ppdef = NULL;
+ if (!This->joydev->has_ff)
+ {
+ TRACE("No force feedback support\n");
+ return DIERR_UNSUPPORTED;
+ }
+
#ifndef HAVE_STRUCT_FF_EFFECT_DIRECTION
- TRACE("not available (compiled w/o ff support)\n");
- *ppdef = NULL;
- return DI_OK;
+ TRACE("not available (compiled w/o force feedback support)\n");
+ return DIERR_UNSUPPORTED;
#else
if (!(new_effect = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_effect))))
Modified: trunk/reactos/dll/directx/wine/dinput/joystick_osx.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dinput/jo…
==============================================================================
--- trunk/reactos/dll/directx/wine/dinput/joystick_osx.c [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/wine/dinput/joystick_osx.c [iso-8859-1] Thu Nov 17 21:57:53
2016
@@ -1398,7 +1398,7 @@
if(!This->ff){
TRACE("No force feedback support\n");
*out = NULL;
- return S_OK;
+ return DIERR_UNSUPPORTED;
}
if(outer)
Modified: trunk/reactos/media/doc/README.WINE
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=…
==============================================================================
--- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original)
+++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Thu Nov 17 21:57:53 2016
@@ -30,7 +30,7 @@
reactos/dll/directx/wine/d3dxof # Synced to WineStaging-1.9.16
reactos/dll/directx/wine/ddraw # Synced to WineStaging-1.9.4
reactos/dll/directx/wine/devenum # Synced to WineStaging-1.9.16
-reactos/dll/directx/wine/dinput # Synced to WineStaging-1.9.16
+reactos/dll/directx/wine/dinput # Synced to WineStaging-1.9.23
reactos/dll/directx/wine/dinput8 # Synced to WineStaging-1.9.11
reactos/dll/directx/wine/dmusic # Synced to WineStaging-1.9.16
reactos/dll/directx/wine/dplay # Synced to WineStaging-1.9.11