diff --git a/tracker/agb-tracker-interop/src/lib.rs b/tracker/agb-tracker-interop/src/lib.rs index 365a4020..a1a094b7 100644 --- a/tracker/agb-tracker-interop/src/lib.rs +++ b/tracker/agb-tracker-interop/src/lib.rs @@ -46,6 +46,7 @@ pub enum PatternEffect { Arpeggio(Num, Num), Panning(Num), Volume(Num), + VolumeSlide(Num), } #[cfg(feature = "quote")] @@ -185,6 +186,10 @@ impl quote::ToTokens for PatternEffect { let volume = volume.to_raw(); quote! { Volume(agb_tracker::__private::Num::from_raw(#volume))} } + PatternEffect::VolumeSlide(amount) => { + let amount = amount.to_raw(); + quote! { VolumeSlide(agb_tracker::__private::Num::from_raw(#amount))} + } }; tokens.append_all(quote! { diff --git a/tracker/agb-tracker/src/lib.rs b/tracker/agb-tracker/src/lib.rs index 204a9f25..b1dfa5e9 100644 --- a/tracker/agb-tracker/src/lib.rs +++ b/tracker/agb-tracker/src/lib.rs @@ -40,6 +40,7 @@ pub struct Tracker { struct TrackerChannel { channel_id: Option, base_speed: Num, + volume: Num, } impl Tracker { @@ -48,6 +49,7 @@ impl Tracker { channels.resize_with(track.num_channels, || TrackerChannel { channel_id: None, base_speed: 0.into(), + volume: 0.into(), }); Self { @@ -183,6 +185,14 @@ impl TrackerChannel { } PatternEffect::Volume(volume) => { channel.volume(*volume); + self.volume = *volume; + } + PatternEffect::VolumeSlide(amount) => { + self.volume += *amount; + if self.volume < 0.into() { + self.volume = 0.into(); + } + channel.volume(self.volume); } } } diff --git a/tracker/agb-xm-core/src/lib.rs b/tracker/agb-xm-core/src/lib.rs index 742cae47..ffc7882b 100644 --- a/tracker/agb-xm-core/src/lib.rs +++ b/tracker/agb-xm-core/src/lib.rs @@ -188,6 +188,16 @@ pub fn parse_module(module: &Module) -> TokenStream { 0x8 => { PatternEffect::Panning(Num::new(slot.effect_parameter as i16 - 128) / 128) } + 0xA => { + let first = slot.effect_parameter >> 4; + let second = slot.effect_parameter & 0xF; + + if first == 0 { + PatternEffect::VolumeSlide(-Num::new(second as i16) / 16) + } else { + PatternEffect::VolumeSlide(Num::new(first as i16) / 16) + } + } 0xC => PatternEffect::Volume(Num::new(slot.effect_parameter as i16) / 255), _ => PatternEffect::None, };