76 lines
1.6 KiB
Rust
76 lines
1.6 KiB
Rust
#[macro_use]
|
|
extern crate bitflags;
|
|
|
|
pub(crate) mod controller;
|
|
pub(crate) mod twitch;
|
|
|
|
use anyhow::{anyhow, Result};
|
|
use log::{debug, error, info, warn};
|
|
use std::{
|
|
fs::{File, OpenOptions},
|
|
io::{Read, Write},
|
|
str::from_utf8,
|
|
sync::{Arc, RwLock},
|
|
thread::spawn,
|
|
time::Instant,
|
|
};
|
|
|
|
#[derive(Debug)]
|
|
pub(crate) struct State {
|
|
controller: [u8; 4],
|
|
last_got: Box<Instant>,
|
|
ok: bool,
|
|
}
|
|
|
|
pub(crate) type MTState = Arc<RwLock<State>>;
|
|
|
|
fn main() -> Result<()> {
|
|
pretty_env_logger::try_init()?;
|
|
kankyo::init()?;
|
|
|
|
let mut vblank = File::open("vblank")?;
|
|
let mut input = OpenOptions::new().write(true).open("input")?;
|
|
|
|
let st = {
|
|
let st = State {
|
|
controller: [0; 4],
|
|
last_got: Box::new(Instant::now()),
|
|
ok: true,
|
|
};
|
|
|
|
Arc::new(RwLock::new(st))
|
|
};
|
|
|
|
info!("ready");
|
|
|
|
{
|
|
let st = st.clone();
|
|
spawn(move || twitch::run(st));
|
|
}
|
|
|
|
loop {
|
|
let mut data = [0; 3];
|
|
debug!("waiting for vblank");
|
|
vblank.read(&mut data)?;
|
|
let str = from_utf8(&data)?;
|
|
debug!("got data: {}", str);
|
|
|
|
match str {
|
|
"OK\n" => {
|
|
let mut data = st.write().unwrap();
|
|
input.write(&data.controller)?;
|
|
data.controller[0] = 0;
|
|
data.controller[1] = 0;
|
|
}
|
|
"BYE" => {
|
|
warn!("asked to exit by the game");
|
|
return Ok(());
|
|
}
|
|
_ => {
|
|
error!("got unknown FIFO data {}", str);
|
|
return Err(anyhow!("unknown FIFO data received"));
|
|
}
|
|
};
|
|
}
|
|
}
|