Authors: Ove Kaaven <ovek@transgaming.com>, Gavriel State <gav@transgaming.com>

Implemented circular buffering for the dinput mouse device.
Mapped the mouse warp on the center of the cooperative window, which
should make windowed games work better in managed mode.
This commit is contained in:
Alexandre Julliard 2001-01-28 23:14:25 +00:00
parent d4b933e7d2
commit e81843bb61
5 changed files with 81 additions and 70 deletions

View File

@ -34,16 +34,19 @@ extern DataFormat *create_DataFormat(DIDATAFORMAT *wine_format, LPCDIDATAFORMAT
{ \
/* If queue_len > 0, queuing is requested -> TRACE the event queued */ \
if (This->queue_len > 0) { \
TRACE(" queueing %d at offset %d (queue pos %d / size %d)\n", \
DWORD nq; \
TRACE(" queueing %d at offset %d (queue head %d / size %d)\n", \
(int) (data), (int) (offset), \
(int) (This->queue_pos), (int) (This->queue_len)); \
(int) (This->queue_head), (int) (This->queue_len)); \
\
if ((offset >= 0) && (This->queue_pos < This->queue_len)) { \
This->data_queue[This->queue_pos].dwOfs = offset; \
This->data_queue[This->queue_pos].dwData = data; \
This->data_queue[This->queue_pos].dwTimeStamp = xtime; \
This->data_queue[This->queue_pos].dwSequence = seq; \
This->queue_pos++; \
nq = This->queue_head+1; \
while (nq >= This->queue_len) nq -= This->queue_len; \
if ((offset >= 0) && (nq != This->queue_tail)) { \
This->data_queue[This->queue_head].dwOfs = offset; \
This->data_queue[This->queue_head].dwData = data; \
This->data_queue[This->queue_head].dwTimeStamp = xtime; \
This->data_queue[This->queue_head].dwSequence = seq; \
This->queue_head = nq; \
} \
} \
}

View File

@ -113,7 +113,7 @@ HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPU
* IDirectInputA_EnumDevices
*/
static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
LPDIRECTINPUTA iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,
LPDIRECTINPUT7A iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,
LPVOID pvRef, DWORD dwFlags
)
{
@ -133,13 +133,13 @@ static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
return 0;
}
static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUTA iface)
static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUT7A iface)
{
ICOM_THIS(IDirectInputAImpl,iface);
return ++(This->ref);
}
static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUTA iface)
static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUT7A iface)
{
ICOM_THIS(IDirectInputAImpl,iface);
if (!(--This->ref)) {
@ -150,7 +150,7 @@ static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUTA iface)
}
static HRESULT WINAPI IDirectInputAImpl_CreateDevice(
LPDIRECTINPUTA iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,
LPDIRECTINPUT7A iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,
LPUNKNOWN punk
) {
ICOM_THIS(IDirectInputAImpl,iface);
@ -173,7 +173,7 @@ static HRESULT WINAPI IDirectInputAImpl_CreateDevice(
}
static HRESULT WINAPI IDirectInputAImpl_QueryInterface(
LPDIRECTINPUTA iface,REFIID riid,LPVOID *ppobj
LPDIRECTINPUT7A iface,REFIID riid,LPVOID *ppobj
) {
ICOM_THIS(IDirectInputAImpl,iface);
@ -193,12 +193,12 @@ static HRESULT WINAPI IDirectInputAImpl_QueryInterface(
}
static HRESULT WINAPI IDirectInputAImpl_Initialize(
LPDIRECTINPUTA iface,HINSTANCE hinst,DWORD x
LPDIRECTINPUT7A iface,HINSTANCE hinst,DWORD x
) {
return DIERR_ALREADYINITIALIZED;
}
static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUTA iface,
static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUT7A iface,
REFGUID rguid) {
ICOM_THIS(IDirectInputAImpl,iface);
@ -207,7 +207,7 @@ static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUTA iface,
return DI_OK;
}
static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUTA iface,
static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUT7A iface,
HWND hwndOwner,
DWORD dwFlags) {
ICOM_THIS(IDirectInputAImpl,iface);

View File

@ -59,7 +59,7 @@ struct JoystickAImpl
HANDLE hEvent;
LONG lMin,lMax,deadzone;
LPDIDEVICEOBJECTDATA data_queue;
int queue_pos, queue_len;
int queue_head, queue_tail, queue_len;
DIJOYSTATE js;
};
@ -287,7 +287,8 @@ static HRESULT WINAPI JoystickAImpl_GetDeviceState(
FIXME("len %ld is not sizeof(DIJOYSTATE), unsupported format.\n",len);
}
memcpy(ptr,&(This->js),len);
This->queue_pos = 0;
This->queue_head = 0;
This->queue_tail = 0;
return 0;
}

