From 00aec891925e530ced84f63a04aefaf0a4631582 Mon Sep 17 00:00:00 2001 From: Michele Fochi Date: Sat, 13 Feb 2016 20:41:19 +0100 Subject: [PATCH 1/2] Added support for autofire under cheat menu and available only if cheats activated. --- src/emu/inpttype.h | 1 + src/emu/ioport.cpp | 23 ++++- src/emu/ioport.h | 14 +++ src/emu/ui/cheatopt.cpp | 220 +++++++++++++++++++++++++++++++++++++--- src/emu/ui/cheatopt.h | 25 +++++ src/emu/ui/mainmenu.cpp | 2 +- src/emu/ui/ui.cpp | 15 +++ 7 files changed, 284 insertions(+), 16 deletions(-) diff --git a/src/emu/inpttype.h b/src/emu/inpttype.h index 96395a60e7c..4d711e4d676 100644 --- a/src/emu/inpttype.h +++ b/src/emu/inpttype.h @@ -730,6 +730,7 @@ void construct_core_types_UI(simple_list &typelist) INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TIMECODE, "Write current timecode", input_seq(KEYCODE_F12, input_seq::not_code, KEYCODE_LSHIFT) ) INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RECORD_MOVIE, "Record Movie", input_seq(KEYCODE_F12, KEYCODE_LSHIFT) ) INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TOGGLE_CHEAT, "Toggle Cheat", input_seq(KEYCODE_F6) ) + INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_TOGGLE_AUTOFIRE, "Toggle Autofire", input_seq() ) INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_UP, "UI Up", input_seq(KEYCODE_UP, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(0)) ) INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_DOWN, "UI Down", input_seq(KEYCODE_DOWN, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(0)) ) INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_LEFT, "UI Left", input_seq(KEYCODE_LEFT, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(0)) ) diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp index ec88792df12..17e11748df1 100644 --- a/src/emu/ioport.cpp +++ b/src/emu/ioport.cpp @@ -1699,6 +1699,7 @@ void ioport_field::get_user_settings(user_settings &settings) else { settings.toggle = m_live->toggle; + settings.autofire = m_live->autofire; } } @@ -1737,6 +1738,7 @@ void ioport_field::set_user_settings(const user_settings &settings) else { m_live->toggle = settings.toggle; + m_live->autofire = settings.autofire; } } @@ -1904,6 +1906,19 @@ void ioport_field::frame_update(ioport_value &result, bool mouse_down) // if the state changed, look for switch down/switch up bool curstate = mouse_down || machine().input().seq_pressed(seq()) || m_digital_value; + if (m_live->autofire && !machine().ioport().get_autofire_toggle()) + { + if (curstate) + { + if (m_live->autopressed > machine().ioport().get_autofire_delay()) + m_live->autopressed = 0; + else if (m_live->autopressed > machine().ioport().get_autofire_delay() / 2) + curstate = false; + m_live->autopressed++; + } + else + m_live->autopressed = 0; + } bool changed = false; if (curstate != m_live->last) { @@ -2156,7 +2171,9 @@ ioport_field_live::ioport_field_live(ioport_field &field, analog_field *analog) impulse(0), last(0), toggle(field.toggle()), - joydir(digital_joystick::JOYDIR_COUNT) + joydir(digital_joystick::JOYDIR_COUNT), + autofire(false), + autopressed(0) { // fill in the basic values for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) @@ -2460,7 +2477,9 @@ ioport_manager::ioport_manager(running_machine &machine) m_has_configs(false), m_has_analog(false), m_has_dips(false), - m_has_bioses(false) + m_has_bioses(false), + m_autofire_toggle(false), + m_autofire_delay(3) // 1 seems too fast for a bunch of games { memset(m_type_to_entry, 0, sizeof(m_type_to_entry)); } diff --git a/src/emu/ioport.h b/src/emu/ioport.h index d398a8df2c1..6d9d941fa4a 100644 --- a/src/emu/ioport.h +++ b/src/emu/ioport.h @@ -382,6 +382,7 @@ enum ioport_type IPT_UI_EXPORT, IPT_UI_AUDIT_FAST, IPT_UI_AUDIT_ALL, + IPT_UI_TOGGLE_AUTOFIRE, // additional OSD-specified UI port types (up to 16) IPT_OSD_1, @@ -1095,6 +1096,7 @@ public: struct user_settings { ioport_value value; // for DIP switches + bool autofire; // for autofire settings input_seq seq[SEQ_TYPE_TOTAL]; // sequences of all types INT32 sensitivity; // for analog controls INT32 delta; // for analog controls @@ -1171,6 +1173,8 @@ struct ioport_field_live bool last; // were we pressed last time? bool toggle; // current toggle setting digital_joystick::direction_t joydir; // digital joystick direction index + bool autofire; // autofire + int autopressed; // autofire status std::string name; // overridden name }; @@ -1413,6 +1417,12 @@ public: ioport_type token_to_input_type(const char *string, int &player) const; std::string input_type_to_token(ioport_type type, int player); + // autofire + bool get_autofire_toggle() { return m_autofire_toggle; } + void set_autofire_toggle(bool toggle) { m_autofire_toggle = toggle; } + int get_autofire_delay() { return m_autofire_delay; } + void set_autofire_delay(int delay) { m_autofire_delay = delay; } + private: // internal helpers void init_port_types(); @@ -1484,6 +1494,10 @@ private: bool m_has_analog; bool m_has_dips; bool m_has_bioses; + + // autofire + bool m_autofire_toggle; // autofire toggle + int m_autofire_delay; // autofire delay }; diff --git a/src/emu/ui/cheatopt.cpp b/src/emu/ui/cheatopt.cpp index 015ccba6908..a2b9ccffd6c 100644 --- a/src/emu/ui/cheatopt.cpp +++ b/src/emu/ui/cheatopt.cpp @@ -24,6 +24,7 @@ void ui_menu_cheat::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) { @@ -33,7 +34,7 @@ void ui_menu_cheat::handle() machine().popmessage(nullptr); /* handle reset all + reset all cheats for reload all option */ - if ((FPTR)menu_event->itemref < 3 && menu_event->iptkey == IPT_UI_SELECT) + if (menu_event->itemref < ITEMREF_CHEATS_FIRST_ITEM && menu_event->iptkey == IPT_UI_SELECT) { for (cheat_entry *curcheat = machine().cheat().first(); curcheat != nullptr; curcheat = curcheat->next()) if (curcheat->select_default_state()) @@ -42,7 +43,7 @@ void ui_menu_cheat::handle() /* handle individual cheats */ - else if ((FPTR)menu_event->itemref > 2) + else if (menu_event->itemref > ITEMREF_CHEATS_FIRST_ITEM) { cheat_entry *curcheat = reinterpret_cast(menu_event->itemref); const char *string; @@ -80,7 +81,7 @@ void ui_menu_cheat::handle() } /* handle reload all */ - if ((FPTR)menu_event->itemref == 2 && menu_event->iptkey == IPT_UI_SELECT) + if (menu_event->itemref == ITEMREF_CHEATS_RELOAD_ALL && menu_event->iptkey == IPT_UI_SELECT) { /* re-init cheat engine and thus reload cheats/cheats have already been turned off by here */ machine().cheat().reload(); @@ -90,6 +91,12 @@ void ui_menu_cheat::handle() machine().popmessage("All cheats reloaded"); } + /* handle autofire menu */ + if (menu_event->itemref == ITEMREF_CHEATS_AUTOFIRE_SETTINGS && menu_event->iptkey == IPT_UI_SELECT) + { + ui_menu::stack_push(global_alloc_clear(machine(), container)); + } + /* if things changed, update */ if (changed) reset(UI_MENU_RESET_REMEMBER_REF); @@ -110,23 +117,210 @@ void ui_menu_cheat::populate() /* iterate over cheats */ std::string text; std::string subtext; - for (cheat_entry *curcheat = machine().cheat().first(); curcheat != nullptr; curcheat = curcheat->next()) - { - UINT32 flags; - curcheat->menu_text(text, subtext, flags); - item_append(text.c_str(), subtext.c_str(), flags, curcheat); - } + + // add the autofire menu + item_append("Autofire Settings", nullptr, 0, (void *)ITEMREF_CHEATS_AUTOFIRE_SETTINGS); /* add a separator */ item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); - /* add a reset all option */ - item_append("Reset All", nullptr, 0, (void *)1); + // add other cheats + if (machine().cheat().first() != nullptr) { + for (cheat_entry *curcheat = machine().cheat().first(); curcheat != nullptr; curcheat = curcheat->next()) + { + UINT32 flags; + curcheat->menu_text(text, subtext, flags); + item_append(text.c_str(), subtext.c_str(), flags, curcheat); + } - /* add a reload all cheats option */ - item_append("Reload All", nullptr, 0, (void *)2); + /* add a separator */ + item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); + + /* add a reset all option */ + item_append("Reset All", nullptr, 0, (void *)ITEMREF_CHEATS_RESET_ALL); + + /* add a reload all cheats option */ + item_append("Reload All", nullptr, 0, (void *)ITEMREF_CHEATS_RELOAD_ALL); + } } ui_menu_cheat::~ui_menu_cheat() { } + + + + + +/*------------------------------------------------- + menu_autofire - handle the autofire settings + menu +-------------------------------------------------*/ + +ui_menu_autofire::ui_menu_autofire(running_machine &machine, render_container *container) : ui_menu(machine, container) +{ + screen_device_iterator iter(machine.root_device()); + const screen_device *screen = iter.first(); + + if (screen == nullptr) + { + refresh = 60.0; + } + else + { + refresh = ATTOSECONDS_TO_HZ(screen->refresh_attoseconds()); + } +} + +ui_menu_autofire::~ui_menu_autofire() +{ +} + +void ui_menu_autofire::handle() +{ + ioport_field *field; + bool changed = false; + + /* process the menu */ + const ui_menu_event *menu_event = process(0); + + /* handle events */ + if (menu_event != nullptr && menu_event->itemref != nullptr) + { + // menu item is changed using left/right keys only + if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) + { + if (menu_event->itemref == ITEMREF_AUTOFIRE_STATUS) + { + // toggle autofire status + bool autofire_toggle = machine().ioport().get_autofire_toggle(); // (menu_event->iptkey == IPT_UI_LEFT); + machine().ioport().set_autofire_toggle(!autofire_toggle); + changed = true; + } + else if (menu_event->itemref == ITEMREF_AUTOFIRE_DELAY) + { + // change autofire frequency + int autofire_delay = machine().ioport().get_autofire_delay(); + if (menu_event->iptkey == IPT_UI_LEFT) + { + autofire_delay--; + if (autofire_delay < 1) + autofire_delay = 1; + } + else + { + autofire_delay++; + if (autofire_delay > 30) + autofire_delay = 30; + } + machine().ioport().set_autofire_delay(autofire_delay); + changed = true; + } + else + { + // enable autofire on specific button + field = (ioport_field *)menu_event->itemref; + ioport_field::user_settings settings; + field->get_user_settings(settings); + settings.autofire = (menu_event->iptkey == IPT_UI_RIGHT); + field->set_user_settings(settings); + changed = true; + } + } + } + + // if toggle settings changed, redraw menu to reflect new options + if (!changed) + { + changed = (last_toggle != machine().ioport().get_autofire_toggle()); + } + + /* if something changed, rebuild the menu */ + if (changed) + { + reset(UI_MENU_RESET_REMEMBER_REF); + } +} + + +/*------------------------------------------------- + menu_autofire_populate - populate the autofire + menu +-------------------------------------------------*/ + +void ui_menu_autofire::populate() +{ + ioport_field *field; + ioport_port *port; + char temp_text[64]; + + /* add autofire toggle item */ + bool autofire_toggle = machine().ioport().get_autofire_toggle(); + item_append("Autofire Status", (autofire_toggle ? "Disabled" : "Enabled"), + (autofire_toggle ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW), (void *)ITEMREF_AUTOFIRE_STATUS); + + /* iterate over the input ports and add autofire toggle items */ + int menu_items = 0; + for (port = machine().ioport().first_port(); port != nullptr; port = port->next()) + { + bool is_first_button = true; + for (field = port->first_field(); field != nullptr; field = field->next()) + { + if ((field->name()) && ((field->type() >= IPT_BUTTON1 && field->type() <= IPT_BUTTON16))) // IPT_BUTTON1 + 15))) + { + menu_items++; + ioport_field::user_settings settings; + field->get_user_settings(settings); + + if (is_first_button) + { + /* add a separator for each player */ + item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); + is_first_button = false; + } + /* add an autofire item */ + if (!autofire_toggle) + { + // item is enabled and can be switched to values on/off + item_append(field->name(), (settings.autofire ? "On" : "Off"), + (settings.autofire ? MENU_FLAG_LEFT_ARROW : MENU_FLAG_RIGHT_ARROW), (void *)field); + } + else + { + // item is disabled + item_append(field->name(), (settings.autofire ? "On" : "Off"), + MENU_FLAG_DISABLE | MENU_FLAG_INVERT, nullptr); + } + } + } + } + + /* add text item if no buttons found */ + if (menu_items==0) + { + item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); + item_append("No buttons found on this machine!", nullptr, MENU_FLAG_DISABLE, nullptr); + } + + /* add a separator */ + item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); + + /* add autofire delay item */ + int value = machine().ioport().get_autofire_delay(); + snprintf(temp_text, ARRAY_LENGTH(temp_text), "%d = %.2f Hz", value, (float)refresh/value); + if (!autofire_toggle) + { + item_append("Autofire Delay", temp_text, MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW, (void *)ITEMREF_AUTOFIRE_DELAY); + } + else + { + item_append("Autofire Delay", temp_text, MENU_FLAG_DISABLE | MENU_FLAG_INVERT, nullptr); + } + + /* add a separator */ + item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); + + last_toggle = autofire_toggle; +} + + diff --git a/src/emu/ui/cheatopt.h b/src/emu/ui/cheatopt.h index 0358af493ab..a9321df7304 100644 --- a/src/emu/ui/cheatopt.h +++ b/src/emu/ui/cheatopt.h @@ -13,6 +13,12 @@ #ifndef __UI_CHEATOPT_H__ #define __UI_CHEATOPT_H__ +// itemrefs for key menu items +#define ITEMREF_CHEATS_RESET_ALL ((void *) 0x0001) +#define ITEMREF_CHEATS_RELOAD_ALL ((void *) 0x0002) +#define ITEMREF_CHEATS_AUTOFIRE_SETTINGS ((void *) 0x0003) +#define ITEMREF_CHEATS_FIRST_ITEM ((void *) 0x0004) + class ui_menu_cheat : public ui_menu { public: ui_menu_cheat(running_machine &machine, render_container *container); @@ -21,4 +27,23 @@ public: virtual void handle() override; }; + +// itemrefs for key menu items +#define ITEMREF_AUTOFIRE_STATUS ((void *) 0x0001) +#define ITEMREF_AUTOFIRE_DELAY ((void *) 0x0002) +#define ITEMREF_AUTOFIRE_FIRST_BUTTON ((void *) 0x0003) + +class ui_menu_autofire : public ui_menu { +public: + ui_menu_autofire(running_machine &machine, render_container *container); + virtual ~ui_menu_autofire(); + virtual void populate() override; + virtual void handle() override; + +private: + float refresh; + bool last_toggle; +}; + + #endif /* __UI_CHEATOPT_H__ */ diff --git a/src/emu/ui/mainmenu.cpp b/src/emu/ui/mainmenu.cpp index 3ea29398fd2..bd1ac36ee48 100644 --- a/src/emu/ui/mainmenu.cpp +++ b/src/emu/ui/mainmenu.cpp @@ -133,7 +133,7 @@ void ui_menu_main::populate() item_append("Crosshair Options", nullptr, 0, (void *)CROSSHAIR); /* add cheat menu */ - if (machine().options().cheat() && machine().cheat().first() != nullptr) + if (machine().options().cheat()) item_append("Cheat", nullptr, 0, (void *)CHEAT); // add dats menu diff --git a/src/emu/ui/ui.cpp b/src/emu/ui/ui.cpp index c92e700b433..38bfea64fd9 100644 --- a/src/emu/ui/ui.cpp +++ b/src/emu/ui/ui.cpp @@ -1769,6 +1769,21 @@ UINT32 ui_manager::handler_ingame(running_machine &machine, render_container *co if (machine.ui_input().pressed(IPT_UI_THROTTLE)) machine.video().toggle_throttle(); + // toggle autofire + if (machine.ui_input().pressed(IPT_UI_TOGGLE_AUTOFIRE)) + { + if (!machine.options().cheat()) + { + machine.popmessage("Autofire can't be enabled"); + } + else + { + bool autofire_toggle = machine.ioport().get_autofire_toggle(); + machine.ioport().set_autofire_toggle(!autofire_toggle); + machine.popmessage("Autofire %s", autofire_toggle ? "Disabled" : "Enabled"); + } + } + // check for fast forward if (machine.ioport().type_pressed(IPT_UI_FAST_FORWARD)) { From 7c5b979ffae1a2b1e8884146f5b566f9ed2f966d Mon Sep 17 00:00:00 2001 From: Michele Fochi Date: Sat, 13 Feb 2016 21:21:22 +0100 Subject: [PATCH 2/2] Fix osd message --- src/emu/ui/ui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emu/ui/ui.cpp b/src/emu/ui/ui.cpp index 38bfea64fd9..953882f8b07 100644 --- a/src/emu/ui/ui.cpp +++ b/src/emu/ui/ui.cpp @@ -1780,7 +1780,7 @@ UINT32 ui_manager::handler_ingame(running_machine &machine, render_container *co { bool autofire_toggle = machine.ioport().get_autofire_toggle(); machine.ioport().set_autofire_toggle(!autofire_toggle); - machine.popmessage("Autofire %s", autofire_toggle ? "Disabled" : "Enabled"); + machine.popmessage("Autofire %s", autofire_toggle ? "Enabled" : "Disabled"); } }