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

📄 swfdec_sprite_movie.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
字号:
/* Swfdec * Copyright (C) 2006 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor,  * Boston, MA  02110-1301  USA */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "swfdec_sprite_movie.h"#include "swfdec_audio_event.h"#include "swfdec_audio_stream.h"#include "swfdec_debug.h"#include "swfdec_js.h"#include "swfdec_player_internal.h"#include "swfdec_ringbuffer.h"#include "swfdec_root_movie.h"#include "swfdec_script.h"#include "swfdec_sprite.h"/*** SWFDEC_SPRITE_MOVIE ***/static SwfdecMovie *swfdec_sprite_movie_find (GList *movie_list, int depth){  GList *walk;  for (walk = movie_list; walk; walk = walk->next) {    SwfdecMovie *movie = walk->data;    if (movie->depth < depth)      continue;    if (movie->depth == depth)      return movie;    break;  }  return NULL;}static gbooleanswfdec_sprite_movie_remove_child (SwfdecMovie *movie, int depth){  SwfdecMovie *child = swfdec_movie_find (movie, depth);  if (child == NULL)    return FALSE;  swfdec_movie_remove (child);  return TRUE;}static voidswfdec_sprite_movie_run_script (gpointer movie, gpointer data){  swfdec_script_execute (data, SWFDEC_SCRIPTABLE (movie));}static voidswfdec_sprite_movie_perform_one_action (SwfdecSpriteMovie *movie, SwfdecSpriteAction *action,    gboolean skip_scripts, GList **movie_list){  SwfdecMovie *mov = SWFDEC_MOVIE (movie);  SwfdecPlayer *player = SWFDEC_ROOT_MOVIE (mov->root)->player;  SwfdecMovie *child;  SwfdecContent *content;  switch (action->type) {    case SWFDEC_SPRITE_ACTION_SCRIPT:      SWFDEC_LOG ("SCRIPT action");      if (!skip_scripts) {	swfdec_player_add_action (player, mov, swfdec_sprite_movie_run_script, action->data);      }      break;    case SWFDEC_SPRITE_ACTION_ADD:      content = action->data;      SWFDEC_LOG ("ADD action: depth %d", content->depth);      if (swfdec_sprite_movie_remove_child (mov, content->depth))	SWFDEC_DEBUG ("removed a child before adding new one");      child = swfdec_sprite_movie_find (*movie_list, content->depth);      if (child == NULL || child->content->sequence != content->sequence) {	child = swfdec_movie_new (mov, content);      } else {	swfdec_movie_set_content (child, content);	*movie_list = g_list_remove (*movie_list, child);	mov->list = g_list_insert_sorted (mov->list, child, swfdec_movie_compare_depths);      }      break;    case SWFDEC_SPRITE_ACTION_UPDATE:      content = action->data;      SWFDEC_LOG ("UPDATE action: depth %d", content->depth);      child = swfdec_movie_find (mov, content->depth);      if (child != NULL && child->content->sequence == content->sequence) {	swfdec_movie_set_content (child, content);      } else if (child) {	SWFDEC_INFO ("supposed to update depth %d, but child is in different sequence", 	    content->depth);      } else {	SWFDEC_INFO ("supposed to update depth %d, but no child", content->depth);      }      break;    case SWFDEC_SPRITE_ACTION_REMOVE:      SWFDEC_LOG ("REMOVE action: depth %d", GPOINTER_TO_INT (action->data));      if (!swfdec_sprite_movie_remove_child (mov, GPOINTER_TO_INT (action->data)))	SWFDEC_INFO ("could not remove, no child at depth %d", GPOINTER_TO_INT (action->data));      break;    default:      g_assert_not_reached ();  }}static voidswfdec_movie_tell_about_removal (SwfdecMovie *movie){  GList *walk;  if (movie->will_be_removed)    return;  movie->will_be_removed = TRUE;  for (walk = movie->list; walk; walk = walk->next) {    swfdec_movie_tell_about_removal (walk->data);  }}voidswfdec_sprite_movie_prepare (SwfdecSpriteMovie *movie){  GList *walk;  guint frame;  g_return_if_fail (SWFDEC_IS_SPRITE_MOVIE (movie));  if (SWFDEC_MOVIE (movie)->stopped ||      movie->sprite == NULL)    return;  frame = swfdec_sprite_get_next_frame (movie->sprite, SWFDEC_MOVIE (movie)->frame);  /* tell all relevant movies that they won't survive this */  for (walk = SWFDEC_MOVIE (movie)->list; walk; walk = walk->next) {    SwfdecMovie *cur = walk->data;    if (frame < cur->content->sequence->start || 	frame >= cur->content->sequence->end)      swfdec_movie_tell_about_removal (cur);  }}static voidswfdec_sprite_movie_goto (SwfdecMovie *mov, guint goto_frame){  SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);  SwfdecPlayer *player;  GList *old, *walk;  guint i, j, start;  g_assert (goto_frame < mov->n_frames);  if (mov->will_be_removed)    return;  if (goto_frame == movie->current_frame)    return;  player = SWFDEC_ROOT_MOVIE (mov->root)->player;  SWFDEC_LOG ("doing goto %u for %p %d", goto_frame, mov,       SWFDEC_CHARACTER (SWFDEC_SPRITE_MOVIE (mov)->sprite)->id);  mov->frame = goto_frame;  if (goto_frame < movie->current_frame) {    start = 0;    old = mov->list;    mov->list = NULL;  } else {    start = movie->current_frame + 1;    old = NULL;  }  movie->current_frame = goto_frame;  SWFDEC_DEBUG ("performing goto %u -> %u for character %u",       start, goto_frame, SWFDEC_CHARACTER (movie->sprite)->id);  for (i = start; i <= movie->current_frame; i++) {    SwfdecSpriteFrame *frame = &movie->sprite->frames[i];    if (SWFDEC_IS_ROOT_MOVIE (movie))      swfdec_root_movie_perform_root_actions (SWFDEC_ROOT_MOVIE (movie), i);     if (frame->actions == NULL)      continue;    for (j = 0; j < frame->actions->len; j++) {      swfdec_sprite_movie_perform_one_action (movie,	  &g_array_index (frame->actions, SwfdecSpriteAction, j),	  i != movie->current_frame, &old);    }  }  /* FIXME: not sure about the order here, might be relevant for unload events */  for (walk = old; walk; walk = walk->next) {    swfdec_movie_remove (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_iterate (SwfdecMovie *mov){  SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);  unsigned int goto_frame;  if (mov->will_be_removed)    return;  swfdec_movie_queue_script (mov, SWFDEC_EVENT_ENTER);  if (!mov->stopped) {    goto_frame = swfdec_sprite_get_next_frame (movie->sprite, mov->frame);    swfdec_sprite_movie_goto (mov, goto_frame);  }}static gbooleanswfdec_sprite_movie_iterate_end (SwfdecMovie *mov){  SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);  SwfdecSpriteFrame *last;  SwfdecSpriteFrame *current;  GSList *walk;  SwfdecPlayer *player = SWFDEC_ROOT_MOVIE (SWFDEC_MOVIE (movie)->root)->player;  current = &movie->sprite->frames[movie->current_frame];  if (!SWFDEC_MOVIE_CLASS (swfdec_sprite_movie_parent_class)->iterate_end (mov)) {    g_assert (movie->sound_stream == NULL);    return FALSE;  }    /* first start all event sounds */  /* FIXME: is this correct? */  if (movie->sound_frame != movie->current_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 ||      SWFDEC_MOVIE (movie)->stopped) {    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->current_frame);  if (movie->sound_frame + 1 != movie->current_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->current_frame;  return TRUE;new_decoder:  if (movie->sound_stream) {    swfdec_audio_remove (movie->sound_stream);    g_object_unref (movie->sound_stream);  }  movie->sound_stream = swfdec_audio_stream_new (player,       movie->sprite, movie->current_frame);  movie->sound_frame = movie->current_frame;  return TRUE;}static voidswfdec_sprite_movie_init_movie (SwfdecMovie *mov){  SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);  mov->n_frames = movie->sprite->n_frames;  swfdec_sprite_movie_goto (mov, 0);  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_ROOT_MOVIE (mov->root)->player;  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 voidswfdec_sprite_movie_class_init (SwfdecSpriteMovieClass * g_class){  GObjectClass *object_class = G_OBJECT_CLASS (g_class);  SwfdecMovieClass *movie_class = SWFDEC_MOVIE_CLASS (g_class);  object_class->dispose = swfdec_sprite_movie_dispose;  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;}static voidswfdec_sprite_movie_init (SwfdecSpriteMovie * movie){  movie->current_frame = (guint) -1;  movie->sound_frame = (guint) -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -