diff options
Diffstat (limited to 'src/emu/drivenum.cpp')
-rw-r--r-- | src/emu/drivenum.cpp | 201 |
1 files changed, 79 insertions, 122 deletions
diff --git a/src/emu/drivenum.cpp b/src/emu/drivenum.cpp index a23db4c54bc..41439f5dac4 100644 --- a/src/emu/drivenum.cpp +++ b/src/emu/drivenum.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "drivenum.h" #include "softlist_dev.h" + #include <ctype.h> @@ -35,17 +36,15 @@ driver_list::driver_list() int driver_list::find(const char *name) { // if no name, bail - if (name == nullptr) + if (!name) return -1; - // create a dummy item for comparison purposes - game_driver driver; - driver.name = name; - game_driver *driverptr = &driver; - // binary search to find it - const game_driver **result = reinterpret_cast<const game_driver **>(bsearch(&driverptr, s_drivers_sorted, s_driver_count, sizeof(*s_drivers_sorted), driver_sort_callback)); - return (result == nullptr) ? -1 : result - s_drivers_sorted; + game_driver const *const *const begin = s_drivers_sorted; + game_driver const *const *const end = begin + s_driver_count; + auto const cmp = [] (game_driver const *driver, char const *name) { return core_stricmp(driver->name, name) < 0; }; + game_driver const *const *const result = std::lower_bound(begin, end, name, cmp); + return ((result == end) || core_stricmp((*result)->name, name)) ? -1 : std::distance(begin, result); } @@ -66,19 +65,6 @@ bool driver_list::matches(const char *wildstring, const char *string) //------------------------------------------------- -// driver_sort_callback - compare two items in -// an array of game_driver pointers -//------------------------------------------------- - -int driver_list::driver_sort_callback(const void *elem1, const void *elem2) -{ - const game_driver * const *item1 = reinterpret_cast<const game_driver * const *>(elem1); - const game_driver * const *item2 = reinterpret_cast<const game_driver * const *>(elem2); - return core_stricmp((*item1)->name, (*item2)->name); -} - - -//------------------------------------------------- // penalty_compare - compare two strings for // closeness and assign a score. //------------------------------------------------- @@ -129,33 +115,25 @@ int driver_list::penalty_compare(const char *source, const char *target) //------------------------------------------------- driver_enumerator::driver_enumerator(emu_options &options) - : m_current(-1), - m_filtered_count(0), - m_options(options), - m_included(s_driver_count), - m_config(s_driver_count) + : m_current(-1) + , m_filtered_count(0) + , m_options(options) + , m_included(s_driver_count) + , m_config(CONFIG_CACHE_COUNT) { include_all(); } driver_enumerator::driver_enumerator(emu_options &options, const char *string) - : m_current(-1), - m_filtered_count(0), - m_options(options), - m_included(s_driver_count), - m_config(s_driver_count) + : driver_enumerator(options) { filter(string); } driver_enumerator::driver_enumerator(emu_options &options, const game_driver &driver) - : m_current(-1), - m_filtered_count(0), - m_options(options), - m_included(s_driver_count), - m_config(s_driver_count) + : driver_enumerator(options) { filter(driver); } @@ -176,24 +154,16 @@ driver_enumerator::~driver_enumerator() // driver, allocating on demand if needed //------------------------------------------------- -machine_config &driver_enumerator::config(int index, emu_options &options) const +std::shared_ptr<machine_config> const &driver_enumerator::config(std::size_t index, emu_options &options) const { - assert(index >= 0 && index < s_driver_count); + assert(index < s_driver_count); // if we don't have it cached, add it - if (m_config[index] == nullptr) - { - // if our cache is full, release the head entry - if (m_config_cache.size() == CONFIG_CACHE_COUNT) - { - int first = m_config_cache.front(); - m_config[first] = nullptr; - m_config_cache.erase(m_config_cache.begin()); - } - m_config[index] = std::make_unique<machine_config>(*s_drivers_sorted[index], options); - m_config_cache.push_back(index); - } - return *m_config[index]; + std::shared_ptr<machine_config> &config = m_config[index]; + if (!config) + config = std::make_shared<machine_config>(*s_drivers_sorted[index], options); + + return config; } @@ -202,13 +172,13 @@ machine_config &driver_enumerator::config(int index, emu_options &options) const // given string //------------------------------------------------- -int driver_enumerator::filter(const char *filterstring) +std::size_t driver_enumerator::filter(const char *filterstring) { // reset the count exclude_all(); // match name against each driver in the list - for (int index = 0; index < s_driver_count; index++) + for (std::size_t index = 0; index < s_driver_count; index++) if (matches(filterstring, s_drivers_sorted[index]->name)) include(index); @@ -221,13 +191,13 @@ int driver_enumerator::filter(const char *filterstring) // given driver //------------------------------------------------- -int driver_enumerator::filter(const game_driver &driver) +std::size_t driver_enumerator::filter(const game_driver &driver) { // reset the count exclude_all(); // match name against each driver in the list - for (int index = 0; index < s_driver_count; index++) + for (std::size_t index = 0; index < s_driver_count; index++) if (s_drivers_sorted[index] == &driver) include(index); @@ -242,12 +212,10 @@ int driver_enumerator::filter(const game_driver &driver) void driver_enumerator::include_all() { std::fill(m_included.begin(), m_included.end(), true); - m_filtered_count = s_driver_count; + m_filtered_count = m_included.size(); // always exclude the empty driver - int empty = find("___empty"); - assert(empty != -1); - m_included[empty] = 0; + exclude(find("___empty")); } @@ -258,20 +226,14 @@ void driver_enumerator::include_all() bool driver_enumerator::next() { - // always advance one release_current(); - m_current++; + // always advance one // if we have a filter, scan forward to the next match - while (m_current < s_driver_count) - { - if (m_included[m_current]) - break; - m_current++; - } + for (m_current++; (m_current < s_driver_count) && !m_included[m_current]; m_current++) { } // return true if we end up in range - return (m_current >= 0 && m_current < s_driver_count); + return (m_current >= 0) && (m_current < s_driver_count); } @@ -282,20 +244,14 @@ bool driver_enumerator::next() bool driver_enumerator::next_excluded() { - // always advance one release_current(); - m_current++; + // always advance one // if we have a filter, scan forward to the next match - while (m_current < s_driver_count) - { - if (!m_included[m_current]) - break; - m_current++; - } + for (m_current++; (m_current < s_driver_count) && m_included[m_current]; m_current++) { } // return true if we end up in range - return (m_current >= 0 && m_current < s_driver_count); + return (m_current >= 0) && (m_current < s_driver_count); } @@ -304,12 +260,12 @@ bool driver_enumerator::next_excluded() // an array of game_driver pointers //------------------------------------------------- -void driver_enumerator::find_approximate_matches(const char *string, int count, int *results) +void driver_enumerator::find_approximate_matches(const char *string, std::size_t count, int *results) { #undef rand // if no name, pick random entries - if (string == nullptr || string[0] == 0) + if (!string || !string[0]) { // seed the RNG first srand(osd_ticks()); @@ -323,7 +279,7 @@ void driver_enumerator::find_approximate_matches(const char *string, int count, assert(arrayindex == m_filtered_count); // shuffle - for (int shufnum = 0; shufnum < 4 * s_driver_count; shufnum++) + for (int shufnum = 0; shufnum < (4 * s_driver_count); shufnum++) { int item1 = rand() % m_filtered_count; int item2 = rand() % m_filtered_count; @@ -335,49 +291,49 @@ void driver_enumerator::find_approximate_matches(const char *string, int count, // copy out the first few entries for (int matchnum = 0; matchnum < count; matchnum++) results[matchnum] = templist[matchnum % m_filtered_count]; - return; } - - // allocate memory to track the penalty value - std::vector<int> penalty(count); - - // initialize everyone's states - for (int matchnum = 0; matchnum < count; matchnum++) + else { - penalty[matchnum] = 9999; - results[matchnum] = -1; - } + // allocate memory to track the penalty value + std::vector<int> penalty(count); - // scan the entire drivers array - for (int index = 0; index < s_driver_count; index++) - if (m_included[index]) + // initialize everyone's states + for (int matchnum = 0; matchnum < count; matchnum++) { - // skip things that can't run - if ((s_drivers_sorted[index]->flags & MACHINE_NO_STANDALONE) != 0) - continue; - - // pick the best match between driver name and description - int curpenalty = penalty_compare(string, s_drivers_sorted[index]->description); - int tmp = penalty_compare(string, s_drivers_sorted[index]->name); - curpenalty = std::min(curpenalty, tmp); + penalty[matchnum] = 9999; + results[matchnum] = -1; + } - // insert into the sorted table of matches - for (int matchnum = count - 1; matchnum >= 0; matchnum--) + // scan the entire drivers array + for (int index = 0; index < s_driver_count; index++) + { + // skip things that can't run + if (m_included[index] && !(s_drivers_sorted[index]->flags & MACHINE_NO_STANDALONE)) { - // stop if we're worse than the current entry - if (curpenalty >= penalty[matchnum]) - break; + // pick the best match between driver name and description + int curpenalty = penalty_compare(string, s_drivers_sorted[index]->description); + int tmp = penalty_compare(string, s_drivers_sorted[index]->name); + curpenalty = (std::min)(curpenalty, tmp); - // as long as this isn't the last entry, bump this one down - if (matchnum < count - 1) + // insert into the sorted table of matches + for (int matchnum = count - 1; matchnum >= 0; matchnum--) { - penalty[matchnum + 1] = penalty[matchnum]; - results[matchnum + 1] = results[matchnum]; + // stop if we're worse than the current entry + if (curpenalty >= penalty[matchnum]) + break; + + // as long as this isn't the last entry, bump this one down + if (matchnum < count - 1) + { + penalty[matchnum + 1] = penalty[matchnum]; + results[matchnum + 1] = results[matchnum]; + } + results[matchnum] = index; + penalty[matchnum] = curpenalty; } - results[matchnum] = index; - penalty[matchnum] = curpenalty; } } + } } @@ -390,14 +346,15 @@ void driver_enumerator::find_approximate_matches(const char *string, int count, void driver_enumerator::release_current() const { // skip if no current entry - if (m_current < 0 || m_current >= s_driver_count) - return; - - // skip if we haven't cached a config - if (m_config[m_current] == nullptr) - return; - - // iterate over software lists in this entry and reset - for (software_list_device &swlistdev : software_list_device_iterator(m_config[m_current]->root_device())) - swlistdev.release(); + if ((m_current >= 0) && (m_current < s_driver_count)) + { + // skip if we haven't cached a config + auto const cached = m_config.find(m_current); + if (cached != m_config.end()) + { + // iterate over software lists in this entry and reset + for (software_list_device &swlistdev : software_list_device_iterator(cached->second->root_device())) + swlistdev.release(); + } + } } |