Only version MovieClips. Unversioned display objects recursively read their parents' versions, or the default version otherwise.

This commit is contained in:
David Wendt 2019-10-13 17:27:04 -04:00
parent 269775c0e1
commit 911de06584
8 changed files with 23 additions and 34 deletions

View File

@ -17,7 +17,6 @@ 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, '_>,
@ -46,7 +45,7 @@ impl<'gc> Button<'gc> {
};
Button {
base: DisplayObjectBase::new(swf_version),
base: Default::default(),
static_data: gc_arena::Gc::allocate(gc_context, static_data),
children: BTreeMap::new(),
hit_area: BTreeMap::new(),

View File

@ -1,5 +1,5 @@
use crate::avm1::Value;
use crate::player::{RenderContext, UpdateContext};
use crate::player::{RenderContext, UpdateContext, NEWEST_PLAYER_VERSION};
use crate::prelude::*;
use crate::transform::Transform;
use gc_arena::{Collect, GcCell, MutationContext};
@ -14,13 +14,10 @@ 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> DisplayObjectBase<'gc> {
pub fn new(swf_version: u8) -> Self {
impl<'gc> Default for DisplayObjectBase<'gc> {
fn default() -> Self {
Self {
parent: Default::default(),
place_frame: Default::default(),
@ -28,7 +25,6 @@ impl<'gc> DisplayObjectBase<'gc> {
transform: Default::default(),
name: Default::default(),
clip_depth: Default::default(),
swf_version: swf_version,
}
}
}
@ -86,9 +82,6 @@ impl<'gc> DisplayObject<'gc> for DisplayObjectBase<'gc> {
fn box_clone(&self) -> Box<dyn DisplayObject<'gc>> {
Box::new(self.clone())
}
fn swf_version(&self) -> u8 {
self.swf_version
}
}
pub trait DisplayObject<'gc>: 'gc + Collect + Debug {
@ -198,7 +191,11 @@ pub trait DisplayObject<'gc>: 'gc + Collect + Debug {
}
/// Return the version of the SWF that created this movie clip.
fn swf_version(&self) -> u8;
fn swf_version(&self) -> u8 {
self.parent()
.map(|p| p.read().swf_version())
.unwrap_or(NEWEST_PLAYER_VERSION)
}
}
impl<'gc> Clone for Box<dyn DisplayObject<'gc>> {

View File

@ -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: DisplayObjectBase::new(context.swf_version),
base: Default::default(),
text: swf_tag.initial_text.clone().unwrap_or_default(),
static_data: gc_arena::Gc::allocate(context.gc_context, EditTextStatic(swf_tag)),
}

View File

@ -17,7 +17,7 @@ impl<'gc> Graphic<'gc> {
bounds: swf_shape.shape_bounds.clone().into(),
};
Graphic {
base: DisplayObjectBase::new(context.swf_version),
base: Default::default(),
static_data: gc_arena::Gc::allocate(context.gc_context, static_data),
}
}

View File

@ -13,12 +13,11 @@ 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: DisplayObjectBase::new(swf_version),
base: Default::default(),
static_data: gc_arena::Gc::allocate(gc_context, static_data),
ratio: 0,
}

View File

@ -22,6 +22,7 @@ type FrameNumber = u16;
#[derive(Clone, Debug)]
pub struct MovieClip<'gc> {
base: DisplayObjectBase<'gc>,
swf_version: u8,
static_data: Gc<'gc, MovieClipStatic>,
tag_stream_pos: u64,
is_playing: bool,
@ -35,7 +36,8 @@ pub struct MovieClip<'gc> {
impl<'gc> MovieClip<'gc> {
pub fn new(swf_version: u8, gc_context: MutationContext<'gc, '_>) -> Self {
Self {
base: DisplayObjectBase::new(swf_version),
base: Default::default(),
swf_version,
static_data: Gc::allocate(gc_context, MovieClipStatic::default()),
tag_stream_pos: 0,
is_playing: false,
@ -56,7 +58,8 @@ impl<'gc> MovieClip<'gc> {
num_frames: u16,
) -> Self {
Self {
base: DisplayObjectBase::new(swf_version),
base: Default::default(),
swf_version,
static_data: Gc::allocate(
gc_context,
MovieClipStatic {
@ -952,12 +955,8 @@ 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(
context.swf_version,
&swf_button,
&context.library,
context.gc_context,
);
let button =
crate::button::Button::from_swf_tag(&swf_button, &context.library, context.gc_context);
context
.library
.register_character(swf_button.id, Character::Button(Box::new(button)));
@ -971,12 +970,8 @@ 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(
context.swf_version,
&swf_button,
&context.library,
context.gc_context,
);
let button =
crate::button::Button::from_swf_tag(&swf_button, &context.library, context.gc_context);
context
.library
.register_character(swf_button.id, Character::Button(Box::new(button)));

View File

@ -461,8 +461,7 @@ impl<Audio: AudioBackend, Renderer: RenderBackend, Navigator: NavigatorBackend>
// Finalize morph shapes.
for (id, static_data) in morph_shapes {
let morph_shape =
crate::morph_shape::MorphShape::new(swf_version, gc_context, static_data);
let morph_shape = crate::morph_shape::MorphShape::new(gc_context, static_data);
update_context.library.register_character(
id,
crate::character::Character::MorphShape(Box::new(morph_shape)),

View File

@ -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: DisplayObjectBase::new(context.swf_version),
base: Default::default(),
static_data: gc_arena::Gc::allocate(
context.gc_context,
TextStatic {