summaryrefslogtreecommitdiff
path: root/src/metadata.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/metadata.rs')
-rw-r--r--src/metadata.rs127
1 files changed, 0 insertions, 127 deletions
diff --git a/src/metadata.rs b/src/metadata.rs
deleted file mode 100644
index 7692434..0000000
--- a/src/metadata.rs
+++ /dev/null
@@ -1,127 +0,0 @@
-use phosphor::Colour;
-
-
-pub fn parse_metadata(bytecode: &[u8]) -> Option<ProgramMetadata> {
- MetadataParser::from_bytecode(bytecode).parse()
-}
-
-
-struct MetadataParser<'a> {
- bytecode: &'a [u8],
-}
-
-impl<'a> MetadataParser<'a> {
- pub fn from_bytecode(bytecode: &'a [u8]) -> Self {
- Self { bytecode }
- }
-
- pub fn parse(self) -> Option<ProgramMetadata> {
- macro_rules! array {
- ($len:expr, $slice:expr) => {{
- let mut array = [0; $len];
- for i in 0..$len { array[i] = *$slice.get(i).unwrap_or(&0); }
- array
- }};
- }
-
- if self.range(0x00, 3) != &[0x41, 0x00, 0x20] {
- return None;
- }
-
- let (name, version) = split_name_version(self.string(self.double(0x10)));
- let authors = self.string(self.double(0x12)).map(|string| {
- string.lines().map(|line| line.to_string()).collect()
- });
-
- Some( ProgramMetadata {
- bedrock_string: array!(7, self.range(0x03, 7)),
- program_memory_size: match self.double(0x0a) {
- 0 => 65536, double => double as usize },
- working_stack_size: match self.byte(0x0c) {
- 0 => 256, byte => byte as usize },
- return_stack_size: match self.byte(0x0d) {
- 0 => 256, byte => byte as usize },
- required_devices: self.double(0x0e),
- name,
- version,
- authors,
- description: self.string(self.double(0x14)),
- path_buffer: match self.double(0x16) {
- 0 => None, addr => Some(addr as usize) },
- small_icon: match self.double(0x18) {
- 0 => None, addr => Some(array!(72, self.range(addr, 72))) },
- large_icon: match self.double(0x1a) {
- 0 => None, addr => Some(array!(512, self.range(addr, 512))) },
- bg_colour: parse_colour(self.double(0x1c)),
- fg_colour: parse_colour(self.double(0x1e)),
- } )
- }
-
- fn byte(&self, address: u16) -> u8 {
- *self.bytecode.get(address as usize).unwrap_or(&0)
- }
-
- fn double(&self, address: u16) -> u16 {
- u16::from_be_bytes([
- *self.bytecode.get(address as usize).unwrap_or(&0),
- *self.bytecode.get(address as usize + 1).unwrap_or(&0),
- ])
- }
-
- fn range(&self, address: u16, length: usize) -> &[u8] {
- let start = address as usize;
- let end = start + length;
- self.bytecode.get(start..end).unwrap_or(&[])
- }
-
- fn string(&self, address: u16) -> Option<String> {
- if address == 0 { return None; }
- let start = address as usize;
- let mut end = start;
- while let Some(byte) = self.bytecode.get(end) {
- match byte { 0 => break, _ => end += 1 }
- }
- let range = self.bytecode.get(start..end)?;
- Some( String::from_utf8_lossy(range).to_string() )
- }
-}
-
-fn split_name_version(string: Option<String>) -> (Option<String>, Option<String>) {
- if let Some(string) = string {
- match string.split_once('/') {
- Some((left, right)) => (Some(left.to_string()), Some(right.to_string())),
- None => (Some(string), None),
- }
- } else {
- (None, None)
- }
-}
-
-fn parse_colour(double: u16) -> Option<Colour> {
- let i = (double >> 12 ) as usize;
- let r = (double >> 8 & 0xf) as u8 * 17;
- let g = (double >> 4 & 0xf) as u8 * 17;
- let b = (double & 0xf) as u8 * 17;
- match i {
- 0 => Some(Colour::from_rgb(r, g, b)),
- _ => None,
- }
-}
-
-
-pub struct ProgramMetadata {
- pub bedrock_string: [u8; 7],
- pub program_memory_size: usize,
- pub working_stack_size: usize,
- pub return_stack_size: usize,
- pub required_devices: u16,
- pub name: Option<String>,
- pub version: Option<String>,
- pub authors: Option<Vec<String>>,
- pub description: Option<String>,
- pub path_buffer: Option<usize>,
- pub small_icon: Option<[u8; 72]>,
- pub large_icon: Option<[u8; 512]>,
- pub bg_colour: Option<Colour>,
- pub fg_colour: Option<Colour>,
-}