avm1: Implement getInstanceAtDepth

This commit is contained in:
Adrian Wielgosik 2021-02-28 19:23:04 +01:00 committed by Mike Welsh
parent 9daa6468ee
commit 14e0980226
5 changed files with 65 additions and 0 deletions

View File

@ -176,6 +176,7 @@ pub fn create_proto<'gc>(
"getBounds" => get_bounds,
"getBytesLoaded" => get_bytes_loaded,
"getBytesTotal" => get_bytes_total,
"getInstanceAtDepth" => get_instance_at_depth,
"getNextHighestDepth" => get_next_highest_depth,
"getRect" => get_rect,
"getURL" => get_url,
@ -818,6 +819,41 @@ fn get_bytes_total<'gc>(
.unwrap_or(Value::Undefined))
}
fn get_instance_at_depth<'gc>(
movie_clip: MovieClip<'gc>,
activation: &mut Activation<'_, 'gc, '_>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if activation.current_swf_version() >= 7 {
let depth = if let Some(depth) = args.get(0) {
depth
.coerce_to_i32(activation)?
.wrapping_add(AVM_DEPTH_BIAS)
} else {
avm_error!(
activation,
"MovieClip.get_instance_at_depth: Too few parameters"
);
return Ok(Value::Undefined);
};
match movie_clip.child_by_depth(depth) {
Some(child) => {
// If the child doesn't have a corresponding AVM object, return mc itself.
// NOTE: this behavior was guessed from observing behavior for Text and Graphic;
// I didn't test other variants like Bitmap, MorphSpahe, Video
// or objects that weren't fully initialized yet.
match child.object() {
Value::Undefined => Ok(movie_clip.object()),
obj => Ok(obj),
}
}
None => Ok(Value::Undefined),
}
} else {
Ok(Value::Undefined)
}
}
fn get_next_highest_depth<'gc>(
movie_clip: MovieClip<'gc>,
activation: &mut Activation<'_, 'gc, '_>,

View File

@ -163,6 +163,7 @@ swf_tests! {
(lessthan2_swf7, "avm1/lessthan2_swf7", 1),
(logical_ops_swf4, "avm1/logical_ops_swf4", 1),
(logical_ops_swf8, "avm1/logical_ops_swf8", 1),
(movieclip_get_instance_at_depth, "avm1/movieclip_get_instance_at_depth", 1),
(movieclip_depth_methods, "avm1/movieclip_depth_methods", 3),
(get_variable_in_scope, "avm1/get_variable_in_scope", 1),
(movieclip_init_object, "avm1/movieclip_init_object", 1),

View File

@ -0,0 +1,28 @@
//_root.getInstanceAtDepth(-16384)
undefined
//_root.getInstanceAtDepth(-16384).getDepth()
undefined
//_root.getInstanceAtDepth(-16383)
_level0
//_root.getInstanceAtDepth(-16383).getDepth()
-16384
//_root.getInstanceAtDepth(-16382)
_level0.instance1
//_root.getInstanceAtDepth(-16382).getDepth()
-16382
//_root.getInstanceAtDepth(-16381)
undefined
//_root.getInstanceAtDepth(-16381).getDepth()
undefined
//_root.getInstanceAtDepth(-16380)
_level0
//_root.getInstanceAtDepth(-16380).getDepth()
-16384
//_root.getInstanceAtDepth(-16379)
_level0.instance2
//_root.getInstanceAtDepth(-16379).getDepth()
-16379
//this.getInstanceAtDepth(123)
_level0.fromscript
//_root.getInstanceAtDepth(123).getDepth()
123