mirror of
https://github.com/marcriera/ddgo-pnp-controller.git
synced 2025-04-11 06:29:29 +02:00
Add ZKNS-001 support, HID reliability fix
This commit is contained in:
parent
029f5c7af3
commit
97a561f644
10 changed files with 256 additions and 114 deletions
|
@ -1,4 +1,6 @@
|
|||
use std::thread;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
|
@ -6,6 +8,7 @@ use std::process::Command;
|
|||
use std::path::Path;
|
||||
|
||||
use crate::controller::physical::ControllerState;
|
||||
|
||||
mod dgoc44u;
|
||||
mod tcpp20009;
|
||||
mod tcpp20011;
|
||||
|
@ -14,6 +17,7 @@ mod sotp031201_p4b2b7;
|
|||
mod sotp031201_p5b5;
|
||||
mod sotp031201_p5b7;
|
||||
mod vok00106;
|
||||
mod zkns001;
|
||||
|
||||
const FFS_MOUNT: &str = "/tmp/ffs";
|
||||
const ENDPOINT0: &str = "/tmp/ffs/ep0";
|
||||
|
@ -30,6 +34,7 @@ pub enum ControllerModel {
|
|||
SOTP031201P5B5,
|
||||
SOTP031201P5B7,
|
||||
VOK00106,
|
||||
ZKNS001,
|
||||
}
|
||||
|
||||
pub struct DeviceDescriptor {
|
||||
|
@ -46,11 +51,16 @@ pub fn set_model(state: &ControllerState) -> Option<ControllerModel> {
|
|||
let model;
|
||||
let model_name;
|
||||
let descriptors: (&DeviceDescriptor, &[u8], &[u8]);
|
||||
if !state.button_right {
|
||||
if state.button_right {
|
||||
model_name = "DGOC44-U";
|
||||
model = ControllerModel::DGOC44U;
|
||||
descriptors = (&dgoc44u::DEVICE_DESCRIPTOR, &dgoc44u::DESCRIPTORS, &dgoc44u::STRINGS);
|
||||
}
|
||||
else if state.button_up {
|
||||
model_name = "ZKNS-001";
|
||||
model = ControllerModel::ZKNS001;
|
||||
descriptors = (&zkns001::DEVICE_DESCRIPTOR, &zkns001::DESCRIPTORS, &zkns001::STRINGS);
|
||||
}
|
||||
else if state.button_d {
|
||||
model_name = "TCPP-20009";
|
||||
model = ControllerModel::TCPP20009;
|
||||
|
@ -120,16 +130,24 @@ pub fn set_state(state: &mut ControllerState, model: &ControllerModel) {
|
|||
ControllerModel::VOK00106 => {
|
||||
vok00106::update_gadget(state);
|
||||
}
|
||||
ControllerModel::ZKNS001 => {
|
||||
zkns001::update_gadget(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_ctrl_transfer(model: ControllerModel, data: &[u8]) {
|
||||
if data[1] == 6 {
|
||||
let report;
|
||||
println!("CTRL TRANSFER: {:?}", data);
|
||||
if data[1] == 6 && data[3] == 34 {
|
||||
// Get HID report descriptor
|
||||
let report: Option<&[u8]>;
|
||||
match model {
|
||||
ControllerModel::DGOC44U => {
|
||||
report = Some(&dgoc44u::HID_REPORT_DESCRIPTOR);
|
||||
}
|
||||
ControllerModel::ZKNS001 => {
|
||||
report = Some(&zkns001::HID_REPORT_DESCRIPTOR);
|
||||
}
|
||||
_ => {
|
||||
report = None;
|
||||
}
|
||||
|
@ -143,8 +161,9 @@ pub fn handle_ctrl_transfer(model: ControllerModel, data: &[u8]) {
|
|||
None => (),
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if data[1] == 9 {
|
||||
// Other control transfer, pass it to emulated controller loop
|
||||
super::physical::set_lamp(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,8 +192,9 @@ fn init_gadget(model: &ControllerModel, (device, descriptors, strings): (&Device
|
|||
// Control transfer received
|
||||
handle_ctrl_transfer(controller_model, &buffer[0..8]);
|
||||
}
|
||||
|
||||
}
|
||||
// Wait between cycles
|
||||
sleep(Duration::from_millis(10));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -4,13 +4,13 @@ use bitflags::bitflags;
|
|||
use crate::controller::physical::ControllerState;
|
||||
use crate::controller::emulated::{DeviceDescriptor, ENDPOINT1};
|
||||
|
||||
pub const DESCRIPTORS: [u8; 66] = [0x01, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
pub const DESCRIPTORS: [u8; 66] = [0x01, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x09, 0x04, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,
|
||||
0x09, 0x21, 0x11, 0x01, 0x00, 0x01, 0x22, 0x3F, 0x00,
|
||||
0x07, 0x05, 0x81, 0x03, 0x08, 0x00, 0x14,
|
||||
0x07, 0x05, 0x81, 0x03, 0x08, 0x00, 0x28,
|
||||
0x09, 0x04, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,
|
||||
0x09, 0x21, 0x11, 0x01, 0x00, 0x01, 0x22, 0x3F, 0x00,
|
||||
0x07, 0x05, 0x81, 0x03, 0x08, 0x00, 0x14];
|
||||
0x07, 0x05, 0x81, 0x03, 0x08, 0x00, 0x28];
|
||||
pub const STRINGS: [u8; 16] = [0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
|
||||
|
||||
pub const DEVICE_DESCRIPTOR: DeviceDescriptor = DeviceDescriptor{b_device_class: 0x0, b_device_sub_class: 0x0, id_vendor: 0x0AE4, id_product: 0x0003, i_manufacturer: "TAITO", i_product: "Densha de Go! Plug & Play", i_serial_number: "DGOC-44U"};
|
||||
|
@ -54,21 +54,20 @@ const POWER_NOTCHES: [u8; 6] = [0x81, 0x6D, 0x54, 0x3F, 0x21, 0x00];
|
|||
const BRAKE_NOTCHES: [u8; 10] = [0x79, 0x8A, 0x94, 0x9A, 0xA2, 0xA8, 0xAF, 0xB2, 0xB5, 0xB9];
|
||||
|
||||
bitflags! {
|
||||
struct Buttons: u8 {
|
||||
const NONE = 0;
|
||||
const B = 1;
|
||||
const A = 2;
|
||||
const C = 4;
|
||||
const D = 8;
|
||||
const SELECT = 16;
|
||||
const START = 32;
|
||||
const UP = Self::SELECT.bits | Self::D.bits;
|
||||
const DOWN = Self::SELECT.bits | Self::B.bits;
|
||||
const LEFT = Self::SELECT.bits | Self::A.bits;
|
||||
const RIGHT = Self::SELECT.bits | Self::C.bits;
|
||||
}
|
||||
struct Buttons: u8 {
|
||||
const NONE = 0;
|
||||
const B = 1;
|
||||
const A = 2;
|
||||
const C = 4;
|
||||
const D = 8;
|
||||
const SELECT = 16;
|
||||
const START = 32;
|
||||
const UP = Self::SELECT.bits | Self::D.bits;
|
||||
const DOWN = Self::SELECT.bits | Self::B.bits;
|
||||
const LEFT = Self::SELECT.bits | Self::A.bits;
|
||||
const RIGHT = Self::SELECT.bits | Self::C.bits;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn update_gadget(state: &mut ControllerState) {
|
||||
// Calculate data for handles
|
||||
|
|
|
@ -18,25 +18,25 @@ const POWER_NOTCHES: [u8; 6] = [0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0C];
|
|||
const BRAKE_NOTCHES: [u8; 10] = [0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02, 0x02, 0x01];
|
||||
|
||||
bitflags! {
|
||||
struct Buttons1: u8 {
|
||||
const NONE = 0;
|
||||
const S = 1;
|
||||
const D = 2;
|
||||
const A = 4;
|
||||
const A2 = 8;
|
||||
const B = 16;
|
||||
const C = 32;
|
||||
}
|
||||
struct Buttons2: u8 {
|
||||
const NONE = 0;
|
||||
const START = 1;
|
||||
const SELECT = 2;
|
||||
const UP = 4;
|
||||
const DOWN = 8;
|
||||
const LEFT = 16;
|
||||
const RIGHT = 32;
|
||||
}
|
||||
struct Buttons1: u8 {
|
||||
const NONE = 0;
|
||||
const S = 1;
|
||||
const D = 2;
|
||||
const A = 4;
|
||||
const A2 = 8;
|
||||
const B = 16;
|
||||
const C = 32;
|
||||
}
|
||||
struct Buttons2: u8 {
|
||||
const NONE = 0;
|
||||
const START = 1;
|
||||
const SELECT = 2;
|
||||
const UP = 4;
|
||||
const DOWN = 8;
|
||||
const LEFT = 16;
|
||||
const RIGHT = 32;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_gadget(state: &mut ControllerState) {
|
||||
// Calculate data for handles
|
||||
|
|
|
@ -18,25 +18,25 @@ const POWER_NOTCHES: [u8; 6] = [0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0D];
|
|||
const BRAKE_NOTCHES: [u8; 10] = [0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02, 0x01];
|
||||
|
||||
bitflags! {
|
||||
struct Buttons1: u8 {
|
||||
const NONE = 0;
|
||||
const S = 1;
|
||||
const D = 2;
|
||||
const A = 4;
|
||||
const A2 = 8;
|
||||
const B = 16;
|
||||
const C = 32;
|
||||
}
|
||||
struct Buttons2: u8 {
|
||||
const NONE = 0;
|
||||
const START = 1;
|
||||
const SELECT = 2;
|
||||
const UP = 4;
|
||||
const DOWN = 8;
|
||||
const LEFT = 16;
|
||||
const RIGHT = 32;
|
||||
}
|
||||
struct Buttons1: u8 {
|
||||
const NONE = 0;
|
||||
const S = 1;
|
||||
const D = 2;
|
||||
const A = 4;
|
||||
const A2 = 8;
|
||||
const B = 16;
|
||||
const C = 32;
|
||||
}
|
||||
struct Buttons2: u8 {
|
||||
const NONE = 0;
|
||||
const START = 1;
|
||||
const SELECT = 2;
|
||||
const UP = 4;
|
||||
const DOWN = 8;
|
||||
const LEFT = 16;
|
||||
const RIGHT = 32;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_gadget(state: &mut ControllerState) {
|
||||
// Calculate data for handles
|
||||
|
|
|
@ -18,25 +18,25 @@ const POWER_NOTCHES: [u8; 6] = [0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C];
|
|||
const BRAKE_NOTCHES: [u8; 10] = [0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01];
|
||||
|
||||
bitflags! {
|
||||
struct Buttons1: u8 {
|
||||
const NONE = 0;
|
||||
const S = 1;
|
||||
const D = 2;
|
||||
const A = 4;
|
||||
const A2 = 8;
|
||||
const B = 16;
|
||||
const C = 32;
|
||||
}
|
||||
struct Buttons2: u8 {
|
||||
const NONE = 0;
|
||||
const START = 1;
|
||||
const SELECT = 2;
|
||||
const UP = 4;
|
||||
const DOWN = 8;
|
||||
const LEFT = 16;
|
||||
const RIGHT = 32;
|
||||
}
|
||||
struct Buttons1: u8 {
|
||||
const NONE = 0;
|
||||
const S = 1;
|
||||
const D = 2;
|
||||
const A = 4;
|
||||
const A2 = 8;
|
||||
const B = 16;
|
||||
const C = 32;
|
||||
}
|
||||
struct Buttons2: u8 {
|
||||
const NONE = 0;
|
||||
const START = 1;
|
||||
const SELECT = 2;
|
||||
const UP = 4;
|
||||
const DOWN = 8;
|
||||
const LEFT = 16;
|
||||
const RIGHT = 32;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_gadget(state: &mut ControllerState) {
|
||||
// Calculate data for handles
|
||||
|
|
|
@ -18,25 +18,25 @@ const POWER_NOTCHES: [u8; 6] = [0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E];
|
|||
const BRAKE_NOTCHES: [u8; 10] = [0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02, 0x01];
|
||||
|
||||
bitflags! {
|
||||
struct Buttons1: u8 {
|
||||
const NONE = 0;
|
||||
const S = 1;
|
||||
const D = 2;
|
||||
const A = 4;
|
||||
const A2 = 8;
|
||||
const B = 16;
|
||||
const C = 32;
|
||||
}
|
||||
struct Buttons2: u8 {
|
||||
const NONE = 0;
|
||||
const START = 1;
|
||||
const SELECT = 2;
|
||||
const UP = 4;
|
||||
const DOWN = 8;
|
||||
const LEFT = 16;
|
||||
const RIGHT = 32;
|
||||
}
|
||||
struct Buttons1: u8 {
|
||||
const NONE = 0;
|
||||
const S = 1;
|
||||
const D = 2;
|
||||
const A = 4;
|
||||
const A2 = 8;
|
||||
const B = 16;
|
||||
const C = 32;
|
||||
}
|
||||
struct Buttons2: u8 {
|
||||
const NONE = 0;
|
||||
const START = 1;
|
||||
const SELECT = 2;
|
||||
const UP = 4;
|
||||
const DOWN = 8;
|
||||
const LEFT = 16;
|
||||
const RIGHT = 32;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_gadget(state: &mut ControllerState) {
|
||||
// Calculate data for handles
|
||||
|
|
|
@ -18,16 +18,16 @@ const POWER_NOTCHES: [u8; 6] = [0x81, 0x6D, 0x54, 0x3F, 0x21, 0x00];
|
|||
const BRAKE_NOTCHES: [u8; 10] = [0x79, 0x8A, 0x94, 0x9A, 0xA2, 0xA8, 0xAF, 0xB2, 0xB5, 0xB9];
|
||||
|
||||
bitflags! {
|
||||
struct Buttons: u8 {
|
||||
const NONE = 0;
|
||||
const B = 1;
|
||||
const A = 2;
|
||||
const C = 4;
|
||||
const D = 8;
|
||||
const SELECT = 16;
|
||||
const START = 32;
|
||||
}
|
||||
struct Buttons: u8 {
|
||||
const NONE = 0;
|
||||
const B = 1;
|
||||
const A = 2;
|
||||
const C = 4;
|
||||
const D = 8;
|
||||
const SELECT = 16;
|
||||
const START = 32;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_gadget(state: &mut ControllerState) {
|
||||
// Calculate data for handles
|
||||
|
|
|
@ -12,22 +12,22 @@ pub const DESCRIPTORS: [u8; 48] = [0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0
|
|||
0x07, 0x05, 0x81, 0x03, 0x08, 0x00, 0x14];
|
||||
pub const STRINGS: [u8; 16] = [0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
|
||||
|
||||
pub const DEVICE_DESCRIPTOR: DeviceDescriptor = DeviceDescriptor{b_device_class: 0xFF, b_device_sub_class: 0x5, id_vendor: 0x0AE4, id_product: 0x0005, i_manufacturer: "TAITO", i_product: "Densha de Go! Plug & Play (Shinkansen)", i_serial_number: "TCPP20011"};
|
||||
pub const DEVICE_DESCRIPTOR: DeviceDescriptor = DeviceDescriptor{b_device_class: 0xFF, b_device_sub_class: 0x5, id_vendor: 0x0AE4, id_product: 0x0005, i_manufacturer: "TAITO", i_product: "Densha de Go! Plug & Play (Shinkansen mode)", i_serial_number: "TCPP20011"};
|
||||
|
||||
const POWER_NOTCHES: [u8; 6] = [0x12, 0x36, 0x5A, 0x90, 0xC6, 0xFB];
|
||||
const BRAKE_NOTCHES: [u8; 10] = [0x1C, 0x38, 0x54, 0x70, 0x8B, 0xA7, 0xC3, 0xDF, 0xDF, 0xFB];
|
||||
|
||||
bitflags! {
|
||||
struct Buttons: u8 {
|
||||
const NONE = 0;
|
||||
const D = 1;
|
||||
const C = 2;
|
||||
const B = 4;
|
||||
const A = 8;
|
||||
const SELECT = 16;
|
||||
const START = 32;
|
||||
}
|
||||
struct Buttons: u8 {
|
||||
const NONE = 0;
|
||||
const D = 1;
|
||||
const C = 2;
|
||||
const B = 4;
|
||||
const A = 8;
|
||||
const SELECT = 16;
|
||||
const START = 32;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_gadget(state: &mut ControllerState) {
|
||||
// Calculate data for handles
|
||||
|
|
123
src/controller/emulated/zkns001.rs
Normal file
123
src/controller/emulated/zkns001.rs
Normal file
|
@ -0,0 +1,123 @@
|
|||
use std::fs::File;
|
||||
use std::io::{Write};
|
||||
use bitflags::bitflags;
|
||||
use crate::controller::physical::ControllerState;
|
||||
use crate::controller::emulated::{DeviceDescriptor, ENDPOINT1};
|
||||
|
||||
pub const DESCRIPTORS: [u8; 80] = [0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x09, 0x04, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00,
|
||||
0x09, 0x21, 0x11, 0x01, 0x00, 0x01, 0x22, 0x5E, 0x00,
|
||||
0x07, 0x05, 0x02, 0x03, 0x40, 0x00, 0x05,
|
||||
0x07, 0x05, 0x81, 0x03, 0x40, 0x00, 0x05,
|
||||
0x09, 0x04, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00,
|
||||
0x09, 0x21, 0x11, 0x01, 0x00, 0x01, 0x22, 0x5E, 0x00,
|
||||
0x07, 0x05, 0x02, 0x03, 0x40, 0x00, 0x05,
|
||||
0x07, 0x05, 0x81, 0x03, 0x40, 0x00, 0x05];
|
||||
pub const STRINGS: [u8; 16] = [0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
|
||||
|
||||
pub const DEVICE_DESCRIPTOR: DeviceDescriptor = DeviceDescriptor{b_device_class: 0x0, b_device_sub_class: 0x0, id_vendor: 0x33DD, id_product: 0x0001, i_manufacturer: "TAITO", i_product: "Densha de Go! Plug & Play (NS One Handle mode)", i_serial_number: "ZKNS-001"};
|
||||
|
||||
pub const HID_REPORT_DESCRIPTOR: [u8; 94] = [
|
||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||
0x09, 0x05, // Usage (Game Pad)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x35, 0x00, // Physical Minimum (0)
|
||||
0x45, 0x01, // Physical Maximum (1)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x0E, // Report Count (14)
|
||||
0x05, 0x09, // Usage Page (Button)
|
||||
0x19, 0x01, // Usage Minimum (0x01)
|
||||
0x29, 0x0E, // Usage Maximum (0x0E)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||
0x25, 0x07, // Logical Maximum (7)
|
||||
0x46, 0x3B, 0x01, // Physical Maximum (315)
|
||||
0x75, 0x04, // Report Size (4)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x65, 0x14, // Unit (System: English Rotation, Length: Centimeter)
|
||||
0x09, 0x39, // Usage (Hat switch)
|
||||
0x81, 0x42, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
|
||||
0x65, 0x00, // Unit (None)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||
0x46, 0xFF, 0x00, // Physical Maximum (255)
|
||||
0x09, 0x30, // Usage (X)
|
||||
0x09, 0x31, // Usage (Y)
|
||||
0x09, 0x32, // Usage (Z)
|
||||
0x09, 0x35, // Usage (Rz)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x04, // Report Count (4)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x0A, 0x4F, 0x48, // Usage (0x484F)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x08, // Report Count (8)
|
||||
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x0A, 0x4F, 0x48, // Usage (0x484F)
|
||||
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0xC0, // End Collection
|
||||
];
|
||||
|
||||
const POWER_NOTCHES: [u8; 6] = [0x80, 0x9F, 0xB7, 0xCE, 0xE6, 0xFF];
|
||||
const BRAKE_NOTCHES: [u8; 10] = [0x80, 0x65, 0x57, 0x49, 0x3C, 0x2E, 0x20, 0x13, 0x05, 0x00];
|
||||
|
||||
bitflags! {
|
||||
struct Buttons1: u8 {
|
||||
const NONE = 0;
|
||||
const Y = 1;
|
||||
const B = 2;
|
||||
const A = 4;
|
||||
const X = 8;
|
||||
const ZL = 64;
|
||||
}
|
||||
struct Buttons2: u8 {
|
||||
const NONE = 0;
|
||||
const SELECT = 1;
|
||||
const START = 2;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_gadget(state: &mut ControllerState) {
|
||||
// Calculate data for handles
|
||||
let mut handle = POWER_NOTCHES[state.power as usize];
|
||||
if state.brake > 0 {
|
||||
handle = BRAKE_NOTCHES[state.brake as usize];
|
||||
}
|
||||
|
||||
// Calculate data for buttons 1
|
||||
let mut buttons1 = Buttons1::NONE;
|
||||
if state.button_a { buttons1.insert(Buttons1::Y) }
|
||||
if state.button_b { buttons1.insert(Buttons1::B) }
|
||||
if state.button_c { buttons1.insert(Buttons1::A) }
|
||||
if state.button_d { buttons1.insert(Buttons1::X) }
|
||||
if state.brake == 9 { buttons1.insert(Buttons1::ZL) }
|
||||
|
||||
// Calculate data for buttons 2
|
||||
let mut buttons2 = Buttons2::NONE;
|
||||
if state.button_start { buttons2.insert(Buttons2::START) }
|
||||
if state.button_select { buttons2.insert(Buttons2::SELECT) }
|
||||
|
||||
// Calculate data for D-pad
|
||||
let mut dpad: u8 = 0xF;
|
||||
if state.button_up { dpad = 0x0 }
|
||||
if state.button_down { dpad = 0x4 }
|
||||
if state.button_left { dpad = 0x6 }
|
||||
if state.button_right { dpad = 0x2 }
|
||||
if state.button_up & state.button_left { dpad = 0x7 }
|
||||
if state.button_up & state.button_right { dpad = 0x1 }
|
||||
if state.button_down & state.button_left { dpad = 0x5 }
|
||||
if state.button_down & state.button_right { dpad = 0x3 }
|
||||
|
||||
// Assemble data and send it to gadget
|
||||
let data = [buttons1.bits, buttons2.bits, dpad, 0x80, handle, 0x80, 0x80, 0x00];
|
||||
if let Ok(mut file) = File::create(ENDPOINT1) {
|
||||
file.write(&data).ok();
|
||||
}
|
||||
}
|
|
@ -39,7 +39,7 @@ fn main() -> Result<()> {
|
|||
set_rumble(controller_state.rumble);
|
||||
|
||||
// Wait between cycles
|
||||
sleep(Duration::from_millis(20));
|
||||
sleep(Duration::from_millis(5));
|
||||
}
|
||||
}
|
||||
return Result::Ok(());
|
||||
|
|
Loading…
Add table
Reference in a new issue