Support Rumble on Windows

This commit is contained in:
loki
2021-07-18 11:05:34 +02:00
parent 5ff5942258
commit 1fda8f6219
11 changed files with 165 additions and 43 deletions

View File

@@ -46,7 +46,7 @@ void free_id(std::bitset<N> &gamepad_mask, int id) {
gamepad_mask[id] = false;
}
static util::TaskPool::task_id_t task_id {};
static util::TaskPool::task_id_t key_press_repeat_id {};
static std::unordered_map<short, bool> key_press {};
static std::array<std::uint8_t, 5> mouse_press {};
@@ -84,10 +84,13 @@ struct gamepad_t {
};
struct input_t {
input_t(safe::mail_raw_t::event_t<input::touch_port_t> touch_port_event)
input_t(
safe::mail_raw_t::event_t<input::touch_port_t> touch_port_event,
platf::rumble_queue_t rumble_queue)
: active_gamepad_state {},
gamepads(MAX_GAMEPADS),
touch_port_event { std::move(touch_port_event) },
rumble_queue { std::move(rumble_queue) },
mouse_left_button_timeout {},
touch_port { 0, 0, 0, 0, 0, 0, 1.0f } {}
@@ -95,6 +98,7 @@ struct input_t {
std::vector<gamepad_t> gamepads;
safe::mail_raw_t::event_t<input::touch_port_t> touch_port_event;
platf::rumble_queue_t rumble_queue;
util::ThreadPool::task_id_t mouse_left_button_timeout;
@@ -314,13 +318,13 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_MOUSE_BUTTON_PACKET packet
void repeat_key(short key_code) {
// If key no longer pressed, stop repeating
if(!key_press[key_code]) {
task_id = nullptr;
key_press_repeat_id = nullptr;
return;
}
platf::keyboard(platf_input, key_code & 0x00FF, false);
task_id = task_pool.pushDelayed(repeat_key, config::input.key_repeat_period, key_code).task_id;
key_press_repeat_id = task_pool.pushDelayed(repeat_key, config::input.key_repeat_period, key_code).task_id;
}
short map_keycode(short keycode) {
@@ -345,12 +349,12 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_KEYBOARD_PACKET packet) {
auto &pressed = key_press[packet->keyCode];
if(!pressed) {
if(!release) {
if(task_id) {
task_pool.cancel(task_id);
if(key_press_repeat_id) {
task_pool.cancel(key_press_repeat_id);
}
if(config::input.key_repeat_delay.count() > 0) {
task_id = task_pool.pushDelayed(repeat_key, config::input.key_repeat_delay, packet->keyCode).task_id;
key_press_repeat_id = task_pool.pushDelayed(repeat_key, config::input.key_repeat_delay, packet->keyCode).task_id;
}
}
else {
@@ -374,7 +378,7 @@ void passthrough(PNV_SCROLL_PACKET packet) {
platf::scroll(platf_input, util::endian::big(packet->scrollAmt1));
}
int updateGamepads(std::vector<gamepad_t> &gamepads, std::int16_t old_state, std::int16_t new_state) {
int updateGamepads(std::vector<gamepad_t> &gamepads, std::int16_t old_state, std::int16_t new_state, platf::rumble_queue_t rumble_queue) {
auto xorGamepadMask = old_state ^ new_state;
if(!xorGamepadMask) {
return 0;
@@ -400,7 +404,7 @@ int updateGamepads(std::vector<gamepad_t> &gamepads, std::int16_t old_state, std
return -1;
}
if(platf::alloc_gamepad(platf_input, id)) {
if(platf::alloc_gamepad(platf_input, id, std::move(rumble_queue))) {
free_id(gamepadMask, id);
// allocating a gamepad failed: solution: ignore gamepads
// The implementations of platf::alloc_gamepad already has logging
@@ -416,7 +420,7 @@ int updateGamepads(std::vector<gamepad_t> &gamepads, std::int16_t old_state, std
}
void passthrough(std::shared_ptr<input_t> &input, PNV_MULTI_CONTROLLER_PACKET packet) {
if(updateGamepads(input->gamepads, input->active_gamepad_state, packet->activeGamepadMask)) {
if(updateGamepads(input->gamepads, input->active_gamepad_state, packet->activeGamepadMask, input->rumble_queue)) {
return;
}
@@ -552,7 +556,7 @@ void passthrough(std::shared_ptr<input_t> &input, std::vector<std::uint8_t> &&in
}
void reset(std::shared_ptr<input_t> &input) {
task_pool.cancel(task_id);
task_pool.cancel(key_press_repeat_id);
task_pool.cancel(input->mouse_left_button_timeout);
// Ensure input is synchronous, by using the task_pool
@@ -576,7 +580,9 @@ void init() {
}
std::shared_ptr<input_t> alloc(safe::mail_t mail) {
auto input = std::make_shared<input_t>(mail->event<input::touch_port_t>(mail::touch_port));
auto input = std::make_shared<input_t>(
mail->event<input::touch_port_t>(mail::touch_port),
mail->queue<platf::rumble_t>(mail::rumble));
// Workaround to ensure new frames will be captured when a client connects
task_pool.pushDelayed([]() {