diff --git a/core/src/avm1/globals/movie_clip.rs b/core/src/avm1/globals/movie_clip.rs index de634c6c1..9f2c5644e 100644 --- a/core/src/avm1/globals/movie_clip.rs +++ b/core/src/avm1/globals/movie_clip.rs @@ -378,14 +378,16 @@ pub fn goto_frame<'gc>( stop: bool, scene_offset: u16, ) -> Result, Error> { - if let Some(value) = args.get(0) { - if let Ok(mut frame) = value.as_i32() { + match args.get(0).cloned().unwrap_or(Value::Undefined) { + Value::Number(n) => { // Frame # // Gotoing <= 0 has no effect. // Gotoing greater than _totalframes jumps to the last frame. // Wraps around as an i32. // TODO: -1 +1 here to match Flash's behavior. // We probably want to change our frame representation to 0-based. + // Scene offset is only used by GotoFrame2 global opcode. + let mut frame = crate::avm1::value::f64_to_wrapping_i32(n); frame = frame.wrapping_sub(1); frame = frame.wrapping_add(i32::from(scene_offset)); if frame >= 0 { @@ -396,8 +398,10 @@ pub fn goto_frame<'gc>( movie_clip.goto_frame(context, frame.saturating_add(1) as u16, stop); } } - } else { - let frame_label = value.clone().coerce_to_string(avm, context)?; + } + val => { + // Coerce to string and search for a frame label. + let frame_label = val.clone().coerce_to_string(avm, context)?; if let Some(mut frame) = movie_clip.frame_label_to_number(&frame_label) { frame = frame.wrapping_add(scene_offset); movie_clip.goto_frame(context, frame, stop); diff --git a/core/src/display_object/movie_clip.rs b/core/src/display_object/movie_clip.rs index 3bbe0e7fd..fc4ee655f 100644 --- a/core/src/display_object/movie_clip.rs +++ b/core/src/display_object/movie_clip.rs @@ -160,12 +160,9 @@ impl<'gc> MovieClip<'gc> { } pub fn frame_label_to_number(self, frame_label: &str) -> Option { - self.0 - .read() - .static_data - .frame_labels - .get(frame_label) - .copied() + // Frame labels are case insensitive. + let label = frame_label.to_ascii_lowercase(); + self.0.read().static_data.frame_labels.get(&label).copied() } /// Gets the clip events for this movieclip. @@ -1513,12 +1510,14 @@ impl<'gc, 'a> MovieClipData<'gc> { cur_frame: FrameNumber, static_data: &mut MovieClipStatic, ) -> DecodeResult { - let frame_label = reader.read_frame_label(tag_len)?; - if static_data - .frame_labels - .insert(frame_label.label, cur_frame) - .is_some() + let mut frame_label = reader.read_frame_label(tag_len)?; + // Frame labels are case insensitive (ASCII). + frame_label.label.make_ascii_lowercase(); + if let std::collections::hash_map::Entry::Vacant(v) = + static_data.frame_labels.entry(frame_label.label) { + v.insert(cur_frame); + } else { log::warn!("Movie clip {}: Duplicated frame label", self.id()); } Ok(())