mirror of
https://github.com/holub/mame
synced 2025-05-06 22:35:43 +03:00
257 lines
6.5 KiB
C++
257 lines
6.5 KiB
C++
// license:BSD-3-Clause
|
|
// copyright-holders:Nicola Salmoria, Aaron Giles
|
|
/***************************************************************************
|
|
|
|
output.c
|
|
|
|
General purpose output routines.
|
|
***************************************************************************/
|
|
|
|
#include "emu.h"
|
|
#include "coreutil.h"
|
|
#include "modules/output/output_module.h"
|
|
|
|
|
|
#define OUTPUT_VERBOSE 0
|
|
|
|
|
|
//**************************************************************************
|
|
// OUTPUT MANAGER
|
|
//**************************************************************************
|
|
|
|
//-------------------------------------------------
|
|
// output_manager - constructor
|
|
//-------------------------------------------------
|
|
|
|
output_manager::output_manager(running_machine &machine)
|
|
: m_machine(machine),
|
|
m_uniqueid(12345)
|
|
{
|
|
/* add pause callback */
|
|
machine.add_notifier(MACHINE_NOTIFY_PAUSE, machine_notify_delegate(&output_manager::pause, this));
|
|
machine.add_notifier(MACHINE_NOTIFY_RESUME, machine_notify_delegate(&output_manager::resume, this));
|
|
}
|
|
|
|
/*-------------------------------------------------
|
|
find_item - find an item based on a string
|
|
-------------------------------------------------*/
|
|
|
|
output_manager::output_item* output_manager::find_item(const char *string)
|
|
{
|
|
auto item = m_itemtable.find(std::string(string));
|
|
if (item != m_itemtable.end())
|
|
return &item->second;
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
create_new_item - create a new item
|
|
-------------------------------------------------*/
|
|
|
|
output_manager::output_item *output_manager::create_new_item(const char *outname, int32_t value)
|
|
{
|
|
output_item item;
|
|
|
|
/* fill in the data */
|
|
item.name = outname;
|
|
item.id = m_uniqueid++;
|
|
item.value = value;
|
|
|
|
/* add us to the hash table */
|
|
m_itemtable.insert(std::pair<std::string, output_item>(outname, item));
|
|
return &m_itemtable.find(outname)->second;
|
|
}
|
|
|
|
/*-------------------------------------------------
|
|
output_pause - send pause message
|
|
-------------------------------------------------*/
|
|
|
|
void output_manager::pause()
|
|
{
|
|
set_value("pause", 1);
|
|
}
|
|
|
|
void output_manager::resume()
|
|
{
|
|
set_value("pause", 0);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
output_set_value - set the value of an output
|
|
-------------------------------------------------*/
|
|
|
|
void output_manager::set_value(const char *outname, int32_t value)
|
|
{
|
|
output_item *item = find_item(outname);
|
|
int32_t oldval;
|
|
|
|
/* if no item of that name, create a new one and send the item's state */
|
|
if (item == nullptr)
|
|
{
|
|
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)
|
|
{
|
|
if (OUTPUT_VERBOSE)
|
|
machine().logerror("Output %s = %d (was %d)\n", outname, value, oldval);
|
|
|
|
/* call the local notifiers first */
|
|
for (auto notify : item->notifylist)
|
|
(*notify.m_notifier)(outname, value, notify.m_param);
|
|
|
|
/* call the global notifiers next */
|
|
for (auto notify : m_global_notifylist)
|
|
(*notify.m_notifier)(outname, value, notify.m_param);
|
|
}
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
output_set_indexed_value - set the value of an
|
|
indexed output
|
|
-------------------------------------------------*/
|
|
|
|
void output_manager::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 */
|
|
set_value(buffer, value);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
output_get_value - return the value of an
|
|
output
|
|
-------------------------------------------------*/
|
|
|
|
int32_t output_manager::get_value(const char *outname)
|
|
{
|
|
output_item *item = find_item(outname);
|
|
|
|
/* if no item, value is 0 */
|
|
if (item == nullptr)
|
|
return 0;
|
|
return item->value;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
output_get_indexed_value - get the value of an
|
|
indexed output
|
|
-------------------------------------------------*/
|
|
|
|
int32_t output_manager::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 get_value(buffer);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
output_set_notifier - sets a notifier callback
|
|
for a particular output, or for all outputs
|
|
if nullptr is specified
|
|
-------------------------------------------------*/
|
|
|
|
void output_manager::set_notifier(const char *outname, output_notifier_func callback, void *param)
|
|
{
|
|
output_notify notify(callback, param);
|
|
/* if an item is specified, find it */
|
|
if (outname != nullptr)
|
|
{
|
|
output_item *item = find_item(outname);
|
|
|
|
/* if no item of that name, create a new one */
|
|
if (item == nullptr)
|
|
item = create_new_item(outname, 0);
|
|
|
|
item->notifylist.push_back(notify);
|
|
}
|
|
else
|
|
m_global_notifylist.push_back(notify);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
output_notify_all - immediately call the given
|
|
notifier for all outputs
|
|
-------------------------------------------------*/
|
|
|
|
void output_manager::notify_all(output_module *module)
|
|
{
|
|
for (auto &item : m_itemtable)
|
|
module->notify(item.second.name.c_str(), item.second.value);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
output_name_to_id - returns a unique ID for
|
|
a given name
|
|
-------------------------------------------------*/
|
|
|
|
uint32_t output_manager::name_to_id(const char *outname)
|
|
{
|
|
output_item *item = find_item(outname);
|
|
|
|
/* if no item, ID is 0 */
|
|
if (item == nullptr)
|
|
return 0;
|
|
return item->id;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
output_id_to_name - returns a name that maps
|
|
to a given unique ID
|
|
-------------------------------------------------*/
|
|
|
|
const char *output_manager::id_to_name(uint32_t id)
|
|
{
|
|
for (auto &item : m_itemtable)
|
|
if (item.second.id == id)
|
|
return item.second.name.c_str();
|
|
|
|
/* nothing found, return nullptr */
|
|
return nullptr;
|
|
}
|