Created
March 22, 2016 16:02
-
-
Save niconii/b464a290976dd3eaa2e7 to your computer and use it in GitHub Desktop.
A little SNES controller simulator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait ControllerPins { | |
// inputs: | |
// latch pin (normally low) | |
fn latch_rising(&mut self); | |
fn latch_falling(&mut self); | |
// clock pin (normally high) | |
fn clock_rising(&mut self); | |
fn clock_falling(&mut self); | |
// output: | |
// data pin (high = 0, low = 1) | |
fn data(&self) -> bool; | |
} | |
struct SnesController { | |
buttons: u16, | |
shift_reg: u16, | |
data: bool | |
} | |
impl SnesController { | |
fn new() -> Self { | |
SnesController { | |
buttons: 0, | |
shift_reg: 0, | |
data: false | |
} | |
} | |
/// This only represents the state of the actual buttons, not | |
/// any sort of latches in the controller. | |
fn set_buttons(&mut self, buttons: u16) { | |
self.buttons = buttons; | |
} | |
/// Shifts 1 into right end, putting leftmost bit in self.data. | |
fn shift(&mut self) { | |
self.data = (self.shift_reg & 0x8000) != 0; | |
self.shift_reg <<= 1; | |
self.shift_reg |= 0x0001; | |
} | |
} | |
impl ControllerPins for SnesController { | |
fn latch_rising(&mut self) { | |
self.shift_reg = self.buttons & 0xfff0; | |
// bits 12...15 are controller id, which happens to be | |
// 0b0000 for a normal controller | |
} | |
fn latch_falling(&mut self) { | |
// Because the clock pin is normally high, the controller | |
// shifts the first bit on the falling edge of latch, | |
// so that the first bit will be read correctly. | |
self.shift() | |
} | |
fn clock_rising(&mut self) { | |
self.shift() | |
} | |
fn clock_falling(&mut self) { } | |
fn data(&self) -> bool { | |
self.data | |
} | |
} | |
fn main() { | |
let mut controller = SnesController::new(); | |
controller.set_buttons(0b0101_0100_1010_0000); | |
// read buttons from controller | |
controller.latch_rising(); | |
controller.latch_falling(); | |
for _ in 0..16 { | |
controller.clock_falling(); | |
print!("{}", controller.data() as u8); | |
controller.clock_rising(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment