mirror of
https://github.com/holub/mame
synced 2025-05-09 15:51:48 +03:00
Changes to the cheat.xml format:
- new tag <comment> (within <cheat>) is read and preserved when saved - removed variable attribute from <parameter>; it is now assumed to be 'param' - added default attribute for <parameter> Added new variable 'frame' accessible from cheat scripts. This can be used in the conditional to prevent execution on every frame, or for other effects (like displaying temporary messages). Added new variable 'argindex' which is the index when processing an <argument> with a count attribute greater than 1. Can be used in expressions like: <argument count="3">main.pb@(1000+argindex)</argument> Reinstated the cheat menu. It now displays all loaded cheats and allows for them to be activated. All known cheat behaviors should be working now.
This commit is contained in:
parent
2d165fe1c3
commit
4a36b515ed
512
src/emu/cheat.c
512
src/emu/cheat.c
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<mamecheat version="1">
|
<mamecheat version="1">
|
||||||
<cheat desc="blah">
|
<cheat desc="blah">
|
||||||
<parameter variable="varname(param)" min="minval(0)" max="maxval(numitems)" step="stepval(1)">
|
<parameter min="minval(0)" max="maxval(numitems)" step="stepval(1)" default="defvalue(minval)">
|
||||||
<item value="itemval(previtemval|minval+stepval)">text</item>
|
<item value="itemval(previtemval|minval+stepval)">text</item>
|
||||||
...
|
...
|
||||||
</parameter>
|
</parameter>
|
||||||
@ -26,15 +26,37 @@
|
|||||||
...
|
...
|
||||||
</script>
|
</script>
|
||||||
...
|
...
|
||||||
|
<comment>
|
||||||
|
... text ...
|
||||||
|
</comment>
|
||||||
</cheat>
|
</cheat>
|
||||||
...
|
...
|
||||||
</mamecheat>
|
</mamecheat>
|
||||||
|
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
Expressions are standard debugger expressions. Note that & and
|
||||||
|
< must be escaped per XML rules. Within attributes you must use
|
||||||
|
& and <. For tags, you can also use <![CDATA[ ... ]]>.
|
||||||
|
|
||||||
|
Each cheat has its own context-specific variables:
|
||||||
|
|
||||||
|
temp0-temp9 -- 10 temporary variables for any use
|
||||||
|
param -- the current value of the cheat parameter
|
||||||
|
frame -- the current frame index
|
||||||
|
argindex -- for arguments with multiple iterations, this is the index
|
||||||
|
|
||||||
|
By default, each cheat has 10 temporary variables that are
|
||||||
|
persistent while executing its scripts. Additional temporary
|
||||||
|
variables may be requested via the 'tempvariables' attribute
|
||||||
|
on the cheat.
|
||||||
|
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "xmlfile.h"
|
#include "xmlfile.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
#include "uimenu.h"
|
||||||
#include "debug/debugcpu.h"
|
#include "debug/debugcpu.h"
|
||||||
#include "debug/express.h"
|
#include "debug/express.h"
|
||||||
|
|
||||||
@ -54,6 +76,7 @@
|
|||||||
#define CHEAT_VERSION 1
|
#define CHEAT_VERSION 1
|
||||||
|
|
||||||
#define DEFAULT_TEMP_VARIABLES 10
|
#define DEFAULT_TEMP_VARIABLES 10
|
||||||
|
#define MAX_ARGUMENTS 32
|
||||||
|
|
||||||
enum _script_state
|
enum _script_state
|
||||||
{
|
{
|
||||||
@ -85,11 +108,12 @@ struct _parameter_item
|
|||||||
typedef struct _cheat_parameter cheat_parameter;
|
typedef struct _cheat_parameter cheat_parameter;
|
||||||
struct _cheat_parameter
|
struct _cheat_parameter
|
||||||
{
|
{
|
||||||
astring * name; /* name of the parameter */
|
|
||||||
UINT64 minval; /* minimum value */
|
UINT64 minval; /* minimum value */
|
||||||
UINT64 maxval; /* maximum value */
|
UINT64 maxval; /* maximum value */
|
||||||
UINT64 stepval; /* step value */
|
UINT64 stepval; /* step value */
|
||||||
|
UINT64 defval; /* default value */
|
||||||
UINT64 value; /* live value of the parameter */
|
UINT64 value; /* live value of the parameter */
|
||||||
|
char valuestring[32]; /* small space for a value string */
|
||||||
parameter_item * itemlist; /* list of items */
|
parameter_item * itemlist; /* list of items */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -133,10 +157,13 @@ struct _cheat_entry
|
|||||||
{
|
{
|
||||||
cheat_entry * next; /* next cheat entry */
|
cheat_entry * next; /* next cheat entry */
|
||||||
astring * description; /* string description/menu title */
|
astring * description; /* string description/menu title */
|
||||||
|
astring * comment; /* comment data */
|
||||||
cheat_parameter * parameter; /* parameter */
|
cheat_parameter * parameter; /* parameter */
|
||||||
cheat_script * script[SCRIPT_STATE_COUNT]; /* up to 1 script for each state */
|
cheat_script * script[SCRIPT_STATE_COUNT]; /* up to 1 script for each state */
|
||||||
symbol_table * symbols; /* symbol table for this cheat */
|
symbol_table * symbols; /* symbol table for this cheat */
|
||||||
|
script_state state; /* current cheat state */
|
||||||
UINT32 numtemp; /* number of temporary variables */
|
UINT32 numtemp; /* number of temporary variables */
|
||||||
|
UINT64 argindex; /* argument index variable */
|
||||||
UINT64 tempvar[1]; /* value of the temporary variables */
|
UINT64 tempvar[1]; /* value of the temporary variables */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -145,6 +172,11 @@ struct _cheat_entry
|
|||||||
struct _cheat_private
|
struct _cheat_private
|
||||||
{
|
{
|
||||||
cheat_entry * cheatlist; /* cheat list */
|
cheat_entry * cheatlist; /* cheat list */
|
||||||
|
UINT64 framecount; /* frame count */
|
||||||
|
astring * output[UI_TARGET_FONT_ROWS*2]; /* array of output strings */
|
||||||
|
UINT8 justify[UI_TARGET_FONT_ROWS*2]; /* justification for each string */
|
||||||
|
UINT8 numlines; /* nnumber of lines available for output */
|
||||||
|
INT8 lastline; /* last line used for output */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -154,11 +186,13 @@ struct _cheat_private
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
static void cheat_exit(running_machine *machine);
|
static void cheat_exit(running_machine *machine);
|
||||||
|
static void cheat_frame(running_machine *machine);
|
||||||
|
static void cheat_execute_script(cheat_private *cheatinfo, cheat_entry *cheat, script_state state);
|
||||||
|
|
||||||
static cheat_entry *cheat_list_load(const char *filename);
|
static cheat_entry *cheat_list_load(running_machine *machine, const char *filename);
|
||||||
static int cheat_list_save(const char *filename, const cheat_entry *cheatlist);
|
static int cheat_list_save(const char *filename, const cheat_entry *cheatlist);
|
||||||
static void cheat_list_free(cheat_entry *cheat);
|
static void cheat_list_free(cheat_entry *cheat);
|
||||||
static cheat_entry *cheat_entry_load(const char *filename, xml_data_node *cheatnode);
|
static cheat_entry *cheat_entry_load(running_machine *machine, const char *filename, xml_data_node *cheatnode);
|
||||||
static void cheat_entry_save(mame_file *cheatfile, const cheat_entry *cheat);
|
static void cheat_entry_save(mame_file *cheatfile, const cheat_entry *cheat);
|
||||||
static void cheat_entry_free(cheat_entry *cheat);
|
static void cheat_entry_free(cheat_entry *cheat);
|
||||||
static cheat_parameter *cheat_parameter_load(const char *filename, xml_data_node *paramnode);
|
static cheat_parameter *cheat_parameter_load(const char *filename, xml_data_node *paramnode);
|
||||||
@ -171,7 +205,7 @@ static script_entry *script_entry_load(const char *filename, xml_data_node *entr
|
|||||||
static void script_entry_save(mame_file *cheatfile, const script_entry *entry);
|
static void script_entry_save(mame_file *cheatfile, const script_entry *entry);
|
||||||
static void script_entry_free(script_entry *entry);
|
static void script_entry_free(script_entry *entry);
|
||||||
|
|
||||||
static astring *quote_astring(astring *string, int isattribute);
|
static astring *quote_astring_expression(astring *string, int isattribute);
|
||||||
static int validate_format(const char *filename, int line, const script_entry *entry);
|
static int validate_format(const char *filename, int line, const script_entry *entry);
|
||||||
static UINT64 cheat_variable_get(void *ref);
|
static UINT64 cheat_variable_get(void *ref);
|
||||||
static void cheat_variable_set(void *ref, UINT64 value);
|
static void cheat_variable_set(void *ref, UINT64 value);
|
||||||
@ -198,6 +232,7 @@ void cheat_init(running_machine *machine)
|
|||||||
cheat_private *cheatinfo;
|
cheat_private *cheatinfo;
|
||||||
|
|
||||||
/* request a callback */
|
/* request a callback */
|
||||||
|
add_frame_callback(machine, cheat_frame);
|
||||||
add_exit_callback(machine, cheat_exit);
|
add_exit_callback(machine, cheat_exit);
|
||||||
|
|
||||||
/* allocate memory */
|
/* allocate memory */
|
||||||
@ -206,7 +241,7 @@ void cheat_init(running_machine *machine)
|
|||||||
machine->cheat_data = cheatinfo;
|
machine->cheat_data = cheatinfo;
|
||||||
|
|
||||||
/* load the cheat file */
|
/* load the cheat file */
|
||||||
cheatinfo->cheatlist = cheat_list_load(machine->basename);
|
cheatinfo->cheatlist = cheat_list_load(machine, machine->basename);
|
||||||
|
|
||||||
/* temporary: save the file back out as output.xml for comparison */
|
/* temporary: save the file back out as output.xml for comparison */
|
||||||
if (cheatinfo->cheatlist != NULL)
|
if (cheatinfo->cheatlist != NULL)
|
||||||
@ -221,10 +256,353 @@ void cheat_init(running_machine *machine)
|
|||||||
static void cheat_exit(running_machine *machine)
|
static void cheat_exit(running_machine *machine)
|
||||||
{
|
{
|
||||||
cheat_private *cheatinfo = machine->cheat_data;
|
cheat_private *cheatinfo = machine->cheat_data;
|
||||||
|
int linenum;
|
||||||
|
|
||||||
/* free the list of cheats */
|
/* free the list of cheats */
|
||||||
if (cheatinfo->cheatlist != NULL)
|
if (cheatinfo->cheatlist != NULL)
|
||||||
cheat_list_free(cheatinfo->cheatlist);
|
cheat_list_free(cheatinfo->cheatlist);
|
||||||
|
|
||||||
|
/* free any text strings */
|
||||||
|
for (linenum = 0; linenum < ARRAY_LENGTH(cheatinfo->output); linenum++)
|
||||||
|
if (cheatinfo->output[linenum] != NULL)
|
||||||
|
astring_free(cheatinfo->output[linenum]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
CHEAT UI
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
cheat_render_text - called by the UI system
|
||||||
|
to render text
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
void cheat_render_text(running_machine *machine)
|
||||||
|
{
|
||||||
|
cheat_private *cheatinfo = machine->cheat_data;
|
||||||
|
if (cheatinfo != NULL)
|
||||||
|
{
|
||||||
|
int linenum;
|
||||||
|
|
||||||
|
/* render any text and free it along the way */
|
||||||
|
for (linenum = 0; linenum < ARRAY_LENGTH(cheatinfo->output); linenum++)
|
||||||
|
if (cheatinfo->output[linenum] != NULL)
|
||||||
|
{
|
||||||
|
/* output the text */
|
||||||
|
ui_draw_text_full(astring_c(cheatinfo->output[linenum]),
|
||||||
|
0.0f, (float)linenum * ui_get_line_height(), 1.0f,
|
||||||
|
cheatinfo->justify[linenum], WRAP_NEVER, DRAW_OPAQUE,
|
||||||
|
ARGB_WHITE, ARGB_BLACK, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
cheat_get_next_menu_entry - return the
|
||||||
|
text needed to display this cheat in a menu
|
||||||
|
item
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
void *cheat_get_next_menu_entry(running_machine *machine, void *previous, const char **description, const char **state, UINT32 *flags)
|
||||||
|
{
|
||||||
|
cheat_private *cheatinfo = machine->cheat_data;
|
||||||
|
cheat_entry *preventry = previous;
|
||||||
|
cheat_entry *cheat;
|
||||||
|
|
||||||
|
/* NULL previous means get the first */
|
||||||
|
cheat = (preventry == NULL) ? cheatinfo->cheatlist : preventry->next;
|
||||||
|
if (cheat == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* description is standard */
|
||||||
|
if (description != NULL)
|
||||||
|
*description = astring_c(cheat->description);
|
||||||
|
|
||||||
|
/* if we have no parameter, it's just on/off */
|
||||||
|
if (cheat->parameter == NULL)
|
||||||
|
{
|
||||||
|
if (state != NULL)
|
||||||
|
*state = (cheat->state == SCRIPT_STATE_RUN) ? "On" : "Off";
|
||||||
|
if (flags != NULL)
|
||||||
|
*flags = cheat->state ? MENU_FLAG_LEFT_ARROW : MENU_FLAG_RIGHT_ARROW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we have a value parameter, compute it */
|
||||||
|
else if (cheat->parameter->itemlist == NULL)
|
||||||
|
{
|
||||||
|
if (state != NULL)
|
||||||
|
{
|
||||||
|
sprintf(cheat->parameter->valuestring, "%d", (UINT32)cheat->parameter->value);
|
||||||
|
*state = cheat->parameter->valuestring;
|
||||||
|
}
|
||||||
|
if (flags != NULL)
|
||||||
|
{
|
||||||
|
*flags = 0;
|
||||||
|
if (cheat->parameter->value > cheat->parameter->minval)
|
||||||
|
*flags |= MENU_FLAG_LEFT_ARROW;
|
||||||
|
if (cheat->parameter->value < cheat->parameter->maxval)
|
||||||
|
*flags |= MENU_FLAG_RIGHT_ARROW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we have an item list, pick the index */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parameter_item *item, *prev = NULL;
|
||||||
|
|
||||||
|
for (item = cheat->parameter->itemlist; item != NULL; prev = item, item = item->next)
|
||||||
|
if (item->value == cheat->parameter->value)
|
||||||
|
break;
|
||||||
|
if (state != NULL)
|
||||||
|
*state = (item != NULL) ? astring_c(item->text) : "??Invalid??";
|
||||||
|
if (flags != NULL)
|
||||||
|
{
|
||||||
|
*flags = 0;
|
||||||
|
if (item == NULL || prev != NULL)
|
||||||
|
*flags |= MENU_FLAG_LEFT_ARROW;
|
||||||
|
if (item == NULL || item->next != NULL)
|
||||||
|
*flags |= MENU_FLAG_RIGHT_ARROW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return a pointer to this item */
|
||||||
|
return cheat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
cheat_select_previous_state - select the
|
||||||
|
previous state for a cheat
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
int cheat_select_previous_state(running_machine *machine, void *entry)
|
||||||
|
{
|
||||||
|
cheat_private *cheatinfo = machine->cheat_data;
|
||||||
|
cheat_entry *cheat = entry;
|
||||||
|
int changed = FALSE;
|
||||||
|
|
||||||
|
/* if we have no parameter, it's just on/off */
|
||||||
|
if (cheat->parameter == NULL)
|
||||||
|
{
|
||||||
|
if (cheat->state != SCRIPT_STATE_OFF)
|
||||||
|
{
|
||||||
|
cheat->state = SCRIPT_STATE_OFF;
|
||||||
|
cheat_execute_script(cheatinfo, cheat, SCRIPT_STATE_OFF);
|
||||||
|
changed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we have a value parameter, compute it */
|
||||||
|
else if (cheat->parameter->itemlist == NULL)
|
||||||
|
{
|
||||||
|
if (cheat->parameter->value > cheat->parameter->minval)
|
||||||
|
{
|
||||||
|
if (cheat->parameter->value < cheat->parameter->minval + cheat->parameter->stepval)
|
||||||
|
cheat->parameter->value = cheat->parameter->minval;
|
||||||
|
else
|
||||||
|
cheat->parameter->value -= cheat->parameter->stepval;
|
||||||
|
cheat_execute_script(cheatinfo, cheat, SCRIPT_STATE_CHANGE);
|
||||||
|
changed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we have an item list, pick the index */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parameter_item *item, *prev = NULL;
|
||||||
|
|
||||||
|
for (item = cheat->parameter->itemlist; item != NULL; prev = item, item = item->next)
|
||||||
|
if (item->value == cheat->parameter->value)
|
||||||
|
break;
|
||||||
|
if (prev != NULL)
|
||||||
|
{
|
||||||
|
cheat->parameter->value = prev->value;
|
||||||
|
cheat_execute_script(cheatinfo, cheat, SCRIPT_STATE_CHANGE);
|
||||||
|
changed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
cheat_select_next_state - select the
|
||||||
|
next state for a cheat
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
int cheat_select_next_state(running_machine *machine, void *entry)
|
||||||
|
{
|
||||||
|
cheat_private *cheatinfo = machine->cheat_data;
|
||||||
|
cheat_entry *cheat = entry;
|
||||||
|
int changed = FALSE;
|
||||||
|
|
||||||
|
/* if we have no parameter, it's just on/off */
|
||||||
|
if (cheat->parameter == NULL)
|
||||||
|
{
|
||||||
|
if (cheat->state != SCRIPT_STATE_RUN)
|
||||||
|
{
|
||||||
|
cheat->state = SCRIPT_STATE_RUN;
|
||||||
|
cheat_execute_script(cheatinfo, cheat, SCRIPT_STATE_ON);
|
||||||
|
changed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we have a value parameter, compute it */
|
||||||
|
else if (cheat->parameter->itemlist == NULL)
|
||||||
|
{
|
||||||
|
if (cheat->parameter->value < cheat->parameter->maxval)
|
||||||
|
{
|
||||||
|
if (cheat->parameter->value > cheat->parameter->maxval - cheat->parameter->stepval)
|
||||||
|
cheat->parameter->value = cheat->parameter->maxval;
|
||||||
|
else
|
||||||
|
cheat->parameter->value += cheat->parameter->stepval;
|
||||||
|
cheat_execute_script(cheatinfo, cheat, SCRIPT_STATE_CHANGE);
|
||||||
|
changed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we have an item list, pick the index */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parameter_item *item;
|
||||||
|
|
||||||
|
for (item = cheat->parameter->itemlist; item != NULL; item = item->next)
|
||||||
|
if (item->value == cheat->parameter->value)
|
||||||
|
break;
|
||||||
|
if (item->next != NULL)
|
||||||
|
{
|
||||||
|
cheat->parameter->value = item->next->value;
|
||||||
|
cheat_execute_script(cheatinfo, cheat, SCRIPT_STATE_CHANGE);
|
||||||
|
changed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
CHEAT EXECUTION
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
cheat_frame - per-frame callback
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void cheat_frame(running_machine *machine)
|
||||||
|
{
|
||||||
|
cheat_private *cheatinfo = machine->cheat_data;
|
||||||
|
cheat_entry *cheat;
|
||||||
|
int linenum;
|
||||||
|
|
||||||
|
/* set up for accumulating output */
|
||||||
|
cheatinfo->lastline = 0;
|
||||||
|
cheatinfo->numlines = floor(1.0f / ui_get_line_height());
|
||||||
|
cheatinfo->numlines = MIN(cheatinfo->numlines, ARRAY_LENGTH(cheatinfo->output));
|
||||||
|
for (linenum = 0; linenum < ARRAY_LENGTH(cheatinfo->output); linenum++)
|
||||||
|
if (cheatinfo->output[linenum] != NULL)
|
||||||
|
{
|
||||||
|
astring_free(cheatinfo->output[linenum]);
|
||||||
|
cheatinfo->output[linenum] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* iterate over running cheats and execute them */
|
||||||
|
for (cheat = cheatinfo->cheatlist; cheat != NULL; cheat = cheat->next)
|
||||||
|
if (cheat->state == SCRIPT_STATE_RUN)
|
||||||
|
cheat_execute_script(cheatinfo, cheat, SCRIPT_STATE_RUN);
|
||||||
|
|
||||||
|
/* increment the frame counter */
|
||||||
|
cheatinfo->framecount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
cheat_execute_script - execute the
|
||||||
|
appropriate script
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void cheat_execute_script(cheat_private *cheatinfo, cheat_entry *cheat, script_state state)
|
||||||
|
{
|
||||||
|
script_entry *entry;
|
||||||
|
|
||||||
|
/* if no script, bail */
|
||||||
|
if (cheat->script[state] == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* iterate over entries */
|
||||||
|
for (entry = cheat->script[state]->entrylist; entry != NULL; entry = entry->next)
|
||||||
|
{
|
||||||
|
EXPRERR error;
|
||||||
|
UINT64 result;
|
||||||
|
|
||||||
|
/* evaluate the condition */
|
||||||
|
if (entry->condition != NULL)
|
||||||
|
{
|
||||||
|
error = expression_execute(entry->condition, &result);
|
||||||
|
if (error != EXPRERR_NONE)
|
||||||
|
mame_printf_warning("Error executing conditional expression \"%s\": %s\n", expression_original_string(entry->condition), exprerr_to_string(error));
|
||||||
|
|
||||||
|
/* if the condition is false, or we got an error, don't execute */
|
||||||
|
if (error != EXPRERR_NONE || result == 0)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if there is an action, execute it */
|
||||||
|
if (entry->expression != NULL)
|
||||||
|
{
|
||||||
|
error = expression_execute(entry->expression, &result);
|
||||||
|
if (error != EXPRERR_NONE)
|
||||||
|
mame_printf_warning("Error executing expression \"%s\": %s\n", expression_original_string(entry->expression), exprerr_to_string(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if there is a string to display, compute it */
|
||||||
|
if (entry->format != NULL)
|
||||||
|
{
|
||||||
|
UINT64 params[MAX_ARGUMENTS];
|
||||||
|
output_argument *arg;
|
||||||
|
astring *string;
|
||||||
|
int curarg = 0;
|
||||||
|
int row;
|
||||||
|
|
||||||
|
/* iterate over arguments and evaluate them */
|
||||||
|
for (arg = entry->arglist; arg != NULL; arg = arg->next)
|
||||||
|
for (cheat->argindex = 0; cheat->argindex < arg->count; cheat->argindex++)
|
||||||
|
{
|
||||||
|
error = expression_execute(arg->expression, ¶ms[curarg++]);
|
||||||
|
if (error != EXPRERR_NONE)
|
||||||
|
mame_printf_warning("Error executing argument expression \"%s\": %s\n", expression_original_string(arg->expression), exprerr_to_string(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* determine which row we belong to */
|
||||||
|
row = entry->line;
|
||||||
|
if (row == 0)
|
||||||
|
row = (cheatinfo->lastline >= 0) ? cheatinfo->lastline + 1 : cheatinfo->lastline - 1;
|
||||||
|
cheatinfo->lastline = row;
|
||||||
|
row = (row < 0) ? cheatinfo->numlines + row : row - 1;
|
||||||
|
row = MAX(row, 0);
|
||||||
|
row = MIN(row, cheatinfo->numlines - 1);
|
||||||
|
|
||||||
|
/* either re-use or allocate a string */
|
||||||
|
string = cheatinfo->output[row];
|
||||||
|
if (string == NULL)
|
||||||
|
string = cheatinfo->output[row] = astring_alloc();
|
||||||
|
cheatinfo->justify[row] = entry->justify;
|
||||||
|
|
||||||
|
/* generate the astring */
|
||||||
|
astring_printf(string, astring_c(entry->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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -238,7 +616,7 @@ static void cheat_exit(running_machine *machine)
|
|||||||
memory and create the cheat entry list
|
memory and create the cheat entry list
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
static cheat_entry *cheat_list_load(const char *filename)
|
static cheat_entry *cheat_list_load(running_machine *machine, const char *filename)
|
||||||
{
|
{
|
||||||
xml_data_node *rootnode, *mamecheatnode, *cheatnode;
|
xml_data_node *rootnode, *mamecheatnode, *cheatnode;
|
||||||
cheat_entry *cheatlist = NULL;
|
cheat_entry *cheatlist = NULL;
|
||||||
@ -294,7 +672,7 @@ static cheat_entry *cheat_list_load(const char *filename)
|
|||||||
for (cheatnode = xml_get_sibling(mamecheatnode->child, "cheat"); cheatnode != NULL; cheatnode = xml_get_sibling(cheatnode->next, "cheat"))
|
for (cheatnode = xml_get_sibling(mamecheatnode->child, "cheat"); cheatnode != NULL; cheatnode = xml_get_sibling(cheatnode->next, "cheat"))
|
||||||
{
|
{
|
||||||
/* load this entry */
|
/* load this entry */
|
||||||
cheat_entry *curcheat = cheat_entry_load(filename, cheatnode);
|
cheat_entry *curcheat = cheat_entry_load(machine, filename, cheatnode);
|
||||||
if (curcheat == NULL)
|
if (curcheat == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -371,9 +749,10 @@ static void cheat_list_free(cheat_entry *cheat)
|
|||||||
structures
|
structures
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
static cheat_entry *cheat_entry_load(const char *filename, xml_data_node *cheatnode)
|
static cheat_entry *cheat_entry_load(running_machine *machine, const char *filename, xml_data_node *cheatnode)
|
||||||
{
|
{
|
||||||
xml_data_node *paramnode, *scriptnode;
|
cheat_private *cheatinfo = machine->cheat_data;
|
||||||
|
xml_data_node *paramnode, *scriptnode, *commentnode;
|
||||||
const char *description;
|
const char *description;
|
||||||
int tempcount, curtemp;
|
int tempcount, curtemp;
|
||||||
cheat_entry *cheat;
|
cheat_entry *cheat;
|
||||||
@ -402,6 +781,8 @@ static cheat_entry *cheat_entry_load(const char *filename, xml_data_node *cheatn
|
|||||||
|
|
||||||
/* create the symbol table */
|
/* create the symbol table */
|
||||||
cheat->symbols = symtable_alloc(NULL);
|
cheat->symbols = symtable_alloc(NULL);
|
||||||
|
symtable_add_register(cheat->symbols, "frame", &cheatinfo->framecount, cheat_variable_get, NULL);
|
||||||
|
symtable_add_register(cheat->symbols, "argindex", &cheat->argindex, cheat_variable_get, NULL);
|
||||||
for (curtemp = 0; curtemp < tempcount; curtemp++)
|
for (curtemp = 0; curtemp < tempcount; curtemp++)
|
||||||
{
|
{
|
||||||
char tempname[20];
|
char tempname[20];
|
||||||
@ -409,6 +790,19 @@ static cheat_entry *cheat_entry_load(const char *filename, xml_data_node *cheatn
|
|||||||
symtable_add_register(cheat->symbols, tempname, &cheat->tempvar[curtemp], cheat_variable_get, cheat_variable_set);
|
symtable_add_register(cheat->symbols, tempname, &cheat->tempvar[curtemp], cheat_variable_get, cheat_variable_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* read the first comment node */
|
||||||
|
commentnode = xml_get_sibling(cheatnode->child, "comment");
|
||||||
|
if (commentnode != NULL)
|
||||||
|
{
|
||||||
|
if (commentnode->value != NULL && commentnode->value[0] != 0)
|
||||||
|
cheat->comment = astring_dupc(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 */
|
/* read the first parameter node */
|
||||||
paramnode = xml_get_sibling(cheatnode->child, "parameter");
|
paramnode = xml_get_sibling(cheatnode->child, "parameter");
|
||||||
if (paramnode != NULL)
|
if (paramnode != NULL)
|
||||||
@ -420,7 +814,7 @@ static cheat_entry *cheat_entry_load(const char *filename, xml_data_node *cheatn
|
|||||||
|
|
||||||
/* set this as the parameter and add the symbol */
|
/* set this as the parameter and add the symbol */
|
||||||
cheat->parameter = curparam;
|
cheat->parameter = curparam;
|
||||||
symtable_add_register(cheat->symbols, astring_c(curparam->name), &curparam->value, cheat_variable_get, cheat_variable_set);
|
symtable_add_register(cheat->symbols, "param", &curparam->value, cheat_variable_get, NULL);
|
||||||
|
|
||||||
/* only one parameter allowed */
|
/* only one parameter allowed */
|
||||||
paramnode = xml_get_sibling(paramnode->next, "parameter");
|
paramnode = xml_get_sibling(paramnode->next, "parameter");
|
||||||
@ -444,6 +838,9 @@ static cheat_entry *cheat_entry_load(const char *filename, xml_data_node *cheatn
|
|||||||
else
|
else
|
||||||
cheat->script[curscript->state] = curscript;
|
cheat->script[curscript->state] = curscript;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set the initial state */
|
||||||
|
cheat->state = (cheat->parameter != NULL) ? SCRIPT_STATE_RUN : SCRIPT_STATE_OFF;
|
||||||
return cheat;
|
return cheat;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -453,8 +850,8 @@ error:
|
|||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
cheat_entry_save - save a single cheat
|
cheat_entry_save - save a single cheat
|
||||||
entry
|
entry
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
static void cheat_entry_save(mame_file *cheatfile, const cheat_entry *cheat)
|
static void cheat_entry_save(mame_file *cheatfile, const cheat_entry *cheat)
|
||||||
@ -466,6 +863,10 @@ static void cheat_entry_save(mame_file *cheatfile, const cheat_entry *cheat)
|
|||||||
if (cheat->numtemp != DEFAULT_TEMP_VARIABLES)
|
if (cheat->numtemp != DEFAULT_TEMP_VARIABLES)
|
||||||
mame_fprintf(cheatfile, " tempvariables=\"%d\"", cheat->numtemp);
|
mame_fprintf(cheatfile, " tempvariables=\"%d\"", cheat->numtemp);
|
||||||
mame_fprintf(cheatfile, ">\n");
|
mame_fprintf(cheatfile, ">\n");
|
||||||
|
|
||||||
|
/* save the comment */
|
||||||
|
if (cheat->comment != NULL)
|
||||||
|
mame_fprintf(cheatfile, "\t\t<comment><![CDATA[\n%s\n\t\t]]></comment>\n", astring_c(cheat->comment));
|
||||||
|
|
||||||
/* output the parameter, if present */
|
/* output the parameter, if present */
|
||||||
if (cheat->parameter != NULL)
|
if (cheat->parameter != NULL)
|
||||||
@ -482,7 +883,7 @@ static void cheat_entry_save(mame_file *cheatfile, const cheat_entry *cheat)
|
|||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
cheat_entry_free - free a single cheat entry
|
cheat_entry_free - free a single cheat entry
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
static void cheat_entry_free(cheat_entry *cheat)
|
static void cheat_entry_free(cheat_entry *cheat)
|
||||||
@ -492,6 +893,9 @@ static void cheat_entry_free(cheat_entry *cheat)
|
|||||||
if (cheat->description != NULL)
|
if (cheat->description != NULL)
|
||||||
astring_free(cheat->description);
|
astring_free(cheat->description);
|
||||||
|
|
||||||
|
if (cheat->comment != NULL)
|
||||||
|
astring_free(cheat->comment);
|
||||||
|
|
||||||
if (cheat->parameter != NULL)
|
if (cheat->parameter != NULL)
|
||||||
cheat_parameter_free(cheat->parameter);
|
cheat_parameter_free(cheat->parameter);
|
||||||
|
|
||||||
@ -507,9 +911,9 @@ static void cheat_entry_free(cheat_entry *cheat)
|
|||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
cheat_parameter_load - load a single cheat
|
cheat_parameter_load - load a single cheat
|
||||||
parameter and create the underlying data
|
parameter and create the underlying data
|
||||||
structures
|
structures
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
static cheat_parameter *cheat_parameter_load(const char *filename, xml_data_node *paramnode)
|
static cheat_parameter *cheat_parameter_load(const char *filename, xml_data_node *paramnode)
|
||||||
@ -523,10 +927,10 @@ static cheat_parameter *cheat_parameter_load(const char *filename, xml_data_node
|
|||||||
memset(param, 0, sizeof(*param));
|
memset(param, 0, sizeof(*param));
|
||||||
|
|
||||||
/* read the core attributes */
|
/* read the core attributes */
|
||||||
param->name = astring_dupc(xml_get_attribute_string(paramnode, "variable", "param"));
|
|
||||||
param->minval = xml_get_attribute_int(paramnode, "min", 0);
|
param->minval = xml_get_attribute_int(paramnode, "min", 0);
|
||||||
param->maxval = xml_get_attribute_int(paramnode, "max", 0);
|
param->maxval = xml_get_attribute_int(paramnode, "max", 0);
|
||||||
param->stepval = xml_get_attribute_int(paramnode, "step", 1);
|
param->stepval = xml_get_attribute_int(paramnode, "step", 1);
|
||||||
|
param->defval = xml_get_attribute_int(paramnode, "default", param->minval);
|
||||||
|
|
||||||
/* iterate over items */
|
/* iterate over items */
|
||||||
itemtailptr = ¶m->itemlist;
|
itemtailptr = ¶m->itemlist;
|
||||||
@ -553,11 +957,20 @@ static cheat_parameter *cheat_parameter_load(const char *filename, xml_data_node
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
curitem->value = xml_get_attribute_int(itemnode, "value", 0);
|
curitem->value = xml_get_attribute_int(itemnode, "value", 0);
|
||||||
|
|
||||||
|
/* ensure the maximum expands to suit */
|
||||||
|
param->maxval = MAX(param->maxval, curitem->value);
|
||||||
|
|
||||||
/* add to the end of the list */
|
/* add to the end of the list */
|
||||||
*itemtailptr = curitem;
|
*itemtailptr = curitem;
|
||||||
itemtailptr = &curitem->next;
|
itemtailptr = &curitem->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if no default, pick the minimum */
|
||||||
|
if (xml_get_attribute_string(paramnode, "default", NULL) == NULL)
|
||||||
|
param->defval = (param->itemlist != NULL) ? param->itemlist->value : param->minval;
|
||||||
|
param->value = param->defval;
|
||||||
|
|
||||||
return param;
|
return param;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -574,7 +987,7 @@ error:
|
|||||||
static void cheat_parameter_save(mame_file *cheatfile, const cheat_parameter *param)
|
static void cheat_parameter_save(mame_file *cheatfile, const cheat_parameter *param)
|
||||||
{
|
{
|
||||||
/* output the parameter tag */
|
/* output the parameter tag */
|
||||||
mame_fprintf(cheatfile, "\t\t<parameter variable=\"%s\"", astring_c(param->name));
|
mame_fprintf(cheatfile, "\t\t<parameter");
|
||||||
|
|
||||||
/* if no items, just output min/max/step */
|
/* if no items, just output min/max/step */
|
||||||
if (param->itemlist == NULL)
|
if (param->itemlist == NULL)
|
||||||
@ -585,6 +998,7 @@ static void cheat_parameter_save(mame_file *cheatfile, const cheat_parameter *pa
|
|||||||
mame_fprintf(cheatfile, " max=\"%d\"", (UINT32)param->maxval);
|
mame_fprintf(cheatfile, " max=\"%d\"", (UINT32)param->maxval);
|
||||||
if (param->stepval != 1)
|
if (param->stepval != 1)
|
||||||
mame_fprintf(cheatfile, " step=\"%d\"", (UINT32)param->stepval);
|
mame_fprintf(cheatfile, " step=\"%d\"", (UINT32)param->stepval);
|
||||||
|
mame_fprintf(cheatfile, " default=\"%d\"", (UINT32)param->defval);
|
||||||
mame_fprintf(cheatfile, "/>\n");
|
mame_fprintf(cheatfile, "/>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -593,7 +1007,7 @@ static void cheat_parameter_save(mame_file *cheatfile, const cheat_parameter *pa
|
|||||||
{
|
{
|
||||||
const parameter_item *curitem;
|
const parameter_item *curitem;
|
||||||
|
|
||||||
mame_fprintf(cheatfile, ">\n");
|
mame_fprintf(cheatfile, " default=\"%d\">\n", (UINT32)param->defval);
|
||||||
for (curitem = param->itemlist; curitem != NULL; curitem = curitem->next)
|
for (curitem = param->itemlist; curitem != NULL; curitem = curitem->next)
|
||||||
mame_fprintf(cheatfile, "\t\t\t<item value=\"%d\">%s</item>\n", (UINT32)curitem->value, astring_c(curitem->text));
|
mame_fprintf(cheatfile, "\t\t\t<item value=\"%d\">%s</item>\n", (UINT32)curitem->value, astring_c(curitem->text));
|
||||||
mame_fprintf(cheatfile, "\t\t</parameter>\n");
|
mame_fprintf(cheatfile, "\t\t</parameter>\n");
|
||||||
@ -608,9 +1022,6 @@ static void cheat_parameter_save(mame_file *cheatfile, const cheat_parameter *pa
|
|||||||
|
|
||||||
static void cheat_parameter_free(cheat_parameter *param)
|
static void cheat_parameter_free(cheat_parameter *param)
|
||||||
{
|
{
|
||||||
if (param->name != NULL)
|
|
||||||
astring_free(param->name);
|
|
||||||
|
|
||||||
while (param->itemlist != NULL)
|
while (param->itemlist != NULL)
|
||||||
{
|
{
|
||||||
parameter_item *item = param->itemlist;
|
parameter_item *item = param->itemlist;
|
||||||
@ -674,8 +1085,8 @@ static cheat_script *cheat_script_load(const char *filename, xml_data_node *scri
|
|||||||
/* anything else is ignored */
|
/* anything else is ignored */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mame_printf_warning("%s.xml(%d): unknown script item '%s' will be lost if saved\n", filename, curentry->line, entrynode->name);
|
mame_printf_warning("%s.xml(%d): unknown script item '%s' will be lost if saved\n", filename, entrynode->line, entrynode->name);
|
||||||
goto error;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curentry == NULL)
|
if (curentry == NULL)
|
||||||
@ -792,6 +1203,7 @@ static script_entry *script_entry_load(const char *filename, xml_data_node *entr
|
|||||||
output_argument **argtailptr;
|
output_argument **argtailptr;
|
||||||
const char *align, *format;
|
const char *align, *format;
|
||||||
xml_data_node *argnode;
|
xml_data_node *argnode;
|
||||||
|
int totalargs = 0;
|
||||||
|
|
||||||
/* extract format */
|
/* extract format */
|
||||||
format = xml_get_attribute_string(entrynode, "format", NULL);
|
format = xml_get_attribute_string(entrynode, "format", NULL);
|
||||||
@ -828,6 +1240,7 @@ static script_entry *script_entry_load(const char *filename, xml_data_node *entr
|
|||||||
|
|
||||||
/* first extract attributes */
|
/* first extract attributes */
|
||||||
curarg->count = xml_get_attribute_int(argnode, "count", 1);
|
curarg->count = xml_get_attribute_int(argnode, "count", 1);
|
||||||
|
totalargs += curarg->count;
|
||||||
|
|
||||||
/* read the expression */
|
/* read the expression */
|
||||||
expression = argnode->value;
|
expression = argnode->value;
|
||||||
@ -847,6 +1260,13 @@ static script_entry *script_entry_load(const char *filename, xml_data_node *entr
|
|||||||
*argtailptr = curarg;
|
*argtailptr = curarg;
|
||||||
argtailptr = &curarg->next;
|
argtailptr = &curarg->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* max out on arguments */
|
||||||
|
if (totalargs > MAX_ARGUMENTS)
|
||||||
|
{
|
||||||
|
mame_printf_error("%s.xml(%d): too many arguments (found %d, max is %d)\n", filename, argnode->line, totalargs, MAX_ARGUMENTS);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* validate the format against the arguments */
|
/* validate the format against the arguments */
|
||||||
if (!validate_format(filename, entrynode->line, entry))
|
if (!validate_format(filename, entrynode->line, entry))
|
||||||
@ -861,8 +1281,8 @@ error:
|
|||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
script_entry_save - save a single action
|
script_entry_save - save a single action
|
||||||
or output
|
or output
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
static void script_entry_save(mame_file *cheatfile, const script_entry *entry)
|
static void script_entry_save(mame_file *cheatfile, const script_entry *entry)
|
||||||
@ -875,10 +1295,10 @@ static void script_entry_save(mame_file *cheatfile, const script_entry *entry)
|
|||||||
mame_fprintf(cheatfile, "\t\t\t<action");
|
mame_fprintf(cheatfile, "\t\t\t<action");
|
||||||
if (entry->condition != NULL)
|
if (entry->condition != NULL)
|
||||||
{
|
{
|
||||||
quote_astring(astring_cpyc(tempstring, expression_original_string(entry->condition)), TRUE);
|
quote_astring_expression(astring_cpyc(tempstring, expression_original_string(entry->condition)), TRUE);
|
||||||
mame_fprintf(cheatfile, " condition=\"%s\"", astring_c(tempstring));
|
mame_fprintf(cheatfile, " condition=\"%s\"", astring_c(tempstring));
|
||||||
}
|
}
|
||||||
quote_astring(astring_cpyc(tempstring, expression_original_string(entry->expression)), FALSE);
|
quote_astring_expression(astring_cpyc(tempstring, expression_original_string(entry->expression)), FALSE);
|
||||||
mame_fprintf(cheatfile, ">%s</action>\n", astring_c(tempstring));
|
mame_fprintf(cheatfile, ">%s</action>\n", astring_c(tempstring));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -888,7 +1308,7 @@ static void script_entry_save(mame_file *cheatfile, const script_entry *entry)
|
|||||||
mame_fprintf(cheatfile, "\t\t\t<output format=\"%s\"", astring_c(entry->format));
|
mame_fprintf(cheatfile, "\t\t\t<output format=\"%s\"", astring_c(entry->format));
|
||||||
if (entry->condition != NULL)
|
if (entry->condition != NULL)
|
||||||
{
|
{
|
||||||
quote_astring(astring_cpyc(tempstring, expression_original_string(entry->condition)), TRUE);
|
quote_astring_expression(astring_cpyc(tempstring, expression_original_string(entry->condition)), TRUE);
|
||||||
mame_fprintf(cheatfile, " condition=\"%s\"", astring_c(tempstring));
|
mame_fprintf(cheatfile, " condition=\"%s\"", astring_c(tempstring));
|
||||||
}
|
}
|
||||||
if (entry->line != 0)
|
if (entry->line != 0)
|
||||||
@ -911,7 +1331,7 @@ static void script_entry_save(mame_file *cheatfile, const script_entry *entry)
|
|||||||
mame_fprintf(cheatfile, "\t\t\t\t<argument");
|
mame_fprintf(cheatfile, "\t\t\t\t<argument");
|
||||||
if (curarg->count != 1)
|
if (curarg->count != 1)
|
||||||
mame_fprintf(cheatfile, " count=\"%d\"", (int)curarg->count);
|
mame_fprintf(cheatfile, " count=\"%d\"", (int)curarg->count);
|
||||||
quote_astring(astring_cpyc(tempstring, expression_original_string(curarg->expression)), FALSE);
|
quote_astring_expression(astring_cpyc(tempstring, expression_original_string(curarg->expression)), FALSE);
|
||||||
mame_fprintf(cheatfile, ">%s</argument>\n", astring_c(tempstring));
|
mame_fprintf(cheatfile, ">%s</argument>\n", astring_c(tempstring));
|
||||||
}
|
}
|
||||||
mame_fprintf(cheatfile, "\t\t\t</output>\n");
|
mame_fprintf(cheatfile, "\t\t\t</output>\n");
|
||||||
@ -923,8 +1343,8 @@ static void script_entry_save(mame_file *cheatfile, const script_entry *entry)
|
|||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
script_entry_free - free a single script
|
script_entry_free - free a single script
|
||||||
entry
|
entry
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
static void script_entry_free(script_entry *entry)
|
static void script_entry_free(script_entry *entry)
|
||||||
@ -956,23 +1376,33 @@ static void script_entry_free(script_entry *entry)
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
quote_astring - quote a string so that it
|
quote_astring_expression - quote an expression
|
||||||
is valid to embed in an XML document
|
string so that it is valid to embed in an XML
|
||||||
|
document
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
static astring *quote_astring(astring *string, int isattribute)
|
static astring *quote_astring_expression(astring *string, int isattribute)
|
||||||
{
|
{
|
||||||
astring_replacec(string, 0, "&", "&");
|
|
||||||
astring_replacec(string, 0, "<", "<");
|
|
||||||
if (isattribute)
|
if (isattribute)
|
||||||
astring_replacec(string, 0, "\"", """);
|
{
|
||||||
|
astring_replacec(string, 0, "&", "&");
|
||||||
|
astring_replacec(string, 0, "<", "<");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (astring_chr(string, 0, '&') != -1 || astring_chr(string, 0, '<') != -1)
|
||||||
|
{
|
||||||
|
astring_insc(string, 0, "<![CDATA[ ");
|
||||||
|
astring_catc(string, " ]]>");
|
||||||
|
}
|
||||||
|
}
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
validate_format - check that a format string
|
validate_format - check that a format string
|
||||||
has the correct number and type of arguments
|
has the correct number and type of arguments
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
static int validate_format(const char *filename, int line, const script_entry *entry)
|
static int validate_format(const char *filename, int line, const script_entry *entry)
|
||||||
|
@ -16,6 +16,33 @@
|
|||||||
|
|
||||||
#include "mamecore.h"
|
#include "mamecore.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
FUNCTION PROTOTYPES
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- core system management ----- */
|
||||||
|
|
||||||
|
/* initialize the cheat system, loading any cheat files */
|
||||||
void cheat_init(running_machine *machine);
|
void cheat_init(running_machine *machine);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- cheat UI helpers ----- */
|
||||||
|
|
||||||
|
/* render any text overlays */
|
||||||
|
void cheat_render_text(running_machine *machine);
|
||||||
|
|
||||||
|
/* return data about the next menu entry, or the first entry if previous == NULL */
|
||||||
|
void *cheat_get_next_menu_entry(running_machine *machine, void *previous, const char **description, const char **state, UINT32 *flags);
|
||||||
|
|
||||||
|
/* select the previous menu state */
|
||||||
|
int cheat_select_previous_state(running_machine *machine, void *entry);
|
||||||
|
|
||||||
|
/* select the next menu state */
|
||||||
|
int cheat_select_next_state(running_machine *machine, void *entry);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __CHEAT_H__ */
|
#endif /* __CHEAT_H__ */
|
||||||
|
@ -429,6 +429,9 @@ void ui_update_and_render(running_machine *machine)
|
|||||||
if (alpha >= 0)
|
if (alpha >= 0)
|
||||||
render_ui_add_rect(0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(alpha,0x00,0x00,0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
|
render_ui_add_rect(0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(alpha,0x00,0x00,0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* render any cheat stuff at the bottom */
|
||||||
|
cheat_render_text(machine);
|
||||||
|
|
||||||
/* call the current UI handler */
|
/* call the current UI handler */
|
||||||
assert(ui_handler_callback != NULL);
|
assert(ui_handler_callback != NULL);
|
||||||
|
@ -24,7 +24,8 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/* preferred font height; use ui_get_line_height() to get actual height */
|
/* preferred font height; use ui_get_line_height() to get actual height */
|
||||||
#define UI_TARGET_FONT_HEIGHT (1.0f / 25.0f)
|
#define UI_TARGET_FONT_ROWS (25)
|
||||||
|
#define UI_TARGET_FONT_HEIGHT (1.0f / (float)UI_TARGET_FONT_ROWS)
|
||||||
#define UI_MAX_FONT_HEIGHT (1.0f / 15.0f)
|
#define UI_MAX_FONT_HEIGHT (1.0f / 15.0f)
|
||||||
|
|
||||||
/* width of lines drawn in the UI */
|
/* width of lines drawn in the UI */
|
||||||
|
@ -271,6 +271,8 @@ static void menu_bookkeeping(running_machine *machine, ui_menu *menu, void *para
|
|||||||
static void menu_bookkeeping_populate(running_machine *machine, ui_menu *menu, attotime *curtime);
|
static void menu_bookkeeping_populate(running_machine *machine, ui_menu *menu, attotime *curtime);
|
||||||
#endif
|
#endif
|
||||||
static void menu_game_info(running_machine *machine, ui_menu *menu, void *parameter, void *state);
|
static void menu_game_info(running_machine *machine, ui_menu *menu, void *parameter, void *state);
|
||||||
|
static void menu_cheat(running_machine *machine, ui_menu *menu, void *parameter, void *state);
|
||||||
|
static void menu_cheat_populate(running_machine *machine, ui_menu *menu);
|
||||||
static void menu_memory_card(running_machine *machine, ui_menu *menu, void *parameter, void *state);
|
static void menu_memory_card(running_machine *machine, ui_menu *menu, void *parameter, void *state);
|
||||||
static void menu_memory_card_populate(running_machine *machine, ui_menu *menu, int cardnum);
|
static void menu_memory_card_populate(running_machine *machine, ui_menu *menu, int cardnum);
|
||||||
static void menu_video_targets(running_machine *machine, ui_menu *menu, void *parameter, void *state);
|
static void menu_video_targets(running_machine *machine, ui_menu *menu, void *parameter, void *state);
|
||||||
@ -1459,8 +1461,8 @@ static void menu_main_populate(running_machine *machine, ui_menu *menu, void *st
|
|||||||
ui_menu_item_append(menu, "Video Options", NULL, 0, (render_target_get_indexed(1) != NULL) ? menu_video_targets : menu_video_options);
|
ui_menu_item_append(menu, "Video Options", NULL, 0, (render_target_get_indexed(1) != NULL) ? menu_video_targets : menu_video_options);
|
||||||
|
|
||||||
/* add cheat menu */
|
/* add cheat menu */
|
||||||
// if (options_get_bool(mame_options(), OPTION_CHEAT))
|
if (options_get_bool(mame_options(), OPTION_CHEAT) && cheat_get_next_menu_entry(machine, NULL, NULL, NULL, NULL) != NULL)
|
||||||
// ui_menu_item_append(menu, "Cheat", NULL, 0, menu_cheat);
|
ui_menu_item_append(menu, "Cheat", NULL, 0, menu_cheat);
|
||||||
|
|
||||||
/* add memory card menu */
|
/* add memory card menu */
|
||||||
if (machine->config->memcard_handler != NULL)
|
if (machine->config->memcard_handler != NULL)
|
||||||
@ -2415,6 +2417,70 @@ static void menu_game_info(running_machine *machine, ui_menu *menu, void *parame
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
menu_cheat - handle the cheat menu
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void menu_cheat(running_machine *machine, ui_menu *menu, void *parameter, void *state)
|
||||||
|
{
|
||||||
|
const ui_menu_event *event;
|
||||||
|
|
||||||
|
/* if the menu isn't built, populate now */
|
||||||
|
if (!ui_menu_populated(menu))
|
||||||
|
menu_cheat_populate(machine, menu);
|
||||||
|
|
||||||
|
/* process the menu */
|
||||||
|
event = ui_menu_process(menu, UI_MENU_PROCESS_LR_REPEAT);
|
||||||
|
|
||||||
|
/* handle events */
|
||||||
|
if (event != NULL && event->itemref != NULL)
|
||||||
|
{
|
||||||
|
int changed = FALSE;
|
||||||
|
|
||||||
|
switch (event->iptkey)
|
||||||
|
{
|
||||||
|
/* if selected, reset to default value */
|
||||||
|
case IPT_UI_SELECT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* left decrements */
|
||||||
|
case IPT_UI_LEFT:
|
||||||
|
changed = cheat_select_previous_state(machine, event->itemref);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* right increments */
|
||||||
|
case IPT_UI_RIGHT:
|
||||||
|
changed = cheat_select_next_state(machine, event->itemref);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if things changed, update */
|
||||||
|
if (changed)
|
||||||
|
ui_menu_reset(menu, UI_MENU_RESET_REMEMBER_REF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
menu_cheat_populate - populate the cheat menu
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void menu_cheat_populate(running_machine *machine, ui_menu *menu)
|
||||||
|
{
|
||||||
|
const char *text, *subtext;
|
||||||
|
void *curcheat;
|
||||||
|
UINT32 flags;
|
||||||
|
|
||||||
|
/* iterate over cheats */
|
||||||
|
for (curcheat = cheat_get_next_menu_entry(machine, NULL, &text, &subtext, &flags);
|
||||||
|
curcheat != NULL;
|
||||||
|
curcheat = cheat_get_next_menu_entry(machine, curcheat, &text, &subtext, &flags))
|
||||||
|
{
|
||||||
|
ui_menu_item_append(menu, text, subtext, flags, curcheat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
menu_memory_card - handle the memory card
|
menu_memory_card - handle the memory card
|
||||||
menu
|
menu
|
||||||
|
Loading…
Reference in New Issue
Block a user