nost: touch piano mode (#830)

## Link to GitHub Issue or related Pull Request, if one exists
n/a

## Description of change
Touch piano mode. Allows piano keys to be played with the touch screen.
Since the touch screen is still needed for menu navigation (including
during songs) a toggle switch is added so that the user can flip between
navigation mode and piano mode.

The touch targets are pixel-perfect. Don't let the game's piano
animations fool you.

## Testing
This commit is contained in:
bicarus
2026-07-23 15:49:50 -07:00
committed by GitHub
parent 80deb4bbbd
commit 64600826b7
15 changed files with 540 additions and 2 deletions
@@ -2,6 +2,9 @@
// mingw otherwise doesn't load touch stuff
#define _WIN32_WINNT 0x0601
#include <atomic>
#include "nativetouchhook.h"
#include "avs/game.h"
#include "rawinput/touch.h"
#include "inject.h"
@@ -32,6 +35,7 @@ namespace nativetouch {
static decltype(GetSystemMetrics) *GetSystemMetrics_orig = nullptr;
static decltype(GetTouchInputInfo) *GetTouchInputInfo_orig = nullptr;
static std::atomic<TouchInputFilter> touch_input_filter { nullptr };
static bool native_touch_hooked = false;
static bool native_display_initialized = false;
static DWORD native_display_orientation = DMDO_DEFAULT;
@@ -184,6 +188,22 @@ namespace nativetouch {
point->dwFlags = 0;
}
}
const auto filter = touch_input_filter.load(std::memory_order_acquire);
if (point->dwFlags != 0 && filter != nullptr) {
const NativeTouchEvent event {
.id = point->dwID,
.x = point->x / 100,
.y = point->y / 100,
.down = (point->dwFlags & TOUCHEVENTF_DOWN) != 0,
.move = (point->dwFlags & TOUCHEVENTF_MOVE) != 0,
.up = (point->dwFlags & TOUCHEVENTF_UP) != 0,
.synthetic = synthetic,
};
if (filter(event)) {
point->dwFlags = 0;
}
}
}
return result;
@@ -193,6 +213,10 @@ namespace nativetouch {
return native_touch_hooked;
}
void set_input_filter(TouchInputFilter filter) {
touch_input_filter.store(filter, std::memory_order_release);
}
void refresh_contact_lifetime() {
if (settings::REFRESH_CONTACT_LIFETIME_FROM_GAME_LOOP) {
inject::refresh_contact_lifetime();