Skip to content

Commit 629b986

Browse files
committed
Update how mouse buffer and sequence work
#493
1 parent 8c092ff commit 629b986

File tree

3 files changed

+90
-48
lines changed

3 files changed

+90
-48
lines changed

Dllmain/BuildNo.rc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
#define BUILD_NUMBER 8147
1+
#define BUILD_NUMBER 8148

dinput8/IDirectInputDevice8.cpp

Lines changed: 87 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,25 @@ HRESULT m_IDirectInputDevice8::GetProperty(REFGUID rguidProp, LPDIPROPHEADER pdi
8383
{
8484
Logging::LogDebug() << __FUNCTION__ << " (" << this << ")";
8585

86-
return ProxyInterface->GetProperty(rguidProp, pdiph);
86+
HRESULT hr = ProxyInterface->GetProperty(rguidProp, pdiph);
87+
88+
if (SUCCEEDED(hr))
89+
{
90+
// Handle mouse input buffer size
91+
if (IsMouse && Config.FixHighFrequencyMouse)
92+
{
93+
if ((DWORD)&rguidProp == (DWORD)&DIPROP_BUFFERSIZE && RequestedMouseBufferSize)
94+
{
95+
if (pdiph && pdiph->dwSize == sizeof(DIPROPDWORD))
96+
{
97+
DIPROPDWORD* pOut = reinterpret_cast<DIPROPDWORD*>(pdiph);
98+
pOut->dwData = RequestedMouseBufferSize;
99+
}
100+
}
101+
}
102+
}
103+
104+
return hr;
87105
}
88106

89107
HRESULT m_IDirectInputDevice8::SetProperty(REFGUID rguidProp, LPCDIPROPHEADER pdiph)
@@ -104,9 +122,23 @@ HRESULT m_IDirectInputDevice8::SetProperty(REFGUID rguidProp, LPCDIPROPHEADER pd
104122

105123
DIPROPDWORD dipdw = *pIn;
106124

107-
DWORD requested = dipdw.dwData;
125+
DWORD requested = dipdw.dwData ? dipdw.dwData : RequestedMouseBufferSize;
108126
dipdw.dwData = max(dipdw.dwData, dwMinBufferSize);
109127

128+
if (requested == 0)
129+
{
130+
DIPROPDWORD r_dipdw = {};
131+
r_dipdw.diph.dwSize = sizeof(DIPROPDWORD);
132+
r_dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
133+
r_dipdw.diph.dwObj = 0;
134+
r_dipdw.diph.dwHow = DIPH_DEVICE;
135+
136+
if (SUCCEEDED(ProxyInterface->GetProperty(DIPROP_BUFFERSIZE, &r_dipdw.diph)))
137+
{
138+
requested = r_dipdw.dwData;
139+
}
140+
}
141+
110142
HRESULT hr = ProxyInterface->SetProperty(rguidProp, &dipdw.diph);
111143

112144
if (SUCCEEDED(hr))
@@ -183,6 +215,10 @@ HRESULT m_IDirectInputDevice8::GetMouseDeviceData(DWORD cbObjectData, LPDIDEVICE
183215
*pdwInOut = 0;
184216
return hr;
185217
}
218+
if (dwItems == INFINITE)
219+
{
220+
dwItems = MouseBufferSize ? MouseBufferSize : 32; // Resonable default
221+
}
186222

187223
// Ensure buffer is large enough
188224
const DWORD requiredBytes = dwItems * cbObjectData;
@@ -207,15 +243,24 @@ HRESULT m_IDirectInputDevice8::GetMouseDeviceData(DWORD cbObjectData, LPDIDEVICE
207243
}
208244

209245
// Merge and store device object data
210-
if (!isFlushingData)
246+
if (!isFlushingData && dwItems)
211247
{
212248
bool isSet[3] = { false };
213249
DWORD Loc[3] = { 0 };
214250

251+
if (SequenceCounter == 0)
252+
{
253+
SequenceCounter = lpdod->dwSequence;
254+
}
255+
if (LastSentSequenceCounter && std::abs((LONG)LastSentSequenceCounter - (LONG)lpdod->dwSequence) > 1)
256+
{
257+
isBufferOverflow = true;
258+
}
259+
215260
// Loop through buffer and merge like data
216261
for (UINT x = 0; x < dwItems; x++)
217262
{
218-
// Storing movement data
263+
// Handle movement data
219264
if (lpdod->dwOfs == Ofs.x || lpdod->dwOfs == Ofs.y || lpdod->dwOfs == Ofs.z)
220265
{
221266
const int v = lpdod->dwOfs == Ofs.x ? 0 : lpdod->dwOfs == Ofs.y ? 1 : 2;
@@ -224,35 +269,29 @@ HRESULT m_IDirectInputDevice8::GetMouseDeviceData(DWORD cbObjectData, LPDIDEVICE
224269
if (isSet[v])
225270
{
226271
dod[Loc[v]].lData += (LONG)lpdod->dwData;
272+
273+
lpdod = (LPDIDEVICEOBJECTDATA)((BYTE*)lpdod + cbObjectData);
274+
continue;
227275
}
228276
// Storing new movement data
229277
else
230278
{
231-
if constexpr (std::is_same_v<T, MOUSECACHEDATA_DX3>)
232-
{
233-
dod.push_back({ lpdod->dwOfs, (LONG)lpdod->dwData, lpdod->dwTimeStamp, lpdod->dwSequence });
234-
}
235-
else
236-
{
237-
dod.push_back({ lpdod->dwOfs, (LONG)lpdod->dwData, lpdod->dwTimeStamp, lpdod->dwSequence, lpdod->uAppData });
238-
}
239-
240279
isSet[v] = true;
241-
Loc[v] = dod.size() - 1;
280+
Loc[v] = dod.size();
242281
}
243282
}
244-
// Storing button data
283+
284+
// Store data
285+
if constexpr (std::is_same_v<T, MOUSECACHEDATA_DX3>)
286+
{
287+
dod.push_back({ lpdod->dwOfs, (LONG)lpdod->dwData, lpdod->dwTimeStamp, SequenceCounter++ });
288+
}
245289
else
246290
{
247-
if constexpr (std::is_same_v<T, MOUSECACHEDATA_DX3>)
248-
{
249-
dod.push_back({ lpdod->dwOfs, (LONG)lpdod->dwData, lpdod->dwTimeStamp, lpdod->dwSequence });
250-
}
251-
else
252-
{
253-
dod.push_back({ lpdod->dwOfs, (LONG)lpdod->dwData, lpdod->dwTimeStamp, lpdod->dwSequence, lpdod->uAppData });
254-
}
291+
dod.push_back({ lpdod->dwOfs, (LONG)lpdod->dwData, lpdod->dwTimeStamp, SequenceCounter++, lpdod->uAppData });
255292
}
293+
LastSentSequenceCounter = lpdod->dwSequence;
294+
256295
lpdod = (LPDIDEVICEOBJECTDATA)((BYTE*)lpdod + cbObjectData);
257296
}
258297

@@ -265,8 +304,9 @@ HRESULT m_IDirectInputDevice8::GetMouseDeviceData(DWORD cbObjectData, LPDIDEVICE
265304
{
266305
if (dod[Loc[v]].lData != 0)
267306
{
268-
double factor = (dod[Loc[v]].dwOfs == Ofs.y) ? Config.MouseMovementFactor : std::abs(Config.MouseMovementFactor);
307+
double factor = (item == Ofs.y) ? Config.MouseMovementFactor : std::abs(Config.MouseMovementFactor);
269308
LONG baseMovement = (LONG)round(dod[Loc[v]].lData * factor);
309+
270310
if (std::abs(baseMovement) < (LONG)Config.MouseMovementPadding)
271311
{
272312
dod[Loc[v]].lData = (dod[Loc[v]].lData < 0) ? -(LONG)Config.MouseMovementPadding : (LONG)Config.MouseMovementPadding;
@@ -280,6 +320,24 @@ HRESULT m_IDirectInputDevice8::GetMouseDeviceData(DWORD cbObjectData, LPDIDEVICE
280320
}
281321
}
282322

323+
// Check buffer size
324+
if (MouseBufferSize == 0)
325+
{
326+
DIPROPDWORD dipdw = {};
327+
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
328+
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
329+
dipdw.diph.dwObj = 0;
330+
dipdw.diph.dwHow = DIPH_DEVICE;
331+
332+
SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);
333+
}
334+
335+
// Check for buffer overflow
336+
if (RequestedMouseBufferSize && RequestedMouseBufferSize < dod.size())
337+
{
338+
isBufferOverflow = true;
339+
}
340+
283341
DWORD dwOut = 0;
284342

285343
// Checking for device object data
@@ -299,31 +357,12 @@ HRESULT m_IDirectInputDevice8::GetMouseDeviceData(DWORD cbObjectData, LPDIDEVICE
299357
// Fill device object data
300358
else
301359
{
302-
if (MouseBufferSize == 0)
303-
{
304-
DIPROPDWORD dipdw = {};
305-
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
306-
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
307-
dipdw.diph.dwObj = 0;
308-
dipdw.diph.dwHow = DIPH_DEVICE;
309-
310-
if (SUCCEEDED(ProxyInterface->GetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)))
311-
{
312-
MouseBufferSize = dipdw.dwData;
313-
RequestedMouseBufferSize = dipdw.dwData;
314-
}
315-
else
316-
{
317-
LOG_LIMIT(100, __FUNCTION__ << " Warning: failed to get default mouse buffer size!");
318-
}
319-
}
320-
321-
DWORD dwRequested = *pdwInOut;
322-
if (dwRequested == INFINITE && RequestedMouseBufferSize)
360+
DWORD requested = *pdwInOut;
361+
if (requested == INFINITE && RequestedMouseBufferSize)
323362
{
324-
dwRequested = RequestedMouseBufferSize;
363+
requested = RequestedMouseBufferSize;
325364
}
326-
dwOut = min(dod.size(), dwRequested);
365+
dwOut = min(dod.size(), requested);
327366

328367
memcpy(rgdod, dod.data(), sizeof(T) * dwOut);
329368

@@ -345,6 +384,7 @@ HRESULT m_IDirectInputDevice8::GetMouseDeviceData(DWORD cbObjectData, LPDIDEVICE
345384

346385
if (isBufferOverflow)
347386
{
387+
SequenceCounter += 5; // Simulate overflow
348388
return DI_BUFFEROVERFLOW;
349389
}
350390

dinput8/IDirectInputDevice8.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class m_IDirectInputDevice8 : public IDirectInputDevice8A, public IDirectInputDe
2828
bool IsMouse = false;
2929
DWORD MouseBufferSize = 0;
3030
DWORD RequestedMouseBufferSize = 0;
31+
DWORD SequenceCounter = 0;
32+
DWORD LastSentSequenceCounter = 0;
3133
DWORD LastObjectSize = 0;
3234
struct {
3335
DWORD x = DIMOFS_X;

0 commit comments

Comments
 (0)