From 6277eaeaee903e779f7c07d218631e67f9f15ba6 Mon Sep 17 00:00:00 2001
From: GBA bot <gw@ilym.me>
Date: Sun, 2 Jan 2022 21:47:08 +0000
Subject: [PATCH 1/3] Split vblank() into frame() and after_vblank()

---
 agb/src/sound/mixer/sw_mixer.rs | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/agb/src/sound/mixer/sw_mixer.rs b/agb/src/sound/mixer/sw_mixer.rs
index 2a5fbb29..c9da82ab 100644
--- a/agb/src/sound/mixer/sw_mixer.rs
+++ b/agb/src/sound/mixer/sw_mixer.rs
@@ -45,14 +45,16 @@ impl<'a> Mixer<'a> {
         hw::set_sound_control_register_for_mixer();
     }
 
-    pub fn vblank(&mut self) {
-        self.buffer.swap();
+    pub fn frame(&mut self) {
         self.buffer.clear();
-
         self.buffer
             .write_channels(self.channels.iter_mut().flatten());
     }
 
+    pub fn after_vblank(&mut self) {
+        self.buffer.swap();
+    }
+
     pub fn play_sound(&mut self, new_channel: SoundChannel) -> Option<ChannelId> {
         for (i, channel) in self.channels.iter_mut().enumerate() {
             if let Some(some_channel) = channel {

From f62501a748d203a44e10b3baea6cb6e1d5a04c6b Mon Sep 17 00:00:00 2001
From: GBA bot <gw@ilym.me>
Date: Sun, 2 Jan 2022 21:48:05 +0000
Subject: [PATCH 2/3] Update the examples to correctly use the new API

---
 agb/examples/mixer_basic.rs  | 3 ++-
 agb/examples/stereo_sound.rs | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/agb/examples/mixer_basic.rs b/agb/examples/mixer_basic.rs
index 7fb68045..ed8d3cf6 100644
--- a/agb/examples/mixer_basic.rs
+++ b/agb/examples/mixer_basic.rs
@@ -51,7 +51,8 @@ fn main() -> ! {
             }
         }
 
+        mixer.frame();
         vblank_provider.wait_for_vblank();
-        mixer.vblank();
+        mixer.after_vblank();
     }
 }
diff --git a/agb/examples/stereo_sound.rs b/agb/examples/stereo_sound.rs
index f261d9ed..27f82015 100644
--- a/agb/examples/stereo_sound.rs
+++ b/agb/examples/stereo_sound.rs
@@ -29,7 +29,8 @@ fn main() -> ! {
     loop {
         vblank_provider.wait_for_vblank();
         let before_mixing_cycles = timer.get_value();
-        mixer.vblank();
+        mixer.after_vblank();
+        mixer.frame();
         let after_mixing_cycles = timer.get_value();
 
         frame_counter = frame_counter.wrapping_add(1);

From 96aefcbdf50cf9030242a00f0bf2b678a89b9328 Mon Sep 17 00:00:00 2001
From: GBA bot <gw@ilym.me>
Date: Sun, 2 Jan 2022 21:59:17 +0000
Subject: [PATCH 3/3] Update all the usages of `mixer.vblank()`

---
 .../the-hat-chooses-the-wizard/src/main.rs    | 33 ++++++++++++-------
 .../the-hat-chooses-the-wizard/src/sfx.rs     |  2 +-
 .../src/splash_screen.rs                      | 10 ++++--
 examples/the-purple-night/src/main.rs         |  3 +-
 examples/the-purple-night/src/sfx.rs          |  8 +++--
 5 files changed, 37 insertions(+), 19 deletions(-)

diff --git a/examples/the-hat-chooses-the-wizard/src/main.rs b/examples/the-hat-chooses-the-wizard/src/main.rs
index 2411df1c..aa5c9292 100644
--- a/examples/the-hat-chooses-the-wizard/src/main.rs
+++ b/examples/the-hat-chooses-the-wizard/src/main.rs
@@ -808,9 +808,10 @@ pub fn main() -> ! {
                 break;
             }
 
+            music_box.before_frame(&mut mixer);
+            mixer.frame();
             vblank.wait_for_vblank();
-            music_box.after_blank(&mut mixer);
-            mixer.vblank();
+            mixer.after_vblank();
 
             level_display::write_level(
                 &mut world_display,
@@ -820,9 +821,10 @@ pub fn main() -> ! {
 
             world_display.show();
 
+            music_box.before_frame(&mut mixer);
+            mixer.frame();
             vblank.wait_for_vblank();
-            music_box.after_blank(&mut mixer);
-            mixer.vblank();
+            mixer.after_vblank();
 
             let mut level = PlayingLevel::open_level(
                 &map_tiles::LEVELS[current_level as usize],
@@ -833,17 +835,21 @@ pub fn main() -> ! {
             );
             let mut level_load = level.load_1().step_by(24);
             for _ in 0..30 {
+                music_box.before_frame(&mut mixer);
+                mixer.frame();
                 vblank.wait_for_vblank();
-                music_box.after_blank(&mut mixer);
-                mixer.vblank();
+                mixer.after_vblank();
+
                 level_load.next();
             }
             level_load.count();
             let mut level_load = level.load_2().step_by(24);
             for _ in 0..30 {
+                music_box.before_frame(&mut mixer);
+                mixer.frame();
                 vblank.wait_for_vblank();
-                music_box.after_blank(&mut mixer);
-                mixer.vblank();
+                mixer.after_vblank();
+
                 level_load.next();
             }
             level_load.count();
@@ -857,9 +863,10 @@ pub fn main() -> ! {
                     UpdateState::Dead => {
                         level.dead_start();
                         while level.dead_update() {
+                            music_box.before_frame(&mut mixer);
+                            mixer.frame();
                             vblank.wait_for_vblank();
-                            music_box.after_blank(&mut mixer);
-                            mixer.vblank();
+                            mixer.after_vblank();
                         }
                         break;
                     }
@@ -868,9 +875,11 @@ pub fn main() -> ! {
                         break;
                     }
                 }
+
+                music_box.before_frame(&mut mixer);
+                mixer.frame();
                 vblank.wait_for_vblank();
-                music_box.after_blank(&mut mixer);
-                mixer.vblank();
+                mixer.after_vblank();
             }
         }
 
diff --git a/examples/the-hat-chooses-the-wizard/src/sfx.rs b/examples/the-hat-chooses-the-wizard/src/sfx.rs
index 1ba37a53..6fbaab7e 100644
--- a/examples/the-hat-chooses-the-wizard/src/sfx.rs
+++ b/examples/the-hat-chooses-the-wizard/src/sfx.rs
@@ -46,7 +46,7 @@ impl MusicBox {
         MusicBox { frame: 0 }
     }
 
-    pub fn after_blank(&mut self, mixer: &mut Mixer) {
+    pub fn before_frame(&mut self, mixer: &mut Mixer) {
         if self.frame == 0 {
             // play the introduction
             mixer.play_sound(SoundChannel::new_high_priority(music_data::INTRO_MUSIC));
diff --git a/examples/the-hat-chooses-the-wizard/src/splash_screen.rs b/examples/the-hat-chooses-the-wizard/src/splash_screen.rs
index ef0e9525..56552fef 100644
--- a/examples/the-hat-chooses-the-wizard/src/splash_screen.rs
+++ b/examples/the-hat-chooses-the-wizard/src/splash_screen.rs
@@ -52,12 +52,16 @@ pub fn show_splash_screen(
         ) {
             break;
         }
-        vblank.wait_for_vblank();
         if let Some(ref mut mixer) = mixer {
             if let Some(ref mut music_box) = music_box {
-                music_box.after_blank(mixer);
+                music_box.before_frame(mixer);
             }
-            mixer.vblank();
+            mixer.frame();
+        }
+        vblank.wait_for_vblank();
+
+        if let Some(ref mut mixer) = mixer {
+            mixer.after_vblank();
         }
     }
     splash_screen_display.hide();
diff --git a/examples/the-purple-night/src/main.rs b/examples/the-purple-night/src/main.rs
index 118c1196..2a657b04 100644
--- a/examples/the-purple-night/src/main.rs
+++ b/examples/the-purple-night/src/main.rs
@@ -2185,8 +2185,9 @@ fn game_with_level(gba: &mut agb::Gba) {
         );
 
         start_at_boss = loop {
+            sfx.frame();
             vblank.wait_for_vblank();
-            sfx.vblank();
+            sfx.after_vblank();
             match game.advance_frame(&object, &mut sfx) {
                 GameStatus::Continue => {}
                 GameStatus::Lost => {
diff --git a/examples/the-purple-night/src/sfx.rs b/examples/the-purple-night/src/sfx.rs
index 5125795c..400e5aaa 100644
--- a/examples/the-purple-night/src/sfx.rs
+++ b/examples/the-purple-night/src/sfx.rs
@@ -35,8 +35,12 @@ impl<'a> Sfx<'a> {
         Self { mixer, bgm: None }
     }
 
-    pub fn vblank(&mut self) {
-        self.mixer.vblank();
+    pub fn frame(&mut self) {
+        self.mixer.frame();
+    }
+
+    pub fn after_vblank(&mut self) {
+        self.mixer.after_vblank();
     }
 
     pub fn stop_music(&mut self) {