diff --git a/core/src/avm1.rs b/core/src/avm1.rs index d3f06e919..7f4fbedb8 100644 --- a/core/src/avm1.rs +++ b/core/src/avm1.rs @@ -120,6 +120,7 @@ impl Avm1 { Action::RemoveSprite => self.action_remove_sprite(context)?, Action::Return => self.action_return(context)?, Action::SetMember => self.action_set_member(context)?, + Action::SetProperty => self.action_set_property(context)?, Action::SetTarget(target) => self.action_set_target(context, &target)?, Action::SetVariable => self.action_set_variable(context)?, Action::StackSwap => self.action_stack_swap(context)?, @@ -828,6 +829,29 @@ impl Avm1 { unimplemented!("Action::SetMember"); } + fn action_set_property(&mut self, context: &mut ActionContext) -> Result<(), Error> { + let value = self.pop()?.as_f64()? as f32; + let prop_index = self.pop()?.as_u32()? as usize; + let clip_path = self.pop()?; + let path = clip_path.as_string()?; + if let Some(clip) = + Avm1::resolve_slash_path(context.active_clip, context.root, path) + { + if let Some(clip) = clip.write(context.gc_context).as_movie_clip_mut() { + match prop_index { + 0 => clip.set_x(value), + 1 => clip.set_y(value), + 2 => clip.set_x_scale(value), + 3 => clip.set_y_scale(value), + _ => log::warn!("ActionSetProperty: Unimplemented property index {}", prop_index), + } + } + } else { + log::warn!("ActionSetProperty: Invalid path {}", path); + } + Ok(()) + } + fn action_set_variable(&mut self, context: &mut ActionContext) -> Result<(), Error> { // Flash 4-style variable let value = self.pop()?; diff --git a/core/src/display_object.rs b/core/src/display_object.rs index 366b3608e..bf7c8754c 100644 --- a/core/src/display_object.rs +++ b/core/src/display_object.rs @@ -33,6 +33,9 @@ impl<'gc> DisplayObject<'gc> for DisplayObjectBase<'gc> { fn matrix(&self) -> &Matrix { &self.transform.matrix } + fn matrix_mut(&mut self) -> &mut Matrix { + &mut self.transform.matrix + } fn set_matrix(&mut self, matrix: &Matrix) { self.transform.matrix = *matrix; } @@ -76,6 +79,7 @@ pub trait DisplayObject<'gc>: 'gc + Collect { fn transform(&self) -> &Transform; fn matrix(&self) -> &Matrix; + fn matrix_mut(&mut self) -> &mut Matrix; fn set_matrix(&mut self, matrix: &Matrix); fn color_transform(&self) -> &ColorTransform; fn set_color_transform(&mut self, color_transform: &ColorTransform); @@ -136,6 +140,9 @@ macro_rules! impl_display_object { fn matrix(&self) -> &crate::matrix::Matrix { self.$field.matrix() } + fn matrix_mut(&mut self) -> &mut crate::matrix::Matrix { + self.$field.matrix_mut() + } fn set_matrix(&mut self, matrix: &crate::matrix::Matrix) { self.$field.set_matrix(matrix) } diff --git a/core/src/movie_clip.rs b/core/src/movie_clip.rs index ecfc876ec..9032b1482 100644 --- a/core/src/movie_clip.rs +++ b/core/src/movie_clip.rs @@ -118,18 +118,34 @@ impl<'gc> MovieClip<'gc> { self.matrix().tx } + pub fn set_x(&mut self, val: f32) { + self.matrix_mut().tx = val; + } + pub fn y(&self) -> f32 { self.matrix().ty } + pub fn set_y(&mut self, val: f32) { + self.matrix_mut().ty = val; + } + pub fn x_scale(&self) -> f32 { self.matrix().a * 100.0 } + pub fn set_x_scale(&mut self, val: f32) { + self.matrix_mut().a = val / 100.0; + } + pub fn y_scale(&self) -> f32 { self.matrix().d * 100.0 } + pub fn set_y_scale(&mut self, val: f32) { + self.matrix_mut().d = val / 100.0; + } + pub fn current_frame(&self) -> FrameNumber { self.current_frame }