diff --git a/.cargo/config.toml b/.cargo/config.toml index 172e583..35033f3 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,5 +2,5 @@ rustflags = ["--cfg=web_sys_unstable_apis"] # Enable for testing WASM-only stuff -#[build] +[build] #target = "wasm32-unknown-unknown" diff --git a/Cargo.toml b/Cargo.toml index fa308ca..bf46776 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,7 @@ byteorder = "1.5.0" [target.'cfg(target_family = "wasm")'.dependencies] gloo = { version = "0.11.0", features = ["futures", "worker"] } +futures = "0.3.30" [package.metadata.wasm-pack.profile.dev.wasm-bindgen] dwarf-debug-info = true diff --git a/src/netmd/commands.rs b/src/netmd/commands.rs index 6c01299..ae845e1 100644 --- a/src/netmd/commands.rs +++ b/src/netmd/commands.rs @@ -18,7 +18,7 @@ use super::utils::{ sanitize_full_width_title, sanitize_half_width_title, }; -#[derive(FromPrimitive, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, FromPrimitive, PartialEq, Eq)] pub enum OperatingStatus { Ready = 50687, Playing = 50037, @@ -31,12 +31,14 @@ pub enum OperatingStatus { ReadyForTransfer = 65319, } +#[derive(Debug, Clone)] pub struct Time { pub minute: u16, pub second: u16, pub frame: u16, } +#[derive(Debug, Clone)] pub struct DeviceStatus { pub disc_present: bool, pub state: Option, @@ -44,7 +46,7 @@ pub struct DeviceStatus { pub time: Time, } -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct Track { index: u16, title: String, @@ -72,6 +74,7 @@ impl Track { } } +#[derive(Debug, Clone)] pub struct Group { index: u16, title: Option, @@ -79,6 +82,7 @@ pub struct Group { tracks: Vec, } +#[derive(Debug, Clone)] pub struct Disc { title: String, full_width_title: String, @@ -101,7 +105,10 @@ impl Disc { } pub fn tracks(&self) -> Vec { - self.groups.iter().flat_map(|g| g.tracks.clone()).collect() + let mut tracks: Vec = self.groups.iter().flat_map(|g| g.tracks.clone()).collect(); + tracks.sort_unstable_by_key(|t| t.index); + + tracks } fn remaining_characters_for_titles( @@ -334,7 +341,7 @@ impl NetMDContext { for (index, group) in track_group_list.iter().enumerate() { let mut tracks = vec![]; for track in &group.2 { - let (encoding, channel) = self.interface.track_encoding(*track).await?; + let (encoding, channel) = self.interface.track_encoding(*track).await.unwrap(); let duration = self.interface.track_length(*track).await?; let flags = self.interface.track_flags(*track).await?; let title = self.interface.track_title(*track, false).await?; @@ -541,6 +548,22 @@ impl NetMDContext { Ok(result) } + + pub fn interface(&self) -> &NetMDInterface { + &self.interface + } + + pub fn interface_mut(&mut self) -> &mut NetMDInterface { + &mut self.interface + } +} + +impl From for NetMDContext { + fn from(value: NetMDInterface) -> Self { + Self { + interface: value + } + } } fn chars_to_cells(len: usize) -> usize { diff --git a/src/netmd/encryption.rs b/src/netmd/encryption.rs index 285dc6c..8516d14 100644 --- a/src/netmd/encryption.rs +++ b/src/netmd/encryption.rs @@ -4,6 +4,11 @@ use rand::RngCore; use std::thread; use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver}; +#[cfg(target_family = "wasm")] +use gloo::worker::{Spawnable, reactor::{reactor, ReactorScope}}; +#[cfg(target_family = "wasm")] +use futures::{sink::SinkExt, StreamExt}; + use super::interface::DataEncryptorInput; type DesEcbEnc = ecb::Decryptor; @@ -13,7 +18,8 @@ pub fn new_thread_encryptor( _input: DataEncryptorInput, ) -> UnboundedReceiver<(Vec, Vec, Vec)> { let (tx, rx) = unbounded_channel::<(Vec, Vec, Vec)>(); - let input = Box::from(_input); + let input = _input; + thread::spawn(move || { let mut iv = [0u8; 8]; @@ -75,3 +81,13 @@ pub fn new_thread_encryptor( rx } + +#[cfg(target_family = "wasm")] +#[reactor] +async fn Encryptor(mut scope: ReactorScope) { + while let Some(m) = scope.next().await { + if scope.send(m.pow(2)).await.is_err() { + break; + } + } +} diff --git a/src/netmd/interface.rs b/src/netmd/interface.rs index 4430ebb..439b39d 100644 --- a/src/netmd/interface.rs +++ b/src/netmd/interface.rs @@ -1339,10 +1339,10 @@ impl NetMDInterface { Err(_) => unreachable!(), }; - let channels = match result[0].to_i64() { - Ok(0x01) => Channels::Stereo, - Ok(0x00) => Channels::Mono, - Ok(e) => return Err(InterfaceError::InvalidEncoding(e as u8)), + let channels = match result[1].to_i64() { + Ok(0x00) => Channels::Stereo, + Ok(0x01) => Channels::Mono, + Ok(e) => return Err(InterfaceError::InvalidDiscFormat(e as u8)), Err(_) => unreachable!(), };