Skip to content

Commit

Permalink
Merge pull request EasyRPG#3207 from Ghabry/fix-touch-input
Browse files Browse the repository at this point in the history
Windows: Fix touch input, disable window rounding
  • Loading branch information
carstene1ns authored Apr 20, 2024
2 parents 9c29b62 + 13d7e27 commit b313163
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 40 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/stable-compilation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions src/input_source.cpp
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
2 changes: 1 addition & 1 deletion src/platform/sdl/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static void LogCallback(LogLevel lvl, std::string const& msg, LogCallbackUserDat
extern "C" int main(int argc, char* argv[]) {
std::vector<std::string> args;

#if defined(_WIN32) && !defined(__WINRT__)
#if defined(_WIN32)
// Use widestring args
int argc_w;
LPWSTR *argv_w = CommandLineToArgvW(GetCommandLineW(), &argc_w);
Expand Down
78 changes: 45 additions & 33 deletions src/platform/sdl/sdl2_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#ifdef _WIN32
# include <windows.h>
# include <SDL_syswm.h>
# include <dwmapi.h>
#elif defined(__ANDROID__)
# include <jni.h>
# include <SDL_system.h>
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -647,15 +668,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) {
Expand Down Expand Up @@ -940,29 +956,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 All @@ -971,17 +991,9 @@ 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;
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,
Expand All @@ -990,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
Expand Down

0 comments on commit b313163

Please sign in to comment.