summaryrefslogtreecommitdiffstats
path: root/docs/release/src/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'docs/release/src/frontend')
-rw-r--r--docs/release/src/frontend/mame/clifront.cpp13
-rw-r--r--docs/release/src/frontend/mame/language.cpp115
-rw-r--r--docs/release/src/frontend/mame/ui/about.cpp266
-rw-r--r--docs/release/src/frontend/mame/ui/inifile.cpp90
4 files changed, 398 insertions, 86 deletions
diff --git a/docs/release/src/frontend/mame/clifront.cpp b/docs/release/src/frontend/mame/clifront.cpp
index f7c0db3e1dd..c2115c943cd 100644
--- a/docs/release/src/frontend/mame/clifront.cpp
+++ b/docs/release/src/frontend/mame/clifront.cpp
@@ -1059,16 +1059,18 @@ const char cli_frontend::s_softlist_xml_dtd[] =
"<?xml version=\"1.0\"?>\n" \
"<!DOCTYPE softwarelists [\n" \
"<!ELEMENT softwarelists (softwarelist*)>\n" \
- "\t<!ELEMENT softwarelist (software+)>\n" \
+ "\t<!ELEMENT softwarelist (notes?, software+)>\n" \
"\t\t<!ATTLIST softwarelist name CDATA #REQUIRED>\n" \
"\t\t<!ATTLIST softwarelist description CDATA #IMPLIED>\n" \
- "\t\t<!ELEMENT software (description, year, publisher, info*, sharedfeat*, part*)>\n" \
+ "\t\t<!ELEMENT notes (#PCDATA)>\n" \
+ "\t\t<!ELEMENT software (description, year, publisher, notes?, info*, sharedfeat*, part*)>\n" \
"\t\t\t<!ATTLIST software name CDATA #REQUIRED>\n" \
"\t\t\t<!ATTLIST software cloneof CDATA #IMPLIED>\n" \
"\t\t\t<!ATTLIST software supported (yes|partial|no) \"yes\">\n" \
"\t\t\t<!ELEMENT description (#PCDATA)>\n" \
"\t\t\t<!ELEMENT year (#PCDATA)>\n" \
"\t\t\t<!ELEMENT publisher (#PCDATA)>\n" \
+ "\t\t\t<!ELEMENT notes (#PCDATA)>\n" \
"\t\t\t<!ELEMENT info EMPTY>\n" \
"\t\t\t\t<!ATTLIST info name CDATA #REQUIRED>\n" \
"\t\t\t\t<!ATTLIST info value CDATA #IMPLIED>\n" \
@@ -1130,9 +1132,12 @@ void cli_frontend::output_single_softlist(std::ostream &out, software_list_devic
util::stream_format(out, "\t\t\t<year>%s</year>\n", util::xml::normalize_string(swinfo.year().c_str()));
util::stream_format(out, "\t\t\t<publisher>%s</publisher>\n", util::xml::normalize_string(swinfo.publisher().c_str()));
- for (const feature_list_item &flist : swinfo.other_info())
+ for (const auto &flist : swinfo.info())
util::stream_format(out, "\t\t\t<info name=\"%s\" value=\"%s\"/>\n", flist.name(), util::xml::normalize_string(flist.value().c_str()));
+ for (const auto &flist : swinfo.shared_features())
+ util::stream_format(out, "\t\t\t<sharedfeat name=\"%s\" value=\"%s\"/>\n", flist.name(), util::xml::normalize_string(flist.value().c_str()));
+
for (const software_part &part : swinfo.parts())
{
util::stream_format(out, "\t\t\t<part name=\"%s\"", util::xml::normalize_string(part.name().c_str()));
@@ -1141,7 +1146,7 @@ void cli_frontend::output_single_softlist(std::ostream &out, software_list_devic
out << ">\n";
- for (const feature_list_item &flist : part.featurelist())
+ for (const auto &flist : part.features())
util::stream_format(out, "\t\t\t\t<feature name=\"%s\" value=\"%s\" />\n", flist.name(), util::xml::normalize_string(flist.value().c_str()));
// TODO: display ROM region information
diff --git a/docs/release/src/frontend/mame/language.cpp b/docs/release/src/frontend/mame/language.cpp
index d68ba282087..486283110a6 100644
--- a/docs/release/src/frontend/mame/language.cpp
+++ b/docs/release/src/frontend/mame/language.cpp
@@ -9,6 +9,8 @@
***************************************************************************/
#include "emu.h"
+#include "language.h"
+
#include "emuopts.h"
#include "corestr.h"
@@ -17,46 +19,20 @@
#include <memory>
#include <new>
#include <unordered_map>
+#include <utility>
namespace {
-constexpr uint32_t MO_MAGIC = 0x950412de;
-constexpr uint32_t MO_MAGIC_REVERSED = 0xde120495;
-
-struct cstr_hash
-{
- size_t operator()(char const *s) const noexcept
- {
- // Bernstein string hash
- size_t result(5381);
- while (*s)
- result = ((result << 5) + result) + u8(*s++);
- return result;
- }
-};
-
-struct cstr_compare
-{
- size_t operator()(char const *x, char const *y) const noexcept
- {
- return !std::strcmp(x, y);
- }
-};
+constexpr u32 MO_MAGIC = 0x950412de;
+constexpr u32 MO_MAGIC_REVERSED = 0xde120495;
std::unique_ptr<u32 []> f_translation_data;
-std::unordered_map<char const *, char const *, cstr_hash, cstr_compare> f_translation_map;
+std::unordered_map<std::string_view, std::pair<char const *, u32> > f_translation_map;
} // anonymous namespace
-char const *lang_translate(char const *word)
-{
- auto const found = f_translation_map.find(word);
- return (f_translation_map.end() != found) ? found->second : word;
-}
-
-
void load_translation(emu_options &m_options)
{
f_translation_data.reset();
@@ -91,7 +67,7 @@ void load_translation(emu_options &m_options)
return;
}
- f_translation_data.reset(new (std::nothrow) uint32_t [(size + 3) / 4]);
+ f_translation_data.reset(new (std::nothrow) u32 [(size + 3) / 4]);
if (!f_translation_data)
{
file.close();
@@ -176,12 +152,81 @@ void load_translation(emu_options &m_options)
continue;
}
- char const *const original = &data[original_offset];
- char const *const translation = &data[translation_offset];
- auto const ins = f_translation_map.emplace(original, translation);
+ std::string_view const original(&data[original_offset], original_length);
+ char const *const translation(&data[translation_offset]);
+ auto const ins = f_translation_map.emplace(original, std::make_pair(translation, translation_length));
if (!ins.second)
- osd_printf_warning("Loading translation file %s: translation %u '%s'='%s' conflicts with previous translation '%s'='%s'\n", name, i, original, translation, ins.first->first, ins.first->second);
+ {
+ osd_printf_warning(
+ "Loading translation file %s: translation %u '%s'='%s' conflicts with previous translation '%s'='%s'\n",
+ name,
+ i,
+ original,
+ translation,
+ ins.first->first,
+ ins.first->second.first);
+ }
}
osd_printf_verbose("Loaded %u translations from file %s\n", f_translation_map.size(), name);
}
+
+
+char const *lang_translate(char const *message)
+{
+ auto const found = f_translation_map.find(message);
+ if (f_translation_map.end() != found)
+ return found->second.first;
+ return message;
+}
+
+
+std::string_view lang_translate(std::string_view message)
+{
+ auto const found = f_translation_map.find(message);
+ if (f_translation_map.end() != found)
+ return std::string_view(found->second.first, found->second.second);
+ return message;
+}
+
+
+char const *lang_translate(char const *context, char const *message)
+{
+ if (!f_translation_map.empty())
+ {
+ auto const ctxlen(std::strlen(context));
+ auto const msglen(std::strlen(message));
+ std::string key;
+ key.reserve(ctxlen + 1 + msglen);
+ key.append(context, ctxlen);
+ key.append(1, '\004');
+ key.append(message, msglen);
+ auto const found = f_translation_map.find(key);
+ if (f_translation_map.end() != found)
+ return found->second.first;
+ }
+ return message;
+}
+
+
+std::string_view lang_translate(char const *context, std::string_view message)
+{
+ return lang_translate(std::string_view(context), message);
+}
+
+
+std::string_view lang_translate(std::string_view context, std::string_view message)
+{
+ if (!f_translation_map.empty())
+ {
+ std::string key;
+ key.reserve(context.length() + 1 + message.length());
+ key.append(context);
+ key.append(1, '\004');
+ key.append(message);
+ auto const found = f_translation_map.find(key);
+ if (f_translation_map.end() != found)
+ return std::string_view(found->second.first, found->second.second);
+ }
+ return message;
+}
diff --git a/docs/release/src/frontend/mame/ui/about.cpp b/docs/release/src/frontend/mame/ui/about.cpp
new file mode 100644
index 00000000000..aa7de9671fc
--- /dev/null
+++ b/docs/release/src/frontend/mame/ui/about.cpp
@@ -0,0 +1,266 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/***************************************************************************
+
+ ui/about.cpp
+
+ About box
+
+***************************************************************************/
+
+#include "emu.h"
+#include "ui/about.h"
+
+#include "ui/ui.h"
+#include "ui/utils.h"
+
+#include "mame.h"
+
+#include <string_view>
+
+
+namespace ui {
+
+namespace {
+
+#include "copying.ipp"
+
+} // anonymous namespace
+
+
+/**************************************************
+ ABOUT BOX
+**************************************************/
+
+
+//-------------------------------------------------
+// ctor
+//-------------------------------------------------
+
+menu_about::menu_about(mame_ui_manager &mui, render_container &container)
+ : menu(mui, container)
+ , m_header{
+ util::string_format(
+#ifdef MAME_DEBUG
+ _("%1$s %2$s (%3$s%4$sP%5$s, debug)"),
+#else
+ _("%1$s %2$s (%3$s%4$sP%5$s)"),
+#endif
+ emulator_info::get_appname(),
+ bare_build_version,
+ (sizeof(int) == sizeof(void *)) ? "I" : "",
+ (sizeof(long) == sizeof(void *)) ? "L" : (sizeof(long long) == sizeof(void *)) ? "LL" : "",
+ sizeof(void *) * 8),
+ /*util::string_format(_("Revision: %1$s"), bare_vcs_revision)*/" " } // MESSUI
+{
+}
+
+
+//-------------------------------------------------
+// dtor
+//-------------------------------------------------
+
+menu_about::~menu_about()
+{
+}
+
+
+//-------------------------------------------------
+// perform our special rendering
+//-------------------------------------------------
+
+void menu_about::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
+{
+ // draw the title
+ draw_text_box(
+ std::begin(m_header), std::end(m_header),
+ origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
+ ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
+}
+
+
+//-------------------------------------------------
+// draw - draw about
+//-------------------------------------------------
+
+void menu_about::draw(uint32_t flags)
+{
+ rgb_t const color = ui().colors().text_color();
+ float const aspect = machine().render().ui_aspect(&container());
+ float const line_height = ui().get_line_height();
+ float const ud_arrow_width = line_height * aspect;
+ float const gutter_width = 0.52f * line_height * aspect;
+ float const visible_width = 1.0f - (2.0f * ui().box_lr_border() * aspect);
+ float const visible_left = (1.0f - visible_width) * 0.5f;
+ float const extra_height = 2.0f * line_height;
+ float const visible_extra_menu_height = get_customtop() + get_custombottom() + extra_height;
+
+ // determine effective positions taking into account the hilighting arrows
+ float const maximum_width = visible_width - 2.0f * gutter_width;
+
+ draw_background();
+ map_mouse();
+
+ // account for extra space at the top and bottom
+ float visible_main_menu_height = 1.0f - 2.0f * ui().box_tb_border() - visible_extra_menu_height;
+ m_visible_lines = int(std::trunc(visible_main_menu_height / line_height));
+ visible_main_menu_height = float(m_visible_lines) * line_height;
+
+ // compute top/left of inner menu area by centering, if the menu is at the bottom of the extra, adjust
+ float const visible_top = ((1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f) + get_customtop();
+
+ // lay out the text if necessary
+ if (!m_layout || (m_layout->width() != maximum_width))
+ {
+ m_layout.emplace(ui().create_layout(container(), maximum_width));
+ for (char const *const *line = copying_text; *line; ++line)
+ {
+ m_layout->add_text(*line, color);
+ m_layout->add_text("\n", color);
+ }
+ }
+ float const actual_width = m_layout->actual_width();
+
+ // compute text box size
+ float const x1 = visible_left + ((maximum_width - actual_width) * 0.5f);
+ float const y1 = visible_top - ui().box_tb_border();
+ float const x2 = visible_left + visible_width - ((maximum_width - actual_width) * 0.5f);
+ float const y2 = visible_top + visible_main_menu_height + ui().box_tb_border() + extra_height;
+ float const effective_left = x1 + gutter_width;
+ float const line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
+ float const line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
+ float const separator = visible_top + float(m_visible_lines) * line_height;
+
+ ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
+
+ int const visible_items = m_layout->lines();
+ m_visible_lines = (std::min)(visible_items, m_visible_lines);
+ top_line = (std::max)(0, top_line);
+ if (top_line + m_visible_lines >= visible_items)
+ top_line = visible_items - m_visible_lines;
+
+ clear_hover();
+ if (top_line)
+ {
+ // if we're on the top line, display the up arrow
+ rgb_t fgcolor = ui().colors().text_color();
+ if (mouse_in_rect(line_x0, visible_top, line_x1, visible_top + line_height))
+ {
+ fgcolor = ui().colors().mouseover_color();
+ highlight(
+ line_x0, visible_top,
+ line_x1, visible_top + line_height,
+ ui().colors().mouseover_bg_color());
+ set_hover(HOVER_ARROW_UP);
+ }
+ draw_arrow(
+ 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, visible_top + 0.25f * line_height,
+ 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, visible_top + 0.75f * line_height,
+ fgcolor, ROT0);
+ }
+ if ((top_line + m_visible_lines) < visible_items)
+ {
+ // if we're on the bottom line, display the down arrow
+ float const line_y = visible_top + float(m_visible_lines - 1) * line_height;
+ rgb_t fgcolor = ui().colors().text_color();
+ if (mouse_in_rect(line_x0, line_y, line_x1, line_y + line_height))
+ {
+ fgcolor = ui().colors().mouseover_color();
+ highlight(
+ line_x0, line_y,
+ line_x1, line_y + line_height,
+ ui().colors().mouseover_bg_color());
+ set_hover(HOVER_ARROW_DOWN);
+ }
+ draw_arrow(
+ 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height,
+ 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, line_y + 0.75f * line_height,
+ fgcolor, ROT0 ^ ORIENTATION_FLIP_Y);
+ }
+
+ // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
+ m_visible_items = m_visible_lines - (top_line ? 1 : 0) - (top_line + m_visible_lines != visible_items);
+ m_layout->emit(
+ container(),
+ top_line ? (top_line + 1) : 0, m_visible_items,
+ effective_left, visible_top + (top_line ? line_height : 0.0f));
+
+ // add visual separator before the "return to prevous menu" item
+ container().add_line(
+ x1, separator + (0.5f * line_height),
+ x2, separator + (0.5f * line_height),
+ UI_LINE_WIDTH, ui().colors().text_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
+
+ menu_item const &pitem = item(0);
+ std::string_view const itemtext = pitem.text;
+ float const line_y0 = separator + line_height;
+ float const line_y1 = line_y0 + line_height;
+
+ if (mouse_in_rect(line_x0, line_y0, line_x1, line_y1) && is_selectable(pitem))
+ set_hover(0);
+
+ highlight(line_x0, line_y0, line_x1, line_y1, ui().colors().selected_bg_color());
+ ui().draw_text_full(
+ container(), itemtext,
+ effective_left, line_y0, actual_width,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
+ mame_ui_manager::NORMAL,
+ ui().colors().selected_color(), ui().colors().selected_bg_color(),
+ nullptr, nullptr);
+
+ // if there is something special to add, do it by calling the virtual method
+ custom_render(get_selection_ref(), get_customtop(), get_custombottom(), x1, y1, x2, y2);
+}
+
+
+//-------------------------------------------------
+// populate - populates the about modal
+//-------------------------------------------------
+
+void menu_about::populate(float &customtop, float &custombottom)
+{
+ // make space for the title and revision
+ customtop = (ui().get_line_height() * m_header.size()) + (ui().box_tb_border() * 3.0f);
+}
+
+
+//-------------------------------------------------
+// handle - manages inputs in the about modal
+//-------------------------------------------------
+
+void menu_about::handle()
+{
+ const event *event = process(PROCESS_CUSTOM_NAV);
+ if (event)
+ {
+ switch (event->iptkey)
+ {
+ case IPT_UI_UP:
+ --top_line;
+ break;
+
+ case IPT_UI_DOWN:
+ ++top_line;
+ break;
+
+ case IPT_UI_PAGE_UP:
+ top_line -= m_visible_lines - 3;
+ break;
+
+ case IPT_UI_PAGE_DOWN:
+ top_line += m_visible_lines - 3;
+ break;
+
+ case IPT_UI_HOME:
+ top_line = 0;
+ break;
+
+ case IPT_UI_END:
+ top_line = m_layout->lines() - m_visible_lines;
+ break;
+ }
+ }
+}
+
+};
diff --git a/docs/release/src/frontend/mame/ui/inifile.cpp b/docs/release/src/frontend/mame/ui/inifile.cpp
index 9e43de79623..02713cd5f57 100644
--- a/docs/release/src/frontend/mame/ui/inifile.cpp
+++ b/docs/release/src/frontend/mame/ui/inifile.cpp
@@ -13,10 +13,13 @@
#include "ui/moptions.h"
-#include "corestr.h"
+#include "language.h"
+
#include "drivenum.h"
#include "softlist_dev.h"
+#include "corestr.h"
+
#include <algorithm>
#include <cstring>
#include <iterator>
@@ -227,49 +230,59 @@ favorite_manager::favorite_manager(ui_options &options)
if (!file.open(FAVORITE_FILENAME))
{
char readbuf[1024];
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
while (readbuf[0] == '[')
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
- while (file.gets(readbuf, 1024))
+ while (file.gets(readbuf, std::size(readbuf)))
{
ui_software_info tmpmatches;
tmpmatches.shortname = chartrimcarriage(readbuf);
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
tmpmatches.longname = chartrimcarriage(readbuf);
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
tmpmatches.parentname = chartrimcarriage(readbuf);
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
tmpmatches.year = chartrimcarriage(readbuf);
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
tmpmatches.publisher = chartrimcarriage(readbuf);
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
tmpmatches.supported = software_support(atoi(readbuf));
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
tmpmatches.part = chartrimcarriage(readbuf);
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
chartrimcarriage(readbuf);
auto dx = driver_list::find(readbuf);
if (0 > dx)
continue;
tmpmatches.driver = &driver_list::driver(dx);
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
tmpmatches.listname = chartrimcarriage(readbuf);
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
tmpmatches.interface = chartrimcarriage(readbuf);
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
tmpmatches.instance = chartrimcarriage(readbuf);
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
tmpmatches.startempty = atoi(readbuf);
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
tmpmatches.parentlongname = chartrimcarriage(readbuf);
- file.gets(readbuf, 1024);
- tmpmatches.usage = chartrimcarriage(readbuf);
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
+ //tmpmatches.usage = chartrimcarriage(readbuf); TODO: recover multi-line info
+ file.gets(readbuf, std::size(readbuf));
tmpmatches.devicetype = chartrimcarriage(readbuf);
- file.gets(readbuf, 1024);
+ file.gets(readbuf, std::size(readbuf));
tmpmatches.available = atoi(readbuf);
+
+ // need to populate this, it isn't displayed anywhere else
+ tmpmatches.infotext.append(tmpmatches.longname);
+ tmpmatches.infotext.append(1, '\n');
+ tmpmatches.infotext.append(_("swlist-info", "Software list/item"));
+ tmpmatches.infotext.append(1, '\n');
+ tmpmatches.infotext.append(tmpmatches.listname);
+ tmpmatches.infotext.append(1, ':');
+ tmpmatches.infotext.append(tmpmatches.shortname);
+
m_favorites.emplace(std::move(tmpmatches));
}
file.close();
@@ -300,25 +313,18 @@ void favorite_manager::add_favorite(running_machine &machine)
if (imagedev)
{
// creating this is fairly expensive, but we'll assume this usually succeeds
- ui_software_info info;
software_part const *const part(imagedev->part_entry());
assert(software);
assert(part);
-
- // start with simple stuff that can just be copied
- info.shortname = software->shortname();
- info.longname = software->longname();
- info.parentname = software->parentname();
- info.year = software->year();
- info.publisher = software->publisher();
- info.supported = software->supported();
- info.part = part->name();
- info.driver = &driver;
- info.listname = imagedev->software_list_name();
- info.interface = part->interface();
- info.instance = imagedev->instance_name();
- info.startempty = 0;
- info.devicetype = strensure(imagedev->image_type_name());
+ ui_software_info info(
+ *software,
+ *part,
+ driver,
+ imagedev->software_list_name(),
+ imagedev->instance_name(),
+ strensure(imagedev->image_type_name()));
+
+ // assume it's available if it's mounted
info.available = true;
// look up the parent in the list if necessary (eugh, O(n) walk)
@@ -336,16 +342,6 @@ void favorite_manager::add_favorite(running_machine &machine)
}
}
- // fill in with the first usage entry we find
- for (feature_list_item const &feature : software->other_info())
- {
- if (feature.name() == "usage")
- {
- info.usage = feature.value();
- break;
- }
- }
-
// hooray for move semantics!
add_impl(std::move(info));
}
@@ -575,7 +571,7 @@ void favorite_manager::save_favorites()
buf << info.instance << '\n';
util::stream_format(buf, "%d\n", info.startempty);
buf << info.parentlongname << '\n';
- buf << info.usage << '\n';
+ buf << '\n'; //buf << info.usage << '\n'; TODO: store multi-line info in a recoverable format
buf << info.devicetype << '\n';
util::stream_format(buf, "%d\n", info.available);