mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-01 22:30:42 -07:00
iidx: workaround for touch monitors that report contact area (#462)
## Link to GitHub Issue, if one exists n/a ## Description of change When touch monitors send touch area size information (`TOUCHEVENTFMASK_CONTACTAREA` flag and `cxContact` / `cyContact` fields of `TOUCHINPUT` struct) from `GetTouchInputInfo`, IIDX gets confused and does some unexpected things when interacting with the subscreen. As a workaround, hook `GetTouchInputInfo` and clear out the flag & values. This is only done for IIDX AND when -iidxnativetouch is on. ## Testing Tested on a Dell touch monitor, simulating "bad" values.
This commit is contained in:
@@ -526,6 +526,7 @@ set(SOURCE_FILES ${SOURCE_FILES}
|
|||||||
misc/device.cpp
|
misc/device.cpp
|
||||||
misc/eamuse.cpp
|
misc/eamuse.cpp
|
||||||
misc/extdev.cpp
|
misc/extdev.cpp
|
||||||
|
misc/nativetouchhook.cpp
|
||||||
misc/sciunit.cpp
|
misc/sciunit.cpp
|
||||||
misc/sde.cpp
|
misc/sde.cpp
|
||||||
misc/wintouchemu.cpp
|
misc/wintouchemu.cpp
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "hooks/sleephook.h"
|
#include "hooks/sleephook.h"
|
||||||
#include "launcher/options.h"
|
#include "launcher/options.h"
|
||||||
#include "touch/touch.h"
|
#include "touch/touch.h"
|
||||||
|
#include "misc/nativetouchhook.h"
|
||||||
#include "misc/wintouchemu.h"
|
#include "misc/wintouchemu.h"
|
||||||
#include "misc/eamuse.h"
|
#include "misc/eamuse.h"
|
||||||
#include "util/detour.h"
|
#include "util/detour.h"
|
||||||
@@ -332,7 +333,9 @@ namespace games::iidx {
|
|||||||
// need to hook `avs2-core.dll` so AVS win32fs operations go through rom hook
|
// need to hook `avs2-core.dll` so AVS win32fs operations go through rom hook
|
||||||
devicehook_init(avs::core::DLL_INSTANCE);
|
devicehook_init(avs::core::DLL_INSTANCE);
|
||||||
|
|
||||||
if (!NATIVE_TOUCH) {
|
if (NATIVE_TOUCH) {
|
||||||
|
nativetouchhook::hook(avs::game::DLL_INSTANCE);
|
||||||
|
} else {
|
||||||
wintouchemu::FORCE = true;
|
wintouchemu::FORCE = true;
|
||||||
wintouchemu::INJECT_MOUSE_AS_WM_TOUCH = true;
|
wintouchemu::INJECT_MOUSE_AS_WM_TOUCH = true;
|
||||||
wintouchemu::hook_title_ends("beatmania IIDX", "main", avs::game::DLL_INSTANCE);
|
wintouchemu::hook_title_ends("beatmania IIDX", "main", avs::game::DLL_INSTANCE);
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
// enable touch functions - set version to windows 7
|
||||||
|
// mingw otherwise doesn't load touch stuff
|
||||||
|
#define _WIN32_WINNT 0x0601
|
||||||
|
|
||||||
|
#include "wintouchemu.h"
|
||||||
|
|
||||||
|
#include "util/detour.h"
|
||||||
|
#include "util/logging.h"
|
||||||
|
|
||||||
|
#define TOUCH_SIMULATE_FAT_FINGERS 0
|
||||||
|
#define TOUCH_DEBUG_VERBOSE 0
|
||||||
|
|
||||||
|
#if TOUCH_DEBUG_VERBOSE
|
||||||
|
#define log_debug(module, format_str, ...) logger::push( \
|
||||||
|
LOG_FORMAT("M", module, format_str, ## __VA_ARGS__), logger::Style::GREY)
|
||||||
|
#else
|
||||||
|
#define log_debug(module, format_str, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace nativetouchhook {
|
||||||
|
|
||||||
|
static decltype(GetTouchInputInfo) *GetTouchInputInfo_orig = nullptr;
|
||||||
|
|
||||||
|
static void strip_contact_size(PTOUCHINPUT point) {
|
||||||
|
|
||||||
|
#if TOUCH_SIMULATE_FAT_FINGERS
|
||||||
|
point->dwMask |= 0x004;
|
||||||
|
point->cxContact = 80 * 100;
|
||||||
|
point->cyContact = 60 * 100;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// most monitors do not set TOUCHEVENTFMASK_CONTACTAREA, but for
|
||||||
|
// monitors that do set it, IIDX can get very confused (SDVX is not
|
||||||
|
// affected)
|
||||||
|
//
|
||||||
|
// while the test menu and the touch "glow" seem to work properly,
|
||||||
|
// interacting with subscreen menu items or entering PIN becomes
|
||||||
|
// very unpredictable
|
||||||
|
//
|
||||||
|
// to fix this, simply remove the contact area width and height
|
||||||
|
//
|
||||||
|
// note: test menu > I/O > touch test gives 5 numbers:
|
||||||
|
// n: x, y, w, h
|
||||||
|
// where
|
||||||
|
// n is the nth touch input since boot
|
||||||
|
// x, y are coordinates (center of finger)
|
||||||
|
// w, h are contact width and height
|
||||||
|
//
|
||||||
|
// when TOUCHEVENTFMASK_CONTACTAREA is not set, w/h will
|
||||||
|
// automatically be seen as 1x1, which works perfectly fine
|
||||||
|
|
||||||
|
log_debug(
|
||||||
|
"touch::native",
|
||||||
|
"[{}, {}] dwMask = 0x{:x}, cxContact = {}, cyContact = {}",
|
||||||
|
point->x / 100,
|
||||||
|
point->y / 100,
|
||||||
|
point->dwMask,
|
||||||
|
point->cxContact,
|
||||||
|
point->cyContact);
|
||||||
|
|
||||||
|
point->dwMask &= ~(0x004ul); // clear TOUCHEVENTFMASK_CONTACTAREA
|
||||||
|
point->cxContact = 0;
|
||||||
|
point->cyContact = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL WINAPI GetTouchInputInfoHook(
|
||||||
|
HTOUCHINPUT hTouchInput, UINT cInputs, PTOUCHINPUT pInputs, int cbSize) {
|
||||||
|
|
||||||
|
// call the original fist
|
||||||
|
const auto result = GetTouchInputInfo_orig(hTouchInput, cInputs, pInputs, cbSize);
|
||||||
|
if (result == 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < cInputs; i++) {
|
||||||
|
PTOUCHINPUT point = &pInputs[i];
|
||||||
|
strip_contact_size(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hook(HMODULE module) {
|
||||||
|
GetTouchInputInfo_orig = detour::iat_try("GetTouchInputInfo", GetTouchInputInfoHook, module);
|
||||||
|
if (GetTouchInputInfo_orig != nullptr) {
|
||||||
|
log_misc("touch::native", "GetTouchInputInfo hooked");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
namespace nativetouchhook {
|
||||||
|
void hook(HMODULE module);
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user