@@ -309,6 +309,74 @@ DMF_DsHidMini_Close(
309309
310310#pragma endregion
311311
312+ #pragma region Accelerometer Specific
313+
314+ //
315+ // Convert accelerometer values to selected axis
316+ // SHORT value, value to convert
317+ // int mode, what operations to apply
318+ // int sensitivity, sensitivity adjustment value
319+ //
320+ // AccelY converts with wrong tilt for thumb axis so flip, dont break
321+ // AccelY and X gets sensitivity adjustment then add 127 to represent Thumb axis
322+ // Check Y is less than 0 if so make sensitivity adjustment on positive value of Y then double to scale properly
323+ // Check Y is more than 0 if so make sensitivity adjustment on value of Y then double to scale properly
324+ //
325+ //
326+ USHORT AccelConversion (SHORT value ,int mode ,int sensitivity )
327+ {
328+ switch (mode )
329+ {
330+ case (DsAccelY ):
331+ value -= value * 2 ;
332+ case (DsAccelX ):
333+ value = (value * 0XC ) / (1000 / sensitivity ) + 0X7F ;
334+ break ;
335+ case (DsAccelYtoL2 ):
336+ value = (value > 0 ) ? 0 : (SHORT )abs ((value * 0XC ) / (1000 / sensitivity ) * 2 );
337+ break ;
338+ case (DsAccelYtoR2 ):
339+ value = (value < 0 ) ? 0 : (value * 0XC ) / (1000 / sensitivity ) * 2 ;
340+ break ;
341+ default :
342+ break ;
343+ }
344+ // Ensure in range when returning
345+ return (value < 0 ) ? 0 : (value = (value > 255 ) ? 255 : value );
346+ }
347+
348+ //
349+ // Switch profiler mode then perform operations
350+ // takes full inReport and Context currenty
351+ // Y axis Middle/Level seems to need 0X1FF, any less and the reading is offset towards down
352+ // X axis Middle/Level is 0X1F7
353+ // if new L2 or R2 pressure values are above 0 set as engaged
354+ //
355+
356+ PDS3_RAW_INPUT_REPORT AccelProfiler (PDS3_RAW_INPUT_REPORT pInReport , PDEVICE_CONTEXT pDevCtx )
357+ {
358+
359+ switch (pDevCtx -> Configuration .ProfilerMode )
360+ {
361+ case DsProfileModeb :
362+ pInReport -> LeftThumbY = (UCHAR )AccelConversion (0X1FF - _byteswap_ushort (pInReport -> AccelerometerY ), DsAccelY , pDevCtx -> Configuration .AccelYSensitivity );
363+ case DsProfileModea :
364+ pInReport -> LeftThumbX = (UCHAR )AccelConversion (0X1F7 - _byteswap_ushort (pInReport -> AccelerometerX ), DsAccelX , pDevCtx -> Configuration .AccelXSensitivity );
365+ break ;
366+ case DsProfileModec :
367+ pInReport -> LeftThumbX = (UCHAR )AccelConversion (0X1F7 - _byteswap_ushort (pInReport -> AccelerometerX ), DsAccelX , pDevCtx -> Configuration .AccelXSensitivity );
368+ pInReport -> Pressure .Values .R2 = (UCHAR )AccelConversion (0X1FF - _byteswap_ushort (pInReport -> AccelerometerY ), DsAccelYtoR2 , pDevCtx -> Configuration .AccelYSensitivity );
369+ if (pInReport -> Pressure .Values .R2 ) { pInReport -> Buttons .Individual .R2 = 1 ; }
370+ pInReport -> Pressure .Values .L2 = (UCHAR )AccelConversion (0X1FF - _byteswap_ushort (pInReport -> AccelerometerY ), DsAccelYtoL2 , pDevCtx -> Configuration .AccelYSensitivity );
371+ if (pInReport -> Pressure .Values .L2 ) { pInReport -> Buttons .Individual .L2 = 1 ; }
372+ default :
373+ break ;
374+ }
375+ return pInReport ;
376+ }
377+
378+ #pragma endregion
379+
312380#pragma region DMF Virtual HID Mini-specific
313381
314382NTSTATUS
@@ -1483,6 +1551,42 @@ VOID DsUsb_EvtUsbInterruptPipeReadComplete(
14831551 {
14841552 pDevCtx -> BatteryStatus = battery ;
14851553 }
1554+
1555+ //
1556+ // Quick profile combo (L1 + (Circle || Cross || Triangle || Square)) detectection
1557+ //
1558+ if (pDevCtx -> Configuration .EnableProfiler && pInReport -> Buttons .Individual .PS )
1559+ {
1560+ t1 = & pDevCtx -> ProfileSwitcherTimestamp ;
1561+
1562+ if (pDevCtx -> ProfileSwitcherTimestamp .QuadPart == 0 )
1563+ {
1564+ QueryPerformanceCounter (t1 );
1565+ }
1566+
1567+ QueryPerformanceCounter (& t2 );
1568+
1569+ ms = (t2 .QuadPart - t1 -> QuadPart ) / (freq .QuadPart / 1000 );
1570+
1571+ //
1572+ // Timeout reached so check if mode change is requested
1573+ //
1574+ if (ms > 1000 )
1575+ {
1576+ DS_PROFILE_MODE mode = (pInReport -> Buttons .Individual .Cross ) ? DsProfileModeDefault :
1577+ (pInReport -> Buttons .Individual .Square ) ? DsProfileModea :
1578+ (pInReport -> Buttons .Individual .Triangle ) ? DsProfileModeb :
1579+ (pInReport -> Buttons .Individual .Circle ) ? DsProfileModec : -1 ;
1580+ pDevCtx -> Configuration .ProfilerMode = ((mode > -1 ) && (pDevCtx -> Configuration .ProfilerMode != mode )) ? mode : pDevCtx -> Configuration .ProfilerMode ;
1581+ FuncExitNoReturn (TRACE_DSHIDMINIDRV );
1582+ return ;
1583+ }
1584+ }
1585+
1586+ //
1587+ // If not default profile process accelerometer data for pInReport
1588+ //
1589+ pInReport = (pDevCtx -> Configuration .EnableProfiler && (pDevCtx -> Configuration .ProfilerMode != DsProfileModeDefault )) ? AccelProfiler (pInReport , pDevCtx ) : pInReport ;
14861590
14871591 Ds_ProcessHidInputReport (pDevCtx , pInReport );
14881592
@@ -1798,6 +1902,41 @@ DsBth_HidInterruptReadContinuousRequestCompleted(
17981902 pDevCtx -> Connection .Bth .IdleDisconnectTimestamp .QuadPart = 0 ;
17991903 }
18001904
1905+ //
1906+ // Quick profile combo (L1 + (Circle || Cross || Triangle || Square)) detectection
1907+ //
1908+ if (pDevCtx -> Configuration .EnableProfiler && pInReport -> Buttons .Individual .PS )
1909+ {
1910+ t1 = & pDevCtx -> ProfileSwitcherTimestamp ;
1911+
1912+ if (pDevCtx -> ProfileSwitcherTimestamp .QuadPart == 0 )
1913+ {
1914+ QueryPerformanceCounter (t1 );
1915+ }
1916+
1917+ QueryPerformanceCounter (& t2 );
1918+
1919+ ms = (t2 .QuadPart - t1 -> QuadPart ) / (freq .QuadPart / 1000 );
1920+
1921+ //
1922+ // Timeout reached so check if mode change is requested
1923+ //
1924+ if (ms > 1000 )
1925+ {
1926+ DS_PROFILE_MODE mode = (pInReport -> Buttons .Individual .Cross ) ? DsProfileModeDefault :
1927+ (pInReport -> Buttons .Individual .Square ) ? DsProfileModea :
1928+ (pInReport -> Buttons .Individual .Triangle ) ? DsProfileModeb :
1929+ (pInReport -> Buttons .Individual .Circle ) ? DsProfileModec : -1 ;
1930+ pDevCtx -> Configuration .ProfilerMode = ((mode > -1 ) && (pDevCtx -> Configuration .ProfilerMode != mode )) ? mode : pDevCtx -> Configuration .ProfilerMode ;
1931+ }
1932+ return ContinuousRequestTarget_BufferDisposition_ContinuousRequestTargetAndContinueStreaming ;
1933+ }
1934+
1935+ //
1936+ // If not default profile process accelerometer data for pInReport
1937+ //
1938+ pInReport = (pDevCtx -> Configuration .EnableProfiler && (pDevCtx -> Configuration .ProfilerMode != DsProfileModeDefault )) ? AccelProfiler (pInReport , pDevCtx ) : pInReport ;
1939+
18011940 Ds_ProcessHidInputReport (pDevCtx , pInReport );
18021941
18031942 return ContinuousRequestTarget_BufferDisposition_ContinuousRequestTargetAndContinueStreaming ;
0 commit comments