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; } }
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; } }