Make internal UI display list of missing files if system/software set is found but incomplete.

Also consolidated selgame/selsoft code for actually launching systems into one place.
This commit is contained in:
Vas Crabb 2017-07-19 22:04:29 +10:00
parent d3568b23eb
commit 0aad5cb057
10 changed files with 644 additions and 536 deletions

View File

@ -273,7 +273,10 @@ media_auditor::summary media_auditor::summarize(const char *name, std::ostream *
// output the game name, file name, and length (if applicable)
if (output)
{
util::stream_format(*output, "%-12s: %s", name, record.name());
if (name)
util::stream_format(*output, "%-12s: %s", name, record.name());
else
util::stream_format(*output, "%s", record.name());
if (record.expected_length() > 0)
util::stream_format(*output, " (%d bytes)", record.expected_length());
*output << " - ";

View File

@ -159,9 +159,7 @@ favorite_manager::favorite_manager(running_machine &machine, ui_options &moption
void favorite_manager::add_favorite_game(const game_driver *driver)
{
m_list.emplace(driver->type.fullname(),
ui_software_info{driver->name, driver->type.fullname(), "", "", "", 0, "", driver, "", "", "",
1, "", "", "", true});
m_list.emplace(driver->type.fullname(), *driver);
save_favorite_games();
}

View File

@ -33,6 +33,7 @@
#include "softlist_dev.h"
#include "uiinput.h"
#include "luaengine.h"
extern const char UI_VERSION_TAG[];
namespace ui {
@ -77,7 +78,7 @@ menu_select_game::menu_select_game(mame_ui_manager &mui, render_container &conta
if (first_start)
{
reselect_last::driver = moptions.last_used_machine();
reselect_last::set_driver(moptions.last_used_machine());
std::string tmp(moptions.last_used_filter());
std::size_t found = tmp.find_first_of(",");
if (found == std::string::npos)
@ -171,7 +172,7 @@ void menu_select_game::handle()
bool check_filter = false;
// if i have to load datfile, performe an hard reset
// if I have to load datfile, perform a hard reset
if (ui_globals::reset)
{
ui_globals::reset = false;
@ -197,11 +198,9 @@ void menu_select_game::handle()
const event *menu_event = process(PROCESS_LR_REPEAT);
if (menu_event && menu_event->itemref)
{
if (m_ui_error)
if (dismiss_error())
{
// reset the error on any future menu_event
m_ui_error = false;
machine().ui_input().reset();
}
else if (menu_event->iptkey == IPT_UI_SELECT)
{
@ -459,9 +458,7 @@ void menu_select_game::handle()
}
// if we're in an error state, overlay an error message
if (m_ui_error)
ui().draw_text_box(container(), _("The selected machine is missing one or more required ROM or CHD images. "
"Please select a different machine.\n\nPress any key to continue."), ui::text_layout::CENTER, 0.5f, 0.5f, UI_RED_COLOR);
draw_error_text();
// handle filters selection from key shortcuts
if (check_filter)
@ -536,7 +533,7 @@ void menu_select_game::populate(float &customtop, float &custombottom)
int curitem = 0;
for (auto & elem : m_displaylist)
{
if (old_item_selected == -1 && elem->name == reselect_last::driver)
if (old_item_selected == -1 && elem->name == reselect_last::driver())
old_item_selected = curitem;
bool cloneof = strcmp(elem->parent, "0");
@ -564,7 +561,7 @@ void menu_select_game::populate(float &customtop, float &custombottom)
auto flags = flags_ui | FLAG_UI_FAVORITE;
if (favmap.second.startempty == 1)
{
if (old_item_selected == -1 && favmap.second.shortname == reselect_last::driver)
if (old_item_selected == -1 && favmap.second.shortname == reselect_last::driver())
old_item_selected = curitem;
bool cloneof = strcmp(favmap.second.driver->parent, "0");
@ -579,7 +576,7 @@ void menu_select_game::populate(float &customtop, float &custombottom)
}
else
{
if (old_item_selected == -1 && favmap.second.shortname == reselect_last::driver)
if (old_item_selected == -1 && favmap.second.shortname == reselect_last::driver())
old_item_selected = curitem;
item_append(favmap.second.longname, favmap.second.devicetype,
favmap.second.parentname.empty() ? flags : (FLAG_INVERT | flags), (void *)&favmap.second);
@ -618,11 +615,13 @@ void menu_select_game::populate(float &customtop, float &custombottom)
else
top_line = selected - (ui_globals::visible_main_lines / 2);
if (reselect_last::software.empty())
if (reselect_last::software().empty())
reselect_last::reset();
}
else
{
reselect_last::reset();
}
}
//-------------------------------------------------
@ -773,31 +772,32 @@ void menu_select_game::inkey_select(const event *menu_event)
{
const game_driver *driver = (const game_driver *)menu_event->itemref;
// special case for configure options
if ((uintptr_t)driver == CONF_OPTS)
{
// special case for configure options
menu::stack_push<menu_game_options>(ui(), container());
// special case for configure machine
}
else if (uintptr_t(driver) == CONF_MACHINE)
{
// special case for configure machine
if (m_prev_selected)
menu::stack_push<menu_machine_configure>(ui(), container(), reinterpret_cast<const game_driver *>(m_prev_selected));
return;
}
// special case for configure plugins
else if ((uintptr_t)driver == CONF_PLUGINS)
{
// special case for configure plugins
menu::stack_push<menu_plugins_configure>(ui(), container());
}
// anything else is a driver
else
{
// anything else is a driver
// audit the game first to see if we're going to work
driver_enumerator enumerator(machine().options(), *driver);
enumerator.next();
media_auditor auditor(enumerator);
media_auditor::summary summary = auditor.audit_media(AUDIT_VALIDATE_FAST);
media_auditor::summary const summary = auditor.audit_media(AUDIT_VALIDATE_FAST);
// if everything looks good, schedule the new driver
if (summary == media_auditor::CORRECT || summary == media_auditor::BEST_AVAILABLE || summary == media_auditor::NONE_NEEDED)
@ -812,24 +812,13 @@ void menu_select_game::inkey_select(const event *menu_event)
}
}
s_bios biosname;
if (!ui().options().skip_bios_menu() && has_multiple_bios(driver, biosname))
menu::stack_push<bios_selection>(ui(), container(), biosname, (void *)driver, false, false);
else
{
reselect_last::driver = driver->name;
reselect_last::software.clear();
reselect_last::swlist.clear();
mame_machine_manager::instance()->schedule_new_driver(*driver);
machine().schedule_hard_reset();
stack_reset();
}
if (!select_bios(*driver, false))
launch_system(*driver);
}
// otherwise, display an error
else
{
reset(reset_options::REMEMBER_REF);
m_ui_error = true;
// otherwise, display an error
set_error(reset_options::REMEMBER_REF, make_error_text(media_auditor::NOTFOUND != summary, auditor));
}
}
}
@ -841,7 +830,6 @@ void menu_select_game::inkey_select(const event *menu_event)
void menu_select_game::inkey_select_favorite(const event *menu_event)
{
ui_software_info *ui_swinfo = (ui_software_info *)menu_event->itemref;
ui_options &mopt = ui().options();
if ((uintptr_t)ui_swinfo == CONF_OPTS)
{
@ -869,7 +857,7 @@ void menu_select_game::inkey_select_favorite(const event *menu_event)
driver_enumerator enumerator(machine().options(), *ui_swinfo->driver);
enumerator.next();
media_auditor auditor(enumerator);
media_auditor::summary summary = auditor.audit_media(AUDIT_VALIDATE_FAST);
media_auditor::summary const summary = auditor.audit_media(AUDIT_VALIDATE_FAST);
if (summary == media_auditor::CORRECT || summary == media_auditor::BEST_AVAILABLE || summary == media_auditor::NONE_NEEDED)
{
@ -884,25 +872,16 @@ void menu_select_game::inkey_select_favorite(const event *menu_event)
}
// if everything looks good, schedule the new driver
s_bios biosname;
if (!mopt.skip_bios_menu() && has_multiple_bios(ui_swinfo->driver, biosname))
menu::stack_push<bios_selection>(ui(), container(), biosname, (void *)ui_swinfo->driver, false, false);
else
if (!select_bios(*ui_swinfo->driver, false))
{
reselect_last::driver = ui_swinfo->driver->name;
reselect_last::software.clear();
reselect_last::swlist.clear();
reselect_last::set(true);
mame_machine_manager::instance()->schedule_new_driver(*ui_swinfo->driver);
machine().schedule_hard_reset();
stack_reset();
reselect_last::reselect(true);
launch_system(*ui_swinfo->driver);
}
}
else
{
// otherwise, display an error
reset(reset_options::REMEMBER_REF);
m_ui_error = true;
set_error(reset_options::REMEMBER_REF, make_error_text(media_auditor::NOTFOUND != summary, auditor));
}
}
else
@ -914,50 +893,17 @@ void menu_select_game::inkey_select_favorite(const event *menu_event)
software_list_device *swlist = software_list_device::find_by_name(*drv.config(), ui_swinfo->listname.c_str());
const software_info *swinfo = swlist->find(ui_swinfo->shortname.c_str());
media_auditor::summary summary = auditor.audit_software(swlist->list_name(), swinfo, AUDIT_VALIDATE_FAST);
media_auditor::summary const summary = auditor.audit_software(swlist->list_name(), swinfo, AUDIT_VALIDATE_FAST);
if (summary == media_auditor::CORRECT || summary == media_auditor::BEST_AVAILABLE || summary == media_auditor::NONE_NEEDED)
{
s_bios biosname;
if (!mopt.skip_bios_menu() && has_multiple_bios(ui_swinfo->driver, biosname))
{
menu::stack_push<bios_selection>(ui(), container(), biosname, (void *)ui_swinfo, true, false);
return;
}
else if (!mopt.skip_parts_menu() && swinfo->has_multiple_parts(ui_swinfo->interface.c_str()))
{
s_parts parts;
for (const software_part &swpart : swinfo->parts())
{
if (swpart.matches_interface(ui_swinfo->interface.c_str()))
{
std::string menu_part_name(swpart.name());
if (swpart.feature("part_id") != nullptr)
menu_part_name.assign("(").append(swpart.feature("part_id")).append(")");
parts.emplace(swpart.name(), menu_part_name);
}
}
menu::stack_push<software_parts>(ui(), container(), parts, ui_swinfo);
return;
}
std::string string_list = string_format("%s:%s:%s:%s", ui_swinfo->listname, ui_swinfo->shortname, ui_swinfo->part, ui_swinfo->instance);
mopt.set_value(OPTION_SOFTWARENAME, string_list.c_str(), OPTION_PRIORITY_CMDLINE);
std::string snap_list = std::string(ui_swinfo->listname).append(PATH_SEPARATOR).append(ui_swinfo->shortname);
mopt.set_value(OPTION_SNAPNAME, snap_list.c_str(), OPTION_PRIORITY_CMDLINE);
reselect_last::driver = drv.driver().name;
reselect_last::software = ui_swinfo->shortname;
reselect_last::swlist = ui_swinfo->listname;
mame_machine_manager::instance()->schedule_new_driver(drv.driver());
machine().schedule_hard_reset();
stack_reset();
if (!select_bios(*ui_swinfo, false) && !select_part(*swinfo, *ui_swinfo))
launch_system(drv.driver(), *ui_swinfo, ui_swinfo->part);
}
// otherwise, display an error
else
{
reset(reset_options::REMEMBER_POSITION);
m_ui_error = true;
// otherwise, display an error
set_error(reset_options::REMEMBER_POSITION, make_error_text(media_auditor::NOTFOUND != summary, auditor));
}
}
}
@ -1745,4 +1691,18 @@ std::string menu_select_game::make_software_description(ui_software_info const &
return string_format(_("System: %1$-.100s"), software.driver->type.fullname());
}
std::string menu_select_game::make_error_text(bool summary, media_auditor const &auditor)
{
std::ostringstream str;
str << _("The selected machine is missing one or more required ROM or CHD images. Please select a different machine.\n\n");
if (summary)
{
auditor.summarize(nullptr, &str);
str << "\n";
}
str << _("Press any key to continue.");
return str.str();
}
} // namespace ui

View File

@ -15,8 +15,10 @@
#include "ui/selmenu.h"
class media_auditor;
namespace ui {
class menu_select_game : public menu_select_launch
{
public:
@ -76,6 +78,8 @@ private:
bool load_available_machines();
void load_custom_filters();
static std::string make_error_text(bool summary, media_auditor const &auditor);
void *get_selection_ptr() const
{
void *const selected_ref(get_selection_ref());

View File

@ -14,7 +14,6 @@
#include "ui/icorender.h"
#include "ui/inifile.h"
#include "ui/utils.h"
// these hold static bitmap images
#include "ui/defimg.ipp"
@ -28,6 +27,7 @@
#include "emuopts.h"
#include "rendutil.h"
#include "softlist.h"
#include "softlist_dev.h"
#include "uiinput.h"
#include "luaengine.h"
@ -38,7 +38,9 @@
namespace ui {
namespace {
std::pair<char const *, char const *> const arts_info[] =
{
{ __("Snapshots"), OPTION_SNAPSHOT_DIRECTORY },
@ -69,10 +71,259 @@ char const *const hover_msg[] = {
} // anonymous namespace
std::string menu_select_launch::reselect_last::s_driver;
std::string menu_select_launch::reselect_last::s_software;
std::string menu_select_launch::reselect_last::s_swlist;
bool menu_select_launch::reselect_last::s_reselect = false;
std::mutex menu_select_launch::s_cache_guard;
menu_select_launch::cache_ptr_map menu_select_launch::s_caches;
template bool menu_select_launch::select_bios(game_driver const &, bool);
template bool menu_select_launch::select_bios(ui_software_info const &, bool);
void menu_select_launch::reselect_last::reset()
{
s_driver.clear();
s_software.clear();
s_swlist.clear();
reselect(false);
}
void menu_select_launch::reselect_last::set_driver(std::string const &name)
{
s_driver = name;
s_software.clear();
s_swlist.clear();
}
void menu_select_launch::reselect_last::set_software(game_driver const &driver, ui_software_info const &swinfo)
{
s_driver = driver.name;
if (swinfo.startempty)
{
// magic strings are bad...
s_software = "[Start empty]";
s_swlist.clear();
}
else
{
s_software = swinfo.shortname;
s_swlist = swinfo.listname;
}
}
//-------------------------------------------------
// ctor
//-------------------------------------------------
menu_select_launch::software_parts::software_parts(mame_ui_manager &mui, render_container &container, s_parts &&parts, ui_software_info const &ui_info)
: menu(mui, container)
, m_uiinfo(ui_info)
, m_parts(std::move(parts))
{
}
//-------------------------------------------------
// dtor
//-------------------------------------------------
menu_select_launch::software_parts::~software_parts()
{
}
//-------------------------------------------------
// populate
//-------------------------------------------------
void menu_select_launch::software_parts::populate(float &customtop, float &custombottom)
{
for (auto & elem : m_parts)
item_append(elem.first, elem.second, 0, (void *)&elem);
item_append(menu_item_type::SEPARATOR);
customtop = ui().get_line_height() + (3.0f * UI_BOX_TB_BORDER);
}
//-------------------------------------------------
// handle
//-------------------------------------------------
void menu_select_launch::software_parts::handle()
{
// process the menu
const event *menu_event = process(0);
if (menu_event && (menu_event->iptkey) == IPT_UI_SELECT && menu_event->itemref)
{
for (auto const &elem : m_parts)
{
if ((void*)&elem == menu_event->itemref)
{
launch_system(ui(), *m_uiinfo.driver, &m_uiinfo, &elem.first, nullptr);
break;
}
}
}
}
//-------------------------------------------------
// perform our special rendering
//-------------------------------------------------
void menu_select_launch::software_parts::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
{
float width;
ui().draw_text_full(container(), _("Software part selection:"), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
width += 2 * UI_BOX_LR_BORDER;
float maxwidth = std::max(origx2 - origx1, width);
// compute our bounds
float x1 = 0.5f - 0.5f * maxwidth;
float x2 = x1 + maxwidth;
float y1 = origy1 - top;
float y2 = origy1 - UI_BOX_TB_BORDER;
// draw a box
ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_GREEN_COLOR);
// take off the borders
x1 += UI_BOX_LR_BORDER;
x2 -= UI_BOX_LR_BORDER;
y1 += UI_BOX_TB_BORDER;
// draw the text within it
ui().draw_text_full(container(), _("Software part selection:"), x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
}
//-------------------------------------------------
// ctor
//-------------------------------------------------
menu_select_launch::bios_selection::bios_selection(mame_ui_manager &mui, render_container &container, s_bios &&biosname, game_driver const &driver, bool inlist)
: bios_selection(mui, container, std::move(biosname), reinterpret_cast<void const *>(&driver), false, inlist)
{
}
menu_select_launch::bios_selection::bios_selection(mame_ui_manager &mui, render_container &container, s_bios &&biosname, ui_software_info const &swinfo, bool inlist)
: bios_selection(mui, container, std::move(biosname), reinterpret_cast<void const *>(&swinfo), true, inlist)
{
}
menu_select_launch::bios_selection::bios_selection(mame_ui_manager &mui, render_container &container, s_bios &&biosname, void const *driver, bool software, bool inlist)
: menu(mui, container)
, m_driver(driver)
, m_software(software)
, m_inlist(inlist)
, m_bios(std::move(biosname))
{
}
//-------------------------------------------------
// dtor
//-------------------------------------------------
menu_select_launch::bios_selection::~bios_selection()
{
}
//-------------------------------------------------
// populate
//-------------------------------------------------
void menu_select_launch::bios_selection::populate(float &customtop, float &custombottom)
{
for (auto & elem : m_bios)
item_append(elem.first, "", 0, (void *)&elem.first);
item_append(menu_item_type::SEPARATOR);
customtop = ui().get_line_height() + (3.0f * UI_BOX_TB_BORDER);
}
//-------------------------------------------------
// handle
//-------------------------------------------------
void menu_select_launch::bios_selection::handle()
{
// process the menu
const event *menu_event = process(0);
if (menu_event && menu_event->iptkey == IPT_UI_SELECT && menu_event->itemref)
{
for (auto & elem : m_bios)
{
if ((void*)&elem.first == menu_event->itemref)
{
if (!m_software)
{
const game_driver *s_driver = (const game_driver *)m_driver;
if (m_inlist)
{
ui_software_info empty(*s_driver);
launch_system(ui(), *s_driver, &empty, nullptr, &elem.second);
}
else
{
reselect_last::reselect(true);
launch_system(ui(), *s_driver, nullptr, nullptr, &elem.second);
}
}
else
{
ui_software_info *ui_swinfo = (ui_software_info *)m_driver;
machine().options().set_value(OPTION_BIOS, elem.second, OPTION_PRIORITY_CMDLINE); // oh dear, relying on this persisting through the part selection menu
driver_enumerator drivlist(machine().options(), *ui_swinfo->driver);
drivlist.next();
software_list_device *swlist = software_list_device::find_by_name(*drivlist.config(), ui_swinfo->listname.c_str());
const software_info *swinfo = swlist->find(ui_swinfo->shortname.c_str());
if (!select_part(ui(), container(), *swinfo, *ui_swinfo))
{
reselect_last::reselect(true);
launch_system(ui(), drivlist.driver(), ui_swinfo, nullptr, &elem.second);
}
}
}
}
}
}
//-------------------------------------------------
// perform our special rendering
//-------------------------------------------------
void menu_select_launch::bios_selection::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
{
float width;
ui().draw_text_full(container(), _("Bios selection:"), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
width += 2 * UI_BOX_LR_BORDER;
float maxwidth = std::max(origx2 - origx1, width);
// compute our bounds
float x1 = 0.5f - 0.5f * maxwidth;
float x2 = x1 + maxwidth;
float y1 = origy1 - top;
float y2 = origy1 - UI_BOX_TB_BORDER;
// draw a box
ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_GREEN_COLOR);
// take off the borders
x1 += UI_BOX_LR_BORDER;
x2 -= UI_BOX_LR_BORDER;
y1 += UI_BOX_TB_BORDER;
// draw the text within it
ui().draw_text_full(container(), _("Bios selection:"), x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
}
menu_select_launch::cache::cache(running_machine &machine)
: m_snapx_bitmap(std::make_unique<bitmap_argb32>(0, 0))
, m_snapx_texture()
@ -151,6 +402,7 @@ menu_select_launch::menu_select_launch(mame_ui_manager &mui, render_container &c
, m_info_driver(nullptr)
, m_info_software(nullptr)
, m_info_view(-1)
, m_items_list()
, m_info_buffer()
, m_cache()
, m_is_swlist(is_swlist)
@ -179,6 +431,71 @@ menu_select_launch::menu_select_launch(mame_ui_manager &mui, render_container &c
}
bool menu_select_launch::dismiss_error()
{
bool const result = m_ui_error;
if (result)
{
m_ui_error = false;
m_error_text.clear();
machine().ui_input().reset();
}
return result;
}
void menu_select_launch::set_error(reset_options ropt, std::string &&message)
{
reset(ropt);
m_ui_error = true;
m_error_text = std::move(message);
}
//-------------------------------------------------
// actually start an emulation session
//-------------------------------------------------
void menu_select_launch::launch_system(mame_ui_manager &mui, game_driver const &driver, ui_software_info const *swinfo, std::string const *part, int const *bios)
{
emu_options &moptions(mui.machine().options());
moptions.set_system_name(driver.name);
if (swinfo)
{
if (!swinfo->startempty)
{
if (part)
{
std::string const string_list(util::string_format("%s:%s:%s:%s", swinfo->listname, swinfo->shortname, *part, swinfo->instance));
printf("%s\n", string_list.c_str());
moptions.set_value(OPTION_SOFTWARENAME, string_list.c_str(), OPTION_PRIORITY_CMDLINE);
}
else
{
std::string const string_list(util::string_format("%s:%s", swinfo->listname, swinfo->shortname));
printf("%s\n", string_list.c_str());
moptions.set_value(OPTION_SOFTWARENAME, string_list.c_str(), OPTION_PRIORITY_CMDLINE);
}
std::string const snap_list(util::string_format("%s%s%s", swinfo->listname, PATH_SEPARATOR, swinfo->shortname));
moptions.set_value(OPTION_SNAPNAME, snap_list.c_str(), OPTION_PRIORITY_CMDLINE);
}
reselect_last::set_software(driver, *swinfo);
}
else
{
reselect_last::set_driver(driver);
}
if (bios)
moptions.set_value(OPTION_BIOS, *bios, OPTION_PRIORITY_CMDLINE);
mame_machine_manager::instance()->schedule_new_driver(driver);
mui.machine().schedule_hard_reset();
stack_reset(mui.machine());
}
//-------------------------------------------------
// perform our special rendering
//-------------------------------------------------
@ -517,6 +834,50 @@ void menu_select_launch::draw_info_arrow(int ub, float origx1, float origx2, flo
0.5f * (origx1 + origx2) + 0.5f * (ud_arrow_width * text_size), oy1 + 0.75f * (line_height * text_size), fgcolor, orientation);
}
bool menu_select_launch::draw_error_text()
{
if (m_ui_error)
ui().draw_text_box(container(), m_error_text.c_str(), ui::text_layout::CENTER, 0.5f, 0.5f, UI_RED_COLOR);
return m_ui_error;
}
template <typename T> bool menu_select_launch::select_bios(T const &driver, bool inlist)
{
s_bios biosname;
if (ui().options().skip_bios_menu() || !has_multiple_bios(driver, biosname))
return false;
menu::stack_push<bios_selection>(ui(), container(), std::move(biosname), driver, inlist);
return true;
}
bool menu_select_launch::select_part(software_info const &info, ui_software_info const &ui_info)
{
return select_part(ui(), container(), info, ui_info);
}
bool menu_select_launch::select_part(mame_ui_manager &mui, render_container &container, software_info const &info, ui_software_info const &ui_info)
{
if (mui.options().skip_parts_menu() || !info.has_multiple_parts(ui_info.interface.c_str()))
return false;
s_parts parts;
for (software_part const &part : info.parts())
{
if (part.matches_interface(ui_info.interface.c_str()))
{
std::string menu_part_name(part.name());
if (part.feature("part_id"))
menu_part_name.assign("(").append(part.feature("part_id")).append(")");
parts.emplace(part.name(), std::move(menu_part_name));
}
}
menu::stack_push<software_parts>(mui, container, std::move(parts), ui_info);
return true;
}
//-------------------------------------------------
// draw toolbar
@ -1860,12 +2221,55 @@ void menu_select_launch::draw_snapx(float origx1, float origy1, float origx2, fl
}
//-------------------------------------------------
// get bios count
//-------------------------------------------------
bool menu_select_launch::has_multiple_bios(ui_software_info const &swinfo, s_bios &biosname)
{
return has_multiple_bios(*swinfo.driver, biosname);
}
bool menu_select_launch::has_multiple_bios(game_driver const &driver, s_bios &biosname)
{
if (!driver.rom)
return false;
auto const entries = rom_build_entries(driver.rom);
std::string default_name;
for (const rom_entry &rom : entries)
if (ROMENTRY_ISDEFAULT_BIOS(&rom))
default_name = ROM_GETNAME(&rom);
for (const rom_entry &rom : entries)
{
if (ROMENTRY_ISSYSTEM_BIOS(&rom))
{
std::string name(ROM_GETHASHDATA(&rom));
std::string bname(ROM_GETNAME(&rom));
int bios_flags = ROM_GETBIOSFLAGS(&rom);
if (bname == default_name)
{
name.append(_(" (default)"));
biosname.emplace(biosname.begin(), name, bios_flags - 1);
}
else
biosname.emplace_back(name, bios_flags - 1);
}
}
return biosname.size() > 1U;
}
void menu_select_launch::exit(running_machine &machine)
{
std::lock_guard<std::mutex> guard(s_cache_guard);
s_caches.erase(&machine);
}
//-------------------------------------------------
// draw infos
//-------------------------------------------------

View File

@ -41,11 +41,38 @@ protected:
rightbottom
};
class reselect_last
{
public:
static std::string const &driver() { return s_driver; }
static std::string const &software() { return s_software; }
static std::string const &swlist() { return s_swlist; }
static void reselect(bool value) { s_reselect = value; }
static bool get() { return s_reselect; }
static void reset();
static void set_driver(std::string const &name);
static void set_driver(game_driver const &driver) { set_driver(driver.name); }
static void set_software(game_driver const &driver, ui_software_info const &swinfo);
private:
static std::string s_driver, s_software, s_swlist;
static bool s_reselect;
};
menu_select_launch(mame_ui_manager &mui, render_container &container, bool is_swlist);
focused_menu get_focus() const { return m_focus; }
void set_focus(focused_menu focus) { m_focus = focus; }
bool dismiss_error();
void set_error(reset_options ropt, std::string &&message);
void launch_system(game_driver const &driver) { launch_system(ui(), driver, nullptr, nullptr, nullptr); }
void launch_system(game_driver const &driver, ui_software_info const &swinfo) { launch_system(ui(), driver, &swinfo, nullptr, nullptr); }
void launch_system(game_driver const &driver, ui_software_info const &swinfo, std::string const &part) { launch_system(ui(), driver, &swinfo, &part, nullptr); }
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
// handlers
@ -55,16 +82,61 @@ protected:
void draw_common_arrow(float origx1, float origy1, float origx2, float origy2, int current, int dmin, int dmax, float title);
void draw_info_arrow(int ub, float origx1, float origx2, float oy1, float line_height, float text_size, float ud_arrow_width);
bool draw_error_text();
template <typename T> bool select_bios(T const &driver, bool inlist);
bool select_part(software_info const &info, ui_software_info const &ui_info);
int visible_items;
void *m_prev_selected;
int m_total_lines;
int m_topline_datsview; // right box top line
bool m_ui_error;
private:
using bitmap_vector = std::vector<bitmap_argb32>;
using texture_ptr_vector = std::vector<texture_ptr>;
using s_parts = std::unordered_map<std::string, std::string>;
using s_bios = std::vector<std::pair<std::string, int>>;
class software_parts : public menu
{
public:
software_parts(mame_ui_manager &mui, render_container &container, s_parts &&parts, ui_software_info const &ui_info);
virtual ~software_parts() override;
protected:
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void handle() override;
ui_software_info const &m_uiinfo;
s_parts const m_parts;
};
class bios_selection : public menu
{
public:
bios_selection(mame_ui_manager &mui, render_container &container, s_bios &&biosname, game_driver const &driver, bool inlist);
bios_selection(mame_ui_manager &mui, render_container &container, s_bios &&biosname, ui_software_info const &swinfo, bool inlist);
virtual ~bios_selection() override;
protected:
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
private:
bios_selection(mame_ui_manager &mui, render_container &container, s_bios &&biosname, void const *driver, bool software, bool inlist);
virtual void populate(float &customtop, float &custombottom) override;
virtual void handle() override;
void const *m_driver;
bool m_software, m_inlist;
s_bios m_bios;
};
class cache
{
public:
@ -117,12 +189,6 @@ private:
// draw left panel
virtual float draw_left_panel(float x1, float y1, float x2, float y2) = 0;
game_driver const *m_info_driver;
ui_software_info const *m_info_software;
int m_info_view;
std::vector<std::string> m_items_list;
std::string m_info_buffer;
// draw infos
void infos_render(float x1, float y1, float x2, float y2);
virtual void general_info(const game_driver *driver, std::string &buffer) = 0;
@ -178,9 +244,23 @@ private:
virtual std::string make_driver_description(game_driver const &driver) const = 0;
virtual std::string make_software_description(ui_software_info const &software) const = 0;
static void launch_system(mame_ui_manager &mui, game_driver const &driver, ui_software_info const *swinfo, std::string const *part, int const *bios);
static bool select_part(mame_ui_manager &mui, render_container &container, software_info const &info, ui_software_info const &ui_info);
static bool has_multiple_bios(ui_software_info const &swinfo, s_bios &biosname);
static bool has_multiple_bios(game_driver const &driver, s_bios &biosname);
// cleanup function
static void exit(running_machine &machine);
bool m_ui_error;
std::string m_error_text;
game_driver const *m_info_driver;
ui_software_info const *m_info_software;
int m_info_view;
std::vector<std::string> m_items_list;
std::string m_info_buffer;
cache_ptr m_cache;
bool m_is_swlist;
focused_menu m_focus;

View File

@ -29,10 +29,7 @@
namespace ui {
std::string reselect_last::driver;
std::string reselect_last::software;
std::string reselect_last::swlist;
bool reselect_last::m_reselect = false;
static const char *region_lists[] = { "arab", "arg", "asia", "aus", "aut", "bel", "blr", "bra", "can", "chi", "chn", "cze", "den",
"ecu", "esp", "euro", "fin", "fra", "gbr", "ger", "gre", "hkg", "hun", "irl", "isr",
"isv", "ita", "jpn", "kaz", "kor", "lat", "lux", "mex", "ned", "nld", "nor", "nzl",
@ -87,42 +84,6 @@ bool compare_software(ui_software_info a, ui_software_info b)
}
}
//-------------------------------------------------
// get bios count
//-------------------------------------------------
bool has_multiple_bios(const game_driver *driver, s_bios &biosname)
{
if (driver->rom == nullptr)
return false;
auto entries = rom_build_entries(driver->rom);
std::string default_name;
for (const rom_entry &rom : entries)
if (ROMENTRY_ISDEFAULT_BIOS(&rom))
default_name = ROM_GETNAME(&rom);
for (const rom_entry &rom : entries)
{
if (ROMENTRY_ISSYSTEM_BIOS(&rom))
{
std::string name(ROM_GETHASHDATA(&rom));
std::string bname(ROM_GETNAME(&rom));
int bios_flags = ROM_GETBIOSFLAGS(&rom);
if (bname == default_name)
{
name.append(_(" (default)"));
biosname.emplace(biosname.begin(), name, bios_flags - 1);
}
else
biosname.emplace_back(name, bios_flags - 1);
}
}
return (biosname.size() > 1);
}
//-------------------------------------------------
// ctor
//-------------------------------------------------
@ -130,8 +91,7 @@ bool has_multiple_bios(const game_driver *driver, s_bios &biosname)
menu_select_software::menu_select_software(mame_ui_manager &mui, render_container &container, const game_driver *driver)
: menu_select_launch(mui, container, true)
{
if (reselect_last::get())
reselect_last::set(false);
reselect_last::reselect(false);
sw_filters::actual = 0;
highlight = 0;
@ -175,11 +135,9 @@ void menu_select_software::handle()
if (menu_event && menu_event->itemref)
{
if (m_ui_error)
if (dismiss_error())
{
// reset the error on any future event
m_ui_error = false;
machine().ui_input().reset();
}
else if (menu_event->iptkey == IPT_UI_SELECT)
{
@ -372,10 +330,7 @@ void menu_select_software::handle()
}
// if we're in an error state, overlay an error message
if (m_ui_error)
ui().draw_text_box(container(), _("The selected software is missing one or more required files. "
"Please select a different software.\n\nPress any key to continue."),
ui::text_layout::CENTER, 0.5f, 0.5f, UI_RED_COLOR);
draw_error_text();
// handle filters selection from key shortcuts
if (check_filter)
@ -472,10 +427,10 @@ void menu_select_software::populate(float &customtop, float &custombottom)
// iterate over entries
for (size_t curitem = 0; curitem < m_displaylist.size(); ++curitem)
{
if (reselect_last::software == "[Start empty]" && !reselect_last::driver.empty())
if (reselect_last::software() == "[Start empty]" && !reselect_last::driver().empty())
old_software = 0;
else if (m_displaylist[curitem]->shortname == reselect_last::software && m_displaylist[curitem]->listname == reselect_last::swlist)
else if (m_displaylist[curitem]->shortname == reselect_last::software() && m_displaylist[curitem]->listname == reselect_last::swlist())
old_software = m_has_empty_start ? curitem + 1 : curitem;
item_append(m_displaylist[curitem]->longname, m_displaylist[curitem]->devicetype,
@ -515,7 +470,7 @@ void menu_select_software::populate(float &customtop, float &custombottom)
void menu_select_software::build_software_list()
{
// add start empty item
m_swinfo.emplace_back(m_driver->name, m_driver->type.fullname(), "", "", "", 0, "", m_driver, "", "", "", 1, "", "", "", true);
m_swinfo.emplace_back(*m_driver);
machine_config config(*m_driver, machine().options());
@ -531,50 +486,26 @@ void menu_select_software::build_software_list()
{
const char *instance_name = nullptr;
const char *type_name = nullptr;
ui_software_info tmpmatches;
for (device_image_interface &image : image_interface_iterator(config.root_device()))
{
const char *interface = image.image_interface();
if (interface != nullptr && part.matches_interface(interface))
char const *const interface = image.image_interface();
if (interface && part.matches_interface(interface))
{
instance_name = image.instance_name().c_str();
if (instance_name != nullptr)
tmpmatches.instance = image.instance_name();
type_name = image.image_type_name();
if (type_name != nullptr)
tmpmatches.devicetype = type_name;
break;
}
}
if (instance_name == nullptr || type_name == nullptr)
if (!instance_name || !type_name)
continue;
tmpmatches.shortname = swinfo.shortname();
tmpmatches.longname = swinfo.longname();
tmpmatches.parentname = swinfo.parentname();
tmpmatches.year = swinfo.year();
tmpmatches.publisher = swinfo.publisher();
tmpmatches.supported = swinfo.supported();
tmpmatches.part = part.name();
tmpmatches.driver = m_driver;
tmpmatches.listname = swlist.list_name();
tmpmatches.interface = part.interface();
tmpmatches.startempty = 0;
tmpmatches.parentlongname.clear();
tmpmatches.usage.clear();
tmpmatches.available = false;
ui_software_info tmpmatches(swinfo, part, *m_driver, swlist.list_name(), instance_name, type_name);
for (const feature_list_item &flist : swinfo.other_info())
if (!strcmp(flist.name().c_str(), "usage"))
tmpmatches.usage = flist.value();
m_swinfo.push_back(tmpmatches);
m_filter.region.set(tmpmatches.longname);
m_filter.publisher.set(tmpmatches.publisher);
m_filter.year.set(tmpmatches.year);
m_filter.type.set(tmpmatches.devicetype);
m_swinfo.emplace_back(std::move(tmpmatches));
}
}
}
@ -658,27 +589,15 @@ void menu_select_software::build_software_list()
void menu_select_software::inkey_select(const event *menu_event)
{
ui_software_info *ui_swinfo = (ui_software_info *)menu_event->itemref;
ui_options &mopt = ui().options();
if (ui_swinfo->startempty == 1)
{
s_bios biosname;
if (!mopt.skip_bios_menu() && has_multiple_bios(ui_swinfo->driver, biosname))
if (!select_bios(*ui_swinfo->driver, true))
{
menu::stack_push<bios_selection>(ui(), container(), biosname, (void *)ui_swinfo->driver, false, true);
}
else
{
reselect_last::driver = ui_swinfo->driver->name;
reselect_last::software = "[Start empty]";
reselect_last::swlist.clear();
reselect_last::set(true);
mame_machine_manager::instance()->schedule_new_driver(*ui_swinfo->driver);
machine().schedule_hard_reset();
stack_reset();
reselect_last::reselect(true);
launch_system(*ui_swinfo->driver, *ui_swinfo);
}
}
else
{
// first validate
@ -688,51 +607,28 @@ void menu_select_software::inkey_select(const event *menu_event)
software_list_device *swlist = software_list_device::find_by_name(*drivlist.config(), ui_swinfo->listname.c_str());
const software_info *swinfo = swlist->find(ui_swinfo->shortname.c_str());
media_auditor::summary summary = auditor.audit_software(swlist->list_name(), swinfo, AUDIT_VALIDATE_FAST);
media_auditor::summary const summary = auditor.audit_software(swlist->list_name(), swinfo, AUDIT_VALIDATE_FAST);
if (summary == media_auditor::CORRECT || summary == media_auditor::BEST_AVAILABLE || summary == media_auditor::NONE_NEEDED)
{
s_bios biosname;
if (!mopt.skip_bios_menu() && has_multiple_bios(ui_swinfo->driver, biosname))
if (!select_bios(*ui_swinfo, false) && !select_part(*swinfo, *ui_swinfo))
{
menu::stack_push<bios_selection>(ui(), container(), biosname, (void *)ui_swinfo, true, false);
return;
reselect_last::reselect(true);
launch_system(drivlist.driver(), *ui_swinfo);
}
else if (!mopt.skip_parts_menu() && swinfo->has_multiple_parts(ui_swinfo->interface.c_str()))
{
s_parts parts;
for (const software_part &swpart : swinfo->parts())
{
if (swpart.matches_interface(ui_swinfo->interface.c_str()))
{
std::string menu_part_name(swpart.name());
if (swpart.feature("part_id") != nullptr)
menu_part_name.assign("(").append(swpart.feature("part_id")).append(")");
parts.emplace(swpart.name(), menu_part_name);
}
}
menu::stack_push<software_parts>(ui(), container(), parts, ui_swinfo);
return;
}
machine().options().set_system_name(m_driver->name);
machine().options().set_value(OPTION_SOFTWARENAME, ui_swinfo->shortname, OPTION_PRIORITY_CMDLINE);
std::string snap_list = std::string(ui_swinfo->listname).append(PATH_SEPARATOR).append(ui_swinfo->shortname);
machine().options().set_value(OPTION_SNAPNAME, snap_list.c_str(), OPTION_PRIORITY_CMDLINE);
reselect_last::driver = drivlist.driver().name;
reselect_last::software = ui_swinfo->shortname;
reselect_last::swlist = ui_swinfo->listname;
reselect_last::set(true);
mame_machine_manager::instance()->schedule_new_driver(drivlist.driver());
machine().schedule_hard_reset();
stack_reset();
}
// otherwise, display an error
else
{
reset(reset_options::REMEMBER_POSITION);
m_ui_error = true;
// otherwise, display an error
std::ostringstream str;
str << _("The selected software is missing one or more required files. Please select a different software.\n\n");
if (media_auditor::NOTFOUND != summary)
{
auditor.summarize(nullptr, &str);
str << "\n";
}
str << _("Press any key to continue."),
set_error(reset_options::REMEMBER_POSITION, str.str());
}
}
}
@ -1239,243 +1135,6 @@ float menu_select_software::draw_left_panel(float x1, float y1, float x2, float
}
}
//-------------------------------------------------
// ctor
//-------------------------------------------------
software_parts::software_parts(mame_ui_manager &mui, render_container &container, s_parts parts, ui_software_info *ui_info) : menu(mui, container)
{
m_parts = parts;
m_uiinfo = ui_info;
}
//-------------------------------------------------
// dtor
//-------------------------------------------------
software_parts::~software_parts()
{
}
//-------------------------------------------------
// populate
//-------------------------------------------------
void software_parts::populate(float &customtop, float &custombottom)
{
for (auto & elem : m_parts)
item_append(elem.first, elem.second, 0, (void *)&elem);
item_append(menu_item_type::SEPARATOR);
customtop = ui().get_line_height() + (3.0f * UI_BOX_TB_BORDER);
}
//-------------------------------------------------
// handle
//-------------------------------------------------
void software_parts::handle()
{
// process the menu
const event *menu_event = process(0);
if (menu_event && (menu_event->iptkey) == IPT_UI_SELECT && menu_event->itemref)
{
for (auto & elem : m_parts)
{
if ((void*)&elem == menu_event->itemref)
{
std::string string_list = std::string(m_uiinfo->listname).append(":").append(m_uiinfo->shortname).append(":").append(elem.first).append(":").append(m_uiinfo->instance);
machine().options().set_value(OPTION_SOFTWARENAME, string_list.c_str(), OPTION_PRIORITY_CMDLINE);
reselect_last::driver = m_uiinfo->driver->name;
reselect_last::software = m_uiinfo->shortname;
reselect_last::swlist = m_uiinfo->listname;
reselect_last::set(true);
std::string snap_list = std::string(m_uiinfo->listname).append("/").append(m_uiinfo->shortname);
machine().options().set_value(OPTION_SNAPNAME, snap_list.c_str(), OPTION_PRIORITY_CMDLINE);
mame_machine_manager::instance()->schedule_new_driver(*m_uiinfo->driver);
machine().schedule_hard_reset();
stack_reset();
}
}
}
}
//-------------------------------------------------
// perform our special rendering
//-------------------------------------------------
void software_parts::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
{
float width;
ui().draw_text_full(container(), _("Software part selection:"), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
width += 2 * UI_BOX_LR_BORDER;
float maxwidth = std::max(origx2 - origx1, width);
// compute our bounds
float x1 = 0.5f - 0.5f * maxwidth;
float x2 = x1 + maxwidth;
float y1 = origy1 - top;
float y2 = origy1 - UI_BOX_TB_BORDER;
// draw a box
ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_GREEN_COLOR);
// take off the borders
x1 += UI_BOX_LR_BORDER;
x2 -= UI_BOX_LR_BORDER;
y1 += UI_BOX_TB_BORDER;
// draw the text within it
ui().draw_text_full(container(), _("Software part selection:"), x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
}
//-------------------------------------------------
// ctor
//-------------------------------------------------
bios_selection::bios_selection(mame_ui_manager &mui, render_container &container, s_bios biosname, void *_driver, bool _software, bool _inlist) : menu(mui, container)
{
m_bios = biosname;
m_driver = _driver;
m_software = _software;
m_inlist = _inlist;
}
//-------------------------------------------------
// dtor
//-------------------------------------------------
bios_selection::~bios_selection()
{
}
//-------------------------------------------------
// populate
//-------------------------------------------------
void bios_selection::populate(float &customtop, float &custombottom)
{
for (auto & elem : m_bios)
item_append(elem.first, "", 0, (void *)&elem.first);
item_append(menu_item_type::SEPARATOR);
customtop = ui().get_line_height() + (3.0f * UI_BOX_TB_BORDER);
}
//-------------------------------------------------
// handle
//-------------------------------------------------
void bios_selection::handle()
{
// process the menu
const event *menu_event = process(0);
emu_options &moptions = machine().options();
if (menu_event && menu_event->iptkey == IPT_UI_SELECT && menu_event->itemref)
{
for (auto & elem : m_bios)
{
if ((void*)&elem.first == menu_event->itemref)
{
if (!m_software)
{
const game_driver *s_driver = (const game_driver *)m_driver;
reselect_last::driver = s_driver->name;
if (m_inlist)
reselect_last::software = "[Start empty]";
else
{
reselect_last::software.clear();
reselect_last::swlist.clear();
reselect_last::set(true);
}
moptions.set_value(OPTION_BIOS, elem.second, OPTION_PRIORITY_CMDLINE);
mame_machine_manager::instance()->schedule_new_driver(*s_driver);
machine().schedule_hard_reset();
stack_reset();
}
else
{
ui_software_info *ui_swinfo = (ui_software_info *)m_driver;
machine().options().set_value(OPTION_BIOS, elem.second, OPTION_PRIORITY_CMDLINE);
driver_enumerator drivlist(machine().options(), *ui_swinfo->driver);
drivlist.next();
software_list_device *swlist = software_list_device::find_by_name(*drivlist.config(), ui_swinfo->listname.c_str());
const software_info *swinfo = swlist->find(ui_swinfo->shortname.c_str());
if (!ui().options().skip_parts_menu() && swinfo->has_multiple_parts(ui_swinfo->interface.c_str()))
{
s_parts parts;
for (const software_part &swpart : swinfo->parts())
{
if (swpart.matches_interface(ui_swinfo->interface.c_str()))
{
std::string menu_part_name(swpart.name());
if (swpart.feature("part_id") != nullptr)
menu_part_name.assign("(").append(swpart.feature("part_id")).append(")");
parts.emplace(swpart.name(), menu_part_name);
}
}
menu::stack_push<software_parts>(ui(), container(), parts, ui_swinfo);
return;
}
moptions.set_value(OPTION_SYSTEMNAME, drivlist.driver().name, OPTION_PRIORITY_CMDLINE);
moptions.set_value(OPTION_SOFTWARENAME,
ui_swinfo->listname + ":" + ui_swinfo->shortname,
OPTION_PRIORITY_CMDLINE);
moptions.set_value(OPTION_SNAPNAME,
ui_swinfo->listname + std::string(PATH_SEPARATOR) + ui_swinfo->shortname,
OPTION_PRIORITY_CMDLINE);
reselect_last::driver = drivlist.driver().name;
reselect_last::software = ui_swinfo->shortname;
reselect_last::swlist = ui_swinfo->listname;
reselect_last::set(true);
mame_machine_manager::instance()->schedule_new_driver(drivlist.driver());
machine().schedule_hard_reset();
stack_reset();
}
}
}
}
}
//-------------------------------------------------
// perform our special rendering
//-------------------------------------------------
void bios_selection::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
{
float width;
ui().draw_text_full(container(), _("Bios selection:"), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
width += 2 * UI_BOX_LR_BORDER;
float maxwidth = std::max(origx2 - origx1, width);
// compute our bounds
float x1 = 0.5f - 0.5f * maxwidth;
float x2 = x1 + maxwidth;
float y1 = origy1 - top;
float y2 = origy1 - UI_BOX_TB_BORDER;
// draw a box
ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_GREEN_COLOR);
// take off the borders
x1 += UI_BOX_LR_BORDER;
x2 -= UI_BOX_LR_BORDER;
y1 += UI_BOX_TB_BORDER;
// draw the text within it
ui().draw_text_full(container(), _("Bios selection:"), x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
}
//-------------------------------------------------
// get selected software and/or driver
//-------------------------------------------------

View File

@ -16,8 +16,6 @@
#include "ui/selmenu.h"
namespace ui {
using s_bios = std::vector<std::pair<std::string, int>>;
using s_parts = std::unordered_map<std::string, std::string>;
// Menu Class
class menu_select_software : public menu_select_launch
@ -31,6 +29,7 @@ protected:
private:
enum { VISIBLE_GAMES_IN_SEARCH = 200 };
std::string m_search;
const game_driver *m_driver;
bool m_has_empty_start;
@ -68,55 +67,6 @@ private:
virtual void general_info(const game_driver *driver, std::string &buffer) override {}
};
class software_parts : public menu
{
public:
software_parts(mame_ui_manager &mui, render_container &container, s_parts parts, ui_software_info *ui_info);
virtual ~software_parts() override;
protected:
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void handle() override;
ui_software_info *m_uiinfo;
s_parts m_parts;
};
class bios_selection : public menu
{
public:
bios_selection(mame_ui_manager &mui, render_container &container, s_bios biosname, void *driver, bool software, bool inlist);
virtual ~bios_selection() override;
protected:
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void handle() override;
void *m_driver;
bool m_software, m_inlist;
s_bios m_bios;
};
struct reselect_last
{
static std::string driver, software, swlist;
static void set(bool value) { m_reselect = value; }
static bool get() { return m_reselect; }
static void reset() { driver.clear(); software.clear(); swlist.clear(); set(false); }
private:
static bool m_reselect;
};
// Getter
bool has_multiple_bios(const game_driver *driver, s_bios &biosname);
} // namespace ui
#endif /* MAME_FRONTEND_UI_SELSOFT_H */

View File

@ -11,6 +11,9 @@
#include "emu.h"
#include "ui/utils.h"
#include "softlist.h"
extern const char UI_VERSION_TAG[];
const char UI_VERSION_TAG[] = "# UI INFO ";
@ -195,3 +198,39 @@ void c_year::set(const char *str)
ui.push_back(name);
}
ui_software_info::ui_software_info(
software_info const &info,
software_part const &p,
game_driver const &d,
std::string const &li,
std::string const &is,
std::string const &de)
: shortname(info.shortname()), longname(info.longname()), parentname(info.parentname())
, year(info.year()), publisher(info.publisher())
, supported(info.supported())
, part(p.name())
, driver(&d)
, listname(li), interface(p.interface()), instance(is)
, startempty(0)
, parentlongname()
, usage()
, devicetype(de)
, available(false)
{
for (feature_list_item const &feature : info.other_info())
{
if (feature.name() == "usage")
{
usage = feature.value();
break;
}
}
}
// info for starting empty
ui_software_info::ui_software_info(game_driver const &d)
: shortname(d.name), longname(d.type.fullname()), driver(&d), startempty(1), available(true)
{
}

View File

@ -128,15 +128,35 @@ enum
// GLOBAL STRUCTURES
struct ui_software_info
{
ui_software_info() {}
ui_software_info(std::string sname, std::string lname, std::string pname, std::string y, std::string pub,
uint8_t s, std::string pa, const game_driver *d, std::string li, std::string i, std::string is, uint8_t em,
std::string plong, std::string u, std::string de, bool av)
ui_software_info() { }
// info for software list item
ui_software_info(
software_info const &info,
software_part const &p,
game_driver const &d,
std::string const &li,
std::string const &is,
std::string const &de);
// info for starting empty
ui_software_info(game_driver const &d);
// copyable/movable
ui_software_info(ui_software_info const &) = default;
ui_software_info(ui_software_info &&) = default;
ui_software_info &operator=(ui_software_info const &) = default;
ui_software_info &operator=(ui_software_info &&) = default;
bool operator==(ui_software_info const &r)
{
shortname = sname; longname = lname; parentname = pname; year = y; publisher = pub;
supported = s; part = pa; driver = d; listname = li; interface = i; instance = is; startempty = em;
parentlongname = plong; usage = u; devicetype = de; available = av;
return shortname == r.shortname && longname == r.longname && parentname == r.parentname
&& year == r.year && publisher == r.publisher && supported == r.supported
&& part == r.part && driver == r.driver && listname == r.listname
&& interface == r.interface && instance == r.instance && startempty == r.startempty
&& parentlongname == r.parentlongname && usage == r.usage && devicetype == r.devicetype;
}
std::string shortname;
std::string longname;
std::string parentname;
@ -153,15 +173,6 @@ struct ui_software_info
std::string usage;
std::string devicetype;
bool available = false;
bool operator==(const ui_software_info& r)
{
return shortname == r.shortname && longname == r.longname && parentname == r.parentname
&& year == r.year && publisher == r.publisher && supported == r.supported
&& part == r.part && driver == r.driver && listname == r.listname
&& interface == r.interface && instance == r.instance && startempty == r.startempty
&& parentlongname == r.parentlongname && usage == r.usage && devicetype == r.devicetype;
}
};
// Manufacturers