summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/ui/selsoft.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/ui/selsoft.cpp')
-rw-r--r--src/emu/ui/selsoft.cpp1976
1 files changed, 0 insertions, 1976 deletions
diff --git a/src/emu/ui/selsoft.cpp b/src/emu/ui/selsoft.cpp
deleted file mode 100644
index 985a7d31bfc..00000000000
--- a/src/emu/ui/selsoft.cpp
+++ /dev/null
@@ -1,1976 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Dankan1890
-/***************************************************************************
-
- ui/selsoft.cpp
-
- UI softwares menu.
-
-***************************************************************************/
-
-#include "emu.h"
-#include "emuopts.h"
-#include "ui/ui.h"
-#include "ui/menu.h"
-#include "uiinput.h"
-#include "audit.h"
-#include "ui/selsoft.h"
-#include "ui/datmenu.h"
-#include "ui/datfile.h"
-#include "ui/inifile.h"
-#include "ui/selector.h"
-#include "rendfont.h"
-#include "rendutil.h"
-#include "softlist.h"
-#include <algorithm>
-
-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",
- "pol", "rus", "slo", "spa", "sui", "swe", "tha", "tpe", "tw", "uk", "ukr", "usa" };
-
-//-------------------------------------------------
-// compares two items in the software list and
-// sort them by parent-clone
-//-------------------------------------------------
-
-bool compare_software(ui_software_info a, ui_software_info b)
-{
- ui_software_info *x = &a;
- ui_software_info *y = &b;
-
- bool clonex = (x->parentname[0] != '\0');
- bool cloney = (y->parentname[0] != '\0');
-
- if (!clonex && !cloney)
- return (strmakelower(x->longname) < strmakelower(y->longname));
-
- std::string cx(x->parentlongname), cy(y->parentlongname);
-
- if (clonex && cx[0] == '\0')
- clonex = false;
-
- if (cloney && cy[0] == '\0')
- cloney = false;
-
- if (!clonex && !cloney)
- return (strmakelower(x->longname) < strmakelower(y->longname));
- else if (clonex && cloney)
- {
- if (!core_stricmp(x->parentname.c_str(), y->parentname.c_str()) && !core_stricmp(x->instance.c_str(), y->instance.c_str()))
- return (strmakelower(x->longname) < strmakelower(y->longname));
- else
- return (strmakelower(cx) < strmakelower(cy));
- }
- else if (!clonex && cloney)
- {
- if (!core_stricmp(x->shortname.c_str(), y->parentname.c_str()) && !core_stricmp(x->instance.c_str(), y->instance.c_str()))
- return true;
- else
- return (strmakelower(x->longname) < strmakelower(cy));
- }
- else
- {
- if (!core_stricmp(x->parentname.c_str(), y->shortname.c_str()) && !core_stricmp(x->instance.c_str(), y->instance.c_str()))
- return false;
- else
- return (strmakelower(cx) < strmakelower(y->longname));
- }
-}
-
-//-------------------------------------------------
-// get bios count
-//-------------------------------------------------
-
-bool has_multiple_bios(const game_driver *driver, std::vector<s_bios> &biosname)
-{
- if (driver->rom == nullptr)
- return 0;
-
- std::string default_name;
- for (const rom_entry *rom = driver->rom; !ROMENTRY_ISEND(rom); ++rom)
- if (ROMENTRY_ISDEFAULT_BIOS(rom))
- default_name = ROM_GETNAME(rom);
-
- for (const rom_entry *rom = driver->rom; !ROMENTRY_ISEND(rom); ++rom)
- {
- 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
-//-------------------------------------------------
-
-ui_menu_select_software::ui_menu_select_software(running_machine &machine, render_container *container, const game_driver *driver) : ui_menu(machine, container)
-{
- if (reselect_last::get())
- reselect_last::set(false);
-
- sw_filters::actual = 0;
-
- m_driver = driver;
- build_software_list();
- load_sw_custom_filters();
-
- ui_globals::curimage_view = SNAPSHOT_VIEW;
- ui_globals::switch_image = true;
- ui_globals::cur_sw_dats_view = UI_FIRST_LOAD;
-
- std::string error_string;
- machine.options().set_value(OPTION_SOFTWARENAME, "", OPTION_PRIORITY_CMDLINE, error_string);
-}
-
-//-------------------------------------------------
-// dtor
-//-------------------------------------------------
-
-ui_menu_select_software::~ui_menu_select_software()
-{
- ui_globals::curimage_view = CABINETS_VIEW;
- ui_globals::switch_image = true;
-}
-
-//-------------------------------------------------
-// handle
-//-------------------------------------------------
-
-void ui_menu_select_software::handle()
-{
- bool check_filter = false;
-
- // ignore pause keys by swallowing them before we process the menu
- machine().ui_input().pressed(IPT_UI_PAUSE);
-
- // process the menu
- const ui_menu_event *m_event = process(UI_MENU_PROCESS_LR_REPEAT);
-
- if (m_event != nullptr && m_event->itemref != nullptr)
- {
- // reset the error on any future m_event
- if (ui_error)
- ui_error = false;
-
- // handle selections
- else if (m_event->iptkey == IPT_UI_SELECT)
- inkey_select(m_event);
-
- // handle UI_LEFT
- else if (m_event->iptkey == IPT_UI_LEFT)
- {
- // Images
- if (ui_globals::rpanel == RP_IMAGES && ui_globals::curimage_view > FIRST_VIEW)
- {
- ui_globals::curimage_view--;
- ui_globals::switch_image = true;
- ui_globals::default_image = false;
- }
-
- // Infos
- else if (ui_globals::rpanel == RP_INFOS && ui_globals::cur_sw_dats_view > 0)
- {
- ui_globals::cur_sw_dats_view--;
- topline_datsview = 0;
- }
- }
-
- // handle UI_RIGHT
- else if (m_event->iptkey == IPT_UI_RIGHT)
- {
- // Images
- if (ui_globals::rpanel == RP_IMAGES && ui_globals::curimage_view < LAST_VIEW)
- {
- ui_globals::curimage_view++;
- ui_globals::switch_image = true;
- ui_globals::default_image = false;
- }
-
- // Infos
- else if (ui_globals::rpanel == RP_INFOS && ui_globals::cur_sw_dats_view < 1)
- {
- ui_globals::cur_sw_dats_view++;
- topline_datsview = 0;
- }
- }
-
- // handle UI_DATS
- else if (m_event->iptkey == IPT_UI_DATS && machine().ui().options().enabled_dats())
- {
- ui_software_info *ui_swinfo = (ui_software_info *)m_event->itemref;
-
- if ((FPTR)ui_swinfo > 1 && machine().datfile().has_data(ui_swinfo->driver))
- {
- if (ui_swinfo->startempty == 1)
- ui_menu::stack_push(global_alloc_clear<ui_menu_dats_view>(machine(), container, ui_swinfo->driver));
- else
- ui_menu::stack_push(global_alloc_clear<ui_menu_dats_view>(machine(), container, ui_swinfo));
- }
- }
-
- // handle UI_UP_FILTER
- else if (m_event->iptkey == IPT_UI_UP_FILTER && sw_filters::actual > UI_SW_FIRST)
- {
- l_sw_hover = sw_filters::actual - 1;
- check_filter = true;
- }
-
- // handle UI_DOWN_FILTER
- else if (m_event->iptkey == IPT_UI_DOWN_FILTER && sw_filters::actual < UI_SW_LAST)
- {
- l_sw_hover = sw_filters::actual + 1;
- check_filter = true;
- }
-
- // handle UI_LEFT_PANEL
- else if (m_event->iptkey == IPT_UI_LEFT_PANEL)
- ui_globals::rpanel = RP_IMAGES;
-
- // handle UI_RIGHT_PANEL
- else if (m_event->iptkey == IPT_UI_RIGHT_PANEL)
- ui_globals::rpanel = RP_INFOS;
-
- // escape pressed with non-empty text clears the text
- else if (m_event->iptkey == IPT_UI_CANCEL && m_search[0] != 0)
- {
- m_search[0] = '\0';
- reset(UI_MENU_RESET_SELECT_FIRST);
- }
-
- // handle UI_FAVORITES
- else if (m_event->iptkey == IPT_UI_FAVORITES)
- {
- ui_software_info *swinfo = (ui_software_info *)m_event->itemref;
-
- if ((FPTR)swinfo > 2)
- {
- if (!machine().favorite().isgame_favorite(*swinfo))
- {
- machine().favorite().add_favorite_game(*swinfo);
- machine().popmessage("%s\n added to favorites list.", swinfo->longname.c_str());
- }
-
- else
- {
- machine().popmessage("%s\n removed from favorites list.", swinfo->longname.c_str());
- machine().favorite().remove_favorite_game();
- }
- }
- }
-
- // typed characters append to the buffer
- else if (m_event->iptkey == IPT_SPECIAL)
- inkey_special(m_event);
-
- else if (m_event->iptkey == IPT_OTHER)
- check_filter = true;
- }
-
- if (m_event != nullptr && m_event->itemref == nullptr)
- {
- // reset the error on any future m_event
- if (ui_error)
- ui_error = false;
-
- else if (m_event->iptkey == IPT_OTHER)
- check_filter = true;
-
- // handle UI_UP_FILTER
- else if (m_event->iptkey == IPT_UI_UP_FILTER && sw_filters::actual > UI_SW_FIRST)
- {
- l_sw_hover = sw_filters::actual - 1;
- check_filter = true;
- }
-
- // handle UI_DOWN_FILTER
- else if (m_event->iptkey == IPT_UI_DOWN_FILTER && sw_filters::actual < UI_SW_LAST)
- {
- l_sw_hover = sw_filters::actual + 1;
- check_filter = true;
- }
- }
-
- // if we're in an error state, overlay an error message
- if (ui_error)
- machine().ui().draw_text_box(container,
- "The selected software is missing one or more required files. "
- "Please select a different software.\n\nPress any key (except ESC) to continue.",
- JUSTIFY_CENTER, 0.5f, 0.5f, UI_RED_COLOR);
-
- // handle filters selection from key shortcuts
- if (check_filter)
- {
- m_search[0] = '\0';
-
- switch (l_sw_hover)
- {
- case UI_SW_REGION:
- ui_menu::stack_push(global_alloc_clear<ui_menu_selector>(machine(), container, m_filter.region.ui,
- m_filter.region.actual, SELECTOR_SOFTWARE, l_sw_hover));
- break;
- case UI_SW_YEARS:
- ui_menu::stack_push(global_alloc_clear<ui_menu_selector>(machine(), container, m_filter.year.ui,
- m_filter.year.actual, SELECTOR_SOFTWARE, l_sw_hover));
- break;
- case UI_SW_LIST:
- ui_menu::stack_push(global_alloc_clear<ui_menu_selector>(machine(), container, m_filter.swlist.description,
- m_filter.swlist.actual, SELECTOR_SOFTWARE, l_sw_hover));
- break;
- case UI_SW_TYPE:
- ui_menu::stack_push(global_alloc_clear<ui_menu_selector>(machine(), container, m_filter.type.ui,
- m_filter.type.actual, SELECTOR_SOFTWARE, l_sw_hover));
- break;
- case UI_SW_PUBLISHERS:
- ui_menu::stack_push(global_alloc_clear<ui_menu_selector>(machine(), container, m_filter.publisher.ui,
- m_filter.publisher.actual, SELECTOR_SOFTWARE, l_sw_hover));
- break;
- case UI_SW_CUSTOM:
- sw_filters::actual = l_sw_hover;
- ui_menu::stack_push(global_alloc_clear<ui_menu_swcustom_filter>(machine(), container, m_driver, m_filter));
- break;
- default:
- sw_filters::actual = l_sw_hover;
- reset(UI_MENU_RESET_SELECT_FIRST);
- break;
- }
- }
-}
-
-//-------------------------------------------------
-// populate
-//-------------------------------------------------
-
-void ui_menu_select_software::populate()
-{
- UINT32 flags_ui = MENU_FLAG_UI_SWLIST | MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW;
- m_has_empty_start = true;
- int old_software = -1;
-
- machine_config config(*m_driver, machine().options());
- image_interface_iterator iter(config.root_device());
-
- for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next())
- if (image->filename() == nullptr && image->must_be_loaded())
- {
- m_has_empty_start = false;
- break;
- }
-
- // no active search
- if (m_search[0] == 0)
- {
- // if the device can be loaded empty, add an item
- if (m_has_empty_start)
- item_append("[Start empty]", nullptr, flags_ui, (void *)&m_swinfo[0]);
-
- m_displaylist.clear();
- m_tmp.clear();
-
- switch (sw_filters::actual)
- {
- case UI_SW_PUBLISHERS:
- build_list(m_tmp, m_filter.publisher.ui[m_filter.publisher.actual].c_str());
- break;
-
- case UI_SW_LIST:
- build_list(m_tmp, m_filter.swlist.name[m_filter.swlist.actual].c_str());
- break;
-
- case UI_SW_YEARS:
- build_list(m_tmp, m_filter.year.ui[m_filter.year.actual].c_str());
- break;
-
- case UI_SW_TYPE:
- build_list(m_tmp, m_filter.type.ui[m_filter.type.actual].c_str());
- break;
-
- case UI_SW_REGION:
- build_list(m_tmp, m_filter.region.ui[m_filter.region.actual].c_str());
- break;
-
- case UI_SW_CUSTOM:
- build_custom();
- break;
-
- default:
- build_list(m_tmp);
- break;
- }
-
- // iterate over entries
- for (size_t curitem = 0; curitem < m_displaylist.size(); ++curitem)
- {
- 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)
- old_software = m_has_empty_start ? curitem + 1 : curitem;
-
- item_append(m_displaylist[curitem]->longname.c_str(), m_displaylist[curitem]->devicetype.c_str(),
- m_displaylist[curitem]->parentname.empty() ? flags_ui : (MENU_FLAG_INVERT | flags_ui), (void *)m_displaylist[curitem]);
- }
- }
-
- else
- {
- find_matches(m_search, VISIBLE_GAMES_IN_SEARCH);
-
- for (int curitem = 0; m_searchlist[curitem] != nullptr; ++curitem)
- item_append(m_searchlist[curitem]->longname.c_str(), m_searchlist[curitem]->devicetype.c_str(),
- m_searchlist[curitem]->parentname.empty() ? flags_ui : (MENU_FLAG_INVERT | flags_ui),
- (void *)m_searchlist[curitem]);
- }
-
- item_append(MENU_SEPARATOR_ITEM, nullptr, flags_ui, nullptr);
-
- // configure the custom rendering
- customtop = 4.0f * machine().ui().get_line_height() + 5.0f * UI_BOX_TB_BORDER;
- custombottom = 5.0f * machine().ui().get_line_height() + 4.0f * UI_BOX_TB_BORDER;
-
- if (old_software != -1)
- {
- selected = old_software;
- top_line = selected - (ui_globals::visible_sw_lines / 2);
- }
-
- reselect_last::reset();
-}
-
-//-------------------------------------------------
-// build a list of softwares
-//-------------------------------------------------
-
-void ui_menu_select_software::build_software_list()
-{
- // add start empty item
- m_swinfo.emplace_back(m_driver->name, m_driver->description, "", "", "", 0, "", m_driver, "", "", "", 1, "", "", "", true);
-
- machine_config config(*m_driver, machine().options());
- software_list_device_iterator deviter(config.root_device());
-
- // iterate thru all software lists
- for (software_list_device *swlist = deviter.first(); swlist != nullptr; swlist = deviter.next())
- {
- m_filter.swlist.name.push_back(swlist->list_name());
- m_filter.swlist.description.push_back(swlist->description());
- for (software_info *swinfo = swlist->first_software_info(); swinfo != nullptr; swinfo = swinfo->next())
- {
- software_part *part = swinfo->first_part();
- if (part->is_compatible(*swlist))
- {
- const char *instance_name = nullptr;
- const char *type_name = nullptr;
- ui_software_info tmpmatches;
- image_interface_iterator imgiter(config.root_device());
- for (device_image_interface *image = imgiter.first(); image != nullptr; image = imgiter.next())
- {
- const char *interface = image->image_interface();
- if (interface != nullptr && part->matches_interface(interface))
- {
- instance_name = image->instance_name();
- 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)
- continue;
-
- if (swinfo->shortname()) tmpmatches.shortname = swinfo->shortname();
- if (swinfo->longname()) tmpmatches.longname = swinfo->longname();
- if (swinfo->parentname()) tmpmatches.parentname = swinfo->parentname();
- if (swinfo->year()) tmpmatches.year = swinfo->year();
- if (swinfo->publisher()) tmpmatches.publisher = swinfo->publisher();
- tmpmatches.supported = swinfo->supported();
- if (part->name()) tmpmatches.part = part->name();
- tmpmatches.driver = m_driver;
- if (swlist->list_name()) tmpmatches.listname = swlist->list_name();
- if (part->interface()) tmpmatches.interface = part->interface();
- tmpmatches.startempty = 0;
- tmpmatches.parentlongname.clear();
- tmpmatches.usage.clear();
- tmpmatches.available = false;
-
- for (feature_list_item *flist = swinfo->other_info(); flist != nullptr; flist = flist->next())
- if (!strcmp(flist->name(), "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_displaylist.resize(m_swinfo.size() + 1);
-
- // retrieve and set the long name of software for parents
- for (size_t y = 1; y < m_swinfo.size(); ++y)
- {
- if (!m_swinfo[y].parentname.empty())
- {
- std::string lparent(m_swinfo[y].parentname);
- bool found = false;
-
- // first scan backward
- for (int x = y; x > 0; --x)
- if (lparent == m_swinfo[x].shortname && m_swinfo[y].listname == m_swinfo[x].listname)
- {
- m_swinfo[y].parentlongname = m_swinfo[x].longname;
- found = true;
- break;
- }
-
- // not found? then scan forward
- for (size_t x = y; !found && x < m_swinfo.size(); ++x)
- if (lparent == m_swinfo[x].shortname && m_swinfo[y].listname == m_swinfo[x].listname)
- {
- m_swinfo[y].parentlongname = m_swinfo[x].longname;
- break;
- }
- }
- }
-
- std::string searchstr, curpath;
- const osd_directory_entry *dir;
- for (auto & elem : m_filter.swlist.name)
- {
- path_iterator path(machine().options().media_path());
- while (path.next(curpath))
- {
- searchstr.assign(curpath).append(PATH_SEPARATOR).append(elem).append(";");
- file_enumerator fpath(searchstr.c_str());
-
- // iterate while we get new objects
- while ((dir = fpath.next()) != nullptr)
- {
- std::string name;
- if (dir->type == ENTTYPE_FILE)
- name = core_filename_extract_base(dir->name, true);
- else if (dir->type == ENTTYPE_DIR && strcmp(dir->name, ".") != 0)
- name = dir->name;
- else
- continue;
-
- strmakelower(name);
- for (auto & yelem : m_swinfo)
- if (yelem.shortname == name && yelem.listname == elem)
- {
- yelem.available = true;
- break;
- }
- }
- }
- }
-
- // sort array
- std::stable_sort(m_swinfo.begin() + 1, m_swinfo.end(), compare_software);
- std::stable_sort(m_filter.region.ui.begin(), m_filter.region.ui.end());
- std::stable_sort(m_filter.year.ui.begin(), m_filter.year.ui.end());
- std::stable_sort(m_filter.type.ui.begin(), m_filter.type.ui.end());
- std::stable_sort(m_filter.publisher.ui.begin(), m_filter.publisher.ui.end());
-
- for (size_t x = 1; x < m_swinfo.size(); ++x)
- m_sortedlist.push_back(&m_swinfo[x]);
-}
-
-//-------------------------------------------------
-// perform our special rendering
-//-------------------------------------------------
-
-void ui_menu_select_software::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
-{
- ui_software_info *swinfo = (ui_software_info *)selectedref;
- const game_driver *driver = nullptr;
- ui_manager &mui = machine().ui();
- float width;
- std::string tempbuf[5], filtered;
- rgb_t color = UI_BACKGROUND_COLOR;
- bool isstar = false;
- float tbarspace = mui.get_line_height();
-
- // determine the text for the header
- int vis_item = (m_search[0] != 0) ? visible_items : (m_has_empty_start ? visible_items - 1 : visible_items);
- strprintf(tempbuf[0], "MAME %s ( %d / %d softwares )", bare_build_version, vis_item, (int)m_swinfo.size() - 1);
- tempbuf[1].assign("Driver: \"").append(m_driver->description).append("\" software list ");
-
- if (sw_filters::actual == UI_SW_REGION && m_filter.region.ui.size() != 0)
- filtered.assign("Region: ").append(m_filter.region.ui[m_filter.region.actual]).append(" - ");
- else if (sw_filters::actual == UI_SW_PUBLISHERS)
- filtered.assign("Publisher: ").append(m_filter.publisher.ui[m_filter.publisher.actual]).append(" - ");
- else if (sw_filters::actual == UI_SW_YEARS)
- filtered.assign("Year: ").append(m_filter.year.ui[m_filter.year.actual]).append(" - ");
- else if (sw_filters::actual == UI_SW_LIST)
- filtered.assign("Software List: ").append(m_filter.swlist.description[m_filter.swlist.actual]).append(" - ");
- else if (sw_filters::actual == UI_SW_TYPE)
- filtered.assign("Device type: ").append(m_filter.type.ui[m_filter.type.actual]).append(" - ");
-
- tempbuf[2].assign(filtered).append("Search: ").append(m_search).append("_");
-
- // get the size of the text
- float maxwidth = origx2 - origx1;
-
- for (int line = 0; line < 3; ++line)
- {
- mui.draw_text_full(container, tempbuf[line].c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
- width += 2 * UI_BOX_LR_BORDER;
- maxwidth = MAX(width, maxwidth);
- }
-
- // compute our bounds
- float x1 = 0.5f - 0.5f * maxwidth;
- float x2 = x1 + maxwidth;
- float y1 = origy1 - top;
- float y2 = origy1 - 3.0f * UI_BOX_TB_BORDER - tbarspace;
-
- // draw a box
- mui.draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_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
- for (int line = 0; line < 3; ++line)
- {
- mui.draw_text_full(container, tempbuf[line].c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
- y1 += mui.get_line_height();
- }
-
- // determine the text to render below
- if (swinfo && swinfo->startempty == 1)
- driver = swinfo->driver;
-
- if ((FPTR)driver > 1)
- {
- isstar = machine().favorite().isgame_favorite(driver);
-
- // first line is game description
- strprintf(tempbuf[0], "%-.100s", driver->description);
-
- // next line is year, manufacturer
- strprintf(tempbuf[1], "%s, %-.100s", driver->year, driver->manufacturer);
-
- // next line is clone/parent status
- int cloneof = driver_list::non_bios_clone(*driver);
-
- if (cloneof != -1)
- strprintf(tempbuf[2], "Driver is clone of: %-.100s", driver_list::driver(cloneof).description);
- else
- tempbuf[2] = "Driver is parent";
-
- // next line is overall driver status
- if (driver->flags & MACHINE_NOT_WORKING)
- tempbuf[3] = "Overall: NOT WORKING";
- else if (driver->flags & MACHINE_UNEMULATED_PROTECTION)
- tempbuf[3] = "Overall: Unemulated Protection";
- else
- tempbuf[3] = "Overall: Working";
-
- // next line is graphics, sound status
- if (driver->flags & (MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_COLORS))
- tempbuf[4] = "Graphics: Imperfect, ";
- else
- tempbuf[4] = "Graphics: OK, ";
-
- if (driver->flags & MACHINE_NO_SOUND)
- tempbuf[4].append("Sound: Unimplemented");
- else if (driver->flags & MACHINE_IMPERFECT_SOUND)
- tempbuf[4].append("Sound: Imperfect");
- else
- tempbuf[4].append("Sound: OK");
-
- color = UI_GREEN_COLOR;
-
- if ((driver->flags & (MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_COLORS
- | MACHINE_NO_SOUND | MACHINE_IMPERFECT_SOUND)) != 0)
- color = UI_YELLOW_COLOR;
-
- if ((driver->flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION)) != 0)
- color = UI_RED_COLOR;
-
- }
-
- else if ((FPTR)swinfo > 1)
- {
- isstar = machine().favorite().isgame_favorite(*swinfo);
-
- // first line is long name
- strprintf(tempbuf[0], "%-.100s", swinfo->longname.c_str());
-
- // next line is year, publisher
- strprintf(tempbuf[1], "%s, %-.100s", swinfo->year.c_str(), swinfo->publisher.c_str());
-
- // next line is parent/clone
- if (!swinfo->parentname.empty())
- strprintf(tempbuf[2], "Software is clone of: %-.100s", !swinfo->parentlongname.empty() ? swinfo->parentlongname.c_str() : swinfo->parentname.c_str());
- else
- tempbuf[2] = "Software is parent";
-
- // next line is supported status
- if (swinfo->supported == SOFTWARE_SUPPORTED_NO)
- {
- tempbuf[3] = "Supported: No";
- color = UI_RED_COLOR;
- }
- else if (swinfo->supported == SOFTWARE_SUPPORTED_PARTIAL)
- {
- tempbuf[3] = "Supported: Partial";
- color = UI_YELLOW_COLOR;
- }
- else
- {
- tempbuf[3] = "Supported: Yes";
- color = UI_GREEN_COLOR;
- }
-
- // last line is romset name
- strprintf(tempbuf[4], "romset: %-.100s", swinfo->shortname.c_str());
- }
-
- else
- {
- std::string copyright(emulator_info::get_copyright());
- size_t found = copyright.find("\n");
-
- tempbuf[0].clear();
- tempbuf[1].assign(emulator_info::get_appname()).append(" ").append(build_version);
- tempbuf[2] = copyright.substr(0, found);
- tempbuf[3] = copyright.substr(found + 1);
- tempbuf[4].clear();
- }
-
- // compute our bounds
- x1 = 0.5f - 0.5f * maxwidth;
- x2 = x1 + maxwidth;
- y1 = y2;
- y2 = origy1 - UI_BOX_TB_BORDER;
-
- // draw toolbar
- draw_toolbar(x1, y1, x2, y2, true);
-
- // get the size of the text
- maxwidth = origx2 - origx1;
-
- for (auto & elem : tempbuf)
- {
- mui.draw_text_full(container, elem.c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
- width += 2 * UI_BOX_LR_BORDER;
- maxwidth = MAX(maxwidth, width);
- }
-
- // compute our bounds
- x1 = 0.5f - 0.5f * maxwidth;
- x2 = x1 + maxwidth;
- y1 = origy2 + UI_BOX_TB_BORDER;
- y2 = origy2 + bottom;
-
- // draw a box
- mui.draw_outlined_box(container, x1, y1, x2, y2, color);
-
- // take off the borders
- x1 += UI_BOX_LR_BORDER;
- x2 -= UI_BOX_LR_BORDER;
- y1 += UI_BOX_TB_BORDER;
-
- // is favorite? draw the star
- if (isstar)
- draw_star(x1, y1);
-
- // draw all lines
- for (auto & elem : tempbuf)
- {
- mui.draw_text_full(container, elem.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
- y1 += machine().ui().get_line_height();
- }
-}
-
-//-------------------------------------------------
-// handle select key event
-//-------------------------------------------------
-
-void ui_menu_select_software::inkey_select(const ui_menu_event *m_event)
-{
- ui_software_info *ui_swinfo = (ui_software_info *)m_event->itemref;
- ui_options &mopt = machine().ui().options();
-
- if (ui_swinfo->startempty == 1)
- {
- std::vector<s_bios> biosname;
- if (!mopt.skip_bios_menu() && has_multiple_bios(ui_swinfo->driver, biosname))
- ui_menu::stack_push(global_alloc_clear<ui_bios_selection>(machine(), 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);
- machine().manager().schedule_new_driver(*ui_swinfo->driver);
- machine().schedule_hard_reset();
- ui_menu::stack_reset(machine());
- }
- }
-
- else
- {
- // first validate
- driver_enumerator drivlist(machine().options(), *ui_swinfo->driver);
- media_auditor auditor(drivlist);
- drivlist.next();
- software_list_device *swlist = software_list_device::find_by_name(drivlist.config(), ui_swinfo->listname.c_str());
- software_info *swinfo = swlist->find(ui_swinfo->shortname.c_str());
-
- media_auditor::summary 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)
- {
- std::vector<s_bios> biosname;
- if (!mopt.skip_bios_menu() && has_multiple_bios(ui_swinfo->driver, biosname))
- {
- ui_menu::stack_push(global_alloc_clear<ui_bios_selection>(machine(), container, biosname, (void *)ui_swinfo, true, false));
- return;
- }
- else if (!mopt.skip_parts_menu() && swinfo->has_multiple_parts(ui_swinfo->interface.c_str()))
- {
- std::unordered_map<std::string, std::string> parts;
- for (const software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next())
- {
- 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);
- }
- }
- ui_menu::stack_push(global_alloc_clear<ui_software_parts>(machine(), container, parts, ui_swinfo));
- return;
- }
- std::string error_string;
- std::string string_list = std::string(ui_swinfo->listname).append(":").append(ui_swinfo->shortname).append(":").append(ui_swinfo->part).append(":").append(ui_swinfo->instance);
- machine().options().set_value(OPTION_SOFTWARENAME, string_list.c_str(), OPTION_PRIORITY_CMDLINE, error_string);
- 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, error_string);
- reselect_last::driver = drivlist.driver().name;
- reselect_last::software = ui_swinfo->shortname;
- reselect_last::swlist = ui_swinfo->listname;
- reselect_last::set(true);
- machine().manager().schedule_new_driver(drivlist.driver());
- machine().schedule_hard_reset();
- ui_menu::stack_reset(machine());
- }
-
- // otherwise, display an error
- else
- {
- reset(UI_MENU_RESET_REMEMBER_POSITION);
- ui_error = true;
- }
- }
-}
-
-//-------------------------------------------------
-// handle special key event
-//-------------------------------------------------
-
-void ui_menu_select_software::inkey_special(const ui_menu_event *m_event)
-{
- int buflen = strlen(m_search);
-
- // if it's a backspace and we can handle it, do so
- if ((m_event->unichar == 8 || m_event->unichar == 0x7f) && buflen > 0)
- {
- *(char *)utf8_previous_char(&m_search[buflen]) = 0;
- reset(UI_MENU_RESET_SELECT_FIRST);
- }
-
- // if it's any other key and we're not maxed out, update
- else if (m_event->unichar >= ' ' && m_event->unichar < 0x7f)
- {
- buflen += utf8_from_uchar(&m_search[buflen], ARRAY_LENGTH(m_search) - buflen, m_event->unichar);
- m_search[buflen] = 0;
- reset(UI_MENU_RESET_SELECT_FIRST);
- }
-}
-
-//-------------------------------------------------
-// load custom filters info from file
-//-------------------------------------------------
-
-void ui_menu_select_software::load_sw_custom_filters()
-{
- // attempt to open the output file
- emu_file file(machine().ui().options().ui_path(), OPEN_FLAG_READ);
- if (file.open("custom_", m_driver->name, "_filter.ini") == FILERR_NONE)
- {
- char buffer[MAX_CHAR_INFO];
-
- // get number of filters
- file.gets(buffer, MAX_CHAR_INFO);
- char *pb = strchr(buffer, '=');
- sw_custfltr::numother = atoi(++pb) - 1;
-
- // get main filter
- file.gets(buffer, MAX_CHAR_INFO);
- pb = strchr(buffer, '=') + 2;
-
- for (int y = 0; y < sw_filters::length; ++y)
- if (!strncmp(pb, sw_filters::text[y], strlen(sw_filters::text[y])))
- {
- sw_custfltr::main = y;
- break;
- }
-
- for (int x = 1; x <= sw_custfltr::numother; ++x)
- {
- file.gets(buffer, MAX_CHAR_INFO);
- char *cb = strchr(buffer, '=') + 2;
- for (int y = 0; y < sw_filters::length; y++)
- {
- if (!strncmp(cb, sw_filters::text[y], strlen(sw_filters::text[y])))
- {
- sw_custfltr::other[x] = y;
- if (y == UI_SW_PUBLISHERS)
- {
- file.gets(buffer, MAX_CHAR_INFO);
- char *ab = strchr(buffer, '=') + 2;
- for (size_t z = 0; z < m_filter.publisher.ui.size(); ++z)
- if (!strncmp(ab, m_filter.publisher.ui[z].c_str(), m_filter.publisher.ui[z].length()))
- sw_custfltr::mnfct[x] = z;
- }
- else if (y == UI_SW_YEARS)
- {
- file.gets(buffer, MAX_CHAR_INFO);
- char *db = strchr(buffer, '=') + 2;
- for (size_t z = 0; z < m_filter.year.ui.size(); ++z)
- if (!strncmp(db, m_filter.year.ui[z].c_str(), m_filter.year.ui[z].length()))
- sw_custfltr::year[x] = z;
- }
- else if (y == UI_SW_LIST)
- {
- file.gets(buffer, MAX_CHAR_INFO);
- char *gb = strchr(buffer, '=') + 2;
- for (size_t z = 0; z < m_filter.swlist.name.size(); ++z)
- if (!strncmp(gb, m_filter.swlist.name[z].c_str(), m_filter.swlist.name[z].length()))
- sw_custfltr::list[x] = z;
- }
- else if (y == UI_SW_TYPE)
- {
- file.gets(buffer, MAX_CHAR_INFO);
- char *fb = strchr(buffer, '=') + 2;
- for (size_t z = 0; z < m_filter.type.ui.size(); ++z)
- if (!strncmp(fb, m_filter.type.ui[z].c_str(), m_filter.type.ui[z].length()))
- sw_custfltr::type[x] = z;
- }
- else if (y == UI_SW_REGION)
- {
- file.gets(buffer, MAX_CHAR_INFO);
- char *eb = strchr(buffer, '=') + 2;
- for (size_t z = 0; z < m_filter.region.ui.size(); ++z)
- if (!strncmp(eb, m_filter.region.ui[z].c_str(), m_filter.region.ui[z].length()))
- sw_custfltr::region[x] = z;
- }
- }
- }
- }
- file.close();
- }
-}
-
-//-------------------------------------------------
-// set software regions
-//-------------------------------------------------
-
-void c_sw_region::set(std::string &str)
-{
- std::string name = getname(str);
- if (std::find(ui.begin(), ui.end(), name) != ui.end())
- return;
-
- ui.push_back(name);
-}
-
-std::string c_sw_region::getname(std::string &str)
-{
- std::string fullname(str);
- strmakelower(fullname);
- size_t found = fullname.find("(");
-
- if (found != std::string::npos)
- {
- size_t ends = fullname.find_first_not_of("abcdefghijklmnopqrstuvwxyz", found + 1);
- std::string temp(fullname.substr(found + 1, ends - found - 1));
-
- for (auto & elem : region_lists)
- if (temp == elem)
- return (str.substr(found + 1, ends - found - 1));
- }
- return std::string("<none>");
-}
-
-//-------------------------------------------------
-// set software device type
-//-------------------------------------------------
-
-void c_sw_type::set(std::string &str)
-{
- if (std::find(ui.begin(), ui.end(), str) != ui.end())
- return;
-
- ui.push_back(str);
-}
-
-//-------------------------------------------------
-// set software years
-//-------------------------------------------------
-
-void c_sw_year::set(std::string &str)
-{
- if (std::find(ui.begin(), ui.end(), str) != ui.end())
- return;
-
- ui.push_back(str);
-}
-
-//-------------------------------------------------
-// set software publishers
-//-------------------------------------------------
-
-void c_sw_publisher::set(std::string &str)
-{
- std::string name = getname(str);
- if (std::find(ui.begin(), ui.end(), name) != ui.end())
- return;
-
- ui.push_back(name);
-}
-
-std::string c_sw_publisher::getname(std::string &str)
-{
- size_t found = str.find("(");
-
- if (found != std::string::npos)
- return (str.substr(0, found - 1));
- else
- return str;
-}
-
-//-------------------------------------------------
-// build display list
-//-------------------------------------------------
-void ui_menu_select_software::build_list(std::vector<ui_software_info *> &s_drivers, const char *filter_text, int filter)
-{
-
- if (s_drivers.empty() && filter == -1)
- {
- filter = sw_filters::actual;
- s_drivers = m_sortedlist;
- }
-
- // iterate over entries
- for (auto & s_driver : s_drivers)
- {
- switch (filter)
- {
- case UI_SW_PARENTS:
- if (s_driver->parentname.empty())
- m_displaylist.push_back(s_driver);
- break;
-
- case UI_SW_CLONES:
- if (!s_driver->parentname.empty())
- m_displaylist.push_back(s_driver);
- break;
-
- case UI_SW_AVAILABLE:
- if (s_driver->available)
- m_displaylist.push_back(s_driver);
- break;
-
- case UI_SW_UNAVAILABLE:
- if (!s_driver->available)
- m_displaylist.push_back(s_driver);
- break;
-
- case UI_SW_SUPPORTED:
- if (s_driver->supported == SOFTWARE_SUPPORTED_YES)
- m_displaylist.push_back(s_driver);
- break;
-
- case UI_SW_PARTIAL_SUPPORTED:
- if (s_driver->supported == SOFTWARE_SUPPORTED_PARTIAL)
- m_displaylist.push_back(s_driver);
- break;
-
- case UI_SW_UNSUPPORTED:
- if (s_driver->supported == SOFTWARE_SUPPORTED_NO)
- m_displaylist.push_back(s_driver);
- break;
-
- case UI_SW_REGION:
- {
- std::string name = m_filter.region.getname(s_driver->longname);
-
- if(!name.empty() && name == filter_text)
- m_displaylist.push_back(s_driver);
- break;
- }
-
- case UI_SW_PUBLISHERS:
- {
- std::string name = m_filter.publisher.getname(s_driver->publisher);
-
- if(!name.empty() && name == filter_text)
- m_displaylist.push_back(s_driver);
- break;
- }
-
- case UI_SW_YEARS:
- if(s_driver->year == filter_text)
- m_displaylist.push_back(s_driver);
- break;
-
- case UI_SW_LIST:
- if(s_driver->listname == filter_text)
- m_displaylist.push_back(s_driver);
- break;
-
- case UI_SW_TYPE:
- if(s_driver->devicetype == filter_text)
- m_displaylist.push_back(s_driver);
- break;
-
- default:
- m_displaylist.push_back(s_driver);
- break;
- }
- }
-}
-
-//-------------------------------------------------
-// find approximate matches
-//-------------------------------------------------
-
-void ui_menu_select_software::find_matches(const char *str, int count)
-{
- // allocate memory to track the penalty value
- std::vector<int> penalty(count, 9999);
- int index = 0;
-
- for (; m_displaylist[index]; ++index)
- {
- // pick the best match between driver name and description
- int curpenalty = fuzzy_substring(str, m_displaylist[index]->longname);
- int tmp = fuzzy_substring(str, m_displaylist[index]->shortname);
- curpenalty = MIN(curpenalty, tmp);
-
- // insert into the sorted table of matches
- for (int matchnum = count - 1; matchnum >= 0; --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];
- m_searchlist[matchnum + 1] = m_searchlist[matchnum];
- }
-
- m_searchlist[matchnum] = m_displaylist[index];
- penalty[matchnum] = curpenalty;
- }
- }
- (index < count) ? m_searchlist[index] = nullptr : m_searchlist[count] = nullptr;
-}
-
-//-------------------------------------------------
-// build custom display list
-//-------------------------------------------------
-
-void ui_menu_select_software::build_custom()
-{
- std::vector<ui_software_info *> s_drivers;
-
- build_list(m_sortedlist, nullptr, sw_custfltr::main);
-
- for (int count = 1; count <= sw_custfltr::numother; ++count)
- {
- int filter = sw_custfltr::other[count];
- s_drivers = m_displaylist;
- m_displaylist.clear();
-
- switch (filter)
- {
- case UI_SW_YEARS:
- build_list(s_drivers, m_filter.year.ui[sw_custfltr::year[count]].c_str(), filter);
- break;
- case UI_SW_LIST:
- build_list(s_drivers, m_filter.swlist.name[sw_custfltr::list[count]].c_str(), filter);
- break;
- case UI_SW_TYPE:
- build_list(s_drivers, m_filter.type.ui[sw_custfltr::type[count]].c_str(), filter);
- break;
- case UI_SW_PUBLISHERS:
- build_list(s_drivers, m_filter.publisher.ui[sw_custfltr::mnfct[count]].c_str(), filter);
- break;
- case UI_SW_REGION:
- build_list(s_drivers, m_filter.region.ui[sw_custfltr::region[count]].c_str(), filter);
- break;
- default:
- build_list(s_drivers, nullptr, filter);
- break;
- }
- }
-}
-
-//-------------------------------------------------
-// draw left box
-//-------------------------------------------------
-
-float ui_menu_select_software::draw_left_panel(float x1, float y1, float x2, float y2)
-{
- ui_manager &mui = machine().ui();
-
- if (ui_globals::panels_status == SHOW_PANELS || ui_globals::panels_status == HIDE_RIGHT_PANEL)
- {
- float origy1 = y1;
- float origy2 = y2;
- float text_size = 0.75f;
- float l_height = mui.get_line_height();
- float line_height = l_height * text_size;
- float left_width = 0.0f;
- int text_lenght = sw_filters::length;
- int afilter = sw_filters::actual;
- int phover = HOVER_SW_FILTER_FIRST;
- const char **text = sw_filters::text;
- float sc = y2 - y1 - (2.0f * UI_BOX_TB_BORDER);
-
- if ((text_lenght * line_height) > sc)
- {
- float lm = sc / (text_lenght);
- text_size = lm / l_height;
- line_height = l_height * text_size;
- }
-
- float text_sign = mui.get_string_width_ex("_# ", text_size);
- for (int x = 0; x < text_lenght; ++x)
- {
- float total_width;
-
- // compute width of left hand side
- total_width = mui.get_string_width_ex(text[x], text_size);
- total_width += text_sign;
-
- // track the maximum
- if (total_width > left_width)
- left_width = total_width;
- }
-
- x2 = x1 + left_width + 2.0f * UI_BOX_LR_BORDER;
- //machine().ui().draw_outlined_box(container, x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
- mui.draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
-
- // take off the borders
- x1 += UI_BOX_LR_BORDER;
- x2 -= UI_BOX_LR_BORDER;
- y1 += UI_BOX_TB_BORDER;
- y2 -= UI_BOX_TB_BORDER;
-
- for (int filter = 0; filter < text_lenght; ++filter)
- {
- std::string str(text[filter]);
- rgb_t bgcolor = UI_TEXT_BG_COLOR;
- rgb_t fgcolor = UI_TEXT_COLOR;
-
- if (mouse_hit && x1 <= mouse_x && x2 > mouse_x && y1 <= mouse_y && y1 + line_height > mouse_y)
- {
- bgcolor = UI_MOUSEOVER_BG_COLOR;
- fgcolor = UI_MOUSEOVER_COLOR;
- hover = phover + filter;
- }
-
- if (afilter == filter)
- {
- bgcolor = UI_SELECTED_BG_COLOR;
- fgcolor = UI_SELECTED_COLOR;
- }
-
- if (bgcolor != UI_TEXT_BG_COLOR)
- container->add_rect(x1, y1, x2, y1 + line_height, bgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
-
- float x1t = x1 + text_sign;
- if (afilter == UI_SW_CUSTOM)
- {
- if (filter == sw_custfltr::main)
- {
- str.assign("@custom1 ").append(text[filter]);
- x1t -= text_sign;
- }
- else
- {
- for (int count = 1; count <= sw_custfltr::numother; ++count)
- {
- int cfilter = sw_custfltr::other[count];
- if (cfilter == filter)
- {
- strprintf(str, "@custom%d %s", count + 1, text[filter]);
- x1t -= text_sign;
- break;
- }
- }
- }
- convert_command_glyph(str);
- }
-
- mui.draw_text_full(container, str.c_str(), x1t, y1, x2 - x1, JUSTIFY_LEFT, WRAP_NEVER,
- DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr, text_size);
- y1 += line_height;
- }
-
- x1 = x2 + UI_BOX_LR_BORDER;
- x2 = x1 + 2.0f * UI_BOX_LR_BORDER;
- y1 = origy1;
- y2 = origy2;
- line_height = mui.get_line_height();
- float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
- rgb_t fgcolor = UI_TEXT_COLOR;
-
- // set left-right arrows dimension
- float ar_x0 = 0.5f * (x2 + x1) - 0.5f * lr_arrow_width;
- float ar_y0 = 0.5f * (y2 + y1) + 0.1f * line_height;
- float ar_x1 = ar_x0 + lr_arrow_width;
- float ar_y1 = 0.5f * (y2 + y1) + 0.9f * line_height;
-
- //machine().ui().draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
- mui.draw_outlined_box(container, x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
-
- if (mouse_hit && x1 <= mouse_x && x2 > mouse_x && y1 <= mouse_y && y2 > mouse_y)
- {
- fgcolor = UI_MOUSEOVER_COLOR;
- hover = HOVER_LPANEL_ARROW;
- }
-
- draw_arrow(container, ar_x0, ar_y0, ar_x1, ar_y1, fgcolor, ROT90 ^ ORIENTATION_FLIP_X);
- return x2 + UI_BOX_LR_BORDER;
- }
- else
- {
- float line_height = mui.get_line_height();
- float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
- rgb_t fgcolor = UI_TEXT_COLOR;
-
- // set left-right arrows dimension
- float ar_x0 = 0.5f * (x2 + x1) - 0.5f * lr_arrow_width;
- float ar_y0 = 0.5f * (y2 + y1) + 0.1f * line_height;
- float ar_x1 = ar_x0 + lr_arrow_width;
- float ar_y1 = 0.5f * (y2 + y1) + 0.9f * line_height;
-
- //machine().ui().draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
- mui.draw_outlined_box(container, x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
-
- if (mouse_hit && x1 <= mouse_x && x2 > mouse_x && y1 <= mouse_y && y2 > mouse_y)
- {
- fgcolor = UI_MOUSEOVER_COLOR;
- hover = HOVER_LPANEL_ARROW;
- }
-
- draw_arrow(container, ar_x0, ar_y0, ar_x1, ar_y1, fgcolor, ROT90);
- return x2 + UI_BOX_LR_BORDER;
- }
-}
-
-//-------------------------------------------------
-// draw infos
-//-------------------------------------------------
-
-void ui_menu_select_software::infos_render(void *selectedref, float origx1, float origy1, float origx2, float origy2)
-{
- ui_manager &mui = machine().ui();
- float line_height = mui.get_line_height();
- static std::string buffer;
- std::vector<int> xstart;
- std::vector<int> xend;
- float text_size = machine().ui().options().infos_size();
- ui_software_info *soft = (ui_software_info *)selectedref;
- static ui_software_info *oldsoft = nullptr;
- static int old_sw_view = -1;
-
- float gutter_width = 0.4f * line_height * machine().render().ui_aspect() * 1.3f;
- float ud_arrow_width = line_height * machine().render().ui_aspect();
- float oy1 = origy1 + line_height;
-
- // apply title to right panel
- if (soft && soft->usage.empty())
- {
- mui.draw_text_full(container, "History", origx1, origy1, origx2 - origx1, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
- ui_globals::cur_sw_dats_view = 0;
- }
- else
- {
- float title_size = 0.0f;
- float txt_lenght = 0.0f;
- std::string t_text[2];
- t_text[0] = "History";
- t_text[1] = "Usage";
-
- for (auto & elem : t_text)
- {
- mui.draw_text_full(container, elem.c_str(), origx1, origy1, origx2 - origx1, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &txt_lenght, nullptr);
- txt_lenght += 0.01f;
- title_size = MAX(txt_lenght, title_size);
- }
-
- mui.draw_text_full(container, t_text[ui_globals::cur_sw_dats_view].c_str(), origx1, origy1, origx2 - origx1,
- JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR,
- nullptr, nullptr);
-
- draw_common_arrow(origx1, origy1, origx2, origy2, ui_globals::cur_sw_dats_view, 0, 1, title_size);
- }
-
- if (oldsoft != soft || old_sw_view != ui_globals::cur_sw_dats_view)
- {
- buffer.clear();
- old_sw_view = ui_globals::cur_sw_dats_view;
- oldsoft = soft;
- if (ui_globals::cur_sw_dats_view == 0)
- {
- if (soft->startempty == 1)
- machine().datfile().load_data_info(soft->driver, buffer, UI_HISTORY_LOAD);
- else
- machine().datfile().load_software_info(soft->listname, buffer, soft->shortname, soft->parentname);
- }
- else
- buffer = soft->usage;
- }
-
- if (buffer.empty())
- {
- mui.draw_text_full(container, "No Infos Available", origx1, (origy2 + origy1) * 0.5f, origx2 - origx1, JUSTIFY_CENTER,
- WRAP_WORD, DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
- return;
- }
- else
- totallines = mui.wrap_text(container, buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size);
-
- int r_visible_lines = floor((origy2 - oy1) / (line_height * text_size));
- if (totallines < r_visible_lines)
- r_visible_lines = totallines;
- if (topline_datsview < 0)
- topline_datsview = 0;
- if (topline_datsview + r_visible_lines >= totallines)
- topline_datsview = totallines - r_visible_lines;
-
- for (int r = 0; r < r_visible_lines; ++r)
- {
- int itemline = r + topline_datsview;
- std::string tempbuf;
- tempbuf.assign(buffer.substr(xstart[itemline], xend[itemline] - xstart[itemline]));
-
- // up arrow
- if (r == 0 && topline_datsview != 0)
- info_arrow(0, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
- // bottom arrow
- else if (r == r_visible_lines - 1 && itemline != totallines - 1)
- info_arrow(1, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
- else
- mui.draw_text_full(container, tempbuf.c_str(), origx1 + gutter_width, oy1, origx2 - origx1,
- JUSTIFY_LEFT, WRAP_TRUNCATE, DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR,
- nullptr, nullptr, text_size);
- oy1 += (line_height * text_size);
- }
-
- // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
- right_visible_lines = r_visible_lines - (topline_datsview != 0) - (topline_datsview + r_visible_lines != totallines);
-}
-
-//-------------------------------------------------
-// perform our special rendering
-//-------------------------------------------------
-
-void ui_menu_select_software::arts_render(void *selectedref, float origx1, float origy1, float origx2, float origy2)
-{
- ui_manager &mui = machine().ui();
- float line_height = mui.get_line_height();
- static ui_software_info *oldsoft = nullptr;
- static const game_driver *olddriver = nullptr;
- const game_driver *driver = nullptr;
- ui_software_info *soft = (ui_software_info *)selectedref;
-
- if (soft && soft->startempty == 1)
- {
- driver = soft->driver;
- oldsoft = nullptr;
- }
- else
- olddriver = nullptr;
-
- if (driver)
- {
- if (ui_globals::default_image)
- ((driver->flags & MACHINE_TYPE_ARCADE) == 0) ? ui_globals::curimage_view = CABINETS_VIEW : ui_globals::curimage_view = SNAPSHOT_VIEW;
-
- std::string searchstr;
- searchstr = arts_render_common(origx1, origy1, origx2, origy2);
-
- // loads the image if necessary
- if (driver != olddriver || !snapx_bitmap->valid() || ui_globals::switch_image)
- {
- emu_file snapfile(searchstr.c_str(), OPEN_FLAG_READ);
- bitmap_argb32 *tmp_bitmap;
- tmp_bitmap = auto_alloc(machine(), bitmap_argb32);
-
- // try to load snapshot first from saved "0000.png" file
- std::string fullname(driver->name);
- render_load_png(*tmp_bitmap, snapfile, fullname.c_str(), "0000.png");
-
- if (!tmp_bitmap->valid())
- render_load_jpeg(*tmp_bitmap, snapfile, fullname.c_str(), "0000.jpg");
-
- // if fail, attemp to load from standard file
- if (!tmp_bitmap->valid())
- {
- fullname.assign(driver->name).append(".png");
- render_load_png(*tmp_bitmap, snapfile, nullptr, fullname.c_str());
-
- if (!tmp_bitmap->valid())
- {
- fullname.assign(driver->name).append(".jpg");
- render_load_jpeg(*tmp_bitmap, snapfile, nullptr, fullname.c_str());
- }
- }
-
- // if fail again, attemp to load from parent file
- if (!tmp_bitmap->valid())
- {
- // set clone status
- bool cloneof = strcmp(driver->parent, "0");
- if (cloneof)
- {
- int cx = driver_list::find(driver->parent);
- if (cx != -1 && ((driver_list::driver(cx).flags & MACHINE_IS_BIOS_ROOT) != 0))
- cloneof = false;
- }
-
- if (cloneof)
- {
- fullname.assign(driver->parent).append(".png");
- render_load_png(*tmp_bitmap, snapfile, nullptr, fullname.c_str());
-
- if (!tmp_bitmap->valid())
- {
- fullname.assign(driver->parent).append(".jpg");
- render_load_jpeg(*tmp_bitmap, snapfile, nullptr, fullname.c_str());
- }
- }
- }
-
- olddriver = driver;
- ui_globals::switch_image = false;
- arts_render_images(tmp_bitmap, origx1, origy1, origx2, origy2, false);
- auto_free(machine(), tmp_bitmap);
- }
-
- // if the image is available, loaded and valid, display it
- if (snapx_bitmap->valid())
- {
- float x1 = origx1 + 0.01f;
- float x2 = origx2 - 0.01f;
- float y1 = origy1 + UI_BOX_TB_BORDER + line_height;
- float y2 = origy2 - UI_BOX_TB_BORDER - line_height;
-
- // apply texture
- container->add_quad( x1, y1, x2, y2, ARGB_WHITE, snapx_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
- }
- }
- else if (soft)
- {
- std::string fullname, pathname;
- if (ui_globals::default_image)
- (soft->startempty == 0) ? ui_globals::curimage_view = SNAPSHOT_VIEW : ui_globals::curimage_view = CABINETS_VIEW;
-
- // arts title and searchpath
- std::string searchstr;
- searchstr = arts_render_common(origx1, origy1, origx2, origy2);
-
- // loads the image if necessary
- if (soft != oldsoft || !snapx_bitmap->valid() || ui_globals::switch_image)
- {
- emu_file snapfile(searchstr.c_str(), OPEN_FLAG_READ);
- bitmap_argb32 *tmp_bitmap;
- tmp_bitmap = auto_alloc(machine(), bitmap_argb32);
-
- if (soft->startempty == 1)
- {
- // Load driver snapshot
- fullname.assign(soft->driver->name).append(".png");
- render_load_png(*tmp_bitmap, snapfile, nullptr, fullname.c_str());
-
- if (!tmp_bitmap->valid())
- {
- fullname.assign(soft->driver->name).append(".jpg");
- render_load_jpeg(*tmp_bitmap, snapfile, nullptr, fullname.c_str());
- }
- }
- else if (ui_globals::curimage_view == TITLES_VIEW)
- {
- // First attempt from name list
- pathname.assign(soft->listname).append("_titles");
- fullname.assign(soft->shortname).append(".png");
- render_load_png(*tmp_bitmap, snapfile, pathname.c_str(), fullname.c_str());
-
- if (!tmp_bitmap->valid())
- {
- fullname.assign(soft->shortname).append(".jpg");
- render_load_jpeg(*tmp_bitmap, snapfile, pathname.c_str(), fullname.c_str());
- }
- }
- else
- {
- // First attempt from name list
- pathname = soft->listname;
- fullname.assign(soft->shortname).append(".png");
- render_load_png(*tmp_bitmap, snapfile, pathname.c_str(), fullname.c_str());
-
- if (!tmp_bitmap->valid())
- {
- fullname.assign(soft->shortname).append(".jpg");
- render_load_jpeg(*tmp_bitmap, snapfile, pathname.c_str(), fullname.c_str());
- }
-
- if (!tmp_bitmap->valid())
- {
- // Second attempt from driver name + part name
- pathname.assign(soft->driver->name).append(soft->part);
- fullname.assign(soft->shortname).append(".png");
- render_load_png(*tmp_bitmap, snapfile, pathname.c_str(), fullname.c_str());
-
- if (!tmp_bitmap->valid())
- {
- fullname.assign(soft->shortname).append(".jpg");
- render_load_jpeg(*tmp_bitmap, snapfile, pathname.c_str(), fullname.c_str());
- }
- }
- }
-
- oldsoft = soft;
- ui_globals::switch_image = false;
- arts_render_images(tmp_bitmap, origx1, origy1, origx2, origy2, true);
- auto_free(machine(), tmp_bitmap);
- }
-
- // if the image is available, loaded and valid, display it
- if (snapx_bitmap->valid())
- {
- float x1 = origx1 + 0.01f;
- float x2 = origx2 - 0.01f;
- float y1 = origy1 + UI_BOX_TB_BORDER + line_height;
- float y2 = origy2 - UI_BOX_TB_BORDER - line_height;
-
- // apply texture
- container->add_quad(x1, y1, x2, y2, ARGB_WHITE, snapx_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
- }
- }
-}
-
-void ui_menu_select_software::draw_right_panel(void *selectedref, float origx1, float origy1, float origx2, float origy2)
-{
- ui_manager &mui = machine().ui();
- float line_height = mui.get_line_height();
- float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
- rgb_t fgcolor = UI_TEXT_COLOR;
- bool hide = (ui_globals::panels_status == HIDE_RIGHT_PANEL || ui_globals::panels_status == HIDE_BOTH);
- float x2 = (hide) ? origx2 : origx1 + 2.0f * UI_BOX_LR_BORDER;
-
- // set left-right arrows dimension
- float ar_x0 = 0.5f * (x2 + origx1) - 0.5f * lr_arrow_width;
- float ar_y0 = 0.5f * (origy2 + origy1) + 0.1f * line_height;
- float ar_x1 = ar_x0 + lr_arrow_width;
- float ar_y1 = 0.5f * (origy2 + origy1) + 0.9f * line_height;
-
- //machine().ui().draw_outlined_box(container, origx1, origy1, origx2, origy2, UI_BACKGROUND_COLOR);
- mui.draw_outlined_box(container, origx1, origy1, origx2, origy2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
-
- if (mouse_hit && origx1 <= mouse_x && x2 > mouse_x && origy1 <= mouse_y && origy2 > mouse_y)
- {
- fgcolor = UI_MOUSEOVER_COLOR;
- hover = HOVER_RPANEL_ARROW;
- }
-
- if (hide)
- {
- draw_arrow(container, ar_x0, ar_y0, ar_x1, ar_y1, fgcolor, ROT90 ^ ORIENTATION_FLIP_X);
- return;
- }
-
- draw_arrow(container, ar_x0, ar_y0, ar_x1, ar_y1, fgcolor, ROT90);
- origx1 = x2;
- origy1 = draw_right_box_title(origx1, origy1, origx2, origy2);
-
- if (ui_globals::rpanel == RP_IMAGES)
- arts_render(selectedref, origx1, origy1, origx2, origy2);
- else
- infos_render(selectedref, origx1, origy1, origx2, origy2);
-}
-
-//-------------------------------------------------
-// ctor
-//-------------------------------------------------
-
-ui_software_parts::ui_software_parts(running_machine &machine, render_container *container, std::unordered_map<std::string, std::string> parts, ui_software_info *ui_info) : ui_menu(machine, container)
-{
- m_parts = parts;
- m_uiinfo = ui_info;
-}
-
-//-------------------------------------------------
-// dtor
-//-------------------------------------------------
-
-ui_software_parts::~ui_software_parts()
-{
-}
-
-//-------------------------------------------------
-// populate
-//-------------------------------------------------
-
-void ui_software_parts::populate()
-{
- for (auto & elem : m_parts)
- item_append(elem.first.c_str(), elem.second.c_str(), 0, (void *)&elem);
-
- item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr);
- customtop = machine().ui().get_line_height() + (3.0f * UI_BOX_TB_BORDER);
-}
-
-//-------------------------------------------------
-// handle
-//-------------------------------------------------
-
-void ui_software_parts::handle()
-{
- // process the menu
- const ui_menu_event *event = process(0);
- if (event != nullptr && event->iptkey == IPT_UI_SELECT && event->itemref != nullptr)
- for (auto & elem : m_parts)
- if ((void*)&elem == event->itemref)
- {
- std::string error_string;
- 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, error_string);
-
- 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, error_string);
-
- machine().manager().schedule_new_driver(*m_uiinfo->driver);
- machine().schedule_hard_reset();
- ui_menu::stack_reset(machine());
- }
-}
-
-//-------------------------------------------------
-// perform our special rendering
-//-------------------------------------------------
-
-void ui_software_parts::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
-{
- float width;
- ui_manager &mui = machine().ui();
- mui.draw_text_full(container, "Software part selection:", 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
- width += 2 * UI_BOX_LR_BORDER;
- float maxwidth = 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
- mui.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
- mui.draw_text_full(container, "Software part selection:", x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
-}
-
-//-------------------------------------------------
-// ctor
-//-------------------------------------------------
-
-ui_bios_selection::ui_bios_selection(running_machine &machine, render_container *container, std::vector<s_bios> biosname, void *_driver, bool _software, bool _inlist) : ui_menu(machine, container)
-{
- m_bios = biosname;
- m_driver = _driver;
- m_software = _software;
- m_inlist = _inlist;
-}
-
-//-------------------------------------------------
-// dtor
-//-------------------------------------------------
-
-ui_bios_selection::~ui_bios_selection()
-{
-}
-
-//-------------------------------------------------
-// populate
-//-------------------------------------------------
-
-void ui_bios_selection::populate()
-{
- for (auto & elem : m_bios)
- item_append(elem.name.c_str(), nullptr, 0, (void *)&elem.name);
-
- item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr);
- customtop = machine().ui().get_line_height() + (3.0f * UI_BOX_TB_BORDER);
-}
-
-//-------------------------------------------------
-// handle
-//-------------------------------------------------
-
-void ui_bios_selection::handle()
-{
- // process the menu
- const ui_menu_event *event = process(0);
- ui_options &moptions = machine().ui().options();
- if (event != nullptr && event->iptkey == IPT_UI_SELECT && event->itemref != nullptr)
- for (auto & elem : m_bios)
- if ((void*)&elem.name == 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);
- }
-
- std::string error;
- moptions.set_value("bios", elem.id, OPTION_PRIORITY_CMDLINE, error);
- machine().manager().schedule_new_driver(*s_driver);
- machine().schedule_hard_reset();
- ui_menu::stack_reset(machine());
- }
- else
- {
- ui_software_info *ui_swinfo = (ui_software_info *)m_driver;
- std::string error;
- machine().options().set_value("bios", elem.id, OPTION_PRIORITY_CMDLINE, error);
- 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());
- software_info *swinfo = swlist->find(ui_swinfo->shortname.c_str());
- if (!moptions.skip_parts_menu() && swinfo->has_multiple_parts(ui_swinfo->interface.c_str()))
- {
- std::unordered_map<std::string, std::string> parts;
- for (const software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next())
- {
- 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);
- }
- }
- ui_menu::stack_push(global_alloc_clear<ui_software_parts>(machine(), container, parts, ui_swinfo));
- return;
- }
- std::string error_string;
- std::string string_list = std::string(ui_swinfo->listname).append(":").append(ui_swinfo->shortname).append(":").append(ui_swinfo->part).append(":").append(ui_swinfo->instance);
- moptions.set_value(OPTION_SOFTWARENAME, string_list.c_str(), OPTION_PRIORITY_CMDLINE, error_string);
- std::string snap_list = std::string(ui_swinfo->listname).append(PATH_SEPARATOR).append(ui_swinfo->shortname);
- moptions.set_value(OPTION_SNAPNAME, snap_list.c_str(), OPTION_PRIORITY_CMDLINE, error_string);
- reselect_last::driver = drivlist.driver().name;
- reselect_last::software = ui_swinfo->shortname;
- reselect_last::swlist = ui_swinfo->listname;
- reselect_last::set(true);
- machine().manager().schedule_new_driver(drivlist.driver());
- machine().schedule_hard_reset();
- ui_menu::stack_reset(machine());
- }
- }
-}
-
-//-------------------------------------------------
-// perform our special rendering
-//-------------------------------------------------
-
-void ui_bios_selection::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
-{
- float width;
- ui_manager &mui = machine().ui();
- mui.draw_text_full(container, "Bios selection:", 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
- width += 2 * UI_BOX_LR_BORDER;
- float maxwidth = 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
- mui.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
- mui.draw_text_full(container, "Bios selection:", x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
-}