Skip to main content

nes_sim/
input.rs

1use crate::savestate::{SaveStateError, StateReader, StateWriter};
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4pub enum ControllerButton {
5    A,
6    B,
7    Select,
8    Start,
9    Up,
10    Down,
11    Left,
12    Right,
13}
14
15impl ControllerButton {
16    const fn bit(self) -> u8 {
17        match self {
18            Self::A => 0x01,
19            Self::B => 0x02,
20            Self::Select => 0x04,
21            Self::Start => 0x08,
22            Self::Up => 0x10,
23            Self::Down => 0x20,
24            Self::Left => 0x40,
25            Self::Right => 0x80,
26        }
27    }
28}
29
30#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
31pub struct ControllerState {
32    bits: u8,
33}
34
35impl ControllerState {
36    pub const fn new() -> Self {
37        Self { bits: 0 }
38    }
39
40    pub const fn from_bits(bits: u8) -> Self {
41        Self { bits }
42    }
43
44    pub const fn bits(self) -> u8 {
45        self.bits
46    }
47
48    pub const fn pressed(self, button: ControllerButton) -> bool {
49        (self.bits & button.bit()) != 0
50    }
51
52    pub fn set_pressed(&mut self, button: ControllerButton, pressed: bool) {
53        if pressed {
54            self.bits |= button.bit();
55        } else {
56            self.bits &= !button.bit();
57        }
58    }
59}
60
61#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
62pub(crate) struct Joypad {
63    strobe: bool,
64    state: ControllerState,
65    shift: u8,
66}
67
68impl Joypad {
69    pub(crate) const fn new() -> Self {
70        Self {
71            strobe: false,
72            state: ControllerState::new(),
73            shift: 0,
74        }
75    }
76
77    pub(crate) fn set_state(&mut self, state: ControllerState) {
78        self.state = state;
79        if self.strobe {
80            self.shift = state.bits();
81        }
82    }
83
84    pub(crate) fn write(&mut self, data: u8) {
85        self.strobe = (data & 0x01) != 0;
86        if self.strobe {
87            self.shift = self.state.bits();
88        }
89    }
90
91    pub(crate) fn read(&mut self) -> u8 {
92        if self.strobe {
93            return u8::from(self.state.pressed(ControllerButton::A));
94        }
95
96        let bit = self.shift & 0x01;
97        self.shift = (self.shift >> 1) | 0x80;
98        bit
99    }
100
101    pub(crate) fn save_state(&self, writer: &mut StateWriter) {
102        writer.write_bool(self.strobe);
103        writer.write_u8(self.state.bits());
104        writer.write_u8(self.shift);
105    }
106
107    pub(crate) fn load_state(
108        &mut self,
109        reader: &mut StateReader<'_>,
110    ) -> Result<(), SaveStateError> {
111        self.strobe = reader.read_bool()?;
112        self.state = ControllerState::from_bits(reader.read_u8()?);
113        self.shift = reader.read_u8()?;
114        Ok(())
115    }
116}