re: the pad word is REMAPPED -- my own bit table was mislabelled throughout

input-pad-read-path.md says of the word the C_PAD_DECODER reads: "There is
no shift and no remap on the way in -- the bit positions are XINPUT's own."
That is wrong. sub_8220D500 rebuilds the word out of XINPUT_GAMEPAD before
anything else sees it, into the game's own numbering.

  bits  0-3   A B X Y
  bits  4-7   left stick  UP DOWN LEFT RIGHT   (+/-20000 of 32767)
  bits  8-11  right stick UP DOWN LEFT RIGHT
  bits 12-15  D-pad       UP DOWN LEFT RIGHT
  bits 16-17  START, BACK
  bits 18-19  LB, RB
  bits 20-21  LT, RT  -- digital, threshold >220 of 255
  bits 22-23  L3, R3

Extracted mechanically from the image, no row typed by hand. The control is
the shape of the result: the 24 assignments land on bits 0..23, each used
exactly once, none repeated. A misdecode does not produce a bijection over a
contiguous range, and coincidence does not put the stick and D-pad
directions in the same order in two aligned nibbles.

So every mask in that page's tables names the wrong button. The 0xE000 x18
site, read there as "B | X | Y", is "D-pad DOWN | LEFT | RIGHT" -- eighteen
sites testing a menu cursor, which is what 18 sites should be.

And its headline negative is REFUTED: "LB and RB are not menu inputs" is
false. They are bound at config fields this+0x70 and this+0x84, LT/RT at
+0x74/+0x80. The negative was searched for 0x0100/0x0200 -- LB and RB in
XINPUT's numbering -- in a word where they live at 0x40000/0x80000. Right
function, right buttons, wrong bit positions, so it could only come back
empty. A negative is only as good as the numbering it was searched in.

Also decodes the ring record: +12 HELD, +16 PRESSED, +20 RELEASED, +28/+32
raw trigger bytes. Edge and level are one struct four bytes apart, which
displaces that page's guess that press-vs-hold was split between GetState
and the XamInputGetKeystrokeEx queue.

The superset claim in that page survives and is untouched: sub_82457038
really does compare every XINPUT_GAMEPAD field, and it really is
XINPUT-layout. This page depends on it.

Not decoded: which output bit means which ACTION, and per-screen sets. 5 of
18 output-bit sites did not resolve to a pad guard, so the output map is a
lower bound -- in particular "START is not tested" is NOT claimed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jc4pciRArGHfxGGhEbwp5t
This commit is contained in:
sylph-decoder
2026-09-01 18:33:42 +00:00
parent 0eb5637329
commit 1e388d0176
7 changed files with 377 additions and 1 deletions

View File

@@ -1,6 +1,23 @@
# The pad read path — what the game asks the console for
**Status: ✅ decoded from the image** for the driver, for the field set, and for
> # 🔴 CORRECTION 2026-09-01 — the bit tables below are MISLABELLED
>
> The word this page calls "XINPUT's own bit positions, no shift and no remap"
> is **remapped**. `sub_8220D500` rebuilds it out of `XINPUT_GAMEPAD` before the
> decoder sees it, into the game's own numbering: `0x1`=A, `0x10`=left-stick UP,
> `0x1000`=D-pad UP, `0x40000`=LB. **Every mask in the two tables below names the
> wrong button**, and the negative *"LB and RB are not menu inputs"* is **false** —
> they are bound at config fields `this+0x70` and `this+0x84`.
>
> ✅ **What survives:** §"What the game reads: the whole of `XINPUT_GAMEPAD`".
> That was read off `sub_82457038`, which really is XINPUT-layout.
>
> Corrected in
> [`input-button-numbering-is-remapped.md`](input-button-numbering-is-remapped.md).
> The sections below are kept for the addresses, which are right; only the
> **labels** are wrong.
**Status: 🔴 partly REFUTED — see the correction above.** ✅ decoded from the image for the driver, for the field set, and for
the complete button set `C_PAD_DECODER` tests; ❔ **not decoded** for which of
those each individual screen acts on, or for the decoder's own output bit
numbering. Instrument: ⟨image⟩ — the executable's own