The lifetime of a button press for peripherals with input
#1
NOTE: This documentation assumes you have the source code for Kodi and peripheral.joystick open in front of you. The fixed-width font is the class or struct you should reference.

When a controller is plugged in and a button is pressed, it starts a large chain reaction of different systems. The button's journey is destined to reach one or more eventual outcomes:
  • An emulator / game add-on
  • Kodi's input system
  • A configuration utility

Game input

Instead of being forced to use a single controller abstraction, game add-ons can request input in the form of any platform controller known to Kodi. For example, a NES emulator receives input events for a NES controller; if the emulator doesn't care, it receives events for a default 360-style controller.

Kodi's input system

If no game is receiving input in fullscreen mode, the button is translated to the default 360-style controller and Kodi's keymapping system takes over from here

Configuration utilities

A configuration utility needs know the button's driver index in order to map it to a feature on its controller. In addition to raw driver events, it also needs to promiscuously monitor the input translated to its platform controller to highlight features in the GUI as they're pressed.

The final system can handle any number of these input listeners, monitoring input in the form of any number of platform controllers

Image

(some class names are outdated, sorry)

I'll attempt to document this process here.
Reply
#2
1. Scanning for peripherals

When Kodi starts up, the peripherals subsystem does a scan for peripherals. Kodi supports several busses including USB. Two new virtual busses have been added:
  • Add-on bus - joysticks are provided by peripheral library binary add-ons
  • Application bus - provides the keyboard, as keyboard input comes from the logical level of the application, not a specific keyboard

This chart shows joysticks being scanned through the peripheral API. The keyboard is always assumed to be attached.

Image
Reply
#3
2. Receiving joystick events

The peripherals subsystem asks the peripheral add-ons for events every frame. Joysticks are polled by the add-on and changes in state are sent back to the peripherals subsystem.

Image
Reply
#4
3. Handling events

Joystick drivers present three kinds of elements:
  • Buttons
  • Hats
  • Axes

Most of the time we want to know how these map to a particular system's controller (Kodi uses the Xbox 360 profile). The controller configuration GUI, however, also needs access to the raw driver elements. There is an event handler for both of these situations.

Image


Note: CGenericJoystickInputHandling and CGenericJoystickButtonMapping are now called CInputHandling and CButtonMapping, respectively.
Reply
#5
4. Handling input for the Game API

When a port is opened by the Game API, it is assigned an input handler that receives driver events involving driver elements, and dispatches events in the form of the desired controller.

Image
Reply
#6
5. Mapping driver elements to the system's controller

This input handler uses an internal button map to translate driver elements to the desired system controller. Currently, all button mapping and translating is done inside peripheral add-ons.

Image

A sample buttonmap.xml from the add-on's userdata folder userdata/addon_data/peripheral.joystick:

Code:
<?xml version="1.0" ?>
<buttonmap>
    <devices>
        <device name="Keyboard" provider="application">
            <controller id="game.controller.default">
                <feature name="x" button="128" />
            </controller>
            <controller id="game.controller.nes">
                <feature name="a" button="90" />
                <feature name="b" button="88" />
                <feature name="down" button="129" />
                <feature name="left" button="130" />
                <feature name="right" button="131" />
                <feature name="select" button="92" />
                <feature name="start" button="13" />
                <feature name="up" button="128" />
            </controller>
        </device>
        <device name="Gamepad F310" provider="cocoa" vid="1133" pid="1133">
            <controller id="game.controller.default">
                <feature name="a" button="0" />
                <feature name="b" button="1" />
                <feature name="x" button="2" />
                <feature name="y" button="3" />
                <feature name="lefttrigger" axis="-4" />
                <feature name="righttrigger" axis="-5" />
            </controller>
        </device>
    </devices>
</buttonmap>
Reply
#7
6. Translating Kodi controller to libretro's "RetroPad"

Unfortunately, libretro uses a fixed controller (called the RetroPad) for all of its cores, instead of a separate controller per system like Kodi. Therefore, each core needs a map of how its Kodi controller translates to the RetroPad.

Image

Sample button map from Nestopia's buttonmap.xml:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<buttonmap>
    <controller id="game.controller.nes" type="joypad">
        <feature name="a" mapto="a"/>
        <feature name="b" mapto="b"/>
        <feature name="start" mapto="start"/>
        <feature name="select" mapto="select"/>
        <feature name="up" mapto="up"/>
        <feature name="down" mapto="down"/>
        <feature name="right" mapto="right"/>
        <feature name="left" mapto="left"/>
    </controller>
    <controller id="game.controller.nes.zapper" type="lightgun">
        <feature name="trigger" mapto="trigger"/>
    </controller>
</buttonmap>
Reply
#8
7. Kodi Input

If the event isn't handled by the Game API, it is sent to a default controller (basically a Xbox 360 controller). The default controller translates it to a key for the file joystick.xml.

Image

joystick.xml belongs to Kodi's keymap system. It maps a standardized Xbox 360 controller to Kodi actions. It looks something like this:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<keymap>
  <global>
    <joystick>
      <a>Select</a>
      <b>Back</b>
      <x>ContextMenu</x>
      <y>FullScreen</y>
      <start>ActivateWindow(PlayerControls)</start>
      <back>Back</back>
      <left>Left</left>
      <right>Right</right>
      <up>Up</up>
      <down>Down</down>
      <leftthumbbutton>Screenshot</leftthumbbutton>
      <rightthumbbutton>ActivateWindow(ShutdownMenu)</rightthumbbutton>
      <leftstickleft>AnalogSeekBack</leftstickleft>
      <leftstickright>AnalogSeekForward</leftstickright>
      <rightstickup>VolumeUp</rightstickup>
      <rightstickdown>VolumeDown</rightstickdown>
      <guide>ActivateWindow(Home)</guide>
      <lefttrigger>ScrollUp</lefttrigger>
      <righttrigger>ScrollDown</righttrigger>
    </joystick>
  </global>
</keymap>

Previously, this was 4,000 lines of XML across many files that encoded a large database of how the buttons/hats/axes reported by the driver map to Kodi actions depending on driver name and platform. This mass of data has been moved to a peripheral add-on; joystick keymapping is now a much more pleasant experience.
Reply
#9
8. Button mapping (controller configuration)

When the controller's button dialog wants the user to press a button, it creates a button mapper for the controller it belongs to.

Image

It then waits for an event. When the event arrives, the dialog tells its button mapper to map the event to the controller feature being mapped.

Image
Reply
#10
9. Keyboard input

Keyboard input is really quite simple. It just emulates a joystick with a large number of buttons. Any event handler down the chain that can handle joystick input can request to monitor the keyboard as a raw device or as any available controller profile.

NES emulators, for example, don't know if their NES controller is being emulated by a joystick or a keyboard. The event handlers are identical for both.

Image
Reply
#11
So I guess the Scotland trip went well? Smile
Reply
#12
great work. Just sent you some bitcoin for the most professional docs ever created for this project^^
Donate: https://kodi.tv/contribute/donate (foundation), 146Gr48FqHM7TPB9q33HHv6uWpgQqdz1yk (BTC personal)
Estuary: Kodis new default skin - ExtendedInfo Script - KodiDevKit
Reply
#13
thanks! i'll start gathering stuff on the wiki once things have been tested and stabalize
Reply
#14
I was gonna say, don't rely on imgur.com to keep them Wink
Reply
#15
crap i just switched to imgur a few months ago cuz my last photo storage site sucked. what img site do you recommend?
Reply

Logout Mark Read Team Forum Stats Members Help
The lifetime of a button press for peripherals with input1