Skip to content

Commit ecdb4f7

Browse files
committed
Quick and dirty DualSense support, USB only for now
1 parent ec58a58 commit ecdb4f7

File tree

2 files changed

+108
-6
lines changed

2 files changed

+108
-6
lines changed

JoyShockLibrary/InputHelpers.cpp

Lines changed: 106 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,112 @@ bool handle_input(JoyShock *jc, uint8_t *packet, int len, bool &hasIMU) {
141141
}
142142

143143
if (jc->controller_type == ControllerType::s_ds) {
144-
printf("%d: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
145-
packet[0], packet[1], packet[2], packet[3], packet[4], packet[5], packet[6], packet[7], packet[8], packet[9],
146-
packet[10], packet[11], packet[12], packet[13], packet[14], packet[15], packet[16], packet[17], packet[18], packet[19], packet[20]);
144+
//printf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
145+
// packet[0], packet[1], packet[2], packet[3], packet[4], packet[5], packet[6], packet[7], packet[8], packet[9],
146+
// packet[10], packet[11], packet[12], packet[13], packet[14], packet[15], packet[16], packet[17], packet[18], packet[19], packet[20],
147+
// packet[21], packet[22], packet[23], packet[24], packet[25], packet[26], packet[27], packet[28], packet[29], packet[30],
148+
// packet[31], packet[32], packet[33], packet[34], packet[35], packet[36], packet[37], packet[38], packet[39], packet[40],
149+
// packet[41], packet[42], packet[43], packet[44], packet[45], packet[46], packet[47], packet[48], packet[49], packet[50]);
150+
int indexOffset = 1;
151+
152+
// Gyroscope:
153+
// Gyroscope data is relative (degrees/s)
154+
int16_t gyroSampleX = uint16_to_int16(packet[indexOffset + 15] | (packet[indexOffset + 16] << 8) & 0xFF00);
155+
int16_t gyroSampleY = uint16_to_int16(packet[indexOffset + 17] | (packet[indexOffset + 18] << 8) & 0xFF00);
156+
int16_t gyroSampleZ = uint16_to_int16(packet[indexOffset + 19] | (packet[indexOffset + 20] << 8) & 0xFF00);
157+
int16_t accelSampleX = uint16_to_int16(packet[indexOffset + 21] | (packet[indexOffset + 22] << 8) & 0xFF00);
158+
int16_t accelSampleY = uint16_to_int16(packet[indexOffset + 23] | (packet[indexOffset + 24] << 8) & 0xFF00);
159+
int16_t accelSampleZ = uint16_to_int16(packet[indexOffset + 25] | (packet[indexOffset + 26] << 8) & 0xFF00);
160+
161+
if ((gyroSampleX | gyroSampleY | gyroSampleZ | accelSampleX | accelSampleY | accelSampleZ) == 0)
162+
{
163+
// all zero?
164+
hasIMU = false;
165+
}
166+
167+
// convert to real units
168+
jc->imu_state.gyroX = (float)(gyroSampleX) * (2000.0 / 32767.0);
169+
jc->imu_state.gyroY = (float)(gyroSampleY) * (2000.0 / 32767.0);
170+
jc->imu_state.gyroZ = (float)(gyroSampleZ) * (2000.0 / 32767.0);
171+
172+
jc->imu_state.accelX = (float)(accelSampleX) / 8192.0;
173+
jc->imu_state.accelY = (float)(accelSampleY) / 8192.0;
174+
jc->imu_state.accelZ = (float)(accelSampleZ) / 8192.0;
175+
176+
//printf("DS accel: %.4f, %.4f, %.4f\n", jc->imu_state.accelX, jc->imu_state.accelY, jc->imu_state.accelZ);
177+
178+
//printf("%.4f,%.4f,%.4f,%.4f,%.4f,%.4f,%d\n",
179+
// jc->gyro.yaw, jc->gyro.pitch, jc->gyro.roll, jc->accel.x, jc->accel.y, jc->accel.z, universal_counter++);
180+
181+
// Touchpad:
182+
jc->last_touch_state = jc->touch_state;
183+
184+
jc->touch_state.t0Id = (int)(packet[indexOffset + 32] & 0x7F);
185+
jc->touch_state.t1Id = (int)(packet[indexOffset + 36] & 0x7F);
186+
jc->touch_state.t0Down = (packet[indexOffset + 32] & 0x80) == 0;
187+
jc->touch_state.t1Down = (packet[indexOffset + 36] & 0x80) == 0;
188+
189+
jc->touch_state.t0X = (packet[indexOffset + 33] | (packet[indexOffset + 34] & 0x0F) << 8) / 1920.0f;
190+
jc->touch_state.t0Y = ((packet[indexOffset + 34] & 0xF0) >> 4 | packet[indexOffset + 35] << 4) / 943.0f;
191+
jc->touch_state.t1X = (packet[indexOffset + 37] | (packet[indexOffset + 38] & 0x0F) << 8) / 1920.0f;
192+
jc->touch_state.t1Y = ((packet[indexOffset + 38] & 0xF0) >> 4 | packet[indexOffset + 39] << 4) / 943.0f;
193+
194+
//printf("DS touch: %d, %d, %d, %d, %.4f, %.4f, %.4f, %.4f\n",
195+
// jc->touch_state.t0Id, jc->touch_state.t1Id, jc->touch_state.t0Down, jc->touch_state.t1Down,
196+
// jc->touch_state.t0X, jc->touch_state.t0Y, jc->touch_state.t1X, jc->touch_state.t1Y);
197+
198+
// DS dpad is a hat... 0x08 is released, 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW
199+
// http://eleccelerator.com/wiki/index.php?title=DualShock_4
200+
uint8_t hat = packet[indexOffset + 7] & 0x0f;
201+
202+
if ((hat > 2) & (hat < 6)) jc->simple_state.buttons |= JSMASK_DOWN; // down = SE | S | SW
203+
if ((hat == 7) | (hat < 2)) jc->simple_state.buttons |= JSMASK_UP; // up = N | NE | NW
204+
if ((hat > 0) & (hat < 4)) jc->simple_state.buttons |= JSMASK_RIGHT; // right = NE | E | SE
205+
if ((hat > 4) & (hat < 8)) jc->simple_state.buttons |= JSMASK_LEFT; // left = SW | W | NW
206+
207+
jc->simple_state.buttons |= ((int)(packet[indexOffset + 7] >> 4) << JSOFFSET_W) & JSMASK_W;
208+
jc->simple_state.buttons |= ((int)(packet[indexOffset + 7] >> 7) << JSOFFSET_N) & JSMASK_N;
209+
jc->simple_state.buttons |= ((int)(packet[indexOffset + 7] >> 5) << JSOFFSET_S) & JSMASK_S;
210+
jc->simple_state.buttons |= ((int)(packet[indexOffset + 7] >> 6) << JSOFFSET_E) & JSMASK_E;
211+
jc->simple_state.buttons |= ((int)(packet[indexOffset + 8] >> 6) << JSOFFSET_LCLICK) & JSMASK_LCLICK;
212+
jc->simple_state.buttons |= ((int)(packet[indexOffset + 8] >> 7) << JSOFFSET_RCLICK) & JSMASK_RCLICK;
213+
jc->simple_state.buttons |= ((int)(packet[indexOffset + 8] >> 5) << JSOFFSET_OPTIONS) & JSMASK_OPTIONS;
214+
jc->simple_state.buttons |= ((int)(packet[indexOffset + 8] >> 4) << JSOFFSET_SHARE) & JSMASK_SHARE;
215+
jc->simple_state.buttons |= ((int)(packet[indexOffset + 8] >> 1) << JSOFFSET_R) & JSMASK_R;
216+
jc->simple_state.buttons |= ((int)(packet[indexOffset + 8]) << JSOFFSET_L) & JSMASK_L;
217+
jc->simple_state.buttons |= ((int)(packet[indexOffset + 9]) << JSOFFSET_PS) & JSMASK_PS;
218+
jc->simple_state.buttons |= ((int)(packet[indexOffset + 9] >> 1) << JSOFFSET_TOUCHPAD_CLICK) & JSMASK_TOUCHPAD_CLICK;
219+
//jc->btns.zr = (packet[indexOffset+6] >> 3) & 1;
220+
//jc->btns.zl = (packet[indexOffset+6] >> 2) & 1;
221+
jc->simple_state.rTrigger = packet[indexOffset + 5] / 255.0f;
222+
jc->simple_state.lTrigger = packet[indexOffset + 4] / 255.0f;
223+
224+
if (jc->simple_state.rTrigger > 0.0) jc->simple_state.buttons |= JSMASK_ZR;
225+
if (jc->simple_state.lTrigger > 0.0) jc->simple_state.buttons |= JSMASK_ZL;
226+
227+
uint16_t stick_x = packet[indexOffset + 0];
228+
uint16_t stick_y = packet[indexOffset + 1];
229+
stick_y = 255 - stick_y;
230+
231+
uint16_t stick2_x = packet[indexOffset + 2];
232+
uint16_t stick2_y = packet[indexOffset + 3];
233+
stick2_y = 255 - stick2_y;
234+
235+
jc->simple_state.stickLX = (std::fmin)(1.0, (stick_x - 127.0) / 127.0);
236+
jc->simple_state.stickLY = (std::fmin)(1.0, (stick_y - 127.0) / 127.0);
237+
jc->simple_state.stickRX = (std::fmin)(1.0, (stick2_x - 127.0) / 127.0);
238+
jc->simple_state.stickRY = (std::fmin)(1.0, (stick2_y - 127.0) / 127.0);
239+
240+
if (jc->use_continuous_calibration) {
241+
jc->push_sensor_samples(jc->imu_state.gyroX, jc->imu_state.gyroY, jc->imu_state.gyroZ,
242+
sqrtf(jc->imu_state.accelX * jc->imu_state.accelX + jc->imu_state.accelY * jc->imu_state.accelY + jc->imu_state.accelZ * jc->imu_state.accelZ));
243+
jc->get_average_gyro(jc->offset_x, jc->offset_y, jc->offset_z, jc->accel_magnitude);
244+
}
245+
246+
jc->imu_state.gyroX -= jc->offset_x;
247+
jc->imu_state.gyroY -= jc->offset_y;
248+
jc->imu_state.gyroZ -= jc->offset_z;
249+
147250
return true;
148251
}
149252

JoyShockLibrary/JoyShockLibrary.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,7 @@ void pollIndividualLoop(JoyShock *jc) {
139139
_pollCallback(jc->intHandle, jc->simple_state, jc->last_simple_state, jc->imu_state, jc->last_imu_state, jc->delta_time);
140140
}
141141
// touchpad will have its own callback so that it doesn't change the existing api
142-
// todo: s_ds (DualSense) should be able to do this, too
143-
if (jc->controller_type == ControllerType::s_ds4 && _pollTouchCallback != nullptr) {
142+
if (jc->controller_type != ControllerType::n_switch && _pollTouchCallback != nullptr) {
144143
_pollTouchCallback(jc->intHandle, jc->touch_state, jc->last_touch_state, jc->delta_time);
145144
}
146145
_callbackLock.unlock_shared();
@@ -179,7 +178,7 @@ void pollIndividualLoop(JoyShock *jc) {
179178
int JslConnectDevices()
180179
{
181180
// for writing to console:
182-
freopen("CONOUT$", "w", stdout);
181+
//freopen("CONOUT$", "w", stdout);
183182
if (_joyshocks.size() > 0) {
184183
// already connected? clean up old stuff!
185184
JslDisconnectAndDisposeAll();

0 commit comments

Comments
 (0)