diff options
Diffstat (limited to 'src')
27 files changed, 532 insertions, 372 deletions
diff --git a/src/devices/bus/centronics/epson_lx800.cpp b/src/devices/bus/centronics/epson_lx800.cpp index 0ef9b942f53..3733c92cb2b 100644 --- a/src/devices/bus/centronics/epson_lx800.cpp +++ b/src/devices/bus/centronics/epson_lx800.cpp @@ -16,7 +16,9 @@ #include "emu.h" #include "epson_lx800.h" + #include "speaker.h" + #include "lx800.lh" @@ -114,54 +116,44 @@ INPUT_PORTS_START( epson_lx800 ) PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Line Feed") PORT_CODE(KEYCODE_L) PORT_START("DIPSW1") - PORT_DIPNAME(0x01, 0x00, "Typeface") - PORT_DIPLOCATION("DIP:8") - PORT_DIPSETTING(0x01, "Condensed") - PORT_DIPSETTING(0x00, DEF_STR(Normal)) - PORT_DIPNAME(0x02, 0x00, "ZERO font") - PORT_DIPLOCATION("DIP:7") - PORT_DIPSETTING(0x02, "0") - PORT_DIPSETTING(0x00, "0") - PORT_DIPNAME(0x04, 0x00, "Character Table") - PORT_DIPLOCATION("DIP:6") - PORT_DIPSETTING(0x04, "Graphic") - PORT_DIPSETTING(0x00, "Italic") - PORT_DIPNAME(0x08, 0x00, "Paper-out detection") - PORT_DIPLOCATION("DIP:5") - PORT_DIPSETTING(0x08, "Valid") - PORT_DIPSETTING(0x00, "Invalid") - PORT_DIPNAME(0x10, 0x00, "Printing quality") - PORT_DIPLOCATION("DIP:4") - PORT_DIPSETTING(0x10, "NLQ") - PORT_DIPSETTING(0x00, "Draft") - PORT_DIPNAME(0xe0, 0xe0, "International character set") - PORT_DIPLOCATION("DIP:3,2,1") - PORT_DIPSETTING(0xe0, "U.S.A.") - PORT_DIPSETTING(0x60, "France") - PORT_DIPSETTING(0xa0, "Germany") - PORT_DIPSETTING(0x20, "U.K.") - PORT_DIPSETTING(0xc0, "Denmark") - PORT_DIPSETTING(0x40, "Sweden") - PORT_DIPSETTING(0x80, "Italy") - PORT_DIPSETTING(0x00, "Spain") + PORT_DIPNAME(0x01, 0x00, "Typeface") PORT_DIPLOCATION("SW 1:!1") + PORT_DIPSETTING( 0x00, "Normal") + PORT_DIPSETTING( 0x01, "Condensed") + PORT_DIPNAME(0x02, 0x00, "Shape of zero") PORT_DIPLOCATION("SW 1:!2") + PORT_DIPSETTING( 0x00, "Not slashed") + PORT_DIPSETTING( 0x02, "Slashed") + PORT_DIPNAME(0x04, 0x00, "Character table") PORT_DIPLOCATION("SW 1:!3") + PORT_DIPSETTING( 0x00, "Italics") + PORT_DIPSETTING( 0x04, "Graphics") + PORT_DIPNAME(0x08, 0x00, "Paper-out detection") PORT_DIPLOCATION("SW 1:!4") + PORT_DIPSETTING( 0x00, "Invalid") + PORT_DIPSETTING( 0x08, "Valid") + PORT_DIPNAME(0x10, 0x00, "Printing quality") PORT_DIPLOCATION("SW 1:!5") + PORT_DIPSETTING( 0x00, "Draft") + PORT_DIPSETTING( 0x10, "NLQ") + PORT_DIPNAME(0xe0, 0xe0, "International character set") PORT_DIPLOCATION("SW 1:!6,!7,!8") + PORT_DIPSETTING( 0xe0, "USA") + PORT_DIPSETTING( 0x60, "France") + PORT_DIPSETTING( 0xa0, "Germany") + PORT_DIPSETTING( 0x20, "UK") + PORT_DIPSETTING( 0xc0, "Denmark") + PORT_DIPSETTING( 0x40, "Sweden") + PORT_DIPSETTING( 0x80, "Italy") + PORT_DIPSETTING( 0x00, "Spain") PORT_START("DIPSW2") - PORT_DIPNAME(0x01, 0x00, "Page length") - PORT_DIPLOCATION("DIP:4") - PORT_DIPSETTING(0x01, "12\"") - PORT_DIPSETTING(0x00, "11\"") - PORT_DIPNAME(0x02, 0x00, "Cut sheet feeder mode") - PORT_DIPLOCATION("DIP:3") - PORT_DIPSETTING(0x02, "Valid") - PORT_DIPSETTING(0x00, "Invalid") - PORT_DIPNAME(0x04, 0x00, "1\" skip over perforation") - PORT_DIPLOCATION("DIP:2") - PORT_DIPSETTING(0x04, "Valid") - PORT_DIPSETTING(0x00, "Invalid") - PORT_DIPNAME(0x08, 0x00, "AUTO FEED XT control") - PORT_DIPLOCATION("DIP:1") - PORT_DIPSETTING(0x08, "Fix to LOW") - PORT_DIPSETTING(0x00, "Depends on external signal") + PORT_DIPNAME(0x01, 0x00, "Page length") PORT_DIPLOCATION("SW 2:!1") + PORT_DIPSETTING( 0x00, "11\"") + PORT_DIPSETTING( 0x01, "12\"") + PORT_DIPNAME(0x02, 0x00, "Cut-sheet feeder mode") PORT_DIPLOCATION("SW 2:!2") + PORT_DIPSETTING( 0x00, DEF_STR(Off)) + PORT_DIPSETTING( 0x02, DEF_STR(On)) + PORT_DIPNAME(0x04, 0x00, "Skip over perforation") PORT_DIPLOCATION("SW 2:!3") + PORT_DIPSETTING( 0x00, DEF_STR(Off)) + PORT_DIPSETTING( 0x04, "1\"") + PORT_DIPNAME(0x08, 0x00, "Auto line feed") PORT_DIPLOCATION("SW 2:!4") + PORT_DIPSETTING( 0x00, DEF_STR(Off)) // controlled by /AUTO FEED XT signal (Centronics pin 14) + PORT_DIPSETTING( 0x08, DEF_STR(On)) INPUT_PORTS_END diff --git a/src/devices/bus/centronics/epson_lx810l.cpp b/src/devices/bus/centronics/epson_lx810l.cpp index 21c6510ec95..ad901edb5b5 100644 --- a/src/devices/bus/centronics/epson_lx810l.cpp +++ b/src/devices/bus/centronics/epson_lx810l.cpp @@ -177,8 +177,7 @@ void epson_lx810l_device::device_add_mconfig(machine_config &config) INPUT PORTS ***************************************************************************/ -static INPUT_PORTS_START( epson_lx810l ) - +static INPUT_PORTS_START( epson_lx810 ) /* Buttons on printer */ PORT_START("ONLINE") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("On Line") PORT_CODE(KEYCODE_0_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, epson_lx810l_device, online_sw, 0) @@ -193,76 +192,75 @@ static INPUT_PORTS_START( epson_lx810l ) PORT_START("RESET") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Reset Printer") PORT_CODE(KEYCODE_2_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, epson_lx810l_device, reset_printer, 0) - - /* DIPSW1 */ PORT_START("DIPSW1") + PORT_DIPNAME(0x01, 0x00, "Character spacing") PORT_DIPLOCATION("SW 1:!1") + PORT_DIPSETTING( 0x00, "10 cpi") + PORT_DIPSETTING( 0x01, "12 cpi") + PORT_DIPNAME(0x02, 0x00, "Shape of zero") PORT_DIPLOCATION("SW 1:!2") + PORT_DIPSETTING( 0x00, "Not slashed") + PORT_DIPSETTING( 0x02, "Slashed") + PORT_DIPNAME(0x04, 0x00, "Character table") PORT_DIPLOCATION("SW 1:!3") + PORT_DIPSETTING( 0x00, "Italics") + PORT_DIPSETTING( 0x04, "Graphics") + PORT_DIPNAME(0x08, 0x08, "Short tear-off") PORT_DIPLOCATION("SW 1:!4") + PORT_DIPSETTING( 0x08, DEF_STR(Off)) + PORT_DIPSETTING( 0x00, DEF_STR(On)) + PORT_DIPNAME(0x10, 0x00, "Draft printing speed") PORT_DIPLOCATION("SW 1:!6") + PORT_DIPSETTING( 0x10, DEF_STR(Normal)) + PORT_DIPSETTING( 0x00, "High speed") + PORT_DIPNAME(0xe0, 0xe0, "International character set") PORT_DIPLOCATION("SW 1:!6,!7,!8") + PORT_DIPSETTING( 0xe0, "USA (PC 437)") + PORT_DIPSETTING( 0x60, "France (PC 850)") + PORT_DIPSETTING( 0xa0, "Germany (PC 860)") + PORT_DIPSETTING( 0x20, "UK (PC 863)") + PORT_DIPSETTING( 0xc0, "Denmark (PC 865)") + PORT_DIPSETTING( 0x40, "Sweden (PC 437)") + PORT_DIPSETTING( 0x80, "Italy (PC 437)") + PORT_DIPSETTING( 0x00, "Spain (PC 437)") - PORT_DIPNAME(0x01, 0x01, "Character spacing") - PORT_DIPLOCATION("DIP:1") - PORT_DIPSETTING(0x01, "12 cpi") /* default */ - PORT_DIPSETTING(0x00, "10 cpi") - - PORT_DIPNAME(0x02, 0x00, "Shape of zero") - PORT_DIPLOCATION("DIP:2") - PORT_DIPSETTING(0x02, "Slashed") - PORT_DIPSETTING(0x00, "Not slashed") /* default */ - - PORT_DIPNAME(0x0c, 0x08, "Page length") - PORT_DIPLOCATION("DIP:3,4") - PORT_DIPSETTING(0x00, "11 inches") - PORT_DIPSETTING(0x04, "12 inches") - PORT_DIPSETTING(0x08, "8.5 inches") /* default */ - PORT_DIPSETTING(0x0c, "11.7 inches") - - PORT_DIPNAME(0x10, 0x10, "Character table") - PORT_DIPLOCATION("DIP:5") - PORT_DIPSETTING(0x10, "Graphics") /* default */ - PORT_DIPSETTING(0x00, "Italics") - - PORT_DIPNAME(0xe0, 0xe0, "International characters and PC selection") - PORT_DIPLOCATION("DIP:6,7,8") - PORT_DIPSETTING(0xe0, "United States") /* default */ - PORT_DIPSETTING(0x60, "France") - PORT_DIPSETTING(0xa0, "Germany") - PORT_DIPSETTING(0x20, "United Kingdom") - PORT_DIPSETTING(0xc0, "Denmark") - PORT_DIPSETTING(0x40, "Sweden") - PORT_DIPSETTING(0x80, "Italy") - PORT_DIPSETTING(0x00, "Spain") - - /* DIPSW2 */ PORT_START("DIPSW2") + PORT_DIPNAME(0x01, 0x00, "Page length") PORT_DIPLOCATION("SW 2:!1") + PORT_DIPSETTING( 0x00, "11\"") + PORT_DIPSETTING( 0x01, "12\"") + PORT_DIPNAME(0x02, 0x00, "Cut-sheet feeder mode") PORT_DIPLOCATION("SW 2:!2") + PORT_DIPSETTING( 0x00, DEF_STR(Off)) + PORT_DIPSETTING( 0x02, DEF_STR(On)) + PORT_DIPNAME(0x04, 0x00, "Skip over perforation") PORT_DIPLOCATION("SW 2:!3") + PORT_DIPSETTING( 0x00, DEF_STR(Off)) + PORT_DIPSETTING( 0x04, "1\"") + PORT_DIPNAME(0x08, 0x00, "Auto line feed") PORT_DIPLOCATION("SW 2:!4") + PORT_DIPSETTING( 0x00, DEF_STR(Off)) + PORT_DIPSETTING( 0x08, DEF_STR(On)) +INPUT_PORTS_END - PORT_DIPNAME(0x01, 0x01, "Short tear-off") - PORT_DIPLOCATION("DIP:1") - PORT_DIPSETTING(0x01, "Invalid") /* default */ - PORT_DIPSETTING(0x00, "Valid") - - PORT_DIPNAME(0x02, 0x00, "Cut-sheet feeder mode") - PORT_DIPLOCATION("DIP:2") - PORT_DIPSETTING(0x02, "ON") - PORT_DIPSETTING(0x00, "OFF") /* default */ - - PORT_DIPNAME(0x04, 0x00, "Skip-over-perforation") - PORT_DIPLOCATION("DIP:3") - PORT_DIPSETTING(0x04, "ON") - PORT_DIPSETTING(0x00, "OFF") /* default */ - - PORT_DIPNAME(0x08, 0x00, "Auto line feed") - PORT_DIPLOCATION("DIP:4") - PORT_DIPSETTING(0x08, "ON") - PORT_DIPSETTING(0x00, "OFF") /* default */ - +static INPUT_PORTS_START( epson_lx810l ) + PORT_INCLUDE(epson_lx810) + + PORT_MODIFY("DIPSW1") + PORT_DIPNAME(0x0c, 0x00, "Page length") PORT_DIPLOCATION("SW 1:!3,!4") + PORT_DIPSETTING( 0x08, "8.5\"") + PORT_DIPSETTING( 0x00, "11\"") + PORT_DIPSETTING( 0x0c, "11.7\" (A4)") + PORT_DIPSETTING( 0x04, "12\"") + PORT_DIPNAME(0x10, 0x00, "Character table") PORT_DIPLOCATION("SW 1:!5") + PORT_DIPSETTING( 0x00, "Italics") + PORT_DIPSETTING( 0x10, "Graphics") + + PORT_MODIFY("DIPSW2") + PORT_DIPNAME(0x01, 0x01, "Short tear-off") PORT_DIPLOCATION("SW 2:!1") + PORT_DIPSETTING( 0x01, "Invalid") + PORT_DIPSETTING( 0x00, "Valid") INPUT_PORTS_END + //------------------------------------------------- // input_ports - device-specific input ports //------------------------------------------------- ioport_constructor epson_lx810l_device::device_input_ports() const { - return INPUT_PORTS_NAME( epson_lx810l ); + return INPUT_PORTS_NAME(epson_lx810l); } INPUT_CHANGED_MEMBER(epson_lx810l_device::online_sw) diff --git a/src/emu/input.cpp b/src/emu/input.cpp index b58958a6935..c8959349b88 100644 --- a/src/emu/input.cpp +++ b/src/emu/input.cpp @@ -97,6 +97,7 @@ static const code_string_table devclass_string_table[] = // token strings for item modifiers static const code_string_table modifier_token_table[] = { + { ITEM_MODIFIER_REVERSE, "REVERSE" }, { ITEM_MODIFIER_POS, "POS" }, { ITEM_MODIFIER_NEG, "NEG" }, { ITEM_MODIFIER_LEFT, "LEFT" }, @@ -109,6 +110,7 @@ static const code_string_table modifier_token_table[] = // friendly strings for item modifiers static const code_string_table modifier_string_table[] = { + { ITEM_MODIFIER_REVERSE, "Reverse" }, { ITEM_MODIFIER_POS, "+" }, { ITEM_MODIFIER_NEG, "-" }, { ITEM_MODIFIER_LEFT, "Left" }, @@ -632,21 +634,21 @@ s32 input_manager::code_value(input_code code) // process items according to their native type switch (targetclass) { - case ITEM_CLASS_ABSOLUTE: - if (result == 0) - result = item->read_as_absolute(code.item_modifier()); - break; + case ITEM_CLASS_ABSOLUTE: + if (result == 0) + result = item->read_as_absolute(code.item_modifier()); + break; - case ITEM_CLASS_RELATIVE: - result += item->read_as_relative(code.item_modifier()); - break; + case ITEM_CLASS_RELATIVE: + result += item->read_as_relative(code.item_modifier()); + break; - case ITEM_CLASS_SWITCH: - result |= item->read_as_switch(code.item_modifier()); - break; + case ITEM_CLASS_SWITCH: + result |= item->read_as_switch(code.item_modifier()); + break; - default: - break; + default: + break; } } } while (0); @@ -1054,38 +1056,40 @@ s32 input_manager::seq_axis_value(const input_seq &seq, input_item_class &itemcl bool enable = true; for (int codenum = 0; ; codenum++) { - // handle NOT input_code code = seq[codenum]; if (code == input_seq::not_code) + { + // handle NOT invert = true; - - // handle OR and END - else if (code == input_seq::or_code || code == input_seq::end_code) + } + else if (code == input_seq::end_code) { - // if we have a positive result from the previous set, we're done - if (itemclass != ITEM_CLASS_INVALID || code == input_seq::end_code) - break; + // handle END + break; + } + else if (code == input_seq::or_code) + { + // handle OR - // otherwise, reset our state - result = 0; + // reset invert and enable for the next group invert = false; enable = true; } - - // handle everything else only if we're still enabled else if (enable) { + // handle everything else only if we're still enabled + // switch codes serve as enables if (code.item_class() == ITEM_CLASS_SWITCH) { // AND against previous digital codes if (enable) - enable &= code_pressed(code) ^ invert; + enable = code_pressed(code) ^ invert; + // FIXME: need to clear current group value if enable became false } - - // non-switch codes are analog values else { + // non-switch codes are analog values s32 value = code_value(code); // if we got a 0 value, don't do anything except remember the first type @@ -1094,19 +1098,23 @@ s32 input_manager::seq_axis_value(const input_seq &seq, input_item_class &itemcl if (itemclasszero == ITEM_CLASS_INVALID) itemclasszero = code.item_class(); } - - // non-zero absolute values stick else if (code.item_class() == ITEM_CLASS_ABSOLUTE) { + // non-zero absolute values override relative values + if (itemclass == ITEM_CLASS_ABSOLUTE) + result += value; + else + result = value; itemclass = ITEM_CLASS_ABSOLUTE; - result = value; } - - // non-zero relative values accumulate else if (code.item_class() == ITEM_CLASS_RELATIVE) { - itemclass = ITEM_CLASS_RELATIVE; - result += value; + // non-zero relative values accumulate in the absence of absolute values + if (itemclass != ITEM_CLASS_ABSOLUTE) + { + result += value; + itemclass = ITEM_CLASS_RELATIVE; + } } } @@ -1115,6 +1123,10 @@ s32 input_manager::seq_axis_value(const input_seq &seq, input_item_class &itemcl } } + // saturate mixed absolute values + if (itemclass == ITEM_CLASS_ABSOLUTE) + result = std::clamp(result, INPUT_ABSOLUTE_MIN, INPUT_ABSOLUTE_MAX); + // if the caller wants to know the type, provide it if (result == 0) itemclass = itemclasszero; diff --git a/src/emu/input.h b/src/emu/input.h index 89b643edfff..7bc03c13831 100644 --- a/src/emu/input.h +++ b/src/emu/input.h @@ -75,6 +75,7 @@ enum input_item_class enum input_item_modifier { ITEM_MODIFIER_NONE, + ITEM_MODIFIER_REVERSE, ITEM_MODIFIER_POS, ITEM_MODIFIER_NEG, ITEM_MODIFIER_LEFT, diff --git a/src/emu/inputdev.cpp b/src/emu/inputdev.cpp index e22549519e9..436f83cf0df 100644 --- a/src/emu/inputdev.cpp +++ b/src/emu/inputdev.cpp @@ -840,13 +840,20 @@ input_device_relative_item::input_device_relative_item(input_device &device, std s32 input_device_relative_item::read_as_switch(input_item_modifier modifier) { // process according to modifiers - if (modifier == ITEM_MODIFIER_POS || modifier == ITEM_MODIFIER_RIGHT || modifier == ITEM_MODIFIER_DOWN) - return (update_value() > 0); - else if (modifier == ITEM_MODIFIER_NEG || modifier == ITEM_MODIFIER_LEFT || modifier == ITEM_MODIFIER_UP) - return (update_value() < 0); - + switch (modifier) + { + case ITEM_MODIFIER_POS: + case ITEM_MODIFIER_RIGHT: + case ITEM_MODIFIER_DOWN: + return update_value() > 0; + case ITEM_MODIFIER_NEG: + case ITEM_MODIFIER_LEFT: + case ITEM_MODIFIER_UP: + return update_value() < 0; // all other cases just return 0 - return 0; + default: + return 0; + } } @@ -858,7 +865,10 @@ s32 input_device_relative_item::read_as_switch(input_item_modifier modifier) s32 input_device_relative_item::read_as_relative(input_item_modifier modifier) { // just return directly - return update_value(); + if (ITEM_MODIFIER_REVERSE == modifier) + return -update_value(); + else + return update_value(); } @@ -979,9 +989,11 @@ s32 input_device_absolute_item::read_as_absolute(input_item_modifier modifier) } // positive/negative: scale to full axis - if (modifier == ITEM_MODIFIER_POS) + if (modifier == ITEM_MODIFIER_REVERSE) + result = -result; + else if (modifier == ITEM_MODIFIER_POS) result = std::max(result, 0) * 2 + INPUT_ABSOLUTE_MIN; - if (modifier == ITEM_MODIFIER_NEG) + else if (modifier == ITEM_MODIFIER_NEG) result = std::max(-result, 0) * 2 + INPUT_ABSOLUTE_MIN; return result; } diff --git a/src/frontend/mame/iptseqpoll.cpp b/src/frontend/mame/iptseqpoll.cpp index 639295f7e02..9c4782f4c54 100644 --- a/src/frontend/mame/iptseqpoll.cpp +++ b/src/frontend/mame/iptseqpoll.cpp @@ -12,7 +12,8 @@ input_code_poller::input_code_poller(input_manager &manager) noexcept : m_manager(manager), - m_axis_memory() + m_axis_memory(), + m_switch_memory() { } @@ -26,6 +27,7 @@ void input_code_poller::reset() { // iterate over device classes and devices m_axis_memory.clear(); + m_switch_memory.clear(); for (input_device_class classno = DEVICE_CLASS_FIRST_VALID; DEVICE_CLASS_LAST_VALID >= classno; ++classno) { input_class &devclass(m_manager.device_class(classno)); @@ -53,22 +55,7 @@ void input_code_poller::reset() } - -switch_code_poller_base::switch_code_poller_base(input_manager &manager) noexcept : - input_code_poller(manager), - m_switch_memory() -{ -} - - -void switch_code_poller_base::reset() -{ - m_switch_memory.clear(); - input_code_poller::reset(); -} - - -bool switch_code_poller_base::code_pressed_once(input_code code, bool moved) +bool input_code_poller::code_pressed_once(input_code code, bool moved) { // look for the code in the memory bool const pressed(m_manager.code_pressed(code)); @@ -105,14 +92,50 @@ input_code axis_code_poller::poll() // iterate over the axis items we found for (auto memory = m_axis_memory.begin(); m_axis_memory.end() != memory; ++memory) { - input_code const code = memory->first->code(); + input_code code = memory->first->code(); if (memory->first->check_axis(code.item_modifier(), memory->second)) { m_axis_memory.erase(memory); + if (!m_manager.device_class(memory->first->device().devclass()).multi()) + code.set_device_index(0); return code; } } + // iterate over device classes and devices, skipping disabled classes + for (input_device_class classno = DEVICE_CLASS_FIRST_VALID; DEVICE_CLASS_LAST_VALID >= classno; ++classno) + { + input_class &devclass(m_manager.device_class(classno)); + if (!devclass.enabled()) + continue; + + for (int devnum = 0; devclass.maxindex() >= devnum; ++devnum) + { + // fetch the device; ignore if nullptr + input_device *const device(devclass.device(devnum)); + if (!device) + continue; + + // iterate over items within each device + for (input_item_id itemid = ITEM_ID_FIRST_VALID; device->maxitem() >= itemid; ++itemid) + { + input_device_item *const item(device->item(itemid)); + if (!item) + continue; + + input_code code = item->code(); + if (item->itemclass() == ITEM_CLASS_SWITCH) + { + // item is natively a switch, poll it + if (code_pressed_once(code, true)) + return code; + else + continue; + } + } + } + } + // if nothing, return an invalid code return INPUT_CODE_INVALID; } @@ -120,7 +143,7 @@ input_code axis_code_poller::poll() switch_code_poller::switch_code_poller(input_manager &manager) noexcept : - switch_code_poller_base(manager) + input_code_poller(manager) { } @@ -210,7 +233,7 @@ input_code switch_code_poller::poll() keyboard_code_poller::keyboard_code_poller(input_manager &manager) noexcept : - switch_code_poller_base(manager) + input_code_poller(manager) { } @@ -336,42 +359,93 @@ input_code axis_sequence_poller::do_poll() lastcode = m_sequence[curlen - 2]; input_code newcode = m_code_poller.poll(); - // if the last code doesn't match absolute/relative of this code, ignore the new one - input_item_class const lastclass = lastcode.item_class(); - input_item_class const newclass = newcode.item_class(); - if (((ITEM_CLASS_ABSOLUTE == lastclass) && (ITEM_CLASS_ABSOLUTE != newclass)) || - ((ITEM_CLASS_RELATIVE == lastclass) && (ITEM_CLASS_RELATIVE != newclass))) - newcode = INPUT_CODE_INVALID; - - // if the new code is valid, check for half-axis toggles on absolute controls - if ((INPUT_CODE_INVALID != newcode) && curlen && (ITEM_CLASS_ABSOLUTE == newclass)) + // if not empty, see if it's the same control again to cycle modifiers + if ((INPUT_CODE_INVALID != newcode) && curlen) { + input_item_class const newclass = newcode.item_class(); input_code last_nomodifier = lastcode; last_nomodifier.set_item_modifier(ITEM_MODIFIER_NONE); if (newcode == last_nomodifier) { - // increment the modifier, wrapping back to none - switch (lastcode.item_modifier()) + if (ITEM_CLASS_ABSOLUTE == newclass) { - case ITEM_MODIFIER_NONE: - newcode.set_item_modifier(ITEM_MODIFIER_POS); - break; - case ITEM_MODIFIER_POS: - newcode.set_item_modifier(ITEM_MODIFIER_NEG); - break; - default: - case ITEM_MODIFIER_NEG: - newcode.set_item_modifier(ITEM_MODIFIER_NONE); - break; + // increment the modifier, wrapping back to none + switch (lastcode.item_modifier()) + { + case ITEM_MODIFIER_NONE: + newcode.set_item_modifier(ITEM_MODIFIER_POS); + break; + case ITEM_MODIFIER_POS: + newcode.set_item_modifier(ITEM_MODIFIER_NEG); + break; + case ITEM_MODIFIER_NEG: + newcode.set_item_modifier(ITEM_MODIFIER_REVERSE); + break; + default: + case ITEM_MODIFIER_REVERSE: + newcode.set_item_modifier(ITEM_MODIFIER_NONE); + break; + } + + // back up over the previous code so we can re-append + if (has_or) + m_sequence.backspace(); + m_sequence.backspace(); + } + else if (ITEM_CLASS_RELATIVE == newclass) + { + // increment the modifier, wrapping back to none + switch (lastcode.item_modifier()) + { + case ITEM_MODIFIER_NONE: + newcode.set_item_modifier(ITEM_MODIFIER_REVERSE); + break; + default: + case ITEM_MODIFIER_REVERSE: + newcode.set_item_modifier(ITEM_MODIFIER_NONE); + break; + } + + // back up over the previous code so we can re-append + if (has_or) + m_sequence.backspace(); + m_sequence.backspace(); } + else if (!has_or && (ITEM_CLASS_SWITCH == newclass)) + { + // back up over the existing code + m_sequence.backspace(); - // back up over the previous code so we can re-append - if (has_or) + // if there was a NOT preceding it, delete it as well, otherwise append a fresh one + if (m_sequence[curlen - 2] == input_seq::not_code) + m_sequence.backspace(); + else + m_sequence += input_seq::not_code; + } + } + else if (!has_or && (ITEM_CLASS_SWITCH == newclass)) + { + // ignore switches following axes + if (ITEM_CLASS_SWITCH != lastcode.item_class()) + { + // hack to stop it timing out so user can cancel m_sequence.backspace(); - m_sequence.backspace(); + newcode = lastcode; + } } } - return newcode; + + // hack to stop it timing out before assigning an axis + if (ITEM_CLASS_SWITCH == newcode.item_class()) + { + m_sequence += newcode; + set_modified(); + return INPUT_CODE_INVALID; + } + else + { + return newcode; + } } diff --git a/src/frontend/mame/iptseqpoll.h b/src/frontend/mame/iptseqpoll.h index b9f31f70477..b33eeebf292 100644 --- a/src/frontend/mame/iptseqpoll.h +++ b/src/frontend/mame/iptseqpoll.h @@ -27,22 +27,10 @@ public: protected: input_code_poller(input_manager &manager) noexcept; - input_manager &m_manager; - std::vector<std::pair<input_device_item *, s32> > m_axis_memory; -}; - - -class switch_code_poller_base : public input_code_poller -{ -public: - virtual void reset() override; - -protected: - switch_code_poller_base(input_manager &manager) noexcept; - bool code_pressed_once(input_code code, bool moved); -private: + input_manager &m_manager; + std::vector<std::pair<input_device_item *, s32> > m_axis_memory; std::vector<input_code> m_switch_memory; }; @@ -56,7 +44,7 @@ public: }; -class switch_code_poller : public switch_code_poller_base +class switch_code_poller : public input_code_poller { public: switch_code_poller(input_manager &manager) noexcept; @@ -65,7 +53,7 @@ public: }; -class keyboard_code_poller : public switch_code_poller_base +class keyboard_code_poller : public input_code_poller { public: keyboard_code_poller(input_manager &manager) noexcept; @@ -90,6 +78,8 @@ public: protected: input_sequence_poller() noexcept; + void set_modified() noexcept { m_modified = true; } + input_seq m_sequence; private: diff --git a/src/frontend/mame/ui/confswitch.cpp b/src/frontend/mame/ui/confswitch.cpp index 3aa10cd9133..1e89cb48d58 100644 --- a/src/frontend/mame/ui/confswitch.cpp +++ b/src/frontend/mame/ui/confswitch.cpp @@ -102,7 +102,6 @@ void menu_confswitch::populate(float &customtop, float &custombottom) // loop over input ports and set up the current values device_t *prev_owner(nullptr); - bool first_entry(true); for (field_descriptor &desc : m_fields) { ioport_field &field(desc.field); @@ -114,11 +113,10 @@ void menu_confswitch::populate(float &customtop, float &custombottom) if (&field.device() != prev_owner) { prev_owner = &field.device(); - if (first_entry) - first_entry = false; + if (prev_owner->owner()) + item_append(string_format(_("%1$s [root%2$s]"), prev_owner->type().fullname(), prev_owner->tag()), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); else - item_append(menu_item_type::SEPARATOR); - item_append(string_format("[root%s]", prev_owner->tag()), 0, nullptr); + item_append(string_format(_("[root%1$s]"), prev_owner->tag()), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); } // set the left/right flags appropriately @@ -214,6 +212,51 @@ void menu_confswitch::handle(event const *ev) field.select_next_setting(); changed = true; break; + + // trick to get previous group - depend on headings having null reference + case IPT_UI_PREV_GROUP: + { + auto current = selected_index(); + bool found_break = false; + while (0 < current) + { + if (!found_break) + { + if (!item(--current).ref) + found_break = true; + } + else if (!item(current - 1).ref) + { + set_selected_index(current); + set_top_line(current - 1); + break; + } + else + { + --current; + } + } + } + break; + + // trick to get next group - depend on special item references + case IPT_UI_NEXT_GROUP: + { + auto current = selected_index(); + while (item_count() > ++current) + { + if (!item(current).ref) + { + if ((item_count() > (current + 1)) && (uintptr_t(item(current + 1).ref) != 1)) + { + set_selected_index(current + 1); + set_top_line(current); + } + break; + } + } + } + break; } // if anything changed, rebuild the menu, trying to stay on the same field diff --git a/src/frontend/mame/ui/filemngr.cpp b/src/frontend/mame/ui/filemngr.cpp index 029950865d4..06c2d822b1e 100644 --- a/src/frontend/mame/ui/filemngr.cpp +++ b/src/frontend/mame/ui/filemngr.cpp @@ -33,16 +33,13 @@ namespace ui { // ctor //------------------------------------------------- -menu_file_manager::menu_file_manager(mame_ui_manager &mui, render_container &container, const char *warnings) : menu(mui, container), selected_device(nullptr) +menu_file_manager::menu_file_manager(mame_ui_manager &mui, render_container &container, const char *warnings) + : menu(mui, container) + , selected_device(nullptr) + , m_warnings(warnings ? warnings : "") { - // This warning string is used when accessing from the force_file_manager call, i.e. + // The warning string is used when accessing from the force_file_manager call, i.e. // when the file manager is loaded top front in the case of mandatory image devices - if (warnings) - m_warnings.assign(warnings); - else - m_warnings.clear(); - - m_curr_selected = false; } @@ -108,12 +105,10 @@ void menu_file_manager::populate(float &customtop, float &custombottom) std::string tmp_inst, tmp_name; if (!m_warnings.empty()) - { item_append(m_warnings, FLAG_DISABLE, nullptr); - item_append(std::string(), FLAG_DISABLE, nullptr); - } // cycle through all devices for this system + bool missing_mandatory = false; std::unordered_set<std::string> devtags; for (device_t &dev : device_enumerator(machine().root_device())) { @@ -135,12 +130,16 @@ void menu_file_manager::populate(float &customtop, float &custombottom) if (strcmp(scan.device().owner()->tag(), dev.tag()) == 0) if (devtags.insert(scan.device().tag()).second) { + if (!scan.basename() && scan.must_be_loaded()) + missing_mandatory = true; + // check whether we already had some devices with the same owner: if not, output the owner tag! if (!tag_appended) { item_append(string_format(_("[root%1$s]"), dev.tag()), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); tag_appended = true; } + // finally, append the image interface to the menu fill_image_line(&scan, tmp_inst, tmp_name); item_append(tmp_inst, tmp_name, 0, (void *)&scan); @@ -150,8 +149,8 @@ void menu_file_manager::populate(float &customtop, float &custombottom) } item_append(menu_item_type::SEPARATOR); - if (m_warnings.empty() || m_curr_selected) - item_append(_("Reset Machine"), 0, (void *)1); + if (m_warnings.empty() || !missing_mandatory) + item_append(m_warnings.empty() ? _("Reset Machine") : _("Start Machine"), 0, (void *)1); custombottom = ui().get_line_height() + 3.0f * ui().box_tb_border(); } @@ -175,7 +174,6 @@ void menu_file_manager::handle(event const *ev) selected_device = (device_image_interface *) ev->itemref; if (selected_device) { - m_curr_selected = true; floppy_image_device *floppy_device = dynamic_cast<floppy_image_device *>(selected_device); if (floppy_device) menu::stack_push<menu_control_floppy_image>(ui(), container(), *floppy_device); @@ -192,14 +190,9 @@ void menu_file_manager::handle(event const *ev) // force file manager menu void menu_file_manager::force_file_manager(mame_ui_manager &mui, render_container &container, const char *warnings) { - // reset the menu stack + // drop any existing menus and start the file manager menu::stack_reset(mui); - - // add the quit entry followed by the game select entry - menu::stack_push_special_main<menu_quit_game>(mui, container); - menu::stack_push<menu_file_manager>(mui, container, warnings); - - // force the menus on + menu::stack_push_special_main<menu_file_manager>(mui, container, warnings); mui.show_menu(); // make sure MAME is paused diff --git a/src/frontend/mame/ui/filemngr.h b/src/frontend/mame/ui/filemngr.h index a925e24b35e..379912c8dfb 100644 --- a/src/frontend/mame/ui/filemngr.h +++ b/src/frontend/mame/ui/filemngr.h @@ -38,8 +38,7 @@ private: void fill_image_line(device_image_interface *img, std::string &instance, std::string &filename); - std::string m_warnings; - bool m_curr_selected; + std::string const m_warnings; }; } // namespace ui diff --git a/src/frontend/mame/ui/filesel.cpp b/src/frontend/mame/ui/filesel.cpp index ea5c1e02e37..3da27ae7a36 100644 --- a/src/frontend/mame/ui/filesel.cpp +++ b/src/frontend/mame/ui/filesel.cpp @@ -59,6 +59,7 @@ menu_file_selector::menu_file_selector(mame_ui_manager &mui, render_container &c , m_result(result) { (void)m_image; + set_process_flags(PROCESS_IGNOREPAUSE); } diff --git a/src/frontend/mame/ui/imgcntrl.cpp b/src/frontend/mame/ui/imgcntrl.cpp index 96f520d332b..5708a4a832a 100644 --- a/src/frontend/mame/ui/imgcntrl.cpp +++ b/src/frontend/mame/ui/imgcntrl.cpp @@ -234,7 +234,7 @@ void menu_control_device_image::menu_activated() else { m_software_info_name.clear(); - menu::stack_push_special_main<menu_software_list>(ui(), container(), m_sld, m_image.image_interface(), m_software_info_name); + menu::stack_push<menu_software_list>(ui(), container(), m_sld, m_image.image_interface(), m_software_info_name); m_state = SELECT_PARTLIST; } break; diff --git a/src/frontend/mame/ui/menu.cpp b/src/frontend/mame/ui/menu.cpp index 94b4b1eff5e..525e378dca6 100644 --- a/src/frontend/mame/ui/menu.cpp +++ b/src/frontend/mame/ui/menu.cpp @@ -112,7 +112,7 @@ menu::global_state::~global_state() void menu::global_state::stack_push(std::unique_ptr<menu> &&menu) { - if (m_stack && m_stack->m_active) + if (m_stack && m_stack->is_active()) { m_stack->m_active = false; m_stack->menu_deactivated(); @@ -127,8 +127,13 @@ void menu::global_state::stack_pop() { if (m_stack) { - if (m_stack->m_one_shot) + if (m_stack->is_one_shot()) m_hide = true; + if (m_stack->is_active()) + { + m_stack->m_active = false; + m_stack->menu_deactivated(); + } m_stack->menu_dismissed(); std::unique_ptr<menu> menu(std::move(m_stack)); m_stack = std::move(menu->m_parent); @@ -177,10 +182,10 @@ uint32_t menu::global_state::ui_handler(render_container &container) { // if we have no menus stacked up, start with the main menu if (!m_stack) - stack_push(std::unique_ptr<menu>(make_unique_clear<menu_main>(m_ui, container))); + stack_push(std::make_unique<menu_main>(m_ui, container)); // ensure topmost menu is active - need a loop because it could push another menu - while (m_stack && !m_stack->m_active) + while (m_stack && !m_stack->is_active()) { m_stack->m_active = true; m_stack->menu_activated(); @@ -199,11 +204,11 @@ uint32_t menu::global_state::ui_handler(render_container &container) { if (m_stack) { - if (m_stack->m_one_shot) + if (m_stack->is_one_shot()) { stack_pop(); } - else if (m_stack->m_active) + else if (m_stack->is_active()) { m_stack->m_active = false; m_stack->menu_deactivated(); @@ -287,17 +292,6 @@ void menu::reset(reset_options options) //------------------------------------------------- -// is_special_main_menu - returns whether the -// menu has special needs -//------------------------------------------------- - -bool menu::is_special_main_menu() const -{ - return m_special_main_menu; -} - - -//------------------------------------------------- // set_special_main_menu - set whether the // menu has special needs //------------------------------------------------- @@ -897,6 +891,8 @@ void menu::handle_events(uint32_t flags, event &ev) { ev.iptkey = IPT_UI_CANCEL; stack_pop(); + if (is_special_main_menu()) + machine().schedule_exit(); } stop = true; } @@ -974,6 +970,8 @@ void menu::handle_keys(uint32_t flags, int &iptkey) { iptkey = IPT_UI_CANCEL; stack_pop(); + if (is_special_main_menu()) + machine().schedule_exit(); } return; } @@ -981,7 +979,7 @@ void menu::handle_keys(uint32_t flags, int &iptkey) // UI configure hides the menus if (!(flags & PROCESS_NOKEYS) && exclusive_input_pressed(iptkey, IPT_UI_CONFIGURE, 0) && !m_global_state.stack_has_special_main_menu()) { - if (m_one_shot) + if (is_one_shot()) stack_pop(); else m_global_state.hide_menu(); @@ -996,7 +994,11 @@ void menu::handle_keys(uint32_t flags, int &iptkey) if (exclusive_input_pressed(iptkey, IPT_UI_CANCEL, 0)) { if (!custom_ui_cancel()) + { stack_pop(); + if (is_special_main_menu()) + machine().schedule_exit(); + } return; } diff --git a/src/frontend/mame/ui/menu.h b/src/frontend/mame/ui/menu.h index b2111168dc4..00b42890f4b 100644 --- a/src/frontend/mame/ui/menu.h +++ b/src/frontend/mame/ui/menu.h @@ -65,12 +65,12 @@ public: template <typename T, typename... Params> static void stack_push(Params &&... args) { - stack_push(std::unique_ptr<menu>(make_unique_clear<T>(std::forward<Params>(args)...))); + stack_push(std::make_unique<T>(std::forward<Params>(args)...)); } template <typename T, typename... Params> static void stack_push_special_main(Params &&... args) { - std::unique_ptr<menu> ptr(make_unique_clear<T>(std::forward<Params>(args)...)); + std::unique_ptr<menu> ptr(std::make_unique<T>(std::forward<Params>(args)...)); ptr->set_special_main_menu(true); stack_push(std::move(ptr)); } @@ -130,6 +130,10 @@ protected: running_machine &machine() const { return m_ui.machine(); } render_container &container() const { return m_container; } + bool is_special_main_menu() const { return m_special_main_menu; } + bool is_one_shot() const { return m_one_shot; } + bool is_active() const { return m_active; } + void set_one_shot(bool oneshot) { m_one_shot = oneshot; } void set_needs_prev_menu_item(bool needs) { m_needs_prev_menu_item = needs; } void reset(reset_options options); @@ -338,7 +342,6 @@ private: virtual void draw(uint32_t flags); // request the specific handling of the game selection main menu - bool is_special_main_menu() const; void set_special_main_menu(bool disable); // to be implemented in derived classes @@ -392,6 +395,37 @@ private: float m_mouse_y; }; + +template <typename Base = menu> +class autopause_menu : public Base +{ +protected: + using Base::Base; + + virtual void menu_activated() override + { + m_was_paused = this->machine().paused(); + if (m_was_paused) + m_unpaused = false; + else if (!m_unpaused) + this->machine().pause(); + Base::menu_activated(); + } + + virtual void menu_deactivated() override + { + m_unpaused = !this->machine().paused(); + if (!m_was_paused && !m_unpaused) + this->machine().resume(); + Base::menu_deactivated(); + } + +private: + bool m_was_paused = false; + bool m_unpaused = false; +}; + + } // namespace ui #endif // MAME_FRONTEND_UI_MENU_H diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp index 2254ef609e3..8c70dce18ad 100644 --- a/src/frontend/mame/ui/miscmenu.cpp +++ b/src/frontend/mame/ui/miscmenu.cpp @@ -560,32 +560,6 @@ menu_crosshair::~menu_crosshair() { } -/*------------------------------------------------- - menu_quit_game - handle the "menu" for - quitting the game --------------------------------------------------*/ - -menu_quit_game::menu_quit_game(mame_ui_manager &mui, render_container &container) : menu(mui, container) -{ -} - -menu_quit_game::~menu_quit_game() -{ -} - -void menu_quit_game::populate(float &customtop, float &custombottom) -{ -} - -void menu_quit_game::handle(event const *ev) -{ - // request a reset - machine().schedule_exit(); - - // reset the menu stack - stack_reset(); -} - //------------------------------------------------- // ctor / dtor //------------------------------------------------- diff --git a/src/frontend/mame/ui/miscmenu.h b/src/frontend/mame/ui/miscmenu.h index 1b19b4c5d45..b17e6713597 100644 --- a/src/frontend/mame/ui/miscmenu.h +++ b/src/frontend/mame/ui/miscmenu.h @@ -54,6 +54,7 @@ private: attotime prevtime; }; + class menu_crosshair : public menu { public: @@ -87,16 +88,6 @@ private: std::vector<std::string> m_pics; }; -class menu_quit_game : public menu -{ -public: - menu_quit_game(mame_ui_manager &mui, render_container &container); - virtual ~menu_quit_game(); - -private: - virtual void populate(float &customtop, float &custombottom) override; - virtual void handle(event const *ev) override; -}; class menu_bios_selection : public menu { @@ -127,6 +118,7 @@ private: std::vector<const game_driver*> m_list; }; + //------------------------------------------------- // machine configure menu //------------------------------------------------- @@ -173,6 +165,7 @@ private: bool m_want_favorite; }; + //------------------------------------------------- // plugins configure menu //------------------------------------------------- diff --git a/src/frontend/mame/ui/quitmenu.cpp b/src/frontend/mame/ui/quitmenu.cpp new file mode 100644 index 00000000000..bb26f7e6290 --- /dev/null +++ b/src/frontend/mame/ui/quitmenu.cpp @@ -0,0 +1,61 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/*************************************************************************** + + ui/quitmenu.h + + Menus involved in quitting MAME. + +***************************************************************************/ + +#include "emu.h" +#include "quitmenu.h" + +#include "uiinput.h" + + +namespace ui { + +menu_confirm_quit::menu_confirm_quit(mame_ui_manager &mui, render_container &container) + : autopause_menu<>(mui, container) +{ + set_one_shot(true); + set_process_flags(PROCESS_CUSTOM_ONLY | PROCESS_NOINPUT); +} + + +menu_confirm_quit::~menu_confirm_quit() +{ +} + + +void menu_confirm_quit::custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) +{ + ui().draw_text_box( + container(), + util::string_format( + _("Are you sure you want to quit?\n\n" + "Press %1$s to quit\n" + "Press %2$s to return to emulation"), + ui().get_general_input_setting(IPT_UI_SELECT), + ui().get_general_input_setting(IPT_UI_CANCEL)), + text_layout::text_justify::CENTER, + 0.5f, 0.5f, + UI_RED_COLOR); +} + + +void menu_confirm_quit::populate(float &customtop, float &custombottom) +{ +} + + +void menu_confirm_quit::handle(event const *ev) +{ + if (machine().ui_input().pressed(IPT_UI_SELECT)) + machine().schedule_exit(); + else if (machine().ui_input().pressed(IPT_UI_CANCEL)) + stack_pop(); +} + +} // namespace ui diff --git a/src/frontend/mame/ui/quitmenu.h b/src/frontend/mame/ui/quitmenu.h new file mode 100644 index 00000000000..81ca61e2892 --- /dev/null +++ b/src/frontend/mame/ui/quitmenu.h @@ -0,0 +1,36 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/*************************************************************************** + + ui/quitmenu.h + + Menus involved in quitting MAME. + +***************************************************************************/ +#ifndef MAME_FRONTEND_UI_QUITMENU_H +#define MAME_FRONTEND_UI_QUITMENU_H + +#pragma once + +#include "ui/menu.h" + + +namespace ui { + +class menu_confirm_quit : public autopause_menu<> +{ +public: + menu_confirm_quit(mame_ui_manager &mui, render_container &container); + virtual ~menu_confirm_quit(); + +protected: + virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override; + +private: + virtual void populate(float &customtop, float &custombottom) override; + virtual void handle(event const *ev) override; +}; + +} // namespace ui + +#endif // MAME_FRONTEND_UI_QUITMENU_H diff --git a/src/frontend/mame/ui/selgame.cpp b/src/frontend/mame/ui/selgame.cpp index 5fceddc1b3e..315722922d2 100644 --- a/src/frontend/mame/ui/selgame.cpp +++ b/src/frontend/mame/ui/selgame.cpp @@ -438,7 +438,9 @@ void menu_select_game::populate(float &customtop, float &custombottom) skip_main_items = 3; } else + { skip_main_items = 0; + } // configure the custom rendering customtop = 3.0f * ui().get_line_height() + 5.0f * ui().box_tb_border(); @@ -569,14 +571,9 @@ void menu_select_game::build_available_list() void menu_select_game::force_game_select(mame_ui_manager &mui, render_container &container) { - // reset the menu stack + // drop any existing menus and start the system selection menu menu::stack_reset(mui); - - // add the quit entry followed by the game select entry - menu::stack_push_special_main<menu_quit_game>(mui, container); - menu::stack_push<menu_select_game>(mui, container, nullptr); - - // force the menus on + menu::stack_push_special_main<menu_select_game>(mui, container, nullptr); mui.show_menu(); // make sure MAME is paused diff --git a/src/frontend/mame/ui/selmenu.cpp b/src/frontend/mame/ui/selmenu.cpp index 29bec4fe639..b299c7e4167 100644 --- a/src/frontend/mame/ui/selmenu.cpp +++ b/src/frontend/mame/ui/selmenu.cpp @@ -1441,6 +1441,8 @@ void menu_select_launch::handle_keys(uint32_t flags, int &iptkey) { // otherwise pop the stack stack_pop(); + if (is_special_main_menu()) + machine().schedule_exit(); } return; } @@ -1761,6 +1763,8 @@ void menu_select_launch::handle_events(uint32_t flags, event &ev) { ev.iptkey = IPT_UI_CANCEL; stack_pop(); + if (is_special_main_menu()) + machine().schedule_exit(); stop = true; } else if (hover() >= HOVER_RP_FIRST && hover() <= HOVER_RP_LAST) diff --git a/src/frontend/mame/ui/simpleselgame.cpp b/src/frontend/mame/ui/simpleselgame.cpp index 82fde5bae79..7cb346ee397 100644 --- a/src/frontend/mame/ui/simpleselgame.cpp +++ b/src/frontend/mame/ui/simpleselgame.cpp @@ -13,7 +13,6 @@ #include "ui/simpleselgame.h" #include "ui/info.h" -#include "ui/miscmenu.h" #include "ui/optsmenu.h" #include "ui/ui.h" #include "ui/utils.h" @@ -418,13 +417,10 @@ void simple_menu_select_game::force_game_select(mame_ui_manager &mui, render_con char *gamename = (char *)mui.machine().options().system_name(); // reset the menu stack - menu::stack_reset(mui); - - // add the quit entry followed by the game select entry - menu::stack_push_special_main<menu_quit_game>(mui, container); - menu::stack_push<simple_menu_select_game>(mui, container, gamename); - // force the menus on + // drop any existing menus and start the system selection menu + menu::stack_reset(mui); + menu::stack_push_special_main<simple_menu_select_game>(mui, container, gamename); mui.show_menu(); // make sure MAME is paused diff --git a/src/frontend/mame/ui/sliders.h b/src/frontend/mame/ui/sliders.h index 6dd763b9c2f..a1ac25bf96c 100644 --- a/src/frontend/mame/ui/sliders.h +++ b/src/frontend/mame/ui/sliders.h @@ -2,7 +2,7 @@ // copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods /*************************************************************************** - ui/miscmenu.h + ui/sliders.h Internal MAME menus for the user interface. diff --git a/src/frontend/mame/ui/state.cpp b/src/frontend/mame/ui/state.cpp index 72ed3941196..afd02a3b08d 100644 --- a/src/frontend/mame/ui/state.cpp +++ b/src/frontend/mame/ui/state.cpp @@ -89,15 +89,12 @@ menu_load_save_state_base::menu_load_save_state_base( std::string_view footer, bool must_exist, bool one_shot) - : menu(mui, container) + : autopause_menu<>(mui, container) , m_switch_poller(machine().input()) , m_header(header) , m_footer(footer) , m_confirm_delete(nullptr) , m_must_exist(must_exist) - , m_one_shot(one_shot) - , m_first_time(true) - , m_was_paused(false) , m_keys_released(false) { set_one_shot(one_shot); @@ -111,10 +108,6 @@ menu_load_save_state_base::menu_load_save_state_base( menu_load_save_state_base::~menu_load_save_state_base() { - // resume if appropriate (is the destructor really the right place - // to do this sort of activity?) - if (!m_was_paused) - machine().resume(); } @@ -225,24 +218,15 @@ void menu_load_save_state_base::populate(float &customtop, float &custombottom) set_selection(nullptr); } item_append(menu_item_type::SEPARATOR); - if (m_one_shot) + if (is_one_shot()) item_append(_("Cancel"), 0, nullptr); // set up custom render proc customtop = ui().get_line_height() + (3.0f * ui().box_tb_border()); custombottom = (2.0f * ui().get_line_height()) + (3.0f * ui().box_tb_border()); - // pause if appropriate - if (m_first_time) - { - m_was_paused = machine().paused(); - if (!m_was_paused) - machine().pause(); - } - // get ready to poll inputs m_switch_poller.reset(); - m_first_time = false; m_keys_released = false; } diff --git a/src/frontend/mame/ui/state.h b/src/frontend/mame/ui/state.h index f6a48331981..dd3d9f190ec 100644 --- a/src/frontend/mame/ui/state.h +++ b/src/frontend/mame/ui/state.h @@ -22,7 +22,7 @@ namespace ui { -class menu_load_save_state_base : public menu +class menu_load_save_state_base : public autopause_menu<> { public: virtual ~menu_load_save_state_base() override; @@ -73,9 +73,7 @@ private: std::string m_confirm_prompt; file_entry const * m_confirm_delete; bool const m_must_exist; - bool const m_one_shot; bool m_first_time; - bool m_was_paused; bool m_keys_released; static void *itemref_from_file_entry(const file_entry &entry); diff --git a/src/frontend/mame/ui/swlist.cpp b/src/frontend/mame/ui/swlist.cpp index 72e076df67c..70c9471da56 100644 --- a/src/frontend/mame/ui/swlist.cpp +++ b/src/frontend/mame/ui/swlist.cpp @@ -148,6 +148,7 @@ void menu_software_parts::handle(event const *ev) menu_software_list::menu_software_list(mame_ui_manager &mui, render_container &container, software_list_device *swlist, const char *interface, std::string &result) : menu(mui, container), m_result(result) { + set_process_flags(PROCESS_IGNOREPAUSE); m_swlist = swlist; m_interface = interface; m_ordered_by_shortname = false; diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp index fa7d1644d40..7d3a51c8928 100644 --- a/src/frontend/mame/ui/ui.cpp +++ b/src/frontend/mame/ui/ui.cpp @@ -19,6 +19,7 @@ #include "ui/info.h" #include "ui/mainmenu.h" #include "ui/menu.h" +#include "ui/quitmenu.h" #include "ui/sliders.h" #include "ui/state.h" #include "ui/systemlist.h" @@ -594,7 +595,9 @@ void mame_ui_manager::display_startup_screens(bool first_time) // if we're the empty driver, force the menus on if (ui::menu::stack_has_special_main_menu(*this)) + { show_menu(); + } else if (config_menu) { show_menu(); @@ -1417,50 +1420,14 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container) void mame_ui_manager::request_quit() { if (!machine().options().confirm_quit()) + { machine().schedule_exit(); + } else - set_handler(ui_callback_type::GENERAL, handler_callback_func(&mame_ui_manager::handler_confirm_quit, this)); -} - - -//------------------------------------------------- -// handler_confirm_quit - leads the user through -// confirming quit emulation -//------------------------------------------------- - -uint32_t mame_ui_manager::handler_confirm_quit(render_container &container) -{ - uint32_t state = 0; - - // get the text for 'UI Select' - std::string ui_select_text = get_general_input_setting(IPT_UI_SELECT); - - // get the text for 'UI Cancel' - std::string ui_cancel_text = get_general_input_setting(IPT_UI_CANCEL); - - // assemble the quit message - std::string quit_message = string_format( - _("Are you sure you want to quit?\n\n" - "Press ''%1$s'' to quit,\n" - "Press ''%2$s'' to return to emulation."), - ui_select_text, - ui_cancel_text); - - draw_text_box(container, quit_message, ui::text_layout::text_justify::CENTER, 0.5f, 0.5f, UI_RED_COLOR); - machine().pause(); - - // if the user press ENTER, quit the game - if (machine().ui_input().pressed(IPT_UI_SELECT)) - machine().schedule_exit(); - - // if the user press ESC, just continue - else if (machine().ui_input().pressed(IPT_UI_CANCEL)) { - machine().resume(); - state = UI_HANDLER_CANCEL; + show_menu(); + ui::menu::stack_push<ui::menu_confirm_quit>(*this, machine().render().ui_container()); } - - return state; } diff --git a/src/frontend/mame/ui/ui.h b/src/frontend/mame/ui/ui.h index cda90e22df9..272fb0ae810 100644 --- a/src/frontend/mame/ui/ui.h +++ b/src/frontend/mame/ui/ui.h @@ -266,8 +266,6 @@ private: // UI handlers uint32_t handler_ingame(render_container &container); - uint32_t handler_load_save(render_container &container, uint32_t state); - uint32_t handler_confirm_quit(render_container &container); // private methods void set_handler(ui_callback_type callback_type, handler_callback_func &&callback); |