diff options
author | Aaron Giles <aaron@aarongiles.com> | 2009-02-16 18:07:38 +0000 |
---|---|---|
committer | Aaron Giles <aaron@aarongiles.com> | 2009-02-16 18:07:38 +0000 |
commit | 51b90f0e859a484c7f8408bed297b3928de5be34 (patch) | |
tree | d5706a7221f5442700b2f5c971492a950190d72d | |
parent | 7c350198118dadcf373f5fc0d209683138904644 (diff) |
Added the ability for devices to have their own custom inline config management.
This was primarily added to allow for sound routes to be supported in a way that
is compatible with the current driver structure. A device can now define a
DEVICE_CUSTOM_CONFIG callback which is called whenever one of the
MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_* tokens is encountered. A special token
MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_FREE is defined to clean up memory allocated
and/or reset the custom configuration, and is called when the device is torn down
to allow for memory cleanup.
Reimplemented the sound routing using this new mechanism.
-rw-r--r-- | src/emu/cpuexec.c | 4 | ||||
-rw-r--r-- | src/emu/devintrf.h | 7 | ||||
-rw-r--r-- | src/emu/mconfig.c | 66 | ||||
-rw-r--r-- | src/emu/mconfig.h | 30 | ||||
-rw-r--r-- | src/emu/sound.c | 162 | ||||
-rw-r--r-- | src/emu/sound.h | 22 | ||||
-rw-r--r-- | src/emu/tokenize.h | 15 | ||||
-rw-r--r-- | src/emu/validity.c | 34 |
8 files changed, 218 insertions, 122 deletions
diff --git a/src/emu/cpuexec.c b/src/emu/cpuexec.c index fa709823692..08f4fe9e241 100644 --- a/src/emu/cpuexec.c +++ b/src/emu/cpuexec.c @@ -707,6 +707,10 @@ DEVICE_GET_INFO( cpu ) case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(cpu); break; default: + /* if we don't have a device pointer, ignore everything else */ + if (device == NULL) + break; + /* if we have a state pointer, we can handle some stuff for free */ if (device->token != NULL) { diff --git a/src/emu/devintrf.h b/src/emu/devintrf.h index 203e432c30c..06027ab3d09 100644 --- a/src/emu/devintrf.h +++ b/src/emu/devintrf.h @@ -75,6 +75,7 @@ enum DEVINFO_FCT_EXECUTE, /* R/O: device_execute_func */ DEVINFO_FCT_VALIDITY_CHECK, /* R/O: device_validity_check_func */ DEVINFO_FCT_NVRAM, /* R/O: device_nvram_func */ + DEVINFO_FCT_CUSTOM_CONFIG, /* R/O: device_custom_config_func */ DEVINFO_FCT_CLASS_SPECIFIC = 0x24000, /* R/W: device-specific values start here */ DEVINFO_FCT_DEVICE_SPECIFIC = 0x28000, /* R/W: device-specific values start here */ @@ -132,6 +133,10 @@ enum #define DEVICE_VALIDITY_CHECK(name) int DEVICE_VALIDITY_CHECK_NAME(name)(const game_driver *driver, const device_config *device) #define DEVICE_VALIDITY_CHECK_CALL(name) DEVICE_VALIDITY_CHECK(name)(driver, device) +#define DEVICE_CUSTOM_CONFIG_NAME(name) device_custom_config_##name +#define DEVICE_CUSTOM_CONFIG(name) const union _machine_config_token *DEVICE_CUSTOM_CONFIG_NAME(name)(const device_config *device, UINT32 entrytype, const union _machine_config_token *tokens) +#define DEVICE_CUSTOM_CONFIG_CALL(name) DEVICE_CUSTOM_CONFIG(name)(device, entrytype, tokens) + /* shorthand for accessing devices by machine/type/tag */ #define devtag_get_device(mach,type,tag) device_list_find_by_tag((mach)->config->devicelist, type, tag) @@ -191,6 +196,7 @@ typedef INT32 (*device_execute_func)(const device_config *device, INT32 clocks); typedef void (*device_reset_func)(const device_config *device); typedef void (*device_nvram_func)(const device_config *device, mame_file *file, int read_or_write); typedef int (*device_validity_check_func)(const game_driver *driver, const device_config *device); +typedef const union _machine_config_token *(*device_custom_config_func)(const device_config *device, UINT32 entrytype, const union _machine_config_token *tokens); /* a device_type is simply a pointer to its get_info function */ @@ -211,6 +217,7 @@ union _deviceinfo device_reset_func reset; /* DEVINFO_FCT_RESET */ device_execute_func execute; /* DEVINFO_FCT_EXECUTE */ device_validity_check_func validity_check; /* DEVINFO_FCT_VALIDITY_CHECK */ + device_custom_config_func custom_config; /* DEVINFO_FCT_CUSTOM_CONFIG */ device_nvram_func nvram; /* DEVINFO_FCT_NVRAM */ const rom_entry * romregion; /* DEVINFO_PTR_ROM_REGION */ const union _machine_config_token *machine_config;/* DEVINFO_PTR_MACHINE_CONFIG */ diff --git a/src/emu/mconfig.c b/src/emu/mconfig.c index a93e17a92a2..01118f1a679 100644 --- a/src/emu/mconfig.c +++ b/src/emu/mconfig.c @@ -32,6 +32,33 @@ static void machine_config_detokenize(machine_config *config, const machine_conf ***************************************************************************/ /*------------------------------------------------- + remove_device - remove the head device from + the given configuration +-------------------------------------------------*/ + +INLINE void remove_device(device_config **listheadptr, device_type type, const char *tag) +{ + device_config *device = (device_config *)device_list_find_by_tag(*listheadptr, type, tag); + device_custom_config_func custom; + + assert(device != NULL); + + /* call the custom config free function first */ + custom = (device_custom_config_func)devtype_get_info_fct(device->type, DEVINFO_FCT_CUSTOM_CONFIG); + if (custom != NULL) + (*custom)(device, MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_FREE, NULL); + + /* remove the device from the list */ + device_list_remove(listheadptr, type, tag); +} + + + +/*************************************************************************** + MACHINE CONFIGURATIONS +***************************************************************************/ + +/*------------------------------------------------- machine_config_alloc - allocate a new machine configuration and populate it using the supplied constructor @@ -60,7 +87,7 @@ void machine_config_free(machine_config *config) { /* release the device list */ while (config->devicelist != NULL) - device_list_remove(&config->devicelist, config->devicelist->type, config->devicelist->tag); + remove_device(&config->devicelist, config->devicelist->type, config->devicelist->tag); /* release the configuration itself */ free(config); @@ -81,6 +108,7 @@ static void machine_config_detokenize(machine_config *config, const machine_conf /* loop over tokens until we hit the end */ while (entrytype != MCONFIG_TOKEN_END) { + device_custom_config_func custom; int size, offset, bits; UINT32 data32, clock; device_type devtype; @@ -112,7 +140,7 @@ static void machine_config_detokenize(machine_config *config, const machine_conf case MCONFIG_TOKEN_DEVICE_REMOVE: devtype = TOKEN_GET_PTR(tokens, devtype); tag = TOKEN_GET_STRING(tokens); - device_list_remove(&config->devicelist, devtype, device_build_tag(tempstring, owner, tag)); + remove_device(&config->devicelist, devtype, device_build_tag(tempstring, owner, tag)); device = NULL; break; @@ -134,11 +162,27 @@ static void machine_config_detokenize(machine_config *config, const machine_conf assert(device != NULL); device->static_config = TOKEN_GET_PTR(tokens, voidptr); break; + + case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_1: + case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_2: + case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_3: + case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_4: + case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_5: + case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_6: + case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_7: + case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_8: + case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_9: + case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_FREE: + assert(device != NULL); + custom = (device_custom_config_func)devtype_get_info_fct(device->type, DEVINFO_FCT_CUSTOM_CONFIG); + assert(custom != NULL); + tokens = (*custom)(device, entrytype, tokens); + break; case MCONFIG_TOKEN_DEVICE_CONFIG_DATA32: assert(device != NULL); TOKEN_UNGET_UINT32(tokens); - TOKEN_GET_UINT32_UNPACK3(tokens, entrytype, 8, size, 6, offset, 12); + TOKEN_GET_UINT32_UNPACK3(tokens, entrytype, 8, size, 4, offset, 12); data32 = TOKEN_GET_UINT32(tokens); switch (size) { @@ -151,7 +195,7 @@ static void machine_config_detokenize(machine_config *config, const machine_conf case MCONFIG_TOKEN_DEVICE_CONFIG_DATA64: assert(device != NULL); TOKEN_UNGET_UINT32(tokens); - TOKEN_GET_UINT32_UNPACK3(tokens, entrytype, 8, size, 6, offset, 12); + TOKEN_GET_UINT32_UNPACK3(tokens, entrytype, 8, size, 4, offset, 12); TOKEN_EXTRACT_UINT64(tokens, data64); switch (size) { @@ -165,7 +209,7 @@ static void machine_config_detokenize(machine_config *config, const machine_conf case MCONFIG_TOKEN_DEVICE_CONFIG_DATAFP32: assert(device != NULL); TOKEN_UNGET_UINT32(tokens); - TOKEN_GET_UINT32_UNPACK4(tokens, entrytype, 8, size, 6, bits, 6, offset, 12); + TOKEN_GET_UINT32_UNPACK4(tokens, entrytype, 8, size, 4, bits, 6, offset, 12); data32 = TOKEN_GET_UINT32(tokens); switch (size) { @@ -174,18 +218,6 @@ static void machine_config_detokenize(machine_config *config, const machine_conf } break; - case MCONFIG_TOKEN_DEVICE_CONFIG_DATAFP64: - assert(device != NULL); - TOKEN_UNGET_UINT32(tokens); - TOKEN_GET_UINT32_UNPACK4(tokens, entrytype, 8, size, 6, bits, 6, offset, 12); - TOKEN_EXTRACT_UINT64(tokens, data64); - switch (size) - { - case 4: *(float *)((UINT8 *)device->inline_config + offset) = (float)(INT64)data64 / (float)((UINT64)1 << bits); break; - case 8: *(double *)((UINT8 *)device->inline_config + offset) = (double)(INT64)data64 / (double)((UINT64)1 << bits); break; - } - break; - /* core parameters */ case MCONFIG_TOKEN_DRIVER_DATA: diff --git a/src/emu/mconfig.h b/src/emu/mconfig.h index e0ca465edf5..3671a023051 100644 --- a/src/emu/mconfig.h +++ b/src/emu/mconfig.h @@ -37,14 +37,22 @@ enum MCONFIG_TOKEN_DEVICE_ADD, MCONFIG_TOKEN_DEVICE_REMOVE, - MCONFIG_TOKEN_DEVICE_REPLACE, MCONFIG_TOKEN_DEVICE_MODIFY, MCONFIG_TOKEN_DEVICE_CLOCK, MCONFIG_TOKEN_DEVICE_CONFIG, MCONFIG_TOKEN_DEVICE_CONFIG_DATA32, MCONFIG_TOKEN_DEVICE_CONFIG_DATA64, MCONFIG_TOKEN_DEVICE_CONFIG_DATAFP32, - MCONFIG_TOKEN_DEVICE_CONFIG_DATAFP64, + MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_1, + MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_2, + MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_3, + MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_4, + MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_5, + MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_6, + MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_7, + MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_8, + MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_9, + MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_FREE, MCONFIG_TOKEN_DRIVER_DATA, MCONFIG_TOKEN_QUANTUM_TIME, @@ -70,13 +78,6 @@ enum MCONFIG_TOKEN_SOUND_START, MCONFIG_TOKEN_SOUND_RESET, - - MCONFIG_TOKEN_SOUND_ADD, - MCONFIG_TOKEN_SOUND_REMOVE, - MCONFIG_TOKEN_SOUND_MODIFY, - MCONFIG_TOKEN_SOUND_CONFIG, - MCONFIG_TOKEN_SOUND_REPLACE, - MCONFIG_TOKEN_SOUND_ROUTE, }; @@ -173,6 +174,9 @@ union _machine_config_token }; +/* helper macro for returning the size of a field within a struct; similar to offsetof() */ +#define structsizeof(_struct, _field) sizeof(((_struct *)NULL)->_field) + /* start/end tags for the machine driver */ #define MACHINE_DRIVER_NAME(_name) \ @@ -310,12 +314,10 @@ union _machine_config_token #define MDRV_DEVICE_CLOCK(_clock) \ TOKEN_UINT64_PACK2(MCONFIG_TOKEN_DEVICE_CLOCK, 8, _clock, 32), -#define structsizeof(_struct, _field) sizeof(((_struct *)NULL)->_field) - /* inline device configurations that require 32 bits of storage in the token */ #define MDRV_DEVICE_CONFIG_DATA32_EXPLICIT(_size, _offset, _val) \ - TOKEN_UINT32_PACK3(MCONFIG_TOKEN_DEVICE_CONFIG_DATA32, 8, _size, 6, _offset, 12), \ + TOKEN_UINT32_PACK3(MCONFIG_TOKEN_DEVICE_CONFIG_DATA32, 8, _size, 4, _offset, 12), \ TOKEN_UINT32((UINT32)(_val)), #define MDRV_DEVICE_CONFIG_DATA32(_struct, _field, _val) \ @@ -330,7 +332,7 @@ union _machine_config_token /* inline device configurations that require 32 bits of fixed-point storage in the token */ #define MDRV_DEVICE_CONFIG_DATAFP32_EXPLICIT(_size, _offset, _val, _fixbits) \ - TOKEN_UINT32_PACK4(MCONFIG_TOKEN_DEVICE_CONFIG_DATAFP32, 8, _size, 6, _fixbits, 6, _offset, 12), \ + TOKEN_UINT32_PACK4(MCONFIG_TOKEN_DEVICE_CONFIG_DATAFP32, 8, _size, 4, _fixbits, 6, _offset, 12), \ TOKEN_UINT32((INT32)((float)(_val) * (float)(1 << (_fixbits)))), #define MDRV_DEVICE_CONFIG_DATAFP32(_struct, _field, _val, _fixbits) \ @@ -345,7 +347,7 @@ union _machine_config_token /* inline device configurations that require 64 bits of storage in the token */ #define MDRV_DEVICE_CONFIG_DATA64_EXPLICIT(_size, _offset, _val) \ - TOKEN_UINT32_PACK3(MCONFIG_TOKEN_DEVICE_CONFIG_DATA64, 8, _size, 6, _offset, 12), \ + TOKEN_UINT32_PACK3(MCONFIG_TOKEN_DEVICE_CONFIG_DATA64, 8, _size, 4, _offset, 12), \ TOKEN_UINT64((UINT64)(_val)), #define MDRV_DEVICE_CONFIG_DATA64(_struct, _field, _val) \ diff --git a/src/emu/sound.c b/src/emu/sound.c index 3b22fc2b9f5..33cf0a18cd4 100644 --- a/src/emu/sound.c +++ b/src/emu/sound.c @@ -318,6 +318,54 @@ static DEVICE_START( sound ) /*------------------------------------------------- + device_custom_config_sound - custom inline + config callback for populating sound routes +-------------------------------------------------*/ + +static DEVICE_CUSTOM_CONFIG( sound ) +{ + sound_config *config = device->inline_config; + + switch (entrytype) + { + /* custom config 1 is a new route */ + case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_1: + { + sound_route **routeptr; + int output, input; + UINT32 gain; + + /* put back the token that was originally fetched so we can grab a packed 64-bit token */ + TOKEN_UNGET_UINT32(tokens); + TOKEN_GET_UINT64_UNPACK4(tokens, entrytype, 8, output, 12, input, 12, gain, 32); + + /* allocate a new route */ + for (routeptr = &config->routelist; *routeptr != NULL; routeptr = &(*routeptr)->next) ; + *routeptr = malloc_or_die(sizeof(**routeptr)); + (*routeptr)->next = NULL; + (*routeptr)->output = output; + (*routeptr)->input = input; + (*routeptr)->gain = (float)gain * (1.0f / (float)(1 << 24)); + (*routeptr)->target = TOKEN_GET_STRING(tokens); + break; + } + + /* custom config free is also used as a reset of sound routes */ + case MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_FREE: + while (config->routelist != NULL) + { + sound_route *temp = config->routelist; + config->routelist = temp->next; + free(temp); + } + break; + } + + return tokens; +} + + +/*------------------------------------------------- device_get_info_sound - device get info callback -------------------------------------------------*/ @@ -340,6 +388,7 @@ DEVICE_GET_INFO( sound ) /* --- the following bits of info are returned as pointers to data or functions --- */ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(sound); break; case DEVINFO_FCT_SET_INFO: info->set_info = NULL; break; + case DEVINFO_FCT_CUSTOM_CONFIG: info->custom_config = DEVICE_CUSTOM_CONFIG_NAME(sound); break; /* --- the following bits of info are returned as NULL-terminated strings --- */ case DEVINFO_STR_NAME: @@ -369,36 +418,30 @@ DEVICE_GET_INFO( sound ) static void route_sound(running_machine *machine) { astring *tempstring = astring_alloc(); - int routenum, outputnum; const device_config *curspeak; const device_config *sound; + int outputnum; /* first count up the inputs for each speaker */ for (sound = sound_first(machine->config); sound != NULL; sound = sound_next(sound)) { const sound_config *config = sound->inline_config; int numoutputs = stream_get_device_outputs(sound); - int numassigned = 0; + const sound_route *route; /* iterate over all routes */ - for (routenum = 0; routenum <= ALL_OUTPUTS; routenum++) + for (route = config->routelist; route != NULL; route = route->next) { - const sound_route *mroute = &config->route[routenum]; - if (mroute->target != NULL) - { - const device_config *target_speaker = devtag_get_device(machine, SPEAKER_OUTPUT, mroute->target); - const device_config *target_sound = devtag_get_device(machine, SOUND, mroute->target); - int numentries = (routenum != ALL_OUTPUTS) ? 1 : (numoutputs - numassigned); - - /* if neither found, it's fatal */ - if (target_speaker == NULL && target_sound == NULL) - fatalerror("Sound route \"%s\" not found!\n", mroute->target); - - /* if we got a speaker, bump its input count */ - if (target_speaker != NULL) - get_safe_token(target_speaker)->inputs += numentries; - numassigned += numentries; - } + const device_config *target_speaker = devtag_get_device(machine, SPEAKER_OUTPUT, route->target); + const device_config *target_sound = devtag_get_device(machine, SOUND, route->target); + + /* if neither found, it's fatal */ + if (target_speaker == NULL && target_sound == NULL) + fatalerror("Sound route \"%s\" not found!\n", route->target); + + /* if we got a speaker, bump its input count */ + if (target_speaker != NULL) + get_safe_token(target_speaker)->inputs += (route->output == ALL_OUTPUTS) ? numoutputs : 1; } } @@ -422,59 +465,52 @@ static void route_sound(running_machine *machine) { const sound_config *config = sound->inline_config; int numoutputs = stream_get_device_outputs(sound); - UINT8 assigned[MAX_OUTPUTS] = { FALSE }; + const sound_route *route; /* iterate over all routes */ - for (routenum = 0; routenum <= ALL_OUTPUTS; routenum++) + for (route = config->routelist; route != NULL; route = route->next) { - const sound_route *mroute = &config->route[routenum]; - if (mroute->target != NULL) - { - const device_config *target_speaker = devtag_get_device(machine, SPEAKER_OUTPUT, mroute->target); - const device_config *target_sound = devtag_get_device(machine, SOUND, mroute->target); - int inputnum = mroute->input; - sound_stream *stream; - int streamoutput; - - /* iterate over all outputs, matching any that apply */ - for (outputnum = 0; outputnum < numoutputs; outputnum++) - if (routenum == outputnum || (routenum == ALL_OUTPUTS && !assigned[outputnum])) + const device_config *target_speaker = devtag_get_device(machine, SPEAKER_OUTPUT, route->target); + const device_config *target_sound = devtag_get_device(machine, SOUND, route->target); + int inputnum = route->input; + sound_stream *stream; + int streamoutput; + + /* iterate over all outputs, matching any that apply */ + for (outputnum = 0; outputnum < numoutputs; outputnum++) + if (route->output == outputnum || route->output == ALL_OUTPUTS) + { + /* if it's a speaker, set the input */ + if (target_speaker != NULL) { - /* mark this output as assigned */ - assigned[outputnum] = TRUE; - - /* if it's a speaker, set the input */ - if (target_speaker != NULL) - { - speaker_info *speakerinfo = get_safe_token(target_speaker); + speaker_info *speakerinfo = get_safe_token(target_speaker); - /* generate text for the UI */ - astring_printf(tempstring, "Speaker '%s': %s '%s'", target_speaker->tag, device_get_name(sound), sound->tag); - if (numoutputs > 1) - astring_catprintf(tempstring, " Ch.%d", outputnum); + /* generate text for the UI */ + astring_printf(tempstring, "Speaker '%s': %s '%s'", target_speaker->tag, device_get_name(sound), sound->tag); + if (numoutputs > 1) + astring_catprintf(tempstring, " Ch.%d", outputnum); - /* fill in the input data on this speaker */ - speakerinfo->input[speakerinfo->inputs].gain = mroute->gain; - speakerinfo->input[speakerinfo->inputs].default_gain = mroute->gain; - speakerinfo->input[speakerinfo->inputs].name = auto_strdup(astring_c(tempstring)); + /* fill in the input data on this speaker */ + speakerinfo->input[speakerinfo->inputs].gain = route->gain; + speakerinfo->input[speakerinfo->inputs].default_gain = route->gain; + speakerinfo->input[speakerinfo->inputs].name = auto_strdup(astring_c(tempstring)); - /* connect the output to the input */ - if (stream_device_output_to_stream_output(sound, outputnum, &stream, &streamoutput)) - stream_set_input(speakerinfo->mixer_stream, speakerinfo->inputs++, stream, streamoutput, mroute->gain); - } + /* connect the output to the input */ + if (stream_device_output_to_stream_output(sound, outputnum, &stream, &streamoutput)) + stream_set_input(speakerinfo->mixer_stream, speakerinfo->inputs++, stream, streamoutput, route->gain); + } + + /* otherwise, it's a sound chip */ + else + { + sound_stream *inputstream; + int streaminput; - /* otherwise, it's a sound chip */ - else - { - sound_stream *inputstream; - int streaminput; - - if (stream_device_input_to_stream_input(target_sound, inputnum++, &inputstream, &streaminput)) - if (stream_device_output_to_stream_output(sound, outputnum, &stream, &streamoutput)) - stream_set_input(inputstream, streaminput, stream, streamoutput, mroute->gain); - } + if (stream_device_input_to_stream_input(target_sound, inputnum++, &inputstream, &streaminput)) + if (stream_device_output_to_stream_output(sound, outputnum, &stream, &streamoutput)) + stream_set_input(inputstream, streaminput, stream, streamoutput, route->gain); } - } + } } } diff --git a/src/emu/sound.h b/src/emu/sound.h index 2f57ae6c040..48ebafe097a 100644 --- a/src/emu/sound.h +++ b/src/emu/sound.h @@ -21,7 +21,7 @@ CONSTANTS ***************************************************************************/ -#define MAX_OUTPUTS 256 /* maximum number of outputs a sound chip can support */ +#define MAX_OUTPUTS 4095 /* maximum number of outputs a sound chip can support */ #define ALL_OUTPUTS (MAX_OUTPUTS) /* special value indicating all outputs for the current chip */ @@ -56,8 +56,10 @@ typedef device_type sound_type; typedef struct _sound_route sound_route; struct _sound_route { - const char * target; /* tag of the target */ - int input; /* input ID, -1 is default behavior */ + sound_route * next; /* pointer to next route */ + UINT32 output; /* output index, or ALL_OUTPUTS */ + const char * target; /* target tag */ + UINT32 input; /* target input index */ float gain; /* gain */ }; @@ -67,7 +69,7 @@ typedef struct _sound_config sound_config; struct _sound_config { sound_type type; /* type of sound chip */ - sound_route route[ALL_OUTPUTS+1]; /* one route per output */ + sound_route * routelist; /* list of sound routes */ }; @@ -104,19 +106,23 @@ struct _speaker_config MDRV_DEVICE_MODIFY(_tag, SOUND) \ MDRV_DEVICE_CONFIG_CLEAR() \ MDRV_DEVICE_CONFIG_DATAPTR(sound_config, type, SOUND_##_type) \ - MDRV_DEVICE_CLOCK(_clock) + MDRV_DEVICE_CLOCK(_clock) \ + MDRV_SOUND_ROUTES_RESET() #define MDRV_SOUND_CONFIG(_config) \ MDRV_DEVICE_CONFIG(_config) + +/* sound routine is too complex for standard decoding, so we use a custom config */ #define MDRV_SOUND_ROUTE_EX(_output, _target, _gain, _input) \ - MDRV_DEVICE_CONFIG_DATAPTR_ARRAY_MEMBER(sound_config, route, _output, sound_route, target, _target) \ - MDRV_DEVICE_CONFIG_DATA32_ARRAY_MEMBER(sound_config, route, _output, sound_route, input, _input) \ - MDRV_DEVICE_CONFIG_DATAFP32_ARRAY_MEMBER(sound_config, route, _output, sound_route, gain, _gain, 24) + TOKEN_UINT64_PACK4(MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_1, 8, _output, 12, _input, 12, ((float)(_gain) * (float)(1 << 24)), 32), \ + TOKEN_PTR(stringptr, _target), #define MDRV_SOUND_ROUTE(_output, _target, _gain) \ MDRV_SOUND_ROUTE_EX(_output, _target, _gain, 0) +#define MDRV_SOUND_ROUTES_RESET() \ + TOKEN_UINT32_PACK1(MCONFIG_TOKEN_DEVICE_CONFIG_CUSTOM_FREE, 8), /* add/remove speakers */ diff --git a/src/emu/tokenize.h b/src/emu/tokenize.h index aaff8a6f73b..82152411938 100644 --- a/src/emu/tokenize.h +++ b/src/emu/tokenize.h @@ -28,7 +28,7 @@ /*************************************************************************** - MACROS + TYPE DEFINITIONS ***************************************************************************/ /* include this at the top of your union to get the standard fields */ @@ -46,6 +46,19 @@ const INT64 * i64ptr; \ +/* generic_token can be used when there are no particularly special types */ +typedef struct _generic_token generic_token; +struct _generic_token +{ + TOKEN_COMMON_FIELDS +}; + + + +/*************************************************************************** + MACROS +***************************************************************************/ + /* ----- compile-time token generation macros ----- */ /* GCC and C99 compilers can use designated initializers for type safety */ diff --git a/src/emu/validity.c b/src/emu/validity.c index 1302f0f72bb..b88278fba5e 100644 --- a/src/emu/validity.c +++ b/src/emu/validity.c @@ -1498,32 +1498,28 @@ static int validate_sound(int drivnum, const machine_config *config) for (cursound = sound_first(config); cursound != NULL; cursound = sound_next(cursound)) { const sound_config *curconfig = cursound->inline_config; - int routenum; + const sound_route *route; /* loop over all the routes */ - for (routenum = 0; routenum <= ALL_OUTPUTS; routenum++) + for (route = curconfig->routelist; route != NULL; route = route->next) { - const sound_route *mroute = &curconfig->route[routenum]; - if (mroute->target != NULL) + /* find a speaker with the requested tag */ + for (checkspeak = speaker_output_first(config); checkspeak != NULL; checkspeak = speaker_output_next(checkspeak)) + if (strcmp(route->target, checkspeak->tag) == 0) + break; + + /* if we didn't find one, look for another sound chip with the tag */ + if (checkspeak == NULL) { - /* find a speaker with the requested tag */ - for (checkspeak = speaker_output_first(config); checkspeak != NULL; checkspeak = speaker_output_next(checkspeak)) - if (strcmp(mroute->target, checkspeak->tag) == 0) + for (checksound = sound_first(config); checksound != NULL; checksound = sound_next(checksound)) + if (checksound != cursound && strcmp(route->target, checksound->tag) == 0) break; - /* if we didn't find one, look for another sound chip with the tag */ - if (checkspeak == NULL) + /* if we didn't find one, it's an error */ + if (checksound == NULL) { - for (checksound = sound_first(config); checksound != NULL; checksound = sound_next(checksound)) - if (checksound != cursound && strcmp(mroute->target, checksound->tag) == 0) - break; - - /* if we didn't find one, it's an error */ - if (checksound == NULL) - { - mame_printf_error("%s: %s attempting to route sound to non-existant speaker '%s'\n", driver->source_file, driver->name, mroute->target); - error = TRUE; - } + mame_printf_error("%s: %s attempting to route sound to non-existant speaker '%s'\n", driver->source_file, driver->name, route->target); + error = TRUE; } } } |