The pad, and where it should live

A proposal, not a decision. Nothing here is built and nothing here has moved. It exists so that the move, if it happens, is an afternoon rather than a fortnight of deciding - and so that the reasons survive whether or not it does.

It follows from a question worth quoting: "a shared pad code base would be good, but I don't see how it's not already under orbistoun-inputs."

The short answer is that orbistoun-inputs is a host input crate, and what this project needs from it is a hardware fact. Those look like the same thing and are not.


What is duplicated today

Three repositories in the sibling layout touch a controller:

what it holds why
orbistoun-inputs PadState - host-shaped floats describes what a person's hands are doing
pros-link::pad Pad - unsigned bytes, centre 128 what the target's own structure looks like
pros-link::pads slots, key layouts, conflicts mapping a keyboard onto four pads

The overlap that is real: which buttons exist, what each is called, which keyboard key means which button by default, and how to notice that one key has been bound to two things.

The overlap that looks real and is not: the encoding. That distinction is the whole of D023 and it is still right, though its reasoning has moved - see below.


Why it is not already in orbistoun-inputs

Because that crate solves the half this project does not have, and stops exactly where this project starts.

       orbistoun-inputs                       what prosperous needs
       ----------------                       ---------------------
  gamepad / keyboard                          keyboard
        |                                          |
   PadState (floats)  <-- shared shape? -->   Pad (measured bytes)
        |                                          |
  read by an emulator                         24 bytes on a socket
  that owns both ends                         parsed by a payload

orbistoun-inputs maps host input to a pad model that orbistoun itself reads. It owns the producer and the consumer, so the model between them can be whatever is convenient - and floats are convenient, because that is what a gamepad axis is.

This project's Pad is not read here at all. It is written to a wire and parsed by a payload on the target, so its layout is not ours to choose. It is a measurement, and the reason it is bytes centred on 128 is that this is what the target's own structure is.

So the thing that is missing from orbistoun-inputs is missing because that crate was never about the hardware. Its own documentation says so.


What changed since D023

D023 says two pad models exist on purpose, and it is worth being precise about which part of it has aged.

The conclusion holds. Host-shaped floats and measured wire bytes are different things, neither should become the other, and neither is a worse version of the other.

One premise has not. D023 quotes orbistoun-inputs saying the guest-facing layout "is unmeasured and this type deliberately does not guess at it." That was true when written. It is no longer: the button bits have since been measured, credited to Ghostpad in ACKNOWLEDGEMENTS.md, and three real defects in this project's table were found against them.

That does not make orbistoun wrong to have declined to guess. It makes the guess unnecessary, which is a different situation and one D023 could not have described.

So there is a third thing, which is neither of D023's two models: the measured facts themselves. Not a format, not a mapping - a small pile of things that are true about the hardware, which both projects would otherwise have to learn separately and could disagree about.

An inconsistency in D023, while we are here

D023 lists tap-versus-hold among what is shared, and then argues in its last paragraph that tap-versus-hold does not belong here - because this project forwards absolute state sixty times a second and lets the target decide.

The last paragraph is the right one. The list should not name it. Worth fixing when D023 is next touched, rather than left as two sentences that disagree.


The proposal

A crate holding measurements about the hardware's controller, and nothing else.

Working name orbistoun-pad, because the naming and provenance conventions are orbistoun's and this belongs beside selfish in spirit: facts about the hardware, from citable evidence, usable by anything that needs them.

What goes in

Every one of those is a statement about the hardware that is true regardless of who is asking.

What stays out

Why this shape and not a bigger one

Because a crate of facts depends on nothing, and therefore cannot create a cycle. That was the objection to the obvious version of this - prosperous depending on orbistoun while orbistoun reaches hardware through prosperous's transport - and it disappears entirely once the shared thing has no behaviour to depend on anything.

It also means orbistoun takes on no obligation. It can adopt the crate when it builds the boundary where guest code reads a pad, and until then the crate is simply a place the measurements are written down correctly.


What it costs

Honestly: a third repository in the sibling layout, for something currently about two hundred lines. That is the argument against, and it is not nothing.

The argument for is one measurement. The Ghostpad table was wrong here in three separate ways - invented bits, signed sticks, a trigger missing its digital bit - and each was found by reading somebody else's implementation rather than by any test passing. If that table is ever wrong again, it should be wrong in one place.

What has to be true before it happens


If it does not happen

The duplication stays, and this document becomes the thing that stops it drifting: the bits are here, the poisoned one is named, and the reason Pad::rest() is not Pad::default() is written down. That is most of the value at a fraction of the cost, which is worth saying plainly rather than treating the crate as inevitable.