mirror of
https://github.com/4yn/slidershim.git
synced 2025-02-17 10:58:35 +01:00
deprecate
This commit is contained in:
parent
e64e68e9d9
commit
e097eacdd0
@ -1,89 +1,169 @@
|
||||
use std::{
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
},
|
||||
thread::{self, JoinHandle},
|
||||
use std::{error, ops::DerefMut, time::Duration};
|
||||
|
||||
use rusb::{self, DeviceHandle, GlobalContext};
|
||||
|
||||
use crate::slider_io::{
|
||||
config::DeviceMode,
|
||||
controller_state::{ControllerState, FullState, LedState},
|
||||
worker::Job,
|
||||
};
|
||||
|
||||
use crate::slider_io::{config::DeviceMode, controller_state::FullState, hid};
|
||||
|
||||
pub struct DeviceThread {
|
||||
thread: Option<JoinHandle<()>>,
|
||||
stop_signal: Arc<AtomicBool>,
|
||||
pub struct Buffer {
|
||||
pub data: [u8; 128],
|
||||
pub len: usize,
|
||||
}
|
||||
|
||||
impl DeviceThread {
|
||||
pub fn new(state: &FullState, mode: DeviceMode) -> Self {
|
||||
let controller_state = state.clone_controller();
|
||||
let led_state = state.clone_led();
|
||||
let stop_signal = Arc::new(AtomicBool::new(false));
|
||||
impl Buffer {
|
||||
pub fn new() -> Self {
|
||||
Buffer {
|
||||
data: [0; 128],
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
|
||||
let stop_signal_clone = Arc::clone(&stop_signal);
|
||||
fn slice(&self) -> &[u8] {
|
||||
&self.data[0..self.len]
|
||||
}
|
||||
}
|
||||
|
||||
type HidReadCallback = fn(&Buffer, &mut ControllerState) -> ();
|
||||
type HidLedCallback = fn(&mut Buffer, &mut LedState) -> ();
|
||||
|
||||
pub struct HidDeviceJob {
|
||||
state: FullState,
|
||||
vid: u16,
|
||||
pid: u16,
|
||||
read_endpoint: u8,
|
||||
led_endpoint: u8,
|
||||
|
||||
read_callback: HidReadCallback,
|
||||
read_buf: Buffer,
|
||||
|
||||
led_callback: HidLedCallback,
|
||||
led_buf: Buffer,
|
||||
|
||||
handle: Option<DeviceHandle<GlobalContext>>,
|
||||
}
|
||||
|
||||
impl HidDeviceJob {
|
||||
fn new(
|
||||
state: FullState,
|
||||
vid: u16,
|
||||
pid: u16,
|
||||
read_endpoint: u8,
|
||||
led_endpoint: u8,
|
||||
read_callback: HidReadCallback,
|
||||
led_callback: HidLedCallback,
|
||||
) -> Self {
|
||||
Self {
|
||||
thread: Some(match mode {
|
||||
DeviceMode::None => thread::spawn(|| {}),
|
||||
DeviceMode::TasollerOne => thread::spawn(|| {}),
|
||||
DeviceMode::TasollerTwo => thread::spawn(|| {}),
|
||||
DeviceMode::Yuancon => thread::spawn(move || {
|
||||
hid::poll_controller(
|
||||
0x1973,
|
||||
0x2001,
|
||||
move |buf| {
|
||||
if (buf.len != 34) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut controller_state_handle = controller_state.lock().unwrap();
|
||||
controller_state_handle
|
||||
.ground_state
|
||||
.clone_from_slice(&buf.data[2..34]);
|
||||
for i in 0..6 {
|
||||
controller_state_handle.air_state[i ^ 1] =
|
||||
if buf.data[0] & (1 << i) == 0 { 1 } else { 0 };
|
||||
}
|
||||
for i in 0..3 {
|
||||
controller_state_handle.extra_state[i] =
|
||||
if buf.data[1] & (1 << i) == 0 { 1 } else { 0 };
|
||||
}
|
||||
|
||||
// println!("{:?}", controller_state_handle.ground_state);
|
||||
},
|
||||
move |buf| {
|
||||
let mut led_state_handle = led_state.lock().unwrap();
|
||||
if led_state_handle.dirty {
|
||||
buf.len = 31 * 2;
|
||||
buf
|
||||
.data
|
||||
.chunks_mut(2)
|
||||
.take(31)
|
||||
.zip(led_state_handle.led_state.chunks(3).rev())
|
||||
.for_each(|(buf_chunk, state_chunk)| {
|
||||
buf_chunk[0] = (state_chunk[0] << 3 & 0xe0) | (state_chunk[2] >> 3);
|
||||
buf_chunk[1] = (state_chunk[1] & 0xf8) | (state_chunk[0] >> 5);
|
||||
});
|
||||
led_state_handle.dirty = false;
|
||||
}
|
||||
},
|
||||
&stop_signal_clone,
|
||||
)
|
||||
// .unwrap_or_else(|err| {
|
||||
// println!("Device thread: {:?}", err);
|
||||
// });
|
||||
.unwrap();
|
||||
}),
|
||||
DeviceMode::Brokenithm { .. } => thread::spawn(|| {}),
|
||||
}),
|
||||
stop_signal: stop_signal,
|
||||
state,
|
||||
vid,
|
||||
pid,
|
||||
read_endpoint,
|
||||
led_endpoint,
|
||||
read_callback,
|
||||
read_buf: Buffer::new(),
|
||||
led_callback,
|
||||
led_buf: Buffer::new(),
|
||||
handle: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_config(mode: &DeviceMode, state: &FullState) -> Self {
|
||||
match mode {
|
||||
DeviceMode::Yuancon => Self::new(
|
||||
state.clone(),
|
||||
0x1973,
|
||||
0x2001,
|
||||
0x81,
|
||||
0x02,
|
||||
|buf, controller_state| {
|
||||
if buf.len != 34 {
|
||||
return;
|
||||
}
|
||||
|
||||
controller_state
|
||||
.ground_state
|
||||
.clone_from_slice(&buf.data[2..34]);
|
||||
for i in 0..6 {
|
||||
controller_state.air_state[i ^ 1] = if buf.data[0] & (1 << i) == 0 { 1 } else { 0 };
|
||||
}
|
||||
for i in 0..3 {
|
||||
controller_state.extra_state[i] = if buf.data[1] & (1 << i) == 0 { 1 } else { 0 };
|
||||
}
|
||||
},
|
||||
|buf, led_state| {
|
||||
if !led_state.dirty {
|
||||
return;
|
||||
}
|
||||
buf.len = 31 * 2;
|
||||
buf
|
||||
.data
|
||||
.chunks_mut(2)
|
||||
.take(31)
|
||||
.zip(led_state.led_state.chunks(3).rev())
|
||||
.for_each(|(buf_chunk, state_chunk)| {
|
||||
buf_chunk[0] = (state_chunk[0] << 3 & 0xe0) | (state_chunk[2] >> 3);
|
||||
buf_chunk[1] = (state_chunk[1] & 0xf8) | (state_chunk[0] >> 5);
|
||||
});
|
||||
led_state.dirty = false;
|
||||
},
|
||||
),
|
||||
_ => panic!("Not implemented"),
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_impl(&mut self) -> Result<(), Box<dyn error::Error>> {
|
||||
let mut handle = rusb::open_device_with_vid_pid(self.vid, self.pid).unwrap();
|
||||
if handle.kernel_driver_active(0).unwrap_or(false) {
|
||||
handle.detach_kernel_driver(0)?;
|
||||
}
|
||||
handle.set_active_configuration(1)?;
|
||||
handle.claim_interface(0)?;
|
||||
self.handle = Some(handle);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DeviceThread {
|
||||
fn drop(&mut self) {
|
||||
self.stop_signal.swap(true, Ordering::SeqCst);
|
||||
if self.thread.is_some() {
|
||||
self.thread.take().unwrap().join().ok();
|
||||
const timeout: Duration = Duration::from_millis(20);
|
||||
|
||||
impl Job for HidDeviceJob {
|
||||
fn setup(&mut self) {
|
||||
self.setup_impl().unwrap();
|
||||
}
|
||||
|
||||
fn tick(&mut self) {
|
||||
// Input loop
|
||||
let handle = self.handle.as_mut().unwrap();
|
||||
|
||||
{
|
||||
let res = handle
|
||||
.read_interrupt(self.read_endpoint, &mut self.read_buf.data, timeout)
|
||||
.unwrap_or(0);
|
||||
self.read_buf.len = res;
|
||||
if self.read_buf.len != 0 {
|
||||
let mut controller_state_handle = self.state.controller_state.lock().unwrap();
|
||||
(self.read_callback)(&self.read_buf, controller_state_handle.deref_mut());
|
||||
}
|
||||
}
|
||||
|
||||
// Led loop
|
||||
{
|
||||
let mut led_state_handle = self.state.led_state.lock().unwrap();
|
||||
(self.led_callback)(&mut self.led_buf, led_state_handle.deref_mut());
|
||||
if self.led_buf.len != 0 {
|
||||
let res = handle
|
||||
.write_interrupt(self.led_endpoint, &self.led_buf.data, timeout)
|
||||
.unwrap_or(0);
|
||||
if res == self.led_buf.len + 1 {
|
||||
self.led_buf.len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn teardown(&mut self) {
|
||||
let handle = self.handle.as_mut().unwrap();
|
||||
handle.release_interface(0).ok();
|
||||
}
|
||||
}
|
||||
|
@ -1,170 +0,0 @@
|
||||
use std::{error, ops::DerefMut, time::Duration};
|
||||
|
||||
use rusb::{self, DeviceHandle, GlobalContext};
|
||||
|
||||
use crate::slider_io::{
|
||||
config::DeviceMode,
|
||||
controller_state::{ControllerState, FullState, LedState},
|
||||
hid,
|
||||
worker::{Job, Worker},
|
||||
};
|
||||
|
||||
pub struct Buffer {
|
||||
pub data: [u8; 128],
|
||||
pub len: usize,
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
pub fn new() -> Self {
|
||||
Buffer {
|
||||
data: [0; 128],
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn slice(&self) -> &[u8] {
|
||||
&self.data[0..self.len]
|
||||
}
|
||||
}
|
||||
|
||||
type HidReadCallback = fn(&Buffer, &mut ControllerState) -> ();
|
||||
type HidLedCallback = fn(&mut Buffer, &mut LedState) -> ();
|
||||
|
||||
pub struct HidDeviceJob {
|
||||
state: FullState,
|
||||
vid: u16,
|
||||
pid: u16,
|
||||
read_endpoint: u8,
|
||||
led_endpoint: u8,
|
||||
|
||||
read_callback: HidReadCallback,
|
||||
read_buf: Buffer,
|
||||
|
||||
led_callback: HidLedCallback,
|
||||
led_buf: Buffer,
|
||||
|
||||
handle: Option<DeviceHandle<GlobalContext>>,
|
||||
}
|
||||
|
||||
impl HidDeviceJob {
|
||||
fn new(
|
||||
state: FullState,
|
||||
vid: u16,
|
||||
pid: u16,
|
||||
read_endpoint: u8,
|
||||
led_endpoint: u8,
|
||||
read_callback: HidReadCallback,
|
||||
led_callback: HidLedCallback,
|
||||
) -> Self {
|
||||
Self {
|
||||
state,
|
||||
vid,
|
||||
pid,
|
||||
read_endpoint,
|
||||
led_endpoint,
|
||||
read_callback,
|
||||
read_buf: Buffer::new(),
|
||||
led_callback,
|
||||
led_buf: Buffer::new(),
|
||||
handle: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_config(mode: &DeviceMode, state: &FullState) -> Self {
|
||||
match mode {
|
||||
DeviceMode::Yuancon => Self::new(
|
||||
state.clone(),
|
||||
0x1973,
|
||||
0x2001,
|
||||
0x81,
|
||||
0x02,
|
||||
|buf, controller_state| {
|
||||
if buf.len != 34 {
|
||||
return;
|
||||
}
|
||||
|
||||
controller_state
|
||||
.ground_state
|
||||
.clone_from_slice(&buf.data[2..34]);
|
||||
for i in 0..6 {
|
||||
controller_state.air_state[i ^ 1] = if buf.data[0] & (1 << i) == 0 { 1 } else { 0 };
|
||||
}
|
||||
for i in 0..3 {
|
||||
controller_state.extra_state[i] = if buf.data[1] & (1 << i) == 0 { 1 } else { 0 };
|
||||
}
|
||||
},
|
||||
|buf, led_state| {
|
||||
if !led_state.dirty {
|
||||
return;
|
||||
}
|
||||
buf.len = 31 * 2;
|
||||
buf
|
||||
.data
|
||||
.chunks_mut(2)
|
||||
.take(31)
|
||||
.zip(led_state.led_state.chunks(3).rev())
|
||||
.for_each(|(buf_chunk, state_chunk)| {
|
||||
buf_chunk[0] = (state_chunk[0] << 3 & 0xe0) | (state_chunk[2] >> 3);
|
||||
buf_chunk[1] = (state_chunk[1] & 0xf8) | (state_chunk[0] >> 5);
|
||||
});
|
||||
led_state.dirty = false;
|
||||
},
|
||||
),
|
||||
_ => panic!("Not implemented"),
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_impl(&mut self) -> Result<(), Box<dyn error::Error>> {
|
||||
let mut handle = rusb::open_device_with_vid_pid(self.vid, self.pid).unwrap();
|
||||
if handle.kernel_driver_active(0).unwrap_or(false) {
|
||||
handle.detach_kernel_driver(0)?;
|
||||
}
|
||||
handle.set_active_configuration(1)?;
|
||||
handle.claim_interface(0)?;
|
||||
self.handle = Some(handle);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
const timeout: Duration = Duration::from_millis(20);
|
||||
|
||||
impl Job for HidDeviceJob {
|
||||
fn setup(&mut self) {
|
||||
self.setup_impl().unwrap();
|
||||
}
|
||||
|
||||
fn tick(&mut self) {
|
||||
// Input loop
|
||||
let handle = self.handle.as_mut().unwrap();
|
||||
|
||||
{
|
||||
let res = handle
|
||||
.read_interrupt(self.read_endpoint, &mut self.read_buf.data, timeout)
|
||||
.unwrap_or(0);
|
||||
self.read_buf.len = res;
|
||||
if self.read_buf.len != 0 {
|
||||
let mut controller_state_handle = self.state.controller_state.lock().unwrap();
|
||||
(self.read_callback)(&self.read_buf, controller_state_handle.deref_mut());
|
||||
}
|
||||
}
|
||||
|
||||
// Led loop
|
||||
{
|
||||
let mut led_state_handle = self.state.led_state.lock().unwrap();
|
||||
(self.led_callback)(&mut self.led_buf, led_state_handle.deref_mut());
|
||||
if self.led_buf.len != 0 {
|
||||
let res = handle
|
||||
.write_interrupt(self.led_endpoint, &self.led_buf.data, timeout)
|
||||
.unwrap_or(0);
|
||||
if res == self.led_buf.len + 1 {
|
||||
self.led_buf.len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn teardown(&mut self) {
|
||||
let handle = self.handle.as_mut().unwrap();
|
||||
handle.release_interface(0).ok();
|
||||
}
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
use std::{
|
||||
error,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc, Mutex,
|
||||
},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use rusb::{self, UsbContext};
|
||||
|
||||
const timeout: Duration = Duration::from_millis(20);
|
||||
|
||||
pub struct Buffer {
|
||||
pub data: [u8; 128],
|
||||
pub len: usize,
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
pub fn new() -> Self {
|
||||
Buffer {
|
||||
data: [0; 128],
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn slice(&self) -> &[u8] {
|
||||
&self.data[0..self.len]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn poll_controller(
|
||||
vid: u16,
|
||||
pid: u16,
|
||||
read_callback: impl Fn(&Buffer) -> (),
|
||||
write_callback: impl Fn(&mut Buffer) -> (),
|
||||
// write_buf: Arc<Mutex<Buffer>>,
|
||||
stop: &AtomicBool,
|
||||
) -> Result<(), Box<dyn error::Error>> {
|
||||
// println!("Getting context");
|
||||
// let mut context = rusb::Context::new().unwrap();
|
||||
// println!("Getting devices");
|
||||
// let devices: Vec<rusb::Device<rusb::Context>> = context
|
||||
// .devices()
|
||||
// .unwrap()
|
||||
// .iter()
|
||||
// .filter(|d| {
|
||||
// d.device_descriptor()
|
||||
// .map(|d| d.vendor_id() == vid && d.product_id() == pid)
|
||||
// .unwrap_or(false)
|
||||
// })
|
||||
// .collect();
|
||||
// println!("Found {:?}", devices);
|
||||
// let mut handle = devices[0].open().unwrap();
|
||||
|
||||
let mut handle = rusb::open_device_with_vid_pid(vid, pid).unwrap();
|
||||
println!("Found device {:?}", handle);
|
||||
// .ok_or("Cannot find usb device".to_string())?;
|
||||
|
||||
// let device = handle.device();
|
||||
if handle.kernel_driver_active(0).unwrap_or(false) {
|
||||
println!("Disabling kernel driver");
|
||||
handle.detach_kernel_driver(0)?;
|
||||
}
|
||||
|
||||
println!("Kernel driver OK");
|
||||
handle.set_active_configuration(1)?;
|
||||
println!("Configuration OK");
|
||||
handle.claim_interface(0)?;
|
||||
println!("Interface OK");
|
||||
|
||||
let mut in_buf = Buffer::new();
|
||||
let mut led_buf = Buffer::new();
|
||||
loop {
|
||||
{
|
||||
// Read loop
|
||||
|
||||
let res = handle
|
||||
.read_interrupt(0x81, &mut in_buf.data, timeout)
|
||||
.unwrap_or(0);
|
||||
|
||||
in_buf.len = res;
|
||||
|
||||
// println!("Read {:?}", res);
|
||||
// println!("Data {:?}", in_buf.data);
|
||||
|
||||
if in_buf.len != 0 {
|
||||
read_callback(&in_buf);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Write loop
|
||||
write_callback(&mut led_buf);
|
||||
if led_buf.len != 0 {
|
||||
let res = handle
|
||||
.write_interrupt(0x02, led_buf.slice(), timeout)
|
||||
.unwrap_or(0);
|
||||
|
||||
// println!(
|
||||
// "Sent {:?} {:?} {:?}",
|
||||
// led_buf.len,
|
||||
// res,
|
||||
// led_buf.slice().len()
|
||||
// );
|
||||
if res == led_buf.len + 1 {
|
||||
led_buf.len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if stop.load(Ordering::SeqCst) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("HID thread stopped");
|
||||
|
||||
handle.release_interface(0)?;
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
use crate::slider_io::{
|
||||
config::Config, controller_state::FullState, device::DeviceThread, device_job::HidDeviceJob,
|
||||
led::LedThread, worker::Worker,
|
||||
config::Config, controller_state::FullState, device::HidDeviceJob, led::LedThread, worker::Worker,
|
||||
};
|
||||
|
||||
pub struct Manager {
|
||||
|
@ -1,8 +1,6 @@
|
||||
pub mod config;
|
||||
pub mod controller_state;
|
||||
pub mod device;
|
||||
pub mod device_job;
|
||||
pub mod hid;
|
||||
pub mod keyboard;
|
||||
pub mod led;
|
||||
pub mod manager;
|
||||
|
Loading…
x
Reference in New Issue
Block a user