diff --git a/src/main.rs b/src/main.rs index c2f4f46..bcb63ea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use anyhow::{Result, anyhow}; -use macroquad::prelude::*; +use macroquad::color::*; use serialport::SerialPortType; #[derive(Clone, Copy, Debug)] @@ -12,7 +12,6 @@ pub enum Instruction { pub struct SerialDevice { port: Box, - ready: bool, } const CHANNEL_COUNT: u8 = 4; @@ -26,18 +25,16 @@ impl SerialDevice { SerialPortType::UsbPort(_) => { this = Ok(Self { port: serialport::new(port.port_name, 115200).open()?, - ready: true, }); + break; } _ => {} }; - break; } this } fn note_off(&mut self, ch: u8) -> Result<()> { - assert!(self.ready); assert!((0..CHANNEL_COUNT).contains(&ch)); let bytes: Vec = vec![0x80 + ch]; self.port.write(&bytes)?; @@ -45,7 +42,6 @@ impl SerialDevice { } fn note_on(&mut self, ch: u8, note: u8) -> Result<()> { - assert!(self.ready); assert!((0..CHANNEL_COUNT).contains(&ch)); assert!((0..=127).contains(¬e)); let bytes: Vec = vec![0x90 + ch, note]; @@ -54,19 +50,16 @@ impl SerialDevice { } fn modulation(&mut self, ch: u8, depth: u8, rate: u8) -> Result<()> { - assert!(self.ready); assert!((0..CHANNEL_COUNT).contains(&ch)); assert!((0..=127).contains(&depth)); - assert!((0..=255).contains(&rate)); let bytes: Vec = vec![0xA0 + ch, depth, rate]; self.port.write(&bytes)?; Ok(()) } fn frequency_on(&mut self, ch: u8, freq: u16) -> Result<()> { - assert!(self.ready); assert!((0..CHANNEL_COUNT).contains(&ch)); - let bytes: Vec = vec![0xB0 + ch, (freq & 0xff) as u8, (freq & 0xff00 >> 8) as u8]; + let bytes: Vec = vec![0xB0 + ch, (freq & 0xff) as u8, (freq >> 8) as u8]; self.port.write(&bytes)?; Ok(()) } @@ -87,28 +80,55 @@ impl SerialDevice { } } -const INSTRUCTIONS_PATTERN: usize = 1024; - pub struct Pattern { - pub channels: [[Option; INSTRUCTIONS_PATTERN]; CHANNEL_COUNT as usize], + pub rows: Vec<[Option; CHANNEL_COUNT as usize]>, } impl Pattern { pub fn new() -> Self { + let mut rows = Vec::new(); + rows.resize_with(256, || [None; CHANNEL_COUNT as usize]); + Self { rows } + } +} + +pub struct TimeSignature { + pub numerator: u8, + pub denominator: u8, +} + +impl Default for TimeSignature { + fn default() -> Self { Self { - channels: [[None; INSTRUCTIONS_PATTERN]; CHANNEL_COUNT as usize], + numerator: 4, + denominator: 4, } } } pub struct Song { + pub bpm: f64, + pub time_signature: TimeSignature, pub patterns: Vec, pub pattern_order: Vec, // index into patterns } impl Song { - pub fn new() -> Self { + const DEFAULT_BPM: f64 = 120.0; + + pub fn new(bpm: Option, time_signature: Option) -> Self { Self { + bpm: bpm.unwrap_or(Self::DEFAULT_BPM), + time_signature: time_signature.unwrap_or_default(), + patterns: vec![Pattern::new()], + pattern_order: vec![0], + } + } + + pub fn empty(bpm: Option, time_signature: Option) -> Self { + Self { + bpm: bpm.unwrap_or(Self::DEFAULT_BPM), + time_signature: time_signature.unwrap_or_default(), patterns: Vec::new(), pattern_order: Vec::new(), } @@ -130,14 +150,20 @@ impl App { } async fn update(&self) { - clear_background(RED); + macroquad::window::clear_background(WHITE); - draw_line(40.0, 40.0, 100.0, 200.0, 15.0, BLUE); - draw_rectangle(screen_width() / 2.0 - 60.0, 100.0, 120.0, 60.0, GREEN); + macroquad::shapes::draw_line(40.0, 40.0, 100.0, 200.0, 15.0, BLUE); + macroquad::shapes::draw_rectangle( + macroquad::window::screen_width() / 2.0 - 60.0, + 100.0, + 120.0, + 60.0, + GREEN, + ); - draw_text("Hello, Macroquad!", 20.0, 20.0, 30.0, DARKGRAY); + macroquad::text::draw_text("Hello, Macroquad!", 20.0, 20.0, 30.0, DARKGRAY); - next_frame().await + macroquad::window::next_frame().await } }