Changelog

for the component badgeteam/hid-host v0.4.0
# Changelog

Notable changes per release, newest first. Versions follow
[semantic versioning](https://semver.org), and each release is tagged `vX.Y.Z` and published to the
ESP Component Registry as `badgeteam/hid-host`.

## 0.4.0

### Added

- `hid_keyboard.h`: the keys a report says are down, as a set of usages rather than as whichever
  shape the keyboard used to say it. The boot report names up to six keys by value and cannot say a
  seventh is held; a keyboard with no such limit sends a bitmap under its own report ID instead.
  Both decode to the same state, so a caller writes one code path. State belongs to the caller, so
  two keyboards plugged in at once no longer overwrite each other, and releasing what a keyboard
  held when it was unplugged is the change walk against a zeroed state rather than a second call.
- `hid_layout.c` reads Array items, which is what a keyboard names its keys with: slots holding the
  usages that are down rather than a bit per control. Everything the parser handled until now was a
  Variable item, one control to a fixed slot, so the Variable flag had never been looked at. With
  it come the modifier bitmap and the key bitmap, and `hid_layout_read_key()`,
  `hid_layout_read_modifier()` and `hid_layout_read_key_bit()` to read them.
- Two keyboard descriptors, taking the corpus to twenty nine: a Dell QuietKey captured off a
  machine here, which is the boot shape every keyboard falls back to, and a hand built one
  describing both shapes at once under two report IDs.

### Fixed

- A report saying rollover is refused rather than decoded as an empty keyboard. A keyboard with
  more keys down than it can name says so in place of naming any of them, and the keys that were
  down are still down.
- A report too short to hold the whole key array is refused rather than half read, since the slots
  that were missed are indistinguishable from keys that came up.

### Note

A keyboard report is valid but scores nothing, so `hid_layout_parse()` still returns false for a
keyboard-only descriptor and `hid_layouts_best()` still picks the mouse out of a composite device.
Existing mouse and gamepad callers are unaffected. Ask for a keyboard through `hid_keyboard_open()`.

## 0.3.2

### Added

- `CONTRIBUTING.md`, `docs/ARCHITECTURE.md` and this changelog.
- Fourteen more captured report descriptors, taking the corpus to twenty seven devices: a stick
  with no axes at all, an Xbox 360 guitar, an Xbox 360 call button, the five descriptors the Linux
  kernel substitutes for what a device sent, the BigBen PS3OFMINIPAD's own descriptor, and five
  dumps of hardware people actually own — an iBuffalo SNES pad whose d-pad is a pair of axes, the
  descriptor a DragonRise JS19 really hands out, a Thrustmaster T.16000M with fourteen bit axes, a
  Logitech WingMan Force 3D with vendor data between its stick and its hat, and a Saitek X-56 Rhino
  throttle with thirty six buttons.

## 0.3.1

### Added

- Six more captured descriptors, from controllers published at
  [DJm00n/ControllersInfo](https://github.com/DJm00n/ControllersInfo). Between them they cover
  sixteen bit axes, analog triggers on the simulation page, a hat switch starting mid byte, four
  byte usages that name their own page, and a device with an X axis and no Y.

### Fixed

- The install snippet in the README pointed at a version older than the one with button usages.

## 0.3.0

### Added

- `hid_layout_t.button_usage[]` and `hid_gamepad_state_t.usage_buttons`, which name a button by
  what the descriptor called it rather than by where the report holds it. A device is free to list
  its buttons in any order, and a Stadia controller lists them backwards, so a caller reading by bit
  position called its Capture button "button one".
- `hid_gamepad_state_t.dpad_up` and its three siblings, carrying only the hat switch and a d-pad
  hiding in the buttons. `state.up` and friends still merge in a pushed stick, which is what a menu
  wants; something drawing the pad itself wants the difference.

## 0.2.0

### Added

- `hid_gamepad.h`: directions and buttons out of a report, without a caller having to know whether
  this pad steers with a stick, a hat switch, or four of its buttons. What a button *means* stays
  with the caller.
- The quirk table, holding what a descriptor cannot say. Its one row is the DualShock 3, which sends
  nothing until the host asks it to start reporting and whose d-pad is four ordinary buttons.
- `hid_layout_parse_all()`, `hid_layouts_best()` and `hid_layouts_find()`. The parser reads every
  input report a device describes rather than giving up at the second report ID, so a pad hiding
  behind a keyboard report is still found.
- Push and Pop, without which every global item after one is wrong.
- The axes past X and Y, where a modern pad keeps its right stick; the simulation controls, where a
  pad that names its analog triggers puts them; and consumer AC Pan, where a sideways mouse wheel
  lives.
- `hid_layout_hat_directions()`, for hats of four and of eight positions, resting outside their own
  range.
- Native tests under the address and undefined behaviour sanitizers, and a libFuzzer harness over
  the parser, both in CI.

### Changed

- Buttons split over two contiguous Input items now count as one run.

### Fixed

- A signed overflow on a hostile logical range, found by the fuzzer.
- A field a short report does not hold used to read as zero, which for an absolute axis meant the
  caller was told the stick was pushed hard left rather than nothing at all. Every reader now checks
  that the report holds the field first, and the direction functions write all of their outputs.

## 0.1.0

### Added

- `hid_layout.h`: the report descriptor parser. Reads the axes, the wheel, the hat switch and the
  buttons out of a descriptor by usage rather than by guessing at report lengths, so a device it has
  never seen still works.
- Native tests against descriptors captured from real hardware, and publishing to the ESP Component
  Registry on a tag.