Files
MoHadiShibli 7e503478c4 Add the PS4 controller test, motion input and experimental extras
PS4 app: Test controllers, opened with Options or from Actions, shows what
each signed-in user's controller sends, read the way a game reads it, on
the controller page's picture. Holding L3 + R3 opens its menu: change user,
rumble each motor, set or reset the light bar, reset orientation, go back.

Service: the control protocol takes motion ('m'), and info says so. Rumble
reached the page with the large and small motors swapped: fixed.

Page: Settings > Experimental, every switch off by default. Lights, rumble
and touchpad fingers for a DualShock 4 or DualSense over WebHID; trigger
rumble on Xbox controllers and a linked DualSense; motion from a phone or a
linked controller.
2026-10-16 16:08:13 +03:00

46 lines
1.7 KiB
C

/* c4fPadFeedbackParse against buffers read from the console (firmware 10.01). */
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "c4f_vda.h"
static C4fPadFeedback parse(const uint8_t *bytes, size_t n)
{
uint8_t buf[256] = {0};
C4fPadFeedback f;
memcpy(buf, bytes, n);
c4fPadFeedbackParse(buf, sizeof(buf), &f);
return f;
}
int main(void)
{
/* A new controller, player 2: update flag, light bar 40 00 00. */
static const uint8_t red[] = { 0x01, 0, 0, 0, 0, 0x40, 0, 0 };
C4fPadFeedback f = parse(red, sizeof(red));
assert(f.r == 0x40 && f.g == 0 && f.b == 0 && f.large == 0 && f.small == 0);
/* Player 3, signed in: light bar 00 40 00, assigned flag at [16]. */
static const uint8_t green[17] = { 0, 0, 0, 0, 0, 0, 0x40, 0, [16] = 1 };
f = parse(green, sizeof(green));
assert(f.r == 0 && f.g == 0x40 && f.b == 0);
/* A game's hit: the large motor at full for ~300 ms. */
static const uint8_t hit[] = { 0, 0, 0, 0xff, 0, 0, 0x40, 0 };
f = parse(hit, sizeof(hit));
assert(f.large == 0xff && f.small == 0 && f.g == 0x40);
/* Each motor on its own from the PS4 app's controller test: the large motor
* in [3], the small one in [4], the reverse of the DS4 report's order. */
static const uint8_t both[] = { 0x01, 0, 0, 0xc0, 0x30, 0x20, 0, 0x20 };
f = parse(both, sizeof(both));
assert(f.large == 0xc0 && f.small == 0x30 && f.r == 0x20 && f.b == 0x20);
/* Too short to hold the fields: nothing, rather than a misread. */
uint8_t shortBuf[4] = { 1, 2, 3, 4 };
c4fPadFeedbackParse(shortBuf, sizeof(shortBuf), &f);
assert(!f.large && !f.small && !f.r && !f.g && !f.b);
puts("PASS rumble and light bar read from the console's buffer layout");
}