diff options
Diffstat (limited to 'src/frontend/mame/ui/miscmenu.cpp')
-rw-r--r-- | src/frontend/mame/ui/miscmenu.cpp | 983 |
1 files changed, 983 insertions, 0 deletions
diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp new file mode 100644 index 00000000000..8ec09c4dc17 --- /dev/null +++ b/src/frontend/mame/ui/miscmenu.cpp @@ -0,0 +1,983 @@ +// license:BSD-3-Clause +// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods, Maurizio Petrarota +/********************************************************************* + + ui/miscmenu.cpp + + Internal MAME menus for the user interface. + +*********************************************************************/ + +#include "emu.h" +#include "mame.h" +#include "osdnet.h" +#include "mameopts.h" + +#include "uiinput.h" +#include "ui/ui.h" +#include "ui/menu.h" +#include "ui/miscmenu.h" +#include "ui/utils.h" +#include "../info.h" +#include "ui/inifile.h" +#include "ui/submenu.h" + +/*************************************************************************** + MENU HANDLERS +***************************************************************************/ + +/*------------------------------------------------- + ui_menu_keyboard_mode - menu that +-------------------------------------------------*/ + +ui_menu_keyboard_mode::ui_menu_keyboard_mode(running_machine &machine, render_container *container) : ui_menu(machine, container) +{ +} + +void ui_menu_keyboard_mode::populate() +{ + bool natural = mame_machine_manager::instance()->ui().use_natural_keyboard(); + item_append(_("Keyboard Mode:"), natural ? _("Natural") : _("Emulated"), natural ? MENU_FLAG_LEFT_ARROW : MENU_FLAG_RIGHT_ARROW, nullptr); +} + +ui_menu_keyboard_mode::~ui_menu_keyboard_mode() +{ +} + +void ui_menu_keyboard_mode::handle() +{ + bool natural = mame_machine_manager::instance()->ui().use_natural_keyboard(); + + /* process the menu */ + const ui_menu_event *menu_event = process(0); + + if (menu_event != nullptr) + { + if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) + { + mame_machine_manager::instance()->ui().set_use_natural_keyboard(natural ^ true); + reset(UI_MENU_RESET_REMEMBER_REF); + } + } +} + + +/*------------------------------------------------- + ui_menu_bios_selection - populates the main + bios selection menu +-------------------------------------------------*/ + +ui_menu_bios_selection::ui_menu_bios_selection(running_machine &machine, render_container *container) : ui_menu(machine, container) +{ +} + +void ui_menu_bios_selection::populate() +{ + /* cycle through all devices for this system */ + for (device_t &device : device_iterator(machine().root_device())) + { + if (device.rom_region()) + { + const char *val = "default"; + for (const rom_entry *rom = device.rom_region(); !ROMENTRY_ISEND(rom); rom++) + { + if (ROMENTRY_ISSYSTEM_BIOS(rom) && ROM_GETBIOSFLAGS(rom) == device.system_bios()) + { + val = ROM_GETHASHDATA(rom); + } + } + item_append(device.owner() == nullptr ? "driver" : device.tag()+1, val, MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW, (void *)&device); + } + } + + item_append(ui_menu_item_type::SEPARATOR); + item_append(_("Reset"), nullptr, 0, (void *)1); +} + +ui_menu_bios_selection::~ui_menu_bios_selection() +{ +} + +/*------------------------------------------------- + ui_menu_bios_selection - menu that +-------------------------------------------------*/ + +void ui_menu_bios_selection::handle() +{ + /* process the menu */ + const ui_menu_event *menu_event = process(0); + + if (menu_event != nullptr && menu_event->itemref != nullptr) + { + if ((FPTR)menu_event->itemref == 1 && menu_event->iptkey == IPT_UI_SELECT) + machine().schedule_hard_reset(); + else if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) + { + device_t *dev = (device_t *)menu_event->itemref; + int cnt = 0; + for (const rom_entry *rom = dev->rom_region(); !ROMENTRY_ISEND(rom); rom++) + { + if (ROMENTRY_ISSYSTEM_BIOS(rom)) cnt ++; + } + int val = dev->system_bios() + ((menu_event->iptkey == IPT_UI_LEFT) ? -1 : +1); + if (val<1) val=cnt; + if (val>cnt) val=1; + dev->set_system_bios(val); + if (strcmp(dev->tag(),":")==0) { + std::string error; + machine().options().set_value("bios", val-1, OPTION_PRIORITY_CMDLINE, error); + assert(error.empty()); + } else { + std::string error; + std::string value = string_format("%s,bios=%d", machine().options().main_value(dev->owner()->tag()+1), val-1); + machine().options().set_value(dev->owner()->tag()+1, value.c_str(), OPTION_PRIORITY_CMDLINE, error); + assert(error.empty()); + } + reset(UI_MENU_RESET_REMEMBER_REF); + } + } +} + + + +ui_menu_network_devices::ui_menu_network_devices(running_machine &machine, render_container *container) : ui_menu(machine, container) +{ +} + +ui_menu_network_devices::~ui_menu_network_devices() +{ +} + +/*------------------------------------------------- + menu_network_devices_populate - populates the main + network device menu +-------------------------------------------------*/ + +void ui_menu_network_devices::populate() +{ + /* cycle through all devices for this system */ + for (device_network_interface &network : network_interface_iterator(machine().root_device())) + { + int curr = network.get_interface(); + const char *title = nullptr; + const osd_netdev::entry_t *entry = netdev_first(); + while(entry) { + if(entry->id==curr) { + title = entry->description; + break; + } + entry = entry->m_next; + } + + item_append(network.device().tag(), (title) ? title : "------", MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW, (void *)network); + } +} + +/*------------------------------------------------- + ui_menu_network_devices - menu that +-------------------------------------------------*/ + +void ui_menu_network_devices::handle() +{ + /* process the menu */ + const ui_menu_event *menu_event = process(0); + + if (menu_event != nullptr && menu_event->itemref != nullptr) + { + if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) { + device_network_interface *network = (device_network_interface *)menu_event->itemref; + int curr = network->get_interface(); + if (menu_event->iptkey == IPT_UI_LEFT) curr--; else curr++; + if (curr==-2) curr = netdev_count() - 1; + network->set_interface(curr); + reset(UI_MENU_RESET_REMEMBER_REF); + } + } +} + + +/*------------------------------------------------- + menu_bookkeeping - handle the bookkeeping + information menu +-------------------------------------------------*/ + +void ui_menu_bookkeeping::handle() +{ + attotime curtime; + + /* if the time has rolled over another second, regenerate */ + curtime = machine().time(); + if (prevtime.seconds() != curtime.seconds()) + { + reset(UI_MENU_RESET_SELECT_FIRST); + prevtime = curtime; + populate(); + } + + /* process the menu */ + process(0); +} + + +/*------------------------------------------------- + menu_bookkeeping - handle the bookkeeping + information menu +-------------------------------------------------*/ +ui_menu_bookkeeping::ui_menu_bookkeeping(running_machine &machine, render_container *container) : ui_menu(machine, container) +{ +} + +ui_menu_bookkeeping::~ui_menu_bookkeeping() +{ +} + +void ui_menu_bookkeeping::populate() +{ + int tickets = machine().bookkeeping().get_dispensed_tickets(); + std::ostringstream tempstring; + int ctrnum; + + /* show total time first */ + if (prevtime.seconds() >= (60 * 60)) + util::stream_format(tempstring, _("Uptime: %1$d:%2$02d:%3$02d\n\n"), prevtime.seconds() / (60 * 60), (prevtime.seconds() / 60) % 60, prevtime.seconds() % 60); + else + util::stream_format(tempstring, _("Uptime: %1$d:%2$02d\n\n"), (prevtime.seconds() / 60) % 60, prevtime.seconds() % 60); + + /* show tickets at the top */ + if (tickets > 0) + util::stream_format(tempstring, _("Tickets dispensed: %1$d\n\n"), tickets); + + /* loop over coin counters */ + for (ctrnum = 0; ctrnum < COIN_COUNTERS; ctrnum++) + { + int count = machine().bookkeeping().coin_counter_get_count(ctrnum); + + /* display the coin counter number */ + /* display how many coins */ + /* display whether or not we are locked out */ + util::stream_format(tempstring, + (count == 0) ? _("Coin %1$c: NA%3$s\n") : _("Coin %1$c: %2$d%3$s\n"), + ctrnum + 'A', + count, + machine().bookkeeping().coin_lockout_get_state(ctrnum) ? _(" (locked)") : ""); + } + + /* append the single item */ + item_append(tempstring.str().c_str(), nullptr, MENU_FLAG_MULTILINE, nullptr); +} + +/*------------------------------------------------- + menu_crosshair - handle the crosshair settings + menu +-------------------------------------------------*/ + +void ui_menu_crosshair::handle() +{ + /* process the menu */ + const ui_menu_event *menu_event = process(UI_MENU_PROCESS_LR_REPEAT); + + /* handle events */ + if (menu_event != nullptr && menu_event->itemref != nullptr) + { + crosshair_user_settings settings; + crosshair_item_data *data = (crosshair_item_data *)menu_event->itemref; + bool changed = false; + //int set_def = false; + int newval = data->cur; + + /* retreive the user settings */ + machine().crosshair().get_user_settings(data->player, &settings); + + switch (menu_event->iptkey) + { + /* if selected, reset to default value */ + case IPT_UI_SELECT: + newval = data->defvalue; + //set_def = true; + break; + + /* left decrements */ + case IPT_UI_LEFT: + newval -= machine().input().code_pressed(KEYCODE_LSHIFT) ? 10 : 1; + break; + + /* right increments */ + case IPT_UI_RIGHT: + newval += machine().input().code_pressed(KEYCODE_LSHIFT) ? 10 : 1; + break; + } + + /* clamp to range */ + if (newval < data->min) + newval = data->min; + if (newval > data->max) + newval = data->max; + + /* if things changed, update */ + if (newval != data->cur) + { + switch (data->type) + { + /* visibility state */ + case CROSSHAIR_ITEM_VIS: + settings.mode = newval; + changed = true; + break; + + /* auto time */ + case CROSSHAIR_ITEM_AUTO_TIME: + settings.auto_time = newval; + changed = true; + break; + } + } + + /* crosshair graphic name */ + if (data->type == CROSSHAIR_ITEM_PIC) + { + switch (menu_event->iptkey) + { + case IPT_UI_SELECT: + /* clear the name string to reset to default crosshair */ + settings.name[0] = 0; + changed = true; + break; + + case IPT_UI_LEFT: + strcpy(settings.name, data->last_name); + changed = true; + break; + + case IPT_UI_RIGHT: + strcpy(settings.name, data->next_name); + changed = true; + break; + } + } + + if (changed) + { + /* save the user settings */ + machine().crosshair().set_user_settings(data->player, &settings); + + /* rebuild the menu */ + reset(UI_MENU_RESET_REMEMBER_POSITION); + } + } +} + + +/*------------------------------------------------- + menu_crosshair_populate - populate the + crosshair settings menu +-------------------------------------------------*/ + +ui_menu_crosshair::ui_menu_crosshair(running_machine &machine, render_container *container) : ui_menu(machine, container) +{ +} + +void ui_menu_crosshair::populate() +{ + crosshair_user_settings settings; + crosshair_item_data *data; + char temp_text[16]; + int player; + UINT8 use_auto = false; + UINT32 flags = 0; + + /* loop over player and add the manual items */ + for (player = 0; player < MAX_PLAYERS; player++) + { + /* get the user settings */ + machine().crosshair().get_user_settings(player, &settings); + + /* add menu items for usable crosshairs */ + if (settings.used) + { + /* Make sure to keep these matched to the CROSSHAIR_VISIBILITY_xxx types */ + static const char *const vis_text[] = { "Off", "On", "Auto" }; + + /* track if we need the auto time menu */ + if (settings.mode == CROSSHAIR_VISIBILITY_AUTO) use_auto = true; + + /* CROSSHAIR_ITEM_VIS - allocate a data item and fill it */ + data = (crosshair_item_data *)m_pool_alloc(sizeof(*data)); + data->type = CROSSHAIR_ITEM_VIS; + data->player = player; + data->min = CROSSHAIR_VISIBILITY_OFF; + data->max = CROSSHAIR_VISIBILITY_AUTO; + data->defvalue = CROSSHAIR_VISIBILITY_DEFAULT; + data->cur = settings.mode; + + /* put on arrows */ + if (data->cur > data->min) + flags |= MENU_FLAG_LEFT_ARROW; + if (data->cur < data->max) + flags |= MENU_FLAG_RIGHT_ARROW; + + /* add CROSSHAIR_ITEM_VIS menu */ + sprintf(temp_text, "P%d Visibility", player + 1); + item_append(temp_text, vis_text[settings.mode], flags, data); + + /* CROSSHAIR_ITEM_PIC - allocate a data item and fill it */ + data = (crosshair_item_data *)m_pool_alloc(sizeof(*data)); + data->type = CROSSHAIR_ITEM_PIC; + data->player = player; + data->last_name[0] = 0; + /* other data item not used by this menu */ + + /* search for crosshair graphics */ + + /* open a path to the crosshairs */ + file_enumerator path(machine().options().crosshair_path()); + const osd_directory_entry *dir; + /* reset search flags */ + bool using_default = false; + bool finished = false; + bool found = false; + + /* if we are using the default, then we just need to find the first in the list */ + if (*(settings.name) == 0) + using_default = true; + + /* look for the current name, then remember the name before */ + /* and find the next name */ + while (((dir = path.next()) != nullptr) && !finished) + { + int length = strlen(dir->name); + + /* look for files ending in .png with a name not larger then 9 chars*/ + if ((length > 4) && (length <= CROSSHAIR_PIC_NAME_LENGTH + 4) && + dir->name[length - 4] == '.' && + tolower((UINT8)dir->name[length - 3]) == 'p' && + tolower((UINT8)dir->name[length - 2]) == 'n' && + tolower((UINT8)dir->name[length - 1]) == 'g') + + { + /* remove .png from length */ + length -= 4; + + if (found || using_default) + { + /* get the next name */ + strncpy(data->next_name, dir->name, length); + data->next_name[length] = 0; + finished = true; + } + else if (!strncmp(dir->name, settings.name, length)) + { + /* we found the current name */ + /* so loop once more to find the next name */ + found = true; + } + else + /* remember last name */ + /* we will do it here in case files get added to the directory */ + { + strncpy(data->last_name, dir->name, length); + data->last_name[length] = 0; + } + } + } + /* if name not found then next item is DEFAULT */ + if (!found && !using_default) + { + data->next_name[0] = 0; + finished = true; + } + /* setup the selection flags */ + flags = 0; + if (finished) + flags |= MENU_FLAG_RIGHT_ARROW; + if (found) + flags |= MENU_FLAG_LEFT_ARROW; + + /* add CROSSHAIR_ITEM_PIC menu */ + sprintf(temp_text, "P%d Crosshair", player + 1); + item_append(temp_text, using_default ? "DEFAULT" : settings.name, flags, data); + } + } + if (use_auto) + { + /* any player can be used to get the autotime */ + machine().crosshair().get_user_settings(0, &settings); + + /* CROSSHAIR_ITEM_AUTO_TIME - allocate a data item and fill it */ + data = (crosshair_item_data *)m_pool_alloc(sizeof(*data)); + data->type = CROSSHAIR_ITEM_AUTO_TIME; + data->min = CROSSHAIR_VISIBILITY_AUTOTIME_MIN; + data->max = CROSSHAIR_VISIBILITY_AUTOTIME_MAX; + data->defvalue = CROSSHAIR_VISIBILITY_AUTOTIME_DEFAULT; + data->cur = settings.auto_time; + + /* put on arrows in visible menu */ + if (data->cur > data->min) + flags |= MENU_FLAG_LEFT_ARROW; + if (data->cur < data->max) + flags |= MENU_FLAG_RIGHT_ARROW; + + /* add CROSSHAIR_ITEM_AUTO_TIME menu */ + sprintf(temp_text, "%d", settings.auto_time); + item_append(_("Visible Delay"), temp_text, flags, data); + } +// else +// /* leave a blank filler line when not in auto time so size does not rescale */ +// item_append("", "", NULL, NULL); +} + +ui_menu_crosshair::~ui_menu_crosshair() +{ +} + +/*------------------------------------------------- + menu_quit_game - handle the "menu" for + quitting the game +-------------------------------------------------*/ + +ui_menu_quit_game::ui_menu_quit_game(running_machine &machine, render_container *container) : ui_menu(machine, container) +{ +} + +ui_menu_quit_game::~ui_menu_quit_game() +{ +} + +void ui_menu_quit_game::populate() +{ +} + +void ui_menu_quit_game::handle() +{ + /* request a reset */ + machine().schedule_exit(); + + /* reset the menu stack */ + ui_menu::stack_reset(machine()); +} + +//------------------------------------------------- +// ctor / dtor +//------------------------------------------------- + +ui_menu_export::ui_menu_export(running_machine &machine, render_container *container, std::vector<const game_driver *> drvlist) + : ui_menu(machine, container), m_list(drvlist) +{ +} + +ui_menu_export::~ui_menu_export() +{ +} + +//------------------------------------------------- +// handlethe options menu +//------------------------------------------------- + +void ui_menu_export::handle() +{ + // process the menu + ui_menu::menu_stack->parent->process(UI_MENU_PROCESS_NOINPUT); + const ui_menu_event *m_event = process(UI_MENU_PROCESS_NOIMAGE); + if (m_event != nullptr && m_event->itemref != nullptr) + { + switch ((FPTR)m_event->itemref) + { + case 1: + case 3: + { + if (m_event->iptkey == IPT_UI_SELECT) + { + std::string filename("exported"); + emu_file infile(mame_machine_manager::instance()->ui().options().ui_path(), OPEN_FLAG_READ); + if (infile.open(filename.c_str(), ".xml") == osd_file::error::NONE) + for (int seq = 0; ; ++seq) + { + std::string seqtext = string_format("%s_%04d", filename, seq); + if (infile.open(seqtext.c_str(), ".xml") != osd_file::error::NONE) + { + filename = seqtext; + break; + } + } + + // attempt to open the output file + emu_file file(mame_machine_manager::instance()->ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + if (file.open(filename.c_str(), ".xml") == osd_file::error::NONE) + { + FILE *pfile; + std::string fullpath(file.fullpath()); + file.close(); + pfile = fopen(fullpath.c_str(), "w"); + + // create the XML and save to file + driver_enumerator drvlist(machine().options()); + drvlist.exclude_all(); + for (auto & elem : m_list) + drvlist.include(driver_list::find(*elem)); + + info_xml_creator creator(drvlist); + creator.output(pfile, ((FPTR)m_event->itemref == 1) ? false : true); + fclose(pfile); + machine().popmessage(_("%s.xml saved under ui folder."), filename.c_str()); + } + } + break; + } + case 2: + { + if (m_event->iptkey == IPT_UI_SELECT) + { + std::string filename("exported"); + emu_file infile(mame_machine_manager::instance()->ui().options().ui_path(), OPEN_FLAG_READ); + if (infile.open(filename.c_str(), ".txt") == osd_file::error::NONE) + for (int seq = 0; ; ++seq) + { + std::string seqtext = string_format("%s_%04d", filename, seq); + if (infile.open(seqtext.c_str(), ".txt") != osd_file::error::NONE) + { + filename = seqtext; + break; + } + } + + // attempt to open the output file + emu_file file(mame_machine_manager::instance()->ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + if (file.open(filename.c_str(), ".txt") == osd_file::error::NONE) + { + // print the header + std::ostringstream buffer; + buffer << _("Name: Description:\n"); + driver_enumerator drvlist(machine().options()); + drvlist.exclude_all(); + for (auto & elem : m_list) + drvlist.include(driver_list::find(*elem)); + + // iterate through drivers and output the info + while (drvlist.next()) + if ((drvlist.driver().flags & MACHINE_NO_STANDALONE) == 0) + util::stream_format(buffer, "%-18s\"%s\"\n", drvlist.driver().name, drvlist.driver().description); + file.puts(buffer.str().c_str()); + file.close(); + machine().popmessage(_("%s.txt saved under ui folder."), filename.c_str()); + } + } + break; + } + default: + break; + } + } +} + +//------------------------------------------------- +// populate +//------------------------------------------------- + +void ui_menu_export::populate() +{ + // add options items + item_append(_("Export list in XML format (like -listxml)"), nullptr, 0, (void *)(FPTR)1); + item_append(_("Export list in XML format (like -listxml, but exclude devices)"), nullptr, 0, (void *)(FPTR)3); + item_append(_("Export list in TXT format (like -listfull)"), nullptr, 0, (void *)(FPTR)2); + item_append(ui_menu_item_type::SEPARATOR); +} + +//------------------------------------------------- +// ctor / dtor +//------------------------------------------------- + +ui_menu_machine_configure::ui_menu_machine_configure(running_machine &machine, render_container *container, const game_driver *prev, float _x0, float _y0) + : ui_menu(machine, container) + , m_drv(prev) + , m_opts(machine.options()) + , x0(_x0) + , y0(_y0) + , m_curbios(0) +{ + // parse the INI file + std::string error; + mame_options::parse_standard_inis(m_opts,error, m_drv); + setup_bios(); +} + +ui_menu_machine_configure::~ui_menu_machine_configure() +{ +} + +//------------------------------------------------- +// handlethe options menu +//------------------------------------------------- + +void ui_menu_machine_configure::handle() +{ + // process the menu + ui_menu::menu_stack->parent->process(UI_MENU_PROCESS_NOINPUT); + const ui_menu_event *m_event = process(UI_MENU_PROCESS_NOIMAGE, x0, y0); + if (m_event != nullptr && m_event->itemref != nullptr) + { + if (m_event->iptkey == IPT_UI_SELECT) + { + switch ((FPTR)m_event->itemref) + { + case SAVE: + { + std::string filename(m_drv->name); + emu_file file(machine().options().ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE); + osd_file::error filerr = file.open(filename.c_str(), ".ini"); + if (filerr == osd_file::error::NONE) + { + std::string inistring = m_opts.output_ini(); + file.puts(inistring.c_str()); + mame_machine_manager::instance()->ui().popup_time(2, "%s", _("\n Configuration saved \n\n")); + } + break; + } + case ADDFAV: + mame_machine_manager::instance()->favorite().add_favorite_game(m_drv); + reset(UI_MENU_RESET_REMEMBER_POSITION); + break; + + case DELFAV: + mame_machine_manager::instance()->favorite().remove_favorite_game(); + reset(UI_MENU_RESET_REMEMBER_POSITION); + break; + case CONTROLLER: + if (m_event->iptkey == IPT_UI_SELECT) + ui_menu::stack_push(global_alloc_clear<ui_submenu>(machine(), container, control_submenu_options, m_drv, &m_opts)); + break; + case VIDEO: + if (m_event->iptkey == IPT_UI_SELECT) + ui_menu::stack_push(global_alloc_clear<ui_submenu>(machine(), container, video_submenu_options, m_drv, &m_opts)); + break; + case ADVANCED: + if (m_event->iptkey == IPT_UI_SELECT) + ui_menu::stack_push(global_alloc_clear<ui_submenu>(machine(), container, advanced_submenu_options, m_drv, &m_opts)); + break; + default: + break; + } + } + else if (m_event->iptkey == IPT_UI_LEFT || m_event->iptkey == IPT_UI_RIGHT) + { + (m_event->iptkey == IPT_UI_LEFT) ? --m_curbios : ++m_curbios; + std::string error; + m_opts.set_value(OPTION_BIOS, m_bios[m_curbios].second, OPTION_PRIORITY_CMDLINE, error); + m_opts.mark_changed(OPTION_BIOS); + reset(UI_MENU_RESET_REMEMBER_POSITION); + } + } +} + +//------------------------------------------------- +// populate +//------------------------------------------------- + +void ui_menu_machine_configure::populate() +{ + // add options items + item_append(_("Bios"), nullptr, MENU_FLAG_DISABLE | MENU_FLAG_UI_HEADING, nullptr); + if (!m_bios.empty()) + { + UINT32 arrows = get_arrow_flags(0, m_bios.size() - 1, m_curbios); + item_append(_("Driver"), m_bios[m_curbios].first.c_str(), arrows, (void *)(FPTR)BIOS); + } + else + item_append(_("This machine has no bios."), nullptr, MENU_FLAG_DISABLE, nullptr); + + item_append(ui_menu_item_type::SEPARATOR); + item_append(_(advanced_submenu_options[0].description), nullptr, 0, (void *)(FPTR)ADVANCED); + item_append(_(video_submenu_options[0].description), nullptr, 0, (void *)(FPTR)VIDEO); + item_append(_(control_submenu_options[0].description), nullptr, 0, (void *)(FPTR)CONTROLLER); + item_append(ui_menu_item_type::SEPARATOR); + + if (!mame_machine_manager::instance()->favorite().isgame_favorite(m_drv)) + item_append(_("Add To Favorites"), nullptr, 0, (void *)ADDFAV); + else + item_append(_("Remove From Favorites"), nullptr, 0, (void *)DELFAV); + + item_append(ui_menu_item_type::SEPARATOR); + item_append(_("Save machine configuration"), nullptr, 0, (void *)(FPTR)SAVE); + item_append(ui_menu_item_type::SEPARATOR); + customtop = 2.0f * mame_machine_manager::instance()->ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER; +} + +//------------------------------------------------- +// perform our special rendering +//------------------------------------------------- + +void ui_menu_machine_configure::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) +{ + float width; + mame_ui_manager &mui = mame_machine_manager::instance()->ui(); + std::string text[2]; + float maxwidth = origx2 - origx1; + + text[0] = _("Configure machine:"); + text[1] = m_drv->description; + + for (auto & elem : text) + { + mui.draw_text_full(container, elem.c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_TRUNCATE, + DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr); + width += 2 * UI_BOX_LR_BORDER; + maxwidth = MAX(maxwidth, width); + } + + // compute our bounds + float x1 = 0.5f - 0.5f * maxwidth; +// float x1 = origx1; + 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 + for (auto & elem : text) + { + mui.draw_text_full(container, elem.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE, + DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); + y1 += mui.get_line_height(); + } +} + +void ui_menu_machine_configure::setup_bios() +{ + if (m_drv->rom == nullptr) + return; + + std::string specbios(m_opts.bios()); + std::string default_name; + for (const rom_entry *rom = m_drv->rom; !ROMENTRY_ISEND(rom); ++rom) + if (ROMENTRY_ISDEFAULT_BIOS(rom)) + default_name = ROM_GETNAME(rom); + + int bios_count = 0; + for (const rom_entry *rom = m_drv->rom; !ROMENTRY_ISEND(rom); ++rom) + { + if (ROMENTRY_ISSYSTEM_BIOS(rom)) + { + std::string name(ROM_GETHASHDATA(rom)); + std::string biosname(ROM_GETNAME(rom)); + int bios_flags = ROM_GETBIOSFLAGS(rom); + std::string bios_number = std::to_string(bios_flags - 1); + + // check biosnumber and name + if (bios_number == specbios || biosname == specbios) + m_curbios = bios_count; + + if (biosname == default_name) + { + name.append(_(" (default)")); + if (specbios == "default") + m_curbios = bios_count; + } + + m_bios.emplace_back(name, bios_flags - 1); + bios_count++; + } + } + +} + +//------------------------------------------------- +// ctor / dtor +//------------------------------------------------- + +ui_menu_plugins_configure::ui_menu_plugins_configure(running_machine &machine, render_container *container) + : ui_menu(machine, container) +{ +} + +ui_menu_plugins_configure::~ui_menu_plugins_configure() +{ + emu_file file_plugin(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + if (file_plugin.open("plugin.ini") != osd_file::error::NONE) + throw emu_fatalerror("Unable to create file plugin.ini\n"); + // generate the updated INI + file_plugin.puts(mame_machine_manager::instance()->plugins().output_ini().c_str()); +} + +//------------------------------------------------- +// handlethe options menu +//------------------------------------------------- + +void ui_menu_plugins_configure::handle() +{ + // process the menu + bool changed = false; + plugin_options& plugins = mame_machine_manager::instance()->plugins(); + ui_menu::menu_stack->parent->process(UI_MENU_PROCESS_NOINPUT); + const ui_menu_event *m_event = process(UI_MENU_PROCESS_NOIMAGE); + if (m_event != nullptr && m_event->itemref != nullptr) + { + if (m_event->iptkey == IPT_UI_LEFT || m_event->iptkey == IPT_UI_RIGHT || m_event->iptkey == IPT_UI_SELECT) + { + int oldval = plugins.int_value((const char*)m_event->itemref); + std::string error_string; + plugins.set_value((const char*)m_event->itemref, oldval == 1 ? 0 : 1, OPTION_PRIORITY_CMDLINE, error_string); + changed = true; + } + } + if (changed) + reset(UI_MENU_RESET_REMEMBER_REF); +} + +//------------------------------------------------- +// populate +//------------------------------------------------- + +void ui_menu_plugins_configure::populate() +{ + plugin_options& plugins = mame_machine_manager::instance()->plugins(); + + for (auto &curentry : plugins) + { + if (!curentry.is_header()) + { + auto enabled = std::string(curentry.value()) == "1"; + item_append(curentry.description(), enabled ? _("On") : _("Off"), + enabled ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)(FPTR)curentry.name()); + } + } + item_append(ui_menu_item_type::SEPARATOR); + customtop = mame_machine_manager::instance()->ui().get_line_height() + (3.0f * UI_BOX_TB_BORDER); +} + +//------------------------------------------------- +// perform our special rendering +//------------------------------------------------- + +void ui_menu_plugins_configure::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) +{ + float width; + mame_ui_manager &mui = mame_machine_manager::instance()->ui(); + + mui.draw_text_full(container, _("Plugins"), 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, _("Plugins"), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE, + DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); +} |