summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend/mame
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2021-10-09 23:41:27 +1100
committer Vas Crabb <vas@vastheman.com>2021-10-09 23:41:27 +1100
commit2bd6aeb5017215e8e3d19f8e161e96774a7c5d14 (patch)
tree49d6d2bcbfd1aee74186d13d66591f633850938e /src/frontend/mame
parentb9bd9ea99c8cce816d0107ade3fd6903be053e8c (diff)
frontend: Support phonetic reading field from localised system name lists.
Diffstat (limited to 'src/frontend/mame')
-rw-r--r--src/frontend/mame/ui/selgame.cpp165
-rw-r--r--src/frontend/mame/ui/utils.cpp6
-rw-r--r--src/frontend/mame/ui/utils.h5
3 files changed, 111 insertions, 65 deletions
diff --git a/src/frontend/mame/ui/selgame.cpp b/src/frontend/mame/ui/selgame.cpp
index 93c3f3e5760..f4d2948b8e1 100644
--- a/src/frontend/mame/ui/selgame.cpp
+++ b/src/frontend/mame/ui/selgame.cpp
@@ -191,10 +191,8 @@ private:
// sort drivers and notify
std::collate<wchar_t> const &coll = std::use_facet<std::collate<wchar_t> >(std::locale());
auto const compare_names =
- [&coll] (std::string const &x, std::string const &y) -> bool
+ [&coll] (std::wstring const &wx, std::wstring const &wy) -> bool
{
- std::wstring const wx = wstring_from_utf8(x);
- std::wstring const wy = wstring_from_utf8(y);
return 0 > coll.compare(wx.data(), wx.data() + wx.size(), wy.data(), wy.data() + wy.size());
};
std::stable_sort(
@@ -207,28 +205,50 @@ private:
if (!lhs.is_clone && !rhs.is_clone)
{
- return compare_names(lhs.description, rhs.description);
+ return compare_names(
+ lhs.reading_description.empty() ? wstring_from_utf8(lhs.description) : lhs.reading_description,
+ rhs.reading_description.empty() ? wstring_from_utf8(rhs.description) : rhs.reading_description);
}
else if (lhs.is_clone && rhs.is_clone)
{
if (!std::strcmp(x.parent, y.parent))
- return compare_names(lhs.description, rhs.description);
+ {
+ return compare_names(
+ lhs.reading_description.empty() ? wstring_from_utf8(lhs.description) : lhs.reading_description,
+ rhs.reading_description.empty() ? wstring_from_utf8(rhs.description) : rhs.reading_description);
+ }
else
- return compare_names(lhs.parent, rhs.parent);
+ {
+ return compare_names(
+ lhs.reading_parent.empty() ? wstring_from_utf8(lhs.parent) : lhs.reading_parent,
+ rhs.reading_parent.empty() ? wstring_from_utf8(rhs.parent) : rhs.reading_parent);
+ }
}
else if (!lhs.is_clone && rhs.is_clone)
{
if (!std::strcmp(x.name, y.parent))
+ {
return true;
+ }
else
- return compare_names(lhs.description, rhs.parent);
+ {
+ return compare_names(
+ lhs.reading_description.empty() ? wstring_from_utf8(lhs.description) : lhs.reading_description,
+ rhs.reading_parent.empty() ? wstring_from_utf8(rhs.parent) : rhs.reading_parent);
+ }
}
else
{
if (!std::strcmp(x.parent, y.name))
+ {
return false;
+ }
else
- return compare_names(lhs.parent, rhs.description);
+ {
+ return compare_names(
+ lhs.reading_parent.empty() ? wstring_from_utf8(lhs.parent) : lhs.reading_parent,
+ rhs.reading_description.empty() ? wstring_from_utf8(rhs.description) : rhs.reading_description);
+ }
}
});
notify_available(AVAIL_SORTED_LIST);
@@ -336,11 +356,17 @@ private:
void load_titles(util::core_file &file)
{
char readbuf[1024];
+ std::string convbuf;
while (file.gets(readbuf, std::size(readbuf)))
{
- // shortname and description separated by tab
- auto const split(std::find(std::begin(readbuf), std::end(readbuf), '\t'));
- if (std::end(readbuf) == split)
+ // shortname, description, and description reading separated by tab
+ auto const eoln(
+ std::find_if(
+ std::begin(readbuf),
+ std::end(readbuf),
+ [] (char ch) { return !ch || ('\n' == ch) || ('\r' == ch); }));
+ auto const split(std::find(std::begin(readbuf), eoln, '\t'));
+ if (eoln == split)
continue;
std::string_view const shortname(readbuf, split - readbuf);
@@ -360,10 +386,10 @@ private:
continue;
}
- // strip additional columns
- auto const start(std::next(split));
- auto const end(std::find(start, std::end(readbuf), '\t'));
- auto const description(strtrimspace(std::string_view(start, end - start)));
+ // find the end of the description
+ auto const descstart(std::next(split));
+ auto const descend(std::find(descstart, eoln, '\t'));
+ auto const description(strtrimspace(std::string_view(descstart, descend - descstart)));
if (description.empty())
{
osd_printf_warning("Empty translated description for system '%s'\n", shortname);
@@ -380,6 +406,26 @@ private:
{
found->description = description;
}
+
+ // populate the reading if it's present
+ if (eoln == descend)
+ continue;
+ auto const readstart(std::next(descend));
+ auto const readend(std::find(readstart, eoln, '\t'));
+ auto const reading(strtrimspace(std::string_view(readstart, readend - readstart)));
+ if (reading.empty())
+ {
+ osd_printf_warning("Empty translated description reading for system '%s'\n", shortname);
+ }
+ else
+ {
+ found->reading_description = wstring_from_utf8(reading);
+ found->ucs_reading_description = ustr_from_utf8(normalize_unicode(reading, unicode_normalization_form::D, true));
+ convbuf.assign(found->driver->manufacturer);
+ convbuf.append(1, ' ');
+ convbuf.append(reading);
+ found->ucs_manufacturer_reading_description = ustr_from_utf8(normalize_unicode(convbuf, unicode_normalization_form::D, true));
+ }
}
// fill in untranslated descriptions
@@ -406,9 +452,14 @@ private:
return a.driver->name < b;
}));
if (m_sorted_list.end() != found)
+ {
info.parent = found->description;
+ info.reading_parent = found->reading_description;
+ }
else
+ {
info.parent = info.driver->parent;
+ }
}
}
}
@@ -1204,67 +1255,53 @@ void menu_select_game::populate_search()
// keep track of what we matched against
const std::u32string ucs_search(ustr_from_utf8(normalize_unicode(m_search, unicode_normalization_form::D, true)));
- // match shortnames
+ // check available search data
if (m_persistent_data.is_available(persistent_data::AVAIL_UCS_SHORTNAME))
- {
m_searched_fields |= persistent_data::AVAIL_UCS_SHORTNAME;
- for (std::pair<double, std::reference_wrapper<ui_system_info const> > &info : m_searchlist)
- info.first = util::edit_distance(ucs_search, info.second.get().ucs_shortname);
- }
-
- // match descriptions
if (m_persistent_data.is_available(persistent_data::AVAIL_UCS_DESCRIPTION))
- {
m_searched_fields |= persistent_data::AVAIL_UCS_DESCRIPTION;
- for (std::pair<double, std::reference_wrapper<ui_system_info const> > &info : m_searchlist)
- {
- if (info.first)
- {
- double const penalty(util::edit_distance(ucs_search, info.second.get().ucs_description));
- info.first = (std::min)(penalty, info.first);
- }
- }
- }
-
- // match "<manufacturer> <description>"
if (m_persistent_data.is_available(persistent_data::AVAIL_UCS_MANUF_DESC))
- {
m_searched_fields |= persistent_data::AVAIL_UCS_MANUF_DESC;
- for (std::pair<double, std::reference_wrapper<ui_system_info const> > &info : m_searchlist)
- {
- if (info.first)
- {
- double const penalty(util::edit_distance(ucs_search, info.second.get().ucs_manufacturer_description));
- info.first = (std::min)(penalty, info.first);
- }
- }
- }
-
- // match default description
if (m_persistent_data.is_available(persistent_data::AVAIL_UCS_DFLT_DESC))
- {
m_searched_fields |= persistent_data::AVAIL_UCS_DFLT_DESC;
- for (std::pair<double, std::reference_wrapper<ui_system_info const> > &info : m_searchlist)
+ if (m_persistent_data.is_available(persistent_data::AVAIL_UCS_MANUF_DFLT_DESC))
+ m_searched_fields |= persistent_data::AVAIL_UCS_MANUF_DFLT_DESC;
+
+ for (std::pair<double, std::reference_wrapper<ui_system_info const> > &info : m_searchlist)
+ {
+ info.first = 1.0;
+ ui_system_info const &sys(info.second);
+
+ // match shortnames
+ if (m_searched_fields & persistent_data::AVAIL_UCS_SHORTNAME)
+ info.first = util::edit_distance(ucs_search, sys.ucs_shortname);
+
+ // match reading
+ if (info.first && !sys.ucs_reading_description.empty())
{
- if (info.first && !info.second.get().ucs_default_description.empty())
- {
- double const penalty(util::edit_distance(ucs_search, info.second.get().ucs_default_description));
- info.first = (std::min)(penalty, info.first);
- }
+ info.first = (std::min)(util::edit_distance(ucs_search, sys.ucs_reading_description), info.first);
+
+ // match "<manufacturer> <reading>"
+ if (info.first)
+ info.first = (std::min)(util::edit_distance(ucs_search, sys.ucs_manufacturer_reading_description), info.first);
}
- }
- // match default description
- if (m_persistent_data.is_available(persistent_data::AVAIL_UCS_MANUF_DFLT_DESC))
- {
- m_searched_fields |= persistent_data::AVAIL_UCS_DFLT_DESC;
- for (std::pair<double, std::reference_wrapper<ui_system_info const> > &info : m_searchlist)
+ // match descriptions
+ if (info.first && (m_searched_fields & persistent_data::AVAIL_UCS_DESCRIPTION))
+ info.first = (std::min)(util::edit_distance(ucs_search, sys.ucs_description), info.first);
+
+ // match "<manufacturer> <description>"
+ if (info.first && (m_searched_fields & persistent_data::AVAIL_UCS_MANUF_DESC))
+ info.first = (std::min)(util::edit_distance(ucs_search, sys.ucs_manufacturer_description), info.first);
+
+ // match default description
+ if (info.first && (m_searched_fields & persistent_data::AVAIL_UCS_DFLT_DESC) && !sys.ucs_default_description.empty())
{
- if (info.first && !info.second.get().ucs_manufacturer_default_description.empty())
- {
- double const penalty(util::edit_distance(ucs_search, info.second.get().ucs_manufacturer_default_description));
- info.first = (std::min)(penalty, info.first);
- }
+ info.first = (std::min)(util::edit_distance(ucs_search, sys.ucs_default_description), info.first);
+
+ // match "<manufacturer> <default description>"
+ if (info.first && (m_searched_fields & persistent_data::AVAIL_UCS_MANUF_DFLT_DESC))
+ info.first = (std::min)(util::edit_distance(ucs_search, sys.ucs_manufacturer_default_description), info.first);
}
}
diff --git a/src/frontend/mame/ui/utils.cpp b/src/frontend/mame/ui/utils.cpp
index ea41c1337ad..dead21e8184 100644
--- a/src/frontend/mame/ui/utils.cpp
+++ b/src/frontend/mame/ui/utils.cpp
@@ -2151,9 +2151,13 @@ void swap(ui_system_info &a, ui_system_info &b) noexcept
swap(a.available, b.available);
swap(a.description, b.description);
swap(a.parent, b.parent);
+ swap(a.reading_description, b.reading_description);
+ swap(a.reading_parent, b.reading_parent);
swap(a.ucs_shortname, b.ucs_shortname);
swap(a.ucs_description, b.ucs_description);
+ swap(a.ucs_reading_description, b.ucs_reading_description);
swap(a.ucs_manufacturer_description, b.ucs_manufacturer_description);
- swap(a.ucs_description, b.ucs_description);
+ swap(a.ucs_manufacturer_reading_description, b.ucs_manufacturer_reading_description);
+ swap(a.ucs_default_description, b.ucs_default_description);
swap(a.ucs_manufacturer_default_description, b.ucs_manufacturer_default_description);
}
diff --git a/src/frontend/mame/ui/utils.h b/src/frontend/mame/ui/utils.h
index 496786c5f2a..4ef91eb5e2e 100644
--- a/src/frontend/mame/ui/utils.h
+++ b/src/frontend/mame/ui/utils.h
@@ -48,9 +48,14 @@ struct ui_system_info
std::string description;
std::string parent;
+ std::wstring reading_description;
+ std::wstring reading_parent;
+
std::u32string ucs_shortname;
std::u32string ucs_description;
+ std::u32string ucs_reading_description;
std::u32string ucs_manufacturer_description;
+ std::u32string ucs_manufacturer_reading_description;
std::u32string ucs_default_description;
std::u32string ucs_manufacturer_default_description;
};