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

📄 gameswf_action.cpp

📁 一个开源的Flash 播放器,可以在Windows/Linux 上运行
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		const char* p = method_arg_fmt;		for (;; p++)		{			char	c = *p;			if (c == 0)			{				// End of args.				break;			}			else if (c == '%')			{				p++;				c = *p;				// Here's an arg.				if (c == 'd')				{					// Integer.					env->push(va_arg(args, int));				}				else if (c == 'f')				{					// Double					env->push(va_arg(args, double));				}				else if (c == 's')				{					// String					env->push(va_arg(args, const char *));				}				else if (c == 'l')				{					p++;					c = *p;					if (c == 's')					{						// Wide string.						env->push(va_arg(args, const wchar_t *));					}					else					{						log_error("call_method_parsed('%s','%s') -- invalid fmt '%%l%c'\n",							  method_name,							  method_arg_fmt,							  c);					}				}				else				{					// Invalid fmt, warn.					log_error("call_method_parsed('%s','%s') -- invalid fmt '%%%c'\n",						  method_name,						  method_arg_fmt,						  c);				}			}			else			{				// Ignore whitespace and commas.				if (c == ' ' || c == '\t' || c == ',')				{					// OK				}				else				{					// Invalid arg; warn.					log_error("call_method_parsed('%s','%s') -- invalid char '%c'\n",						  method_name,						  method_arg_fmt,						  c);				}			}		}		array<with_stack_entry>	dummy_with_stack;		as_value	method = env->get_variable(method_name, dummy_with_stack);		// check method		// Reverse the order of pushed args		int	nargs = env->get_top_index() - starting_index;		for (int i = 0; i < (nargs >> 1); i++)		{			int	i0 = starting_index + 1 + i;			int	i1 = starting_index + nargs - i;			assert(i0 < i1);			swap(&(env->bottom(i0)), &(env->bottom(i1)));		}		// Do the call.		as_value	result = call_method(method, env, this_ptr, nargs, env->get_top_index());		env->drop(nargs);		// Return pointer to static string for return value.		static tu_string	s_retval;		s_retval = result.to_tu_string();		return s_retval.c_str();	}	//	// sound object	//	struct sound_as_object : public as_object	{		tu_string sound;		int sound_id;	};	void	movie_load()	{		IF_VERBOSE_ACTION(log_msg("-- start movie \n"));	}	void	sound_start(const fn_call& fn)	{		IF_VERBOSE_ACTION(log_msg("-- start sound \n"));		sound_handler* s = get_sound_handler();		if (s != NULL)		{			sound_as_object*	so = (sound_as_object*) (as_object*) fn.this_ptr;			assert(so);			s->play_sound(so->sound_id, 0);		}	}	void	sound_stop(const fn_call& fn)	{		IF_VERBOSE_ACTION(log_msg("-- stop sound \n"));		sound_handler* s = get_sound_handler();		if (s != NULL)		{			sound_as_object*	so = (sound_as_object*) (as_object*) fn.this_ptr;			assert(so);			s->stop_sound(so->sound_id);		}	}	void	sound_attach(const fn_call& fn)	{		IF_VERBOSE_ACTION(log_msg("-- attach sound \n"));		if (fn.nargs < 1)		{			log_error("attach sound needs one argument\n");			return;		}		sound_as_object*	so = (sound_as_object*) (as_object*) fn.this_ptr;		assert(so);		so->sound = fn.arg(0).to_tu_string();		// check the import.		movie_definition_sub*	def = (movie_definition_sub*)			fn.env->get_target()->get_root_movie()->get_movie_definition();		assert(def);		smart_ptr<resource> res = def->get_exported_resource(so->sound);		if (res == NULL)		{			log_error("import error: resource '%s' is not exported\n", so->sound.c_str());			return;		}		int si = 0;		sound_sample_impl* ss = (sound_sample_impl*) res->cast_to_sound_sample();		if (ss != NULL)		{			si = ss->m_sound_handler_id;		}		else		{			log_error("sound sample is NULL\n");			return;		}		// sanity check		assert(si >= 0 && si < 1000);		so->sound_id = si;	}	//	// Built-in objects	//	//	// math object	//#if 0	// One-argument simple functions.	#define MATH_WRAP_FUNC1(funcname)							\	void	math_##funcname(as_value* result, as_object_interface* this_ptr,		\				as_environment* env, int nargs, int first_arg_bottom_index)	\	{											\		double	arg = env->bottom(first_arg_bottom_index).to_number();			\		result->set_double(funcname(arg));						\	}#else	// One-argument simple functions.	#define MATH_WRAP_FUNC1(funcname)							\	void	math_##funcname(const fn_call& fn)						\	{											\		double	arg = fn.arg(0).to_number();						\		fn.result->set_double(funcname(arg));						\	}#endif	MATH_WRAP_FUNC1(fabs);	MATH_WRAP_FUNC1(acos);	MATH_WRAP_FUNC1(asin);	MATH_WRAP_FUNC1(atan);	MATH_WRAP_FUNC1(ceil);	MATH_WRAP_FUNC1(cos);	MATH_WRAP_FUNC1(exp);	MATH_WRAP_FUNC1(floor);	MATH_WRAP_FUNC1(log);	MATH_WRAP_FUNC1(sin);	MATH_WRAP_FUNC1(sqrt);	MATH_WRAP_FUNC1(tan);#if 0	// Two-argument functions.	#define MATH_WRAP_FUNC2_EXP(funcname, expr)										\	void	math_##funcname(as_value* result, as_object_interface* this_ptr, as_environment* env, int nargs, int first_arg_bottom_index)	\	{															\		double	arg0 = env->bottom(first_arg_bottom_index).to_number();							\		double	arg1 = env->bottom(first_arg_bottom_index - 1).to_number();						\		result->set_double(expr);											\	}#else	// Two-argument functions.	#define MATH_WRAP_FUNC2_EXP(funcname, expr)										\	void	math_##funcname(const fn_call& fn)										\	{															\		double	arg0 = fn.arg(0).to_number();										\		double	arg1 = fn.arg(1).to_number();										\		fn.result->set_double(expr);											\	}#endif	MATH_WRAP_FUNC2_EXP(atan2, (atan2(arg0, arg1)));	MATH_WRAP_FUNC2_EXP(max, (arg0 > arg1 ? arg0 : arg1));	MATH_WRAP_FUNC2_EXP(min, (arg0 < arg1 ? arg0 : arg1));	MATH_WRAP_FUNC2_EXP(pow, (pow(arg0, arg1)));	// A couple of oddballs.	void	math_random(const fn_call& fn)	{		// Random number between 0 and 1.		fn.result->set_double(tu_random::next_random() / double(Uint32(0x0FFFFFFFF)));	}	void	math_round(const fn_call& fn)	{		// round argument to nearest int.		double	arg0 = fn.arg(0).to_number();		fn.result->set_double(floor(arg0 + 0.5));	}		void math_init()	{		// Create built-in math object.		as_object*	math_obj = new as_object;		// constant		math_obj->set_member("e", 2.7182818284590452354);		math_obj->set_member("ln2", 0.69314718055994530942);		math_obj->set_member("log2e", 1.4426950408889634074);		math_obj->set_member("ln10", 2.30258509299404568402);		math_obj->set_member("log10e", 0.43429448190325182765);		math_obj->set_member("pi", 3.14159265358979323846);		math_obj->set_member("sqrt1_2", 0.7071067811865475244);		math_obj->set_member("sqrt2", 1.4142135623730950488);		// math methods		math_obj->set_member("abs", &math_fabs);		math_obj->set_member("acos", &math_acos);		math_obj->set_member("asin", &math_asin);		math_obj->set_member("atan", &math_atan);		math_obj->set_member("ceil", &math_ceil);		math_obj->set_member("cos", &math_cos);		math_obj->set_member("exp", &math_exp);		math_obj->set_member("floor", &math_floor);		math_obj->set_member("log", &math_log);		math_obj->set_member("random", &math_random);		math_obj->set_member("round", &math_round);		math_obj->set_member("sin", &math_sin);		math_obj->set_member("sqrt", &math_sqrt);		math_obj->set_member("tan", &math_tan);		math_obj->set_member("atan2", &math_atan2);		math_obj->set_member("max", &math_max);		math_obj->set_member("min", &math_min);		math_obj->set_member("pow", &math_pow);		s_global->set_member("math", math_obj);	}			void event_test(const fn_call& fn)	{		log_msg("FIXME: %s\n", __FUNCTION__);	}		//	// key object	//	struct key_as_object : public as_object	{		Uint8	m_keymap[key::KEYCOUNT / 8 + 1];	// bit-array		array<weak_ptr<as_object_interface> >	m_listeners;		int	m_last_key_pressed;		key_as_object()			:			m_last_key_pressed(0)		{			memset(m_keymap, 0, sizeof(m_keymap));		}		bool	is_key_down(int code)		{			if (code < 0 || code >= key::KEYCOUNT) return false;			int	byte_index = code >> 3;			int	bit_index = code - (byte_index << 3);			int	mask = 1 << bit_index;			assert(byte_index >= 0 && byte_index < int(sizeof(m_keymap)/sizeof(m_keymap[0])));			if (m_keymap[byte_index] & mask)			{				return true;			}			else			{				return false;			}		}		void	set_key_down(int code)		{			if (code < 0 || code >= key::KEYCOUNT) return;			m_last_key_pressed = code;			int	byte_index = code >> 3;			int	bit_index = code - (byte_index << 3);			int	mask = 1 << bit_index;			assert(byte_index >= 0 && byte_index < int(sizeof(m_keymap)/sizeof(m_keymap[0])));			m_keymap[byte_index] |= mask;			// Notify listeners.			int i;			int n = m_listeners.size();			for (i = 0; i < n; i++)			{				smart_ptr<as_object_interface>	listener = m_listeners[i];				as_value	method;				if (listener != NULL				    && listener->get_member(event_id(event_id::KEY_DOWN).get_function_name(), &method))				{					call_method(method, NULL /* or root? */, listener.get_ptr(), 0, 0);				}			}		}		void	set_key_up(int code)		{			if (code < 0 || code >= key::KEYCOUNT) return;			int	byte_index = code >> 3;			int	bit_index = code - (byte_index << 3);			int	mask = 1 << bit_index;			assert(byte_index >= 0 && byte_index < int(sizeof(m_keymap)/sizeof(m_keymap[0])));			m_keymap[byte_index] &= ~mask;			// Notify listeners.			for (int i = 0, n = m_listeners.size(); i < n; i++)			{				smart_ptr<as_object_interface>	listener = m_listeners[i];				as_value	method;				if (listener != NULL				    && listener->get_member(event_id(event_id::KEY_UP).get_function_name(), &method))				{					call_method(method, NULL /* or root? */, listener.get_ptr(), 0, 0);				}			}		}		void	cleanup_listeners()		// Remove dead entries in the listeners list.  (Since		// we use weak_ptr's, listeners can disappear without		// notice.)		{			for (int i = m_listeners.size() - 1; i >= 0; i--)			{				if (m_listeners[i] == NULL)				{					m_listeners.remove(i);				}			}		}		void	add_listener(as_object_interface* listener)		{			cleanup_listeners();			for (int i = 0, n = m_listeners.size(); i < n; i++)			{				if (m_listeners[i] == listener)				{					// Already in the list.					return;				}			}			m_listeners.push_back(listener);		}		void	remove_listener(as_object_interface* listener)		{			cleanup_listeners();			for (int i = m_listeners.size() - 1; i >= 0; i--)			{				if (m_listeners[i] == listener)				{					m_listeners.remove(i);				}			}		}		int	get_last_key_pressed() const { return m_last_key_pressed; }	};	void	key_add_listener(const fn_call& fn)	// Add a listener (first arg is object reference) to our list.	// Listeners will have "onKeyDown" and "onKeyUp" methods	// called on them when a key changes state.	{		if (fn.nargs < 1)		{			log_error("key_add_listener needs one argument (the listener object)\n");			return;		}		as_object_interface*	listener = fn.arg(0).to_object();		if (listener == NULL)		{			log_error("key_add_listener passed a NULL object; ignored\n");			return;		}		key_as_object*	ko = (key_as_object*) (as_object*) fn.this_ptr;		assert(ko);		ko->add_listener(listener);	}	void	key_get_ascii(const fn_call& fn)	// Return the ascii value of the last key pressed.	{		key_as_object*	ko = (key_as_object*) (as_object*) fn.this_ptr;		assert(ko);		fn.result->set_undefined();		int	code = ko->get_last_key_pressed();		if (code > 0)		{			// @@ Crude for now; just jamming the key code in a string, as a character.			// Need to apply shift/capslock/numlock, etc...			char	buf[2];			buf[0] = (char) code;			buf[1] = 0;			fn.result->set_string(buf);		}	}	void	key_get_code(const fn_call& fn)	// Returns the keycode of the last key pressed.	{		key_as_object*	ko = (key_as_object*) (as_object*) fn.this_ptr;		assert(ko);		fn.result->set_int(ko->get_last_key_pressed());	}	void	key_is_down(const fn_call& fn)	// Return true if the specified (first arg keycode) key is pressed.	{		if (fn.nargs < 1)		{			log_error("key_is_down needs one argument (the key code)\n");			return;		}		int	code = (int) fn.arg(0).to_number();		key_as_object*	ko = (key_as_object*) (as_object*) fn.this_ptr;		assert(ko);		fn.result->set_bool(ko->is_key_down(code));	}	void	key_is_toggled(const fn_call& fn)	// Given the keycode of NUM_LOCK or CAPSLOCK, returns true if	// the associated state is on.	{		// @@ TODO		fn.result->set_bool(false);	}	void	key_remove_listener(const fn_call& fn)	// Remove a previously-added listener.

⌨️ 快捷键说明

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