gamebridge: Twitch Control #2
|
@ -26,6 +26,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
|
@ -50,6 +56,7 @@ name = "gamebridge"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags",
|
||||
"log",
|
||||
"pretty_env_logger",
|
||||
]
|
||||
|
|
|
@ -8,5 +8,6 @@ edition = "2018"
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
bitflags = "1.2"
|
||||
log = "0.4"
|
||||
pretty_env_logger = "0.4"
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
bitflags! {
|
||||
// 0x0100 Digital Pad Right
|
||||
// 0x0200 Digital Pad Left
|
||||
// 0x0400 Digital Pad Down
|
||||
// 0x0800 Digital Pad Up
|
||||
// 0x1000 Start
|
||||
// 0x2000 Z
|
||||
// 0x4000 B
|
||||
// 0x8000 A
|
||||
pub(crate) struct HiButtons: u8 {
|
||||
const NONE = 0x00;
|
||||
const DPAD_RIGHT = 0x01;
|
||||
const DPAD_LEFT = 0x02;
|
||||
const DPAD_DOWN = 0x04;
|
||||
const DPAD_UP = 0x08;
|
||||
const START = 0x10;
|
||||
const Z_BUTTON = 0x20;
|
||||
const B_BUTTON = 0x40;
|
||||
const A_BUTTON = 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
impl HiButtons {
|
||||
pub fn clear(&mut self) {
|
||||
self.bits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
// 0x0001 C-Right
|
||||
// 0x0002 C-Left
|
||||
// 0x0004 C-Down
|
||||
// 0x0008 C-Up
|
||||
// 0x0010 R
|
||||
// 0x0020 L
|
||||
// 0x0040 (reserved)
|
||||
// 0x0080 (reserved)
|
||||
pub(crate) struct LoButtons: u8 {
|
||||
const NONE = 0x00;
|
||||
const C_RIGHT = 0x01;
|
||||
const C_LEFT = 0x02;
|
||||
const C_DOWN = 0x04;
|
||||
const C_UP = 0x08;
|
||||
const R_BUTTON = 0x10;
|
||||
const L_BUTTON = 0x20;
|
||||
}
|
||||
}
|
||||
|
||||
impl LoButtons {
|
||||
pub fn clear(&mut self) {
|
||||
self.bits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn test(st: crate::MTState) {
|
||||
let mut lo: LoButtons = LoButtons::NONE;
|
||||
let mut hi: HiButtons = HiButtons::NONE;
|
||||
|
||||
loop {
|
||||
use std::{thread::sleep, time::Duration};
|
||||
let one_second = Duration::new(1, 0);
|
||||
|
||||
hi = HiButtons::A_BUTTON | HiButtons::START;
|
||||
|
||||
{
|
||||
println!("pressing a + start");
|
||||
let mut data = st.write().unwrap();
|
||||
data.controller[0] = hi.bits as u8;
|
||||
data.controller[1] = lo.bits as u8;
|
||||
}
|
||||
|
||||
sleep(one_second);
|
||||
|
||||
hi.clear();
|
||||
lo.clear();
|
||||
|
||||
{
|
||||
println!("releasing a + start");
|
||||
let mut data = st.write().unwrap();
|
||||
data.controller[0] = hi.bits as u8;
|
||||
data.controller[1] = lo.bits as u8;
|
||||
}
|
||||
|
||||
sleep(one_second);
|
||||
}
|
||||
}
|
|
@ -1,20 +1,51 @@
|
|||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
|
||||
pub(crate) mod controller;
|
||||
|
||||
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()?;
|
||||
let mut controller_data = [0; 4];
|
||||
|
||||
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 || controller::test(st));
|
||||
}
|
||||
|
||||
loop {
|
||||
let mut data = [0; 3];
|
||||
debug!("waiting for vblank");
|
||||
|
@ -23,11 +54,14 @@ fn main() -> Result<()> {
|
|||
debug!("got data: {}", str);
|
||||
|
||||
match str {
|
||||
"OK\n" => input.write(&controller_data)?,
|
||||
"OK\n" => {
|
||||
let data = st.read().unwrap();
|
||||
input.write(&data.controller)?
|
||||
}
|
||||
"BYE" => {
|
||||
warn!("asked to exit by the game");
|
||||
return Ok(());
|
||||
},
|
||||
}
|
||||
_ => {
|
||||
error!("got unknown FIFO data {}", str);
|
||||
return Err(anyhow!("unknown FIFO data received"));
|
||||
|
|
Loading…
Reference in New Issue