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

📄 swfdec_sprite_movie.c

📁 Swfdec is a decoder/renderer for Macromedia Flash animations. The decoding and rendering engine is
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 <strings.h>#include "swfdec_sprite_movie.h"#include "swfdec_as_internal.h"#include "swfdec_as_strings.h"#include "swfdec_audio_event.h"#include "swfdec_audio_stream.h"#include "swfdec_debug.h"#include "swfdec_graphic_movie.h"#include "swfdec_player_internal.h"#include "swfdec_ringbuffer.h"#include "swfdec_script.h"#include "swfdec_sprite.h"#include "swfdec_swf_instance.h"#include "swfdec_tag.h"#include "swfdec_utils.h"/*** SWFDEC_SPRITE_MOVIE ***/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_as_object_run (movie, data);}static cairo_operator_tswfdec_sprite_convert_operator (guint operator){  return CAIRO_OPERATOR_OVER;}static intswfdec_get_clipeventflags (SwfdecMovie *movie, SwfdecBits * bits){  if (SWFDEC_SWF_DECODER (movie->swf->decoder)->version <= 5) {    return swfdec_bits_get_u16 (bits);  } else {    return swfdec_bits_get_u32 (bits);  }}static gbooleanswfdec_sprite_movie_perform_place (SwfdecSpriteMovie *movie, SwfdecBits *bits, guint tag){  SwfdecPlayer *player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context);  SwfdecMovie *mov = SWFDEC_MOVIE (movie);  SwfdecMovie *cur;  gboolean has_clip_actions;  gboolean has_clip_depth;  gboolean has_name;  gboolean has_ratio;  gboolean has_ctrans;  gboolean has_transform;  gboolean has_character;  gboolean move;  gboolean depth;  gboolean cache;  gboolean has_blend_mode = 0;  gboolean has_filter = 0;  int clip_depth;  cairo_matrix_t transform;  SwfdecColorTransform ctrans;  guint ratio, id, version;  SwfdecEventList *events;  const char *name;  SwfdecGraphic *graphic;  version = SWFDEC_SWF_DECODER (mov->swf->decoder)->version;  /* 1) check which stuff is set */  has_clip_actions = swfdec_bits_getbit (bits);  has_clip_depth = swfdec_bits_getbit (bits);  has_name = swfdec_bits_getbit (bits);  has_ratio = swfdec_bits_getbit (bits);  has_ctrans = swfdec_bits_getbit (bits);  has_transform = swfdec_bits_getbit (bits);  has_character = swfdec_bits_getbit (bits);  move = swfdec_bits_getbit (bits);  SWFDEC_LOG ("performing PlaceObject%d on movie %s", tag == SWFDEC_TAG_PLACEOBJECT2 ? 2 : 3, mov->name);  SWFDEC_LOG ("  has_clip_actions = %d", has_clip_actions);  SWFDEC_LOG ("  has_clip_depth = %d", has_clip_depth);  SWFDEC_LOG ("  has_name = %d", has_name);  SWFDEC_LOG ("  has_ratio = %d", has_ratio);  SWFDEC_LOG ("  has_ctrans = %d", has_ctrans);  SWFDEC_LOG ("  has_transform = %d", has_transform);  SWFDEC_LOG ("  has_character = %d", has_character);  SWFDEC_LOG ("  move = %d", move);  if (tag == SWFDEC_TAG_PLACEOBJECT3) {    swfdec_bits_getbits (bits, 5);    cache = swfdec_bits_getbit (bits);    has_blend_mode = swfdec_bits_getbit (bits);    has_filter = swfdec_bits_getbit (bits);    SWFDEC_LOG ("  cache = %d", cache);    SWFDEC_LOG ("  has filter = %d", has_filter);    SWFDEC_LOG ("  has blend mode = %d", has_blend_mode);  }  /* 2) read all properties */  depth = swfdec_bits_get_u16 (bits);  if (depth >= 16384) {    SWFDEC_FIXME ("depth of placement too high: %u >= 16384", depth);  }  SWFDEC_LOG ("  depth = %d (=> %d)", depth, depth - 16384);  depth -= 16384;  if (has_character) {    id = swfdec_bits_get_u16 (bits);    SWFDEC_LOG ("  id = %d", id);  } else {    id = 0;  }  if (has_transform) {    swfdec_bits_get_matrix (bits, &transform, NULL);    SWFDEC_LOG ("  matrix = { %g %g, %g %g } + { %g %g }", 	transform.xx, transform.yx,	transform.xy, transform.yy,	transform.x0, transform.y0);  }  if (has_ctrans) {    swfdec_bits_get_color_transform (bits, &ctrans);    SWFDEC_LOG ("  color transform = %d %d  %d %d  %d %d  %d %d",	ctrans.ra, ctrans.rb,	ctrans.ga, ctrans.gb,	ctrans.ba, ctrans.bb,	ctrans.aa, ctrans.ab);  }  if (has_ratio) {    ratio = swfdec_bits_get_u16 (bits);    SWFDEC_LOG ("  ratio = %d", ratio);  } else {    ratio = -1;  }  if (has_name) {    char *s = swfdec_bits_get_string_with_version (bits, version);    name = swfdec_as_context_give_string (SWFDEC_AS_CONTEXT (player), s);    SWFDEC_LOG ("  name = %s", name);  } else {    name = NULL;  }  if (has_clip_depth) {    clip_depth = swfdec_bits_get_u16 (bits) - 16384;    SWFDEC_LOG ("  clip_depth = %d (=> %d)", clip_depth + 16384, clip_depth);  } else {    clip_depth = 0;  }  if (has_filter)    swfdec_filters_parse (bits);  if (has_blend_mode) {    /* FIXME: implement */    guint operator = swfdec_bits_get_u8 (bits);    swfdec_sprite_convert_operator (operator);    SWFDEC_ERROR ("  operator = %u", operator);  }  if (has_clip_actions) {    int reserved, clip_event_flags, event_flags, key_code;    char *script_name;    events = swfdec_event_list_new (player);    reserved = swfdec_bits_get_u16 (bits);    clip_event_flags = swfdec_get_clipeventflags (mov, bits);    if (name)      script_name = g_strdup (name);    else if (id)      script_name = g_strdup_printf ("Sprite%u", id);    else      script_name = g_strdup ("unknown");    while ((event_flags = swfdec_get_clipeventflags (mov, bits)) != 0) {      guint length = swfdec_bits_get_u32 (bits);      SwfdecBits action_bits;      swfdec_bits_init_bits (&action_bits, bits, length);      if (event_flags & SWFDEC_EVENT_KEY_PRESS)	key_code = swfdec_bits_get_u8 (&action_bits);      else	key_code = 0;      SWFDEC_INFO ("clip event with flags 0x%X, key code %d", event_flags, key_code);#define SWFDEC_IMPLEMENTED_EVENTS \  (SWFDEC_EVENT_LOAD | SWFDEC_EVENT_UNLOAD | SWFDEC_EVENT_ENTER | SWFDEC_EVENT_INITIALIZE | SWFDEC_EVENT_CONSTRUCT | \   SWFDEC_EVENT_MOUSE_DOWN | SWFDEC_EVENT_MOUSE_MOVE | SWFDEC_EVENT_MOUSE_UP)      if (event_flags & ~SWFDEC_IMPLEMENTED_EVENTS) {	SWFDEC_ERROR ("using non-implemented clip events %u", event_flags & ~SWFDEC_IMPLEMENTED_EVENTS);      }      swfdec_event_list_parse (events, &action_bits, version, 	  event_flags, key_code, script_name);      if (swfdec_bits_left (&action_bits)) {	SWFDEC_ERROR ("not all action data was parsed: %u bytes left",	    swfdec_bits_left (&action_bits));      }    }    g_free (script_name);  } else {    events = NULL;  }  /* 3) perform the actions depending on the set properties */  cur = swfdec_movie_find (mov, depth);  graphic = swfdec_swf_decoder_get_character (SWFDEC_SWF_DECODER (mov->swf->decoder), id);  if (move) {    if (cur == NULL) {      SWFDEC_INFO ("no movie at depth %d, ignoring move command", depth);      goto out;    }    if (graphic) {      SwfdecMovieClass *klass = SWFDEC_MOVIE_GET_CLASS (cur);      if (klass->replace)	klass->replace (cur, graphic);    }    swfdec_movie_set_static_properties (cur, has_transform ? &transform : NULL, 	has_ctrans ? &ctrans : NULL, ratio, clip_depth, events);  } else {    if (cur != NULL && version > 5) {      SWFDEC_INFO ("depth %d is already occupied by movie %s, not placing", depth, cur->name);      goto out;    }    if (!SWFDEC_IS_GRAPHIC (graphic)) {      SWFDEC_FIXME ("character %u is not a graphic (does it even exist?), aborting", id);      if (events)	swfdec_event_list_free (events);      return FALSE;    }    cur = swfdec_movie_new (player, depth, mov, graphic, name);    swfdec_movie_set_static_properties (cur, has_transform ? &transform : NULL, 	has_ctrans ? &ctrans : NULL, ratio, clip_depth, events);    if (SWFDEC_IS_SPRITE_MOVIE (cur)) {      g_queue_push_tail (player->init_queue, cur);      g_queue_push_tail (player->construct_queue, cur);      swfdec_movie_queue_script (cur, SWFDEC_EVENT_LOAD);    }    swfdec_movie_initialize (cur);  }out:  if (events)    swfdec_event_list_free (events);  return TRUE;}static gbooleanswfdec_sprite_movie_perform_one_action (SwfdecSpriteMovie *movie, guint tag, SwfdecBuffer *buffer,    gboolean skip_scripts){  SwfdecMovie *mov = SWFDEC_MOVIE (movie);  SwfdecPlayer *player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (mov)->context);  SwfdecBits bits;  g_assert (mov->swf);  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), movie->frame);  switch (tag) {    case SWFDEC_TAG_DOACTION:      SWFDEC_LOG ("SCRIPT action");      if (!skip_scripts) {	SwfdecScript *script = swfdec_swf_decoder_get_script (	    SWFDEC_SWF_DECODER (mov->swf->decoder), buffer->data);	g_assert (script);	swfdec_player_add_action (player, mov, swfdec_sprite_movie_run_script, script);      }      return TRUE;    case SWFDEC_TAG_PLACEOBJECT2:    case SWFDEC_TAG_PLACEOBJECT3:      return swfdec_sprite_movie_perform_place (movie, &bits, tag);    case SWFDEC_TAG_REMOVEOBJECT:      /* yes, this code is meant to be like this - the following u16 is the        * character id, that we don't care about, the rest is like RemoveObject2       */      swfdec_bits_get_u16 (&bits);      /* fall through */    case SWFDEC_TAG_REMOVEOBJECT2:      {	int depth = swfdec_bits_get_u16 (&bits);	SWFDEC_LOG ("REMOVE action: depth %d => %d", depth, depth - 16384);	depth -= 16384;	if (!swfdec_sprite_movie_remove_child (mov, depth))	  SWFDEC_INFO ("could not remove, no child at depth %d", depth);      }      return TRUE;    case SWFDEC_TAG_SHOWFRAME:      if (movie->frame < movie->n_frames) {	movie->frame++;      } else {	SWFDEC_ERROR ("too many ShowFrame tags");      }      return FALSE;    default:      g_assert_not_reached ();      return FALSE;  }}static gbooleanswfdec_movie_is_compatible (SwfdecMovie *movie, SwfdecMovie *with){  g_assert (movie->depth == with->depth);  if (movie->original_ratio != with->original_ratio)    return FALSE;  if (G_OBJECT_TYPE (movie) != G_OBJECT_TYPE (with))    return FALSE;  return TRUE;}static GList *my_g_list_split (GList *list, GList *split){  GList *prev;

⌨️ 快捷键说明

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