Files
psxrecomp/runtime/tests/test_host_rumble.c
Shokunin ee56f79087 Mod API: title-supplied host rumble (psx_mod_set_host_rumble)
Some titles compute vibration for every pad but only send it over SIO to a
DualShock (R4 with a presented NeGcon). A trusted mod can now hand the runtime
DualShock motor values per seat; the host pad gets the louder of that and the
guest's SIO motors. Values lapse 8 VBlanks after the last call and are cleared
at every session reset, so nothing can stick on. Opt-in: no title that does
not call it changes. PSX_RUMBLE_TRACE now also logs headless.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 23:25:25 -07:00

38 lines
1.4 KiB
C

/* psx_host_rumble.h: title-supplied rumble merge and expiry. */
#include <stdio.h>
#include "psx_host_rumble.h"
static int s_fail;
#define CHECK(c, m) do { if (!(c)) { fprintf(stderr, "FAIL %s\n", m); ++s_fail; } } while (0)
int main(void) {
PsxHostRumbleSlot slot = {0, 0, 0, 0};
uint8_t small = 0, large = 0;
psx_host_rumble_merge(&slot, 5, &small, &large);
CHECK(small == 0 && large == 0, "never set: guest motors unchanged");
psx_host_rumble_set(&slot, 10, 1, 150);
psx_host_rumble_merge(&slot, 10, &small, &large);
CHECK(small == 0xFF && large == 150, "set: small on, large 150");
small = 0; large = 200;
psx_host_rumble_merge(&slot, 12, &small, &large);
CHECK(large == 200 && small == 0xFF, "louder guest large motor wins");
small = 0; large = 0;
psx_host_rumble_merge(&slot, 10 + PSX_HOST_RUMBLE_TTL - 1, &small, &large);
CHECK(large == 150, "still live just before the TTL");
small = 0; large = 0;
psx_host_rumble_merge(&slot, 10 + PSX_HOST_RUMBLE_TTL, &small, &large);
CHECK(small == 0 && large == 0, "lapses after the TTL without a refresh");
psx_host_rumble_set(&slot, 0xFFFFFFFEu, 0, 999);
small = 0; large = 0;
psx_host_rumble_merge(&slot, 1u, &small, &large);
CHECK(large == 255 && small == 0, "clamped to 255; VBlank wrap handled");
if (s_fail) return 1;
puts("host rumble tests passed");
return 0;
}