Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: Fix BG music not stopping in Samorost (close #963) #13781

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

vadosnaprimer
Copy link

@vadosnaprimer vadosnaprimer commented Oct 29, 2023

MovieClip avm1_unload() was already stopping the current stream at https://github.com/ruffle-rs/ruffle/blob/5bebebddbe3c39362ba520cb0c9c28b3cb7f72a3/core/src/display_object/movie_clip.rs#L2924C18-L2924C18 but in Samorost, the BG music that keeps playing after switching SWFs in ruffle is not a stream but a sound.

I don't know how to make it stop only the sound that's currently playing, so here's a "fix" that just stops them all. Technically closes #963 but there may be a neater way.

@Lord-McSweeney
Copy link
Collaborator

Lord-McSweeney commented Oct 29, 2023

Thank you for the contribution! Unfortunately this fix is (probably) not the right way to do it. Can you elaborate on what a "sound" is when you stated that the BG music "is not a stream but a sound"? I don't see any StartSound tags or Sound AS code in the SWF.

EDIT: Whoops, nevermind, there's a StartSound that I missed. I think in that case the right way to do it would be to add a list of handles of currently-playing sounds to MovieClipData, add handles to that list whenever the StartSound tag starts a sound (see MovieClip::start_sound_1), then iterate over all of those handles and call context.stop_sounds_with_handle(...) on them when the movie is unloaded.

@vadosnaprimer
Copy link
Author

Are there examples of this in the code that I could use? I wouldn't be able to add it from scratch, only by copying an existing approach.

@vadosnaprimer
Copy link
Author

vadosnaprimer commented Nov 5, 2023

@Lord-McSweeney AudioManager::stop_all_sounds() does basically what you describe.

MovieClip::start_sound_1() calls AudioManager::start_sound() which adds to this list:

/// The list of actively playing sounds.
sounds: Vec<SoundInstance<'gc>>,

AudioManager::stop_all_sounds() clears that list, and then AudioMixer::stop_all_sounds() iterates through AudioMixer::sound_instances and removes each of them from the arena, also clearing it after that.

pub fn stop_all_sounds(&mut self) {
let mut sound_instances = self
.sound_instances
.lock()
.expect("Cannot be called reentrant");
// This is a workaround for a bug in generational-arena:
// Arena::clear does not properly bump the generational index, allowing for stale references
// to continue to work (this caused #1315). Arena::remove will force a generation bump.
// See https://github.com/fitzgen/generational-arena/issues/30
if let Some((i, _)) = sound_instances.iter().next() {
sound_instances.remove(i);
}
sound_instances.clear();
}

@Lord-McSweeney
Copy link
Collaborator

Yes, except this implementation should only stop sounds that were played in a specific MovieClip, not every sound.

@vadosnaprimer
Copy link
Author

I think in that case the right way to do it would be to add a list of handles of currently-playing sounds to MovieClipData, add handles to that list whenever the StartSound tag starts a sound (see MovieClip::start_sound_1), then iterate over all of those handles and call context.stop_sounds_with_handle(...) on them when the movie is unloaded.

If a sound has ended by itself or by the game before unloading the movie, would I also need to remove it from the list of per-clip handles? I was unable to find a place when sounds get removed when they simply end, so I don't know how I'd duplicate the removal regarding my duplicate list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Samorost: Strange behaviours after switching movies
2 participants