mirror of
https://github.com/holub/mame
synced 2025-06-10 06:47:18 +03:00
docs: Added an introduction to the input system for developers.
emu/ioport.cpp: Removed a long-outdated comment that is now rather misleading.
This commit is contained in:
parent
b9c878e627
commit
dd355e4d68
@ -11,6 +11,7 @@ MAME’s source or working on scripts that run within the MAME framework.
|
|||||||
layout_files
|
layout_files
|
||||||
layout_script
|
layout_script
|
||||||
object_finders
|
object_finders
|
||||||
|
inputsystem
|
||||||
device_memory_interface
|
device_memory_interface
|
||||||
device_rom_interface
|
device_rom_interface
|
||||||
device_disasm_interface
|
device_disasm_interface
|
||||||
|
458
docs/source/techspecs/inputsystem.rst
Normal file
458
docs/source/techspecs/inputsystem.rst
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
.. _inputsystem:
|
||||||
|
|
||||||
|
Input System
|
||||||
|
============
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
:depth: 2
|
||||||
|
|
||||||
|
|
||||||
|
.. _inputsystem-intro:
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
------------
|
||||||
|
|
||||||
|
The variety of systems MAME emulates, as well as the variation in host
|
||||||
|
systems and peripherals, necessitates a flexible, configurable input
|
||||||
|
system.
|
||||||
|
|
||||||
|
Note that the input system is concerned with low-level user input.
|
||||||
|
High-level user interaction, involving things like text input and
|
||||||
|
pointing devices, is handled separately.
|
||||||
|
|
||||||
|
|
||||||
|
.. _inputsystem-components:
|
||||||
|
|
||||||
|
Components
|
||||||
|
----------
|
||||||
|
|
||||||
|
From the emulated system’s point of view, the input system has the
|
||||||
|
following conceptual components.
|
||||||
|
|
||||||
|
Input device
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Input devices supply input values. An input device typically
|
||||||
|
corresponds to a physical device in the host system, for example a
|
||||||
|
keyboard, mouse or game controller. However, there isn’t always a
|
||||||
|
one-to-one correspondence between input devices and physical devices.
|
||||||
|
For example the SDL keyboard provider module aggregates all keyboards
|
||||||
|
into a single input device, and the Win32 lightgun provider module can
|
||||||
|
present two input devices using input from a single mouse.
|
||||||
|
|
||||||
|
Input devices are identified by their device class (keyboard, mouse,
|
||||||
|
joystick or lightgun) and device number within the class. Input
|
||||||
|
provider modules can also supply an implementation-dependent identifier
|
||||||
|
to allow the user to configure stable device numbering.
|
||||||
|
|
||||||
|
Note that input devices are unrelated to emulated devices (``device_t``
|
||||||
|
implementations) despite the similar name.
|
||||||
|
|
||||||
|
Input device item
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Also known as a **control**, and input device item corresponds to a
|
||||||
|
input source that produces a single value. This usually corresponds to
|
||||||
|
a physical control or sensor, for example a joystick axis, a button or
|
||||||
|
an accelerometer.
|
||||||
|
|
||||||
|
MAME supports three kinds of controls: **switches**, **absolute axes**
|
||||||
|
and **relative axes**:
|
||||||
|
|
||||||
|
* Switches produce the value 0 when inactive (released or off) or 1 when
|
||||||
|
active (pressed or on).
|
||||||
|
* Absolute axes produce a value normalised to the range -65,536 to
|
||||||
|
65,536 with zero corresponding to the neutral position.
|
||||||
|
* Relative axes produce a value corresponding to the movement since the
|
||||||
|
previous input update. Mouse-like devices scale values to
|
||||||
|
approximately 512 per nominal 100 DPI pixel.
|
||||||
|
|
||||||
|
Negative axis values should correspond to directions up, to the left,
|
||||||
|
away from the player, or anti-clockwise. For single-ended axes (e.g.
|
||||||
|
pedals or displacement-sensitive triggers and buttons), only zero and
|
||||||
|
the negative portion of the range should be used.
|
||||||
|
|
||||||
|
Switches are used to represent controls that naturally have two distinct
|
||||||
|
states, like buttons and toggle switches.
|
||||||
|
|
||||||
|
Absolute axes are used to represent controls with a definite range
|
||||||
|
and/or neutral position. Examples include steering wheels with limit
|
||||||
|
stops, joystick axes, and displacement-sensitive triggers.
|
||||||
|
|
||||||
|
Relative axes are used to represent controls with an effectively
|
||||||
|
infinite range. Examples include mouse/trackball axes, incremental
|
||||||
|
encoder dials, and gyroscopes.
|
||||||
|
|
||||||
|
Accelerometers and force sensing joystick axes should be represented as
|
||||||
|
absolute axes, even though the range is theoretically open-ended. In
|
||||||
|
practice, there is a limit to the range the transducers can report,
|
||||||
|
which is usually substantially larger than needed for normal operation.
|
||||||
|
|
||||||
|
Input device items are identified by their associated device’s class and
|
||||||
|
device number along with an **input item ID**. MAME supplies item IDs
|
||||||
|
for common types of controls. Additional controls or controls that do
|
||||||
|
not correspond to a common type are dynamically assigned item IDs. MAME
|
||||||
|
supports hundreds to items per input device.
|
||||||
|
|
||||||
|
I/O port field
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
An I/O port field represents an input source in an emulated device or
|
||||||
|
system. Most types of I/O port fields can be assigned one or more
|
||||||
|
combinations of controls, allowing the user to control the input to
|
||||||
|
the emulated system.
|
||||||
|
|
||||||
|
Similarly to input device items, there are multiple types of I/O port
|
||||||
|
fields:
|
||||||
|
|
||||||
|
* **Digital fields** function as switches that produce one of two
|
||||||
|
distinct values. They are used for keyboard keys, eight-way joystick
|
||||||
|
direction switches, toggle switches, photointerruptors and other
|
||||||
|
emulated inputs that function as two-position switches.
|
||||||
|
* **Absolute analog fields** have a range with defined minimum, maximum
|
||||||
|
and neutral positions. They are used for analog joystick axes,
|
||||||
|
displacement-sensitive pedals, paddle knobs, and other emulated inputs
|
||||||
|
with a defined range.
|
||||||
|
* **Relative analog fields** have a range with with defined
|
||||||
|
minimum, maximum and starting positions. On each update, the value
|
||||||
|
accumulates and wraps when it passes either end of the range.
|
||||||
|
Functionally, this is like the output of an up/down counter connected
|
||||||
|
to an incremental encoder. They are used for mouse/trackball axes,
|
||||||
|
steering wheels without limit stops, and other emulated inputs that
|
||||||
|
have no range limits.
|
||||||
|
* DIP switch, configuration and adjuster fields allow the user to set
|
||||||
|
the value through MAME’s user interface.
|
||||||
|
* Additional special field types are used to produce fixed or
|
||||||
|
programmatically generated values.
|
||||||
|
|
||||||
|
A digital field appears to the user as a single assignable input, which
|
||||||
|
accepts switch values.
|
||||||
|
|
||||||
|
An analog field appears to the user as three assignable inputs: an
|
||||||
|
**axis input**, which accepts axis values; and an **increment input**
|
||||||
|
and a **decrement input** which accept switch values.
|
||||||
|
|
||||||
|
Input manager
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The input manager has several responsibilities:
|
||||||
|
|
||||||
|
* Tracking the available input devices in the system.
|
||||||
|
* Reading input values.
|
||||||
|
* Converting between internal identifier values, configuration token
|
||||||
|
strings and display strings.
|
||||||
|
|
||||||
|
In practice, emulated devices and systems rarely interact with the input
|
||||||
|
manager directly. The most common reason to access the input manager is
|
||||||
|
implementing special debug controls, which should be disabled in release
|
||||||
|
builds. Plugins that respond to input need to call the input manager to
|
||||||
|
raed inputs.
|
||||||
|
|
||||||
|
I/O port manager
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The I/O port manager’s primary responsibilities include:
|
||||||
|
|
||||||
|
* Managing assignments of controls to I/O port fields and user interface
|
||||||
|
actions.
|
||||||
|
* Reading input values via the input manager and updating I/O port field
|
||||||
|
values.
|
||||||
|
|
||||||
|
Like the input manager, the I/O port manager is largely transparent to
|
||||||
|
emulated devices and systems. You just need to set up your I/O ports
|
||||||
|
and fields, and the I/O port manager handles the rest.
|
||||||
|
|
||||||
|
|
||||||
|
.. _inputsystem-structures:
|
||||||
|
|
||||||
|
Structures and data types
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
The following data types are used for dealing with input.
|
||||||
|
|
||||||
|
Input code
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
An input code specifies an input device item and how it should be
|
||||||
|
interpreted. It is a tuple consisting of the following values: **device
|
||||||
|
class**, **device number**, **item class**, **item modifier** and **item
|
||||||
|
ID**:
|
||||||
|
|
||||||
|
* The device class, device number and item ID together identify the
|
||||||
|
input device item to read.
|
||||||
|
* The item class specifies the type of output value desired: switch,
|
||||||
|
absolute axis or relative axis. Axis values can be converted to
|
||||||
|
switch values by specifying an appropriate modifier.
|
||||||
|
* The modifier specifies how a value should be interpreted. Valid
|
||||||
|
options depend on the type of input device item and the specified
|
||||||
|
item class.
|
||||||
|
|
||||||
|
If the specified input item is a switch, it can only be read using the
|
||||||
|
switch class, and no modifiers are supported. Attempting to read a
|
||||||
|
switch as an absolute or relative axis always returns zero.
|
||||||
|
|
||||||
|
If the specified input item is an absolute axis, it can be read as an
|
||||||
|
absolute axis or as a switch:
|
||||||
|
|
||||||
|
* Reading an absolute axis item as an absolute axis returns the current
|
||||||
|
state of the control, potentially transformed if a modifier is
|
||||||
|
specified. Supported modifiers are **reverse** to reverse the range
|
||||||
|
of the control, **positive** to map the positive range of the control
|
||||||
|
onto the output (zero corresponding to -65,536 and 65,536
|
||||||
|
corresponding to 65,536), and **negative** to map the negative range
|
||||||
|
of the control onto the output (zero corresponding to -65,536 and
|
||||||
|
-65,536 corresponding to 65,536).
|
||||||
|
* Reading an absolute axis item as a switch returns zero or 1 depending
|
||||||
|
on whether the control is past a threshold in the direction specified
|
||||||
|
by the modifier. Use the **negative** modifier to return 1 when the
|
||||||
|
control is beyond the threshold in the negative direction (up or
|
||||||
|
left), or the **positive** modifier to return 1 when the control is
|
||||||
|
beyond the threshold in the positive direction (down or right). There
|
||||||
|
are two special pairs of modifiers, **left**/**right** and
|
||||||
|
**up**/**down** that are only applicable to the primary X/Y axes of
|
||||||
|
joystick devices. The user can specify a *joystick map* to control
|
||||||
|
how these modifiers interpret joystick movement.
|
||||||
|
* Attempting to read an absolute axis item as a relative axis always
|
||||||
|
returns zero.
|
||||||
|
|
||||||
|
If the specified input item is a relative axis, it can be read as a
|
||||||
|
relative axis or as a switch:
|
||||||
|
|
||||||
|
* Reading a relative axis item as a relative axis returns the change in
|
||||||
|
value since the last input update. The only supported modifier is
|
||||||
|
**reverse**, which negates the value, reversing the direction.
|
||||||
|
* Reading a relative axis as a switch returns 1 if the control moved in
|
||||||
|
the direction specified by the modifier since the last input update.
|
||||||
|
Use the **negative**/**left**/**up** modifiers to return 1 when the
|
||||||
|
control has been moved in the negative direction (up or left), or the
|
||||||
|
**positive**/**right**/**down** modifiers to return 1 when the control
|
||||||
|
has moved in the positive direction (down or right).
|
||||||
|
* Attempting to read a relative axis item as an absolute axis always
|
||||||
|
returns zero.
|
||||||
|
|
||||||
|
There are also special input codes used for specifying how multiple
|
||||||
|
controls are to be combined in an input sequence.
|
||||||
|
|
||||||
|
The most common place you’ll encounter input codes in device and system
|
||||||
|
driver code is when specifying initial assignments for I/O port fields
|
||||||
|
that don’t have default assignments supplied by the core. The
|
||||||
|
``PORT_CODE`` macro is used for this purpose.
|
||||||
|
|
||||||
|
MAME provides macros and helper functions for producing commonly used
|
||||||
|
input codes, including standard keyboard keys and
|
||||||
|
mouse/joystick/lightgun axes and buttons.
|
||||||
|
|
||||||
|
Input sequence
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
An input sequence specifies a combination controls that can be assigned
|
||||||
|
to an input. The name refers to the fact that it is implemented as a
|
||||||
|
sequence container with input codes as elements. It is somewhat
|
||||||
|
misleading, as input sequences are interpreted using instantaneous
|
||||||
|
control values. Input sequences are interpreted differently for switch
|
||||||
|
and axis input.
|
||||||
|
|
||||||
|
Input sequences for switch input must only contain input codes with the
|
||||||
|
item class set to switch along with the special **or** and **not** input
|
||||||
|
codes. The input sequence is interpreted using sum-of-products logic.
|
||||||
|
A **not** code causes the value returned by the immediately following
|
||||||
|
code to be inverted. The conjunction of values returned by successive
|
||||||
|
codes is evaluated until an **or** code is encountered. If the current
|
||||||
|
value is 1 when an **or** code is encountered it is returned, otherwise
|
||||||
|
evaluation continues.
|
||||||
|
|
||||||
|
Input sequences for axis input can contain input codes with the item
|
||||||
|
class set to switch, absolute axis or relative axis along with the
|
||||||
|
special **or** and **not** codes. It’s helpful to think of the input
|
||||||
|
sequence as containing one or more groups of input codes separated by
|
||||||
|
**or** codes:
|
||||||
|
|
||||||
|
* A **not** code causes the value returned by an immediately following
|
||||||
|
switch code to be inverted. It has no effect on absolute or relative
|
||||||
|
axis codes.
|
||||||
|
* Within a group, the conjunction of the values returned by switch codes
|
||||||
|
is evaluated. If it is zero, the group is ignored.
|
||||||
|
* Within a group, multiple axis values of the same type are summed.
|
||||||
|
Values returned by absolute axis codes are summed, and values returned
|
||||||
|
by relative axis codes are summed.
|
||||||
|
* If any absolute axis code in a group returns a non-zero value, the sum
|
||||||
|
of relative axes in the group is ignored. Any non-zero absolute axis
|
||||||
|
value takes precedence over relative axis values.
|
||||||
|
* The same logic is applied when combining group values: group values
|
||||||
|
produced from the same axis type are summed, and values produced from
|
||||||
|
absolute axes take precedence over values produced from relative axes.
|
||||||
|
* After the group values are summed, if the value was produced from
|
||||||
|
absolute axes it is clamped to the range -65,536 to 65,536 (values
|
||||||
|
produced from relative axes are not clamped).
|
||||||
|
|
||||||
|
Emulation code rarely needs to deal with input sequences directly, as
|
||||||
|
they’re handled internally between the I/O port manager and input
|
||||||
|
manager. The input manager also converts input sequences to and from
|
||||||
|
the token strings stored in configuration files and produces text for
|
||||||
|
displaying input sequences to users.
|
||||||
|
|
||||||
|
Plugins with controls or hotkeys need to use input sequences to allow
|
||||||
|
configuration. Utility classes are provided to allow input sequences to
|
||||||
|
be entered by the user in a consistent way, and the input manager can be
|
||||||
|
used for conversions to and from configuration and display strings. It
|
||||||
|
is very rare to need to directly manipulate input sequences.
|
||||||
|
|
||||||
|
|
||||||
|
.. _inputsystem-providermodules:
|
||||||
|
|
||||||
|
Input provider modules
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Input provider modules are part of the OS-dependent layer (OSD), and are
|
||||||
|
not directly exposed to emulation and user interface code. Input
|
||||||
|
provider modules are responsible for detecting available host input
|
||||||
|
devices, setting up input devices for the input manager, and providing
|
||||||
|
callbacks to read the current state of input device items.
|
||||||
|
|
||||||
|
The user is given a choice of input modules to use. One input provider
|
||||||
|
module is used for each of the four input device classes (keyboard,
|
||||||
|
mouse, joystick and lightgun). The available modules depend on the host
|
||||||
|
operating system and OSD implementation. Different modules may use
|
||||||
|
different APIs, support different kinds of devices, or present devices
|
||||||
|
in different ways.
|
||||||
|
|
||||||
|
|
||||||
|
.. _inputsystem-playerpositions:
|
||||||
|
|
||||||
|
Player positions
|
||||||
|
----------------
|
||||||
|
|
||||||
|
MAME uses a concept called *player positions* to help manage input
|
||||||
|
assignments. The number of player positions supported depends on the
|
||||||
|
I/O port field type:
|
||||||
|
|
||||||
|
* Ten player positions are supported for common game inputs, including
|
||||||
|
joystick, pedal, paddle, dial, trackball, lightgun and mouse.
|
||||||
|
* Four player positions are supported for mahjong and hanafuda inputs.
|
||||||
|
* One player position is supported for gambling system inputs.
|
||||||
|
* Other inputs do not use player positions. This includes coin slots,
|
||||||
|
arcade start buttons, tilt switches, service switches and
|
||||||
|
keyboard/keypad keys.
|
||||||
|
|
||||||
|
The user can configure default input assignments per player position for
|
||||||
|
supported I/O port field types which are saved in the file
|
||||||
|
**default.cfg**. These assignments are used for all systems unless the
|
||||||
|
device/system driver supplies its own default assignments, or the user
|
||||||
|
configures system-specific input assignments.
|
||||||
|
|
||||||
|
In order to facilitate development of reusable emulated devices with
|
||||||
|
inputs, particularly slot devices, the I/O port manager automatically
|
||||||
|
renumbers player positions when setting up the emulated system:
|
||||||
|
|
||||||
|
* The I/O port manager starts at player position 1 and begins
|
||||||
|
iterating the emulated device tree in depth first order, starting from
|
||||||
|
the root device.
|
||||||
|
* If a device has I/O port fields that support player positions, they
|
||||||
|
are renumbered to start from the I/O port manager’s current player
|
||||||
|
position.
|
||||||
|
* Before advancing to the next device, the I/O port manager sets its
|
||||||
|
current player position to the last seen player position plus one.
|
||||||
|
|
||||||
|
For a simple example, consider what happens when you run a Sega Mega
|
||||||
|
Drive console with two game pads connected:
|
||||||
|
|
||||||
|
* The I/O port manager starts at player position 1 at the root device.
|
||||||
|
* The first device encountered with I/O port fields that support player
|
||||||
|
positions is the first game pad. The inputs are renumbered to start
|
||||||
|
at player position 1. This has no visible effect, as the I/O port
|
||||||
|
fields are initially numbered starting at player position 1.
|
||||||
|
* Before moving to the next device, the I/O port manager sets its
|
||||||
|
current player position to 2 (the last player position seen plus one).
|
||||||
|
* The next device encountered with I/O port fields that support player
|
||||||
|
positions is the second game pad. The inputs are renumbered to start
|
||||||
|
at player position 2. This avoids I/O port field type conflicts with
|
||||||
|
the first game pad.
|
||||||
|
* Before moving to the next device, the I/O port manager sets its
|
||||||
|
current player position to 3 (the last player position seen plus one).
|
||||||
|
* No more devices with I/O port fields that support player positions are
|
||||||
|
encountered.
|
||||||
|
|
||||||
|
|
||||||
|
.. _inputsystem-updatingfields:
|
||||||
|
|
||||||
|
Updating I/O port fields
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
The I/O port manager updates I/O port fields once for each video frame
|
||||||
|
produced by the first emulated screen in the system. How a field is
|
||||||
|
updated depends on whether it is a digital or analog field.
|
||||||
|
|
||||||
|
Updating digital fields
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Updating digital I/O port fields is simple:
|
||||||
|
|
||||||
|
* The I/O port manager reads the current value for the field’s assigned
|
||||||
|
input sequence (via the input manager).
|
||||||
|
* If the value is zero, the field’s default value is set.
|
||||||
|
* If the value is non-zero, the binary complement of the field’s default
|
||||||
|
value is set.
|
||||||
|
|
||||||
|
Updating absolute analog fields
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Updating absolute analog I/O port fields is more complex due to the need
|
||||||
|
to support a variety of control setups:
|
||||||
|
|
||||||
|
* The I/O port manager reads the current value for the field’s assigned
|
||||||
|
axis input sequence (via the input manager).
|
||||||
|
* If the current value changed since the last update and the input
|
||||||
|
device item that produced the current value was an absolute axis, the
|
||||||
|
field’s value is set to the current value scaled to the correct range,
|
||||||
|
and no further processing is performed.
|
||||||
|
* If the current value is non-zero and the input device device item that
|
||||||
|
produced the current value was a relative axis, the current value is
|
||||||
|
added to the field’s value, scaled by the field’s sensitivity setting.
|
||||||
|
* The I/O port manager reads the current value for the field’s assigned
|
||||||
|
increment input sequence (via the input manager); if this value is
|
||||||
|
non-zero, the field’s increment/decrement speed setting value is added
|
||||||
|
to its value, scaled by its sensitivity setting.
|
||||||
|
* The I/O port manager reads the current value for the field’s assigned
|
||||||
|
decrement input sequence (via the input manager); if this value is
|
||||||
|
non-zero, the field’s increment/decrement speed setting value is
|
||||||
|
subtracted from its value, scaled by its sensitivity setting.
|
||||||
|
* If the current axis input, increment input and decrement input values
|
||||||
|
are all zero, but either or both of the increment input and decrement
|
||||||
|
input values were non-zero the last time the field’s value changed in
|
||||||
|
response to user input, the field’s auto-centring speed setting value
|
||||||
|
is added to or subtracted from its value to move it toward its default
|
||||||
|
value.
|
||||||
|
|
||||||
|
Note that the sensitivity setting value for absolute analog fields
|
||||||
|
affects the response to relative axis input device items and
|
||||||
|
increment/decrement inputs, but it does not affect the response to
|
||||||
|
absolute axis input device items or the auto-centring speed.
|
||||||
|
|
||||||
|
Updating relative analog fields
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Relative analog I/O port fields also need special handling to cater for
|
||||||
|
multiple control setups, but they are a little simpler than absolute
|
||||||
|
analog fields:
|
||||||
|
|
||||||
|
* The I/O port manager reads the current value for the field’s assigned
|
||||||
|
axis input sequence (via the input manager).
|
||||||
|
* If the current value is non-zero and the input device item that
|
||||||
|
produced the current value was an absolute axis, the current value is
|
||||||
|
added to the field’s value, scaled by the field’s sensitivity setting,
|
||||||
|
and no further processing is performed.
|
||||||
|
* If the current value is non-zero and the input device device item that
|
||||||
|
produced the current value was a relative axis, the current value is
|
||||||
|
added to the field’s value, scaled by the field’s sensitivity setting.
|
||||||
|
* The I/O port manager reads the current value for the field’s assigned
|
||||||
|
increment input sequence (via the input manager); if this value is
|
||||||
|
non-zero, the field’s increment/decrement speed setting value is added
|
||||||
|
to its value, scaled by its sensitivity setting.
|
||||||
|
* The I/O port manager reads the current value for the field’s assigned
|
||||||
|
decrement input sequence (via the input manager); if this value is
|
||||||
|
non-zero, the field’s increment/decrement speed setting value is
|
||||||
|
subtracted from its value, scaled by its sensitivity setting.
|
||||||
|
|
||||||
|
Note that the sensitivity setting value for relative analog fields
|
||||||
|
affects the response to all user input.
|
@ -6,88 +6,6 @@
|
|||||||
|
|
||||||
Input/output port handling.
|
Input/output port handling.
|
||||||
|
|
||||||
****************************************************************************
|
|
||||||
|
|
||||||
Theory of operation
|
|
||||||
|
|
||||||
------------
|
|
||||||
OSD controls
|
|
||||||
------------
|
|
||||||
|
|
||||||
There are three types of controls that the OSD can provide as potential
|
|
||||||
input devices: digital controls, absolute analog controls, and relative
|
|
||||||
analog controls.
|
|
||||||
|
|
||||||
Digital controls have only two states: on or off. They are generally
|
|
||||||
mapped to buttons and digital joystick directions (like a gamepad or a
|
|
||||||
joystick hat). The OSD layer must return either 0 (off) or 1 (on) for
|
|
||||||
these types of controls.
|
|
||||||
|
|
||||||
Absolute analog controls are analog in the sense that they return a
|
|
||||||
range of values depending on how much a given control is moved, but they
|
|
||||||
are physically bounded. This means that there is a minimum and maximum
|
|
||||||
limit to how far the control can be moved. They are generally mapped to
|
|
||||||
analog joystick axes, lightguns, most PC steering wheels, and pedals.
|
|
||||||
The OSD layer must determine the minimum and maximum range of each
|
|
||||||
analog device and scale that to a value between -65536 and +65536
|
|
||||||
representing the position of the control. -65536 generally refers to
|
|
||||||
the topmost or leftmost position, while +65536 refers to the bottommost
|
|
||||||
or rightmost position. Note that pedals are a special case here, the
|
|
||||||
OSD layer needs to return half axis as full -65536 to + 65536 range.
|
|
||||||
|
|
||||||
Relative analog controls are analog as well, but are not physically
|
|
||||||
bounded. They can be moved continually in one direction without limit.
|
|
||||||
They are generally mapped to trackballs and mice. Because they are
|
|
||||||
unbounded, the OSD layer can only return delta values since the last
|
|
||||||
read. Because of this, it is difficult to scale appropriately. For
|
|
||||||
MAME's purposes, when mapping a mouse devices to a relative analog
|
|
||||||
control, one pixel of movement should correspond to 512 units. Other
|
|
||||||
analog control types should be scaled to return values of a similar
|
|
||||||
magnitude. Like absolute analog controls, negative values refer to
|
|
||||||
upward or leftward movement, while positive values refer to downward
|
|
||||||
or rightward movement.
|
|
||||||
|
|
||||||
-------------
|
|
||||||
Game controls
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Similarly, the types of controls used by arcade games fall into the same
|
|
||||||
three categories: digital, absolute analog, and relative analog. The
|
|
||||||
tricky part is how to map any arbitrary type of OSD control to an
|
|
||||||
arbitrary type of game control.
|
|
||||||
|
|
||||||
Digital controls: used for game buttons and standard 4/8-way joysticks,
|
|
||||||
as well as many other types of game controls. Mapping an OSD digital
|
|
||||||
control to a game's OSD control is trivial. For OSD analog controls,
|
|
||||||
the MAME core does not directly support mapping any OSD analog devices
|
|
||||||
to digital controls. However, the OSD layer is free to enumerate digital
|
|
||||||
equivalents for analog devices. For example, each analog axis in the
|
|
||||||
Windows OSD code enumerates to two digital controls, one for the
|
|
||||||
negative direction (up/left) and one for the position direction
|
|
||||||
(down/right). When these "digital" inputs are queried, the OSD layer
|
|
||||||
checks the axis position against the center, adding in a dead zone,
|
|
||||||
and returns 0 or 1 to indicate its position.
|
|
||||||
|
|
||||||
Absolute analog controls: used for analog joysticks, lightguns, pedals,
|
|
||||||
and wheel controls. Mapping an OSD absolute analog control to this type
|
|
||||||
is easy. OSD relative analog controls can be mapped here as well by
|
|
||||||
accumulating the deltas and bounding the results. OSD digital controls
|
|
||||||
are mapped to these types of controls in pairs, one for a decrement and
|
|
||||||
one for an increment, but apart from that, operate the same as the OSD
|
|
||||||
relative analog controls by accumulating deltas and applying bounds.
|
|
||||||
The speed of the digital delta is user-configurable per analog input.
|
|
||||||
In addition, most absolute analog control types have an autocentering
|
|
||||||
feature that is activated when using the digital increment/decrement
|
|
||||||
sequences, which returns the control back to the center at a user-
|
|
||||||
controllable speed if no digital sequences are pressed.
|
|
||||||
|
|
||||||
Relative analog controls: used for trackballs and dial controls. Again,
|
|
||||||
mapping an OSD relative analog control to this type is straightforward.
|
|
||||||
OSD absolute analog controls can't map directly to these, but if the OSD
|
|
||||||
layer provides a digital equivalent for each direction, it can be done.
|
|
||||||
OSD digital controls map just like they do for absolute analog controls,
|
|
||||||
except that the accumulated deltas are not bounded, but rather wrap.
|
|
||||||
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user