Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FFB not working on Midnight Club II (log included) #68

Open
instinctualjealousy opened this issue Oct 9, 2023 · 3 comments
Open

FFB not working on Midnight Club II (log included) #68

instinctualjealousy opened this issue Oct 9, 2023 · 3 comments

Comments

@instinctualjealousy
Copy link

I can confirm it works (not well) in XInputPlus and it also works (decently) with that Japanese FFB driver/native dinput8. The game definitely supports it. I've been moving things over to Xidi where possible. I started the game up and did various things (hard driving, crashing into stuff at the end). I do see some effects in the log. The game does not appear to have a toggle for it.

Xidi_DInput8_mc2.exe_1600.log

@instinctualjealousy
Copy link
Author

I'm not going to open another issue for this, but FFB is also not working in Ford Racing 2 for me- I uninstalled the FFB driver just in case of conflicts. Xidi is indeed retrieving FFB data according to this log.

Xidi_DInput8_fr2.exe_11232.log

@samuelgr
Copy link
Owner

For Midnight Club II, I think this is a case of Xidi's existing implementation being slightly different than what DirectInput actually does.

I see this in the log:

[10/09/2023 12:20:48] [D] Creating effect with GUID Square.
[10/09/2023 12:20:48] [D] Begin dump of effect parameters.
[10/09/2023 12:20:48] [D]   Control:
[10/09/2023 12:20:48] [D]     flags = 0x000003ff (DIEP_ALLPARAMS)
[10/09/2023 12:20:48] [D]   Basics:
[10/09/2023 12:20:48] [D]     dwSize = 56 (sizeof(DIEFFECT))
[10/09/2023 12:20:48] [D]     dwFlags = 0x00000012 (DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS)
[10/09/2023 12:20:48] [D]     dwDuration = 4294967295 (INFINITE)
[10/09/2023 12:20:48] [D]     dwSamplePeriod = 0
[10/09/2023 12:20:48] [D]     dwGain = 10000
[10/09/2023 12:20:48] [D]     dwStartDelay = 0
[10/09/2023 12:20:48] [D]     dwTriggerButton = 4294967295 (DIEB_NOTRIGGER)
[10/09/2023 12:20:48] [D]     dwTriggerRepeatInterval = 0
[10/09/2023 12:20:48] [D]   Axes:
[10/09/2023 12:20:48] [D]     cAxes = 2
[10/09/2023 12:20:48] [D]     rgdwAxes[ 0] = 0x0000 (unable to identify)
[10/09/2023 12:20:48] [D]     rgdwAxes[ 1] = 0x0004 (unable to identify)
[10/09/2023 12:20:48] [D]   Direction:
[10/09/2023 12:20:48] [D]     cAxes = 2
[10/09/2023 12:20:48] [D]     rglDirection[ 0] = 1
[10/09/2023 12:20:48] [D]     rglDirection[ 1] = 0
[10/09/2023 12:20:48] [D]   Envelope:
[10/09/2023 12:20:48] [D]     lpEnvelope->dwSize = 20 (sizeof(DIENVELOPE))
[10/09/2023 12:20:48] [D]     lpEnvelope->dwAttackLevel = 0
[10/09/2023 12:20:48] [D]     lpEnvelope->dwAttackTime = 0
[10/09/2023 12:20:48] [D]     lpEnvelope->dwFadeLevel = 0
[10/09/2023 12:20:48] [D]     lpEnvelope->dwFadeTime = 0
[10/09/2023 12:20:48] [D]   Type-Specific:
[10/09/2023 12:20:48] [D]     cbTypeSpecificParams = 16 (sizeof(DIPERIODIC))
[10/09/2023 12:20:48] [D]     lpvTypeSpecificParams->dwMagnitude = 0
[10/09/2023 12:20:48] [D]     lpvTypeSpecificParams->lOffset = 0
[10/09/2023 12:20:48] [D]     lpvTypeSpecificParams->dwPhase = 0
[10/09/2023 12:20:48] [D]     lpvTypeSpecificParams->dwPeriod = 0
[10/09/2023 12:20:48] [D] End dump of effect parameters.
[10/09/2023 12:20:48] [I] Invoked Xidi::VirtualDirectInputDevice<0>::CreateEffect() on interface object 0 associated with Xidi virtual controller 1, result = 0x80070057.

The result of trying to create an effect is always 0x80070057 (DIERR_INVALIDPARAM), meaning that Xidi looks at the parameters and rejects the effect as invalid. I believe the reason is under the "Axes" part of the parameters dump, where Xidi tries to identify the two axes but fails ("unable to identify"). Since the identification method is by object offset (DIEFF_OBJECTOFFSETS in the flags), that means that Xidi believes it doesn't know the offsets, which means as far as Xidi is concerned the application's data format (where the game defines all the offsets) isn't set.

However, earlier in the log:

[10/09/2023 12:20:06] [I] Invoked Xidi::VirtualDirectInputDevice<1>::SetDataFormat() on interface object 2 associated with Xidi virtual controller 1, result = 0x00000000.

The difference is "interface object 2" for SetDataFormat vs "interface object 0" for CreateEffect, even though the associated virtual controller is the same. The way Xidi is currently implemented is it keeps all properties and state, including data format, local to each individual interface object. However, it may be the case that DirectInput shares one data format among all interface objects, in which case the fix to this issue is to change Xidi to do the same thing.

I'll need to do some tests with DirectInput itself to figure out how it handles data formats in this instance.

@samuelgr samuelgr added the bug label Oct 11, 2023
@samuelgr
Copy link
Owner

It turns out that DirectInput itself does exactly what Xidi does: keeps data formats local to individual objects.

I wrote a test program that creates two interface objects for the same device, set the data format on one of them but not the other, and then called CreateEffect. If I call it on the interface object with the data format set, it succeeds, but if I call it on the other interface object, it fails.

I'm not sure exactly how the game is getting away with creating effects successfully, but it is possible DirectInput itself provides a built-in workaround for this game. The FF driver would be able to take advantage of that (since it just plugs into DirectInput), and XInput Plus would be doing its own thing entirely. I don't think this is a bug in Xidi, but fixing the game's FF effects will require a workaround to be implemented.

@samuelgr samuelgr added enhancement and removed bug labels Oct 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants