Repository: ruffle-rs/ruffle (language: rust)

Issue:
[Pestilence Z Episode 1] Regression to the intro screen when waiting on the main screen
### Describe the bug


https://user-images.githubusercontent.com/75052171/187061197-bdc84ab2-90af-4de4-bb0f-cbc6d4829108.mp4

In 'Pestilence Z Episode 1', if you wait for a certain amount of time on the main screen, it rewinds to the initial developer logo screen.

This problem repeats indefinitely, and it keeps returning to the initial screen even after clicking the 'New Game' button.

[Pestilence Z Episode 1.zip](https://github.com/ruffle-rs/ruffle/files/9439214/Pestilence.Z.Episode.1.zip)

last check: 2022-08-28 Nightly


### Expected behavior

Frame regression should be resolved.

### Affected platform

Self-hosted version

### Operating system

Windows 10 21H2

### Browser

Google Chrome 104

### Additional information

_No response_


Discussion / hints:
This is regressed by #4452.
The issue is that `DefineSprite (5712: splash_zombie)` is not stopped/destroyed after being played, so it endlessly runs `_root.gotoAndStop(282);` when its frame 270 is reached. Adding a `stop();` after `_root.gotoAndStop(282);`  prevents the issue from happening.
Something changed in [nightly-2022-12-29](https://github.com/ruffle-rs/ruffle/releases/tag/nightly-2022-12-29): the issue persists but the clip is no longer visible for some reason (you can still hear the sound it plays, which shouldn't happen), so the game should be playable.
This issue is no longer happening for me.
Audio is still looping, this shouldn't happen. Also, the main issue appears to be fixed by a change that shouldn't have any effect on AVM1 files (cc. #10730).

Fix patch:
diff --git a/core/src/display_object/avm1_button.rs b/core/src/display_object/avm1_button.rs
index 1cafe6b53eb03..eecdcd6bead03 100644
--- a/core/src/display_object/avm1_button.rs
+++ b/core/src/display_object/avm1_button.rs
@@ -393,7 +393,12 @@ impl<'gc> TDisplayObject<'gc> for Avm1Button<'gc> {
     }
 
     fn avm1_unload(&self, context: &mut UpdateContext<'gc>) {
+        for child in self.iter_render_list() {
+            child.avm1_unload(context);
+        }
+
         self.drop_focus(context);
+
         if let Some(node) = self.maskee() {
             node.set_masker(context.gc(), None, true);
         } else if let Some(node) = self.masker() {


Test patch:
diff --git a/tests/tests/swfs/avm1/movieclip_in_removed_button/output.txt b/tests/tests/swfs/avm1/movieclip_in_removed_button/output.txt
new file mode 100644
index 0000000000000..e3edbe9451fef
--- /dev/null
+++ b/tests/tests/swfs/avm1/movieclip_in_removed_button/output.txt
@@ -0,0 +1,4 @@
+_level0.button.instance1.onEnterFrame
+_level0.button
+undefined
+undefined
diff --git a/tests/tests/swfs/avm1/movieclip_in_removed_button/test.fla b/tests/tests/swfs/avm1/movieclip_in_removed_button/test.fla
new file mode 100644
index 0000000000000..73a4cb6abbf23
Binary files /dev/null and b/tests/tests/swfs/avm1/movieclip_in_removed_button/test.fla differ
diff --git a/tests/tests/swfs/avm1/movieclip_in_removed_button/test.swf b/tests/tests/swfs/avm1/movieclip_in_removed_button/test.swf
new file mode 100644
index 0000000000000..91e1b8da85941
Binary files /dev/null and b/tests/tests/swfs/avm1/movieclip_in_removed_button/test.swf differ
diff --git a/tests/tests/swfs/avm1/movieclip_in_removed_button/test.toml b/tests/tests/swfs/avm1/movieclip_in_removed_button/test.toml
new file mode 100644
index 0000000000000..6236b82398fd0
--- /dev/null
+++ b/tests/tests/swfs/avm1/movieclip_in_removed_button/test.toml
@@ -0,0 +1,1 @@
+num_frames = 4