View File

@ -75,7 +75,7 @@ struct JoystickAImpl
LPDIDATAFORMAT df;
HANDLE hEvent;
LPDIDEVICEOBJECTDATA data_queue;
int queue_pos, queue_len;
int queue_head, queue_tail, queue_len;
DIJOYSTATE js;
/* data returned by the EVIOCGABS() ioctl */
@ -504,7 +504,8 @@ static HRESULT WINAPI JoystickAImpl_GetDeviceState(
FIXME("len %ld is not sizeof(DIJOYSTATE), unsupported format.\n",len);
}
memcpy(ptr,&(This->js),len);
This->queue_pos = 0;
This->queue_head = 0;
This->queue_tail = 0;
return 0;
}

View File

@ -109,9 +109,10 @@ struct SysMouseAImpl
LPMOUSE_EVENT_PROC prev_handler;
HWND win;
DWORD dwCoopLevel;
POINT mapped_center;
DWORD win_centerX, win_centerY;
LPDIDEVICEOBJECTDATA data_queue;
int queue_pos, queue_len;
int queue_head, queue_tail, queue_len;
WARP_STATUS need_warp;
int acquired;
HANDLE hEvent;
@ -259,6 +260,8 @@ static HRESULT WINAPI SysMouseAImpl_SetCooperativeLevel(
_dump_cooperativelevel_DI(dwflags);
/* Store the window which asks for the mouse */
if (!hwnd)
hwnd = GetDesktopWindow();
This->win = hwnd;
This->dwCoopLevel = dwflags;
@ -349,7 +352,7 @@ static void WINAPI dinput_mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
} else {
/* Now, warp handling */
if ((This->need_warp == WARP_STARTED) &&
(posX == This->win_centerX) && (posX == This->win_centerX)) {
(posX == This->mapped_center.x) && (posY == This->mapped_center.y)) {
/* Warp has been done... */
This->need_warp = WARP_DONE;
goto end;
@ -365,13 +368,13 @@ static void WINAPI dinput_mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
} else {
/* This is the first time the event handler has been called after a
GetData of GetState. */
if (posX != This->win_centerX) {
GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], posX - This->win_centerX, xtime, (This->dinput->evsequence)++);
if (posX != This->mapped_center.x) {
GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], posX - This->mapped_center.x, xtime, (This->dinput->evsequence)++);
This->need_warp = WARP_NEEDED;
}
if (posY != This->win_centerY) {
GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], posY - This->win_centerY, xtime, (This->dinput->evsequence)++);
if (posY != This->mapped_center.y) {
GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], posY - This->mapped_center.y, xtime, (This->dinput->evsequence)++);
This->need_warp = WARP_NEEDED;
}
}
@ -384,8 +387,8 @@ static void WINAPI dinput_mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
This->m_state.lX = posX;
This->m_state.lY = posY;
} else {
This->m_state.lX = posX - This->win_centerX;
This->m_state.lY = posY - This->win_centerY;
This->m_state.lX = posX - This->mapped_center.x;
This->m_state.lY = posY - This->mapped_center.y;
}
} else {
/* Mouse reporting is in relative mode */
@ -533,11 +536,11 @@ static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface)
/* Warp the mouse to the center of the window */
if (This->absolute == 0) {
TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
point.x = This->win_centerX;
point.y = This->win_centerY;
MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
SetCursorPos( point.x, point.y );
This->mapped_center.x = This->win_centerX;
This->mapped_center.y = This->win_centerY;
MapWindowPoints(This->win, HWND_DESKTOP, &This->mapped_center, 1);
TRACE("Warping mouse to %ld - %ld\n", This->mapped_center.x, This->mapped_center.y);
SetCursorPos( This->mapped_center.x, This->mapped_center.y );
#ifdef MOUSE_HACK
This->need_warp = WARP_DONE;
#else
@ -602,13 +605,11 @@ static HRESULT WINAPI SysMouseAImpl_GetDeviceState(
/* Check if we need to do a mouse warping */
if (This->need_warp == WARP_NEEDED) {
POINT point;
TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
point.x = This->win_centerX;
point.y = This->win_centerY;
MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
SetCursorPos( point.x, point.y );
This->mapped_center.x = This->win_centerX;
This->mapped_center.y = This->win_centerY;
MapWindowPoints(This->win, HWND_DESKTOP, &This->mapped_center, 1);
TRACE("Warping mouse to %ld - %ld\n", This->mapped_center.x, This->mapped_center.y);
SetCursorPos( This->mapped_center.x, This->mapped_center.y );
#ifdef MOUSE_HACK
This->need_warp = WARP_DONE;
@ -636,52 +637,56 @@ static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface,
DWORD flags
) {
ICOM_THIS(SysMouseAImpl,iface);
DWORD nqpos = 0;
DWORD len, nqtail;
EnterCriticalSection(&(This->crit));
TRACE("(%p)->(dods=%ld,dod=%p,entries=%ld,fl=0x%08lx)\n",This,dodsize,dod,*entries,flags);
TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags);
len = ((This->queue_head < This->queue_tail) ? This->queue_len : 0)
+ (This->queue_head - This->queue_tail);
if (len > *entries) len = *entries;
if (dod == NULL) {
*entries = This->queue_pos;
nqpos = 0;
*entries = len;
nqtail = This->queue_tail + len;
while (nqtail >= This->queue_len) nqtail -= This->queue_len;
} else {
/* Check for buffer overflow */
if (This->queue_pos > dodsize) {
FIXME("Buffer overflow not handled properly yet...\n");
This->queue_pos = dodsize;
}
if (dodsize != sizeof(DIDEVICEOBJECTDATA)) {
ERR("Wrong structure size !\n");
LeaveCriticalSection(&(This->crit));
return DIERR_INVALIDPARAM;
}
if (This->queue_pos)
TRACE("Application retrieving %d event(s).\n", This->queue_pos);
if (len)
TRACE("Application retrieving %ld event(s).\n", len);
*entries = 0;
nqtail = This->queue_tail;
while (len) {
DWORD span = ((This->queue_head < nqtail) ? This->queue_len : This->queue_head)
- nqtail;
if (span > len) span = len;
/* Copy the buffered data into the application queue */
memcpy(dod, This->data_queue, This->queue_pos * dodsize);
*entries = This->queue_pos;
/* Reset the event queue */
nqpos = 0;
memcpy(dod + *entries, This->data_queue + nqtail, span * dodsize);
/* Advance position */
nqtail += span;
if (nqtail >= This->queue_len) nqtail -= This->queue_len;
*entries += span;
len -= span;
}
}
if (!(flags & DIGDD_PEEK))
This->queue_pos = nqpos;
This->queue_tail = nqtail;
LeaveCriticalSection(&(This->crit));
TRACE("returing *entries = %ld\n",*entries);
/* Check if we need to do a mouse warping */
if (This->need_warp == WARP_NEEDED) {
POINT point;
TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY);
point.x = This->win_centerX;
point.y = This->win_centerY;
MapWindowPoints(This->win, HWND_DESKTOP, &point, 1);
SetCursorPos( point.x, point.y );
This->mapped_center.x = This->win_centerX;
This->mapped_center.y = This->win_centerY;
MapWindowPoints(This->win, HWND_DESKTOP, &This->mapped_center, 1);
TRACE("Warping mouse to %ld - %ld\n", This->mapped_center.x, This->mapped_center.y);
SetCursorPos( This->mapped_center.x, This->mapped_center.y );
#ifdef MOUSE_HACK
This->need_warp = WARP_DONE;
@ -712,7 +717,8 @@ static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface,
This->data_queue = (LPDIDEVICEOBJECTDATA)HeapAlloc(GetProcessHeap(),0,
pd->dwData * sizeof(DIDEVICEOBJECTDATA));
This->queue_pos = 0;
This->queue_head = 0;
This->queue_tail = 0;
This->queue_len = pd->dwData;
break;
}