Forward rumble back to the guest controller (both backends)
The XInput hook used to swallow XInputSetState; now it records the requested left/right motor speeds into the status back-channel (protocol v8->v9: per-slot rumble_left/right in HookStatus). Each frame the host reads them and, only on change, drives the guest's actuator via the active backend: - XInput: XInputSetState on the guest's slot (the open question is whether Steam's RPT virtual pad accepts vibration and routes it to the guest -- needs live RPT); - Steam Input: SteamInput TriggerVibration on the slot's controller handle, with the XInput fallback for slots Steam isn't driving. InputSource gains a set_rumble(slot,left,right) hook (default no-op) implemented by both backends; SteamInputSource now tracks per-slot controller handles + which slots it drives. Verified: hook_selftest (x64 + x86) now asserts the hook records the rumble from XInputSetState into the status; full build x64 + x86 clean; ctest x64 9/9, x86 3/3. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -117,6 +117,10 @@ int run()
|
||||
coop::UiState ui;
|
||||
coop::FrameStats stats;
|
||||
|
||||
// Last rumble forwarded per slot, so we only re-send on change.
|
||||
std::uint16_t last_rumble_l[coop::kMaxPads] = {};
|
||||
std::uint16_t last_rumble_r[coop::kMaxPads] = {};
|
||||
|
||||
while (window.pump_messages())
|
||||
{
|
||||
#ifdef COOP_WITH_STEAM
|
||||
@@ -148,6 +152,22 @@ int run()
|
||||
injection.set_test_input(controllers.test_input()); // toggle lives in the Controllers panel
|
||||
injection.publish(input->pads());
|
||||
injection.tick(); // refresh target liveness before the mirror panels read game_hwnd()
|
||||
|
||||
// Forward the rumble the game requested back to the guest's controller (only
|
||||
// when it changes, to avoid spamming XInputSetState / TriggerVibration).
|
||||
{
|
||||
const coop::HookStatusView hs = injection.hook_status();
|
||||
for (int i = 0; i < static_cast<int>(coop::kMaxPads); ++i)
|
||||
{
|
||||
if (hs.rumble_left[i] != last_rumble_l[i] || hs.rumble_right[i] != last_rumble_r[i])
|
||||
{
|
||||
input->set_rumble(i, hs.rumble_left[i], hs.rumble_right[i]);
|
||||
last_rumble_l[i] = hs.rumble_left[i];
|
||||
last_rumble_r[i] = hs.rumble_right[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const HWND game = injection.game_hwnd();
|
||||
capture.set_target(game);
|
||||
audio.set_target(game);
|
||||
|
||||
Reference in New Issue
Block a user