Add data structure

This commit is contained in:
Gwilym Inzani 2023-08-04 23:17:59 +01:00
parent 9d299f3e66
commit 826fdd881a
2 changed files with 65 additions and 0 deletions

View file

@ -5,6 +5,7 @@ use agb_fixnum::Num;
#[derive(Debug)] #[derive(Debug)]
pub struct Track<'a> { pub struct Track<'a> {
pub samples: &'a [Sample<'a>], pub samples: &'a [Sample<'a>],
pub envelopes: &'a [Envelope<'a>],
pub pattern_data: &'a [PatternSlot], pub pattern_data: &'a [PatternSlot],
pub patterns: &'a [Pattern], pub patterns: &'a [Pattern],
pub patterns_to_play: &'a [usize], pub patterns_to_play: &'a [usize],
@ -21,6 +22,7 @@ pub struct Sample<'a> {
pub should_loop: bool, pub should_loop: bool,
pub restart_point: u32, pub restart_point: u32,
pub volume: Num<i16, 8>, pub volume: Num<i16, 8>,
pub envelope: Option<usize>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -37,6 +39,14 @@ pub struct PatternSlot {
pub effect2: PatternEffect, pub effect2: PatternEffect,
} }
#[derive(Debug)]
pub struct Envelope<'a> {
pub amount: &'a [Num<i16, 8>],
pub sustain: Option<u32>,
pub loop_start: Option<u32>,
pub loop_end: Option<u32>,
}
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub enum PatternEffect { pub enum PatternEffect {
/// Don't play an effect /// Don't play an effect
@ -65,6 +75,7 @@ impl<'a> quote::ToTokens for Track<'a> {
let Track { let Track {
samples, samples,
envelopes,
pattern_data, pattern_data,
patterns, patterns,
frames_per_tick, frames_per_tick,
@ -82,9 +93,11 @@ impl<'a> quote::ToTokens for Track<'a> {
const PATTERN_DATA: &[agb_tracker::__private::agb_tracker_interop::PatternSlot] = &[#(#pattern_data),*]; const PATTERN_DATA: &[agb_tracker::__private::agb_tracker_interop::PatternSlot] = &[#(#pattern_data),*];
const PATTERNS: &[agb_tracker::__private::agb_tracker_interop::Pattern] = &[#(#patterns),*]; const PATTERNS: &[agb_tracker::__private::agb_tracker_interop::Pattern] = &[#(#patterns),*];
const PATTERNS_TO_PLAY: &[usize] = &[#(#patterns_to_play),*]; const PATTERNS_TO_PLAY: &[usize] = &[#(#patterns_to_play),*];
const ENVELOPES: &[agb_tracker::__private::agb_tracker_interop::Envelope<'static>] = &[#(#envelopes),*];
agb_tracker::Track { agb_tracker::Track {
samples: SAMPLES, samples: SAMPLES,
envelopes: ENVELOPES,
pattern_data: PATTERN_DATA, pattern_data: PATTERN_DATA,
patterns: PATTERNS, patterns: PATTERNS,
patterns_to_play: PATTERNS_TO_PLAY, patterns_to_play: PATTERNS_TO_PLAY,
@ -99,6 +112,49 @@ impl<'a> quote::ToTokens for Track<'a> {
} }
} }
#[cfg(feature = "quote")]
impl quote::ToTokens for Envelope<'_> {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
use quote::{quote, TokenStreamExt};
let Envelope {
amount,
sustain,
loop_start,
loop_end,
} = self;
let amount = amount.iter().map(|value| {
let value = value.to_raw();
quote! { agb_tracker::__private::agb_tracker_interop::Num::from_raw(#value) }
});
let sustain = match sustain {
Some(value) => quote!(Some(#value)),
None => quote!(None),
};
let loop_start = match loop_start {
Some(value) => quote!(Some(#value)),
None => quote!(None),
};
let loop_end = match loop_end {
Some(value) => quote!(Some(#value)),
None => quote!(None),
};
tokens.append_all(quote! {
const AMOUNTS: &[agb_tracker::__private::agb_tracker_interop::Num<i16, 8>] = &[#(#amount),*];
agb_tracker::__private::agb_tracker_interop::Envelope {
amount: AMOUNTS,
sustain: #sustain,
loop_start: #loop_start,
loop_end: #loop_end,
}
});
}
}
#[cfg(feature = "quote")] #[cfg(feature = "quote")]
struct ByteString<'a>(&'a [u8]); struct ByteString<'a>(&'a [u8]);
#[cfg(feature = "quote")] #[cfg(feature = "quote")]
@ -120,8 +176,14 @@ impl<'a> quote::ToTokens for Sample<'a> {
should_loop, should_loop,
restart_point, restart_point,
volume, volume,
envelope,
} = self; } = self;
let envelope = match envelope {
Some(index) => quote!(Some(#index)),
None => quote!(None),
};
let samples = ByteString(data); let samples = ByteString(data);
let volume = volume.to_raw(); let volume = volume.to_raw();
@ -136,6 +198,7 @@ impl<'a> quote::ToTokens for Sample<'a> {
should_loop: #should_loop, should_loop: #should_loop,
restart_point: #restart_point, restart_point: #restart_point,
volume: agb_tracker::__private::Num::from_raw(#volume), volume: agb_tracker::__private::Num::from_raw(#volume),
envelope: #envelope,
} }
} }
}); });

View file

@ -377,6 +377,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
should_loop: sample.should_loop, should_loop: sample.should_loop,
restart_point: sample.restart_point, restart_point: sample.restart_point,
volume: sample.volume, volume: sample.volume,
envelope: None,
}) })
.collect(); .collect();
@ -396,6 +397,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
patterns: &patterns, patterns: &patterns,
num_channels: module.get_num_channels(), num_channels: module.get_num_channels(),
patterns_to_play: &patterns_to_play, patterns_to_play: &patterns_to_play,
envelopes: &[],
frames_per_tick, frames_per_tick,
ticks_per_step: ticks_per_step.into(), ticks_per_step: ticks_per_step.into(),