diff --git a/src/controller.rs b/src/controller.rs new file mode 100644 index 0000000..4586bff --- /dev/null +++ b/src/controller.rs @@ -0,0 +1,2 @@ +pub mod physical; +pub mod emulated; diff --git a/src/virtual_controller.rs b/src/controller/emulated.rs similarity index 61% rename from src/virtual_controller.rs rename to src/controller/emulated.rs index 5479e0b..7e65eff 100644 --- a/src/virtual_controller.rs +++ b/src/controller/emulated.rs @@ -1,4 +1,5 @@ use crate::state::ControllerState; +mod dgoc44u; #[derive(PartialEq)] pub enum ControllerModel { @@ -12,7 +13,7 @@ pub fn set_model(state: &ControllerState) -> ControllerModel { println!("Selected controller DGOC44-U."); return ControllerModel::DGOC44U; } - else if state.button_left { + else if state.button_up { println!("Selected controller TCPP-20009."); return ControllerModel::TYPE2; } @@ -20,4 +21,16 @@ pub fn set_model(state: &ControllerState) -> ControllerModel { println!("No controller selected."); return ControllerModel::NONE; } -} \ No newline at end of file +} + +pub fn set_state(state: &mut ControllerState, model: &ControllerModel) { + match model { + ControllerModel::DGOC44U => { + dgoc44u::update_gadget(state); + } + ControllerModel::TYPE2 => { + + } + ControllerModel::NONE => (), + } +} diff --git a/src/controller/emulated/dgoc44u.rs b/src/controller/emulated/dgoc44u.rs new file mode 100644 index 0000000..5845a30 --- /dev/null +++ b/src/controller/emulated/dgoc44u.rs @@ -0,0 +1,13 @@ +use crate::state::ControllerState; + +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]; + +pub fn update_gadget(state: &mut ControllerState) { + // Calculate data for handles + let power = POWER_NOTCHES[state.power as usize]; + let brake = BRAKE_NOTCHES[state.brake as usize]; + + // Assemble data and send it to gadget + let data = [brake, power, 0, 0, 0, 0]; +} \ No newline at end of file diff --git a/src/physical_controller.rs b/src/controller/physical.rs similarity index 84% rename from src/physical_controller.rs rename to src/controller/physical.rs index 735b9bb..94f3131 100644 --- a/src/physical_controller.rs +++ b/src/controller/physical.rs @@ -21,28 +21,14 @@ pub fn get_state(state: &mut ControllerState, dev: &[Device; 2]) { for d in dev { if let Ok(key_vals) = d.get_key_state() { for key in USED_KEYS { - read_input(state, key, key_vals.contains(key)); + if d.supported_keys().map_or(true, |k| k.contains(key)) { + read_input(state, key, key_vals.contains(key)); + } } } } } -/* pub fn fetch_input(state: &mut ControllerState, dev: &mut [Device; 2]) { - for device in dev { - let evs = device.fetch_events(); - match evs { - Ok(evs) => { - for event in evs { - if event.event_type() == EventType::KEY { - read_input(state, Key(event.code()), event.value() != 0); - } - } - }, - Err(_e) => (), - } - } -} */ - fn read_input(controller: &mut ControllerState, key: Key, value: bool) { // Save input status to object for processing match key{ @@ -80,16 +66,16 @@ pub fn set_lamp(status: bool) { if let Ok(mut out) = File::create("/sys/class/leds/led2/brightness") { out.write(if status {b"1"} else {b"0"}).ok(); } - else { + /*else { println!("WARNING: Could not set door lamp status!") - } + }*/ } pub fn set_rumble(status: bool) { if let Ok(mut out) = File::create("/sys/class/leds/led1/brightness") { out.write(if status {b"1"} else {b"0"}).ok(); } - else { + /*else { println!("WARNING: Could not set rumble motor status!") - } -} \ No newline at end of file + }*/ +} diff --git a/src/main.rs b/src/main.rs index 20ba255..186a49e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,4 @@ -mod physical_controller; -mod virtual_controller; +mod controller; mod state; use std::io::Result; @@ -7,17 +6,18 @@ use std::process::Command; use std::time::Duration; use std::thread::sleep; -use virtual_controller::ControllerModel; +use controller::emulated::ControllerModel; +use controller::physical::{set_lamp,set_rumble}; fn main() -> Result<()> { - match physical_controller::init() { + match controller::physical::init() { Ok(dev) => { // Wait 3 seconds and get current state of the controller println!("Press a button to select the controller model..."); sleep(Duration::from_secs(3)); let mut controller_state = Default::default(); - physical_controller::get_state(&mut controller_state, &dev); - let controller_model = virtual_controller::set_model(&controller_state); + controller::physical::get_state(&mut controller_state, &dev); + let controller_model = controller::emulated::set_model(&controller_state); // If no model selected, quit if controller_model == ControllerModel::NONE { @@ -28,14 +28,23 @@ fn main() -> Result<()> { stop_game(); // Vibrate to end selection mode - physical_controller::set_rumble(true); + set_rumble(true); sleep(Duration::from_millis(500)); - physical_controller::set_rumble(false); + set_rumble(false); loop { // Fetch events from input devices - physical_controller::get_state(&mut controller_state, &dev); - sleep(Duration::from_millis(100)); + controller::physical::get_state(&mut controller_state, &dev); + + // Send input to virtual controller + controller::emulated::set_state(&mut controller_state, &controller_model); + + // Update lamp and rumble + set_lamp(controller_state.lamp); + set_rumble(controller_state.rumble); + + // Wait between cycles + sleep(Duration::from_millis(20)); } }, Err(_e) => println!("ERROR: Could not read input devices! Exiting."), diff --git a/src/state.rs b/src/state.rs index e22d5a2..6960331 100644 --- a/src/state.rs +++ b/src/state.rs @@ -12,4 +12,6 @@ pub struct ControllerState { pub button_down: bool, pub button_left: bool, pub button_right: bool, + pub lamp: bool, + pub rumble: bool, } \ No newline at end of file