1 /*
2 	DS5_Input.h is part of DualSenseWindows
3 	https://github.com/Ohjurot/DualSense-Windows
4 
5 	Contributors of this file:
6 	11.2020 Ludwig Füchsl
7 
8 	Licensed under the MIT License (To be found in repository root directory)
9 */
10 module ds5w.ds5input;
11 
12 import ds5w.dswapi;
13 import ds5w.device;
14 import ds5w.ds5state;
15 
16 import core.stdc.string;
17 
18 void evaluateHidInputBuffer(ubyte* hidInBuffer, DS5InputState* ptrInputState)
19 {
20     // Convert sticks to signed range
21     ptrInputState.leftStick.x = cast(ubyte)((cast(short)(hidInBuffer[0x00] - 128)));
22     ptrInputState.leftStick.y = cast(ubyte)((cast(short)(hidInBuffer[0x01] - 127)) * -1);
23     ptrInputState.rightStick.x = cast(ubyte)((cast(short)(hidInBuffer[0x02] - 128)));
24     ptrInputState.rightStick.y = cast(ubyte)((cast(short)(hidInBuffer[0x03] - 127)) * -1);
25 
26     // Convert trigger to unsigned range
27     ptrInputState.leftTrigger = hidInBuffer[0x04];
28     ptrInputState.rightTrigger = hidInBuffer[0x05];
29 
30     // Buttons
31     ptrInputState.buttonsAndDpad = hidInBuffer[0x07] & 0xF0;
32     ptrInputState.buttonsA = hidInBuffer[0x08];
33     ptrInputState.buttonsB = hidInBuffer[0x09];
34 
35     // Dpad
36     switch (hidInBuffer[0x07] & 0x0F)
37     {
38         // Up
39     case 0x0:
40         ptrInputState.buttonsAndDpad |= DS5W_ISTATE_DPAD_UP;
41         break;
42         // Down
43     case 0x4:
44         ptrInputState.buttonsAndDpad |= DS5W_ISTATE_DPAD_DOWN;
45         break;
46         // Left
47     case 0x6:
48         ptrInputState.buttonsAndDpad |= DS5W_ISTATE_DPAD_LEFT;
49         break;
50         // Right
51     case 0x2:
52         ptrInputState.buttonsAndDpad |= DS5W_ISTATE_DPAD_RIGHT;
53         break;
54         // Left Down
55     case 0x5:
56         ptrInputState.buttonsAndDpad |= DS5W_ISTATE_DPAD_LEFT | DS5W_ISTATE_DPAD_DOWN;
57         break;
58         // Left Up
59     case 0x7:
60         ptrInputState.buttonsAndDpad |= DS5W_ISTATE_DPAD_LEFT | DS5W_ISTATE_DPAD_UP;
61         break;
62         // Right Up
63     case 0x1:
64         ptrInputState.buttonsAndDpad |= DS5W_ISTATE_DPAD_RIGHT | DS5W_ISTATE_DPAD_UP;
65         break;
66         // Right Down
67     case 0x3:
68         ptrInputState.buttonsAndDpad |= DS5W_ISTATE_DPAD_RIGHT | DS5W_ISTATE_DPAD_DOWN;
69         break;
70     default:
71         break;
72     }
73 
74     // Copy accelerometer readings
75     memcpy(&ptrInputState.accelerometer, &hidInBuffer[0x0F], 2 * 3);
76 
77     //TEMP: Copy gyro data (no processing currently done!)
78     memcpy(&ptrInputState.gyroscope, &hidInBuffer[0x15], 2 * 3);
79 
80     // Evaluate touch state 1
81     uint touchpad1Raw = *cast(uint*)(&hidInBuffer[0x20]);
82     ptrInputState.touchPoint1.y = (touchpad1Raw & 0xFFF00000) >> 20;
83     ptrInputState.touchPoint1.x = (touchpad1Raw & 0x000FFF00) >> 8;
84     ptrInputState.touchPoint1.down = (touchpad1Raw & (1 << 7)) == 0;
85     ptrInputState.touchPoint1.id = (touchpad1Raw & 127);
86 
87     // Evaluate touch state 2
88     uint touchpad2Raw = *cast(uint*)(&hidInBuffer[0x24]);
89     ptrInputState.touchPoint2.y = (touchpad2Raw & 0xFFF00000) >> 20;
90     ptrInputState.touchPoint2.x = (touchpad2Raw & 0x000FFF00) >> 8;
91     ptrInputState.touchPoint2.down = (touchpad2Raw & (1 << 7)) == 0;
92     ptrInputState.touchPoint2.id = (touchpad2Raw & 127);
93 
94     // Evaluate headphone input
95     ptrInputState.headPhoneConnected = hidInBuffer[0x35] & 0x01;
96 
97     // Trigger force feedback
98     ptrInputState.leftTriggerFeedback = hidInBuffer[0x2A];
99     ptrInputState.rightTriggerFeedback = hidInBuffer[0x29];
100 
101     // Battery
102     ptrInputState.battery.chargin = (hidInBuffer[0x35] & 0x08) ? true : false;
103     ptrInputState.battery.fullyCharged = (hidInBuffer[0x36] & 0x20) ? true : false;
104     ptrInputState.battery.level = (hidInBuffer[0x36] & 0x0F);
105 }