Send proper DS4 timestamp values in our input reports
This commit is contained in:
@@ -75,6 +75,9 @@ namespace platf {
|
|||||||
|
|
||||||
uint8_t client_relative_index;
|
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_rumble;
|
||||||
gamepad_feedback_msg_t last_rgb_led;
|
gamepad_feedback_msg_t last_rgb_led;
|
||||||
};
|
};
|
||||||
@@ -218,6 +221,7 @@ namespace platf {
|
|||||||
assert(!gamepad.gp);
|
assert(!gamepad.gp);
|
||||||
|
|
||||||
gamepad.client_relative_index = id.clientRelativeIndex;
|
gamepad.client_relative_index = id.clientRelativeIndex;
|
||||||
|
gamepad.last_report_ts = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
if (gp_type == Xbox360Wired) {
|
if (gp_type == Xbox360Wired) {
|
||||||
gamepad.gp.reset(vigem_target_x360_alloc());
|
gamepad.gp.reset(vigem_target_x360_alloc());
|
||||||
@@ -272,6 +276,11 @@ namespace platf {
|
|||||||
free_target(int nr) {
|
free_target(int nr) {
|
||||||
auto &gamepad = gamepads[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())) {
|
if (gamepad.gp && vigem_target_is_attached(gamepad.gp.get())) {
|
||||||
auto status = vigem_target_remove(client.get(), gamepad.gp.get());
|
auto status = vigem_target_remove(client.get(), gamepad.gp.get());
|
||||||
if (!VIGEM_SUCCESS(status)) {
|
if (!VIGEM_SUCCESS(status)) {
|
||||||
@@ -1362,6 +1371,42 @@ namespace platf {
|
|||||||
report.bThumbRY = to_ds4_triggerY(gamepad_state.rsY);
|
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.
|
* @brief Updates virtual gamepad with the provided gamepad state.
|
||||||
* @param input The input context.
|
* @param input The input context.
|
||||||
@@ -1387,14 +1432,13 @@ namespace platf {
|
|||||||
if (vigem_target_get_type(gamepad.gp.get()) == Xbox360Wired) {
|
if (vigem_target_get_type(gamepad.gp.get()) == Xbox360Wired) {
|
||||||
x360_update_state(gamepad, gamepad_state);
|
x360_update_state(gamepad, gamepad_state);
|
||||||
status = vigem_target_x360_update(vigem->client.get(), gamepad.gp.get(), gamepad.report.x360);
|
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 {
|
else {
|
||||||
ds4_update_state(gamepad, gamepad_state);
|
ds4_update_state(gamepad, gamepad_state);
|
||||||
status = vigem_target_ds4_update_ex(vigem->client.get(), gamepad.gp.get(), gamepad.report.ds4);
|
ds4_update_ts_and_send(vigem, nr);
|
||||||
}
|
|
||||||
|
|
||||||
if (!VIGEM_SUCCESS(status)) {
|
|
||||||
BOOST_LOG(warning) << "Couldn't send gamepad input to ViGEm ["sv << util::hex(status).to_string_view() << ']';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1509,10 +1553,7 @@ namespace platf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto status = vigem_target_ds4_update_ex(vigem->client.get(), gamepad.gp.get(), gamepad.report.ds4);
|
ds4_update_ts_and_send(vigem, touch.id.globalIndex);
|
||||||
if (!VIGEM_SUCCESS(status)) {
|
|
||||||
BOOST_LOG(warning) << "Couldn't send gamepad touch input to ViGEm ["sv << util::hex(status).to_string_view() << ']';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1540,11 +1581,7 @@ namespace platf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ds4_update_motion(gamepad, motion.motionType, motion.x, motion.y, motion.z);
|
ds4_update_motion(gamepad, motion.motionType, motion.x, motion.y, motion.z);
|
||||||
|
ds4_update_ts_and_send(vigem, motion.id.globalIndex);
|
||||||
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() << ']';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1619,10 +1656,7 @@ namespace platf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto status = vigem_target_ds4_update_ex(vigem->client.get(), gamepad.gp.get(), gamepad.report.ds4);
|
ds4_update_ts_and_send(vigem, battery.id.globalIndex);
|
||||||
if (!VIGEM_SUCCESS(status)) {
|
|
||||||
BOOST_LOG(warning) << "Couldn't send gamepad battery input to ViGEm ["sv << util::hex(status).to_string_view() << ']';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
Reference in New Issue
Block a user