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

📄 gameswf_impl.cpp

📁 一个开源的嵌入式flash播放器的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// gameswf_impl.cpp	-- Thatcher Ulrich <tu@tulrich.com> 2003// This source code has been donated to the Public Domain.  Do// whatever you want with it.// Some implementation for SWF player.// Useful links://// http://sswf.sourceforge.net/SWFalexref.html// http://www.openswf.org// @@ Need to break this file into pieces#include "base/tu_file.h"#include "base/utility.h"#include "gameswf_action.h"#include "gameswf_button.h"#include "gameswf_impl.h"#include "gameswf_font.h"#include "gameswf_fontlib.h"#include "gameswf_log.h"#include "gameswf_morph2.h"#include "gameswf_render.h"#include "gameswf_shape.h"#include "gameswf_stream.h"#include "gameswf_styles.h"#include "gameswf_dlist.h"#include "gameswf_timers.h"#include "base/image.h"#include "base/jpeg.h"#include "base/zlib_adapter.h"#include <string.h>	// for memset#include <typeinfo>#include <float.h>#if TU_CONFIG_LINK_TO_ZLIB#include <zlib.h>#endif // TU_CONFIG_LINK_TO_ZLIBnamespace gameswf{	bool	s_verbose_action = false;	bool	s_verbose_parse = false;#ifndef NDEBUG	bool	s_verbose_debug = true;#else	bool	s_verbose_debug = false;#endif	void	set_verbose_action(bool verbose)	// Enable/disable log messages re: actions.	{		s_verbose_action = verbose;	}	void	set_verbose_parse(bool verbose)	// Enable/disable log messages re: parsing the movie.	{		s_verbose_parse = verbose;	}	static bool	s_use_cache_files = true;	void	set_use_cache_files(bool use_cache)	// Enable/disable attempts to read cache files when loading	// movies.	{		s_use_cache_files = use_cache;	}	// Keep a table of loader functions for the different tag types.	static hash<int, loader_function>	s_tag_loaders;	void	register_tag_loader(int tag_type, loader_function lf)	// Associate the specified tag type with the given tag loader	// function.	{		assert(s_tag_loaders.get(tag_type, NULL) == false);		assert(lf != NULL);		s_tag_loaders.add(tag_type, lf);	}	//	// file_opener callback stuff	//	static file_opener_callback	s_opener_function = NULL;	void	register_file_opener_callback(file_opener_callback opener)	// Host calls this to register a function for opening files,	// for loading movies.	{		s_opener_function = opener;	}	//	// progress callback stuff (from Vitaly)	//	static progress_callback	s_progress_function = NULL;	void	register_progress_callback(progress_callback progress_handle)	// Host calls this to register a function for progress bar handling	// during loading movies.	{		s_progress_function = progress_handle;	}		//	// some utility stuff	//	static void	execute_actions(as_environment* env, const array<action_buffer*>& action_list)	// Execute the actions in the action list, in the given	// environment.	{		for (int i = 0; i < action_list.size(); i++)		{			action_list[i]->execute(env);		}	}	static void	dump_tag_bytes(stream* in)	// Log the contents of the current tag, in hex.	{		static const int	ROW_BYTES = 16;		char	row_buf[ROW_BYTES];		int	row_count = 0;		while(in->get_position() < in->get_tag_end_position())		{			int	c = in->read_u8();			log_msg("%02X", c);			if (c < 32) c = '.';			if (c > 127) c = '.';			row_buf[row_count] = c;						row_count++;			if (row_count >= ROW_BYTES)			{				log_msg("    ");				for (int i = 0; i < ROW_BYTES; i++)				{					log_msg("%c", row_buf[i]);				}				log_msg("\n");				row_count = 0;			}			else			{				log_msg(" ");			}		}		if (row_count > 0)		{			log_msg("\n");		}	}	character*	character_def::create_character_instance(movie* parent, int id)	// Default.  Make a generic_character.	{		return new generic_character(this, parent, id);	}	//	// ref_counted	//	ref_counted::ref_counted()		:		m_ref_count(0),		m_weak_proxy(0)	{	}	ref_counted::~ref_counted()	{		assert(m_ref_count == 0);		if (m_weak_proxy)		{			m_weak_proxy->notify_object_died();			m_weak_proxy->drop_ref();		}	}	void	ref_counted::add_ref() const	{		assert(m_ref_count >= 0);		m_ref_count++;	}	void	ref_counted::drop_ref() const	{		assert(m_ref_count > 0);		m_ref_count--;		if (m_ref_count <= 0)		{			// Delete me!			delete this;		}	}	weak_proxy* ref_counted::get_weak_proxy() const	{		assert(m_ref_count > 0);	// By rights, somebody should be holding a ref to us.		if (m_weak_proxy == NULL)		{			m_weak_proxy = new weak_proxy;			m_weak_proxy->add_ref();		}		return m_weak_proxy;	}	//	// character	//	void	character::do_mouse_drag()	// Implement mouse-dragging for this movie.	{		drag_state	st;		get_drag_state(&st);		if (this == st.m_character)		{			// We're being dragged!			int	x, y, buttons;			get_root_movie()->get_mouse_state(&x, &y, &buttons);			point	world_mouse(PIXELS_TO_TWIPS(x), PIXELS_TO_TWIPS(y));			if (st.m_bound)			{				// Clamp mouse coords within a defined rect.				world_mouse.m_x =					fclamp(world_mouse.m_x, st.m_bound_x0, st.m_bound_x1);				world_mouse.m_y =					fclamp(world_mouse.m_y, st.m_bound_y0, st.m_bound_y1);			}			if (st.m_lock_center)			{				matrix	world_mat = get_world_matrix();				point	local_mouse;				world_mat.transform_by_inverse(&local_mouse, world_mouse);				matrix	parent_world_mat;				if (m_parent)				{					parent_world_mat = m_parent->get_world_matrix();				}				point	parent_mouse;				parent_world_mat.transform_by_inverse(&parent_mouse, world_mouse);									// Place our origin so that it coincides with the mouse coords				// in our parent frame.				matrix	local = get_matrix();				local.m_[0][2] = parent_mouse.m_x;				local.m_[1][2] = parent_mouse.m_y;				set_matrix(local);			}			else			{				// Implement relative drag...			}		}	}	//	// Helper for movie_def_impl	//	struct import_info	{		tu_string	m_source_url;		int	        m_character_id;		tu_string	m_symbol;		import_info()			:			m_character_id(-1)		{		}		import_info(const char* source, int id, const char* symbol)			:			m_source_url(source),			m_character_id(id),			m_symbol(symbol)		{		}	};	//	// movie_def_impl	//	// This class holds the immutable definition of a movie's	// contents.  It cannot be played directly, and does not hold	// current state; for that you need to call create_instance()	// to get a movie_instance.	//	struct movie_def_impl : public movie_definition_sub	{		hash<int, smart_ptr<character_def> >	m_characters;		hash<int, smart_ptr<font> >	 m_fonts;		hash<int, smart_ptr<bitmap_character_def> >	m_bitmap_characters;		hash<int, smart_ptr<sound_sample> >	m_sound_samples;		array<array<execute_tag*> >	   m_playlist;	// A list of movie control events for each frame.		array<array<execute_tag*> >	   m_init_action_list;	// Init actions for each frame.		stringi_hash<int>	           m_named_frames;	// 0-based frame #'s		stringi_hash<smart_ptr<resource> > m_exports;		// Items we import.		array<import_info>	m_imports;		// Movies we import from; hold a ref on these, to keep them alive		array<smart_ptr<movie_definition> >	m_import_source_movies;		// Bitmaps used in this movie; collected in one place to make		// it possible for the host to manage them as textures.		array<smart_ptr<bitmap_info> >	m_bitmap_list;		create_bitmaps_flag	m_create_bitmaps;		create_font_shapes_flag	m_create_font_shapes;		rect	m_frame_size;		float	m_frame_rate;		int	m_frame_count;		int	m_version;		int	m_loading_frame;		uint32	m_file_length;		jpeg::input*	m_jpeg_in;		movie_def_impl(create_bitmaps_flag cbf, create_font_shapes_flag cfs)			:			m_create_bitmaps(cbf),			m_create_font_shapes(cfs),			m_frame_rate(30.0f),			m_frame_count(0),			m_version(0),			m_loading_frame(0),			m_jpeg_in(0)		{		}		~movie_def_impl()		{			// Release our playlist data.			{for (int i = 0, n = m_playlist.size(); i < n; i++)			{				for (int j = 0, m = m_playlist[i].size(); j < m; j++)				{					delete m_playlist[i][j];				}			}}			// Release init action data.			{for (int i = 0, n = m_init_action_list.size(); i < n; i++)			{				for (int j = 0, m = m_init_action_list[i].size(); j < m; j++)				{					delete m_init_action_list[i][j];				}			}}			assert(m_jpeg_in == NULL);	// It's supposed to be cleaned up in read()		}		movie_interface*	create_instance();		// ...		int	get_frame_count() const { return m_frame_count; }		float	get_frame_rate() const { return m_frame_rate; }		float	get_width_pixels() const { return ceilf(TWIPS_TO_PIXELS(m_frame_size.width())); }		float	get_height_pixels() const { return ceilf(TWIPS_TO_PIXELS(m_frame_size.height())); }		virtual int	get_version() const { return m_version; }		virtual int	get_loading_frame() const { return m_loading_frame; }		uint32	get_file_bytes() const { return m_file_length; }		/* movie_def_impl */		virtual create_bitmaps_flag	get_create_bitmaps() const		// Returns DO_CREATE_BITMAPS if we're supposed to		// initialize our bitmap infos, or DO_NOT_INIT_BITMAPS		// if we're supposed to create blank placeholder		// bitmaps (to be init'd later explicitly by the host		// program).		{			return m_create_bitmaps;		}		/* movie_def_impl */		virtual create_font_shapes_flag	get_create_font_shapes() const		// Returns DO_LOAD_FONT_SHAPES if we're supposed to		// initialize our font shape info, or		// DO_NOT_LOAD_FONT_SHAPES if we're supposed to not		// create any (vector) font glyph shapes, and instead		// rely on precached textured fonts glyphs.		{			return m_create_font_shapes;		}		virtual void	add_bitmap_info(bitmap_info* bi)		// All bitmap_info's used by this movie should be		// registered with this API.		{			m_bitmap_list.push_back(bi);		}		virtual int	get_bitmap_info_count() const { return m_bitmap_list.size(); }		virtual bitmap_info*	get_bitmap_info(int i) const		{			return m_bitmap_list[i].get_ptr();		}		virtual void	export_resource(const tu_string& symbol, resource* res)		// Expose one of our resources under the given symbol,		// for export.  Other movies can import it.		{			// SWF sometimes exports the same thing more than once!			m_exports.set(symbol, res);		}		virtual smart_ptr<resource>	get_exported_resource(const tu_string& symbol)		// Get the named exported resource, if we expose it.		// Otherwise return NULL.		{			smart_ptr<resource>	res;			m_exports.get(symbol, &res);			return res;		}		virtual void	add_import(const char* source_url, int id, const char* symbol)		// Adds an entry to a table of resources that need to		// be imported from other movies.  Client code must		// call resolve_import() later, when the source movie		// has been loaded, so that the actual resource can be		// used.		{			assert(in_import_table(id) == false);			m_imports.push_back(import_info(source_url, id, symbol));		}		bool	in_import_table(int character_id)		// Debug helper; returns true if the given		// character_id is listed in the import table.		{			for (int i = 0, n = m_imports.size(); i < n; i++)			{				if (m_imports[i].m_character_id == character_id)				{					return true;				}			}			return false;		}		virtual void	visit_imported_movies(import_visitor* visitor)		// Calls back the visitor for each movie that we		// import symbols from.		{			stringi_hash<bool>	visited;	// ugh!			for (int i = 0, n = m_imports.size(); i < n; i++)			{				import_info&	inf = m_imports[i];				if (visited.find(inf.m_source_url) == visited.end())				{					// Call back the visitor.					visitor->visit(inf.m_source_url.c_str());					visited.set(inf.m_source_url, true);				}			}		}		virtual void	resolve_import(const char* source_url, movie_definition* source_movie)		// Grabs the stuff we want from the source movie.		{			// @@ should be safe, but how can we verify			// it?  Compare a member function pointer, or			// something?			movie_def_impl*	def_impl = static_cast<movie_def_impl*>(source_movie);			movie_definition_sub*	def = static_cast<movie_definition_sub*>(def_impl);			// Iterate in reverse, since we remove stuff along the way.			for (int i = m_imports.size() - 1; i >= 0; i--)			{				const import_info&	inf = m_imports[i];				if (inf.m_source_url == source_url)				{					// Do the import.

⌨️ 快捷键说明

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