diff --git a/tracker/agb-tracker-interop/src/lib.rs b/tracker/agb-tracker-interop/src/lib.rs index eee21c00..ad8a9b66 100644 --- a/tracker/agb-tracker-interop/src/lib.rs +++ b/tracker/agb-tracker-interop/src/lib.rs @@ -94,6 +94,7 @@ pub enum PatternEffect { PitchBend(Num<u32, 8>), Jump(Jump), SampleOffset(u16), + Retrigger(u8), } #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] @@ -403,6 +404,7 @@ impl quote::ToTokens for PatternEffect { quote! { Jump(#jump) } } PatternEffect::SampleOffset(offset) => quote! { SampleOffset(#offset) }, + PatternEffect::Retrigger(ticks) => quote! { Retrigger(#ticks) }, }; tokens.append_all(quote! { diff --git a/tracker/agb-tracker/src/lib.rs b/tracker/agb-tracker/src/lib.rs index 527766bf..500f067f 100644 --- a/tracker/agb-tracker/src/lib.rs +++ b/tracker/agb-tracker/src/lib.rs @@ -613,6 +613,11 @@ impl TrackerChannel { self.current_pos = Some(*offset); } } + PatternEffect::Retrigger(ticks) => { + if tick % *ticks as u32 == 0 { + self.current_pos = Some(0); + } + } } } diff --git a/tracker/agb-xm-core/src/lib.rs b/tracker/agb-xm-core/src/lib.rs index 018aa540..c96063ba 100644 --- a/tracker/agb-xm-core/src/lib.rs +++ b/tracker/agb-xm-core/src/lib.rs @@ -439,6 +439,17 @@ pub fn parse_module(module: &Module) -> agb_tracker_interop::Track { PatternEffect::GlobalVolumeSlide(Num::new(first as i32) / 0x40) } } + // R + 0x1B => { + let first = effect_parameter >> 4; + let second = effect_parameter & 0xF; + + if first != 0 { + eprintln!("Unsupported retrigger effect volume {first}"); + } + + PatternEffect::Retrigger(second) + } e => { let effect_char = char::from_digit(e as u32, 36) .unwrap_or('?') diff --git a/tracker/desktop-player/tests/retrigger.xm b/tracker/desktop-player/tests/retrigger.xm new file mode 100644 index 00000000..e44bfbe0 Binary files /dev/null and b/tracker/desktop-player/tests/retrigger.xm differ