dinput: fix mouse jitter in Halo (bug 7640)

Vitaliy Margolen wine-devel at kievinfo.com
Sat Apr 14 11:02:43 CDT 2007

Martin Traverse wrote:
> Hello,
> I have done a bisection on bug #7640, mouse jitter in Halo which rendered the 
> game unplayable. I have a patch which fixes the problem on my Gentoo system 
> against wine-0.9.35.
> Bug is introduced by
> commit b22ff8018aca7c365e505f1db7732f7050ae259b
> dinput: Remove MsgWaitForMultipleObjects call
> (Note: commit --59b also severely slows dinput response, fixed soon after by
> commit 685a3e6a6ed623718f640e8906bd44fbca3d8b2c
> dinput: Release critical section before warping mouse)
> Bug can be alleviated by reverting the original commit until
> commit af71538d3343a1cec73e75391a7ebfd5b3ed94ee
> dinput: Remove duplicate Keyboard->Poll it is the same as base class
> I put back the specialised version of Poll with MsgWaitForMultipleObjects,
> which fixed the problem, and have sent a patch. It was only necessary to alter 
> Poll, not GetDeviceState. This is the first time I've sent in a patch, 
> obviously I'm not familiar with the code so I'd be grateful for any comments.
> Martin.

You patch is not correct for one simple reason - it "fixes" mouse by
changing keyboard code. I have removed some code like that from dinput
while cleaning it up. It had way too many hacks - leftover from some
wholesale changes by TG. Of course none of their patches stated exactly
what they did and why.

To fix the problem, you first need to find the reason why the code Wine
has doesn't work. And the code you adding will fix the problem. Then you
need to make some tests to check/verify what's going on.

Running small test program (attached) with native dinput shows that it
does not call MsgWaitForMultipleObjects in kbd->Poll at all (look at
+relay channel). You can experiment with this program a bit more to see
what dinput doing and how ;)

-------------- next part --------------

#include <windows.h>

#include "dinput.h"
#include "dxerr8.h"

void test1(HINSTANCE hInstance)
    static const char msg[] = "Calling poll\n";
    HRESULT hr;
    DWORD start_time;
    HANDLE std_out = GetStdHandle( STD_ERROR_HANDLE );;

    hr = DirectInputCreate(hInstance, DIRECTINPUT_VERSION, &pDI, NULL);
    if (FAILED(hr)) printf("DirectInputCreate() failed: %s\n", DXGetErrorString8(hr));
    if (FAILED(hr)) goto cleanup;

    hr = IDirectInput7_CreateDevice(pDI, &GUID_SysKeyboard, &pKeyboard, NULL);
    if (FAILED(hr)) printf("IDirectInput_CreateDevice() failed: %s\n", DXGetErrorString8(hr));
    if (FAILED(hr)) goto cleanup;

    IDirectInputDevice_SetDataFormat(pKeyboard, &c_dfDIKeyboard);
    hr = IDirectInputDevice_Acquire(pKeyboard);
    if (!SUCCEEDED(hr)) printf("IDirectInputDevice_Acquire() failed: %s\n", DXGetErrorString8(hr));

    start_time = GetTickCount();
    while (GetTickCount() - start_time  < 5000)
        WriteFile(std_out, msg, sizeof(msg) - 1, NULL, NULL);

    if (pDI)       IUnknown_Release(pDI);
    if (pKeyboard) IUnknown_Release(pKeyboard);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine, int nCmdShow)
    return 0;

More information about the wine-devel mailing list