Skip to content

Commit

Permalink
avm1: Fix removeMovieClip depth range
Browse files Browse the repository at this point in the history
removeMovieClip should only function on objects within a certain
depth range, usually to prevent removing timeline clips. However,
this wasn't working properly in some cases because the depth was
being biased incorrectly (removeMovieClip never takes a depth
parameter, so we should not bias the depth).
  • Loading branch information
Herschel committed Aug 21, 2020
1 parent 94a246f commit e496ddb
Show file tree
Hide file tree
Showing 4 changed files with 5 additions and 15 deletions.
3 changes: 1 addition & 2 deletions core/src/avm1/activation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1707,8 +1707,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
let target_clip = self.resolve_target_display_object(start_clip, target)?;

if let Some(target_clip) = target_clip.and_then(|o| o.as_movie_clip()) {
let _ =
globals::movie_clip::remove_movie_clip_with_bias(target_clip, &mut self.context, 0);
let _ = globals::movie_clip::remove_movie_clip(target_clip, self, &[]);
} else {
avm_warn!(self, "RemoveSprite: Source is not a movie clip");
}
Expand Down
17 changes: 4 additions & 13 deletions core/src/avm1/globals/movie_clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::globals::display_object::{self, AVM_DEPTH_BIAS, AVM_MAX_DEPTH};
use crate::avm1::globals::matrix::gradient_object_to_matrix;
use crate::avm1::property::Attribute::*;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, UpdateContext, Value};
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use crate::avm_error;
use crate::avm_warn;
use crate::backend::navigator::NavigationMethod;
Expand Down Expand Up @@ -828,21 +828,12 @@ fn prev_frame<'gc>(
Ok(Value::Undefined)
}

fn remove_movie_clip<'gc>(
pub fn remove_movie_clip<'gc>(
movie_clip: MovieClip<'gc>,
activation: &mut Activation<'_, 'gc, '_>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
// removeMovieClip method uses biased depth compared to RemoveSprite
remove_movie_clip_with_bias(movie_clip, &mut activation.context, AVM_DEPTH_BIAS)
}

pub fn remove_movie_clip_with_bias<'gc>(
movie_clip: MovieClip<'gc>,
context: &mut UpdateContext<'_, 'gc, '_>,
depth_bias: i32,
) -> Result<Value<'gc>, Error<'gc>> {
let depth = movie_clip.depth().wrapping_add(depth_bias);
let depth = movie_clip.depth().wrapping_sub(0);
// Can only remove positive depths (when offset by the AVM depth bias).
// Generally this prevents you from removing non-dynamically created clips,
// although you can get around it with swapDepths.
Expand All @@ -855,7 +846,7 @@ pub fn remove_movie_clip_with_bias<'gc>(
return Ok(Value::Undefined);
};

parent.remove_child_from_avm(context, movie_clip.into());
parent.remove_child_from_avm(&mut activation.context, movie_clip.into());
}
Ok(Value::Undefined)
}
Expand Down
Binary file modified core/tests/swfs/avm1/remove_movie_clip/test.fla
Binary file not shown.
Binary file modified core/tests/swfs/avm1/remove_movie_clip/test.swf
Binary file not shown.

0 comments on commit e496ddb

Please sign in to comment.