public DS4Data ReadDS4Data() { byte[] data = new byte[78]; int status = RecieveRaw(hidapi_handle, data); if (status <= 0) return null; // Either there is some sort of error or we haven't recieved anything dump = data; DS4Data cState = new DS4Data(); // From DS4Tool Source // // https://code.google.com/p/ds4-tool/ // cState.lstick[0] = data[1]; cState.lstick[1] = data[2]; cState.rstick[0] = data[3]; cState.rstick[1] = data[4]; cState.L2_analog = data[8]; cState.R2_analog = data[9]; cState.Triangle = ((byte)data[5] & (1 << 7)) != 0; cState.Circle = ((byte)data[5] & (1 << 6)) != 0; cState.Cross = ((byte)data[5] & (1 << 5)) != 0; cState.Square = ((byte)data[5] & (1 << 4)) != 0; cState.DpadUp = ((byte)data[5] & (1 << 3)) != 0; cState.DpadDown = ((byte)data[5] & (1 << 2)) != 0; cState.DpadLeft = ((byte)data[5] & (1 << 1)) != 0; cState.DpadRight = ((byte)data[5] & (1 << 0)) != 0; //Convert dpad into individual On/Off bits instead of a clock representation int dpad_state = ((cState.DpadRight ? 1 : 0) << 0) | ((cState.DpadLeft ? 1 : 0) << 1) | ((cState.DpadDown ? 1 : 0) << 2) | ((cState.DpadUp ? 1 : 0) << 3); switch (dpad_state) { case 0: cState.DpadUp = true; cState.DpadDown = false; cState.DpadLeft = false; cState.DpadRight = false; break; case 1: cState.DpadUp = true; cState.DpadDown = false; cState.DpadLeft = false; cState.DpadRight = true; break; case 2: cState.DpadUp = false; cState.DpadDown = false; cState.DpadLeft = false; cState.DpadRight = true; break; case 3: cState.DpadUp = false; cState.DpadDown = true; cState.DpadLeft = false; cState.DpadRight = true; break; case 4: cState.DpadUp = false; cState.DpadDown = true; cState.DpadLeft = false; cState.DpadRight = false; break; case 5: cState.DpadUp = false; cState.DpadDown = true; cState.DpadLeft = true; cState.DpadRight = false; break; case 6: cState.DpadUp = false; cState.DpadDown = false; cState.DpadLeft = true; cState.DpadRight = false; break; case 7: cState.DpadUp = true; cState.DpadDown = false; cState.DpadLeft = true; cState.DpadRight = false; break; case 8: cState.DpadUp = false; cState.DpadDown = false; cState.DpadLeft = false; cState.DpadRight = false; break; } cState.R3 = (data[6] & (1 << 7)) != 0; cState.L3 = (data[6] & (1 << 6)) != 0; cState.Options = (data[6] & (1 << 5)) != 0; cState.Share = (data[6] & (1 << 4)) != 0; cState.R1 = (data[6] & (1 << 1)) != 0; cState.L1 = (data[6] & (1 << 0)) != 0; cState.R2 = (data[6] & (1 << 3)) != 0; cState.L2 = (data[6] & (1 << 2)) != 0; cState.PS = (data[7] & (1 << 0)) != 0; cState.TouchButton = (data[7] & (1 << 2 - 1)) != 0; // Note: The trackpad, for whatever reason, can send data in multiple "packets" - I assume this accounts for the case where // you miss a read request in between multiple trackpad polls. We DO NOT use this here. bool tp_active1 = (data[0 + TOUCHPAD_DATA_OFFSET] >> 7) == 0; // >= 1 touch detected bool tp_active2 = (data[4 + TOUCHPAD_DATA_OFFSET] >> 7) == 0; // > 1 touch detected int touch1_x = data[1 + TOUCHPAD_DATA_OFFSET] | ((data[2 + TOUCHPAD_DATA_OFFSET] & 0xF) << 8); int touch1_y = ((data[2 + TOUCHPAD_DATA_OFFSET] & 0xF0) >> 4) | ((data[3 + TOUCHPAD_DATA_OFFSET] << 4)); int touch2_x = data[5 + TOUCHPAD_DATA_OFFSET] | ((data[6 + TOUCHPAD_DATA_OFFSET] & 0xF) << 8); int touch2_y = ((data[6 + TOUCHPAD_DATA_OFFSET] & 0xF0) >> 4) | ((data[7 + TOUCHPAD_DATA_OFFSET] << 4)); if(tp_active1 && tp_active2) cState.Touches = new int[,] { { touch1_x, touch1_y }, { touch2_x, touch2_y } }; else if (tp_active1) cState.Touches = new int[,] { { touch1_x, touch1_y }, { -1, -1 } }; else cState.Touches = new int[,] { { -1, -1 }, { -1, -1 } }; // End section from ds4tool source // cState.Timestamp = (ushort)((data[11] << 8) | data[10]); short[] Gyro = new short[3]; short[] Accel = new short[3]; Gyro[0] = (short)((data[14] << 8) | data[13]); Gyro[1] = (short)((data[16] << 8) | data[15]); Gyro[2] = (short)((data[18] << 8) | data[17]); Accel[0] = (short)((data[20] << 8) | data[19]); Accel[1] = (short)((data[22] << 8) | data[21]); Accel[2] = (short)((data[24] << 8) | data[23]); _Orientation.ApplyGyroAccel(Accel, Gyro, cState.Timestamp); cState.Orientation = _Orientation; return cState; }
void Update() { if (!DS4Manager.HasWiimote()) { return; } controller = DS4Manager.Controllers[0]; DS4Data tentative = data; do { data = tentative; tentative = controller.ReadDS4Data(); } while (tentative != null); if (Visual != null) Visual.rotation = data.Orientation.Orientation; }
public DS4Data ReadDS4Data() { byte[] data = new byte[78]; int status = RecieveRaw(hidapi_handle, data); if (status <= 0) { return(null); // Either there is some sort of error or we haven't recieved anything } dump = data; DS4Data cState = new DS4Data(); // From DS4Tool Source // // https://code.google.com/p/ds4-tool/ // cState.lstick[0] = data[1]; cState.lstick[1] = data[2]; cState.rstick[0] = data[3]; cState.rstick[1] = data[4]; cState.L2_analog = data[8]; cState.R2_analog = data[9]; cState.Triangle = ((byte)data[5] & (1 << 7)) != 0; cState.Circle = ((byte)data[5] & (1 << 6)) != 0; cState.Cross = ((byte)data[5] & (1 << 5)) != 0; cState.Square = ((byte)data[5] & (1 << 4)) != 0; cState.DpadUp = ((byte)data[5] & (1 << 3)) != 0; cState.DpadDown = ((byte)data[5] & (1 << 2)) != 0; cState.DpadLeft = ((byte)data[5] & (1 << 1)) != 0; cState.DpadRight = ((byte)data[5] & (1 << 0)) != 0; //Convert dpad into individual On/Off bits instead of a clock representation int dpad_state = ((cState.DpadRight ? 1 : 0) << 0) | ((cState.DpadLeft ? 1 : 0) << 1) | ((cState.DpadDown ? 1 : 0) << 2) | ((cState.DpadUp ? 1 : 0) << 3); switch (dpad_state) { case 0: cState.DpadUp = true; cState.DpadDown = false; cState.DpadLeft = false; cState.DpadRight = false; break; case 1: cState.DpadUp = true; cState.DpadDown = false; cState.DpadLeft = false; cState.DpadRight = true; break; case 2: cState.DpadUp = false; cState.DpadDown = false; cState.DpadLeft = false; cState.DpadRight = true; break; case 3: cState.DpadUp = false; cState.DpadDown = true; cState.DpadLeft = false; cState.DpadRight = true; break; case 4: cState.DpadUp = false; cState.DpadDown = true; cState.DpadLeft = false; cState.DpadRight = false; break; case 5: cState.DpadUp = false; cState.DpadDown = true; cState.DpadLeft = true; cState.DpadRight = false; break; case 6: cState.DpadUp = false; cState.DpadDown = false; cState.DpadLeft = true; cState.DpadRight = false; break; case 7: cState.DpadUp = true; cState.DpadDown = false; cState.DpadLeft = true; cState.DpadRight = false; break; case 8: cState.DpadUp = false; cState.DpadDown = false; cState.DpadLeft = false; cState.DpadRight = false; break; } cState.R3 = (data[6] & (1 << 7)) != 0; cState.L3 = (data[6] & (1 << 6)) != 0; cState.Options = (data[6] & (1 << 5)) != 0; cState.Share = (data[6] & (1 << 4)) != 0; cState.R1 = (data[6] & (1 << 1)) != 0; cState.L1 = (data[6] & (1 << 0)) != 0; cState.R2 = (data[6] & (1 << 3)) != 0; cState.L2 = (data[6] & (1 << 2)) != 0; cState.PS = (data[7] & (1 << 0)) != 0; cState.TouchButton = (data[7] & (1 << 2 - 1)) != 0; // Note: The trackpad, for whatever reason, can send data in multiple "packets" - I assume this accounts for the case where // you miss a read request in between multiple trackpad polls. We DO NOT use this here. bool tp_active1 = (data[0 + TOUCHPAD_DATA_OFFSET] >> 7) == 0; // >= 1 touch detected bool tp_active2 = (data[4 + TOUCHPAD_DATA_OFFSET] >> 7) == 0; // > 1 touch detected int touch1_x = data[1 + TOUCHPAD_DATA_OFFSET] | ((data[2 + TOUCHPAD_DATA_OFFSET] & 0xF) << 8); int touch1_y = ((data[2 + TOUCHPAD_DATA_OFFSET] & 0xF0) >> 4) | ((data[3 + TOUCHPAD_DATA_OFFSET] << 4)); int touch2_x = data[5 + TOUCHPAD_DATA_OFFSET] | ((data[6 + TOUCHPAD_DATA_OFFSET] & 0xF) << 8); int touch2_y = ((data[6 + TOUCHPAD_DATA_OFFSET] & 0xF0) >> 4) | ((data[7 + TOUCHPAD_DATA_OFFSET] << 4)); if (tp_active1 && tp_active2) { cState.Touches = new int[, ] { { touch1_x, touch1_y }, { touch2_x, touch2_y } } } ; else if (tp_active1) { cState.Touches = new int[, ] { { touch1_x, touch1_y }, { -1, -1 } } } ; else { cState.Touches = new int[, ] { { -1, -1 }, { -1, -1 } } }; // End section from ds4tool source // cState.Timestamp = (ushort)((data[11] << 8) | data[10]); short[] Gyro = new short[3]; short[] Accel = new short[3]; Gyro[0] = (short)((data[14] << 8) | data[13]); Gyro[1] = (short)((data[16] << 8) | data[15]); Gyro[2] = (short)((data[18] << 8) | data[17]); Accel[0] = (short)((data[20] << 8) | data[19]); Accel[1] = (short)((data[22] << 8) | data[21]); Accel[2] = (short)((data[24] << 8) | data[23]); _Orientation.ApplyGyroAccel(Accel, Gyro, cState.Timestamp); cState.Orientation = _Orientation; return(cState); }