mirror of
https://github.com/holub/mame
synced 2025-07-01 08:18:59 +03:00
-emu/ioport.cpp: Made default behaviour better.
* If an input is configured to some combination of controls that are not present at all, ignore the setting altogether for the session. * Fixed relative axes with PORT_RESET not responding to absolute controls (MT07685). * Fixed relative axes not responding to an absolute control if the value doesn’t change every frame (eg. holding a stick against the stop). * Changed the scaling for absolute controls assigned to relative axes to make defaults more sane (e.g. arkanoid or spdheat with a joystick). -frontend: Fixed some localisation issues in Analog Controls menu. -docs: Added documentation on assigning inputs.
This commit is contained in:
parent
dce1fd7dfa
commit
d29287e092
@ -3431,11 +3431,10 @@ Debugging Options
|
||||
|
||||
**-[no]debug**
|
||||
|
||||
Activates the integrated debugger. By default, pressing the tilde
|
||||
(**~**) key during emulation breaks into the debugger. MAME also
|
||||
breaks into the debugger after the initial soft reset on startup if
|
||||
the debugger is active. See :ref:`debugger` for information on using
|
||||
the debugger.
|
||||
Activates the integrated debugger. By default, pressing the backtick/tilde
|
||||
(**~**) key during emulation breaks into the debugger. MAME also breaks
|
||||
into the debugger after the initial soft reset on startup if the debugger is
|
||||
active. See :ref:`debugger` for information on using the debugger.
|
||||
|
||||
The default is OFF (**-nodebug**).
|
||||
|
||||
|
@ -17,8 +17,9 @@ issues, developing software to run on vintage systems, creating cheats,
|
||||
ROM hacking, or just investigating how software works.
|
||||
|
||||
Use the ``-debug`` command line option to start MAME with the debugger
|
||||
activated. By default, pressing the tilde (**~**) during emulation
|
||||
breaks into the debugger.
|
||||
activated. By default, pressing the backtick/tilde (**~**) during
|
||||
emulation breaks into the debugger (this can by changed by reassigning
|
||||
the **Break in Debugger** input).
|
||||
|
||||
The exact appearance of the debugger depends on your operating system
|
||||
and the options MAME was built with. All variants of the debugger
|
||||
|
@ -30,7 +30,7 @@ and saving/loading save states.
|
||||
|
||||
**Tab**
|
||||
Toggles the configuration menu.
|
||||
**~** (tilde key)
|
||||
**`**/**~** (backtick/tilde key)
|
||||
Toggles the On-Screen Display.
|
||||
|
||||
If you are running with -debug, this key sends a ‘break’ in emulation.
|
||||
|
@ -30,9 +30,9 @@ starting point.
|
||||
`source code is on GitHub <https://github.com/npwoods/bletchmame>`__.
|
||||
`IV/Play <http://www.mameui.info/>`__ (Microsoft Windows)
|
||||
A simple Windows program for launching systems in MAME. Written in C#, the
|
||||
`souce code is on GitHub <https://github.com/Mataniko/IV-Play>`__.
|
||||
`EmuLoader <http://emuloader.mameworld.info/>`__ (Microsoft Windows)
|
||||
EmuLoader provides a Windows interface for launching systems in multiple
|
||||
`source code is on GitHub <https://github.com/Mataniko/IV-Play>`__.
|
||||
`Emu Loader <http://emuloader.mameworld.info/>`__ (Microsoft Windows)
|
||||
Emu Loader provides a Windows interface for launching systems in multiple
|
||||
emulators, including MAME, Supermodel and DEMUL. Written in Delphi Pascal,
|
||||
the source code is available
|
||||
`on the download page <https://emuloader.mameworld.info/downloads.htm>`__.
|
||||
|
@ -137,6 +137,174 @@ combinations to the **Config Menu**, **Pause** and/or **UI Cancel** inputs to
|
||||
make it possible to use MAME without a keyboard.
|
||||
|
||||
|
||||
.. _ui-inptcfg:
|
||||
|
||||
Configuring inputs
|
||||
------------------
|
||||
|
||||
MAME needs a flexible input system to support the control schemes of the vast
|
||||
array of systems it emulates. In MAME, inputs that only have two distinct
|
||||
states, on and off or active and inactive, are called *digital inputs*, and all
|
||||
other inputs are called *analog inputs*, even if this is not strictly true.
|
||||
|
||||
To assign MAME’s user interface controls or the default inputs for all systems,
|
||||
select **Input (general)** from the main menu during emulation, or select
|
||||
**Configure Options** from the system selection menu and then select **General
|
||||
Inputs**. From there, select a category.
|
||||
|
||||
To assign inputs for the currently running machine, select **Input (this
|
||||
Machine)** from the main menu during emulation. Inputs are grouped by device
|
||||
and sorted by type. You can move between devices with the next group and
|
||||
previous group keys/buttons (**[** and **]** on the keyboard by default).
|
||||
|
||||
The input assignment menus show the name of the emulated input or user interface
|
||||
control on the left, and the input (or combination of inputs) assigned to it on
|
||||
the right.
|
||||
|
||||
To adjust the sensitivity, auto-centre speed and inversion settings, or to see
|
||||
how emulated analog controls react to your inputs, select **Analog Controls**
|
||||
from the main menu during emulation. (This item only appears on the main menu
|
||||
for systems with analog controls.)
|
||||
|
||||
|
||||
.. _ui-inptcfg-digital:
|
||||
|
||||
Digital input settings
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Each emulated digital input has a single assignment setting. For flexibility,
|
||||
MAME can combine host inputs (keys, buttons and joystick axes) using logical
|
||||
**and**, **not** and **or** operations. This is best illustrated with some
|
||||
examples:
|
||||
|
||||
Kbd 1
|
||||
In this simple case, pressing the **1** key on the keyboard activates the
|
||||
emulated input or user interface control.
|
||||
Kbd Down or Joy 1 Down
|
||||
Pressing the down arrow on the keyboard or moving the first joystick down
|
||||
activates the emulated input or user interface control.
|
||||
Kbd P not Kbd Shift not Kbd Right Shift
|
||||
Pressing the **P** key on the keyboard while not pressing either **Shift**
|
||||
key activates the emulated input or user interface control. MAME does not
|
||||
show the implicit **and** operations.
|
||||
Kbd P Kbd Shift or Kbd P Kbd Right Shift
|
||||
Pressing the **P** key while also pressing either of the **Shift** keys
|
||||
activates the emulated input or user interface control. Once again, the
|
||||
implicit **and** operations are not shown.
|
||||
|
||||
(In technical terms, MAME uses Boolean sum of products logic to combine inputs.)
|
||||
|
||||
When a digital input setting is highlighted, the prompt below the menu shows
|
||||
whether selecting it will set the assignment or append an **or** operation to
|
||||
it. Press **UI Left/Right** before selecting the setting to switch between
|
||||
setting or appending an **or** operation. Press **UI Clear** (**Delete** or
|
||||
**Forward Delete** by default) to clear the setting or restore the default
|
||||
assignment.
|
||||
|
||||
When you select a digital input setting, MAME will wait for you to enter an
|
||||
input or a combination of inputs for a logical **and** operation:
|
||||
|
||||
* Press a key or button or move an analog control once to add it to the **and**
|
||||
operation.
|
||||
* Press a key or button or move an analog control twice to add a **not** item to
|
||||
the **and** operation. Pressing the same key or button or moving the same
|
||||
analog control additional times toggles the **not** on and off.
|
||||
* Pressing **UI Cancel** (**Escape** by default) *before* activating any other
|
||||
inputs clears the setting or restores the default assignment.
|
||||
* Pressing **UI Cancel** *after* activating another input leaves the setting
|
||||
unchanged.
|
||||
* The new setting is shown below the menu. Wait one second after activating an
|
||||
input to accept the new setting.
|
||||
|
||||
Here’s how to produce some example settings:
|
||||
|
||||
Kbd 1
|
||||
Press the **1** key on the keyboard once, then wait one second to accept the
|
||||
setting.
|
||||
Kbd F12 Kbd Shift Keyboard Alt
|
||||
Press the **P** key on the keyboard once, press the left **Shift** key once,
|
||||
press the left **Alt** key once, then wait one second to accept the setting.
|
||||
Kbd P not Kbd Shift not Kbd Right Shift
|
||||
Press the **P** key on the keyboard once, press the left **Shift** key
|
||||
twice, press the right **Shift** key twice, then wait one second to accept
|
||||
the setting.
|
||||
|
||||
|
||||
.. _ui-inptcfg-analog:
|
||||
|
||||
Analog input settings
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Each emulated analog input has three assignment settings:
|
||||
|
||||
* Use the *axis setting* to assign an analog axis to control the emulated analog
|
||||
input. The axis setting uses the name of the input with the suffix “Analog”.
|
||||
For example the axis setting for the steering wheel in Ridge Racer is called
|
||||
**Steering Wheel Analog**.
|
||||
* Use the *increment setting* assign an input (or combination of inputs) to
|
||||
increase the value of the emulated analog input. The increment setting uses
|
||||
the name of the input with the suffix “Analog Inc”. For example the increment
|
||||
setting for the steering wheel in Ridge Racer is called **Steering Wheel
|
||||
Analog Inc**. This is a digital input setting – if an analog axis is
|
||||
assigned to it, MAME will not increase the emulated input value at a
|
||||
proportional speed.
|
||||
* Use the *decrement setting* assign an input (or combination of inputs) to
|
||||
decrease the value of the emulated analog input. The decrement setting uses
|
||||
the name of the input with the suffix “Analog Dec”. For example the decrement
|
||||
setting for the steering wheel in Ridge Racer is called **Steering Wheel
|
||||
Analog Dec**. This is a digital input setting – if an analog axis is
|
||||
assigned to it, MAME will not decrease the emulated input value at a
|
||||
proportional speed.
|
||||
|
||||
The increment and decrement settings are most useful for controlling an emulated
|
||||
analog input using digital controls (for example keyboard keys, joystick
|
||||
buttons, or a directional pad). They are configured in the same way as emulated
|
||||
digital inputs (:ref:`see above <ui-inptcfg-digital>`). **It’s important that
|
||||
you don’t assign the same control to the axis setting as well as the increment
|
||||
and/or decrement settings for the same emulated input at the same time.** For
|
||||
example if you assign Ridge Racer’s **Steering Wheel Analog** setting to the X
|
||||
axis of the left analog stick on your controller, you *should not* assign either
|
||||
the **Steering Wheel Analog Inc** or **Steering Wheel Analog Dec** setting to
|
||||
the X axis of the same analog stick.
|
||||
|
||||
To adjust sensitivity, auto-centring speed and inversion settings for emulated
|
||||
analog inputs, or to see how they respond to your settings, select **Analog
|
||||
Controls** from the main menu during emulation. Settings for emulated analog
|
||||
inputs are grouped by device and sorted by type. You can move between devices
|
||||
with the next group and previous group keys/buttons (**[** and **]** on the
|
||||
keyboard by default). The state of the emulated analog inputs is shown below
|
||||
the menu, and reacts in real time. Press the **On Screen Display** key or
|
||||
button (the backtick/tilde key by default on a US ANSI QWERTY keyboard) to hide
|
||||
the menu to make it easier to test without changing settings. Press the same
|
||||
key or button to show the menu again.
|
||||
|
||||
Each emulated input has four settings on the **Analog Controls** menu:
|
||||
|
||||
* The *increment/decrement speed* setting controls how fast the input value
|
||||
increases or decreases in response to the controls assigned to the
|
||||
increment/decrement settings.
|
||||
* The *auto-centering speed* setting controls how fast the input value returns
|
||||
to the neutral state when the controls assigned to the increment/decrement
|
||||
settings are released.
|
||||
* The **reverse** setting allows the direction of the emulated input’s response
|
||||
to controls to be inverted. This applies to controls assigned to the axis
|
||||
setting *and* the increment/decrement settings.
|
||||
* The *sensitivity* setting adjusts the input value’s response to the control
|
||||
assigned to the axis setting.
|
||||
|
||||
|
||||
Use the UI left/right keys or buttons to adjust the highlighted setting.
|
||||
Selecting a setting or pressing the UI clear key/button (**Forward Delete** by
|
||||
default) restores its default value.
|
||||
|
||||
The units for the increment/decrement speed, auto-centering speed and
|
||||
sensitivity settings are tied to the driver/device implementation. The
|
||||
increment/decrement speed and auto-centering speed settings are also tied to the
|
||||
frame rate of the first emulated screen in the system. The response to controls
|
||||
assigned to the increment/decrement settings will change if the system changes
|
||||
the frame rate of this screen.
|
||||
|
||||
|
||||
.. _ui-selmenu:
|
||||
|
||||
The system and software selection menus
|
||||
|
@ -296,6 +296,17 @@ const struct
|
||||
{ INPUT_STRING_None, "None" },
|
||||
};
|
||||
|
||||
|
||||
inline bool input_seq_good(running_machine &machine, input_seq const &seq)
|
||||
{
|
||||
if (INPUT_CODE_INVALID == seq[0])
|
||||
return false;
|
||||
else if (seq.empty())
|
||||
return true;
|
||||
else
|
||||
return input_seq::end_code != machine.input().seq_clean(seq)[0];
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
@ -2122,25 +2133,18 @@ void ioport_manager::load_config(config_type cfg_type, config_level cfg_level, u
|
||||
newseq[seqtype].first.reset();
|
||||
else
|
||||
machine().input().seq_from_tokens(newseq[seqtype].first, seqnode->get_value());
|
||||
newseq[seqtype].second = seqnode->get_value();
|
||||
if (config_type::CONTROLLER != cfg_type)
|
||||
newseq[seqtype].second = seqnode->get_value();
|
||||
}
|
||||
}
|
||||
|
||||
// load into the appropriate place for the config type/level
|
||||
if (config_type::SYSTEM == cfg_type)
|
||||
{
|
||||
load_system_config(*portnode, type, player, newseq);
|
||||
}
|
||||
else if ((config_type::CONTROLLER == cfg_type) && (config_level::DEFAULT != cfg_level))
|
||||
{
|
||||
for (auto &seq : newseq)
|
||||
seq.second = "";
|
||||
load_controller_config(*portnode, type, player, newseq);
|
||||
}
|
||||
else
|
||||
{
|
||||
load_default_config(type, player, newseq);
|
||||
}
|
||||
}
|
||||
|
||||
// after applying the controller config, push that back into the backup, since that is
|
||||
@ -2272,7 +2276,7 @@ bool ioport_manager::load_default_config(
|
||||
{
|
||||
for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
|
||||
{
|
||||
if (newseq[seqtype].first[0] != INPUT_CODE_INVALID)
|
||||
if (input_seq_good(machine(), newseq[seqtype].first))
|
||||
entry.set_seq(seqtype, newseq[seqtype].first);
|
||||
entry.set_cfg(seqtype, newseq[seqtype].second);
|
||||
}
|
||||
@ -2318,7 +2322,7 @@ bool ioport_manager::load_controller_config(
|
||||
// if a sequence was specified, override the developer-specified default for the field
|
||||
for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
|
||||
{
|
||||
if (newseq[seqtype].first[0] != INPUT_CODE_INVALID)
|
||||
if (input_seq_good(machine(), newseq[seqtype].first))
|
||||
field.set_defseq(seqtype, newseq[seqtype].first);
|
||||
}
|
||||
|
||||
@ -2408,7 +2412,7 @@ void ioport_manager::load_system_config(
|
||||
// if a sequence was specified, copy it in
|
||||
for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
|
||||
{
|
||||
if (newseq[seqtype].first[0] != INPUT_CODE_INVALID)
|
||||
if (input_seq_good(machine(), newseq[seqtype].first))
|
||||
field.live().seq[seqtype] = newseq[seqtype].first;
|
||||
field.live().cfg[seqtype] = newseq[seqtype].second;
|
||||
}
|
||||
@ -3557,7 +3561,7 @@ void analog_field::frame_update(running_machine &machine)
|
||||
input_item_class itemclass;
|
||||
s32 rawvalue = machine.input().seq_axis_value(m_field.seq(SEQ_TYPE_STANDARD), itemclass);
|
||||
|
||||
// use programmatically set value if avaiable
|
||||
// use programmatically set value if available
|
||||
if (m_was_written)
|
||||
{
|
||||
m_was_written = false;
|
||||
@ -3567,7 +3571,23 @@ void analog_field::frame_update(running_machine &machine)
|
||||
// if we got an absolute input, it overrides everything else
|
||||
if (itemclass == ITEM_CLASS_ABSOLUTE)
|
||||
{
|
||||
if (m_previousanalog != rawvalue)
|
||||
if (!m_absolute && !m_positionalscale)
|
||||
{
|
||||
// if port is relative, we use the value to simulate the speed of relative movement
|
||||
// sensitivity adjustment is allowed for this mode
|
||||
if (rawvalue)
|
||||
{
|
||||
if (m_field.analog_reset())
|
||||
m_accum = rawvalue / 8;
|
||||
else
|
||||
m_accum += rawvalue / 8;
|
||||
|
||||
// do not bother with other control types if the analog data is changing
|
||||
m_lastdigital = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (m_previousanalog != rawvalue)
|
||||
{
|
||||
// only update if analog value changed
|
||||
m_previousanalog = rawvalue;
|
||||
@ -3580,8 +3600,10 @@ void analog_field::frame_update(running_machine &machine)
|
||||
// if port is absolute, then just return the absolute data supplied
|
||||
m_accum = apply_inverse_sensitivity(rawvalue);
|
||||
}
|
||||
else if (m_positionalscale != 0)
|
||||
else
|
||||
{
|
||||
assert(m_positionalscale); // only way to get here due to previous if
|
||||
|
||||
// if port is positional, we will take the full analog control and divide it
|
||||
// into positions, that way as the control is moved full scale,
|
||||
// it moves through all the positions
|
||||
@ -3591,27 +3613,17 @@ void analog_field::frame_update(running_machine &machine)
|
||||
rawvalue = std::min(rawvalue, m_maximum);
|
||||
m_accum = apply_inverse_sensitivity(rawvalue);
|
||||
}
|
||||
else
|
||||
// if port is relative, we use the value to simulate the speed of relative movement
|
||||
// sensitivity adjustment is allowed for this mode
|
||||
m_accum += rawvalue;
|
||||
|
||||
m_lastdigital = false;
|
||||
// do not bother with other control types if the analog data is changing
|
||||
m_lastdigital = false;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we still have to update fake relative from joystick control
|
||||
if (!m_absolute && m_positionalscale == 0)
|
||||
m_accum += rawvalue;
|
||||
}
|
||||
}
|
||||
|
||||
// if we got it from a relative device, use that as the starting delta
|
||||
// also note that the last input was not a digital one
|
||||
s32 delta = 0;
|
||||
if (itemclass == ITEM_CLASS_RELATIVE && rawvalue != 0)
|
||||
if (itemclass == ITEM_CLASS_RELATIVE && rawvalue)
|
||||
{
|
||||
delta = rawvalue;
|
||||
m_lastdigital = false;
|
||||
@ -3663,9 +3675,9 @@ void analog_field::frame_update(running_machine &machine)
|
||||
s32 center = apply_inverse_sensitivity(m_center);
|
||||
if (m_lastdigital && !keypressed)
|
||||
{
|
||||
// autocenter from positive values
|
||||
if (m_accum >= center)
|
||||
{
|
||||
// autocenter from positive values
|
||||
m_accum -= apply_scale(m_centerdelta, m_keyscalepos);
|
||||
if (m_accum < center)
|
||||
{
|
||||
@ -3673,10 +3685,9 @@ void analog_field::frame_update(running_machine &machine)
|
||||
m_lastdigital = false;
|
||||
}
|
||||
}
|
||||
|
||||
// autocenter from negative values
|
||||
else
|
||||
{
|
||||
// autocenter from negative values
|
||||
m_accum += apply_scale(m_centerdelta, m_keyscaleneg);
|
||||
if (m_accum > center)
|
||||
{
|
||||
|
@ -226,6 +226,7 @@ void menu_analog::handle(event const *ev)
|
||||
{
|
||||
// if selected, reset to default value
|
||||
case IPT_UI_SELECT:
|
||||
case IPT_UI_CLEAR:
|
||||
newval = data.defvalue;
|
||||
break;
|
||||
|
||||
@ -360,25 +361,25 @@ void menu_analog::populate(float &customtop, float &custombottom)
|
||||
{
|
||||
default:
|
||||
case ANALOG_ITEM_KEYSPEED:
|
||||
text = string_format("%s Digital Speed", field->name());
|
||||
text = string_format(_("%1$s Increment/Decrement Speed"), field->name());
|
||||
subtext = string_format("%d", settings.delta);
|
||||
data.cur = settings.delta;
|
||||
break;
|
||||
|
||||
case ANALOG_ITEM_CENTERSPEED:
|
||||
text = string_format("%s Autocenter Speed", field->name());
|
||||
text = string_format(_("%1$s Auto-centering Speed"), field->name());
|
||||
subtext = string_format("%d", settings.centerdelta);
|
||||
data.cur = settings.centerdelta;
|
||||
break;
|
||||
|
||||
case ANALOG_ITEM_REVERSE:
|
||||
text = string_format("%s Reverse", field->name());
|
||||
text = string_format(_("%1$s Reverse"), field->name());
|
||||
subtext.assign(settings.reverse ? "On" : "Off");
|
||||
data.cur = settings.reverse;
|
||||
break;
|
||||
|
||||
case ANALOG_ITEM_SENSITIVITY:
|
||||
text = string_format("%s Sensitivity", field->name());
|
||||
text = string_format(_("%1$s Sensitivity"), field->name());
|
||||
subtext = string_format("%d", settings.sensitivity);
|
||||
data.cur = settings.sensitivity;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user