diff --git a/src/emu/cheat.c b/src/emu/cheat.c index 7bb295a45f6..29652e8acab 100644 --- a/src/emu/cheat.c +++ b/src/emu/cheat.c @@ -60,12 +60,7 @@ #include "debug/debugcpu.h" #include "debug/express.h" - - -/*************************************************************************** - MACROS -***************************************************************************/ - +#include @@ -101,6 +96,7 @@ struct _parameter_item parameter_item * next; /* next item in list */ astring * text; /* name of the item */ UINT64 value; /* value of the item */ + int valformat; /* format of value */ }; @@ -109,9 +105,13 @@ typedef struct _cheat_parameter cheat_parameter; struct _cheat_parameter { UINT64 minval; /* minimum value */ + int minformat; /* format of minimum value */ UINT64 maxval; /* maximum value */ + int maxformat; /* format of maximum value */ UINT64 stepval; /* step value */ + int stepformat; /* format of step value */ UINT64 defval; /* default value */ + int defformat; /* format of default value */ UINT64 value; /* live value of the parameter */ char valuestring[32]; /* small space for a value string */ parameter_item * itemlist; /* list of items */ @@ -216,6 +216,35 @@ static void cheat_variable_set(void *ref, UINT64 value); INLINE FUNCTIONS ***************************************************************************/ +/*------------------------------------------------- + format_int - format an integer according to + the format +-------------------------------------------------*/ + +const char *format_int(astring *string, UINT64 value, int format) +{ + switch (format) + { + default: + case XML_INT_FORMAT_DECIMAL: + astring_printf(string, "%d", (UINT32)value); + break; + + case XML_INT_FORMAT_DECIMAL_POUND: + astring_printf(string, "#%d", (UINT32)value); + break; + + case XML_INT_FORMAT_HEX_DOLLAR: + astring_printf(string, "$%X", (UINT32)value); + break; + + case XML_INT_FORMAT_HEX_C: + astring_printf(string, "0x%X", (UINT32)value); + break; + } + return astring_c(string); +} + /*************************************************************************** @@ -246,6 +275,11 @@ void cheat_init(running_machine *machine) /* temporary: save the file back out as output.xml for comparison */ if (cheatinfo->cheatlist != NULL) cheat_list_save("output", cheatinfo->cheatlist); + + /* we rely on the debugger expression callbacks; if the debugger isn't + enabled, we must jumpstart them manually */ + if ((machine->debug_flags & DEBUG_FLAG_ENABLED) == 0) + debug_cpu_init(machine); } @@ -320,9 +354,25 @@ void *cheat_get_next_menu_entry(running_machine *machine, void *previous, const /* description is standard */ if (description != NULL) *description = astring_c(cheat->description); + + /* some cheat entries are just text for display */ + if (cheat->parameter == NULL && cheat->script[SCRIPT_STATE_RUN] == NULL && cheat->script[SCRIPT_STATE_OFF] == NULL && cheat->script[SCRIPT_STATE_ON] == NULL) + { + if (description != NULL) + { + while (isspace(**description)) + *description += 1; + if (**description == 0) + *description = MENU_SEPARATOR_ITEM; + } + if (state != NULL) + *state = NULL; + if (flags != NULL) + *flags = MENU_FLAG_DISABLE; + } /* if we have no parameter and no run or off script, it's a oneshot cheat */ - if (cheat->parameter == NULL && cheat->script[SCRIPT_STATE_RUN] == NULL && cheat->script[SCRIPT_STATE_OFF] == NULL) + else if (cheat->parameter == NULL && cheat->script[SCRIPT_STATE_RUN] == NULL && cheat->script[SCRIPT_STATE_OFF] == NULL) { if (state != NULL) *state = "Activate"; @@ -392,13 +442,14 @@ int cheat_activate(running_machine *machine, void *entry) cheat_entry *cheat = entry; int changed = FALSE; - /* if we have no parameter and no run or off script, it's a oneshot cheat */ - if (cheat->parameter == NULL && cheat->script[SCRIPT_STATE_RUN] == NULL && cheat->script[SCRIPT_STATE_OFF] == NULL) + /* if we have no parameter and no run or off script, but we do have an on script, it's a oneshot cheat */ + if (cheat->parameter == NULL && cheat->script[SCRIPT_STATE_RUN] == NULL && cheat->script[SCRIPT_STATE_OFF] == NULL && cheat->script[SCRIPT_STATE_ON] != NULL) { cheat_execute_script(cheatinfo, cheat, SCRIPT_STATE_ON); changed = TRUE; popmessage("Activated %s", astring_c(cheat->description)); } + return changed; } @@ -415,7 +466,7 @@ int cheat_select_default_state(running_machine *machine, void *entry) cheat_entry *cheat = entry; int changed = FALSE; - /* if we have no parameter and no run or off script, it's a oneshot cheat */ + /* if we have no parameter and no run or off script, it's either text or a oneshot cheat */ if (cheat->parameter == NULL && cheat->script[SCRIPT_STATE_RUN] == NULL && cheat->script[SCRIPT_STATE_OFF] == NULL) ; @@ -454,7 +505,7 @@ int cheat_select_previous_state(running_machine *machine, void *entry) cheat_entry *cheat = entry; int changed = FALSE; - /* if we have no parameter and no run or off script, it's a oneshot cheat */ + /* if we have no parameter and no run or off script, it's either text or a oneshot cheat */ if (cheat->parameter == NULL && cheat->script[SCRIPT_STATE_RUN] == NULL && cheat->script[SCRIPT_STATE_OFF] == NULL) ; @@ -935,28 +986,40 @@ error: static void cheat_entry_save(mame_file *cheatfile, const cheat_entry *cheat) { script_state state; + int scriptcount; + + /* count the scripts */ + scriptcount = 0; + for (state = SCRIPT_STATE_OFF; state < SCRIPT_STATE_COUNT; state++) + if (cheat->script[state] != NULL) + scriptcount++; /* output the cheat tag */ mame_fprintf(cheatfile, "\tdescription)); if (cheat->numtemp != DEFAULT_TEMP_VARIABLES) mame_fprintf(cheatfile, " tempvariables=\"%d\"", cheat->numtemp); - mame_fprintf(cheatfile, ">\n"); + if (cheat->comment == NULL && cheat->parameter == NULL && scriptcount == 0) + mame_fprintf(cheatfile, " />\n"); + else + { + mame_fprintf(cheatfile, ">\n"); - /* save the comment */ - if (cheat->comment != NULL) - mame_fprintf(cheatfile, "\t\t\n", astring_c(cheat->comment)); + /* save the comment */ + if (cheat->comment != NULL) + mame_fprintf(cheatfile, "\t\t\n", astring_c(cheat->comment)); - /* output the parameter, if present */ - if (cheat->parameter != NULL) - cheat_parameter_save(cheatfile, cheat->parameter); + /* output the parameter, if present */ + if (cheat->parameter != NULL) + cheat_parameter_save(cheatfile, cheat->parameter); - /* output the script nodes */ - for (state = SCRIPT_STATE_OFF; state < SCRIPT_STATE_COUNT; state++) - if (cheat->script[state] != NULL) - cheat_script_save(cheatfile, cheat->script[state]); + /* output the script nodes */ + for (state = SCRIPT_STATE_OFF; state < SCRIPT_STATE_COUNT; state++) + if (cheat->script[state] != NULL) + cheat_script_save(cheatfile, cheat->script[state]); - /* close the cheat tag */ - mame_fprintf(cheatfile, "\t\n"); + /* close the cheat tag */ + mame_fprintf(cheatfile, "\t\n"); + } } @@ -1006,9 +1069,13 @@ static cheat_parameter *cheat_parameter_load(const char *filename, xml_data_node /* read the core attributes */ param->minval = xml_get_attribute_int(paramnode, "min", 0); + param->minformat = xml_get_attribute_int_format(paramnode, "min"); param->maxval = xml_get_attribute_int(paramnode, "max", 0); + param->maxformat = xml_get_attribute_int_format(paramnode, "max"); param->stepval = xml_get_attribute_int(paramnode, "step", 1); + param->stepformat = xml_get_attribute_int_format(paramnode, "step"); param->defval = xml_get_attribute_int(paramnode, "default", param->minval); + param->defformat = xml_get_attribute_int_format(paramnode, "default"); /* iterate over items */ itemtailptr = ¶m->itemlist; @@ -1035,6 +1102,7 @@ static cheat_parameter *cheat_parameter_load(const char *filename, xml_data_node goto error; } curitem->value = xml_get_attribute_int(itemnode, "value", 0); + curitem->valformat = xml_get_attribute_int_format(itemnode, "value"); /* ensure the maximum expands to suit */ param->maxval = MAX(param->maxval, curitem->value); @@ -1064,6 +1132,8 @@ error: static void cheat_parameter_save(mame_file *cheatfile, const cheat_parameter *param) { + astring *string = astring_alloc(); + /* output the parameter tag */ mame_fprintf(cheatfile, "\t\titemlist == NULL) { if (param->minval != 0) - mame_fprintf(cheatfile, " min=\"%d\"", (UINT32)param->minval); + mame_fprintf(cheatfile, " min=\"%s\"", format_int(string, param->minval, param->minformat)); if (param->maxval != 0) - mame_fprintf(cheatfile, " max=\"%d\"", (UINT32)param->maxval); + mame_fprintf(cheatfile, " max=\"%s\"", format_int(string, param->maxval, param->maxformat)); if (param->stepval != 1) - mame_fprintf(cheatfile, " step=\"%d\"", (UINT32)param->stepval); - mame_fprintf(cheatfile, " default=\"%d\"", (UINT32)param->defval); + mame_fprintf(cheatfile, " step=\"%s\"", format_int(string, param->stepval, param->stepformat)); + mame_fprintf(cheatfile, " default=\"%s\"", format_int(string, param->defval, param->defformat)); mame_fprintf(cheatfile, "/>\n"); } @@ -1085,11 +1155,12 @@ static void cheat_parameter_save(mame_file *cheatfile, const cheat_parameter *pa { const parameter_item *curitem; - mame_fprintf(cheatfile, " default=\"%d\">\n", (UINT32)param->defval); + mame_fprintf(cheatfile, " default=\"%s\">\n", format_int(string, param->defval, param->defformat)); for (curitem = param->itemlist; curitem != NULL; curitem = curitem->next) - mame_fprintf(cheatfile, "\t\t\t%s\n", (UINT32)curitem->value, astring_c(curitem->text)); + mame_fprintf(cheatfile, "\t\t\t%s\n", format_int(string, curitem->value, curitem->valformat), astring_c(curitem->text)); mame_fprintf(cheatfile, "\t\t\n"); } + astring_free(string); } diff --git a/src/emu/uimenu.c b/src/emu/uimenu.c index 55b4184f932..ae059048626 100644 --- a/src/emu/uimenu.c +++ b/src/emu/uimenu.c @@ -335,7 +335,7 @@ INLINE void toggle_none_default(input_seq *selected_seq, input_seq *original_seq INLINE int item_is_selectable(const ui_menu_item *item) { - return ((item->flags & MENU_FLAG_MULTILINE) == 0 && strcmp(item->text, MENU_SEPARATOR_ITEM) != 0); + return ((item->flags & (MENU_FLAG_MULTILINE | MENU_FLAG_DISABLE)) == 0 && strcmp(item->text, MENU_SEPARATOR_ITEM) != 0); } @@ -2497,6 +2497,9 @@ static void menu_cheat_populate(running_machine *machine, ui_menu *menu) ui_menu_item_append(menu, text, subtext, flags, curcheat); } + /* add a separator */ + ui_menu_item_append(menu, MENU_SEPARATOR_ITEM, NULL, 0, NULL); + /* add a reset all option */ ui_menu_item_append(menu, "Reset All", NULL, 0, (void *)1); } diff --git a/src/emu/uimenu.h b/src/emu/uimenu.h index 4325e0bf7f7..ae5564a4710 100644 --- a/src/emu/uimenu.h +++ b/src/emu/uimenu.h @@ -27,6 +27,7 @@ #define MENU_FLAG_INVERT (1 << 2) #define MENU_FLAG_MULTILINE (1 << 3) #define MENU_FLAG_REDTEXT (1 << 4) +#define MENU_FLAG_DISABLE (1 << 5) /* special menu item for separators */ #define MENU_SEPARATOR_ITEM "---" diff --git a/src/lib/util/xmlfile.c b/src/lib/util/xmlfile.c index 66091fa3acf..70adc563f8f 100644 --- a/src/lib/util/xmlfile.c +++ b/src/lib/util/xmlfile.c @@ -412,9 +412,36 @@ int xml_get_attribute_int(xml_data_node *node, const char *attribute, int defval const char *string = xml_get_attribute_string(node, attribute, NULL); int value; - if (string == NULL || sscanf(string, "%d", &value) != 1) + if (string == NULL) return defvalue; - return value; + if (string[0] == '$') + return (sscanf(&string[1], "%X", &value) == 1) ? value : defvalue; + if (string[0] == '0' && string[1] == 'x') + return (sscanf(&string[2], "%X", &value) == 1) ? value : defvalue; + if (string[0] == '#') + return (sscanf(&string[1], "%d", &value) == 1) ? value : defvalue; + return (sscanf(&string[0], "%d", &value) == 1) ? value : defvalue; +} + + +/*------------------------------------------------- + xml_get_attribute_int_format - return the + format of the given integer attribute +-------------------------------------------------*/ + +int xml_get_attribute_int_format(xml_data_node *node, const char *attribute) +{ + const char *string = xml_get_attribute_string(node, attribute, NULL); + + if (string == NULL) + return XML_INT_FORMAT_DECIMAL; + if (string[0] == '$') + return XML_INT_FORMAT_HEX_DOLLAR; + if (string[0] == '0' && string[1] == 'x') + return XML_INT_FORMAT_HEX_C; + if (string[0] == '#') + return XML_INT_FORMAT_DECIMAL_POUND; + return XML_INT_FORMAT_DECIMAL; } diff --git a/src/lib/util/xmlfile.h b/src/lib/util/xmlfile.h index 2abbc7f7443..910cc3ab721 100644 --- a/src/lib/util/xmlfile.h +++ b/src/lib/util/xmlfile.h @@ -28,6 +28,15 @@ enum }; +enum +{ + XML_INT_FORMAT_DECIMAL, + XML_INT_FORMAT_DECIMAL_POUND, + XML_INT_FORMAT_HEX_DOLLAR, + XML_INT_FORMAT_HEX_C +}; + + /*************************************************************************** TYPE DEFINITIONS @@ -139,6 +148,9 @@ const char *xml_get_attribute_string(xml_data_node *node, const char *attribute, /* return the integer value of an attribute, or the specified default if not present */ int xml_get_attribute_int(xml_data_node *node, const char *attribute, int defvalue); +/* return the format of the given integer attribute */ +int xml_get_attribute_int_format(xml_data_node *node, const char *attribute); + /* return the float value of an attribute, or the specified default if not present */ float xml_get_attribute_float(xml_data_node *node, const char *attribute, float defvalue);