1
0
mirror of https://github.com/4yn/slidershim.git synced 2025-02-17 10:58:35 +01:00

deprecate

This commit is contained in:
4yn 2022-01-29 01:11:30 +08:00
parent e64e68e9d9
commit e097eacdd0
5 changed files with 157 additions and 374 deletions

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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(())
}

View File

@ -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 {

View File

@ -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;