#[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, ok: bool, } pub(crate) type MTState = Arc>; 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")); } }; } }