mirror of
https://github.com/marcriera/ddgo-pnp-controller.git
synced 2025-04-18 09:39:28 +02:00
Better error handling
This commit is contained in:
parent
e282ef4ccd
commit
d1df749e38
1 changed files with 76 additions and 54 deletions
130
src/main.rs
130
src/main.rs
|
@ -1,7 +1,10 @@
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::io::Result;
|
||||||
|
use std::process::Command;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
|
|
||||||
use evdev_rs::Device;
|
use evdev_rs::Device;
|
||||||
use evdev_rs::InputEvent;
|
use evdev_rs::InputEvent;
|
||||||
use evdev_rs::ReadFlag;
|
use evdev_rs::ReadFlag;
|
||||||
|
@ -9,7 +12,7 @@ use evdev_rs::enums::EventCode;
|
||||||
use evdev_rs::enums::EV_KEY;
|
use evdev_rs::enums::EV_KEY;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Controller {
|
struct ControllerState {
|
||||||
power: u8,
|
power: u8,
|
||||||
brake: u8,
|
brake: u8,
|
||||||
button_sl: bool,
|
button_sl: bool,
|
||||||
|
@ -31,58 +34,67 @@ enum ControllerModel {
|
||||||
TYPE2,
|
TYPE2,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() -> Result<()> {
|
||||||
let d1 = Device::new_from_path("/dev/input/event1").unwrap();
|
let d1 = Device::new_from_path("/dev/input/event1");
|
||||||
let d2 = Device::new_from_path("/dev/input/event2").unwrap();
|
let d2 = Device::new_from_path("/dev/input/event2");
|
||||||
|
|
||||||
let mut controller: Controller = Default::default();
|
match (d1, d2) {
|
||||||
let mut controller_model: ControllerModel = ControllerModel::NONE;
|
(Ok(d1), Ok(d2)) => {
|
||||||
|
let mut controller_state: ControllerState = Default::default();
|
||||||
|
let mut controller_model: ControllerModel = ControllerModel::NONE;
|
||||||
|
|
||||||
|
// Save current time and 5 seconds in the future to check for pressed buttons later
|
||||||
|
let start_time = Instant::now();
|
||||||
|
let init_time = start_time + Duration::from_secs(5);
|
||||||
|
|
||||||
|
// Turn on door light to indicate selection mode
|
||||||
|
set_lamp(true);
|
||||||
|
println!("Hold a button to select the controller model...");
|
||||||
|
|
||||||
// Save current time and 5 seconds in the future to check for pressed buttons later
|
loop {
|
||||||
let start_time = Instant::now();
|
// Process events from both input devices
|
||||||
let init_time = start_time + Duration::from_secs(5);
|
for device in [&d1, &d2] {
|
||||||
|
let ev = device.next_event(ReadFlag::NORMAL);
|
||||||
|
match ev {
|
||||||
|
Ok(ev) => read_input(ev.1, &mut controller_state),
|
||||||
|
Err(_e) => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If init time has passed, try to select model or quit
|
||||||
|
if controller_model == ControllerModel::NONE && Instant::now() >= init_time {
|
||||||
|
if controller_state.button_right {
|
||||||
|
controller_model = ControllerModel::DGOC44U;
|
||||||
|
println!("Selected controller DGOC44-U, starting gadget...");
|
||||||
|
}
|
||||||
|
else if controller_state.button_left {
|
||||||
|
controller_model = ControllerModel::TYPE2;
|
||||||
|
println!("Selected controller TCPP-20009, starting gadget...");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Turn off door light and quit
|
||||||
|
set_lamp(false);
|
||||||
|
println!("No controller selected, exiting...");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Turn off door light and vibrate to end selection mode
|
||||||
|
set_lamp(false);
|
||||||
|
set_rumble(true);
|
||||||
|
sleep(Duration::from_millis(500));
|
||||||
|
set_rumble(false);
|
||||||
|
|
||||||
// Turn on door light to indicate selection mode
|
// Stop main game
|
||||||
set_door(true);
|
stop_game();
|
||||||
println!("Hold a button to select the controller model...");
|
}
|
||||||
|
|
||||||
loop {
|
|
||||||
// Process events from both input devices
|
|
||||||
for device in [&d1, &d2] {
|
|
||||||
let ev = device.next_event(ReadFlag::NORMAL).map(|val| val.1);
|
|
||||||
match ev {
|
|
||||||
Ok(ev) => read_input(ev, &mut controller),
|
|
||||||
Err(_e) => (),
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
_ => println!("ERROR: Could not read input devices! Stopping..."),
|
||||||
// If init time has passed, try to select model or quit
|
|
||||||
if controller_model == ControllerModel::NONE && Instant::now() >= init_time {
|
|
||||||
if controller.button_right {
|
|
||||||
controller_model = ControllerModel::DGOC44U;
|
|
||||||
println!("Selected controller DGOC44-U, starting gadget...");
|
|
||||||
}
|
|
||||||
else if controller.button_left {
|
|
||||||
controller_model = ControllerModel::TYPE2;
|
|
||||||
println!("Selected controller TCPP-20009, starting gadget...");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Turn off door light and quit
|
|
||||||
set_door(false);
|
|
||||||
println!("No controller selected, exiting...");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// Turn off door light and vibrate to end selection mode
|
|
||||||
set_door(false);
|
|
||||||
set_rumble(true);
|
|
||||||
sleep(Duration::from_millis(500));
|
|
||||||
set_rumble(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_input(event: InputEvent, controller: &mut Controller) {
|
fn read_input(event: InputEvent, controller: &mut ControllerState) {
|
||||||
// Save input status to object for easier processing
|
// Save input status to object for easier processing
|
||||||
match event.event_code{
|
match event.event_code{
|
||||||
EventCode::EV_KEY(EV_KEY::KEY_0)=>if event.value == 1 {controller.power = 0},
|
EventCode::EV_KEY(EV_KEY::KEY_0)=>if event.value == 1 {controller.power = 0},
|
||||||
|
@ -115,14 +127,24 @@ fn read_input(event: InputEvent, controller: &mut Controller) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_door(status: bool) -> std::io::Result<()> {
|
fn set_lamp(status: bool) {
|
||||||
let mut out = File::create("/sys/class/leds/led2/brightness")?;
|
if let Ok(mut out) = File::create("/sys/class/leds/led2/brightness") {
|
||||||
out.write(if status {b"1"} else {b"0"})?;
|
out.write(if status {b"1"} else {b"0"}).ok();
|
||||||
Ok(())
|
}
|
||||||
|
else {
|
||||||
|
println!("WARNING: Could not set door lamp status!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_rumble(status: bool) -> std::io::Result<()> {
|
fn set_rumble(status: bool) {
|
||||||
let mut out = File::create("/sys/class/leds/led1/brightness")?;
|
if let Ok(mut out) = File::create("/sys/class/leds/led1/brightness") {
|
||||||
out.write(if status {b"1"} else {b"0"})?;
|
out.write(if status {b"1"} else {b"0"}).ok();
|
||||||
Ok(())
|
}
|
||||||
|
else {
|
||||||
|
println!("WARNING: Could not set rumble motor status!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stop_game() {
|
||||||
|
Command::new("/etc/init.d/S99dgtype3").arg("stop").output().ok();
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue