agb/examples/the-hat-chooses-the-wizard/src/sfx.rs
2023-02-23 21:18:29 +00:00

118 lines
3.8 KiB
Rust

use agb::sound::mixer::{Mixer, SoundChannel};
mod music_data {
// From the open game art page:
//
// USING THE LOOPED VERSION:
// 1. Play the intro.
// 2. When the intro reaches approximately 11.080 seconds, trigger the main loop and let the intro finish underneath it.
// 3. Re-trigger the main loop every time it reaches 1 minute 26.080 seconds, and let the old instance finish underneath the new one.
pub const INTRO_MUSIC: &[u8] =
agb::include_wav!("sfx/Otto Halmén - Sylvan Waltz (loop intro).wav");
pub const LOOP: &[u8] = agb::include_wav!("sfx/Otto Halmén - Sylvan Waltz (loop main).wav");
// These are based on the instructions above and a frame rate of 59.73Hz
pub const TRIGGER_MUSIC_POINT: i32 = 662;
pub const LOOP_MUSIC: i32 = 5141;
}
mod effects {
const WOOSH1: &[u8] = agb::include_wav!("sfx/woosh1.wav");
const WOOSH2: &[u8] = agb::include_wav!("sfx/woosh2.wav");
const WOOSH3: &[u8] = agb::include_wav!("sfx/woosh3.wav");
pub const WHOOSHES: &[&[u8]] = &[WOOSH1, WOOSH2, WOOSH3];
pub const CATCH: &[u8] = agb::include_wav!("sfx/catch.wav");
pub const JUMP: &[u8] = agb::include_wav!("sfx/jump.wav");
pub const LAND: &[u8] = agb::include_wav!("sfx/land.wav");
pub const SLIME_JUMP: &[u8] = agb::include_wav!("sfx/slime-jump.wav");
pub const SLIME_DEATH: &[u8] = agb::include_wav!("sfx/slime-death.wav");
pub const SNAIL_EMERGE: &[u8] = agb::include_wav!("sfx/snail-emerge.wav");
pub const SNAIL_RETREAT: &[u8] = agb::include_wav!("sfx/snail-retreat.wav");
pub const SNAIL_HAT_BOUNCE: &[u8] = agb::include_wav!("sfx/snail-hat-bounce.wav");
pub const SNAIL_DEATH: &[u8] = agb::include_wav!("sfx/snail-death.wav");
}
pub struct SfxPlayer<'a> {
mixer: &'a mut Mixer<'a>,
frame: i32,
}
impl<'a> SfxPlayer<'a> {
pub fn new(mixer: &'a mut Mixer<'a>) -> Self {
SfxPlayer { mixer, frame: 0 }
}
pub fn catch(&mut self) {
self.mixer.play_sound(SoundChannel::new(effects::CATCH));
}
pub fn throw(&mut self) {
self.play_random(effects::WHOOSHES);
}
pub fn jump(&mut self) {
self.mixer.play_sound(SoundChannel::new(effects::JUMP));
}
pub fn slime_jump(&mut self) {
self.mixer
.play_sound(SoundChannel::new(effects::SLIME_JUMP));
}
pub fn slime_death(&mut self) {
self.mixer
.play_sound(SoundChannel::new(effects::SLIME_DEATH));
}
pub fn snail_emerge(&mut self) {
self.mixer
.play_sound(SoundChannel::new(effects::SNAIL_EMERGE));
}
pub fn snail_retreat(&mut self) {
self.mixer
.play_sound(SoundChannel::new(effects::SNAIL_RETREAT));
}
pub fn snail_hat_bounce(&mut self) {
self.mixer
.play_sound(SoundChannel::new(effects::SNAIL_HAT_BOUNCE));
}
pub fn snail_death(&mut self) {
self.mixer
.play_sound(SoundChannel::new(effects::SNAIL_DEATH));
}
pub fn land(&mut self) {
self.mixer.play_sound(SoundChannel::new(effects::LAND));
}
fn play_random(&mut self, effect: &[&'static [u8]]) {
self.mixer.play_sound(SoundChannel::new(
effect[agb::rng::gen() as usize % effect.len()],
));
}
pub fn frame(&mut self) {
if self.frame == 0 {
// play the introduction
self.mixer
.play_sound(SoundChannel::new_high_priority(music_data::INTRO_MUSIC));
} else if self.frame == music_data::TRIGGER_MUSIC_POINT
|| (self.frame - music_data::TRIGGER_MUSIC_POINT) % music_data::LOOP_MUSIC == 0
{
self.mixer
.play_sound(SoundChannel::new_high_priority(music_data::LOOP));
}
self.frame += 1;
self.mixer.frame();
}
}