Skip to content

report_decode #3

Description

@torabit

Why

生バイトの解釈を 1 箇所に閉じる。ここが純関数であれば、以降のフレーム換算とイベント化を実機なしでテストできる。

What

src/report_decode.rs を作る。依存は bitflags だけにする。hidapi と windows に依存させない。

公開する型は以下。

pub struct PadState {
    pub buttons: Buttons,
    pub dpad: Option<Direction>,
    pub left_stick: (u8, u8),
    pub device_ts: u32,
    pub seq: u8,
}

pub enum Direction { N, NE, E, SE, S, SW, W, NW }

pub enum Device { DualSense, DualShock4 }

pub fn decode(device: Device, report: &[u8]) -> Option<PadState>;

Buttons は bitflags で定義する。SQUARE、CROSS、CIRCLE、TRIANGLE、L1、R1、L2、R2、CREATE、OPTIONS、L3、R3、PS、TOUCHPAD。

DualSense の USB 入力レポート (report id 0x01、64 バイト) のオフセット。

byte 内容
0 report id 0x01
1, 2 左スティック X, Y
3, 4 右スティック X, Y
5, 6 L2, R2 アナログ
7 seq_number
8 下位 4bit が dpad hat、bit4 が SQUARE、bit5 が CROSS、bit6 が CIRCLE、bit7 が TRIANGLE
9 bit0 が L1、bit1 が R1、bit2 が L2、bit3 が R2、bit4 が CREATE、bit5 が OPTIONS、bit6 が L3、bit7 が R3
10 bit0 が PS、bit1 が TOUCHPAD
12-15 reserved
16-21 gyro
22-27 accel
28-31 sensor_timestamp (little endian u32)

DualShock 4 の USB 入力レポート (report id 0x01) のオフセット。

byte 内容
0 report id 0x01
1, 2 左スティック X, Y
3, 4 右スティック X, Y
5 下位 4bit が dpad hat、bit4 が SQUARE、bit5 が CROSS、bit6 が CIRCLE、bit7 が TRIANGLE
6 bit0 が L1、bit1 が R1、bit2 が L2、bit3 が R2、bit4 が SHARE、bit5 が OPTIONS、bit6 が L3、bit7 が R3
7 bit0 が PS、bit1 が TOUCHPAD、上位 6bit が 6bit カウンタ
8, 9 L2, R2 アナログ
10, 11 sensor_timestamp (little endian u16)
12 温度
13-18 gyro
19-24 accel

dpad hat の値は 0 が上。時計回りに 1 が右上、2 が右、3 が右下、4 が下、5 が左下、6 が左、7 が左上、8 がニュートラル。8 のとき dpad は None にする。

DualShock 4 は seq 専用のバイトを持たない。byte 7 の上位 6bit を seq に入れる。

このオフセット表は Linux の hid-playstation の構造体定義から書いた。DualSense の実機ダンプは #10 (comment) にある。突き合わせは済んでいて、byte 12 を除いて一致した。

byte 12 は reserved ではなく、レポートごとに 1 進む 2 本目のカウンタになる。上の表はまだ reserved と書いてあるので、実装では byte 12 を読まない。

ダンプは先頭 32 バイトまでなので、byte 32 以降は未検証のまま残る。DualShock 4 の表は実機で検証していない。ダンプと食い違う箇所を見つけたらダンプを正としてオフセットを直し、この表との差分を issue にコメントする。

report[0] が 0x01 でなければ None を返す。レポート長が必要なオフセットに足りなければ None を返す。

ゴール

  • cargo test で、DualSense と DualShock 4 それぞれについて固定バイト列から期待する PadState が得られるテストが通る。DualSense のテストデータは上のダンプの 3 件を使う
  • L1 と R1 の同時押し、dpad の 8 方向すべて、dpad のニュートラル、レポート長不足、report id 不一致のケースがテストされている
  • report_decode.rs の依存が bitflags だけである
  • cargo coupling --check --min-grade=B --max-circular=0 ./src が通る

分解: #1 (comment) / Task 2 / 3c812e1b19b2

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions