summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/validity.c
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2008-05-15 16:25:03 +0000
committer Aaron Giles <aaron@aarongiles.com>2008-05-15 16:25:03 +0000
commit096331c8562467a67fb5674f46dbb26bb032d2a6 (patch)
tree1f9329631b6fb62a81f4bdd894403389d2f70759 /src/emu/validity.c
parentbc4b470ebbee405c6f48253acc225451f52a9b70 (diff)
Restructured input port internals and cleaned up inptport.c:
* Input ports are now maintained hierarchically. At the top level are input ports, which contain a list of fields. Each field represents one or more bits of the port. Certain fields such as DIP switches and configuration switches contain a list of settings, which can be selected. DIP switch fields can also contain a list of DIP switch locations. * Normalized behavior of port overrides (via PORT_INCLUDE or by defining multiple overlapping bits). All fields within a port are kept in strict increasing bit order, so altered DIP switches are now kept in the appropriate order. This addresses MAMETesters bug 01671. * Live port state is now fully separate from configured state. This is manifested in a similar way to devices, where a const list of ports can be managed either offline or live. Each port has a pointer to an opaque set of live state which is NULL when offline or valid when live. Each port also has a running_machine * which is also NULL when offline. * Because of this new arrangement, the conversion from tokens to a list of ports now requires reasonably complex memory allocation, so these port lists must be explicitly allocated and freed (they are not mantained by automatic resource allocation). * Custom and changed callbacks now take a pointer to a field config instead of a running machine. This provides more information about what field triggered the change notification. The machine can be found by referenced field->port->machine. * The inptport.c module has been cleaned up and many ambiguities resolved. Most of this is internal, though it did result in osd_customize_inputport_list() being changed to osd_customize_input_type_list(). The parameter to this function is now a linked list instead of an array, and the structures referenced have been reorganized somewhat. * Updated config.c to pass machine parameters to its callbacks. * Updated validity checks, XML output, and UI system to handle the new structures. * Moved large table of default input settings to a separate include file inpttype.h. * Removed gross hacks in trackfld and hyperspt NVRAM. These may be broken as a result.
Diffstat (limited to 'src/emu/validity.c')
-rw-r--r--src/emu/validity.c533
1 files changed, 257 insertions, 276 deletions
diff --git a/src/emu/validity.c b/src/emu/validity.c
index d87d103f033..d0f9a464b23 100644
--- a/src/emu/validity.c
+++ b/src/emu/validity.c
@@ -947,359 +947,341 @@ static int validate_gfx(int drivnum, const machine_config *config, const UINT32
/*-------------------------------------------------
- display_valid_coin_order - display the
- correct coin order
+ get_defstr_index - return the index of the
+ string assuming it is one of the default
+ strings
-------------------------------------------------*/
-static void display_valid_coin_order(int drivnum, const input_port_entry *memory)
+static int get_defstr_index(const char *name, const game_driver *driver, int *error)
{
- const game_driver *driver = drivers[drivnum];
- const input_port_entry *inp;
- int coin_list[1024];
- int coin_len = 0;
- int i, j;
+ UINT32 crc = quark_string_crc(name);
quark_entry *entry;
-
- for (inp = memory; inp->type != IPT_END; inp++)
- {
- int strindex = 0;
- UINT32 crc;
-
- if ( !inp->name || inp->name == IP_NAME_DEFAULT )
- continue;
-
- /* hash the string and look it up in the string table */
- crc = quark_string_crc(inp->name);
- for (entry = quark_table_get_first(defstr_table, crc); entry; entry = entry->next)
- if (entry->crc == crc && !strcmp(inp->name, input_port_string_from_index(entry - defstr_table->entry)))
- {
- strindex = entry - defstr_table->entry;
- break;
- }
-
- /* if its a coin entry, add it to our list, avoiding repetitions */
- if ( strindex >= INPUT_STRING_9C_1C && strindex <= INPUT_STRING_1C_9C )
+ int strindex = 0;
+
+ /* scan the quark table of input port strings */
+ for (entry = quark_table_get_first(defstr_table, crc); entry != NULL; entry = entry->next)
+ if (entry->crc == crc && strcmp(name, input_port_string_from_index(entry - defstr_table->entry)) == 0)
{
- j = 1;
-
- for( i = 0; i < coin_len; i++ )
- {
- if ( coin_list[i] == strindex )
- {
- j = 0;
- break;
- }
- }
-
- if ( j )
- coin_list[coin_len++] = strindex;
+ strindex = entry - defstr_table->entry;
+ break;
}
- }
- /* now display the proper coin entry list */
- mame_printf_error( "%s: %s proper coin sort order should be:\n", driver->source_file, driver->name );
- for (i = INPUT_STRING_9C_1C; i <= INPUT_STRING_1C_9C; i++)
- for (j = 0; j < coin_len; j++)
- /* if it's on our list, display it */
- if (coin_list[j] == i)
- mame_printf_error("%s\n", input_port_string_from_index(i));
+ /* check for strings that should be DEF_STR */
+ if (strindex != 0 && name != input_port_string_from_index(strindex) && error != NULL)
+ {
+ mame_printf_error("%s: %s must use DEF_STR( %s )\n", driver->source_file, driver->name, name);
+ *error = TRUE;
+ }
+
+ return strindex;
}
/*-------------------------------------------------
- validate_inputs - validate input configuration
+ validate_analog_input_field - validate an
+ analog input field
-------------------------------------------------*/
-static int validate_inputs(int drivnum, const machine_config *config, input_port_entry **memory)
+static void validate_analog_input_field(const input_field_config *field, const game_driver *driver, int *error)
{
- const char *demo_sounds = input_port_string_from_index(INPUT_STRING_Demo_Sounds);
- const char *flipscreen = input_port_string_from_index(INPUT_STRING_Flip_Screen);
- const input_port_entry *inp, *last_dipname_entry = NULL;
- const game_driver *driver = drivers[drivnum];
- const char *tag[MAX_INPUT_PORTS] = { 0 };
- int portnum = 0;
- int empty_string_found = FALSE;
- int last_strindex = 0;
- quark_entry *entry;
- int error = FALSE;
- int coin_error = FALSE;
- UINT32 crc;
+ INT32 analog_max = field->max;
+ INT32 analog_min = field->min;
+ int shift;
- /* skip if no ports */
- if (!driver->ipt)
- return FALSE;
+ if (field->type == IPT_POSITIONAL || field->type == IPT_POSITIONAL_V)
+ {
+ for (shift = 0; (shift <= 31) && (~field->mask & (1 << shift)); shift++) ;
+ /* convert the positional max value to be in the bitmask for testing */
+ analog_max = (analog_max - 1) << shift;
- /* skip if we already validated these ports */
- crc = (FPTR)driver->ipt;
- for (entry = quark_table_get_first(inputs_table, crc); entry; entry = entry->next)
- if (entry->crc == crc && driver->ipt == drivers[entry - inputs_table->entry]->ipt)
- return FALSE;
+ /* positional port size must fit in bits used */
+ if (((field->mask >> shift) + 1) < field->max)
+ {
+ mame_printf_error("%s: %s has an analog port with a positional port size bigger then the mask size\n", driver->source_file, driver->name);
+ *error = TRUE;
+ }
+ }
+ else
+ {
+ /* only positional controls use PORT_WRAPS */
+ if (field->flags & ANALOG_FLAG_WRAPS)
+ {
+ mame_printf_error("%s: %s only positional analog ports use PORT_WRAPS\n", driver->source_file, driver->name);
+ *error = TRUE;
+ }
+ }
- /* otherwise, add ourself to the list */
- quark_add(inputs_table, drivnum, crc);
+ /* analog ports must have a valid sensitivity */
+ if (field->sensitivity == 0)
+ {
+ mame_printf_error("%s: %s has an analog port with zero sensitivity\n", driver->source_file, driver->name);
+ *error = TRUE;
+ }
- /* allocate the input ports */
- *memory = input_port_allocate(driver->ipt, *memory);
+ /* check that the default falls in the bitmask range */
+ if (field->defvalue & ~field->mask)
+ {
+ mame_printf_error("%s: %s has an analog port with a default value out of the bitmask range\n", driver->source_file, driver->name);
+ *error = TRUE;
+ }
- /* iterate over the results */
- for (inp = *memory; inp->type != IPT_END; inp++)
+ /* tests for absolute devices */
+ if (field->type >= __ipt_analog_absolute_start && field->type <= __ipt_analog_absolute_end)
{
- int strindex = 0;
+ INT32 default_value = field->defvalue;
- /* check for duplicate tags */
- if (inp->type == IPT_PORT)
+ /* adjust for signed values */
+ if (analog_min > analog_max)
{
- if (inp->start.tag != NULL && portnum < ARRAY_LENGTH(tag))
- {
- int scanport;
-
- for (scanport = 0; scanport < portnum - 1; scanport++)
- if (strcmp(inp->start.tag, tag[scanport]) == 0)
- {
- mame_printf_error("%s: %s has a duplicate input port tag \"%s\"\n", driver->source_file, driver->name, inp->start.tag);
- error = TRUE;
- }
- tag[portnum++] = inp->start.tag;
- }
- continue;
+ analog_min = -analog_min;
+ if (default_value > analog_max)
+ default_value = -default_value;
}
- if (port_type_is_analog(inp->type))
+ /* check that the default falls in the MINMAX range */
+ if (default_value < analog_min || default_value > analog_max)
{
- INT32 analog_max = inp->analog.max;
- INT32 analog_min = inp->analog.min;
- int shift;
-
- if (inp->type == IPT_POSITIONAL || inp->type == IPT_POSITIONAL_V)
- {
- for (shift = 0; (shift <= 31) && (~inp->mask & (1 << shift)); shift++);
- /* convert the positional max value to be in the bitmask for testing */
- analog_max = (analog_max - 1) << shift;
+ mame_printf_error("%s: %s has an analog port with a default value out PORT_MINMAX range\n", driver->source_file, driver->name);
+ *error = TRUE;
+ }
- /* positional port size must fit in bits used */
- if (((inp->mask >> shift) + 1) < inp->analog.max)
- {
- mame_printf_error("%s: %s has an analog port with a positional port size bigger then the mask size\n", driver->source_file, driver->name);
- error = TRUE;
- }
- }
- else
- {
- /* only positional controls use PORT_WRAPS */
- if (inp->analog.wraps)
- {
- mame_printf_error("%s: %s only positional analog ports use PORT_WRAPS\n", driver->source_file, driver->name);
- error = TRUE;
- }
- }
+ /* check that the MINMAX falls in the bitmask range */
+ /* we use the unadjusted min for testing */
+ if (field->min & ~field->mask || analog_max & ~field->mask)
+ {
+ mame_printf_error("%s: %s has an analog port with a PORT_MINMAX value out of the bitmask range\n", driver->source_file, driver->name);
+ *error = TRUE;
+ }
+ /* absolute analog ports do not use PORT_RESET */
+ if (field->flags & ANALOG_FLAG_RESET)
+ {
+ mame_printf_error("%s: %s - absolute analog ports do not use PORT_RESET\n", driver->source_file, driver->name);
+ *error = TRUE;
+ }
+ }
- /* analog ports must have a valid sensitivity */
- if (inp->analog.sensitivity == 0)
+ /* tests for relative devices */
+ else
+ {
+ /* tests for non IPT_POSITIONAL relative devices */
+ if (field->type != IPT_POSITIONAL && field->type != IPT_POSITIONAL_V)
+ {
+ /* relative devices do not use PORT_MINMAX */
+ if (field->min != 0 || field->max != field->mask)
{
- mame_printf_error("%s: %s has an analog port with zero sensitivity\n", driver->source_file, driver->name);
- error = TRUE;
+ mame_printf_error("%s: %s - relative ports do not use PORT_MINMAX\n", driver->source_file, driver->name);
+ *error = TRUE;
}
- /* check that the default falls in the bitmask range */
- if (inp->default_value & ~inp->mask)
+ /* relative devices do not use a default value */
+ /* the counter is at 0 on power up */
+ if (field->defvalue != 0)
{
- mame_printf_error("%s: %s has an analog port with a default value out of the bitmask range\n", driver->source_file, driver->name);
- error = TRUE;
- }
-
- /* tests for absolute devices */
- if (port_type_is_analog_absolute(inp->type))
- {
- INT32 default_value = inp->default_value;
-
- /* adjust for signed values */
- if (analog_min > analog_max)
- {
- analog_min = -analog_min;
- if (default_value > analog_max)
- default_value = -default_value;
- }
-
- /* check that the default falls in the MINMAX range */
- if (default_value < analog_min || default_value > analog_max)
- {
- mame_printf_error("%s: %s has an analog port with a default value out PORT_MINMAX range\n", driver->source_file, driver->name);
- error = TRUE;
- }
-
- /* check that the MINMAX falls in the bitmask range */
- /* we use the unadjusted min for testing */
- if (inp->analog.min & ~inp->mask || analog_max & ~inp->mask)
- {
- mame_printf_error("%s: %s has an analog port with a PORT_MINMAX value out of the bitmask range\n", driver->source_file, driver->name);
- error = TRUE;
- }
-
- /* absolute analog ports do not use PORT_RESET */
- if (inp->analog.reset)
- {
- mame_printf_error("%s: %s - absolute analog ports do not use PORT_RESET\n", driver->source_file, driver->name);
- error = TRUE;
- }
- }
- else
- /* tests for relative devices */
- {
- /* tests for non IPT_POSITIONAL relative devices */
- if (inp->type != IPT_POSITIONAL && inp->type != IPT_POSITIONAL_V)
- {
- /* relative devices do not use PORT_MINMAX */
- if (inp->analog.min || inp->analog.max != inp->mask)
- {
- mame_printf_error("%s: %s - relative ports do not use PORT_MINMAX\n", driver->source_file, driver->name);
- error = TRUE;
- }
-
- /* relative devices do not use a default value */
- /* the counter is at 0 on power up */
- if (inp->default_value)
- {
- mame_printf_error("%s: %s - relative ports do not use a default value other then 0\n", driver->source_file, driver->name);
- error = TRUE;
- }
- }
+ mame_printf_error("%s: %s - relative ports do not use a default value other then 0\n", driver->source_file, driver->name);
+ *error = TRUE;
}
}
+ }
+}
- /* clear the DIP switch tracking when we hit the first non-DIP entry */
- if (last_dipname_entry != NULL && inp->type != IPT_DIPSWITCH_SETTING)
- last_dipname_entry = NULL;
-
- /* look for invalid (0) types which should be mapped to IPT_OTHER */
- if (inp->type == IPT_INVALID)
- {
- mame_printf_error("%s: %s has an input port with an invalid type (0); use IPT_OTHER instead\n", driver->source_file, driver->name);
- error = TRUE;
- }
- /* if this entry doesn't have a name, we don't care about the rest of this stuff */
- if (inp->name == NULL || inp->name == IP_NAME_DEFAULT)
- {
- /* not allowed for dipswitches */
- if (inp->type == IPT_DIPSWITCH_NAME || inp->type == IPT_DIPSWITCH_SETTING)
- {
- mame_printf_error("%s: %s has a DIP switch name or setting with no name\n", driver->source_file, driver->name);
- error = TRUE;
- }
- last_strindex = 0;
- continue;
- }
+/*-------------------------------------------------
+ validate_dip_settings - validate a DIP switch
+ setting
+-------------------------------------------------*/
- /* check for empty string */
- if (inp->name[0] == 0 && !empty_string_found)
+static void validate_dip_settings(const input_field_config *field, const game_driver *driver, int *error)
+{
+ const char *demo_sounds = input_port_string_from_index(INPUT_STRING_Demo_Sounds);
+ const char *flipscreen = input_port_string_from_index(INPUT_STRING_Flip_Screen);
+ UINT8 coin_list[INPUT_STRING_1C_9C - INPUT_STRING_9C_1C] = { 0 };
+ const input_setting_config *setting;
+ int coin_error = FALSE;
+
+ /* iterate through the settings */
+ for (setting = field->settinglist; setting != NULL; setting = setting->next)
+ {
+ int strindex = get_defstr_index(setting->name, driver, error);
+
+ /* note any coinage strings */
+ if (strindex >= INPUT_STRING_9C_1C && strindex <= INPUT_STRING_1C_9C)
+ coin_list[strindex - INPUT_STRING_9C_1C] = 1;
+
+ /* make sure demo sounds default to on */
+ if (field->name == demo_sounds && strindex == INPUT_STRING_On && field->defvalue != setting->value)
{
- mame_printf_error("%s: %s has an input with an empty string\n", driver->source_file, driver->name);
- error = TRUE;
- empty_string_found = TRUE;
+ mame_printf_error("%s: %s Demo Sounds must default to On\n", driver->source_file, driver->name);
+ *error = TRUE;
}
- /* check for trailing spaces */
- if (inp->name[0] != 0 && inp->name[strlen(inp->name) - 1] == ' ')
+ /* check for bad demo sounds options */
+ if (field->name == demo_sounds && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
{
- mame_printf_error("%s: %s input '%s' has trailing spaces\n", driver->source_file, driver->name, inp->name);
- error = TRUE;
+ mame_printf_error("%s: %s has wrong Demo Sounds option %s (must be Off/On)\n", driver->source_file, driver->name, setting->name);
+ *error = TRUE;
}
- /* check for invalid UTF-8 */
- if (!utf8_is_valid_string(inp->name))
+ /* check for bad flip screen options */
+ if (field->name == flipscreen && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
{
- mame_printf_error("%s: %s input '%s' has invalid characters\n", driver->source_file, driver->name, inp->name);
- error = TRUE;
+ mame_printf_error("%s: %s has wrong Flip Screen option %s (must be Off/On)\n", driver->source_file, driver->name, setting->name);
+ *error = TRUE;
}
- /* hash the string and look it up in the string table */
- crc = quark_string_crc(inp->name);
- for (entry = quark_table_get_first(defstr_table, crc); entry; entry = entry->next)
- if (entry->crc == crc && !strcmp(inp->name, input_port_string_from_index(entry - defstr_table->entry)))
- {
- strindex = entry - defstr_table->entry;
- break;
- }
-
- /* check for strings that should be DEF_STR */
- if (strindex != 0 && inp->name != input_port_string_from_index(strindex))
+ /* if we have a neighbor, compare ourselves to him */
+ if (setting->next != NULL)
{
- mame_printf_error("%s: %s must use DEF_STR( %s )\n", driver->source_file, driver->name, inp->name);
- error = TRUE;
- }
-
- /* track the last dipswitch we encountered */
- if (inp->type == IPT_DIPSWITCH_NAME)
- last_dipname_entry = inp;
+ int next_strindex = get_defstr_index(setting->next->name, driver, error);
- /* check for dipswitch ordering against the last entry */
- if (inp[0].type == IPT_DIPSWITCH_SETTING && inp[-1].type == IPT_DIPSWITCH_SETTING && last_strindex != 0 && strindex != 0)
- {
/* check for inverted off/on dispswitch order */
- if (last_strindex == INPUT_STRING_On && strindex == INPUT_STRING_Off)
+ if (strindex == INPUT_STRING_On && next_strindex == INPUT_STRING_Off)
{
mame_printf_error("%s: %s has inverted Off/On dipswitch order\n", driver->source_file, driver->name);
- error = TRUE;
+ *error = TRUE;
}
/* check for inverted yes/no dispswitch order */
- else if (last_strindex == INPUT_STRING_Yes && strindex == INPUT_STRING_No)
+ else if (strindex == INPUT_STRING_Yes && next_strindex == INPUT_STRING_No)
{
mame_printf_error("%s: %s has inverted No/Yes dipswitch order\n", driver->source_file, driver->name);
- error = TRUE;
+ *error = TRUE;
}
/* check for inverted upright/cocktail dispswitch order */
- else if (last_strindex == INPUT_STRING_Cocktail && strindex == INPUT_STRING_Upright)
+ else if (strindex == INPUT_STRING_Cocktail && next_strindex == INPUT_STRING_Upright)
{
mame_printf_error("%s: %s has inverted Upright/Cocktail dipswitch order\n", driver->source_file, driver->name);
- error = TRUE;
+ *error = TRUE;
}
/* check for proper coin ordering */
- else if (last_strindex >= INPUT_STRING_9C_1C && last_strindex <= INPUT_STRING_1C_9C && strindex >= INPUT_STRING_9C_1C && strindex <= INPUT_STRING_1C_9C &&
- last_strindex >= strindex && !memcmp(&inp[-1].condition, &inp[0].condition, sizeof(inp[-1].condition)))
+ else if (strindex >= INPUT_STRING_9C_1C && strindex <= INPUT_STRING_1C_9C && next_strindex >= INPUT_STRING_9C_1C && next_strindex <= INPUT_STRING_1C_9C &&
+ strindex >= next_strindex && memcmp(&setting->condition, &setting->next->condition, sizeof(setting->condition)) == 0)
{
- mame_printf_error("%s: %s has unsorted coinage %s > %s\n", driver->source_file, driver->name, inp[-1].name, inp[0].name);
- error = TRUE;
- coin_error = TRUE;
+ mame_printf_error("%s: %s has unsorted coinage %s > %s\n", driver->source_file, driver->name, setting->name, setting->next->name);
+ coin_error = *error = TRUE;
}
}
+ }
+
+ /* if we have a coin error, demonstrate the correct way */
+ if (coin_error)
+ {
+ int entry;
+
+ mame_printf_error("%s: %s proper coin sort order should be:\n", driver->source_file, driver->name);
+ for (entry = 0; entry < ARRAY_LENGTH(coin_list); entry++)
+ if (coin_list[entry])
+ mame_printf_error("%s\n", input_port_string_from_index(INPUT_STRING_9C_1C + entry));
+ }
+}
+
- /* check for invalid DIP switch entries */
- if (last_dipname_entry && inp->type == IPT_DIPSWITCH_SETTING)
+/*-------------------------------------------------
+ validate_inputs - validate input configuration
+-------------------------------------------------*/
+
+static int validate_inputs(int drivnum, const machine_config *config)
+{
+ const input_port_config *portlist;
+ const input_port_config *scanport;
+ const input_port_config *port;
+ const input_field_config *field;
+ const game_driver *driver = drivers[drivnum];
+ int empty_string_found = FALSE;
+ quark_entry *entry;
+ int error = FALSE;
+ UINT32 crc;
+
+ /* skip if no ports */
+ if (driver->ipt == NULL)
+ return FALSE;
+
+ /* skip if we already validated these ports */
+ crc = (FPTR)driver->ipt;
+ for (entry = quark_table_get_first(inputs_table, crc); entry != NULL; entry = entry->next)
+ if (entry->crc == crc && driver->ipt == drivers[entry - inputs_table->entry]->ipt)
+ return FALSE;
+
+ /* otherwise, add ourself to the list */
+ quark_add(inputs_table, drivnum, crc);
+
+ /* allocate the input ports */
+ portlist = input_port_config_alloc(driver->ipt);
+
+ /* check for duplicate tags */
+ for (port = portlist; port != NULL; port = port->next)
+ if (port->tag != NULL)
+ for (scanport = port->next; scanport != NULL; scanport = scanport->next)
+ if (scanport->tag != NULL && strcmp(port->tag, scanport->tag) == 0)
+ {
+ mame_printf_error("%s: %s has a duplicate input port tag \"%s\"\n", driver->source_file, driver->name, port->tag);
+ error = TRUE;
+ }
+
+ /* iterate over the results */
+ for (port = portlist; port != NULL; port = port->next)
+ for (field = port->fieldlist; field != NULL; field = field->next)
{
- /* make sure demo sounds default to on */
- if (last_dipname_entry->name == demo_sounds && strindex == INPUT_STRING_On &&
- last_dipname_entry->default_value != inp->default_value)
+ int strindex = 0;
+
+ /* verify analog inputs */
+ if (input_type_is_analog(field->type))
+ validate_analog_input_field(field, driver, &error);
+
+ /* verify dip switches */
+ if (field->type == IPT_DIPSWITCH)
{
- mame_printf_error("%s: %s Demo Sounds must default to On\n", driver->source_file, driver->name);
- error = TRUE;
+ /* dip switch fields must have a name */
+ if (field->name == NULL)
+ {
+ mame_printf_error("%s: %s has a DIP switch name or setting with no name\n", driver->source_file, driver->name);
+ error = TRUE;
+ }
+
+ /* verify the settings list */
+ validate_dip_settings(field, driver, &error);
}
-
- /* check for bad flip screen options */
- if (last_dipname_entry->name == flipscreen && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
+
+ /* look for invalid (0) types which should be mapped to IPT_OTHER */
+ if (field->type == IPT_INVALID)
{
- mame_printf_error("%s: %s has wrong Flip Screen option %s (must be Off/On)\n", driver->source_file, driver->name, inp->name);
+ mame_printf_error("%s: %s has an input port with an invalid type (0); use IPT_OTHER instead\n", driver->source_file, driver->name);
error = TRUE;
}
- /* check for bad demo sounds options */
- if (last_dipname_entry->name == demo_sounds && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
+ /* verify names */
+ if (field->name != NULL)
{
- mame_printf_error("%s: %s has wrong Demo Sounds option %s (must be Off/On)\n", driver->source_file, driver->name, inp->name);
- error = TRUE;
- }
- }
+ /* check for empty string */
+ if (field->name[0] == 0 && !empty_string_found)
+ {
+ mame_printf_error("%s: %s has an input with an empty string\n", driver->source_file, driver->name);
+ empty_string_found = error = TRUE;
+ }
- /* remember the last string index */
- last_strindex = strindex;
- }
+ /* check for trailing spaces */
+ if (field->name[0] != 0 && field->name[strlen(field->name) - 1] == ' ')
+ {
+ mame_printf_error("%s: %s input '%s' has trailing spaces\n", driver->source_file, driver->name, field->name);
+ error = TRUE;
+ }
- if ( coin_error )
- display_valid_coin_order(drivnum, *memory);
+ /* check for invalid UTF-8 */
+ if (!utf8_is_valid_string(field->name))
+ {
+ mame_printf_error("%s: %s input '%s' has invalid characters\n", driver->source_file, driver->name, field->name);
+ error = TRUE;
+ }
+ /* look up the string and print an error if default strings are not used */
+ strindex = get_defstr_index(field->name, driver, &error);
+ }
+ }
+
+ /* free the config */
+ input_port_config_free(portlist);
return error;
}
@@ -1393,7 +1375,6 @@ int mame_validitychecks(const game_driver *curdriver)
osd_ticks_t mess_checks = 0;
#endif
- input_port_entry *inputports = NULL;
int drivnum;
int error = FALSE;
UINT16 lsbtest;
@@ -1487,7 +1468,7 @@ int mame_validitychecks(const game_driver *curdriver)
/* validate input ports */
input_checks -= osd_profiling_ticks();
- error = validate_inputs(drivnum, config, &inputports) || error;
+ error = validate_inputs(drivnum, config) || error;
input_checks += osd_profiling_ticks();
/* validate sounds and speakers */