cardmaker: hook, touch screen hook added

Thanks @domeori https://dev.s-ul.net/domeori/segatools/-/tree/mr-imports
This commit is contained in:
2023-07-14 00:59:10 +02:00
parent 2a6a8bf8b2
commit 01be6ee33c
24 changed files with 952 additions and 0 deletions

View File

@ -14,3 +14,11 @@ void dvd_config_load(struct dvd_config *cfg, const wchar_t *filename)
cfg->enable = GetPrivateProfileIntW(L"dvd", L"enable", 1, filename);
}
void touch_screen_config_load(struct touch_screen_config *cfg, const wchar_t *filename)
{
assert(cfg != NULL);
assert(filename != NULL);
cfg->enable = GetPrivateProfileIntW(L"touch", L"enable", 1, filename);
}

View File

@ -3,5 +3,7 @@
#include <stddef.h>
#include "hooklib/dvd.h"
#include "hooklib/touch.h"
void dvd_config_load(struct dvd_config *cfg, const wchar_t *filename);
void touch_screen_config_load(struct touch_screen_config *cfg, const wchar_t *filename);

View File

@ -27,5 +27,7 @@ hooklib_lib = static_library(
'setupapi.h',
'spike.c',
'spike.h',
'touch.c',
'touch.h',
],
)

171
hooklib/touch.c Normal file
View File

@ -0,0 +1,171 @@
/*
This part (touch screen hook) is mostly taken from spicetools, which is GPL.
This means there can be some license issues if you do use this code in some other places without including source code.
*/
#include <windows.h>
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include "hook/com-proxy.h"
#include "hook/table.h"
#include "hooklib/config.h"
#include "hooklib/dll.h"
#include "hooklib/touch.h"
#include "util/dprintf.h"
/* API hooks */
static int WINAPI hook_GetSystemMetrics(
int nIndex
);
static BOOL WINAPI hook_RegisterTouchWindow(
HWND hwnd,
ULONG ulFlags
);
static BOOL WINAPI hook_GetTouchInputInfo(
HANDLE hTouchInput,
UINT cInputs,
PTOUCHINPUT pInputs,
int cbSize
);
/* Link pointers */
static int (WINAPI *next_GetSystemMetrics)(
int nIndex
);
static BOOL (WINAPI *next_RegisterTouchWindow)(
HWND hwnd,
ULONG ulFlags
);
static BOOL (WINAPI *next_GetTouchInputInfo)(
HANDLE hTouchInput,
UINT cInputs,
PTOUCHINPUT pInputs,
int cbSize
);
static bool touch_hook_initted;
static struct touch_screen_config touch_config;
static const struct hook_symbol touch_hooks[] = {
{
.name = "GetSystemMetrics",
.patch = hook_GetSystemMetrics,
.link = (void **) &next_GetSystemMetrics
},
{
.name = "RegisterTouchWindow",
.patch = hook_RegisterTouchWindow,
.link = (void **) &next_RegisterTouchWindow
},
{
.name = "GetTouchInputInfo",
.patch = hook_GetTouchInputInfo,
.link = (void **) &next_GetTouchInputInfo
},
};
void touch_screen_hook_init(const struct touch_screen_config *cfg, HINSTANCE self)
{
assert(cfg != NULL);
if (!cfg->enable) {
return;
}
if (touch_hook_initted) {
return;
}
touch_hook_initted = true;
memcpy(&touch_config, cfg, sizeof(*cfg));
hook_table_apply(NULL, "user32.dll", touch_hooks, _countof(touch_hooks));
dprintf("TOUCH: hook enabled.\n");
}
// Spicetools misc/wintouchemu.cpp
static int WINAPI hook_GetSystemMetrics(
int nIndex
)
{
if (nIndex == 94) return 0x01 | 0x02 | 0x40 | 0x80;
int orig = next_GetSystemMetrics(nIndex);
return orig;
}
static BOOL WINAPI hook_RegisterTouchWindow(
HWND hwnd,
ULONG ulFlags
)
{
return true;
}
// Converting mouse event to touch event
// Does not work at current stage
static BOOL WINAPI hook_GetTouchInputInfo(
HANDLE hTouchInput,
UINT cInputs,
PTOUCHINPUT pInputs,
int cbSize
)
{
bool result = false;
static bool mouse_state_old = false;
for (UINT input = 0; input < cInputs; input++) {
TOUCHINPUT *touch_input = &pInputs[input];
touch_input->x = 0;
touch_input->y = 0;
touch_input->hSource = NULL;
touch_input->dwID = 0;
touch_input->dwFlags = 0;
touch_input->dwMask = 0;
touch_input->dwTime = 0;
touch_input->dwExtraInfo = 0;
touch_input->cxContact = 0;
touch_input->cyContact = 0;
bool mouse_state = (GetKeyState(VK_LBUTTON) & 0x100) != 0;
if (mouse_state || mouse_state_old) {
POINT cursorPos;
GetCursorPos(&cursorPos);
result = true;
touch_input->x = cursorPos.x * 100;
touch_input->y = cursorPos.y * 100;
touch_input->hSource = hTouchInput;
touch_input->dwID = 0;
touch_input->dwFlags = 0;
if (mouse_state && !mouse_state_old) {
touch_input->dwFlags |= TOUCHEVENTF_DOWN;
} else if (mouse_state && mouse_state_old) {
touch_input->dwFlags |= TOUCHEVENTF_MOVE;
} else if (!mouse_state && mouse_state_old) {
touch_input->dwFlags |= TOUCHEVENTF_UP;
}
touch_input->dwMask = 0;
touch_input->dwTime = 0;
touch_input->dwExtraInfo = 0;
touch_input->cxContact = 0;
touch_input->cyContact = 0;
}
mouse_state_old = mouse_state;
}
return result;
}

14
hooklib/touch.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include <windows.h>
#include <stdbool.h>
struct touch_screen_config {
bool enable;
};
/* Init is not thread safe because API hook init is not thread safe blah
blah blah you know the drill by now. */
void touch_screen_hook_init(const struct touch_screen_config *cfg, HINSTANCE self);