diff options
Diffstat (limited to 'src/frontend/mame/ui/devopt.cpp')
-rw-r--r-- | src/frontend/mame/ui/devopt.cpp | 519 |
1 files changed, 283 insertions, 236 deletions
diff --git a/src/frontend/mame/ui/devopt.cpp b/src/frontend/mame/ui/devopt.cpp index 178f0af8d96..fea0f5106d3 100644 --- a/src/frontend/mame/ui/devopt.cpp +++ b/src/frontend/mame/ui/devopt.cpp @@ -22,290 +22,337 @@ namespace ui { menu -------------------------------------------------*/ -menu_device_config::menu_device_config(mame_ui_manager &mui, render_container &container, device_slot_interface *slot, device_slot_interface::slot_option const *option) : menu(mui, container) +menu_device_config::menu_device_config( + mame_ui_manager &mui, + render_container &container, + device_slot_interface *slot, + device_slot_interface::slot_option const *option) + : menu_textbox(mui, container) + , m_option(option) { - m_option = option; - m_owner = slot; - m_mounted = slot->device().subdevice(option->name()) != nullptr; + m_mounted = machine().root_device().subdevice(slot->device().subtag(option->name())) != nullptr; } -void menu_device_config::populate(float &customtop, float &custombottom) +menu_device_config::~menu_device_config() +{ +} + +void menu_device_config::populate_text(std::optional<text_layout> &layout, float &width, int &lines) { - machine_config &mconfig(const_cast<machine_config &>(machine().config())); - machine_config::token const tok(mconfig.begin_configuration(mconfig.root_device())); - device_t *const dev = mconfig.device_add(m_option->name(), m_option->devtype(), 0); - for (device_t &d : device_enumerator(*dev)) - if (!d.configured()) - d.config_complete(); - - std::ostringstream str; - util::stream_format( - str, - m_mounted - ? _("[This option is currently mounted in the running system]\n\nOption: %1$s\nDevice: %2$s\n\nThe selected option enables the following items:\n") - : _("[This option is NOT currently mounted in the running system]\n\nOption: %1$s\nDevice: %2$s\n\nIf you select this option, the following items will be enabled:\n"), - m_option->name(), - dev->name()); - - // loop over all CPUs - execute_interface_enumerator execiter(*dev); - if (execiter.count() > 0) + if (!layout || (layout->width() != width)) { - str << _("* CPU:\n"); - std::unordered_set<std::string> exectags; - for (device_execute_interface &exec : execiter) + rgb_t const color = ui().colors().text_color(); + layout.emplace(ui().create_layout(container(), width)); + + machine_config &mconfig(const_cast<machine_config &>(machine().config())); + machine_config::token const tok(mconfig.begin_configuration(mconfig.root_device())); + device_t *const dev = mconfig.device_add(m_option->name(), m_option->devtype(), 0); + for (device_t &d : device_enumerator(*dev)) + if (!d.configured()) + d.config_complete(); + + layout->add_text( + util::string_format( + m_mounted + ? _("[This option is currently mounted in the running system]\n\nOption: %1$s\nDevice: %2$s\n\nThe selected option enables the following items:\n") + : _("[This option is NOT currently mounted in the running system]\n\nOption: %1$s\nDevice: %2$s\n\nIf you select this option, the following items will be enabled:\n"), + m_option->name(), + dev->name()), + color); + + // loop over all CPUs + execute_interface_enumerator execiter(*dev); + if (execiter.count() > 0) { - if (!exectags.insert(exec.device().tag()).second) - continue; + layout->add_text(_("* CPU:\n"), color); + std::unordered_set<std::string> exectags; + for (device_execute_interface &exec : execiter) + { + if (!exectags.insert(exec.device().tag()).second) + continue; - // get cpu specific clock that takes internal multiplier/dividers into account - u32 clock = exec.device().clock(); + // get cpu specific clock that takes internal multiplier/dividers into account + u32 clock = exec.device().clock(); - // count how many identical CPUs we have - int count = 1; - const char *name = exec.device().name(); - for (device_execute_interface &scan : execiter) - { - if (exec.device().type() == scan.device().type() && strcmp(name, scan.device().name()) == 0 && exec.device().clock() == scan.device().clock()) - if (exectags.insert(scan.device().tag()).second) - count++; - } + // count how many identical CPUs we have + int count = 1; + const char *name = exec.device().name(); + for (device_execute_interface &scan : execiter) + { + if (exec.device().type() == scan.device().type() && strcmp(name, scan.device().name()) == 0 && exec.device().clock() == scan.device().clock()) + if (exectags.insert(scan.device().tag()).second) + count++; + } - std::string hz(std::to_string(clock)); - int d = (clock >= 1'000'000'000) ? 9 : (clock >= 1'000'000) ? 6 : (clock >= 1000) ? 3 : 0; - if (d > 0) - { - size_t dpos = hz.length() - d; - hz.insert(dpos, "."); - size_t last = hz.find_last_not_of('0'); - hz = hz.substr(0, last + (last != dpos ? 1 : 0)); - } + std::string hz(std::to_string(clock)); + int d = (clock >= 1'000'000'000) ? 9 : (clock >= 1'000'000) ? 6 : (clock >= 1000) ? 3 : 0; + if (d > 0) + { + size_t dpos = hz.length() - d; + hz.insert(dpos, "."); + size_t last = hz.find_last_not_of('0'); + hz = hz.substr(0, last + (last != dpos ? 1 : 0)); + } - // if more than one, prepend a #x in front of the CPU name and display clock - util::stream_format(str, - (count > 1) - ? ((clock != 0) ? " %1$d" UTF8_MULTIPLY "%2$s %3$s" UTF8_NBSP "%4$s\n" : " %1$d" UTF8_MULTIPLY "%2$s\n") - : ((clock != 0) ? " %2$s %3$s" UTF8_NBSP "%4$s\n" : " %2$s\n"), - count, name, hz, - (d == 9) ? _("GHz") : (d == 6) ? _("MHz") : (d == 3) ? _("kHz") : _("Hz")); + // if more than one, prepend a #x in front of the CPU name and display clock + layout->add_text( + util::string_format( + (count > 1) + ? ((clock != 0) ? " %1$d" UTF8_MULTIPLY "%2$s %3$s" UTF8_NBSP "%4$s\n" : " %1$d" UTF8_MULTIPLY "%2$s\n") + : ((clock != 0) ? " %2$s %3$s" UTF8_NBSP "%4$s\n" : " %2$s\n"), + count, name, hz, + (d == 9) ? _("GHz") : (d == 6) ? _("MHz") : (d == 3) ? _("kHz") : _("Hz")), + color); + } } - } - // display screen information - screen_device_enumerator scriter(*dev); - if (scriter.count() > 0) - { - str << _("* Video:\n"); - for (screen_device &screen : scriter) + // display screen information + screen_device_enumerator scriter(*dev); + if (scriter.count() > 0) { - if (screen.screen_type() == SCREEN_TYPE_VECTOR) + layout->add_text(_("* Video:\n"), color); + for (screen_device &screen : scriter) { - util::stream_format(str, _(" Screen '%1$s': Vector\n"), screen.tag()); + if (screen.screen_type() == SCREEN_TYPE_VECTOR) + { + layout->add_text(util::string_format(_(" Screen '%1$s': Vector\n"), screen.tag()), color); + } + else + { + std::string hz(std::to_string(float(screen.frame_period().as_hz()))); + size_t last = hz.find_last_not_of('0'); + size_t dpos = hz.find_last_of('.'); + hz = hz.substr(0, last + (last != dpos ? 1 : 0)); + + const rectangle &visarea = screen.visible_area(); + layout->add_text( + util::string_format( + (screen.orientation() & ORIENTATION_SWAP_XY) + ? _(" Screen '%1$s': %2$d \xC3\x97 %3$d (V) %4$s\xC2\xA0Hz\n") + : _(" Screen '%1$s': %2$d \xC3\x97 %3$d (H) %4$s\xC2\xA0Hz\n"), + screen.tag(), + visarea.width(), + visarea.height(), + hz), + color); + } } - else + } + + // loop over all sound chips + sound_interface_enumerator snditer(*dev); + if (snditer.count() > 0) + { + layout->add_text(_("* Sound:\n"), color); + std::unordered_set<std::string> soundtags; + for (device_sound_interface &sound : snditer) { - std::string hz(std::to_string(float(screen.frame_period().as_hz()))); - size_t last = hz.find_last_not_of('0'); - size_t dpos = hz.find_last_of('.'); - hz = hz.substr(0, last + (last != dpos ? 1 : 0)); - - const rectangle &visarea = screen.visible_area(); - util::stream_format( - str, - (screen.orientation() & ORIENTATION_SWAP_XY) - ? _(" Screen '%1$s': %2$d \xC3\x97 %3$d (V) %4$s\xC2\xA0Hz\n") - : _(" Screen '%1$s': %2$d \xC3\x97 %3$d (H) %4$s\xC2\xA0Hz\n"), - screen.tag(), - visarea.width(), - visarea.height(), - hz); + if (!sound.issound() || !soundtags.insert(sound.device().tag()).second) + continue; + + // count how many identical sound chips we have + int count = 1; + for (device_sound_interface &scan : snditer) + { + if (sound.device().type() == scan.device().type() && sound.device().clock() == scan.device().clock()) + if (soundtags.insert(scan.device().tag()).second) + count++; + } + + const u32 clock = sound.device().clock(); + std::string hz(std::to_string(clock)); + int d = (clock >= 1'000'000'000) ? 9 : (clock >= 1'000'000) ? 6 : (clock >= 1000) ? 3 : 0; + if (d > 0) + { + size_t dpos = hz.length() - d; + hz.insert(dpos, "."); + size_t last = hz.find_last_not_of('0'); + hz = hz.substr(0, last + (last != dpos ? 1 : 0)); + } + + // if more than one, prepend a #x in front of the name and display clock + layout->add_text( + util::string_format( + (count > 1) + ? ((clock != 0) ? " %1$d" UTF8_MULTIPLY "%2$s %3$s" UTF8_NBSP "%4$s\n" : " %1$d" UTF8_MULTIPLY "%2$s\n") + : ((clock != 0) ? " %2$s %3$s" UTF8_NBSP "%4$s\n" : " %2$s\n"), + count, sound.device().name(), hz, + (d == 9) ? _("GHz") : (d == 6) ? _("MHz") : (d == 3) ? _("kHz") : _("Hz")), + color); } } - } - // loop over all sound chips - sound_interface_enumerator snditer(*dev); - if (snditer.count() > 0) - { - str << _("* Sound:\n"); - std::unordered_set<std::string> soundtags; - for (device_sound_interface &sound : snditer) + // scan for BIOS settings + int bios = 0; + if (dev->rom_region()) { - if (!sound.issound() || !soundtags.insert(sound.device().tag()).second) - continue; - - // count how many identical sound chips we have - int count = 1; - for (device_sound_interface &scan : snditer) + // first loop through roms in search of default bios (shortname) + char const *bios_str(nullptr); + for (const tiny_rom_entry *rom = dev->rom_region(); !ROMENTRY_ISEND(rom); ++rom) { - if (sound.device().type() == scan.device().type() && sound.device().clock() == scan.device().clock()) - if (soundtags.insert(scan.device().tag()).second) - count++; + if (ROMENTRY_ISDEFAULT_BIOS(rom)) + bios_str = rom->name; } - const u32 clock = sound.device().clock(); - std::string hz(std::to_string(clock)); - int d = (clock >= 1'000'000'000) ? 9 : (clock >= 1'000'000) ? 6 : (clock >= 1000) ? 3 : 0; - if (d > 0) + // then loop again to count bios options and to get the default bios complete name + char const *bios_desc(nullptr); + for (romload::system_bios const &rom : romload::entries(dev->rom_region()).get_system_bioses()) { - size_t dpos = hz.length() - d; - hz.insert(dpos, "."); - size_t last = hz.find_last_not_of('0'); - hz = hz.substr(0, last + (last != dpos ? 1 : 0)); + bios++; + if (bios_str && !std::strcmp(bios_str, rom.get_name())) + bios_desc = rom.get_description(); } - // if more than one, prepend a #x in front of the name and display clock - util::stream_format(str, - (count > 1) - ? ((clock != 0) ? " %1$d" UTF8_MULTIPLY "%2$s %3$s" UTF8_NBSP "%4$s\n" : " %1$d" UTF8_MULTIPLY "%2$s\n") - : ((clock != 0) ? " %2$s %3$s" UTF8_NBSP "%4$s\n" : " %2$s\n"), - count, sound.device().name(), hz, - (d == 9) ? _("GHz") : (d == 6) ? _("MHz") : (d == 3) ? _("kHz") : _("Hz")); - } - } - - // scan for BIOS settings - int bios = 0; - if (dev->rom_region()) - { - // first loop through roms in search of default bios (shortname) - char const *bios_str(nullptr); - for (const tiny_rom_entry *rom = dev->rom_region(); !ROMENTRY_ISEND(rom); ++rom) - { - if (ROMENTRY_ISDEFAULT_BIOS(rom)) - bios_str = rom->name; - } - - // then loop again to count bios options and to get the default bios complete name - char const *bios_desc(nullptr); - for (romload::system_bios const &rom : romload::entries(dev->rom_region()).get_system_bioses()) - { - bios++; - if (bios_str && !std::strcmp(bios_str, rom.get_name())) - bios_desc = rom.get_description(); + if (bios) + { + layout->add_text( + util::string_format( + _("* BIOS settings:\n %1$d options [default: %2$s]\n"), + bios, + bios_desc ? bios_desc : bios_str ? bios_str : ""), + color); + } } - if (bios) - util::stream_format(str, _("* BIOS settings:\n %1$d options [default: %2$s]\n"), bios, bios_desc ? bios_desc : bios_str ? bios_str : ""); - } - - int input = 0, input_mj = 0, input_hana = 0, input_gamble = 0, input_analog = 0, input_adjust = 0; - int input_keypad = 0, input_keyboard = 0, dips = 0, confs = 0; - std::string errors; - std::ostringstream dips_opt, confs_opt; - ioport_list portlist; - for (device_t &iptdev : device_enumerator(*dev)) - portlist.append(iptdev, errors); - - // check if the device adds inputs to the system - for (auto &port : portlist) - for (ioport_field &field : port.second->fields()) - { - if (field.type() >= IPT_MAHJONG_FIRST && field.type() < IPT_MAHJONG_LAST) - input_mj++; - else if (field.type() >= IPT_HANAFUDA_FIRST && field.type() < IPT_HANAFUDA_LAST) - input_hana++; - else if (field.type() >= IPT_GAMBLING_FIRST && field.type() < IPT_GAMBLING_LAST) - input_gamble++; - else if (field.type() >= IPT_ANALOG_FIRST && field.type() < IPT_ANALOG_LAST) - input_analog++; - else if (field.type() == IPT_ADJUSTER) - input_adjust++; - else if (field.type() == IPT_KEYPAD) - input_keypad++; - else if (field.type() == IPT_KEYBOARD) - input_keyboard++; - else if (field.type() >= IPT_START1 && field.type() < IPT_UI_FIRST) - input++; - else if (field.type() == IPT_DIPSWITCH) + int input = 0, input_mj = 0, input_hana = 0, input_gamble = 0, input_analog = 0, input_adjust = 0; + int input_keypad = 0, input_keyboard = 0, dips = 0, confs = 0; + std::string errors; + std::ostringstream dips_opt, confs_opt; + ioport_list portlist; + for (device_t &iptdev : device_enumerator(*dev)) + portlist.append(iptdev, errors); + + // check if the device adds inputs to the system + for (auto &port : portlist) + for (ioport_field &field : port.second->fields()) { - dips++; - bool def(false); - for (ioport_setting const &setting : field.settings()) + if (field.type() >= IPT_MAHJONG_FIRST && field.type() < IPT_MAHJONG_LAST) + input_mj++; + else if (field.type() >= IPT_HANAFUDA_FIRST && field.type() < IPT_HANAFUDA_LAST) + input_hana++; + else if (field.type() >= IPT_GAMBLING_FIRST && field.type() < IPT_GAMBLING_LAST) + input_gamble++; + else if (field.type() >= IPT_ANALOG_FIRST && field.type() < IPT_ANALOG_LAST) + input_analog++; + else if (field.type() == IPT_ADJUSTER) + input_adjust++; + else if (field.type() == IPT_KEYPAD) + input_keypad++; + else if (field.type() == IPT_KEYBOARD) + input_keyboard++; + else if (field.type() >= IPT_START1 && field.type() < IPT_UI_FIRST) + input++; + else if (field.type() == IPT_DIPSWITCH) { - if (setting.value() == field.defvalue()) + dips++; + bool def(false); + for (ioport_setting const &setting : field.settings()) { - def = true; - util::stream_format(dips_opt, _(" %1$s [default: %2$s]\n"), field.name(), setting.name()); - break; + if (setting.value() == field.defvalue()) + { + def = true; + util::stream_format(dips_opt, _(" %1$s [default: %2$s]\n"), field.name(), setting.name()); + break; + } } + if (!def) + util::stream_format(dips_opt, _(" %1$s\n"), field.name()); } - if (!def) - util::stream_format(dips_opt, _(" %1$s\n"), field.name()); - } - else if (field.type() == IPT_CONFIG) - { - confs++; - bool def(false); - for (ioport_setting const &setting : field.settings()) + else if (field.type() == IPT_CONFIG) { - if (setting.value() == field.defvalue()) + confs++; + bool def(false); + for (ioport_setting const &setting : field.settings()) { - def = true; - util::stream_format(confs_opt, _(" %1$s [default: %2$s]\n"), field.name(), setting.name()); - break; + if (setting.value() == field.defvalue()) + { + def = true; + util::stream_format(confs_opt, _(" %1$s [default: %2$s]\n"), field.name(), setting.name()); + break; + } } + if (!def) + util::stream_format(confs_opt, _(" %1$s\n"), field.name()); } - if (!def) - util::stream_format(confs_opt, _(" %1$s\n"), field.name()); } - } - if (dips) - str << _("* DIP switch settings:\n") << dips_opt.str(); - if (confs) - str << _("* Configuration settings:\n") << confs_opt.str(); - if (input || input_mj || input_hana || input_gamble || input_analog || input_adjust || input_keypad || input_keyboard) - str << _("* Input device(s):\n"); - if (input) - util::stream_format(str, _(" User inputs [%1$d inputs]\n"), input); - if (input_mj) - util::stream_format(str, _(" Mahjong inputs [%1$d inputs]\n"), input_mj); - if (input_hana) - util::stream_format(str, _(" Hanafuda inputs [%1$d inputs]\n"), input_hana); - if (input_gamble) - util::stream_format(str, _(" Gambling inputs [%1$d inputs]\n"), input_gamble); - if (input_analog) - util::stream_format(str, _(" Analog inputs [%1$d inputs]\n"), input_analog); - if (input_adjust) - util::stream_format(str, _(" Adjuster inputs [%1$d inputs]\n"), input_adjust); - if (input_keypad) - util::stream_format(str, _(" Keypad inputs [%1$d inputs]\n"), input_keypad); - if (input_keyboard) - util::stream_format(str, _(" Keyboard inputs [%1$d inputs]\n"), input_keyboard); - - image_interface_enumerator imgiter(*dev); - if (imgiter.count() > 0) - { - str << _("* Media Options:\n"); - for (const device_image_interface &imagedev : imgiter) - util::stream_format(str, _(" %1$s [tag: %2$s]\n"), imagedev.image_type_name(), imagedev.device().tag()); - } + if (dips) + { + layout->add_text(_("* DIP switch settings:\n"), color); + layout->add_text(std::move(dips_opt).str(), color); + } + if (confs) + { + layout->add_text(_("* Configuration settings:\n"), color); + layout->add_text(std::move(confs_opt).str(), color); + } + if (input || input_mj || input_hana || input_gamble || input_analog || input_adjust || input_keypad || input_keyboard) + layout->add_text(_("* Input device(s):\n"), color); + if (input) + layout->add_text(util::string_format(_(" User inputs [%1$d inputs]\n"), input), color); + if (input_mj) + layout->add_text(util::string_format(_(" Mahjong inputs [%1$d inputs]\n"), input_mj), color); + if (input_hana) + layout->add_text(util::string_format(_(" Hanafuda inputs [%1$d inputs]\n"), input_hana), color); + if (input_gamble) + layout->add_text(util::string_format(_(" Gambling inputs [%1$d inputs]\n"), input_gamble), color); + if (input_analog) + layout->add_text(util::string_format(_(" Analog inputs [%1$d inputs]\n"), input_analog), color); + if (input_adjust) + layout->add_text(util::string_format(_(" Adjuster inputs [%1$d inputs]\n"), input_adjust), color); + if (input_keypad) + layout->add_text(util::string_format(_(" Keypad inputs [%1$d inputs]\n"), input_keypad), color); + if (input_keyboard) + layout->add_text(util::string_format(_(" Keyboard inputs [%1$d inputs]\n"), input_keyboard), color); + + image_interface_enumerator imgiter(*dev); + if (imgiter.count() > 0) + { + layout->add_text(_("* Media Options:\n"), color); + for (const device_image_interface &imagedev : imgiter) + { + layout->add_text( + util::string_format( + _(" %1$s [tag: %2$s]\n"), + imagedev.image_type_name(), + imagedev.device().tag()), + color); + } + } - slot_interface_enumerator slotiter(*dev); - if (slotiter.count() > 0) - { - str << _("* Slot Options:\n"); - for (const device_slot_interface &slot : slotiter) - util::stream_format(str, _(" %1$s [default: %2$s]\n"), slot.device().tag(), slot.default_option() ? slot.default_option() : "----"); - } + slot_interface_enumerator slotiter(*dev); + if (slotiter.count() > 0) + { + layout->add_text(_("* Slot Options:\n"), color); + for (const device_slot_interface &slot : slotiter) + { + layout->add_text( + util::string_format( + _(" %1$s [default: %2$s]\n"), + slot.device().tag(), + slot.default_option() ? slot.default_option() : "----"), + color); + } + } - if ((execiter.count() + scriter.count() + snditer.count() + imgiter.count() + slotiter.count() + bios + dips + confs - + input + input_mj + input_hana + input_gamble + input_analog + input_adjust + input_keypad + input_keyboard) == 0) - str << _("[None]\n"); + if ((execiter.count() + scriter.count() + snditer.count() + imgiter.count() + slotiter.count() + bios + dips + confs + + input + input_mj + input_hana + input_gamble + input_analog + input_adjust + input_keypad + input_keyboard) == 0) + layout->add_text(_("[None]\n"), color); - mconfig.device_remove(m_option->name()); - item_append(str.str(), FLAG_MULTILINE, nullptr); + mconfig.device_remove(m_option->name()); + lines = layout->lines(); + } + width = layout->actual_width(); } -void menu_device_config::handle() +void menu_device_config::populate(float &customtop, float &custombottom) { - /* process the menu */ - process(0); } -menu_device_config::~menu_device_config() +void menu_device_config::handle(event const *ev) { + if (ev) + handle_key(ev->iptkey); } } // namespace ui |