@@ -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
89107HRESULT 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
0 commit comments