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

📄 gameswf_types.cpp

📁 一个开源的Flash 播放器,可以在Windows/Linux 上运行
💻 CPP
字号:
// gameswf_types.h	-- Thatcher Ulrich <tu@tulrich.com> 2003// This source code has been donated to the Public Domain.  Do// whatever you want with it.// Some basic types for gameswf.#include "gameswf_types.h"#include "gameswf_log.h"#include "gameswf_stream.h"#include "gameswf_render.h"#include "gameswf.h"#include <string.h>namespace gameswf{	//	// point	//	bool	point::bitwise_equal(const point& p) const	// Bitwise comparison; return true if *this is bitwise	// identical to p.	{		return memcmp(this, &p, sizeof(p)) == 0;	}	//	// matrix	//	matrix	matrix::identity;	matrix::matrix()	{		// Default to identity.		set_identity();	}	bool	matrix::is_valid() const	{		return isfinite(m_[0][0])			&& isfinite(m_[0][1])			&& isfinite(m_[0][2])			&& isfinite(m_[1][0])			&& isfinite(m_[1][1])			&& isfinite(m_[1][2]);	}	void	matrix::set_identity()	// Set the matrix to identity.	{		memset(&m_[0], 0, sizeof(m_));		m_[0][0] = 1;		m_[1][1] = 1;	}	void	matrix::concatenate(const matrix& m)	// Concatenate m's transform onto ours.  When	// transforming points, m happens first, then our	// original xform.	{		matrix	t;		t.m_[0][0] = m_[0][0] * m.m_[0][0] + m_[0][1] * m.m_[1][0];		t.m_[1][0] = m_[1][0] * m.m_[0][0] + m_[1][1] * m.m_[1][0];		t.m_[0][1] = m_[0][0] * m.m_[0][1] + m_[0][1] * m.m_[1][1];		t.m_[1][1] = m_[1][0] * m.m_[0][1] + m_[1][1] * m.m_[1][1];		t.m_[0][2] = m_[0][0] * m.m_[0][2] + m_[0][1] * m.m_[1][2] + m_[0][2];		t.m_[1][2] = m_[1][0] * m.m_[0][2] + m_[1][1] * m.m_[1][2] + m_[1][2];		*this = t;	}	void	matrix::concatenate_translation(float tx, float ty)	// Concatenate a translation onto the front of our	// matrix.  When transforming points, the translation	// happens first, then our original xform.	{		m_[0][2] += m_[0][0] * tx + m_[0][1] * ty;		m_[1][2] += m_[1][0] * tx + m_[1][1] * ty;	}	void	matrix::concatenate_scale(float scale)	// Concatenate a uniform scale onto the front of our	// matrix.  When transforming points, the scale	// happens first, then our original xform.	{		m_[0][0] *= scale;		m_[0][1] *= scale;		m_[1][0] *= scale;		m_[1][1] *= scale;	}	void	matrix::set_lerp(const matrix& m1, const matrix& m2, float t)	// Set this matrix to a blend of m1 and m2, parameterized by t.	{		m_[0][0] = flerp(m1.m_[0][0], m2.m_[0][0], t);		m_[1][0] = flerp(m1.m_[1][0], m2.m_[1][0], t);		m_[0][1] = flerp(m1.m_[0][1], m2.m_[0][1], t);		m_[1][1] = flerp(m1.m_[1][1], m2.m_[1][1], t);		m_[0][2] = flerp(m1.m_[0][2], m2.m_[0][2], t);		m_[1][2] = flerp(m1.m_[1][2], m2.m_[1][2], t);	}		void	matrix::set_scale_rotation(float x_scale, float y_scale, float angle)	// Set the scale & rotation part of the matrix.	// angle in radians.	{		float	cos_angle = cosf(angle);		float	sin_angle = sinf(angle);		m_[0][0] = x_scale * cos_angle;		m_[0][1] = y_scale * -sin_angle;		m_[1][0] = x_scale * sin_angle;		m_[1][1] = y_scale * cos_angle;	}	void	matrix::read(stream* in)	// Initialize from the stream.	{		in->align();		set_identity();		int	has_scale = in->read_uint(1);		if (has_scale)		{			int	scale_nbits = in->read_uint(5);			m_[0][0] = in->read_sint(scale_nbits) / 65536.0f;			m_[1][1] = in->read_sint(scale_nbits) / 65536.0f;		}		int	has_rotate = in->read_uint(1);		if (has_rotate)		{			int	rotate_nbits = in->read_uint(5);			m_[1][0] = in->read_sint(rotate_nbits) / 65536.0f;			m_[0][1] = in->read_sint(rotate_nbits) / 65536.0f;		}		int	translate_nbits = in->read_uint(5);		if (translate_nbits > 0)		{			m_[0][2] = (float) in->read_sint(translate_nbits);			m_[1][2] = (float) in->read_sint(translate_nbits);		}		//IF_VERBOSE_PARSE(log_msg("  mat: has_scale = %d, has_rotate = %d\n", has_scale, has_rotate));	}	void	matrix::print() const	// Debug log.	{		log_msg("| %4.4f %4.4f %4.4f |\n", m_[0][0], m_[0][1], TWIPS_TO_PIXELS(m_[0][2]));		log_msg("| %4.4f %4.4f %4.4f |\n", m_[1][0], m_[1][1], TWIPS_TO_PIXELS(m_[1][2]));	}	void	matrix::transform(point* result, const point& p) const	// Transform point 'p' by our matrix.  Put the result in	// *result.	{		assert(result);		result->m_x = m_[0][0] * p.m_x + m_[0][1] * p.m_y + m_[0][2];		result->m_y = m_[1][0] * p.m_x + m_[1][1] * p.m_y + m_[1][2];	}		void	matrix::transform_vector(point* result, const point& v) const	// Transform vector 'v' by our matrix. Doesn't apply translation.	// Put the result in *result.	{		assert(result);		result->m_x = m_[0][0] * v.m_x + m_[0][1] * v.m_y;		result->m_y = m_[1][0] * v.m_x + m_[1][1] * v.m_y;	}	void	matrix::transform_by_inverse(point* result, const point& p) const	// Transform point 'p' by the inverse of our matrix.  Put result in *result.	{		// @@ TODO optimize this!		matrix	m;		m.set_inverse(*this);		m.transform(result, p);	}	void	matrix::set_inverse(const matrix& m)	// Set this matrix to the inverse of the given matrix.	{		assert(this != &m);		// Invert the rotation part.		float	det = m.m_[0][0] * m.m_[1][1] - m.m_[0][1] * m.m_[1][0];		if (det == 0.0f)		{			// Not invertible.			//assert(0);	// castano: this happens sometimes! (ie. sample6.swf)			// Arbitrary fallback.			set_identity();			m_[0][2] = -m.m_[0][2];			m_[1][2] = -m.m_[1][2];		}		else		{			float	inv_det = 1.0f / det;			m_[0][0] = m.m_[1][1] * inv_det;			m_[1][1] = m.m_[0][0] * inv_det;			m_[0][1] = -m.m_[0][1] * inv_det;			m_[1][0] = -m.m_[1][0] * inv_det;			m_[0][2] = -(m_[0][0] * m.m_[0][2] + m_[0][1] * m.m_[1][2]);			m_[1][2] = -(m_[1][0] * m.m_[0][2] + m_[1][1] * m.m_[1][2]);		}	}	bool	matrix::does_flip() const	// Return true if this matrix reverses handedness.	{		float	det = m_[0][0] * m_[1][1] - m_[0][1] * m_[1][0];		return det < 0.f;	}	float	matrix::get_determinant() const	// Return the determinant of the 2x2 rotation/scale part only.	{		return m_[0][0] * m_[1][1] - m_[1][0] * m_[0][1];	}	float	matrix::get_max_scale() const	// Return the maximum scale factor that this transform	// applies.  For assessing scale, when determining acceptable	// errors in tesselation.	{		// @@ not 100% sure what the heck I'm doing here.  I		// think this is roughly what I want; take the max		// length of the two basis vectors.		float	basis0_length2 = m_[0][0] * m_[0][0] + m_[0][1] * m_[0][1];		float	basis1_length2 = m_[1][0] * m_[1][0] + m_[1][1] * m_[1][1];		float	max_length2 = fmax(basis0_length2, basis1_length2);		return sqrtf(max_length2);	}	float	matrix::get_x_scale() const	{		float	scale = sqrtf(m_[0][0] * m_[0][0] + m_[0][1] * m_[0][1]);		// Are we turned inside out?		if (get_determinant() < 0.f)		{			scale = -scale;		}		return scale;	}	float	matrix::get_y_scale() const	{		return sqrtf(m_[1][1] * m_[1][1] + m_[1][0] * m_[1][0]);	}	float	matrix::get_rotation() const	{		if (get_determinant() < 0.f)		{			// We're turned inside out; negate the			// x-component used to compute rotation.			//			// Matches get_x_scale().			//			// @@ this may not be how Macromedia does it!  Test this!			return atan2f(m_[1][0], -m_[0][0]);		}		else		{			return atan2f(m_[1][0], m_[0][0]);		}	}	//	// cxform	//	cxform	cxform::identity;	cxform::cxform()	// Initialize to identity transform.	{		m_[0][0] = 1;		m_[1][0] = 1;		m_[2][0] = 1;		m_[3][0] = 1;		m_[0][1] = 0;		m_[1][1] = 0;		m_[2][1] = 0;		m_[3][1] = 0;	}	void	cxform::concatenate(const cxform& c)	// Concatenate c's transform onto ours.  When	// transforming colors, c's transform is applied	// first, then ours.	{		m_[0][1] += m_[0][0] * c.m_[0][1];		m_[1][1] += m_[1][0] * c.m_[1][1];		m_[2][1] += m_[2][0] * c.m_[2][1];		m_[3][1] += m_[3][0] * c.m_[3][1];		m_[0][0] *= c.m_[0][0];		m_[1][0] *= c.m_[1][0];		m_[2][0] *= c.m_[2][0];		m_[3][0] *= c.m_[3][0];	}		rgba	cxform::transform(const rgba in) const	// Apply our transform to the given color; return the result.	{		rgba	result;		result.m_r = (Uint8) fclamp(in.m_r * m_[0][0] + m_[0][1], 0, 255);		result.m_g = (Uint8) fclamp(in.m_g * m_[1][0] + m_[1][1], 0, 255);		result.m_b = (Uint8) fclamp(in.m_b * m_[2][0] + m_[2][1], 0, 255);		result.m_a = (Uint8) fclamp(in.m_a * m_[3][0] + m_[3][1], 0, 255);		return result;	}	void	cxform::read_rgb(stream* in)	{		in->align();		int	has_add = in->read_uint(1);		int	has_mult = in->read_uint(1);		int	nbits = in->read_uint(4);		if (has_mult) {			m_[0][0] = in->read_sint(nbits) / 255.0f;			m_[1][0] = in->read_sint(nbits) / 255.0f;			m_[2][0] = in->read_sint(nbits) / 255.0f;			m_[3][0] = 1;		}		else {			for (int i = 0; i < 4; i++) { m_[i][0] = 1; }		}		if (has_add) {			m_[0][1] = (float) in->read_sint(nbits);			m_[1][1] = (float) in->read_sint(nbits);			m_[2][1] = (float) in->read_sint(nbits);			m_[3][1] = 1;		}		else {			for (int i = 0; i < 4; i++) { m_[i][1] = 0; }		}	}	void	cxform::read_rgba(stream* in)	{		in->align();		int	has_add = in->read_uint(1);		int	has_mult = in->read_uint(1);		int	nbits = in->read_uint(4);		if (has_mult) {			m_[0][0] = in->read_sint(nbits) / 255.0f;			m_[1][0] = in->read_sint(nbits) / 255.0f;			m_[2][0] = in->read_sint(nbits) / 255.0f;			m_[3][0] = in->read_sint(nbits) / 255.0f;		}		else {			for (int i = 0; i < 4; i++) { m_[i][0] = 1; }		}		if (has_add) {			m_[0][1] = (float) in->read_sint(nbits);			m_[1][1] = (float) in->read_sint(nbits);			m_[2][1] = (float) in->read_sint(nbits);			m_[3][1] = (float) in->read_sint(nbits);		}		else {			for (int i = 0; i < 4; i++) { m_[i][1] = 0; }		}	}	void cxform::clamp()	// Force component values to be in legal range.	{		m_[0][0] = fclamp(m_[0][0], 0, 1);		m_[1][0] = fclamp(m_[1][0], 0, 1);		m_[2][0] = fclamp(m_[2][0], 0, 1);		m_[3][0] = fclamp(m_[3][0], 0, 1);		m_[0][1] = fclamp(m_[0][1], -255.0f, 255.0f);		m_[1][1] = fclamp(m_[1][1], -255.0f, 255.0f);		m_[2][1] = fclamp(m_[2][1], -255.0f, 255.0f);		m_[3][1] = fclamp(m_[3][1], -255.0f, 255.0f);	}	void	cxform::print() const	// Debug log.	{		log_msg("    *         +\n");		log_msg("| %4.4f %4.4f|\n", m_[0][0], m_[0][1]);		log_msg("| %4.4f %4.4f|\n", m_[1][0], m_[1][1]);		log_msg("| %4.4f %4.4f|\n", m_[2][0], m_[2][1]);		log_msg("| %4.4f %4.4f|\n", m_[3][0], m_[3][1]);	}	//	// rgba	//	void	rgba::read(stream* in, int tag_type)	{		if (tag_type <= 22)		{			read_rgb(in);		}		else		{			read_rgba(in);		}	}	void	rgba::read_rgba(stream* in)	{		read_rgb(in);		m_a = in->read_u8();	}	void	rgba::read_rgb(stream* in)	{		m_r = in->read_u8();		m_g = in->read_u8();		m_b = in->read_u8();		m_a = 0x0FF;	}	void	rgba::print()	// For debugging.	{		log_msg("rgba: %d %d %d %d\n", m_r, m_g, m_b, m_a);	}		void	rgba::set_lerp(const rgba& a, const rgba& b, float f)	{		m_r = (Uint8) frnd(flerp(a.m_r, b.m_r, f));		m_g = (Uint8) frnd(flerp(a.m_g, b.m_g, f));		m_b = (Uint8) frnd(flerp(a.m_b, b.m_b, f));		m_a = (Uint8) frnd(flerp(a.m_a, b.m_a, f));	}	//	// rect	//	void	rect::read(stream* in)	{		in->align();		int	nbits = in->read_uint(5);		m_x_min = (float) in->read_sint(nbits);		m_x_max = (float) in->read_sint(nbits);		m_y_min = (float) in->read_sint(nbits);		m_y_max = (float) in->read_sint(nbits);//		IF_DEBUG(log_msg("rect::read() nbits = %d\n", nbits));	}	void	rect::print() const	// Debug spew.	{		log_msg("xmin = %g, ymin = %g, xmax = %g, ymax = %g\n",			TWIPS_TO_PIXELS(m_x_min),			TWIPS_TO_PIXELS(m_y_min),			TWIPS_TO_PIXELS(m_x_max),			TWIPS_TO_PIXELS(m_y_max));	}		bool	rect::point_test(float x, float y) const	// Return true if the specified point is inside this rect.	{		if (x < m_x_min		    || x > m_x_max		    || y < m_y_min		    || y > m_y_max)		{			return false;		}		else		{			return true;		}	}	void	rect::expand_to_point(float x, float y)	// Expand this rectangle to enclose the given point.	{		m_x_min = fmin(m_x_min, x);		m_y_min = fmin(m_y_min, y);		m_x_max = fmax(m_x_max, x);		m_y_max = fmax(m_y_max, y);	}	point	rect::get_corner(int i) const	// Get one of the rect verts.	{		assert(i >= 0 && i < 4);		return point(			(i == 0 || i == 3) ? m_x_min : m_x_max,			(i < 2) ? m_y_min : m_y_max);	}	void	rect::enclose_transformed_rect(const matrix& m, const rect& r)	// Set ourself to bound a rectangle that has been transformed	// by m.  This is an axial bound of an oriented (and/or	// sheared, scaled, etc) box.	{		// Get the transformed bounding box.		point	p0, p1, p2, p3;		m.transform(&p0, r.get_corner(0));		m.transform(&p1, r.get_corner(1));		m.transform(&p2, r.get_corner(2));		m.transform(&p3, r.get_corner(3));		m_x_min = m_x_max = p0.m_x;		m_y_min = m_y_max = p0.m_y;		expand_to_point(p1.m_x, p1.m_y);		expand_to_point(p2.m_x, p2.m_y);		expand_to_point(p3.m_x, p3.m_y);	}	void	rect::set_lerp(const rect& a, const rect& b, float t)	// Set this to the lerp of a and b.	{		m_x_min = flerp(a.m_x_min, b.m_x_min, t);		m_y_min = flerp(a.m_y_min, b.m_y_min, t);		m_x_max = flerp(a.m_x_max, b.m_x_max, t);		m_y_max = flerp(a.m_y_max, b.m_y_max, t);	}};	// end namespace gameswf// Local Variables:// mode: C++// c-basic-offset: 8 // tab-width: 8// indent-tabs-mode: t// End:

⌨️ 快捷键说明

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