Skip to content

Commit

Permalink
Fix Finger (Touch) Input on Windows
Browse files Browse the repository at this point in the history
On some devices the ID is not 0-4 but counts upwards.

Introduced a new finger ID field to resolve this.
  • Loading branch information
Ghabry authored and carstene1ns committed Apr 20, 2024
1 parent 9c29b62 commit e1ec581
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 19 deletions.
9 changes: 9 additions & 0 deletions src/input_source.cpp
Expand Up @@ -334,4 +334,13 @@ void Input::LogSource::UpdateSystem() {
// input log does not record actions outside of logical frames.
}

void Input::TouchInput::Down(int id, int x, int y) {
this->id = id;
this->position = { x, y };
this->pressed = true;
}

void Input::TouchInput::Up() {
id = -1;
pressed = false;
}
9 changes: 6 additions & 3 deletions src/input_source.h
Expand Up @@ -59,10 +59,13 @@ namespace Input {
};

struct TouchInput {
bool pressed = false;
Point position;
void Down(int id, int x, int y);
void Up();

// Fields for use by InputSource. Do not modify in Ui!
// Do not alter the fields from the Ui class, use Down and Up
int id = -1;
Point position;
bool pressed = false;
bool prev_frame_pressed = false;
Game_Clock::time_point touch_begin;
Game_Clock::time_point touch_end;
Expand Down
36 changes: 20 additions & 16 deletions src/platform/sdl/sdl2_ui.cpp
Expand Up @@ -940,29 +940,33 @@ void Sdl2Ui::ProcessFingerEvent(SDL_Event& evnt) {
// We currently ignore swipe gestures
// A finger touch is detected when the fingers go up a brief delay after going down
if (evnt.type == SDL_FINGERDOWN) {
int finger = evnt.tfinger.fingerId;
if (finger < static_cast<int>(finger_input.size())) {
auto& fi = touch_input[finger];
fi.position.x = (evnt.tfinger.x - viewport.x) * main_surface->width() / xw;
fi.position.y = (evnt.tfinger.y - viewport.y) * main_surface->height() / yh;
auto fi = std::find_if(touch_input.begin(), touch_input.end(), [&](const auto& input) {
return input.id == -1;
});
if (fi == touch_input.end()) {
// already tracking 5 fingers
return;
}

#ifdef EMSCRIPTEN
double display_ratio = emscripten_get_device_pixel_ratio();
fi.position.x = (evnt.tfinger.x * display_ratio - viewport.x) * main_surface->width() / xw;
fi.position.y = (evnt.tfinger.y * display_ratio - viewport.y) * main_surface->height() / yh;
double display_ratio = emscripten_get_device_pixel_ratio();
int x = (evnt.tfinger.x * display_ratio - viewport.x) * main_surface->width() / xw;
int y = (evnt.tfinger.y * display_ratio - viewport.y) * main_surface->height() / yh;
#else
fi.position.x = (evnt.tfinger.x - viewport.x) * main_surface->width() / xw;
fi.position.y = (evnt.tfinger.y - viewport.y) * main_surface->height() / yh;
int x = (evnt.tfinger.x - viewport.x) * main_surface->width() / xw;
int y = (evnt.tfinger.y - viewport.y) * main_surface->height() / yh;
#endif

fi.pressed = true;
}
fi->Down(evnt.tfinger.fingerId, x, y);
} else if (evnt.type == SDL_FINGERUP) {
int finger = evnt.tfinger.fingerId;
if (finger < static_cast<int>(finger_input.size())) {
auto& fi = touch_input[finger];
fi.pressed = false;
auto fi = std::find_if(touch_input.begin(), touch_input.end(), [&](const auto& input) {
return input.id == evnt.tfinger.fingerId;
});
if (fi == touch_input.end()) {
// Finger is not tracked
return;
}
fi->Up();
}
#else
/* unused */
Expand Down

0 comments on commit e1ec581

Please sign in to comment.