📄 swfdec_sprite_movie.c
字号:
if (split == NULL) return list; prev = split->prev; if (prev == NULL) return NULL; prev->next = NULL; split->prev = NULL; return list;}voidswfdec_sprite_movie_goto (SwfdecSpriteMovie *movie, guint goto_frame){ SwfdecMovie *mov; SwfdecPlayer *player; GList *old; guint n; 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; } 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", movie->frame, goto_frame, SWFDEC_CHARACTER (movie->sprite)->id); if (goto_frame < movie->frame) { GList *walk; movie->frame = 0; for (walk = mov->list; walk && swfdec_depth_classify (SWFDEC_MOVIE (walk->data)->depth) != SWFDEC_DEPTH_CLASS_TIMELINE; walk = walk->next) { /* do nothing */ } old = walk; mov->list = my_g_list_split (mov->list, old); for (walk = old; walk && swfdec_depth_classify (SWFDEC_MOVIE (walk->data)->depth) == SWFDEC_DEPTH_CLASS_TIMELINE; walk = walk->next) { /* do nothing */ } old = my_g_list_split (old, walk); mov->list = g_list_concat (mov->list, walk); n = goto_frame; movie->next_action = 0; } else { /* NB: this path is also taken on init */ old = NULL; n = goto_frame - movie->frame; } 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 <= movie->frame) swfdec_swf_instance_advance (mov->swf); if (!swfdec_sprite_get_action (movie->sprite, movie->next_action, &tag, &buffer)) break; movie->next_action++; if (!swfdec_sprite_movie_perform_one_action (movie, tag, buffer, n > 1)) n--; } /* now try to copy eventual movies */ if (old) { SwfdecMovie *prev, *cur; GList *old_walk, *walk; walk = mov->list; old_walk = old; if (!walk) goto out; cur = walk->data; for (; old_walk; old_walk = old_walk->next) { prev = old_walk->data; while (cur->depth < prev->depth) { walk = walk->next; if (!walk) goto out; cur = walk->data; } if (cur->depth == prev->depth && swfdec_movie_is_compatible (prev, cur)) { SwfdecMovieClass *klass = SWFDEC_MOVIE_GET_CLASS (prev); walk->data = prev; /* FIXME: This merging stuff probably needs to be improved a _lot_ */ if (klass->replace) klass->replace (prev, cur->graphic); swfdec_movie_set_static_properties (prev, &cur->original_transform, &cur->original_ctrans, cur->original_ratio, cur->clip_depth, cur->events); swfdec_movie_destroy (cur); cur = prev; continue; } swfdec_movie_remove (prev); }out: for (; old_walk; old_walk = old_walk->next) { swfdec_movie_remove (old_walk->data); } g_list_free (old); }}/*** MOVIE ***/G_DEFINE_TYPE (SwfdecSpriteMovie, swfdec_sprite_movie, SWFDEC_TYPE_MOVIE)static voidswfdec_sprite_movie_dispose (GObject *object){ SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (object); g_assert (movie->sound_stream == NULL); G_OBJECT_CLASS (swfdec_sprite_movie_parent_class)->dispose (object);}static voidswfdec_sprite_movie_do_enter_frame (gpointer movie, gpointer unused){ if (SWFDEC_MOVIE (movie)->will_be_removed) return; swfdec_movie_execute_script (movie, SWFDEC_EVENT_ENTER);}static voidswfdec_sprite_movie_iterate (SwfdecMovie *mov){ SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov); SwfdecPlayer *player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (mov)->context); guint goto_frame; if (mov->will_be_removed) return; swfdec_player_add_action (player, movie, swfdec_sprite_movie_do_enter_frame, NULL); 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 gbooleanswfdec_sprite_movie_iterate_end (SwfdecMovie *mov){ SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov); SwfdecSpriteFrame *last; SwfdecSpriteFrame *current; GSList *walk; SwfdecPlayer *player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (mov)->context); if (!SWFDEC_MOVIE_CLASS (swfdec_sprite_movie_parent_class)->iterate_end (mov)) { g_assert (movie->sound_stream == NULL); return FALSE; } if (movie->sprite == NULL) return TRUE; g_assert (movie->frame <= movie->n_frames); if (movie->frame == 0) { SWFDEC_WARNING ("not at first frame yet"); return TRUE; } current = &movie->sprite->frames[movie->frame - 1]; /* first start all event sounds */ /* FIXME: is this correct? */ 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) g_object_unref (audio); } } /* then do the streaming thing */ if (current->sound_head == NULL || !movie->playing) { if (movie->sound_stream) { swfdec_audio_remove (movie->sound_stream); g_object_unref (movie->sound_stream); movie->sound_stream = NULL; } goto exit; } if (movie->sound_stream == NULL && current->sound_block == NULL) goto exit; 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; if (current->sound_head && movie->sound_stream == NULL) goto new_decoder; last = &movie->sprite->frames[movie->sound_frame]; if (last->sound_head != current->sound_head) goto new_decoder;exit: movie->sound_frame = movie->frame; return TRUE;new_decoder: if (movie->sound_stream) { swfdec_audio_remove (movie->sound_stream); g_object_unref (movie->sound_stream); movie->sound_stream = NULL; } if (current->sound_block) { movie->sound_stream = swfdec_audio_stream_new (player, movie->sprite, movie->frame); movie->sound_frame = movie->frame; } return TRUE;}static voidswfdec_sprite_movie_init_movie (SwfdecMovie *mov){ SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov); SwfdecAsContext *context = SWFDEC_AS_OBJECT (movie)->context; SwfdecAsObject *constructor = NULL; g_assert (mov->swf != NULL); 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); swfdec_sprite_movie_goto (movie, 1); if (!swfdec_sprite_movie_iterate_end (mov)) { g_assert_not_reached (); }}static voidswfdec_sprite_movie_finish_movie (SwfdecMovie *mov){ SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov); SwfdecPlayer *player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (mov)->context); swfdec_player_remove_all_actions (player, mov); if (movie->sound_stream) { swfdec_audio_remove (movie->sound_stream); g_object_unref (movie->sound_stream); movie->sound_stream = NULL; }}static SwfdecMovie *swfdec_sprite_movie_get_by_name (SwfdecMovie *movie, const char *name){ GList *walk; guint version = SWFDEC_AS_OBJECT (movie)->context->version; for (walk = movie->list; walk; walk = walk->next) { SwfdecMovie *cur = walk->data; if (cur->original_name == SWFDEC_AS_STR_EMPTY) continue; if ((version >= 7 && cur->name == name) || swfdec_str_case_equal (cur->name, name)) return cur; } return NULL;}static gbooleanswfdec_sprite_movie_get_variable (SwfdecAsObject *object, SwfdecAsObject *orig, const char *variable, SwfdecAsValue *val, guint *flags){ SwfdecMovie *movie; if (SWFDEC_AS_OBJECT_CLASS (swfdec_sprite_movie_parent_class)->get (object, orig, variable, val, flags)) return TRUE; movie = swfdec_sprite_movie_get_by_name (SWFDEC_MOVIE (object), variable); if (movie == NULL) return FALSE; SWFDEC_AS_VALUE_SET_OBJECT (val, SWFDEC_AS_OBJECT (movie)); *flags = 0; return TRUE;}static voidswfdec_sprite_movie_mark (SwfdecAsObject *object){ GList *walk; for (walk = SWFDEC_MOVIE (object)->list; walk; walk = walk->next) { SwfdecAsObject *child = walk->data; g_assert (child->properties != NULL); swfdec_as_object_mark (child); } SWFDEC_AS_OBJECT_CLASS (swfdec_sprite_movie_parent_class)->mark (object);}static voidswfdec_sprite_movie_class_init (SwfdecSpriteMovieClass * g_class){ GObjectClass *object_class = G_OBJECT_CLASS (g_class); SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (g_class); SwfdecMovieClass *movie_class = SWFDEC_MOVIE_CLASS (g_class); object_class->dispose = swfdec_sprite_movie_dispose; asobject_class->get = swfdec_sprite_movie_get_variable; asobject_class->mark = swfdec_sprite_movie_mark; movie_class->init_movie = swfdec_sprite_movie_init_movie; movie_class->finish_movie = swfdec_sprite_movie_finish_movie; movie_class->iterate_start = swfdec_sprite_movie_iterate; movie_class->iterate_end = swfdec_sprite_movie_iterate_end;}static voidswfdec_sprite_movie_init (SwfdecSpriteMovie * movie){ movie->playing = TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -