aboutsummaryrefslogtreecommitdiff
path: root/lib/header/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/header/src/lib.rs')
-rw-r--r--lib/header/src/lib.rs68
1 files changed, 68 insertions, 0 deletions
diff --git a/lib/header/src/lib.rs b/lib/header/src/lib.rs
index cf0b736..3a62e35 100644
--- a/lib/header/src/lib.rs
+++ b/lib/header/src/lib.rs
@@ -146,6 +146,48 @@ impl std::fmt::Display for Timing {
}
}
+/// The default expansion device available on the NES 2.0 header.
+#[derive(Debug)]
+pub enum DefaultExpansionDevice {
+ Unknown,
+ StandardControllers,
+ FourScoreSatellite,
+ FamicomFourPlayersAdapter,
+ VsSystem4016,
+ VsSystem4017,
+ VsZapper,
+ Zapper,
+ TwoZappers,
+ PowerPadA,
+ PowerPadB,
+}
+
+impl std::fmt::Display for DefaultExpansionDevice {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ match self {
+ Self::Unknown => write!(f, "Unknown"),
+ Self::StandardControllers => write!(f, "Standard NES/Famicom controllers"),
+ Self::FourScoreSatellite => write!(
+ f,
+ "NES Four Score/Satellite with two additional standard controllers"
+ ),
+ Self::FamicomFourPlayersAdapter => {
+ write!(
+ f,
+ "Famicom Four Players Adapter with two additional standard controllers using the \"simple\" protocol"
+ )
+ }
+ Self::VsSystem4016 => write!(f, "Vs. System (1P via $4016)"),
+ Self::VsSystem4017 => write!(f, "Vs. System (1P via $4017)"),
+ Self::VsZapper => write!(f, "Vs. Zapper"),
+ Self::Zapper => write!(f, "Zapper ($4017)"),
+ Self::TwoZappers => write!(f, "Two Zappers"),
+ Self::PowerPadA => write!(f, "Power Pad Side A"),
+ Self::PowerPadB => write!(f, "Power Pad Side B"),
+ }
+ }
+}
+
/// Information that has been parsed from an NES/Famicom ROM header. The
/// `Header` struct implements the `TryFrom` trait. Hence, use
/// `Header::try_from` in order to parse a header.
@@ -190,6 +232,10 @@ pub struct Header {
/// The kind of the header.
pub kind: Kind,
+
+ /// The default expansion device that can be specified in the NES 2.0
+ /// header. Used to specify the default way to experience a game.
+ pub default_expansion_device: Option<DefaultExpansionDevice>,
}
impl TryFrom<&[u8]> for Header {
@@ -219,11 +265,33 @@ impl TryFrom<&[u8]> for Header {
prg_ram_definition: parse_ram_definition(&kind, bytes.get(10), has_persistent_memory),
chr_ram_definition: parse_ram_definition(&kind, bytes.get(11), has_persistent_memory),
timing: parse_timing(&kind, bytes.get(12)),
+ default_expansion_device: if matches!(kind, Kind::Nes20) {
+ Some(parse_default_expansion_device(bytes.get(15).unwrap_or(&0)))
+ } else {
+ None
+ },
kind,
})
}
}
+// Returns the DefaultExpansionDevice for the given byte value.
+fn parse_default_expansion_device(byte: &u8) -> DefaultExpansionDevice {
+ match byte {
+ 1 => DefaultExpansionDevice::StandardControllers,
+ 2 => DefaultExpansionDevice::FourScoreSatellite,
+ 3 => DefaultExpansionDevice::FamicomFourPlayersAdapter,
+ 4 => DefaultExpansionDevice::VsSystem4016,
+ 5 => DefaultExpansionDevice::VsSystem4017,
+ 7 => DefaultExpansionDevice::VsZapper,
+ 8 => DefaultExpansionDevice::Zapper,
+ 9 => DefaultExpansionDevice::TwoZappers,
+ 11 => DefaultExpansionDevice::PowerPadA,
+ 12 => DefaultExpansionDevice::PowerPadB,
+ _ => DefaultExpansionDevice::Unknown,
+ }
+}
+
// Parse the given `byte` by assuming it's a RAM definition. It will just return
// `None` if `has_persistent_memory` is false or the `kind` is not NES 2.0.
fn parse_ram_definition(