From e1ec581f4035e20481c22394ef129ebd66faf995 Mon Sep 17 00:00:00 2001 From: Ghabry Date: Thu, 11 Apr 2024 19:54:05 +0200 Subject: [PATCH 1/4] Fix Finger (Touch) Input on Windows On some devices the ID is not 0-4 but counts upwards. Introduced a new finger ID field to resolve this. --- src/input_source.cpp | 9 +++++++++ src/input_source.h | 9 ++++++--- src/platform/sdl/sdl2_ui.cpp | 36 ++++++++++++++++++++---------------- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/input_source.cpp b/src/input_source.cpp index 25d6f19468..c05b31e3b6 100644 --- a/src/input_source.cpp +++ b/src/input_source.cpp @@ -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; +} diff --git a/src/input_source.h b/src/input_source.h index d42a5754a6..c3b91f0dc4 100644 --- a/src/input_source.h +++ b/src/input_source.h @@ -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; diff --git a/src/platform/sdl/sdl2_ui.cpp b/src/platform/sdl/sdl2_ui.cpp index bc926fe91a..aa1fe91a5d 100644 --- a/src/platform/sdl/sdl2_ui.cpp +++ b/src/platform/sdl/sdl2_ui.cpp @@ -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(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(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 */ From cd7f2120cdea5e0cc192d715b4d4addb457df85b Mon Sep 17 00:00:00 2001 From: Ghabry Date: Thu, 11 Apr 2024 20:00:45 +0200 Subject: [PATCH 2/4] Remove __WINRT__ (OS is not developed anymore by Microsoft) --- src/platform/sdl/main.cpp | 2 +- src/platform/sdl/sdl2_ui.cpp | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/platform/sdl/main.cpp b/src/platform/sdl/main.cpp index f9effd3e49..031a542f8e 100644 --- a/src/platform/sdl/main.cpp +++ b/src/platform/sdl/main.cpp @@ -64,7 +64,7 @@ static void LogCallback(LogLevel lvl, std::string const& msg, LogCallbackUserDat extern "C" int main(int argc, char* argv[]) { std::vector args; -#if defined(_WIN32) && !defined(__WINRT__) +#if defined(_WIN32) // Use widestring args int argc_w; LPWSTR *argv_w = CommandLineToArgvW(GetCommandLineW(), &argc_w); diff --git a/src/platform/sdl/sdl2_ui.cpp b/src/platform/sdl/sdl2_ui.cpp index aa1fe91a5d..6156bf2e1f 100644 --- a/src/platform/sdl/sdl2_ui.cpp +++ b/src/platform/sdl/sdl2_ui.cpp @@ -647,15 +647,10 @@ void Sdl2Ui::SetTitle(const std::string &title) { } bool Sdl2Ui::ShowCursor(bool flag) { -#ifdef __WINRT__ - // Prevent cursor hide in WinRT because it is hidden everywhere while the app runs... - return flag; -#else bool temp_flag = cursor_visible; cursor_visible = flag; SDL_ShowCursor(flag ? SDL_ENABLE : SDL_DISABLE); return temp_flag; -#endif } void Sdl2Ui::ProcessEvent(SDL_Event &evnt) { @@ -975,7 +970,7 @@ void Sdl2Ui::ProcessFingerEvent(SDL_Event& evnt) { } void Sdl2Ui::SetAppIcon() { -#if defined(__WINRT__) || defined(__MORPHOS__) +#if defined(__MORPHOS__) // do nothing #elif defined(_WIN32) SDL_SysWMinfo wminfo; From 5d2a88e7f1d590aada4f3a1a935b7c4d5cfc290f Mon Sep 17 00:00:00 2001 From: Ghabry Date: Thu, 11 Apr 2024 20:20:01 +0200 Subject: [PATCH 3/4] Windows 11: Disable Window rounding This looses pixels in the edges of the game. No error check. Will silently fail when unsupported. --- CMakeLists.txt | 4 ++++ src/platform/sdl/sdl2_ui.cpp | 35 ++++++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 23e1bf4121..40535dc7ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -578,6 +578,10 @@ if(${PLAYER_TARGET_PLATFORM} STREQUAL "SDL2") target_sources(${PROJECT_NAME} PRIVATE src/platform/wiiu/input_buttons.cpp) endif() + + if(WIN32) + target_link_libraries(${PROJECT_NAME} "Dwmapi") + endif() elseif(${PLAYER_TARGET_PLATFORM} STREQUAL "SDL1") target_sources(${PROJECT_NAME} PRIVATE src/platform/sdl/sdl_audio.cpp diff --git a/src/platform/sdl/sdl2_ui.cpp b/src/platform/sdl/sdl2_ui.cpp index 6156bf2e1f..6e5255166d 100644 --- a/src/platform/sdl/sdl2_ui.cpp +++ b/src/platform/sdl/sdl2_ui.cpp @@ -25,6 +25,7 @@ #ifdef _WIN32 # include # include +# include #elif defined(__ANDROID__) # include # include @@ -118,6 +119,19 @@ static uint32_t SelectFormat(const SDL_RendererInfo& rinfo, bool print_all) { return current_fmt; } +#ifdef _WIN32 +HWND GetWindowHandle(SDL_Window* window) { + SDL_SysWMinfo wminfo; + SDL_VERSION(&wminfo.version) + SDL_bool success = SDL_GetWindowWMInfo(window, &wminfo); + + if (success < 0) + Output::Error("Wrong SDL version"); + + return wminfo.info.win.window; +} +#endif + static int FilterUntilFocus(const SDL_Event* evnt); #if defined(USE_KEYBOARD) && defined(SUPPORT_KEYBOARD) @@ -354,8 +368,8 @@ bool Sdl2Ui::RefreshDisplayMode() { window.size_changed = true; auto window_sg = lcf::makeScopeGuard([&]() { - SDL_DestroyWindow(sdl_window); - sdl_window = nullptr; + SDL_DestroyWindow(sdl_window); + sdl_window = nullptr; }); SetAppIcon(); @@ -415,6 +429,13 @@ bool Sdl2Ui::RefreshDisplayMode() { return false; } +#ifdef _WIN32 + HWND window = GetWindowHandle(sdl_window); + // Not using the enum names because this will fail to build when not using a recent Windows 11 SDK + int window_rounding = 1; // DWMWCP_DONOTROUND + DwmSetWindowAttribute(window, 33 /* DWMWA_WINDOW_CORNER_PREFERENCE */, &window_rounding, sizeof(window_rounding)); +#endif + renderer_sg.Dismiss(); window_sg.Dismiss(); } else { @@ -973,14 +994,6 @@ void Sdl2Ui::SetAppIcon() { #if defined(__MORPHOS__) // do nothing #elif defined(_WIN32) - SDL_SysWMinfo wminfo; - SDL_VERSION(&wminfo.version) - SDL_bool success = SDL_GetWindowWMInfo(sdl_window, &wminfo); - - if (success < 0) - Output::Error("Wrong SDL version"); - - HWND window; HINSTANCE handle = GetModuleHandle(NULL); HICON icon = LoadIcon(handle, MAKEINTRESOURCE(23456)); HICON icon_small = (HICON) LoadImage(handle, MAKEINTRESOURCE(23456), IMAGE_ICON, @@ -989,7 +1002,7 @@ void Sdl2Ui::SetAppIcon() { if (icon == NULL || icon_small == NULL) Output::Warning("Could not load window icon."); - window = wminfo.info.win.window; + HWND window = GetWindowHandle(sdl_window); SetClassLongPtr(window, GCLP_HICON, (LONG_PTR) icon); SetClassLongPtr(window, GCLP_HICONSM, (LONG_PTR) icon_small); #else From 13d7e27fc118f987eda7af4128a5aff9a902292f Mon Sep 17 00:00:00 2001 From: Carsten Teibes Date: Sat, 20 Apr 2024 23:26:39 +0200 Subject: [PATCH 4/4] Fix: Add inih to workflow (liblcf dep) --- .github/workflows/stable-compilation.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/stable-compilation.yml b/.github/workflows/stable-compilation.yml index 5971edd831..fd6d4bc711 100644 --- a/.github/workflows/stable-compilation.yml +++ b/.github/workflows/stable-compilation.yml @@ -42,9 +42,10 @@ jobs: apt-get update apt-get install -yqq --no-install-recommends --no-install-suggests \ ca-certificates build-essential cmake ninja-build git \ - libicu-dev libexpat1-dev libsdl2-dev libpng-dev libpixman-1-dev \ - libfmt-dev libfreetype6-dev libharfbuzz-dev libmpg123-dev \ - libsndfile-dev libvorbis-dev libopusfile-dev libspeexdsp-dev \ + libicu-dev libexpat1-dev libinih-dev \ + libsdl2-dev libpng-dev libpixman-1-dev libfmt-dev \ + libfreetype6-dev libharfbuzz-dev libmpg123-dev libsndfile-dev \ + libvorbis-dev libopusfile-dev libspeexdsp-dev \ libdrm-dev libgbm-dev # only needed for sdl2 on debian 11 - name: Clone Repository