diff options
author | 2007-12-17 15:19:59 +0000 | |
---|---|---|
committer | 2007-12-17 15:19:59 +0000 | |
commit | 7b77f1218624ea26dbb2efd85a19f795f5d4e02e (patch) | |
tree | 19209304095572b4fd61c2a2d6a5aa75c4e471ad /src/emu/output.c | |
parent | 3da7f476068b3ffef713218ba2fc1bd5030f2c38 (diff) |
Initial checkin of MAME 0.121.mame0121
Diffstat (limited to 'src/emu/output.c')
-rw-r--r-- | src/emu/output.c | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/src/emu/output.c b/src/emu/output.c new file mode 100644 index 00000000000..9fb63c490a7 --- /dev/null +++ b/src/emu/output.c @@ -0,0 +1,406 @@ +/*************************************************************************** + + output.c + + General purpose output routines. + + Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. + +***************************************************************************/ + +#include "output.h" +#include "mame.h" +#include <zlib.h> + + + +/*************************************************************************** + CONSTANTS +***************************************************************************/ + +#define HASH_SIZE 53 + + + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +typedef struct _output_notify output_notify; +struct _output_notify +{ + output_notify * next; /* link to next item */ + output_notifier notifier; /* callback to call */ + void * param; /* parameter to pass the callback */ +}; + + +typedef struct _output_item output_item; +struct _output_item +{ + output_item * next; /* next item in list */ + const char * name; /* string name of the item */ + UINT32 hash; /* hash for this item name */ + UINT32 id; /* unique ID for this item */ + INT32 value; /* current value */ + output_notify * notifylist; /* list of notifier callbacks */ +}; + + + +/*************************************************************************** + GLOBAL VARIABLES +***************************************************************************/ + +static output_item *itemtable[HASH_SIZE]; +static output_notify *global_notifylist; +static UINT32 uniqueid = 12345; + + + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +static void output_pause(running_machine *machine, int pause); +static void output_exit(running_machine *machine); + + + +/*************************************************************************** + INLINE FUNCTIONS +***************************************************************************/ + +/*------------------------------------------------- + copy_string - make a copy of a string +-------------------------------------------------*/ + +INLINE const char *copy_string(const char *string) +{ + char *newstring = malloc_or_die(strlen(string) + 1); + strcpy(newstring, string); + return newstring; +} + + +/*------------------------------------------------- + get_hash - return the hash of an output value +-------------------------------------------------*/ + +INLINE UINT32 get_hash(const char *string) +{ + return crc32(0, (UINT8 *)string, (UINT32)strlen(string)); +} + + +/*------------------------------------------------- + find_item - find an item based on a string +-------------------------------------------------*/ + +INLINE output_item *find_item(const char *string) +{ + UINT32 hash = get_hash(string); + output_item *item; + + /* use the hash as a starting point and find an entry */ + for (item = itemtable[hash % HASH_SIZE]; item != NULL; item = item->next) + if (item->hash == hash && strcmp(string, item->name) == 0) + return item; + + return NULL; +} + + +/*------------------------------------------------- + create_new_item - create a new item +-------------------------------------------------*/ + +INLINE output_item *create_new_item(const char *outname, INT32 value) +{ + output_item *item = malloc_or_die(sizeof(*item)); + UINT32 hash = get_hash(outname); + + /* fill in the data */ + item->next = itemtable[hash % HASH_SIZE]; + item->name = copy_string(outname); + item->hash = hash; + item->id = uniqueid++; + item->value = value; + item->notifylist = NULL; + + /* add us to the hash table */ + itemtable[hash % HASH_SIZE] = item; + return item; +} + + + +/*************************************************************************** + CORE IMPLEMENTATION +***************************************************************************/ + +/*------------------------------------------------- + output_init - initialize everything +-------------------------------------------------*/ + +void output_init(running_machine *machine) +{ + /* add pause callback */ + add_pause_callback(machine, output_pause); + + /* get a callback when done */ + add_exit_callback(machine, output_exit); + + /* reset the lists */ + memset(itemtable, 0, sizeof(itemtable)); + global_notifylist = NULL; +} + + +/*------------------------------------------------- + output_pause - send pause message +-------------------------------------------------*/ + +static void output_pause(running_machine *machine, int pause) +{ + output_set_value("pause", pause & 1); +} + + +/*------------------------------------------------- + output_exit - cleanup on exit +-------------------------------------------------*/ + +static void output_exit(running_machine *machine) +{ + output_notify *notify; + output_item *item; + int hash; + + /* remove all items */ + for (hash = 0; hash < HASH_SIZE; hash++) + for (item = itemtable[hash]; item != NULL; ) + { + output_item *next = item->next; + + /* remove all notifiers */ + for (notify = item->notifylist; notify != NULL; ) + { + output_notify *next = notify->next; + free(notify); + notify = next; + } + + /* free the name and the item */ + if (item->name != NULL) + free((void *)item->name); + free(item); + item = next; + } + + /* remove all global notifiers */ + for (notify = global_notifylist; notify != NULL; ) + { + output_notify *next = notify->next; + free(notify); + notify = next; + } +} + + +/*------------------------------------------------- + output_set_value - set the value of an output +-------------------------------------------------*/ + +void output_set_value(const char *outname, INT32 value) +{ + output_item *item = find_item(outname); + output_notify *notify; + INT32 oldval; + + /* if no item of that name, create a new one and send the item's state */ + if (item == NULL) + { + item = create_new_item(outname, value); + oldval = value + 1; + } + + else + { + /* set the new value */ + oldval = item->value; + item->value = value; + } + + /* if the value is different, signal the notifier */ + if (oldval != value) + { + /* call the local notifiers first */ + for (notify = item->notifylist; notify != NULL; notify = notify->next) + (*notify->notifier)(outname, value, notify->param); + + /* call the global notifiers next */ + for (notify = global_notifylist; notify != NULL; notify = notify->next) + (*notify->notifier)(outname, value, notify->param); + } +} + + +/*------------------------------------------------- + output_set_indexed_value - set the value of an + indexed output +-------------------------------------------------*/ + +void output_set_indexed_value(const char *basename, int index, int value) +{ + char buffer[100]; + char *dest = buffer; + + /* copy the string */ + while (*basename != 0) + *dest++ = *basename++; + + /* append the index */ + if (index >= 1000) *dest++ = '0' + ((index / 1000) % 10); + if (index >= 100) *dest++ = '0' + ((index / 100) % 10); + if (index >= 10) *dest++ = '0' + ((index / 10) % 10); + *dest++ = '0' + (index % 10); + *dest++ = 0; + + /* set the value */ + output_set_value(buffer, value); +} + + +/*------------------------------------------------- + output_get_value - return the value of an + output +-------------------------------------------------*/ + +INT32 output_get_value(const char *outname) +{ + output_item *item = find_item(outname); + + /* if no item, value is 0 */ + if (item == NULL) + return 0; + return item->value; +} + + +/*------------------------------------------------- + output_get_indexed_value - get the value of an + indexed output +-------------------------------------------------*/ + +INT32 output_get_indexed_value(const char *basename, int index) +{ + char buffer[100]; + char *dest = buffer; + + /* copy the string */ + while (*basename != 0) + *dest++ = *basename++; + + /* append the index */ + if (index >= 1000) *dest++ = '0' + ((index / 1000) % 10); + if (index >= 100) *dest++ = '0' + ((index / 100) % 10); + if (index >= 10) *dest++ = '0' + ((index / 10) % 10); + *dest++ = '0' + (index % 10); + *dest++ = 0; + + /* set the value */ + return output_get_value(buffer); +} + + +/*------------------------------------------------- + output_set_notifier - sets a notifier callback + for a particular output, or for all outputs + if NULL is specified +-------------------------------------------------*/ + +void output_set_notifier(const char *outname, output_notifier callback, void *param) +{ + output_notify **headptr; + + /* if an item is specified, find it */ + if (outname != NULL) + { + output_item *item = find_item(outname); + + /* if no item of that name, create a new one */ + if (item == NULL) + item = create_new_item(outname, 0); + headptr = &item->notifylist; + } + + /* if no item is specified, we add to the global list */ + else + headptr = &global_notifylist; + + /* find the end of the list and add to it */ + while (*headptr != NULL) + headptr = &(*headptr)->next; + *headptr = malloc_or_die(sizeof(**headptr)); + + /* fill in the new record */ + (*headptr)->next = NULL; + (*headptr)->notifier = callback; + (*headptr)->param = param; +} + + +/*------------------------------------------------- + output_notify_all - immediately call the given + notifier for all outputs +-------------------------------------------------*/ + +void output_notify_all(output_notifier callback, void *param) +{ + output_item *item; + int hash; + + /* remove all items */ + for (hash = 0; hash < HASH_SIZE; hash++) + for (item = itemtable[hash]; item != NULL; item = item->next) + (*callback)(item->name, item->value, param); +} + + +/*------------------------------------------------- + output_name_to_id - returns a unique ID for + a given name +-------------------------------------------------*/ + +UINT32 output_name_to_id(const char *outname) +{ + output_item *item = find_item(outname); + + /* if no item, ID is 0 */ + if (item == NULL) + return 0; + return item->id; +} + + +/*------------------------------------------------- + output_id_to_name - returns a name that maps + to a given unique ID +-------------------------------------------------*/ + +const char *output_id_to_name(UINT32 id) +{ + output_item *item; + int hash; + + /* remove all items */ + for (hash = 0; hash < HASH_SIZE; hash++) + for (item = itemtable[hash]; item != NULL; item = item->next) + if (item->id == id) + return item->name; + + /* nothing found, return NULL */ + return NULL; +} |