Added support for autofire under cheat menu and available only if cheats

activated.
This commit is contained in:
Michele Fochi 2016-02-13 20:41:19 +01:00
parent e49253b0e0
commit 00aec89192
7 changed files with 284 additions and 16 deletions

View File

@ -730,6 +730,7 @@ void construct_core_types_UI(simple_list<input_type_entry> &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)) )

View File

@ -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));
}

View File

@ -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
};

View File

@ -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<cheat_entry *>(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<ui_menu_autofire>(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;
}

View File

@ -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__ */

View File

@ -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

View File

@ -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))
{