Benjamin Otte
2007-Jun-27 07:29 UTC
[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
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 at 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
Reasonably Related Threads
- Branch 'as' - 8 commits - libswfdec/swfdec_movie.c libswfdec/swfdec_sprite.c libswfdec/swfdec_sprite.h libswfdec/swfdec_sprite_movie.c libswfdec/swfdec_sprite_movie.h libswfdec/swfdec_swf_decoder.c libswfdec/swfdec_swf_decoder.h
- 11 commits - libswfdec/swfdec_debugger.c libswfdec/swfdec_debugger.h libswfdec/swfdec_event.c libswfdec/swfdec_js_movie.c libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_net_stream.c libswfdec/swfdec_player.c
- 7 commits - doc/swfdec-sections.txt libswfdec-gtk/swfdec_gtk_widget.c libswfdec/swfdec_as_strings.c libswfdec/swfdec_decoder.c libswfdec/swfdec_flv_decoder.c libswfdec/swfdec_movie_asprops.c libswfdec/swfdec_net_stream.c libswfdec/swfdec_player.c
- Branch 'as' - 6 commits - libswfdec/swfdec_as_array.c libswfdec/swfdec_button_movie.c libswfdec/swfdec_morph_movie.c libswfdec/swfdec_movie_asprops.c libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_player.c libswfdec/swfdec_sprite.c
- 6 commits - libswfdec/swfdec_as_interpret.c libswfdec/swfdec_event.c libswfdec/swfdec_event.h libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_resource.c