⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swfdec_sprite_movie.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 2 页
字号:
  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 + -