From 569f818281ac5d9ce04a952c5e764a5e7ae4c027 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 13 Feb 2011 17:45:31 +0000 Subject: [PATCH] Input ports can now be added to device, names are formed as sub tags from parent device tag. [Miodrag Milanovic] --- src/emu/devcpu.h | 1 + src/emu/devintrf.c | 11 +++++++++++ src/emu/devintrf.h | 3 +++ src/emu/devlegcy.h | 3 +++ src/emu/info.c | 10 ++++++++-- src/emu/inptport.c | 36 ++++++++++++++++++++++++++---------- src/emu/inptport.h | 4 ++-- src/emu/machine.c | 2 +- src/emu/validity.c | 13 ++++++++++++- 9 files changed, 67 insertions(+), 16 deletions(-) diff --git a/src/emu/devcpu.h b/src/emu/devcpu.h index f4926dee28c..ea96702da5a 100644 --- a/src/emu/devcpu.h +++ b/src/emu/devcpu.h @@ -423,6 +423,7 @@ public: // basic information getters virtual const rom_entry *rom_region() const { return reinterpret_cast(get_legacy_config_ptr(DEVINFO_PTR_ROM_REGION)); } virtual machine_config_constructor machine_config_additions() const { return reinterpret_cast(get_legacy_config_ptr(DEVINFO_PTR_MACHINE_CONFIG)); } + virtual const input_port_token *input_ports() const { return reinterpret_cast(get_legacy_config_ptr(DEVINFO_PTR_INPUT_PORTS)); } protected: // device_config_execute_interface overrides diff --git a/src/emu/devintrf.c b/src/emu/devintrf.c index cf1f26a6e4f..6f214b777ca 100644 --- a/src/emu/devintrf.c +++ b/src/emu/devintrf.c @@ -401,6 +401,17 @@ machine_config_constructor device_config::machine_config_additions() const +//------------------------------------------------- +// input_ports - return a pointer to the implicit +// input ports description for this device +//------------------------------------------------- + +const input_port_token *device_config::input_ports() const +{ + return NULL; +} + + //************************************************************************** // LIVE DEVICE INTERFACES //************************************************************************** diff --git a/src/emu/devintrf.h b/src/emu/devintrf.h index 79b84a0da37..e5403690d34 100644 --- a/src/emu/devintrf.h +++ b/src/emu/devintrf.h @@ -127,6 +127,7 @@ class device_state_interface; struct rom_entry; class machine_config; class emu_timer; +typedef union _input_port_token input_port_token; // exception classes @@ -311,6 +312,7 @@ public: // optional information overrides virtual const rom_entry *rom_region() const; virtual machine_config_constructor machine_config_additions() const; + virtual const input_port_token *input_ports() const; //------------------- end derived class overrides @@ -455,6 +457,7 @@ public: // machine and ROM configuration getters ... pass through to underlying config const rom_entry *rom_region() const { return m_baseconfig.rom_region(); } machine_config_constructor machine_config_additions() const { return m_baseconfig.machine_config_additions(); } + const input_port_token *input_ports() const { return m_baseconfig.input_ports(); } public: running_machine * machine; diff --git a/src/emu/devlegcy.h b/src/emu/devlegcy.h index f7a960d0d42..69972294a8b 100644 --- a/src/emu/devlegcy.h +++ b/src/emu/devlegcy.h @@ -88,6 +88,7 @@ enum DEVINFO_PTR_ROM_REGION = DEVINFO_PTR_FIRST, // R/O: pointer to device-specific ROM region DEVINFO_PTR_MACHINE_CONFIG, // R/O: pointer to device-specific machine config + DEVINFO_PTR_INPUT_PORTS, DEVINFO_PTR_INTERNAL_MEMORY_MAP, // R/O: address_map_constructor map DEVINFO_PTR_INTERNAL_MEMORY_MAP_0 = DEVINFO_PTR_INTERNAL_MEMORY_MAP + 0, @@ -405,6 +406,7 @@ union deviceinfo device_nvram_func nvram; // DEVINFO_FCT_NVRAM const rom_entry * romregion; // DEVINFO_PTR_ROM_REGION machine_config_constructor machine_config; // DEVINFO_PTR_MACHINE_CONFIG + const input_port_token *ipt; // DEVINFO_PTR_INPUT_PORTS address_map_constructor internal_map8; // DEVINFO_PTR_INTERNAL_MEMORY_MAP address_map_constructor internal_map16; // DEVINFO_PTR_INTERNAL_MEMORY_MAP address_map_constructor internal_map32; // DEVINFO_PTR_INTERNAL_MEMORY_MAP @@ -436,6 +438,7 @@ protected: public: virtual const rom_entry *rom_region() const { return reinterpret_cast(get_legacy_config_ptr(DEVINFO_PTR_ROM_REGION)); } virtual machine_config_constructor machine_config_additions() const { return reinterpret_cast(get_legacy_config_ptr(DEVINFO_PTR_MACHINE_CONFIG)); } + virtual const input_port_token *input_ports() const { return reinterpret_cast(get_legacy_config_ptr(DEVINFO_PTR_INPUT_PORTS)); } // access to legacy inline configuartion void *inline_config() const { return m_inline_config; } diff --git a/src/emu/info.c b/src/emu/info.c index 8d146d52775..283b2db05b2 100644 --- a/src/emu/info.c +++ b/src/emu/info.c @@ -1049,8 +1049,14 @@ static void print_game_info(FILE *out, const game_driver *game) return; /* start tracking resources and allocate the machine and input configs */ - input_port_list_init(portlist, game->ipt, NULL, 0, FALSE); - + input_port_list_init(portlist, game->ipt, NULL, 0, FALSE, NULL); + for (device_config *cfg = config.m_devicelist.first(); cfg != NULL; cfg = cfg->next()) + { + if (cfg->input_ports()!=NULL) { + input_port_list_init(portlist, cfg->input_ports(), NULL, 0, FALSE, cfg); + } + } + /* print the header and the game name */ fprintf(out, "\t<" XML_TOP); fprintf(out, " name=\"%s\"", xml_normalize_string(game->name) ); diff --git a/src/emu/inptport.c b/src/emu/inptport.c index f29384f709e..a91bf345673 100644 --- a/src/emu/inptport.c +++ b/src/emu/inptport.c @@ -788,7 +788,7 @@ static void frame_update_analog_field(running_machine *machine, analog_field_sta static int frame_get_digital_field_state(const input_field_config *field, int mouse_down); /* port configuration helpers */ -static void port_config_detokenize(ioport_list &portlist, const input_port_token *ipt, char *errorbuf, int errorbuflen); +static void port_config_detokenize(ioport_list &portlist, const input_port_token *ipt, char *errorbuf, int errorbuflen, device_config *owner); static input_field_config *field_config_alloc(input_port_config *port, int type, input_port_value defvalue, input_port_value maskbits); static void field_config_insert(input_field_config *field, input_port_value *disallowedbits, char *errorbuf, int errorbuflen); static void field_config_free(input_field_config **fieldptr); @@ -973,7 +973,7 @@ static WRITE_LINE_DEVICE_HANDLER( changed_write_line_device ) system -------------------------------------------------*/ -time_t input_port_init(running_machine *machine, const input_port_token *tokens) +time_t input_port_init(running_machine *machine, const input_port_token *tokens, const device_config_list &devicelist) { //input_port_private *portdata; char errorbuf[1024]; @@ -993,12 +993,21 @@ time_t input_port_init(running_machine *machine, const input_port_token *tokens) /* if we have a token list, proceed */ if (tokens != NULL) { - input_port_list_init(machine->m_portlist, tokens, errorbuf, sizeof(errorbuf), TRUE); + input_port_list_init(machine->m_portlist, tokens, errorbuf, sizeof(errorbuf), TRUE, NULL); if (errorbuf[0] != 0) mame_printf_error("Input port errors:\n%s", errorbuf); - init_port_state(machine); } + for (device_config *config = devicelist.first(); config != NULL; config = config->next()) + { + if (config->input_ports()!=NULL) { + input_port_list_init(machine->m_portlist, config->input_ports(), errorbuf, sizeof(errorbuf), TRUE, config); + if (errorbuf[0] != 0) + mame_printf_error("Input port errors:\n%s", errorbuf); + } + } + + init_port_state(machine); /* register callbacks for when we load configurations */ config_register(machine, "input", load_config_callback, save_config_callback); @@ -1034,7 +1043,7 @@ static void input_port_exit(running_machine &machine) according to the given tokens -------------------------------------------------*/ -void input_port_list_init(ioport_list &portlist, const input_port_token *tokens, char *errorbuf, int errorbuflen, int allocmap) +void input_port_list_init(ioport_list &portlist, const input_port_token *tokens, char *errorbuf, int errorbuflen, int allocmap, device_config *owner) { /* no tokens, no list */ if (tokens == NULL) @@ -1045,7 +1054,7 @@ void input_port_list_init(ioport_list &portlist, const input_port_token *tokens, *errorbuf = 0; /* detokenize into the list */ - port_config_detokenize(portlist, tokens, errorbuf, errorbuflen); + port_config_detokenize(portlist, tokens, errorbuf, errorbuflen, owner); } @@ -2866,13 +2875,15 @@ static int frame_get_digital_field_state(const input_field_config *field, int mo detokenize a series of input port tokens -------------------------------------------------*/ -static void port_config_detokenize(ioport_list &portlist, const input_port_token *ipt, char *errorbuf, int errorbuflen) +static void port_config_detokenize(ioport_list &portlist, const input_port_token *ipt, char *errorbuf, int errorbuflen, device_config *owner) { UINT32 entrytype = INPUT_TOKEN_INVALID; input_setting_config *cursetting = NULL; input_field_config *curfield = NULL; input_port_config *curport = NULL; input_port_value maskbits = 0; + astring tempstring; + const char *fulltag = NULL; UINT16 category; /* (MESS-specific) category */ /* loop over tokens until we hit the end */ @@ -2899,7 +2910,7 @@ static void port_config_detokenize(ioport_list &portlist, const input_port_token field_config_insert(curfield, &maskbits, errorbuf, errorbuflen); maskbits = 0; - port_config_detokenize(portlist, TOKEN_GET_PTR(ipt, tokenptr), errorbuf, errorbuflen); + port_config_detokenize(portlist, TOKEN_GET_PTR(ipt, tokenptr), errorbuf, errorbuflen, owner); curport = NULL; curfield = NULL; cursetting = NULL; @@ -2911,8 +2922,13 @@ static void port_config_detokenize(ioport_list &portlist, const input_port_token field_config_insert(curfield, &maskbits, errorbuf, errorbuflen); maskbits = 0; - string = TOKEN_GET_STRING(ipt); - curport = &portlist.append(string, *global_alloc(input_port_config(string))); + string = TOKEN_GET_STRING(ipt); + if (owner!=NULL) { + fulltag = core_strdup(owner->subtag(tempstring, string)); + } else { + fulltag = string; + } + curport = &portlist.append(fulltag, *global_alloc(input_port_config(fulltag))); curfield = NULL; cursetting = NULL; break; diff --git a/src/emu/inptport.h b/src/emu/inptport.h index a8b466ce5a6..b2556cf9ef2 100644 --- a/src/emu/inptport.h +++ b/src/emu/inptport.h @@ -1058,14 +1058,14 @@ struct _inp_header /* ----- core system management ----- */ /* initialize the input ports, processing the given token list */ -time_t input_port_init(running_machine *machine, const input_port_token *tokens); +time_t input_port_init(running_machine *machine, const input_port_token *tokens, const device_config_list &devicelist); /* ----- port configurations ----- */ /* initialize an input port list structure and allocate ports according to the given tokens */ -void input_port_list_init(ioport_list &portlist, const input_port_token *tokens, char *errorbuf, int errorbuflen, int allocmap); +void input_port_list_init(ioport_list &portlist, const input_port_token *tokens, char *errorbuf, int errorbuflen, int allocmap, device_config *owner); /* return the field that matches the given tag and mask */ const input_field_config *input_field_by_tag_and_mask(const ioport_list &portlist, const char *tag, input_port_value mask); diff --git a/src/emu/machine.c b/src/emu/machine.c index 2ed94eaea23..b437c762ee6 100644 --- a/src/emu/machine.c +++ b/src/emu/machine.c @@ -285,7 +285,7 @@ void running_machine::start() // initialize the input system and input ports for the game // this must be done before memory_init in order to allow specifying // callbacks based on input port tags - time_t newbase = input_port_init(this, m_game.ipt); + time_t newbase = input_port_init(this, m_game.ipt, m_config.m_devicelist); if (newbase != 0) m_base_time = newbase; diff --git a/src/emu/validity.c b/src/emu/validity.c index 4b4571c5688..543a5455ac1 100644 --- a/src/emu/validity.c +++ b/src/emu/validity.c @@ -955,12 +955,23 @@ static bool validate_inputs(const machine_config &config, int_map &defstr_map, i return FALSE; /* allocate the input ports */ - input_port_list_init(portlist, driver.ipt, errorbuf, sizeof(errorbuf), FALSE); + input_port_list_init(portlist, driver.ipt, errorbuf, sizeof(errorbuf), FALSE, NULL); if (errorbuf[0] != 0) { mame_printf_error("%s: %s has input port errors:\n%s\n", driver.source_file, driver.name, errorbuf); error = true; } + for (device_config *cfg = config.m_devicelist.first(); cfg != NULL; cfg = cfg->next()) + { + if (cfg->input_ports()!=NULL) { + input_port_list_init(portlist, cfg->input_ports(), errorbuf, sizeof(errorbuf), FALSE, cfg); + if (errorbuf[0] != 0) + { + mame_printf_error("%s: %s has input port errors:\n%s\n", driver.source_file, driver.name, errorbuf); + error = true; + } + } + } /* check for duplicate tags */ for (port = portlist.first(); port != NULL; port = port->next())