[Swfdec] Branch 'as' - 6 commits - libswfdec/swfdec_as_interpret.c libswfdec/swfdec_movie_asprops.c libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_sprite.c libswfdec/swfdec_sprite.h libswfdec/swfdec_sprite_movie_as.c libswfdec/swfdec_sprite_movie.c libswfdec/swfdec_sprite_movie.h test/trace

Benjamin Otte company at kemper.freedesktop.org
Wed Jun 27 00:29:32 PDT 2007


 libswfdec/swfdec_as_interpret.c        |   90 +++++++++++------------
 libswfdec/swfdec_movie.c               |   14 ---
 libswfdec/swfdec_movie.h               |    7 -
 libswfdec/swfdec_movie_asprops.c       |   70 +++++++++---------
 libswfdec/swfdec_sprite.c              |   15 ---
 libswfdec/swfdec_sprite.h              |    2 
 libswfdec/swfdec_sprite_movie.c        |  127 ++++++++++++++++-----------------
 libswfdec/swfdec_sprite_movie.h        |    6 +
 libswfdec/swfdec_sprite_movie_as.c     |   35 ++++-----
 test/trace/Makefile.am                 |    7 +
 test/trace/duplicate-names-5.swf       |binary
 test/trace/duplicate-names-5.swf.trace |    5 +
 test/trace/duplicate-names-6.swf       |binary
 test/trace/duplicate-names-6.swf.trace |    5 +
 test/trace/duplicate-names-7.swf       |binary
 test/trace/duplicate-names-7.swf.trace |    5 +
 test/trace/duplicate-names.as          |   14 +++
 17 files changed, 203 insertions(+), 199 deletions(-)

New commits:
diff-tree 0d598e6df9d7c2e046935505cee577accc7e0613 (from parents)
Merge: f7beb246452df6fe2941272419dac3da3dd9fbdf fad705a672d2685cd5572f1bbe4fa9e17776441f
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jun 27 09:20:44 2007 +0200

    Merge branch 'as' of ssh://company@git.freedesktop.org/git/swfdec into as

diff-tree f7beb246452df6fe2941272419dac3da3dd9fbdf (from ed536ca7fcef39543b7f7d115af105dfb2494a35)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jun 24 18:33:42 2007 +0200

    Add a check for how duplicate names are handled.

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 76f5642..24c3d4b 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -147,6 +147,13 @@ EXTRA_DIST = \
 	double-to-string-7.swf \
 	double-to-string-7.swf.trace \
 	double-to-string-7.swf.trace.org \
+	duplicate-names.as \
+	duplicate-names-5.swf \
+	duplicate-names-5.swf.trace \
+	duplicate-names-6.swf \
+	duplicate-names-6.swf.trace \
+	duplicate-names-7.swf \
+	duplicate-names-7.swf.trace \
 	event-order.swf \
 	empty-stack.as \
 	empty-stack.swf \
diff --git a/test/trace/duplicate-names-5.swf b/test/trace/duplicate-names-5.swf
new file mode 100644
index 0000000..e0091a3
Binary files /dev/null and b/test/trace/duplicate-names-5.swf differ
diff --git a/test/trace/duplicate-names-5.swf.trace b/test/trace/duplicate-names-5.swf.trace
new file mode 100644
index 0000000..d9080ef
--- /dev/null
+++ b/test/trace/duplicate-names-5.swf.trace
@@ -0,0 +1,5 @@
+undefined
+undefined
+undefined
+undefined
+undefined
diff --git a/test/trace/duplicate-names-6.swf b/test/trace/duplicate-names-6.swf
new file mode 100644
index 0000000..2cf4b54
Binary files /dev/null and b/test/trace/duplicate-names-6.swf differ
diff --git a/test/trace/duplicate-names-6.swf.trace b/test/trace/duplicate-names-6.swf.trace
new file mode 100644
index 0000000..5f2b6f3
--- /dev/null
+++ b/test/trace/duplicate-names-6.swf.trace
@@ -0,0 +1,5 @@
+10
+0
+0
+10
+20
diff --git a/test/trace/duplicate-names-7.swf b/test/trace/duplicate-names-7.swf
new file mode 100644
index 0000000..a50b8c8
Binary files /dev/null and b/test/trace/duplicate-names-7.swf differ
diff --git a/test/trace/duplicate-names-7.swf.trace b/test/trace/duplicate-names-7.swf.trace
new file mode 100644
index 0000000..5f2b6f3
--- /dev/null
+++ b/test/trace/duplicate-names-7.swf.trace
@@ -0,0 +1,5 @@
+10
+0
+0
+10
+20
diff --git a/test/trace/duplicate-names.as b/test/trace/duplicate-names.as
new file mode 100644
index 0000000..b268b5e
--- /dev/null
+++ b/test/trace/duplicate-names.as
@@ -0,0 +1,14 @@
+// makeswf -v 7 -s 200x150 -r 1 -o duplicate-names.swf duplicate-names.as
+
+createEmptyMovieClip ("foo", 10);
+trace (foo.getDepth ());
+createEmptyMovieClip ("foo", 0);
+trace (foo.getDepth ());
+createEmptyMovieClip ("foo", 20);
+trace (foo.getDepth ());
+foo.removeMovieClip ();
+trace (foo.getDepth ());
+foo.removeMovieClip ();
+trace (foo.getDepth ());
+
+loadMovie ("FSCommand:quit", "");
diff-tree ed536ca7fcef39543b7f7d115af105dfb2494a35 (from 055c7160ab34b2062c1ca1da5141ac02b25a7062)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jun 24 18:28:53 2007 +0200

    initialize the movie created with createEmptyMovieClip()
    
    Otherwise he won't have the right prototype set in actionscript, which
    would make it impossible to call any function on it.

