frostoven/Cosmosis

Rework how input works

aggregate1166877 opened this issue · 1 comments

This is currently more a braindump than anything else. It will be used as a basis for reworking existing input.

Related: #88 Rework core engine

1 - Input sources

Input may come from keyboard, mouse, gamepad stick, gamepad button, gamepad
analog button [trigger], or a HOTAS switch.

2 - Responses

Intended response may be a pulsed on-off (eg. toggle lights),
active-until-release (eg. HOTAS switch or hold shift to run), continuous (eg.
partly throttled), or changes streamed infinitely in any direction (eg. looking
around with mouse).

3 - Receiving data

Actions that accept infinite change (such as spinning left infinitely) need to
accept two very different kinds of input: a keyboard button or analog stick
sitting somewhere between 0 and 100% to indicate turn speed, or a mouse that
has not "100%" and speed is determined by player hand movement speed.


Solutions

Simply put, anything that isn't an analog device should pretend to be one. For
example, a keyboard button should either be 0% pressed or 100% pressed.
Meanwhile, a trigger on say an Xbox controller can be 0%, somewhere in between,
or 100%. Same goes for analog sticks.

The mouse is an annoying device because it may be required to act differently
depending on needed use, and acts differently to other devices:

  • If used for looking around while controlling a standing character, raw values
    should be multiplied by a user-chosen mouse speed factor and directly turn
    the character.
  • If used for looking around while controlling a character strapped to a seat,
    raw values should be multiplied by a user-chosen mouse speed factor and
    directly turn the head up to a maximum constraint. Another example is
    if the mouse is used as a flight stick or steering wheel, depending on user
    preference, the stick or wheel should turn more as the mouse is moved
    further, up to a maximum, but not "snap" back into place when the mouse stops
    moving.
  • The mouse may be used in a situation where the aiming "stick" should snap
    back to the center if the mouse is not being moved to simulate feeling like
    an FPS. An example is a fast-moving turret, which acts like a human head but
    is really controlled by a virtual stick.

Whenever a value is no longer 0, a pulse should be triggered - but only once.
No matter what the value changes to, no new pulses should be triggered until
the value is back to 0. Pulses need some deadzone limit (maybe 5%) to prevent
accidental triggering, which the user should be allowed to set. Even though no
new pulses are triggered until the control value hits 0, the value state is
continually updated in case a control needs updated values each frame.

Controls are now, at least with all test cases, truly input agnostic. Additionally, the engine supports remapping digital to analog, analog to digital, with very few exceptions (the exceptions mostly being around unreasonable mouse movement assignments). The engine now even supports realistic slider-to-afterburner mappings for a more realistic flight sim experience should the player want it. This ticket number will be reused after closing if some edge cases were missed.

How input works now:
The ControlSchema TS interface lists all possible options each control may have. Each individual control can be fine-tuned to do exact what it's supposed to, which is how flexibility is achieved. Each control can have any number of bindings, and the binding information of every mapping is explicit about what device the mapping was recorded on. This allows easy deferral to the appropriate input handler, which in turn allows fine-tuning how actions should be handled for every kind of input device.