Exemple #1
0
cheat_script::cheat_script(cheat_manager &manager, symbol_table &symbols, const char *filename, xml_data_node &scriptnode)
	: m_entrylist(manager.machine().respool()),
		m_state(SCRIPT_STATE_RUN)
{
	// read the core attributes
	const char *state = xml_get_attribute_string(&scriptnode, "state", "run");
	if (strcmp(state, "on") == 0)
		m_state = SCRIPT_STATE_ON;
	else if (strcmp(state, "off") == 0)
		m_state = SCRIPT_STATE_OFF;
	else if (strcmp(state, "change") == 0)
		m_state = SCRIPT_STATE_CHANGE;
	else if (strcmp(state, "run") != 0)
		throw emu_fatalerror("%s.xml(%d): invalid script state '%s'\n", filename, scriptnode.line, state);

	// iterate over nodes within the script
	for (xml_data_node *entrynode = scriptnode.child; entrynode != NULL; entrynode = entrynode->next)
	{
		// handle action nodes
		if (strcmp(entrynode->name, "action") == 0)
			m_entrylist.append(*auto_alloc(manager.machine(), script_entry(manager, symbols, filename, *entrynode, true)));

		// handle output nodes
		else if (strcmp(entrynode->name, "output") == 0)
			m_entrylist.append(*auto_alloc(manager.machine(), script_entry(manager, symbols, filename, *entrynode, false)));

		// anything else is ignored
		else
		{
			mame_printf_warning("%s.xml(%d): unknown script item '%s' will be lost if saved\n", filename, entrynode->line, entrynode->name);
			continue;
		}
	}
}
Exemple #2
0
cheat_parameter::cheat_parameter(cheat_manager &manager, symbol_table &symbols, const char *filename, xml_data_node &paramnode)
	: m_value(0),
		m_itemlist(manager.machine().respool())
{
	// read the core attributes
	m_minval = number_and_format(xml_get_attribute_int(&paramnode, "min", 0), xml_get_attribute_int_format(&paramnode, "min"));
	m_maxval = number_and_format(xml_get_attribute_int(&paramnode, "max", 0), xml_get_attribute_int_format(&paramnode, "max"));
	m_stepval = number_and_format(xml_get_attribute_int(&paramnode, "step", 1), xml_get_attribute_int_format(&paramnode, "step"));

	// iterate over items
	for (xml_data_node *itemnode = xml_get_sibling(paramnode.child, "item"); itemnode != NULL; itemnode = xml_get_sibling(itemnode->next, "item"))
	{
		// check for NULL text
		if (itemnode->value == NULL || itemnode->value[0] == 0)
			throw emu_fatalerror("%s.xml(%d): item is missing text\n", filename, itemnode->line);

		// check for non-existant value
		if (xml_get_attribute(itemnode, "value") == NULL)
			throw emu_fatalerror("%s.xml(%d): item is value\n", filename, itemnode->line);

		// extract the parameters
		UINT64 value = xml_get_attribute_int(itemnode, "value", 0);
		int format = xml_get_attribute_int_format(itemnode, "value");

		// allocate and append a new item
		item &curitem = m_itemlist.append(*auto_alloc(manager.machine(), item(itemnode->value, value, format)));

		// ensure the maximum expands to suit
		m_maxval = MAX(m_maxval, curitem.value());
	}

	// add a variable to the symbol table for our value
	symbols.add("param", symbol_table::READ_ONLY, &m_value);
}
Exemple #3
0
void cheat_script::execute(cheat_manager &manager, UINT64 &argindex)
{
	// do nothing if disabled
	if (!manager.enabled())
		return;

	// iterate over entries
	for (script_entry *entry = m_entrylist.first(); entry != NULL; entry = entry->next())
		entry->execute(manager, argindex);
}
Exemple #4
0
void cheat_script::execute(cheat_manager &manager, uint64_t &argindex)
{
	// do nothing if disabled
	if (!manager.enabled())
		return;

	// iterate over entries
	for (auto &entry : m_entrylist)
		entry->execute(manager, argindex);
}
Exemple #5
0
void cheat_script::script_entry::execute(cheat_manager &manager, UINT64 &argindex)
{
	// evaluate the condition
	if (!m_condition.is_empty())
	{
		try
		{
			UINT64 result = m_condition.execute();
			if (result == 0)
				return;
		}
		catch (expression_error &err)
		{
			mame_printf_warning("Error executing conditional expression \"%s\": %s\n", m_condition.original_string(), err.code_string());
			return;
		}
	}

	// if there is an action, execute it
	if (!m_expression.is_empty())
	{
		try
		{
			m_expression.execute();
		}
		catch (expression_error &err)
		{
			mame_printf_warning("Error executing expression \"%s\": %s\n", m_expression.original_string(), err.code_string());
		}
	}

	// if there is a string to display, compute it
	if (m_format)
	{
		// iterate over arguments and evaluate them
		UINT64 params[MAX_ARGUMENTS];
		int curarg = 0;
		for (output_argument *arg = m_arglist.first(); arg != NULL; arg = arg->next())
			curarg += arg->values(argindex, &params[curarg]);

		// generate the astring
		manager.get_output_astring(m_line, m_justify).printf(m_format,
			(UINT32)params[0],  (UINT32)params[1],  (UINT32)params[2],  (UINT32)params[3],
			(UINT32)params[4],  (UINT32)params[5],  (UINT32)params[6],  (UINT32)params[7],
			(UINT32)params[8],  (UINT32)params[9],  (UINT32)params[10], (UINT32)params[11],
			(UINT32)params[12], (UINT32)params[13], (UINT32)params[14], (UINT32)params[15],
			(UINT32)params[16], (UINT32)params[17], (UINT32)params[18], (UINT32)params[19],
			(UINT32)params[20], (UINT32)params[21], (UINT32)params[22], (UINT32)params[23],
			(UINT32)params[24], (UINT32)params[25], (UINT32)params[26], (UINT32)params[27],
			(UINT32)params[28], (UINT32)params[29], (UINT32)params[30], (UINT32)params[31]);
	}
}
Exemple #6
0
void cheat_script::script_entry::execute(cheat_manager &manager, uint64_t &argindex)
{
	// evaluate the condition
	if (!m_condition.is_empty())
	{
		try
		{
			uint64_t result = m_condition.execute();
			if (result == 0)
				return;
		}
		catch (expression_error &err)
		{
			osd_printf_warning("Error executing conditional expression \"%s\": %s\n", m_condition.original_string(), err.code_string());
			return;
		}
	}

	// if there is an action, execute it
	if (!m_expression.is_empty())
	{
		try
		{
			m_expression.execute();
		}
		catch (expression_error &err)
		{
			osd_printf_warning("Error executing expression \"%s\": %s\n", m_expression.original_string(), err.code_string());
		}
	}

	// if there is a string to display, compute it
	if (!m_format.empty())
	{
		// iterate over arguments and evaluate them
		uint64_t params[MAX_ARGUMENTS];
		int curarg = 0;
		for (auto &arg : m_arglist)
			curarg += arg->values(argindex, &params[curarg]);

		// generate the astring
		manager.get_output_string(m_line, m_justify) = string_format(m_format,
			(uint32_t)params[0],  (uint32_t)params[1],  (uint32_t)params[2],  (uint32_t)params[3],
			(uint32_t)params[4],  (uint32_t)params[5],  (uint32_t)params[6],  (uint32_t)params[7],
			(uint32_t)params[8],  (uint32_t)params[9],  (uint32_t)params[10], (uint32_t)params[11],
			(uint32_t)params[12], (uint32_t)params[13], (uint32_t)params[14], (uint32_t)params[15],
			(uint32_t)params[16], (uint32_t)params[17], (uint32_t)params[18], (uint32_t)params[19],
			(uint32_t)params[20], (uint32_t)params[21], (uint32_t)params[22], (uint32_t)params[23],
			(uint32_t)params[24], (uint32_t)params[25], (uint32_t)params[26], (uint32_t)params[27],
			(uint32_t)params[28], (uint32_t)params[29], (uint32_t)params[30], (uint32_t)params[31]);
	}
}
Exemple #7
0
cheat_entry::cheat_entry(cheat_manager &manager, symbol_table &globaltable, const char *filename, xml_data_node &cheatnode)
	: m_manager(manager),
		m_next(NULL),
		m_on_script(NULL),
		m_off_script(NULL),
		m_change_script(NULL),
		m_run_script(NULL),
		m_symbols(&manager.machine(), &globaltable),
		m_state(SCRIPT_STATE_OFF),
		m_numtemp(DEFAULT_TEMP_VARIABLES),
		m_argindex(0)
{
	// reset scripts
	try
	{
		// pull the variable count out ahead of things
		int tempcount = xml_get_attribute_int(&cheatnode, "tempvariables", DEFAULT_TEMP_VARIABLES);
		if (tempcount < 1)
			throw emu_fatalerror("%s.xml(%d): invalid tempvariables attribute (%d)\n", filename, cheatnode.line, tempcount);

		// allocate memory for the cheat
		m_numtemp = tempcount;

		// get the description
		const char *description = xml_get_attribute_string(&cheatnode, "desc", NULL);
		if (description == NULL || description[0] == 0)
			throw emu_fatalerror("%s.xml(%d): empty or missing desc attribute on cheat\n", filename, cheatnode.line);
		m_description = description;

		// create the symbol table
		m_symbols.add("argindex", symbol_table::READ_ONLY, &m_argindex);
		astring tempname;
		for (int curtemp = 0; curtemp < tempcount; curtemp++)
			m_symbols.add(tempname.format("temp%d", curtemp), symbol_table::READ_WRITE);

		// read the first comment node
		xml_data_node *commentnode = xml_get_sibling(cheatnode.child, "comment");
		if (commentnode != NULL)
		{
			// set the value if not NULL
			if (commentnode->value != NULL && commentnode->value[0] != 0)
				m_comment.cpy(commentnode->value);

			// only one comment is kept
			commentnode = xml_get_sibling(commentnode->next, "comment");
			if (commentnode != NULL)
				mame_printf_warning("%s.xml(%d): only one comment node is retained; ignoring additional nodes\n", filename, commentnode->line);
		}

		// read the first parameter node
		xml_data_node *paramnode = xml_get_sibling(cheatnode.child, "parameter");
		if (paramnode != NULL)
		{
			// load this parameter
			m_parameter.reset(global_alloc(cheat_parameter(manager, m_symbols, filename, *paramnode)));

			// only one parameter allowed
			paramnode = xml_get_sibling(paramnode->next, "parameter");
			if (paramnode != NULL)
				mame_printf_warning("%s.xml(%d): only one parameter node allowed; ignoring additional nodes\n", filename, paramnode->line);
		}

		// read the script nodes
		for (xml_data_node *scriptnode = xml_get_sibling(cheatnode.child, "script"); scriptnode != NULL; scriptnode = xml_get_sibling(scriptnode->next, "script"))
		{
			// load this entry
			cheat_script *curscript = global_alloc(cheat_script(manager, m_symbols, filename, *scriptnode));

			// if we have a script already for this slot, it is an error
			auto_pointer<cheat_script> &slot = script_for_state(curscript->state());
			if (slot != NULL)
				mame_printf_warning("%s.xml(%d): only one on script allowed; ignoring additional scripts\n", filename, scriptnode->line);
			else
				slot.reset(curscript);
		}
	}
	catch (emu_fatalerror &)
	{
		// call our destructor to clean up and re-throw
		this->~cheat_entry();
		throw;
	}
}
Exemple #8
0
cheat_entry::cheat_entry(cheat_manager &manager, symbol_table &globaltable, const char *filename, xml_data_node const &cheatnode)
	: m_manager(manager)
	, m_symbols(&manager.machine(), &globaltable)
	, m_state(SCRIPT_STATE_OFF)
	, m_numtemp(DEFAULT_TEMP_VARIABLES)
	, m_argindex(0)
{
	// reset scripts
	try
	{
		// pull the variable count out ahead of things
		int tempcount = cheatnode.get_attribute_int("tempvariables", DEFAULT_TEMP_VARIABLES);
		if (tempcount < 1)
			throw emu_fatalerror("%s.xml(%d): invalid tempvariables attribute (%d)\n", filename, cheatnode.line, tempcount);

		// allocate memory for the cheat
		m_numtemp = tempcount;

		// get the description
		const char *description = cheatnode.get_attribute_string("desc", nullptr);
		if (description == nullptr || description[0] == 0)
			throw emu_fatalerror("%s.xml(%d): empty or missing desc attribute on cheat\n", filename, cheatnode.line);
		m_description = description;

		// create the symbol table
		m_symbols.add("argindex", symbol_table::READ_ONLY, &m_argindex);
		for (int curtemp = 0; curtemp < tempcount; curtemp++) {
			m_symbols.add(string_format("temp%d", curtemp).c_str(), symbol_table::READ_WRITE);
		}

		// read the first comment node
		xml_data_node const *commentnode = cheatnode.get_child("comment");
		if (commentnode != nullptr)
		{
			// set the value if not nullptr
			if (commentnode->get_value() != nullptr && commentnode->get_value()[0] != 0)
				m_comment.assign(commentnode->get_value());

			// only one comment is kept
			commentnode = commentnode->get_next_sibling("comment");
			if (commentnode != nullptr)
				osd_printf_warning("%s.xml(%d): only one comment node is retained; ignoring additional nodes\n", filename, commentnode->line);
		}

		// read the first parameter node
		xml_data_node const *paramnode = cheatnode.get_child("parameter");
		if (paramnode != nullptr)
		{
			// load this parameter
			m_parameter.reset(global_alloc(cheat_parameter(manager, m_symbols, filename, *paramnode)));

			// only one parameter allowed
			paramnode = paramnode->get_next_sibling("parameter");
			if (paramnode != nullptr)
				osd_printf_warning("%s.xml(%d): only one parameter node allowed; ignoring additional nodes\n", filename, paramnode->line);
		}

		// read the script nodes
		for (xml_data_node const *scriptnode = cheatnode.get_child("script"); scriptnode != nullptr; scriptnode = scriptnode->get_next_sibling("script"))
		{
			// load this entry
			auto curscript = global_alloc(cheat_script(manager, m_symbols, filename, *scriptnode));

			// if we have a script already for this slot, it is an error
			std::unique_ptr<cheat_script> &slot = script_for_state(curscript->state());
			if (slot != nullptr)
				osd_printf_warning("%s.xml(%d): only one on script allowed; ignoring additional scripts\n", filename, scriptnode->line);
			else
				slot.reset(curscript);
		}
	}
	catch (emu_fatalerror &)
	{
		// call our destructor to clean up and re-throw
		this->~cheat_entry();
		throw;
	}
}
Exemple #9
0
cheat_script::script_entry::script_entry(cheat_manager &manager, symbol_table &symbols, const char *filename, xml_data_node &entrynode, bool isaction)
	: m_next(NULL),
		m_condition(&symbols),
		m_expression(&symbols),
		m_arglist(manager.machine().respool())
{
	const char *expression = NULL;
	try
	{
		// read the condition if present
		expression = xml_get_attribute_string(&entrynode, "condition", NULL);
		if (expression != NULL)
			m_condition.parse(expression);

		// if this is an action, parse the expression
		if (isaction)
		{
			expression = entrynode.value;
			if (expression == NULL || expression[0] == 0)
				throw emu_fatalerror("%s.xml(%d): missing expression in action tag\n", filename, entrynode.line);
			m_expression.parse(expression);
		}

		// otherwise, parse the attributes and arguments
		else
		{
			// extract format
			const char *format = xml_get_attribute_string(&entrynode, "format", NULL);
			if (format == NULL || format[0] == 0)
				throw emu_fatalerror("%s.xml(%d): missing format in output tag\n", filename, entrynode.line);
			m_format.cpy(format);

			// extract other attributes
			m_line = xml_get_attribute_int(&entrynode, "line", 0);
			m_justify = JUSTIFY_LEFT;
			const char *align = xml_get_attribute_string(&entrynode, "align", "left");
			if (strcmp(align, "center") == 0)
				m_justify = JUSTIFY_CENTER;
			else if (strcmp(align, "right") == 0)
				m_justify = JUSTIFY_RIGHT;
			else if (strcmp(align, "left") != 0)
				throw emu_fatalerror("%s.xml(%d): invalid alignment '%s' specified\n", filename, entrynode.line, align);

			// then parse arguments
			int totalargs = 0;
			for (xml_data_node *argnode = xml_get_sibling(entrynode.child, "argument"); argnode != NULL; argnode = xml_get_sibling(argnode->next, "argument"))
			{
				output_argument &curarg = m_arglist.append(*auto_alloc(manager.machine(), output_argument(manager, symbols, filename, *argnode)));

				// verify we didn't overrun the argument count
				totalargs += curarg.count();
				if (totalargs > MAX_ARGUMENTS)
					throw emu_fatalerror("%s.xml(%d): too many arguments (found %d, max is %d)\n", filename, argnode->line, totalargs, MAX_ARGUMENTS);
			}

			// validate the format against the arguments
			validate_format(filename, entrynode.line);
		}
	}
	catch (expression_error &err)
	{
		throw emu_fatalerror("%s.xml(%d): error parsing cheat expression \"%s\" (%s)\n", filename, entrynode.line, expression, err.code_string());
	}
}