diff --git a/core/src/avm1/globals/math.rs b/core/src/avm1/globals/math.rs index 2391c7aa5..7c96b0c8e 100644 --- a/core/src/avm1/globals/math.rs +++ b/core/src/avm1/globals/math.rs @@ -154,7 +154,8 @@ mod tests { { rootless_arena(|gc_context| { let mut avm = Avm1::new(gc_context); - let movie_clip: Box = Box::new(MovieClip::new(gc_context)); + let movie_clip: Box = + Box::new(MovieClip::new(swf_version, gc_context)); let root = GcCell::allocate(gc_context, movie_clip); let mut context = ActionContext { gc_context, diff --git a/core/src/avm1/object.rs b/core/src/avm1/object.rs index 0a84198bc..85c9d9263 100644 --- a/core/src/avm1/object.rs +++ b/core/src/avm1/object.rs @@ -391,7 +391,8 @@ mod tests { { rootless_arena(|gc_context| { let mut avm = Avm1::new(gc_context); - let movie_clip: Box = Box::new(MovieClip::new(gc_context)); + let movie_clip: Box = + Box::new(MovieClip::new(swf_version, gc_context)); let root = GcCell::allocate(gc_context, movie_clip); let mut context = ActionContext { gc_context, diff --git a/core/src/button.rs b/core/src/button.rs index 778a1337a..9b1d0ed59 100644 --- a/core/src/button.rs +++ b/core/src/button.rs @@ -17,6 +17,7 @@ pub struct Button<'gc> { impl<'gc> Button<'gc> { pub fn from_swf_tag( + swf_version: u8, button: &swf::Button, _library: &crate::library::Library<'gc>, gc_context: gc_arena::MutationContext<'gc, '_>, @@ -45,7 +46,7 @@ impl<'gc> Button<'gc> { }; Button { - base: Default::default(), + base: DisplayObjectBase::new(swf_version), static_data: gc_arena::Gc::allocate(gc_context, static_data), children: BTreeMap::new(), hit_area: BTreeMap::new(), diff --git a/core/src/display_object.rs b/core/src/display_object.rs index 0b506e5ed..fb1a28ef1 100644 --- a/core/src/display_object.rs +++ b/core/src/display_object.rs @@ -14,10 +14,13 @@ pub struct DisplayObjectBase<'gc> { transform: Transform, name: String, clip_depth: Depth, + + ///The version of the SWF that created this display object. + swf_version: u8, } -impl<'gc> Default for DisplayObjectBase<'gc> { - fn default() -> Self { +impl<'gc> DisplayObjectBase<'gc> { + pub fn new(swf_version: u8) -> Self { Self { parent: Default::default(), place_frame: Default::default(), @@ -25,6 +28,7 @@ impl<'gc> Default for DisplayObjectBase<'gc> { transform: Default::default(), name: Default::default(), clip_depth: Default::default(), + swf_version: swf_version, } } } @@ -82,6 +86,9 @@ impl<'gc> DisplayObject<'gc> for DisplayObjectBase<'gc> { fn box_clone(&self) -> Box> { Box::new(self.clone()) } + fn swf_version(&self) -> u8 { + self.swf_version + } } pub trait DisplayObject<'gc>: 'gc + Collect + Debug { @@ -189,6 +196,9 @@ pub trait DisplayObject<'gc>: 'gc + Collect + Debug { _display_object: DisplayNode<'gc>, ) { } + + /// Return the version of the SWF that created this movie clip. + fn swf_version(&self) -> u8; } impl<'gc> Clone for Box> { @@ -247,6 +257,9 @@ macro_rules! impl_display_object { fn box_clone(&self) -> Box> { Box::new(self.clone()) } + fn swf_version(&self) -> u8 { + self.$field.swf_version() + } }; } diff --git a/core/src/edit_text.rs b/core/src/edit_text.rs index 7478d807f..bfd9ac9f7 100644 --- a/core/src/edit_text.rs +++ b/core/src/edit_text.rs @@ -29,7 +29,7 @@ impl<'gc> EditText<'gc> { /// Creates a new `EditText` from an SWF `DefineEditText` tag. pub fn from_swf_tag(context: &mut UpdateContext<'_, 'gc, '_>, swf_tag: swf::EditText) -> Self { Self { - base: Default::default(), + base: DisplayObjectBase::new(context.swf_version), text: swf_tag.initial_text.clone().unwrap_or_default(), static_data: gc_arena::Gc::allocate(context.gc_context, EditTextStatic(swf_tag)), } diff --git a/core/src/graphic.rs b/core/src/graphic.rs index 13f14e27c..b721cfc1a 100644 --- a/core/src/graphic.rs +++ b/core/src/graphic.rs @@ -17,7 +17,7 @@ impl<'gc> Graphic<'gc> { bounds: swf_shape.shape_bounds.clone().into(), }; Graphic { - base: Default::default(), + base: DisplayObjectBase::new(context.swf_version), static_data: gc_arena::Gc::allocate(context.gc_context, static_data), } } diff --git a/core/src/morph_shape.rs b/core/src/morph_shape.rs index 72bc85a01..a15ad175d 100644 --- a/core/src/morph_shape.rs +++ b/core/src/morph_shape.rs @@ -13,11 +13,12 @@ pub struct MorphShape<'gc> { impl<'gc> MorphShape<'gc> { pub fn new( + swf_version: u8, gc_context: gc_arena::MutationContext<'gc, '_>, static_data: MorphShapeStatic, ) -> Self { Self { - base: Default::default(), + base: DisplayObjectBase::new(swf_version), static_data: gc_arena::Gc::allocate(gc_context, static_data), ratio: 0, } diff --git a/core/src/movie_clip.rs b/core/src/movie_clip.rs index 2a16c3b32..c9a8dd9dd 100644 --- a/core/src/movie_clip.rs +++ b/core/src/movie_clip.rs @@ -33,9 +33,9 @@ pub struct MovieClip<'gc> { } impl<'gc> MovieClip<'gc> { - pub fn new(gc_context: MutationContext<'gc, '_>) -> Self { + pub fn new(swf_version: u8, gc_context: MutationContext<'gc, '_>) -> Self { Self { - base: Default::default(), + base: DisplayObjectBase::new(swf_version), static_data: Gc::allocate(gc_context, MovieClipStatic::default()), tag_stream_pos: 0, is_playing: false, @@ -48,6 +48,7 @@ impl<'gc> MovieClip<'gc> { } pub fn new_with_data( + swf_version: u8, gc_context: MutationContext<'gc, '_>, id: CharacterId, tag_stream_start: u64, @@ -55,7 +56,7 @@ impl<'gc> MovieClip<'gc> { num_frames: u16, ) -> Self { Self { - base: Default::default(), + base: DisplayObjectBase::new(swf_version), static_data: Gc::allocate( gc_context, MovieClipStatic { @@ -951,8 +952,12 @@ impl<'gc, 'a> MovieClip<'gc> { reader: &mut SwfStream<&'a [u8]>, ) -> DecodeResult { let swf_button = reader.read_define_button_1()?; - let button = - crate::button::Button::from_swf_tag(&swf_button, &context.library, context.gc_context); + let button = crate::button::Button::from_swf_tag( + context.swf_version, + &swf_button, + &context.library, + context.gc_context, + ); context .library .register_character(swf_button.id, Character::Button(Box::new(button))); @@ -966,8 +971,12 @@ impl<'gc, 'a> MovieClip<'gc> { reader: &mut SwfStream<&'a [u8]>, ) -> DecodeResult { let swf_button = reader.read_define_button_2()?; - let button = - crate::button::Button::from_swf_tag(&swf_button, &context.library, context.gc_context); + let button = crate::button::Button::from_swf_tag( + context.swf_version, + &swf_button, + &context.library, + context.gc_context, + ); context .library .register_character(swf_button.id, Character::Button(Box::new(button))); @@ -1085,6 +1094,7 @@ impl<'gc, 'a> MovieClip<'gc> { let id = reader.read_character_id()?; let num_frames = reader.read_u16()?; let mut movie_clip = MovieClip::new_with_data( + context.swf_version, context.gc_context, id, reader.get_ref().position(), diff --git a/core/src/player.rs b/core/src/player.rs index ec807fbb4..1bec8c0b9 100644 --- a/core/src/player.rs +++ b/core/src/player.rs @@ -16,7 +16,7 @@ static DEVICE_FONT_TAG: &[u8] = include_bytes!("../assets/noto-sans-definefont3. /// The newest known Flash Player version, serves as a default to /// `player_version`. -const NEWEST_PLAYER_VERSION: u8 = 32; +pub const NEWEST_PLAYER_VERSION: u8 = 32; #[derive(Collect)] #[collect(empty_drop)] @@ -148,6 +148,7 @@ impl root: GcCell::allocate( gc_context, Box::new(MovieClip::new_with_data( + header.version, gc_context, 0, 0, @@ -460,7 +461,8 @@ impl // Finalize morph shapes. for (id, static_data) in morph_shapes { - let morph_shape = crate::morph_shape::MorphShape::new(gc_context, static_data); + let morph_shape = + crate::morph_shape::MorphShape::new(swf_version, gc_context, static_data); update_context.library.register_character( id, crate::character::Character::MorphShape(Box::new(morph_shape)), diff --git a/core/src/text.rs b/core/src/text.rs index 1c02313ed..2193b05c1 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -12,7 +12,7 @@ pub struct Text<'gc> { impl<'gc> Text<'gc> { pub fn from_swf_tag(context: &mut UpdateContext<'_, 'gc, '_>, tag: &swf::Text) -> Self { Self { - base: Default::default(), + base: DisplayObjectBase::new(context.swf_version), static_data: gc_arena::Gc::allocate( context.gc_context, TextStatic {