diff --git a/tracker/agb-tracker-interop/src/lib.rs b/tracker/agb-tracker-interop/src/lib.rs index 57aa64ce..82568329 100644 --- a/tracker/agb-tracker-interop/src/lib.rs +++ b/tracker/agb-tracker-interop/src/lib.rs @@ -77,6 +77,15 @@ pub enum PatternEffect { PitchBend(Num), } +#[derive(Debug, Default, Clone, PartialEq, Eq)] +pub enum Waveform { + #[default] + None, + Sine, + Saw, + Square, +} + #[cfg(feature = "quote")] impl quote::ToTokens for Track { fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { @@ -333,3 +342,21 @@ impl quote::ToTokens for PatternEffect { }); } } + +#[cfg(feature = "quote")] +impl quote::ToTokens for Waveform { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + use quote::{quote, TokenStreamExt}; + + let name = match self { + Waveform::None => quote!(None), + Waveform::Sine => quote!(Sine), + Waveform::Saw => quote!(Saw), + Waveform::Square => quote!(Square), + }; + + tokens.append_all(quote! { + agb_tracker::__private::agb_tracker_interop::Waveform::#name + }); + } +} diff --git a/tracker/agb-tracker/Cargo.toml b/tracker/agb-tracker/Cargo.toml index 9b74b9df..70c241c6 100644 --- a/tracker/agb-tracker/Cargo.toml +++ b/tracker/agb-tracker/Cargo.toml @@ -23,6 +23,9 @@ agb = { version = "0.20.5", path = "../../agb", optional = true } agb_fixnum = { version = "0.20.5", path = "../../agb-fixnum" } agb_tracker_interop = { version = "0.20.5", path = "../agb-tracker-interop", default-features = false } +[build-dependencies] +agb_fixnum = { version = "0.20.5", path = "../../agb-fixnum" } + [profile.dev] opt-level = 3 debug = true diff --git a/tracker/agb-tracker/build.rs b/tracker/agb-tracker/build.rs new file mode 100644 index 00000000..f08f522c --- /dev/null +++ b/tracker/agb-tracker/build.rs @@ -0,0 +1,48 @@ +use agb_fixnum::Num; + +use std::env; +use std::fs; +use std::path::Path; + +fn main() { + let sine = (0..64).map(|i| (Num::::new(i) / 64).sin()); + + let square = (0..64).map(|i| { + if i < 32 { + Num::::new(-1) + } else { + Num::::new(1) + } + }); + + let saw = (0..64).map(|i| (Num::::new(i) - 32) / 32); + + let out_dir = env::var_os("OUT_DIR").unwrap(); + let dest_path = Path::new(&out_dir).join("lookups.rs"); + + fs::write( + &dest_path, + format!( + " + pub(crate) static SINE_LOOKUP: [agb_fixnum::Num; 64] = [{sine_lookup}]; + pub(crate) static SQUARE_LOOKUP: [agb_fixnum::Num; 64] = [{square_lookup}]; + pub(crate) static SAW_LOOKUP: [agb_fixnum::Num; 64] = [{saw_lookup}]; + ", + sine_lookup = gen_lookup(sine), + square_lookup = gen_lookup(square), + saw_lookup = gen_lookup(saw), + ), + ) + .unwrap(); + + println!("cargo::rerun-if-changed=build.rs"); +} + +fn gen_lookup(input: impl IntoIterator>) -> String { + let output: Vec<_> = input + .into_iter() + .map(|v| format!("agb_fixnum::Num::from_raw({})", v.to_raw())) + .collect(); + + output.join(", ") +} diff --git a/tracker/agb-tracker/src/lib.rs b/tracker/agb-tracker/src/lib.rs index d1158780..53295c69 100644 --- a/tracker/agb-tracker/src/lib.rs +++ b/tracker/agb-tracker/src/lib.rs @@ -65,6 +65,7 @@ extern crate alloc; +mod lookups; mod mixer; use agb_tracker_interop::{PatternEffect, Sample}; diff --git a/tracker/agb-tracker/src/lookups.rs b/tracker/agb-tracker/src/lookups.rs new file mode 100644 index 00000000..48aa0119 --- /dev/null +++ b/tracker/agb-tracker/src/lookups.rs @@ -0,0 +1,3 @@ +pub(crate) mod lookups { + include!(concat!(env!("OUT_DIR"), "/lookups.rs")); +}