diff --git a/libswfdec/swfdec_sprite_movie_as.c b/libswfdec/swfdec_sprite_movie_as.c
index 7cd80ec..fd3a601 100644
--- a/libswfdec/swfdec_sprite_movie_as.c
+++ b/libswfdec/swfdec_sprite_movie_as.c
@@ -286,6 +286,7 @@ swfdec_sprite_movie_createEmptyMovieClip
   if (movie)
     swfdec_movie_remove (movie);
   movie = swfdec_movie_new (SWFDEC_PLAYER (cx), depth, parent, NULL, name);
+  swfdec_movie_initialize (movie);
   SWFDEC_AS_VALUE_SET_OBJECT (rval, SWFDEC_AS_OBJECT (movie));
 }
 
diff-tree 055c7160ab34b2062c1ca1da5141ac02b25a7062 (from 3f21f4a288e09a03206ff52f1e3fd5496233a7f1)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jun 24 18:27:44 2007 +0200

    add a crude hack so MovieClip-only properties only exist on movielcips

diff --git a/libswfdec/swfdec_movie_asprops.c b/libswfdec/swfdec_movie_asprops.c
index e9fef7d..cf9102e 100644
--- a/libswfdec/swfdec_movie_asprops.c
+++ b/libswfdec/swfdec_movie_asprops.c
@@ -347,34 +347,35 @@ mc_root (SwfdecMovie *movie, SwfdecAsVal
 }
 
 struct {
+  gboolean needs_movie;
   const char *name;
   void (* get) (SwfdecMovie *movie, SwfdecAsValue *ret);
   void (* set) (SwfdecMovie *movie, const SwfdecAsValue *val);
 } swfdec_movieclip_props[] = {
-  { SWFDEC_AS_STR__x,		mc_x_get,	    mc_x_set },
-  { SWFDEC_AS_STR__y,		mc_y_get,	    mc_y_set },
-  { SWFDEC_AS_STR__xscale,	mc_xscale_get,	    mc_xscale_set },
-  { SWFDEC_AS_STR__yscale,	mc_yscale_get,	    mc_yscale_set },
-  { SWFDEC_AS_STR__currentframe,mc_currentframe,    NULL },
-  { SWFDEC_AS_STR__totalframes,	mc_totalframes,	    NULL },
-  { SWFDEC_AS_STR__alpha,	mc_alpha_get,	    mc_alpha_set },
-  { SWFDEC_AS_STR__visible,	mc_visible_get,	    mc_visible_set },
-  { SWFDEC_AS_STR__width,	mc_width_get,	    mc_width_set },
-  { SWFDEC_AS_STR__height,	mc_height_get,	    mc_height_set },
-  { SWFDEC_AS_STR__rotation,	mc_rotation_get,    mc_rotation_set },
-  { SWFDEC_AS_STR__target,	NULL,  NULL }, //"_target"
-  { SWFDEC_AS_STR__framesloaded,mc_framesloaded,    NULL},
-  { SWFDEC_AS_STR__name,	mc_name_get,	    mc_name_set },
-  { SWFDEC_AS_STR__droptarget,	NULL,  NULL }, //"_droptarget"
-  { SWFDEC_AS_STR__url,		NULL,  NULL }, //"_url"
-  { SWFDEC_AS_STR__highquality,	NULL,  NULL }, //"_highquality"
-  { SWFDEC_AS_STR__focusrect,	NULL,  NULL }, //"_focusrect"
-  { SWFDEC_AS_STR__soundbuftime,NULL,  NULL }, //"_soundbuftime"
-  { SWFDEC_AS_STR__quality,	NULL,  NULL }, //"_quality"
-  { SWFDEC_AS_STR__xmouse,	mc_xmouse_get,	    NULL },
-  { SWFDEC_AS_STR__ymouse,	mc_ymouse_get,	    NULL },
-  { SWFDEC_AS_STR__parent,	mc_parent,	    NULL },
-  { SWFDEC_AS_STR__root,	mc_root,	    NULL },
+  { 0, SWFDEC_AS_STR__x,		mc_x_get,	    mc_x_set },
+  { 0, SWFDEC_AS_STR__y,		mc_y_get,	    mc_y_set },
+  { 0, SWFDEC_AS_STR__xscale,	mc_xscale_get,	    mc_xscale_set },
+  { 0, SWFDEC_AS_STR__yscale,	mc_yscale_get,	    mc_yscale_set },
+  { 1, SWFDEC_AS_STR__currentframe,mc_currentframe,    NULL },
+  { 1, SWFDEC_AS_STR__totalframes,	mc_totalframes,	    NULL },
+  { 0, SWFDEC_AS_STR__alpha,	mc_alpha_get,	    mc_alpha_set },
+  { 0, SWFDEC_AS_STR__visible,	mc_visible_get,	    mc_visible_set },
+  { 0, SWFDEC_AS_STR__width,	mc_width_get,	    mc_width_set },
+  { 0, SWFDEC_AS_STR__height,	mc_height_get,	    mc_height_set },
+  { 0, SWFDEC_AS_STR__rotation,	mc_rotation_get,    mc_rotation_set },
+  { 1, SWFDEC_AS_STR__target,	NULL,  NULL }, //"_target"
+  { 1, SWFDEC_AS_STR__framesloaded,mc_framesloaded,    NULL},
+  { 0, SWFDEC_AS_STR__name,	mc_name_get,	    mc_name_set },
+  { 1, SWFDEC_AS_STR__droptarget,	NULL,  NULL }, //"_droptarget"
+  { 0, SWFDEC_AS_STR__url,		NULL,  NULL }, //"_url"
+  { 0, SWFDEC_AS_STR__highquality,	NULL,  NULL }, //"_highquality"
+  { 0, SWFDEC_AS_STR__focusrect,	NULL,  NULL }, //"_focusrect"
+  { 0, SWFDEC_AS_STR__soundbuftime,NULL,  NULL }, //"_soundbuftime"
+  { 0, SWFDEC_AS_STR__quality,	NULL,  NULL }, //"_quality"
+  { 0, SWFDEC_AS_STR__xmouse,	mc_xmouse_get,	    NULL },
+  { 0, SWFDEC_AS_STR__ymouse,	mc_ymouse_get,	    NULL },
+  { 0, SWFDEC_AS_STR__parent,	mc_parent,	    NULL },
+  { 0, SWFDEC_AS_STR__root,	mc_root,	    NULL },
 };
 
 static inline int
