diff --git a/examples/file_load.rs b/examples/file_load.rs index 4fba477..cb54158 100644 --- a/examples/file_load.rs +++ b/examples/file_load.rs @@ -1,8 +1,16 @@ use torque_tracker_engine::file; fn main() { - let file = include_bytes!("../test-files/test-1.it"); - let mut reader = std::io::Cursor::new(file); + // let file = include_bytes!("../test-files/test-1.it"); + // let mut reader = std::io::Cursor::new(&file); + // let song = file::parse_song(&mut reader); + let path = std::env::args().nth(1).unwrap(); + println!("path: {path}"); + // let file_content = std::fs::read(&path).unwrap(); + // assert!(file_content == file); + let file = std::fs::File::open(&path).unwrap(); + println!("file len: {}", file.metadata().unwrap().len()); + let mut reader = std::io::BufReader::new(file); let song = file::parse_song(&mut reader).unwrap(); println!("{song:?}"); } diff --git a/src/file/impulse_format/header.rs b/src/file/impulse_format/header.rs index 70c324d..540b1cb 100644 --- a/src/file/impulse_format/header.rs +++ b/src/file/impulse_format/header.rs @@ -189,6 +189,7 @@ impl ImpulseHeader { .map(|chunk| { let value = u32::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]); if value <= Self::BASE_SIZE as u32 { + // TODO: if i put defect handles pack i probably need to handle 0 // defect_handler(LoadDefect::OutOfBoundsPtr); None } else { diff --git a/src/file/impulse_format/sample.rs b/src/file/impulse_format/sample.rs index 909d597..1b4a5c8 100644 --- a/src/file/impulse_format/sample.rs +++ b/src/file/impulse_format/sample.rs @@ -1,6 +1,7 @@ // look at player/csndfile.c csf_read_sample #![allow(dead_code)] // not nearly done +use std::fmt::Debug; use std::num::NonZeroU32; use crate::file::{InFilePtr, err::LoadErr}; @@ -76,7 +77,7 @@ enum ImpulseSampleEncoding { } /// don't understand what bit 3 is supposed to do -#[derive(Debug, Copy, Clone)] +#[derive(Copy, Clone)] pub struct SampleFormatConvert(u8); impl SampleFormatConvert { @@ -106,7 +107,23 @@ impl SampleFormatConvert { } } -#[derive(Debug, Copy, Clone)] +impl Debug for SampleFormatConvert { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("SampleFormatConvert") + .field("is_signed", &self.is_signed()) + .field("is_big_endian", &self.is_big_endian()) + .field("delta_sample", &self.delta_samples()) + .field("byte_delta", &self.byte_delta()) + .field("tx_wave_12bit", &self.tx_wave_12bit()) + .field( + "should_show_stereo_prompt", + &self.should_show_stereo_prompt(), + ) + .finish() + } +} + +#[derive(Copy, Clone)] pub struct SampleFormatFlags(u8); impl SampleFormatFlags { @@ -119,7 +136,7 @@ impl SampleFormatFlags { pub fn is_8bit(self) -> bool { !self.is_16bit() } - pub fn is_steroe(self) -> bool { + pub fn is_stereo(self) -> bool { (self.0 & 0x04) != 0 } pub fn is_compressed(self) -> bool { @@ -145,6 +162,21 @@ impl SampleFormatFlags { } } +impl Debug for SampleFormatFlags { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut fmt = f.debug_struct("SampleFormatFlags"); + fmt.field("has_sample", &self.has_sample()); + fmt.field("is_16bit", &self.is_16bit()); + fmt.field("is_stereo", &self.is_stereo()); + fmt.field("is_compressed", &self.is_compressed()); + fmt.field("uses_loop", &self.uses_loop()); + fmt.field("uses_sustain_loop", &self.uses_sustain_loop()); + fmt.field("ping_pong_loop", &self.ping_pong_loop()); + fmt.field("ping_pong_sustain_loop", &self.ping_pong_sustain_loop()); + fmt.finish() + } +} + #[derive(Debug)] pub struct ImpulseSampleHeader { pub dos_filename: Box<[u8]>, @@ -169,7 +201,7 @@ pub struct ImpulseSampleHeader { } impl ImpulseSampleHeader { - const SIZE: usize = 80; + pub const SIZE: usize = 80; pub fn parse(buf: &[u8; Self::SIZE]) -> Result { if !buf.starts_with(b"IMPS") { diff --git a/src/file/mod.rs b/src/file/mod.rs index ff856d9..cbf18ae 100644 --- a/src/file/mod.rs +++ b/src/file/mod.rs @@ -1,7 +1,12 @@ +//! I currently use generics. This hinges on the idea that in every program only one type of file reader is used +//! so dynamic dispatch would offer no advantages. Maybe i will / should change this at some point. +//! +//! I would probably use BufReader as the reader to have the buffer below the vtable. +//! would need my own trait to have Read and Seek together in one vtable use err::LoadErr; use impulse_format::{header, pattern}; -use crate::project::song::Song; +use crate::{file::impulse_format::sample::ImpulseSampleHeader, project::song::Song}; pub mod err; pub mod impulse_format; @@ -41,5 +46,21 @@ pub fn parse_song(reader: &mut R) -> Result