diff options
Diffstat (limited to 'src/emu/output.cpp')
-rw-r--r-- | src/emu/output.cpp | 157 |
1 files changed, 90 insertions, 67 deletions
diff --git a/src/emu/output.cpp b/src/emu/output.cpp index 5969d1dbfc5..95b92cfc5d0 100644 --- a/src/emu/output.cpp +++ b/src/emu/output.cpp @@ -2,17 +2,19 @@ // copyright-holders:Nicola Salmoria, Aaron Giles, Vas Crabb /*************************************************************************** - output.c + output.cpp General purpose output routines. + ***************************************************************************/ #include "emu.h" -#include "coreutil.h" -#include "modules/output/output_module.h" +#include "output.h" + +#include <algorithm> -#define OUTPUT_VERBOSE 0 +#define OUTPUT_VERBOSE 0 @@ -55,10 +57,10 @@ void output_manager::output_item::notify(s32 value) // OUTPUT ITEM PROXY //************************************************************************** -void output_manager::item_proxy::resolve(device_t &device, std::string const &name) +void output_manager::item_proxy::resolve(device_t &device, std::string_view name) { assert(!m_item); - m_item = &device.machine().output().find_or_create_item(name.c_str(), 0); + m_item = &device.machine().output().find_or_create_item(name, 0); } @@ -67,24 +69,54 @@ void output_manager::item_proxy::resolve(device_t &device, std::string const &na // OUTPUT MANAGER //************************************************************************** -//------------------------------------------------- -// output_manager - constructor -//------------------------------------------------- +/*------------------------------------------------- + output_manager - constructor +-------------------------------------------------*/ output_manager::output_manager(running_machine &machine) - : m_machine(machine), - m_uniqueid(12345) + : m_machine(machine) + , m_uniqueid(12345) { - /* add pause callback */ + // add callbacks 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)); + machine.save().register_presave(save_prepost_delegate(FUNC(output_manager::presave), this)); + machine.save().register_postload(save_prepost_delegate(FUNC(output_manager::postload), this)); } + +/*------------------------------------------------- + register_save - register for save states +-------------------------------------------------*/ + +void output_manager::register_save() +{ + assert(m_save_order.empty()); + assert(!m_save_data); + + // make space for the data + m_save_order.clear(); + m_save_order.reserve(m_itemtable.size()); + m_save_data = std::make_unique<s32 []>(m_itemtable.size()); + + // sort existing outputs by name and register for save + for (auto &item : m_itemtable) + m_save_order.emplace_back(item.second); + std::sort(m_save_order.begin(), m_save_order.end(), [] (auto const &l, auto const &r) { return l.get().name() < r.get().name(); }); + + // register the reserved space for saving + machine().save().save_pointer(nullptr, "output", nullptr, 0, NAME(m_save_data), m_itemtable.size()); + if (OUTPUT_VERBOSE) + osd_printf_verbose("Registered %u outputs for save states\n", m_itemtable.size()); + +} + + /*------------------------------------------------- find_item - find an item based on a string -------------------------------------------------*/ -output_manager::output_item* output_manager::find_item(const char *string) +output_manager::output_item *output_manager::find_item(std::string_view string) { auto item = m_itemtable.find(std::string(string)); if (item != m_itemtable.end()) @@ -98,22 +130,26 @@ output_manager::output_item* output_manager::find_item(const char *string) create_new_item - create a new item -------------------------------------------------*/ -output_manager::output_item &output_manager::create_new_item(const char *outname, s32 value) +output_manager::output_item &output_manager::create_new_item(std::string_view outname, s32 value) { + if (OUTPUT_VERBOSE) + osd_printf_verbose("Creating output %s = %d%s\n", outname, value, m_save_data ? " (will not be saved)" : ""); + auto const ins(m_itemtable.emplace( std::piecewise_construct, std::forward_as_tuple(outname), - std::forward_as_tuple(*this, outname, m_uniqueid++, value))); + std::forward_as_tuple(*this, std::string(outname), m_uniqueid++, value))); assert(ins.second); return ins.first->second; } -output_manager::output_item &output_manager::find_or_create_item(const char *outname, s32 value) +output_manager::output_item &output_manager::find_or_create_item(std::string_view outname, s32 value) { output_item *const item = find_item(outname); return item ? *item : create_new_item(outname, value); } + /*------------------------------------------------- output_pause - send pause message -------------------------------------------------*/ @@ -130,44 +166,40 @@ void output_manager::resume() /*------------------------------------------------- - output_set_value - set the value of an output + presave - prepare data for save state -------------------------------------------------*/ -void output_manager::set_value(const char *outname, s32 value) +void output_manager::presave() { - output_item *const item = find_item(outname); - - // if no item of that name, create a new one and force notification - if (!item) - create_new_item(outname, value).notify(value); - else - item->set(value); // set the new value (notifies on change) + for (size_t i = 0; m_save_order.size() > i; ++i) + m_save_data[i] = m_save_order[i].get().get(); } /*------------------------------------------------- - output_set_indexed_value - set the value of an - indexed output + postload - restore loaded data -------------------------------------------------*/ -void output_manager::set_indexed_value(const char *basename, int index, int value) +void output_manager::postload() { - char buffer[100]; - char *dest = buffer; + for (size_t i = 0; m_save_order.size() > i; ++i) + m_save_order[i].get().set(m_save_data[i]); +} + - /* copy the string */ - while (*basename != 0) - *dest++ = *basename++; +/*------------------------------------------------- + output_set_value - set the value of an output +-------------------------------------------------*/ - /* 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; +void output_manager::set_value(std::string_view outname, s32 value) +{ + output_item *const item = find_item(outname); - /* set the value */ - set_value(buffer, value); + // if no item of that name, create a new one and force notification + if (!item) + create_new_item(outname, value).notify(value); + else + item->set(value); // set the new value (notifies on change) } @@ -176,7 +208,7 @@ void output_manager::set_indexed_value(const char *basename, int index, int valu output -------------------------------------------------*/ -s32 output_manager::get_value(const char *outname) +s32 output_manager::get_value(std::string_view outname) { output_item const *const item = find_item(outname); @@ -185,36 +217,27 @@ s32 output_manager::get_value(const char *outname) } -/*------------------------------------------------- - output_set_notifier - sets a notifier callback - for a particular output, or for all outputs - if nullptr is specified --------------------------------------------------*/ +//------------------------------------------------- +// set_notifier - sets a notifier callback for a +// particular output +//------------------------------------------------- -void output_manager::set_notifier(const char *outname, output_notifier_func callback, void *param) +void output_manager::set_notifier(std::string_view outname, notifier_func callback, void *param) { // if an item is specified, find/create it - if (outname) - { - output_item *const item = find_item(outname); - (item ? *item : create_new_item(outname, 0)).set_notifier(callback, param); - } - else - { - m_global_notifylist.emplace_back(callback, param); - } + output_item *const item = find_item(outname); + (item ? *item : create_new_item(outname, 0)).set_notifier(callback, param); } -/*------------------------------------------------- - output_notify_all - immediately call the given - notifier for all outputs --------------------------------------------------*/ +//------------------------------------------------- +// set_global_notifier - sets a notifier callback +// for all outputs +//------------------------------------------------- -void output_manager::notify_all(output_module *module) +void output_manager::set_global_notifier(notifier_func callback, void *param) { - for (auto &item : m_itemtable) - module->notify(item.second.name().c_str(), item.second.get()); + m_global_notifylist.emplace_back(callback, param); } @@ -223,7 +246,7 @@ void output_manager::notify_all(output_module *module) a given name -------------------------------------------------*/ -u32 output_manager::name_to_id(const char *outname) +u32 output_manager::name_to_id(std::string_view outname) { // if no item, ID is 0 output_item const *const item = find_item(outname); @@ -236,12 +259,12 @@ u32 output_manager::name_to_id(const char *outname) to a given unique ID -------------------------------------------------*/ -const char *output_manager::id_to_name(u32 id) +char const *output_manager::id_to_name(u32 id) { for (auto &item : m_itemtable) if (item.second.id() == id) return item.second.name().c_str(); - /* nothing found, return nullptr */ + // nothing found, return nullptr return nullptr; } |