@@ -387,6 +388,8 @@ swfdec_movie_get_asprop_index (SwfdecMov
 
   for (i = 0; i < G_N_ELEMENTS (swfdec_movieclip_props); i++) {
     if (swfdec_movieclip_props[i].name == name) {
+      if (swfdec_movieclip_props[i].needs_movie && !SWFDEC_IS_SPRITE_MOVIE (movie))
+	return -1;
       if (swfdec_movieclip_props[i].get == NULL) {
 	SWFDEC_ERROR ("property %s not implemented", name);
       }
diff-tree 3f21f4a288e09a03206ff52f1e3fd5496233a7f1 (from b5472cbe1dd631b9c0d0c2e36dc93f83b1db4108)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jun 24 18:27:12 2007 +0200

    make swfdec_movie_initialize() work with non-sprite movies

diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index d42aac3..457644e 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -555,24 +555,27 @@ static void
 swfdec_sprite_movie_init_movie (SwfdecMovie *mov)
 {
   SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);
-  SwfdecAsContext *context;
-  SwfdecAsObject *constructor;
-  const char *name;
+  SwfdecAsContext *context = SWFDEC_AS_OBJECT (movie)->context;
+  SwfdecAsObject *constructor = NULL;
 
-  g_assert (movie->sprite->parse_frame > 0);
   g_assert (mov->swf != NULL);
 
-  movie->n_frames = movie->sprite->n_frames;
-  name = swfdec_swf_instance_get_export_name (mov->swf,
-      SWFDEC_CHARACTER (movie->sprite));
-  context = SWFDEC_AS_OBJECT (movie)->context;
-  if (name != NULL) {
-    name = swfdec_as_context_get_string (context, name);
-    constructor = swfdec_player_get_export_class (SWFDEC_PLAYER (context),
-      name);
-  } else {
-    constructor = SWFDEC_PLAYER (context)->MovieClip;
+  if (movie->sprite) {
+    const char *name;
+
+    g_assert (movie->sprite->parse_frame > 0);
+    movie->n_frames = movie->sprite->n_frames;
+    name = swfdec_swf_instance_get_export_name (mov->swf,
+	SWFDEC_CHARACTER (movie->sprite));
+    if (name != NULL) {
+      name = swfdec_as_context_get_string (context, name);
+      constructor = swfdec_player_get_export_class (SWFDEC_PLAYER (context),
+	  name);
+    }
   }
+  if (constructor == NULL)
+    constructor = SWFDEC_PLAYER (context)->MovieClip;
+
   swfdec_as_object_set_constructor (SWFDEC_AS_OBJECT (movie), constructor, FALSE);
   swfdec_sprite_movie_goto (movie, 1);
   if (!swfdec_sprite_movie_iterate_end (mov)) {
diff-tree b5472cbe1dd631b9c0d0c2e36dc93f83b1db4108 (from 0e96b023aba5b5548d22679a5fdffcc0ebce13e5)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jun 24 17:40:00 2007 +0200

    rework movie->frame and movie->n_frames
    
    - move frame handling from SwfdecMovie to SwfdecSpriteMovie
    - make movie->frame 1-indexed - or better: make it report the same value as
      _currentframe, which can be 0 for movies created via createEmptyMovieClip ()
    
    This patch might introduce subtle off-by-one bugs for goto actions. I think
    I caught them all and the testsuite passes, but who knows...

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 7fc4ae6..e09b09f 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -50,7 +50,7 @@
 #define swfdec_action_has_register(cx, i) \
   ((i) < (cx)->frame->n_registers)
 
-static SwfdecMovie *
+static SwfdecSpriteMovie *
 swfdec_action_get_target (SwfdecAsContext *context)
 {
   SwfdecAsObject *target = context->frame->target;
@@ -62,11 +62,11 @@ swfdec_action_get_target (SwfdecAsContex
     g_assert (SWFDEC_IS_AS_FRAME (scope));
     target = SWFDEC_AS_FRAME (scope)->thisp;
   }
-  if (!SWFDEC_IS_MOVIE (target)) {
+  if (!SWFDEC_IS_SPRITE_MOVIE (target)) {
     SWFDEC_ERROR ("no valid target");
     return NULL;
   }
-  return SWFDEC_MOVIE (target);
+  return SWFDEC_SPRITE_MOVIE (target);
 }
 
 /*** ALL THE ACTION IS HERE ***/
@@ -74,9 +74,9 @@ swfdec_action_get_target (SwfdecAsContex
 static void
 swfdec_action_stop (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
-  SwfdecMovie *movie = swfdec_action_get_target (cx);
+  SwfdecSpriteMovie *movie = swfdec_action_get_target (cx);
   if (movie)
-    movie->stopped = TRUE;
+    movie->playing = FALSE;
   else
     SWFDEC_ERROR ("no movie to stop");
 }
@@ -84,9 +84,9 @@ swfdec_action_stop (SwfdecAsContext *cx,
 static void
 swfdec_action_play (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
-  SwfdecMovie *movie = swfdec_action_get_target (cx);
+  SwfdecSpriteMovie *movie = swfdec_action_get_target (cx);
   if (movie)
-    movie->stopped = FALSE;
+    movie->playing = TRUE;
   else
     SWFDEC_ERROR ("no movie to play");
 }
@@ -94,10 +94,10 @@ swfdec_action_play (SwfdecAsContext *cx,
 static void
 swfdec_action_next_frame (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
-  SwfdecMovie *movie = swfdec_action_get_target (cx);
+  SwfdecSpriteMovie *movie = swfdec_action_get_target (cx);
   if (movie) {
-    if (movie->frame + 1 < movie->n_frames) {
-      swfdec_movie_goto (movie, movie->frame + 1);
+    if (movie->frame < movie->n_frames) {
+      swfdec_sprite_movie_goto (movie, movie->frame + 1);
     } else {
       SWFDEC_INFO ("can't execute nextFrame, already at last frame");
     }
@@ -109,10 +109,10 @@ swfdec_action_next_frame (SwfdecAsContex
 static void
 swfdec_action_previous_frame (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
-  SwfdecMovie *movie = swfdec_action_get_target (cx);
+  SwfdecSpriteMovie *movie = swfdec_action_get_target (cx);
   if (movie) {
-    if (movie->frame > 0) {
-      swfdec_movie_goto (movie, movie->frame - 1);
+    if (movie->frame > 1) {
+      swfdec_sprite_movie_goto (movie, movie->frame - 1);
     } else {
       SWFDEC_INFO ("can't execute previousFrame, already at first frame");
     }
@@ -124,7 +124,7 @@ swfdec_action_previous_frame (SwfdecAsCo
 static void
 swfdec_action_goto_frame (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
-  SwfdecMovie *movie = swfdec_action_get_target (cx);
+  SwfdecSpriteMovie *movie = swfdec_action_get_target (cx);
   guint frame;
 
   if (len != 2) {
@@ -133,8 +133,8 @@ swfdec_action_goto_frame (SwfdecAsContex
   }
   frame = GUINT16_FROM_LE (*((guint16 *) data));
   if (movie) {
-    swfdec_movie_goto (movie, frame);
-    movie->stopped = TRUE;
+    swfdec_sprite_movie_goto (movie, frame + 1);
+    movie->playing = FALSE;
   } else {
     SWFDEC_ERROR ("no movie to goto on");
   }
@@ -143,51 +143,53 @@ swfdec_action_goto_frame (SwfdecAsContex
 static void
 swfdec_action_goto_label (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
-  SwfdecMovie *movie = swfdec_action_get_target (cx);
+  SwfdecSpriteMovie *movie = swfdec_action_get_target (cx);
 
   if (!memchr (data, 0, len)) {
     SWFDEC_ERROR ("GotoLabel action does not specify a string");
     return;
   }
 
-  if (SWFDEC_IS_SPRITE_MOVIE (movie)) {
-    int frame = swfdec_sprite_get_frame (SWFDEC_SPRITE_MOVIE (movie)->sprite, (const char *) data);
-    if (frame == -1)
+  if (movie) {
+    int frame;
+    if (movie->sprite == NULL ||
+	(frame = swfdec_sprite_get_frame (movie->sprite, (const char *) data)) == -1)
       return;
-    swfdec_movie_goto (movie, frame);
-    movie->stopped = TRUE;
+    swfdec_sprite_movie_goto (movie, frame + 1);
+    movie->playing = FALSE;
   } else {
     SWFDEC_ERROR ("no movie to goto on");
   }
 }
 
-static int
-swfdec_value_to_frame (SwfdecAsContext *cx, SwfdecMovie *movie, SwfdecAsValue *val)
+/* returns: frame to go to or 0 on error */
+static guint
+swfdec_value_to_frame (SwfdecAsContext *cx, SwfdecSpriteMovie *movie, SwfdecAsValue *val)
 {
   int frame;
 
+  if (movie->sprite == NULL)
+    return 0;
   if (SWFDEC_AS_VALUE_IS_STRING (val)) {
     const char *name = SWFDEC_AS_VALUE_GET_STRING (val);
     double d;
-    if (!SWFDEC_IS_SPRITE_MOVIE (movie))
-      return -1;
     if (strchr (name, ':')) {
       SWFDEC_ERROR ("FIXME: handle targets");
     }
     /* treat valid encoded numbers as numbers, otherwise assume it's a frame label */
     d = swfdec_as_value_to_number (cx, val);
     if (isnan (d))
-      frame = swfdec_sprite_get_frame (SWFDEC_SPRITE_MOVIE (movie)->sprite, name);
+      frame = swfdec_sprite_get_frame (movie->sprite, name) + 1;
     else
-      frame = d - 1;
+      frame = d;
   } else if (SWFDEC_AS_VALUE_IS_NUMBER (val)) {
-    return (int) SWFDEC_AS_VALUE_GET_NUMBER (val) - 1;
+    frame = swfdec_as_value_to_integer (cx, val);
   } else {
     SWFDEC_WARNING ("cannot convert value to frame number");
     /* FIXME: how do we treat undefined etc? */
-    frame = -1;
+    frame = 0;
   }
-  return frame;
+  return frame <= 0 ? 0 : frame;
 }
 
 static void
@@ -197,7 +199,7 @@ swfdec_action_goto_frame2 (SwfdecAsConte
   guint bias;
   gboolean play;
   SwfdecAsValue *val;
-  SwfdecMovie *movie;
+  SwfdecSpriteMovie *movie;
 
   swfdec_bits_init_data (&bits, data, len);
   if (swfdec_bits_getbits (&bits, 6)) {
@@ -212,12 +214,12 @@ swfdec_action_goto_frame2 (SwfdecAsConte
   movie = swfdec_action_get_target (cx);
   /* now set it */
   if (movie) {
-    int frame = swfdec_value_to_frame (cx, movie, val);
-    if (frame >= 0) {
+    guint frame = swfdec_value_to_frame (cx, movie, val);
+    if (frame > 0) {
       frame += bias;
-      frame = CLAMP (frame, 0, (int) movie->n_frames - 1);
-      swfdec_movie_goto (movie, frame);
-      movie->stopped = !play;
+      frame = CLAMP (frame, 1, movie->n_frames);
+      swfdec_sprite_movie_goto (movie, frame);
+      movie->playing = play;
     }
   } else {
     SWFDEC_ERROR ("no movie to GotoFrame2 on");
@@ -286,7 +288,7 @@ swfdec_action_wait_for_frame2 (SwfdecAsC
 static void
 swfdec_action_wait_for_frame (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
-  SwfdecMovie *movie;
+  SwfdecSpriteMovie *movie;
   guint frame, jump, loaded;
 
   if (len != 3) {
@@ -301,8 +303,8 @@ swfdec_action_wait_for_frame (SwfdecAsCo
 
   frame = GUINT16_FROM_LE (*((guint16 *) data));
   jump = data[2];
-  if (SWFDEC_MOVIE (movie->swf->movie) == movie) {
-    SwfdecDecoder *dec = movie->swf->decoder;
+  if (SWFDEC_MOVIE (movie)->swf->movie == movie) {
+    SwfdecDecoder *dec = SWFDEC_MOVIE (movie)->swf->decoder;
     loaded = dec->frames_loaded;
     g_assert (loaded <= movie->n_frames);
   } else {
@@ -881,7 +883,7 @@ swfdec_action_increment (SwfdecAsContext
 static void
 swfdec_action_get_url (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
-  SwfdecMovie *movie;
+  SwfdecSpriteMovie *movie;
   SwfdecBits bits;
   char *url, *target;
 
@@ -899,7 +901,7 @@ swfdec_action_get_url (SwfdecAsContext *
   }
   movie = swfdec_action_get_target (cx);
   if (movie)
-    swfdec_movie_load (movie, url, target);
+    swfdec_movie_load (SWFDEC_MOVIE (movie), url, target);
   else
     SWFDEC_WARNING ("no movie to load");
   g_free (url);
@@ -911,7 +913,7 @@ swfdec_action_get_url2 (SwfdecAsContext 
 {
   const char *target, *url;
   guint method;
-  SwfdecMovie *movie;
+  SwfdecSpriteMovie *movie;
 
   if (len != 1) {
     SWFDEC_ERROR ("GetURL2 requires 1 byte of data, not %u", len);
@@ -935,7 +937,7 @@ swfdec_action_get_url2 (SwfdecAsContext 
   }
   movie = swfdec_action_get_target (cx);
   if (movie)
-    swfdec_movie_load (movie, url, target);
+    swfdec_movie_load (SWFDEC_MOVIE (movie), url, target);
   else
     SWFDEC_WARNING ("no movie to load");
 }
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 51d0bbd..0b0d463 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -57,7 +57,6 @@ swfdec_movie_init (SwfdecMovie * movie)
   swfdec_color_transform_init_identity (&movie->original_ctrans);
 
   movie->visible = TRUE;
-  movie->n_frames = 1;
 
   swfdec_rect_init_empty (&movie->extents);
 }
@@ -1045,19 +1044,6 @@ swfdec_movie_load (SwfdecMovie *movie, c
   swfdec_player_launch (player, url, target);
 }
 
-void
-swfdec_movie_goto (SwfdecMovie *movie, guint frame)
-{
-  SwfdecMovieClass *klass;
-
-  g_return_if_fail (SWFDEC_IS_MOVIE (movie));
-  g_return_if_fail (frame < movie->n_frames);
-
-  klass = SWFDEC_MOVIE_GET_CLASS (movie);
-  if (klass->goto_frame)
-    klass->goto_frame (movie, frame);
-}
-
 char *
 swfdec_movie_get_path (SwfdecMovie *movie)
 {
diff --git a/libswfdec/swfdec_movie.h b/libswfdec/swfdec_movie.h
index 2d3f20d..a347951 100644
--- a/libswfdec/swfdec_movie.h
+++ b/libswfdec/swfdec_movie.h
@@ -115,9 +115,6 @@ struct _SwfdecMovie {
   SwfdecColorTransform	color_transform;	/* scripted color transformation */
 
   /* iteration state */
-  guint			frame;			/* current frame */
-  guint			n_frames;		/* amount of frames */
-  gboolean		stopped;		/* if we currently iterate */
   gboolean		visible;		/* whether we currently can be seen or iterate */
   gboolean		will_be_removed;	/* it's known that this movie will not survive the next iteration */
 
@@ -156,8 +153,6 @@ struct _SwfdecMovieClass {
 						 int			button);
 
   /* iterating */
-  void			(* goto_frame)		(SwfdecMovie *		movie,
-						 guint			frame);
   void			(* iterate_start)     	(SwfdecMovie *		movie);
   gboolean		(* iterate_end)		(SwfdecMovie *		movie);
 };
@@ -207,8 +202,6 @@ void		swfdec_movie_render		(SwfdecMovie 
 						 const SwfdecColorTransform *trans,
 						 const SwfdecRect *	inval,
 						 gboolean		fill);
-void		swfdec_movie_goto		(SwfdecMovie *		movie,
-						 guint			frame);
 void		swfdec_movie_execute_script	(SwfdecMovie *		movie,
 						 SwfdecEventType	condition);
 gboolean      	swfdec_movie_queue_script	(SwfdecMovie *		movie,
diff --git a/libswfdec/swfdec_movie_asprops.c b/libswfdec/swfdec_movie_asprops.c
index 2288b0a..e9fef7d 100644
--- a/libswfdec/swfdec_movie_asprops.c
+++ b/libswfdec/swfdec_movie_asprops.c
@@ -133,21 +133,19 @@ mc_yscale_set (SwfdecMovie *movie, const
 static void
 mc_currentframe (SwfdecMovie *movie, SwfdecAsValue *rval)
 {
-  SWFDEC_AS_VALUE_SET_NUMBER (rval, movie->frame + 1);
+  g_assert (SWFDEC_IS_SPRITE_MOVIE (movie));
+  SWFDEC_AS_VALUE_SET_NUMBER (rval, SWFDEC_SPRITE_MOVIE (movie)->frame);
 }
 
 static void
 mc_framesloaded (SwfdecMovie *mov, SwfdecAsValue *rval)
 {
-  /* only root movies can be partially loaded */
-  if (SWFDEC_IS_SPRITE_MOVIE (mov)) {
-    SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);
-    if (movie->sprite) {
-      SWFDEC_AS_VALUE_SET_NUMBER (rval, movie->sprite->parse_frame);
-      return;
-    }
+  SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);
+  if (movie->sprite) {
+    SWFDEC_AS_VALUE_SET_NUMBER (rval, movie->sprite->parse_frame);
+    return;
   }
-  SWFDEC_AS_VALUE_SET_NUMBER (rval, mov->n_frames);
+  SWFDEC_AS_VALUE_SET_INT (rval, movie->n_frames);
 }
 
 static void
@@ -165,7 +163,8 @@ mc_name_set (SwfdecMovie *movie, const S
 static void
 mc_totalframes (SwfdecMovie *movie, SwfdecAsValue *rval)
 {
-  SWFDEC_AS_VALUE_SET_NUMBER (rval, movie->n_frames);
+  g_assert (SWFDEC_IS_SPRITE_MOVIE (movie));
+  SWFDEC_AS_VALUE_SET_INT (rval, SWFDEC_SPRITE_MOVIE (movie)->n_frames);
 }
 
 static void
diff --git a/libswfdec/swfdec_sprite.c b/libswfdec/swfdec_sprite.c
index fb3b111..c525fc1 100644
--- a/libswfdec/swfdec_sprite.c
+++ b/libswfdec/swfdec_sprite.c
@@ -218,21 +218,6 @@ swfdec_sprite_set_n_frames (SwfdecSprite
   SWFDEC_LOG ("n_frames = %d", sprite->n_frames);
 }
 
-guint
-swfdec_sprite_get_next_frame (SwfdecSprite *sprite, guint current_frame)
-{
-  guint next_frame;
-
-  g_return_val_if_fail (SWFDEC_IS_SPRITE (sprite), 0);
-
-  next_frame = current_frame + 1;
-  if (next_frame >= sprite->n_frames)
-    next_frame = 0;
-  if (next_frame >= sprite->parse_frame)
-    next_frame = current_frame;
-  return next_frame;
-}
-
 int
 swfdec_sprite_get_frame (SwfdecSprite *sprite, const char *label)
 {
diff --git a/libswfdec/swfdec_sprite.h b/libswfdec/swfdec_sprite.h
index 9bf1712..34a9c49 100644
--- a/libswfdec/swfdec_sprite.h
+++ b/libswfdec/swfdec_sprite.h
@@ -90,8 +90,6 @@ gboolean	swfdec_sprite_get_action	(Swfde
 						 guint			n,
 						 guint *      		tag,
 						 SwfdecBuffer **	buffer);
-guint		swfdec_sprite_get_next_frame	(SwfdecSprite *		sprite,
-						 guint			current_frame);
 int		swfdec_sprite_get_frame		(SwfdecSprite *		sprite,
 				      		 const char *		label);
 
diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index 5e96105..d42aac3 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -288,7 +288,7 @@ swfdec_sprite_movie_perform_one_action (
   swfdec_bits_init (&bits, buffer);
 
   SWFDEC_LOG ("%p: executing %uth tag %s in frame %u", movie, movie->next_action - 1, 
-      swfdec_swf_decoder_get_tag_name (tag), mov->frame);
+      swfdec_swf_decoder_get_tag_name (tag), movie->frame);
   switch (tag) {
     case SWFDEC_TAG_DOACTION:
       SWFDEC_LOG ("SCRIPT action");
@@ -318,8 +318,8 @@ swfdec_sprite_movie_perform_one_action (
       }
       return TRUE;
     case SWFDEC_TAG_SHOWFRAME:
-      if (mov->frame < mov->n_frames) {
-	mov->frame++;
+      if (movie->frame < movie->n_frames) {
+	movie->frame++;
       } else {
 	SWFDEC_ERROR ("too many ShowFrame tags");
       }
@@ -344,53 +344,51 @@ swfdec_movie_is_compatible (SwfdecMovie 
   return TRUE;
 }
 
-static void
-swfdec_sprite_movie_goto (SwfdecMovie *mov, guint goto_frame)
+void
+swfdec_sprite_movie_goto (SwfdecSpriteMovie *movie, guint goto_frame)
 {
-  SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);
+  SwfdecMovie *mov;
   SwfdecPlayer *player;
   GList *old;
   guint n;
 
-  g_assert (goto_frame < mov->n_frames);
-  if (goto_frame >= movie->sprite->parse_frame) {
+  g_return_if_fail (SWFDEC_IS_SPRITE_MOVIE (movie));
+
+  mov = SWFDEC_MOVIE (movie);
+  /* lots of things where we've got nothing to do */
+  if (goto_frame == 0 || goto_frame > movie->n_frames || 
+      movie->sprite == NULL || mov->will_be_removed || goto_frame == movie->frame)
+    return;
+
+  if (goto_frame > movie->sprite->parse_frame) {
     SWFDEC_WARNING ("jumping to not-yet-loaded frame %u (loaded: %u/%u)",
 	goto_frame, movie->sprite->parse_frame, movie->sprite->n_frames);
     return;
   }
 
-  if (mov->will_be_removed)
-    return;
-  if (goto_frame == mov->frame)
-    return;
-
-  player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (mov)->context);
-  SWFDEC_LOG ("doing goto %u for %p %d", goto_frame, mov, 
-      SWFDEC_CHARACTER (SWFDEC_SPRITE_MOVIE (mov)->sprite)->id);
+  player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context);
+  SWFDEC_LOG ("doing goto %u for %p %d", goto_frame, movie, 
+      SWFDEC_CHARACTER (movie->sprite)->id);
 
   SWFDEC_DEBUG ("performing goto %u -> %u for character %u", 
-      mov->frame, goto_frame, SWFDEC_CHARACTER (movie->sprite)->id);
-  if (goto_frame < mov->frame) {
-    /* this path is also taken on init */
-    mov->frame = 0;
+      movie->frame, goto_frame, SWFDEC_CHARACTER (movie->sprite)->id);
+  if (goto_frame < movie->frame) {
+    movie->frame = 0;
     old = mov->list;
     mov->list = NULL;
-    n = goto_frame + 1;
+    n = goto_frame;
     movie->next_action = 0;
   } else {
+    /* NB: this path is also taken on init */
     old = NULL;
-    n = goto_frame - mov->frame;
-    mov->frame++;
+    n = goto_frame - movie->frame;
   }
-  /* from here on, mov->frame is 1-indexed */
-  if (movie->sprite == NULL)
-    return;
   while (n) {
     guint tag;
     SwfdecBuffer *buffer;
     /* FIXME: These actions should probably just be added to the action queue */
     if (movie == mov->swf->movie &&
-	mov->swf->parse_frame <= mov->frame)
+	mov->swf->parse_frame <= movie->frame)
       swfdec_swf_instance_advance (mov->swf);
     if (!swfdec_sprite_get_action (movie->sprite, movie->next_action, &tag, &buffer))
       break;
@@ -398,12 +396,6 @@ swfdec_sprite_movie_goto (SwfdecMovie *m
     if (!swfdec_sprite_movie_perform_one_action (movie, tag, buffer, n > 1))
       n--;
   }
-  /* now make mov->frame 0-indexed again */
-  if (mov->frame) {
-    mov->frame--;
-  } else {
-    SWFDEC_FIXME ("how to handle movies without a ShowFrame tag?");
-  }
   /* now try to copy eventual movies */
   if (old) {
     SwfdecMovie *prev, *cur;
@@ -479,12 +471,18 @@ swfdec_sprite_movie_iterate (SwfdecMovie
     return;
 
   swfdec_player_add_action (player, movie, swfdec_sprite_movie_do_enter_frame, NULL);
-  if (!mov->stopped && movie->sprite != NULL) {
-    goto_frame = swfdec_sprite_get_next_frame (movie->sprite, mov->frame);
-    swfdec_sprite_movie_goto (mov, goto_frame);
+  if (movie->playing && movie->sprite != NULL) {
+    if (movie->frame == movie->n_frames)
+      goto_frame = 1;
+    else if (movie->sprite && movie->frame == movie->sprite->parse_frame)
+      goto_frame = movie->frame;
+    else
+      goto_frame = movie->frame + 1;
+    swfdec_sprite_movie_goto (movie, goto_frame);
   }
 }
 
+/* FIXME: This function is a mess */
 static gboolean
 swfdec_sprite_movie_iterate_end (SwfdecMovie *mov)
 {
@@ -494,7 +492,6 @@ swfdec_sprite_movie_iterate_end (SwfdecM
   GSList *walk;
   SwfdecPlayer *player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (mov)->context);
 
-  g_assert (mov->frame < mov->n_frames);
   if (!SWFDEC_MOVIE_CLASS (swfdec_sprite_movie_parent_class)->iterate_end (mov)) {
     g_assert (movie->sound_stream == NULL);
     return FALSE;
@@ -502,10 +499,11 @@ swfdec_sprite_movie_iterate_end (SwfdecM
   
   if (movie->sprite == NULL)
     return TRUE;
-  current = &movie->sprite->frames[mov->frame];
+  g_assert (movie->frame <= movie->n_frames);
+  current = &movie->sprite->frames[movie->frame - 1];
   /* first start all event sounds */
   /* FIXME: is this correct? */
-  if (movie->sound_frame != mov->frame) {
+  if (movie->sound_frame != movie->frame) {
     for (walk = current->sound; walk; walk = walk->next) {
       SwfdecAudio *audio = swfdec_audio_event_new (player, walk->data);
       if (audio)
@@ -515,7 +513,7 @@ swfdec_sprite_movie_iterate_end (SwfdecM
 
   /* then do the streaming thing */
   if (current->sound_head == NULL ||
-      SWFDEC_MOVIE (movie)->stopped) {
+      !movie->playing) {
     if (movie->sound_stream) {
       swfdec_audio_remove (movie->sound_stream);
       g_object_unref (movie->sound_stream);
@@ -525,8 +523,8 @@ swfdec_sprite_movie_iterate_end (SwfdecM
   }
   if (movie->sound_stream == NULL && current->sound_block == NULL)
     goto exit;
-  SWFDEC_LOG ("iterating audio (from %u to %u)", movie->sound_frame, mov->frame);
-  if (movie->sound_frame + 1 != mov->frame)
+  SWFDEC_LOG ("iterating audio (from %u to %u)", movie->sound_frame, movie->frame);
+  if (movie->sound_frame + 1 != movie->frame)
     goto new_decoder;
   if (movie->sound_frame == (guint) -1)
     goto new_decoder;
@@ -536,7 +534,7 @@ swfdec_sprite_movie_iterate_end (SwfdecM
   if (last->sound_head != current->sound_head)
     goto new_decoder;
 exit:
-  movie->sound_frame = mov->frame;
+  movie->sound_frame = movie->frame;
   return TRUE;
 
 new_decoder:
@@ -547,8 +545,8 @@ new_decoder:
 
   if (current->sound_block) {
     movie->sound_stream = swfdec_audio_stream_new (player, 
-	movie->sprite, mov->frame);
-    movie->sound_frame = mov->frame;
+	movie->sprite, movie->frame);
+    movie->sound_frame = movie->frame;
   }
   return TRUE;
 }
@@ -564,7 +562,7 @@ swfdec_sprite_movie_init_movie (SwfdecMo
   g_assert (movie->sprite->parse_frame > 0);
   g_assert (mov->swf != NULL);
 
-  mov->n_frames = movie->sprite->n_frames;
+  movie->n_frames = movie->sprite->n_frames;
   name = swfdec_swf_instance_get_export_name (mov->swf,
       SWFDEC_CHARACTER (movie->sprite));
   context = SWFDEC_AS_OBJECT (movie)->context;
@@ -576,7 +574,7 @@ swfdec_sprite_movie_init_movie (SwfdecMo
     constructor = SWFDEC_PLAYER (context)->MovieClip;
   }
   swfdec_as_object_set_constructor (SWFDEC_AS_OBJECT (movie), constructor, FALSE);
-  swfdec_sprite_movie_goto (mov, 0);
+  swfdec_sprite_movie_goto (movie, 1);
   if (!swfdec_sprite_movie_iterate_end (mov)) {
     g_assert_not_reached ();
   }
@@ -659,7 +657,6 @@ swfdec_sprite_movie_class_init (SwfdecSp
 
   movie_class->init_movie = swfdec_sprite_movie_init_movie;
   movie_class->finish_movie = swfdec_sprite_movie_finish_movie;
-  movie_class->goto_frame = swfdec_sprite_movie_goto;
   movie_class->iterate_start = swfdec_sprite_movie_iterate;
   movie_class->iterate_end = swfdec_sprite_movie_iterate_end;
 }
@@ -667,9 +664,6 @@ swfdec_sprite_movie_class_init (SwfdecSp
 static void
 swfdec_sprite_movie_init (SwfdecSpriteMovie * movie)
 {
-  SwfdecMovie *mov = SWFDEC_MOVIE (movie);
-
-  mov->frame = (guint) -1;
-  movie->sound_frame = (guint) -1;
+  movie->playing = TRUE;
 }
 
diff --git a/libswfdec/swfdec_sprite_movie.h b/libswfdec/swfdec_sprite_movie.h
index 9db258a..6f1b570 100644
--- a/libswfdec/swfdec_sprite_movie.h
+++ b/libswfdec/swfdec_sprite_movie.h
@@ -44,6 +44,9 @@ struct _SwfdecSpriteMovie
 
   /* frame information */
   guint			next_action;	/* next action in sprite to perform */
+  guint			frame;		/* current frame */
+  guint			n_frames;	/* amount of frames */
+  gboolean		playing;	/* TRUE if the movie automatically advances */
 
   /* color information */
   SwfdecColor		bg_color;	/* background color (only used on main sprite) */
@@ -60,6 +63,9 @@ struct _SwfdecSpriteMovieClass
 
 GType		swfdec_sprite_movie_get_type		(void);
 
+void		swfdec_sprite_movie_goto		(SwfdecSpriteMovie *	movie,
+							 guint			goto_frame);
+
 
 G_END_DECLS
 #endif
diff --git a/libswfdec/swfdec_sprite_movie_as.c b/libswfdec/swfdec_sprite_movie_as.c
index e173701..7cd80ec 100644
--- a/libswfdec/swfdec_sprite_movie_as.c
+++ b/libswfdec/swfdec_sprite_movie_as.c
@@ -37,14 +37,14 @@ static void
 swfdec_sprite_movie_play (SwfdecAsContext *cx, SwfdecAsObject *obj,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
 {
-  SWFDEC_MOVIE (obj)->stopped = FALSE;
+  SWFDEC_SPRITE_MOVIE (obj)->playing = TRUE;
 }
 
 static void
 swfdec_sprite_movie_stop (SwfdecAsContext *cx, SwfdecAsObject *obj,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
 {
-  SWFDEC_MOVIE (obj)->stopped = TRUE;
+  SWFDEC_SPRITE_MOVIE (obj)->playing = FALSE;
 }
 
 static void
@@ -91,13 +91,13 @@ swfdec_sprite_movie_getNextHighestDepth 
 }
 
 static void
-swfdec_sprite_movie_do_goto (SwfdecMovie *movie, SwfdecAsValue *target)
+swfdec_sprite_movie_do_goto (SwfdecSpriteMovie *movie, SwfdecAsValue *target)
 {
   int frame;
 
   if (SWFDEC_AS_VALUE_IS_STRING (target)) {
     const char *label = SWFDEC_AS_VALUE_GET_STRING (target);
-    frame = swfdec_sprite_get_frame (SWFDEC_SPRITE_MOVIE (movie)->sprite, label);
+    frame = swfdec_sprite_get_frame (movie->sprite, label);
     /* FIXME: nonexisting frames? */
     if (frame == -1)
       return;
@@ -106,51 +106,49 @@ swfdec_sprite_movie_do_goto (SwfdecMovie
     frame = swfdec_as_value_to_integer (SWFDEC_AS_OBJECT (movie)->context, target);
   }
   /* FIXME: how to handle overflow? */
-  frame = CLAMP (frame, 1, (int) movie->n_frames) - 1;
+  frame = CLAMP (frame, 1, (int) movie->n_frames);
 
-  swfdec_movie_goto (movie, frame);
+  swfdec_sprite_movie_goto (movie, frame);
 }
 
 static void
 swfdec_sprite_movie_gotoAndPlay (SwfdecAsContext *cx, SwfdecAsObject *obj,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
 {
-  SwfdecMovie *movie = SWFDEC_MOVIE (obj);
+  SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (obj);
   
   swfdec_sprite_movie_do_goto (movie, &argv[0]);
-  movie->stopped = FALSE;
+  movie->playing = TRUE;
 }
 
 static void
 swfdec_sprite_movie_gotoAndStop (SwfdecAsContext *cx, SwfdecAsObject *obj,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
 {
-  SwfdecMovie *movie = SWFDEC_MOVIE (obj);
+  SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (obj);
   
   swfdec_sprite_movie_do_goto (movie, &argv[0]);
-  movie->stopped = TRUE;
+  movie->playing = FALSE;
 }
 
 static void
 swfdec_sprite_movie_nextFrame (SwfdecAsContext *cx, SwfdecAsObject *obj,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
 {
-  SwfdecMovie *movie = SWFDEC_MOVIE (obj);
+  SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (obj);
   
-  if (movie->frame + 1 < movie->n_frames)
-    swfdec_movie_goto (movie, movie->frame + 1);
-  movie->stopped = TRUE;
+  swfdec_sprite_movie_goto (movie, movie->frame + 1);
+  movie->playing = FALSE;
 }
 
 static void
 swfdec_sprite_movie_prevFrame (SwfdecAsContext *cx, SwfdecAsObject *obj,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
 {
-  SwfdecMovie *movie = SWFDEC_MOVIE (obj);
+  SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (obj);
   
-  if (movie->frame > 0)
-    swfdec_movie_goto (movie, movie->frame - 1);
-  movie->stopped = TRUE;
+  swfdec_sprite_movie_goto (movie, movie->frame - 1);
+  movie->playing = FALSE;
 }
 
 static void


More information about the Swfdec mailing list