diff options
Diffstat (limited to 'src/osd/modules/osdmodule.cpp')
-rw-r--r-- | src/osd/modules/osdmodule.cpp | 121 |
1 files changed, 72 insertions, 49 deletions
diff --git a/src/osd/modules/osdmodule.cpp b/src/osd/modules/osdmodule.cpp index 75adc5c75bb..0fb43d4331a 100644 --- a/src/osd/modules/osdmodule.cpp +++ b/src/osd/modules/osdmodule.cpp @@ -1,47 +1,38 @@ // license:BSD-3-Clause // copyright-holders:Couriersud /* - * osdmodule.c + * osdmodule.cpp * */ #include "modules/osdmodule.h" +#include "emucore.h" + +#include "osdcore.h" + #include <algorithm> osd_module_manager::osd_module_manager() { - for (int i=0; i<MAX_MODULES; i++) - { - m_modules[i] = nullptr; - m_selected[i] = nullptr; - } } + osd_module_manager::~osd_module_manager() { - for (int i = 0; m_modules[i] != nullptr; i++) - { - global_free(m_modules[i]); - } } void osd_module_manager::register_module(const module_type &mod_type) { - auto const slot = std::find(std::begin(m_modules), std::end(m_modules), nullptr); - if (std::end(m_modules) == slot) - throw emu_fatalerror("osd_module_manager::register_module: Module registration beyond MAX_MODULES!"); - - osd_module *module = mod_type(); + std::unique_ptr<osd_module> module = mod_type(); if (module->probe()) { osd_printf_verbose("===> registered module %s %s\n", module->name(), module->type()); - *slot = module; + m_modules.emplace_back(std::move(module)); } else { osd_printf_verbose("===> not supported %s %s\n", module->name(), module->type()); - global_free(module); } } @@ -54,64 +45,96 @@ osd_module *osd_module_manager::get_module_generic(const char *type, const char { int const i = get_module_index(type, name); if (i >= 0) - return m_modules[i]; + return m_modules[i].get(); else return nullptr; } -osd_module *osd_module_manager::select_module(const char *type, const char *name) +osd_module &osd_module_manager::select_module(osd_interface &osd, const osd_options &options, const char *type, const char *name) { - osd_module *m = get_module_generic(type, name); - - // FIXME: check if already exists! - int i; - for (i = 0; m_selected[i] != nullptr; i++) - ; - m_selected[i] = m; - return m; -} + // see if a module of this type has already been already selected + for (osd_module &existing : m_selected) + { + if (existing.type() == type) + { + osd_printf_warning( + "Attempt to select %s module %s after selecting module %s\n", + type, + (name && *name) ? name : "<default>", + existing.name()); + return existing; + } + } -void osd_module_manager::init(const osd_options &options) -{ - for (int i = 0; m_selected[i] != nullptr; i++) + // try to start the selected module + osd_module *const m = get_module_generic(type, name); + if (m) { - m_selected[i]->init(options); + //osd_printf_verbose("Attempting to initialize %s module %s\n", type, m->name()); + if (!m->init(osd, options)) + { + m_selected.emplace_back(*m); + return *m; + } + osd_printf_verbose("Initializing %s module %s failed\n", type, m->name()); + } + else + { + osd_printf_verbose("Could not find %s module %s\n", type, name ? name : "<default>"); + } + + // walk down the list until something works + for (auto const &fallback : m_modules) + { + if ((fallback->type() == type) && (fallback.get() != m)) + { + osd_printf_verbose("Attempting to initialize %s module %s\n", type, fallback->name()); + if (!fallback->init(osd, options)) + { + osd_printf_warning( + m + ? "Initializing %s module %s failed, falling back to %s\n" + : "Could not find %s module %s, falling back to %s\n", + type, + m ? m->name() : (name && *name) ? name : "<default>", + fallback->name()); + m_selected.emplace_back(*fallback); + return *fallback; + } + } } + + // can't deal with absence of a module, and at least the "none" module should have worked + throw emu_fatalerror("All %s modules failed to initialize", type); } void osd_module_manager::exit() { // Find count - int cnt; - for (cnt = 0; m_selected[cnt] != nullptr; cnt++) - ; - for (int i = cnt - 1; i >= 0; i--) + while (!m_selected.empty()) { - m_selected[i]->exit(); - m_selected[i] = nullptr; + m_selected.back().get().exit(); + m_selected.pop_back(); } } int osd_module_manager::get_module_index(const char *type, const char *name) const { - for (int i = 0; m_modules[i] != nullptr; i++) + for (int i = 0; m_modules.size() > i; i++) { - if (strcmp(m_modules[i]->type(), type) == 0 && ((name[0] == 0) || (strcmp(name, m_modules[i]->name())==0))) + if ((m_modules[i]->type() == type) && (!name[0] || (m_modules[i]->name() == name))) return i; } return -1; } -void osd_module_manager::get_module_names(const char *type, const int max, int *num, const char *names[]) const +std::vector<std::string_view> osd_module_manager::get_module_names(const char *type) const { - *num = 0; - for (int i = 0; m_modules[i] != nullptr; i++) + std::vector<std::string_view> result; + for (auto &m : m_modules) { - if ((strcmp(m_modules[i]->type(), type) == 0) && (*num < max)) - { - names[*num] = m_modules[i]->name(); - *num = *num + 1; - } - + if (m->type() == type) + result.emplace_back(m->name()); } + return result; } |