mirror of
https://github.com/LizardByte/Sunshine.git
synced 2025-01-30 03:32:43 +00:00
Send proper DS4 timestamp values in our input reports
This commit is contained in:
parent
a0fcaf7d19
commit
11361ac9b6
@ -75,6 +75,9 @@ namespace platf {
|
||||
|
||||
uint8_t client_relative_index;
|
||||
|
||||
thread_pool_util::ThreadPool::task_id_t repeat_task {};
|
||||
std::chrono::steady_clock::time_point last_report_ts;
|
||||
|
||||
gamepad_feedback_msg_t last_rumble;
|
||||
gamepad_feedback_msg_t last_rgb_led;
|
||||
};
|
||||
@ -218,6 +221,7 @@ namespace platf {
|
||||
assert(!gamepad.gp);
|
||||
|
||||
gamepad.client_relative_index = id.clientRelativeIndex;
|
||||
gamepad.last_report_ts = std::chrono::steady_clock::now();
|
||||
|
||||
if (gp_type == Xbox360Wired) {
|
||||
gamepad.gp.reset(vigem_target_x360_alloc());
|
||||
@ -272,6 +276,11 @@ namespace platf {
|
||||
free_target(int nr) {
|
||||
auto &gamepad = gamepads[nr];
|
||||
|
||||
if (gamepad.repeat_task) {
|
||||
task_pool.cancel(gamepad.repeat_task);
|
||||
gamepad.repeat_task = 0;
|
||||
}
|
||||
|
||||
if (gamepad.gp && vigem_target_is_attached(gamepad.gp.get())) {
|
||||
auto status = vigem_target_remove(client.get(), gamepad.gp.get());
|
||||
if (!VIGEM_SUCCESS(status)) {
|
||||
@ -1362,6 +1371,42 @@ namespace platf {
|
||||
report.bThumbRY = to_ds4_triggerY(gamepad_state.rsY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends DS4 input with updated timestamps and repeats to keep timestamp updated.
|
||||
* @details Some applications require updated timestamps values to register DS4 input.
|
||||
* @param vigem The global ViGEm context object.
|
||||
* @param nr The global gamepad index.
|
||||
*/
|
||||
void
|
||||
ds4_update_ts_and_send(vigem_t *vigem, int nr) {
|
||||
auto &gamepad = vigem->gamepads[nr];
|
||||
|
||||
// Cancel any pending updates. We will requeue one here when we're finished.
|
||||
if (gamepad.repeat_task) {
|
||||
task_pool.cancel(gamepad.repeat_task);
|
||||
gamepad.repeat_task = 0;
|
||||
}
|
||||
|
||||
if (gamepad.gp && vigem_target_is_attached(gamepad.gp.get())) {
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
auto delta_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(now - gamepad.last_report_ts);
|
||||
|
||||
// Timestamp is reported in 5.333us units
|
||||
gamepad.report.ds4.Report.wTimestamp += (uint16_t) (delta_ns.count() / 5333);
|
||||
|
||||
// Send the report to the virtual device
|
||||
auto status = vigem_target_ds4_update_ex(vigem->client.get(), gamepad.gp.get(), gamepad.report.ds4);
|
||||
if (!VIGEM_SUCCESS(status)) {
|
||||
BOOST_LOG(warning) << "Couldn't send gamepad input to ViGEm ["sv << util::hex(status).to_string_view() << ']';
|
||||
return;
|
||||
}
|
||||
|
||||
// Repeat at least every 100ms to keep the 16-bit timestamp field from overflowing
|
||||
gamepad.last_report_ts = now;
|
||||
gamepad.repeat_task = task_pool.pushDelayed(ds4_update_ts_and_send, 100ms, vigem, nr).task_id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates virtual gamepad with the provided gamepad state.
|
||||
* @param input The input context.
|
||||
@ -1387,14 +1432,13 @@ namespace platf {
|
||||
if (vigem_target_get_type(gamepad.gp.get()) == Xbox360Wired) {
|
||||
x360_update_state(gamepad, gamepad_state);
|
||||
status = vigem_target_x360_update(vigem->client.get(), gamepad.gp.get(), gamepad.report.x360);
|
||||
if (!VIGEM_SUCCESS(status)) {
|
||||
BOOST_LOG(warning) << "Couldn't send gamepad input to ViGEm ["sv << util::hex(status).to_string_view() << ']';
|
||||
}
|
||||
}
|
||||
else {
|
||||
ds4_update_state(gamepad, gamepad_state);
|
||||
status = vigem_target_ds4_update_ex(vigem->client.get(), gamepad.gp.get(), gamepad.report.ds4);
|
||||
}
|
||||
|
||||
if (!VIGEM_SUCCESS(status)) {
|
||||
BOOST_LOG(warning) << "Couldn't send gamepad input to ViGEm ["sv << util::hex(status).to_string_view() << ']';
|
||||
ds4_update_ts_and_send(vigem, nr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1509,10 +1553,7 @@ namespace platf {
|
||||
}
|
||||
}
|
||||
|
||||
auto status = vigem_target_ds4_update_ex(vigem->client.get(), gamepad.gp.get(), gamepad.report.ds4);
|
||||
if (!VIGEM_SUCCESS(status)) {
|
||||
BOOST_LOG(warning) << "Couldn't send gamepad touch input to ViGEm ["sv << util::hex(status).to_string_view() << ']';
|
||||
}
|
||||
ds4_update_ts_and_send(vigem, touch.id.globalIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1540,11 +1581,7 @@ namespace platf {
|
||||
}
|
||||
|
||||
ds4_update_motion(gamepad, motion.motionType, motion.x, motion.y, motion.z);
|
||||
|
||||
auto status = vigem_target_ds4_update_ex(vigem->client.get(), gamepad.gp.get(), gamepad.report.ds4);
|
||||
if (!VIGEM_SUCCESS(status)) {
|
||||
BOOST_LOG(warning) << "Couldn't send gamepad motion input to ViGEm ["sv << util::hex(status).to_string_view() << ']';
|
||||
}
|
||||
ds4_update_ts_and_send(vigem, motion.id.globalIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1619,10 +1656,7 @@ namespace platf {
|
||||
}
|
||||
}
|
||||
|
||||
auto status = vigem_target_ds4_update_ex(vigem->client.get(), gamepad.gp.get(), gamepad.report.ds4);
|
||||
if (!VIGEM_SUCCESS(status)) {
|
||||
BOOST_LOG(warning) << "Couldn't send gamepad battery input to ViGEm ["sv << util::hex(status).to_string_view() << ']';
|
||||
}
|
||||
ds4_update_ts_and_send(vigem, battery.id.globalIndex);
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
x
Reference in New Issue
Block a user