avm2: Don't stop root movie clip, even if it doesn't extend `MovieClip`

Normally, Flash Player will ignores frames for a movie clip with
a symbol class that doesn't extend `MovieClip` (e.g. it extends
`Sprite`). However, the root movie appears to have frame run
unconditionally, even if it only extends `Sprite`. This can
be observed by adding a Graphics child in the second frame only -
the child will flicker in and out as the player switches between
frames, but only for the root movie clip.

Seedling relies on this behavior - it has `DoAbc2` tags in the second
frame, and has a main `Preloader` class that extends `Sprite`.
This commit is contained in:
Aaron Hill 2023-10-17 23:54:02 -04:00
parent e6f9796094
commit fd4d6921d8
5 changed files with 19 additions and 1 deletions

View File

@ -1908,7 +1908,8 @@ pub trait TDisplayObject<'gc>:
// It's possible to have a DefineSprite tag with multiple frames, but have
// the corresponding `SymbolClass` *not* extend `MovieClip` (e.g. extending `Sprite` directly.)
// When this occurs, Flash Player will run the first frame, and immediately stop.
if !obj.is_of_type(movieclip_class, context) {
// However, Flash Player runs frames for the root movie clip, even if it doesn't extend `MovieClip`.
if !obj.is_of_type(movieclip_class, context) && !movie.is_root() {
movie.stop(context);
}
}

View File

@ -0,0 +1,17 @@
package {
import flash.display.Sprite;
public class MainClass extends Sprite {
public function MainClass() {
var child = new MyChild();
child.x = 100;
child.y = 50;
this.addChild(child);
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
tests/tests/swfs/avm2/sprite_with_frames/test.fla Normal file → Executable file

Binary file not shown.