forked from Hay1tsme/segatools
Compare commits
4 Commits
develop
...
2025-07-27
Author | SHA1 | Date | |
---|---|---|---|
16dc43cfd8
|
|||
d83e7d3c3a
|
|||
ec00a83d6b
|
|||
d62b64ca5a
|
@ -23,8 +23,6 @@
|
|||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
#include "platform/vfs.h"
|
#include "platform/vfs.h"
|
||||||
#include "platform/system.h"
|
#include "platform/system.h"
|
||||||
#include "platform/openssl.h"
|
|
||||||
|
|
||||||
|
|
||||||
void platform_config_load(struct platform_config *cfg, const wchar_t *filename)
|
void platform_config_load(struct platform_config *cfg, const wchar_t *filename)
|
||||||
{
|
{
|
||||||
@ -43,7 +41,6 @@ void platform_config_load(struct platform_config *cfg, const wchar_t *filename)
|
|||||||
nusec_config_load(&cfg->nusec, filename);
|
nusec_config_load(&cfg->nusec, filename);
|
||||||
vfs_config_load(&cfg->vfs, filename);
|
vfs_config_load(&cfg->vfs, filename);
|
||||||
system_config_load(&cfg->system, filename);
|
system_config_load(&cfg->system, filename);
|
||||||
openssl_config_load(&cfg->openssl, filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void amvideo_config_load(struct amvideo_config *cfg, const wchar_t *filename)
|
void amvideo_config_load(struct amvideo_config *cfg, const wchar_t *filename)
|
||||||
@ -365,12 +362,3 @@ void epay_config_load(struct epay_config *cfg, const wchar_t *filename)
|
|||||||
cfg->enable = GetPrivateProfileIntW(L"epay", L"enable", 1, filename);
|
cfg->enable = GetPrivateProfileIntW(L"epay", L"enable", 1, filename);
|
||||||
cfg->hook = GetPrivateProfileIntW(L"epay", L"hook", 1, filename);
|
cfg->hook = GetPrivateProfileIntW(L"epay", L"hook", 1, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void openssl_config_load(struct openssl_config *cfg, const wchar_t *filename)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
|
|
||||||
cfg->enable = GetPrivateProfileIntW(L"openssl", L"enable", 1, filename);
|
|
||||||
cfg->override = GetPrivateProfileIntW(L"openssl", L"override", 0, filename);
|
|
||||||
}
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
#include "platform/vfs.h"
|
#include "platform/vfs.h"
|
||||||
#include "platform/system.h"
|
#include "platform/system.h"
|
||||||
#include "platform/openssl.h"
|
|
||||||
|
|
||||||
void platform_config_load(
|
void platform_config_load(
|
||||||
struct platform_config *cfg,
|
struct platform_config *cfg,
|
||||||
@ -37,4 +36,3 @@ void nusec_config_load(struct nusec_config *cfg, const wchar_t *filename);
|
|||||||
void pcbid_config_load(struct pcbid_config *cfg, const wchar_t *filename);
|
void pcbid_config_load(struct pcbid_config *cfg, const wchar_t *filename);
|
||||||
void vfs_config_load(struct vfs_config *cfg, const wchar_t *filename);
|
void vfs_config_load(struct vfs_config *cfg, const wchar_t *filename);
|
||||||
void system_config_load(struct system_config *cfg, const wchar_t *filename);
|
void system_config_load(struct system_config *cfg, const wchar_t *filename);
|
||||||
void openssl_config_load(struct openssl_config *cfg, const wchar_t *filename);
|
|
||||||
|
@ -38,7 +38,5 @@ platform_lib = static_library(
|
|||||||
'vfs.h',
|
'vfs.h',
|
||||||
'system.c',
|
'system.c',
|
||||||
'system.h',
|
'system.h',
|
||||||
'openssl.c',
|
|
||||||
'openssl.h'
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -1,116 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <intrin.h>
|
|
||||||
|
|
||||||
#include "hook/table.h"
|
|
||||||
|
|
||||||
#include "hooklib/config.h"
|
|
||||||
|
|
||||||
#include "platform/openssl.h"
|
|
||||||
|
|
||||||
#include "util/dprintf.h"
|
|
||||||
|
|
||||||
/* API hooks */
|
|
||||||
|
|
||||||
static char * __cdecl hook_getenv(const char *name);
|
|
||||||
|
|
||||||
/* Link pointers */
|
|
||||||
|
|
||||||
static char * (__cdecl *next_getenv)(const char *name);
|
|
||||||
|
|
||||||
static bool openssl_hook_initted;
|
|
||||||
static struct openssl_config openssl_config;
|
|
||||||
|
|
||||||
static const struct hook_symbol openssl_hooks[] = {
|
|
||||||
{
|
|
||||||
.name = "getenv",
|
|
||||||
.patch = hook_getenv,
|
|
||||||
.link = (void **) &next_getenv
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static int check_intel_sha_extension() {
|
|
||||||
int n_ids;
|
|
||||||
int is_intel;
|
|
||||||
char vendor[0x20] = {0};
|
|
||||||
int cpui[4] = {0};
|
|
||||||
|
|
||||||
/* OpenSSL 1.0.2 beta to 1.0.2k contain bugs that crash "AM Daemon" due to
|
|
||||||
bad SHA values on processors with the SHA extensions, such as Intel 10th
|
|
||||||
gen CPUs or higher.
|
|
||||||
|
|
||||||
Credits: kagaminehaku */
|
|
||||||
|
|
||||||
__cpuid(cpui, 0);
|
|
||||||
n_ids = cpui[0];
|
|
||||||
|
|
||||||
*((int *) vendor) = cpui[1];
|
|
||||||
*((int *) (vendor + 4)) = cpui[3];
|
|
||||||
*((int *) (vendor + 8)) = cpui[2];
|
|
||||||
|
|
||||||
/* Check that the CPU vendor is Intel */
|
|
||||||
is_intel = (strcmp(vendor, "GenuineIntel") == 0);
|
|
||||||
|
|
||||||
if (is_intel && n_ids >= 7) {
|
|
||||||
__cpuidex(cpui, 7, 0);
|
|
||||||
|
|
||||||
/* SHA extensions supported */
|
|
||||||
return (cpui[1] & (1 << 29)) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT openssl_hook_init(const struct openssl_config *cfg)
|
|
||||||
{
|
|
||||||
assert(cfg != NULL);
|
|
||||||
|
|
||||||
if (!cfg->enable) {
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (openssl_hook_initted) {
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg->override) {
|
|
||||||
dprintf("OpenSSL: hook enabled.\n");
|
|
||||||
} else if (check_intel_sha_extension()) {
|
|
||||||
dprintf("OpenSSL: Intel CPU SHA extension detected, hook enabled.\n");
|
|
||||||
} else {
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
openssl_hook_initted = true;
|
|
||||||
|
|
||||||
memcpy(&openssl_config, cfg, sizeof(*cfg));
|
|
||||||
hook_table_apply(
|
|
||||||
NULL,
|
|
||||||
"msvcr110.dll",
|
|
||||||
openssl_hooks,
|
|
||||||
_countof(openssl_hooks)
|
|
||||||
);
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char * __cdecl hook_getenv(const char *name)
|
|
||||||
{
|
|
||||||
/* Overrides OpenSSL's Intel CPU identification. This disables the OpenSSL
|
|
||||||
code check for SHA extensions. */
|
|
||||||
if (name && strcmp(name, "OPENSSL_ia32cap") == 0) {
|
|
||||||
static char override[] = "~0x20000000";
|
|
||||||
|
|
||||||
dprintf("OpenSSL: Overriding OPENSSL_ia32cap -> %s\n", override);
|
|
||||||
|
|
||||||
return override;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *real_val = next_getenv(name);
|
|
||||||
|
|
||||||
return real_val;
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
struct openssl_config {
|
|
||||||
bool enable;
|
|
||||||
bool override;
|
|
||||||
};
|
|
||||||
|
|
||||||
HRESULT openssl_hook_init(const struct openssl_config *cfg);
|
|
@ -14,7 +14,6 @@
|
|||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
#include "platform/vfs.h"
|
#include "platform/vfs.h"
|
||||||
#include "platform/system.h"
|
#include "platform/system.h"
|
||||||
#include "platform/openssl.h"
|
|
||||||
|
|
||||||
HRESULT platform_hook_init(
|
HRESULT platform_hook_init(
|
||||||
const struct platform_config *cfg,
|
const struct platform_config *cfg,
|
||||||
@ -95,11 +94,5 @@ HRESULT platform_hook_init(
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = openssl_hook_init(&cfg->openssl);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include "platform/pcbid.h"
|
#include "platform/pcbid.h"
|
||||||
#include "platform/vfs.h"
|
#include "platform/vfs.h"
|
||||||
#include "platform/system.h"
|
#include "platform/system.h"
|
||||||
#include "platform/openssl.h"
|
|
||||||
|
|
||||||
struct platform_config {
|
struct platform_config {
|
||||||
struct amvideo_config amvideo;
|
struct amvideo_config amvideo;
|
||||||
@ -29,7 +28,6 @@ struct platform_config {
|
|||||||
struct nusec_config nusec;
|
struct nusec_config nusec;
|
||||||
struct vfs_config vfs;
|
struct vfs_config vfs;
|
||||||
struct system_config system;
|
struct system_config system;
|
||||||
struct openssl_config openssl;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT platform_hook_init(
|
HRESULT platform_hook_init(
|
||||||
|
5
dist/apm3/launch.bat
vendored
5
dist/apm3/launch.bat
vendored
@ -17,13 +17,10 @@ if exist %tmp%\SequenceSetting.json (
|
|||||||
:BEGIN
|
:BEGIN
|
||||||
pushd %~dp0
|
pushd %~dp0
|
||||||
|
|
||||||
set DOORSTOP_DISABLE=TRUE
|
|
||||||
qprocess amdaemon.exe > NUL
|
qprocess amdaemon.exe > NUL
|
||||||
IF %ERRORLEVEL% NEQ 0 start /min "AM Daemon" inject -d -k apm3hook.dll amdaemon.exe -c daemon_config\common.json daemon_config\server.json config_hook.json
|
IF %ERRORLEVEL% NEQ 0 start /min "AM Daemon" inject -d -k apm3hook.dll amdaemon.exe -c daemon_config\common.json daemon_config\server.json config_hook.json
|
||||||
set DOORSTOP_DISABLE=
|
|
||||||
|
|
||||||
REM Add "-screen-fullscreen 0 -popupWindow" if you want to run in windowed mode
|
inject -d -k apm3hook.dll APMV3System -screen-fullscreen 0 -screen-width 1920 -screen-height 1080 -popupWindow -logFile output_log.txt
|
||||||
inject -d -k apm3hook.dll APMV3System -logFile output_log.txt
|
|
||||||
|
|
||||||
if exist %tmp%\segaboot (
|
if exist %tmp%\segaboot (
|
||||||
del %tmp%\segaboot
|
del %tmp%\segaboot
|
||||||
|
25
dist/fgo/segatools.ini
vendored
25
dist/fgo/segatools.ini
vendored
@ -194,20 +194,19 @@ stickDeadzone=7849
|
|||||||
[keyboard]
|
[keyboard]
|
||||||
; Keyboard bindings:
|
; Keyboard bindings:
|
||||||
|
|
||||||
; Keyboard movement
|
; Stick controls (default: WASD)
|
||||||
; Default is WASD keys for Joystick movemnt
|
|
||||||
up=0x57
|
up=0x57
|
||||||
down=0x53
|
|
||||||
left=0x41
|
left=0x41
|
||||||
|
down=0x53
|
||||||
right=0x44
|
right=0x44
|
||||||
|
|
||||||
; Dash button. Default is the Left Shift,
|
; Attack (default: Space)
|
||||||
dash=0xA0
|
attack=0x20
|
||||||
; Cycle Target button. Default is the F key.
|
; Dash (default: LSHIFT)
|
||||||
target=0x46
|
dash=0xa0
|
||||||
; Attack button, Default is the Right Mouse Button.
|
; Change Target (default: J)
|
||||||
attack=0x02
|
target=0x4A
|
||||||
; Noble Phantasm button. Default is the Spacebar
|
; Re-center camera (default: K)
|
||||||
np=0x20
|
camera=0x4B
|
||||||
; Center Camera, Default is the C key
|
; Noble Phantasm (default: L)
|
||||||
camera=0x43
|
np=0x4C
|
||||||
|
3
dist/idac/segatools.ini
vendored
3
dist/idac/segatools.ini
vendored
@ -235,9 +235,6 @@ viewChg=2
|
|||||||
; This is not possible on most devices, so we set the left and right button again.
|
; This is not possible on most devices, so we set the left and right button again.
|
||||||
left=7
|
left=7
|
||||||
right=8
|
right=8
|
||||||
; Additional mapping for up and down buttons in DPad.
|
|
||||||
up=4
|
|
||||||
down=3
|
|
||||||
; Button mappings for the simulated six-speed shifter.
|
; Button mappings for the simulated six-speed shifter.
|
||||||
shiftDn=6
|
shiftDn=6
|
||||||
shiftUp=5
|
shiftUp=5
|
||||||
|
@ -663,21 +663,4 @@ Enables the Thinca emulation. This will allow you to enable E-Money on compatibl
|
|||||||
|
|
||||||
Default: `1`
|
Default: `1`
|
||||||
|
|
||||||
Enables hooking of respective Thinca DLL functions to emulate the existence of E-Money. This cannot be used with a real E-Money server.
|
Enables hooking of respective Thinca DLL functions to emulate the existence of E-Money. This cannot be used with a real E-Money server.
|
||||||
|
|
||||||
## `[openssl]`
|
|
||||||
|
|
||||||
Configure the OpenSSL SHA extension bug hook.
|
|
||||||
|
|
||||||
### `enable`
|
|
||||||
|
|
||||||
Default: `1`
|
|
||||||
|
|
||||||
Enables the OpenSSL hook to fix the SHA extension bug on Intel CPUs.
|
|
||||||
|
|
||||||
### `override`
|
|
||||||
|
|
||||||
Default: `0`
|
|
||||||
|
|
||||||
Enables the override to always hook the OpenSSL env variable. By default the
|
|
||||||
hook is only applied to Intel CPUs with the SHA extension present.
|
|
@ -1,4 +1,9 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <dinput.h>
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <wchar.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "apm3io/backend.h"
|
#include "apm3io/backend.h"
|
||||||
@ -20,6 +25,9 @@ static HRESULT apm3_di_config_apply(const struct apm3_di_config *cfg);
|
|||||||
static BOOL CALLBACK apm3_di_enum_callback(
|
static BOOL CALLBACK apm3_di_enum_callback(
|
||||||
const DIDEVICEINSTANCEW *dev,
|
const DIDEVICEINSTANCEW *dev,
|
||||||
void *ctx);
|
void *ctx);
|
||||||
|
static BOOL CALLBACK apm3_di_enum_callback_shifter(
|
||||||
|
const DIDEVICEINSTANCEW *dev,
|
||||||
|
void *ctx);
|
||||||
static void apm3_di_get_gamebtns(uint16_t *gamebtn_out);
|
static void apm3_di_get_gamebtns(uint16_t *gamebtn_out);
|
||||||
static uint8_t apm3_di_decode_pov(DWORD pov);
|
static uint8_t apm3_di_decode_pov(DWORD pov);
|
||||||
|
|
||||||
@ -34,7 +42,7 @@ static IDirectInputDevice8W *apm3_di_dev;
|
|||||||
static IDirectInputEffect *apm3_di_fx;
|
static IDirectInputEffect *apm3_di_fx;
|
||||||
static uint8_t apm3_di_home;
|
static uint8_t apm3_di_home;
|
||||||
static uint8_t apm3_di_start;
|
static uint8_t apm3_di_start;
|
||||||
static uint8_t apm3_di_button[APM3_BUTTON_COUNT];
|
static uint8_t apm3_di_button[8];
|
||||||
|
|
||||||
HRESULT apm3_di_init(
|
HRESULT apm3_di_init(
|
||||||
const struct apm3_di_config *cfg,
|
const struct apm3_di_config *cfg,
|
||||||
@ -42,6 +50,10 @@ HRESULT apm3_di_init(
|
|||||||
const struct apm3_io_backend **backend)
|
const struct apm3_io_backend **backend)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
HMODULE dinput8;
|
||||||
|
HRESULT (WINAPI *api_entry)(HINSTANCE,DWORD,REFIID,LPVOID *,LPUNKNOWN);
|
||||||
|
wchar_t dll_path[MAX_PATH];
|
||||||
|
UINT path_pos;
|
||||||
|
|
||||||
assert(cfg != NULL);
|
assert(cfg != NULL);
|
||||||
assert(backend != NULL);
|
assert(backend != NULL);
|
||||||
@ -60,18 +72,6 @@ HRESULT apm3_di_init(
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = DirectInput8Create(
|
|
||||||
inst,
|
|
||||||
DIRECTINPUT_VERSION,
|
|
||||||
&IID_IDirectInput8W,
|
|
||||||
(void**)&apm3_di_api,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
dprintf("DirectInput: DirectInput8Create failed: %08x\n", (int)hr);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = IDirectInput8_EnumDevices(
|
hr = IDirectInput8_EnumDevices(
|
||||||
apm3_di_api,
|
apm3_di_api,
|
||||||
DI8DEVCLASS_GAMECTRL,
|
DI8DEVCLASS_GAMECTRL,
|
||||||
@ -138,7 +138,7 @@ static HRESULT apm3_di_config_apply(const struct apm3_di_config *cfg)
|
|||||||
dprintf("Stick: Start button . . . : %i\n", cfg->start);
|
dprintf("Stick: Start button . . . : %i\n", cfg->start);
|
||||||
|
|
||||||
/* Print the configuration for all 8 buttons */
|
/* Print the configuration for all 8 buttons */
|
||||||
for (i = 0; i < APM3_BUTTON_COUNT; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
dprintf("Stick: Button %i . . . . . : %i\n", i, cfg->button[i]);
|
dprintf("Stick: Button %i . . . . . : %i\n", i, cfg->button[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ static HRESULT apm3_di_config_apply(const struct apm3_di_config *cfg)
|
|||||||
apm3_di_start = cfg->start;
|
apm3_di_start = cfg->start;
|
||||||
apm3_di_home = cfg->home;
|
apm3_di_home = cfg->home;
|
||||||
|
|
||||||
for (i = 0; i < APM3_BUTTON_COUNT; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
apm3_di_button[i] = cfg->button[i];
|
apm3_di_button[i] = cfg->button[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,9 +88,18 @@ void idac_hook_config_load(
|
|||||||
platform_config_load(&cfg->platform, filename);
|
platform_config_load(&cfg->platform, filename);
|
||||||
aime_config_load(&cfg->aime, filename);
|
aime_config_load(&cfg->aime, filename);
|
||||||
idac_dll_config_load(&cfg->dll, filename);
|
idac_dll_config_load(&cfg->dll, filename);
|
||||||
|
zinput_config_load(&cfg->zinput, filename);
|
||||||
dvd_config_load(&cfg->dvd, filename);
|
dvd_config_load(&cfg->dvd, filename);
|
||||||
io4_config_load(&cfg->io4, filename);
|
io4_config_load(&cfg->io4, filename);
|
||||||
ffb_config_load(&cfg->ffb, filename);
|
ffb_config_load(&cfg->ffb, filename);
|
||||||
led15070_config_load(&cfg->led15070, filename);
|
led15070_config_load(&cfg->led15070, filename);
|
||||||
indrun_config_load(&cfg->indrun, filename);
|
indrun_config_load(&cfg->indrun, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void zinput_config_load(struct zinput_config *cfg, const wchar_t *filename)
|
||||||
|
{
|
||||||
|
assert(cfg != NULL);
|
||||||
|
assert(filename != NULL);
|
||||||
|
|
||||||
|
cfg->enable = GetPrivateProfileIntW(L"zinput", L"enable", 1, filename);
|
||||||
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "hooklib/dvd.h"
|
#include "hooklib/dvd.h"
|
||||||
|
|
||||||
#include "idachook/idac-dll.h"
|
#include "idachook/idac-dll.h"
|
||||||
|
#include "idachook/zinput.h"
|
||||||
#include "idachook/indrun.h"
|
#include "idachook/indrun.h"
|
||||||
|
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
@ -20,6 +21,7 @@ struct idac_hook_config {
|
|||||||
struct io4_config io4;
|
struct io4_config io4;
|
||||||
struct ffb_config ffb;
|
struct ffb_config ffb;
|
||||||
struct idac_dll_config dll;
|
struct idac_dll_config dll;
|
||||||
|
struct zinput_config zinput;
|
||||||
struct led15070_config led15070;
|
struct led15070_config led15070;
|
||||||
struct indrun_config indrun;
|
struct indrun_config indrun;
|
||||||
};
|
};
|
||||||
@ -32,6 +34,10 @@ void idac_hook_config_load(
|
|||||||
struct idac_hook_config *cfg,
|
struct idac_hook_config *cfg,
|
||||||
const wchar_t *filename);
|
const wchar_t *filename);
|
||||||
|
|
||||||
|
void zinput_config_load(
|
||||||
|
struct zinput_config *cfg,
|
||||||
|
const wchar_t *filename);
|
||||||
|
|
||||||
void indrun_config_load(
|
void indrun_config_load(
|
||||||
struct indrun_config *cfg,
|
struct indrun_config *cfg,
|
||||||
const wchar_t *filename);
|
const wchar_t *filename);
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "idachook/idac-dll.h"
|
#include "idachook/idac-dll.h"
|
||||||
#include "idachook/io4.h"
|
#include "idachook/io4.h"
|
||||||
#include "idachook/ffb.h"
|
#include "idachook/ffb.h"
|
||||||
|
#include "idachook/zinput.h"
|
||||||
|
|
||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
|
|
||||||
@ -54,6 +55,7 @@ static DWORD CALLBACK idac_pre_startup(void)
|
|||||||
/* Hook Win32 APIs */
|
/* Hook Win32 APIs */
|
||||||
|
|
||||||
serial_hook_init();
|
serial_hook_init();
|
||||||
|
zinput_hook_init(&idac_hook_cfg.zinput);
|
||||||
dvd_hook_init(&idac_hook_cfg.dvd, idac_hook_mod);
|
dvd_hook_init(&idac_hook_cfg.dvd, idac_hook_mod);
|
||||||
|
|
||||||
/* Initialize emulation hooks */
|
/* Initialize emulation hooks */
|
||||||
|
@ -25,6 +25,8 @@ shared_library(
|
|||||||
'idac-dll.h',
|
'idac-dll.h',
|
||||||
'io4.c',
|
'io4.c',
|
||||||
'io4.h',
|
'io4.h',
|
||||||
|
'zinput.c',
|
||||||
|
'zinput.h',
|
||||||
'indrun.c',
|
'indrun.c',
|
||||||
'indrun.h',
|
'indrun.h',
|
||||||
'ffb.c',
|
'ffb.c',
|
||||||
|
187
games/idachook/zinput.c
Normal file
187
games/idachook/zinput.c
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <dinput.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "idachook/config.h"
|
||||||
|
#include "idachook/zinput.h"
|
||||||
|
|
||||||
|
#include "hook/table.h"
|
||||||
|
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
|
HRESULT WINAPI hook_DirectInput8Create(
|
||||||
|
HINSTANCE hinst,
|
||||||
|
DWORD dwVersion,
|
||||||
|
REFIID riidltf,
|
||||||
|
LPVOID *ppvOut,
|
||||||
|
LPUNKNOWN punkOuter);
|
||||||
|
|
||||||
|
static unsigned long WINAPI hook_AddRef(IUnknown *self);
|
||||||
|
|
||||||
|
static unsigned long WINAPI hook_Release(IUnknown *self);
|
||||||
|
|
||||||
|
static HRESULT WINAPI hook_CreateDevice(
|
||||||
|
IDirectInput8W *self,
|
||||||
|
REFGUID rguid,
|
||||||
|
LPDIRECTINPUTDEVICE8W * lplpDirectInputDevice,
|
||||||
|
LPUNKNOWN pUnkOuter);
|
||||||
|
|
||||||
|
static HRESULT WINAPI hook_EnumDevices(
|
||||||
|
IDirectInput8W *self,
|
||||||
|
DWORD dwDevType,
|
||||||
|
LPDIENUMDEVICESCALLBACKW lpCallback,
|
||||||
|
LPVOID pvRef,
|
||||||
|
DWORD dwFlags);
|
||||||
|
|
||||||
|
static HRESULT WINAPI hook_SetDataFormat(
|
||||||
|
IDirectInputDevice8W *self,
|
||||||
|
LPCDIDATAFORMAT lpdf);
|
||||||
|
|
||||||
|
static HRESULT WINAPI hook_SetCooperativeLevel(
|
||||||
|
IDirectInputDevice8W *self,
|
||||||
|
HWND hwnd,
|
||||||
|
DWORD flags);
|
||||||
|
|
||||||
|
static HRESULT WINAPI hook_Acquire(IDirectInputDevice8W *self);
|
||||||
|
|
||||||
|
static HRESULT WINAPI hook_Unacquire(IDirectInputDevice8W *self);
|
||||||
|
|
||||||
|
static HRESULT WINAPI hook_GetDeviceState(
|
||||||
|
IDirectInputDevice8W *self,
|
||||||
|
DWORD cbData,
|
||||||
|
LPVOID lpvData);
|
||||||
|
|
||||||
|
static const IDirectInput8WVtbl api_vtbl = {
|
||||||
|
.AddRef = (void *) hook_AddRef,
|
||||||
|
.Release = (void *) hook_Release,
|
||||||
|
.CreateDevice = hook_CreateDevice,
|
||||||
|
.EnumDevices = hook_EnumDevices,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const IDirectInput8W api = { (void *) &api_vtbl };
|
||||||
|
|
||||||
|
static const IDirectInputDevice8WVtbl dev_vtbl = {
|
||||||
|
.AddRef = (void *) hook_AddRef,
|
||||||
|
.Release = (void *) hook_Release,
|
||||||
|
.SetDataFormat = hook_SetDataFormat,
|
||||||
|
.SetCooperativeLevel= hook_SetCooperativeLevel,
|
||||||
|
.Acquire = hook_Acquire,
|
||||||
|
.Unacquire = hook_Unacquire,
|
||||||
|
.GetDeviceState = hook_GetDeviceState,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const IDirectInputDevice8W dev = { (void *) &dev_vtbl };
|
||||||
|
|
||||||
|
static const struct hook_symbol zinput_hook_syms[] = {
|
||||||
|
{
|
||||||
|
.name = "DirectInput8Create",
|
||||||
|
.patch = hook_DirectInput8Create,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT zinput_hook_init(struct zinput_config *cfg)
|
||||||
|
{
|
||||||
|
assert(cfg != NULL);
|
||||||
|
|
||||||
|
if (!cfg->enable) {
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hook_table_apply(
|
||||||
|
NULL,
|
||||||
|
"dinput8.dll",
|
||||||
|
zinput_hook_syms,
|
||||||
|
_countof(zinput_hook_syms));
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WINAPI hook_DirectInput8Create(
|
||||||
|
HINSTANCE hinst,
|
||||||
|
DWORD dwVersion,
|
||||||
|
REFIID riidltf,
|
||||||
|
LPVOID *ppvOut,
|
||||||
|
LPUNKNOWN punkOuter)
|
||||||
|
{
|
||||||
|
dprintf("ZInput: Blocking built-in DirectInput support\n");
|
||||||
|
*ppvOut = (void *) &api;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long WINAPI hook_AddRef(IUnknown *self)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long WINAPI hook_Release(IUnknown *self)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI hook_CreateDevice(
|
||||||
|
IDirectInput8W *self,
|
||||||
|
REFGUID rguid,
|
||||||
|
LPDIRECTINPUTDEVICE8W *lplpDirectInputDevice,
|
||||||
|
LPUNKNOWN pUnkOuter)
|
||||||
|
{
|
||||||
|
dprintf("ZInput: %s\n", __func__);
|
||||||
|
*lplpDirectInputDevice = (void *) &dev;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI hook_EnumDevices(
|
||||||
|
IDirectInput8W *self,
|
||||||
|
DWORD dwDevType,
|
||||||
|
LPDIENUMDEVICESCALLBACKW lpCallback,
|
||||||
|
LPVOID pvRef,
|
||||||
|
DWORD dwFlags)
|
||||||
|
{
|
||||||
|
dprintf("ZInput: %s\n", __func__);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI hook_SetDataFormat(
|
||||||
|
IDirectInputDevice8W *self,
|
||||||
|
LPCDIDATAFORMAT lpdf)
|
||||||
|
{
|
||||||
|
dprintf("ZInput: %s\n", __func__);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI hook_SetCooperativeLevel(
|
||||||
|
IDirectInputDevice8W *self,
|
||||||
|
HWND hwnd,
|
||||||
|
DWORD flags)
|
||||||
|
{
|
||||||
|
dprintf("ZInput: %s\n", __func__);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI hook_Acquire(IDirectInputDevice8W *self)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI hook_Unacquire(IDirectInputDevice8W *self)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI hook_GetDeviceState(
|
||||||
|
IDirectInputDevice8W *self,
|
||||||
|
DWORD cbData,
|
||||||
|
LPVOID lpvData)
|
||||||
|
{
|
||||||
|
memset(lpvData, 0, cbData);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
11
games/idachook/zinput.h
Normal file
11
games/idachook/zinput.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
struct zinput_config {
|
||||||
|
bool enable;
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT zinput_hook_init(struct zinput_config *cfg);
|
@ -60,8 +60,6 @@ void idac_di_config_load(struct idac_di_config *cfg, const wchar_t *filename)
|
|||||||
cfg->view_chg = GetPrivateProfileIntW(L"dinput", L"viewChg", 0, filename);
|
cfg->view_chg = GetPrivateProfileIntW(L"dinput", L"viewChg", 0, filename);
|
||||||
cfg->left = GetPrivateProfileIntW(L"dinput", L"left", 0, filename);
|
cfg->left = GetPrivateProfileIntW(L"dinput", L"left", 0, filename);
|
||||||
cfg->right = GetPrivateProfileIntW(L"dinput", L"right", 0, filename);
|
cfg->right = GetPrivateProfileIntW(L"dinput", L"right", 0, filename);
|
||||||
cfg->up = GetPrivateProfileIntW(L"dinput", L"up", 0, filename);
|
|
||||||
cfg->down = GetPrivateProfileIntW(L"dinput", L"down", 0, filename);
|
|
||||||
cfg->shift_dn = GetPrivateProfileIntW(L"dinput", L"shiftDn", 0, filename);
|
cfg->shift_dn = GetPrivateProfileIntW(L"dinput", L"shiftDn", 0, filename);
|
||||||
cfg->shift_up = GetPrivateProfileIntW(L"dinput", L"shiftUp", 0, filename);
|
cfg->shift_up = GetPrivateProfileIntW(L"dinput", L"shiftUp", 0, filename);
|
||||||
|
|
||||||
|
@ -18,8 +18,6 @@ struct idac_di_config {
|
|||||||
uint8_t view_chg;
|
uint8_t view_chg;
|
||||||
uint8_t left;
|
uint8_t left;
|
||||||
uint8_t right;
|
uint8_t right;
|
||||||
uint8_t up;
|
|
||||||
uint8_t down;
|
|
||||||
uint8_t shift_dn;
|
uint8_t shift_dn;
|
||||||
uint8_t shift_up;
|
uint8_t shift_up;
|
||||||
uint8_t gear[6];
|
uint8_t gear[6];
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <dinput.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
#include "idacio/backend.h"
|
#include "idacio/backend.h"
|
||||||
#include "idacio/config.h"
|
#include "idacio/config.h"
|
||||||
@ -71,8 +77,6 @@ static uint8_t idac_di_view_chg;
|
|||||||
static uint8_t idac_di_start;
|
static uint8_t idac_di_start;
|
||||||
static uint8_t idac_di_left;
|
static uint8_t idac_di_left;
|
||||||
static uint8_t idac_di_right;
|
static uint8_t idac_di_right;
|
||||||
static uint8_t idac_di_up;
|
|
||||||
static uint8_t idac_di_down;
|
|
||||||
static uint8_t idac_di_gear[6];
|
static uint8_t idac_di_gear[6];
|
||||||
static bool idac_di_use_pedals;
|
static bool idac_di_use_pedals;
|
||||||
static bool idac_di_reverse_brake_axis;
|
static bool idac_di_reverse_brake_axis;
|
||||||
@ -84,6 +88,10 @@ HRESULT idac_di_init(
|
|||||||
const struct idac_io_backend **backend)
|
const struct idac_io_backend **backend)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
HMODULE dinput8;
|
||||||
|
HRESULT (WINAPI *api_entry)(HINSTANCE,DWORD,REFIID,LPVOID *,LPUNKNOWN);
|
||||||
|
wchar_t dll_path[MAX_PATH];
|
||||||
|
UINT path_pos;
|
||||||
|
|
||||||
assert(cfg != NULL);
|
assert(cfg != NULL);
|
||||||
assert(backend != NULL);
|
assert(backend != NULL);
|
||||||
@ -102,15 +110,47 @@ HRESULT idac_di_init(
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = DirectInput8Create(
|
/* Initial D THE ARCADE has some built-in DirectInput support that is not
|
||||||
|
particularly useful. idachook shorts this out by redirecting dinput8.dll
|
||||||
|
to a no-op implementation of DirectInput. However, idacio does need to
|
||||||
|
talk to the real operating system implementation of DirectInput without
|
||||||
|
the stub DLL interfering, so build a path to
|
||||||
|
C:\Windows\System32\dinput.dll here. */
|
||||||
|
|
||||||
|
dll_path[0] = L'\0';
|
||||||
|
path_pos = GetSystemDirectoryW(dll_path, _countof(dll_path));
|
||||||
|
wcscat_s(
|
||||||
|
dll_path + path_pos,
|
||||||
|
_countof(dll_path) - path_pos,
|
||||||
|
L"\\dinput8.dll");
|
||||||
|
|
||||||
|
dinput8 = LoadLibraryW(dll_path);
|
||||||
|
|
||||||
|
if (dinput8 == NULL) {
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
dprintf("DirectInput: LoadLibrary failed: %08x\n", (int) hr);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
api_entry = (void *) GetProcAddress(dinput8, "DirectInput8Create");
|
||||||
|
|
||||||
|
if (api_entry == NULL) {
|
||||||
|
dprintf("DirectInput: GetProcAddress failed\n");
|
||||||
|
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = api_entry(
|
||||||
inst,
|
inst,
|
||||||
DIRECTINPUT_VERSION,
|
DIRECTINPUT_VERSION,
|
||||||
&IID_IDirectInput8W,
|
&IID_IDirectInput8W,
|
||||||
(void**)&idac_di_api,
|
(void **) &idac_di_api,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dprintf("DirectInput: DirectInput8Create failed: %08x\n", (int)hr);
|
dprintf("DirectInput: API create failed: %08x\n", (int) hr);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,16 +289,6 @@ static HRESULT idac_di_config_apply(const struct idac_di_config *cfg)
|
|||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg->up > 32) {
|
|
||||||
dprintf("Wheel: Invalid up button: %i\n", cfg->up);
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg->down > 32) {
|
|
||||||
dprintf("Wheel: Invalid down button: %i\n", cfg->down);
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg->shift_dn > 32) {
|
if (cfg->shift_dn > 32) {
|
||||||
dprintf("Wheel: Invalid shift down button: %i\n", cfg->shift_dn);
|
dprintf("Wheel: Invalid shift down button: %i\n", cfg->shift_dn);
|
||||||
|
|
||||||
@ -294,8 +324,6 @@ static HRESULT idac_di_config_apply(const struct idac_di_config *cfg)
|
|||||||
dprintf("Wheel: View Change button : %i\n", cfg->view_chg);
|
dprintf("Wheel: View Change button : %i\n", cfg->view_chg);
|
||||||
dprintf("Wheel: Left button . . . . : %i\n", cfg->left);
|
dprintf("Wheel: Left button . . . . : %i\n", cfg->left);
|
||||||
dprintf("Wheel: Right button . . . : %i\n", cfg->right);
|
dprintf("Wheel: Right button . . . : %i\n", cfg->right);
|
||||||
dprintf("Wheel: Up button . . . . . : %i\n", cfg->up);
|
|
||||||
dprintf("Wheel: Down button . . . : %i\n", cfg->down);
|
|
||||||
dprintf("Wheel: Shift Down button . : %i\n", cfg->shift_dn);
|
dprintf("Wheel: Shift Down button . : %i\n", cfg->shift_dn);
|
||||||
dprintf("Wheel: Shift Up button . . : %i\n", cfg->shift_up);
|
dprintf("Wheel: Shift Up button . . : %i\n", cfg->shift_up);
|
||||||
dprintf("Wheel: Reverse Brake Axis : %i\n", cfg->reverse_brake_axis);
|
dprintf("Wheel: Reverse Brake Axis : %i\n", cfg->reverse_brake_axis);
|
||||||
@ -331,8 +359,6 @@ static HRESULT idac_di_config_apply(const struct idac_di_config *cfg)
|
|||||||
idac_di_view_chg = cfg->view_chg;
|
idac_di_view_chg = cfg->view_chg;
|
||||||
idac_di_left = cfg->left;
|
idac_di_left = cfg->left;
|
||||||
idac_di_right = cfg->right;
|
idac_di_right = cfg->right;
|
||||||
idac_di_up = cfg->up;
|
|
||||||
idac_di_down = cfg->down;
|
|
||||||
idac_di_shift_dn = cfg->shift_dn;
|
idac_di_shift_dn = cfg->shift_dn;
|
||||||
idac_di_shift_up = cfg->shift_up;
|
idac_di_shift_up = cfg->shift_up;
|
||||||
idac_di_reverse_brake_axis = cfg->reverse_brake_axis;
|
idac_di_reverse_brake_axis = cfg->reverse_brake_axis;
|
||||||
@ -496,14 +522,6 @@ static void idac_di_get_buttons(uint8_t *gamebtn_out)
|
|||||||
gamebtn |= IDAC_IO_GAMEBTN_RIGHT;
|
gamebtn |= IDAC_IO_GAMEBTN_RIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idac_di_up && state.st.rgbButtons[idac_di_up - 1]) {
|
|
||||||
gamebtn |= IDAC_IO_GAMEBTN_UP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idac_di_down && state.st.rgbButtons[idac_di_down - 1]) {
|
|
||||||
gamebtn |= IDAC_IO_GAMEBTN_DOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
*gamebtn_out = gamebtn;
|
*gamebtn_out = gamebtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <dinput.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
#include "swdcio/backend.h"
|
#include "swdcio/backend.h"
|
||||||
#include "swdcio/config.h"
|
#include "swdcio/config.h"
|
||||||
@ -75,6 +81,10 @@ HRESULT swdc_di_init(
|
|||||||
const struct swdc_io_backend **backend)
|
const struct swdc_io_backend **backend)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
HMODULE dinput8;
|
||||||
|
HRESULT (WINAPI *api_entry)(HINSTANCE,DWORD,REFIID,LPVOID *,LPUNKNOWN);
|
||||||
|
wchar_t dll_path[MAX_PATH];
|
||||||
|
UINT path_pos;
|
||||||
|
|
||||||
assert(cfg != NULL);
|
assert(cfg != NULL);
|
||||||
assert(backend != NULL);
|
assert(backend != NULL);
|
||||||
@ -93,15 +103,46 @@ HRESULT swdc_di_init(
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = DirectInput8Create(
|
/* SWDC has some built-in DirectInput support that is not
|
||||||
|
particularly useful. swdchook shorts this out by redirecting dinput8.dll
|
||||||
|
to a no-op implementation of DirectInput. However, swdcio does need to
|
||||||
|
talk to the real operating system implementation of DirectInput without
|
||||||
|
the stub DLL interfering, so build a path to
|
||||||
|
C:\Windows\System32\dinput.dll here. */
|
||||||
|
|
||||||
|
dll_path[0] = L'\0';
|
||||||
|
path_pos = GetSystemDirectoryW(dll_path, _countof(dll_path));
|
||||||
|
wcscat_s(
|
||||||
|
dll_path + path_pos,
|
||||||
|
_countof(dll_path) - path_pos,
|
||||||
|
L"\\dinput8.dll");
|
||||||
|
|
||||||
|
dinput8 = LoadLibraryW(dll_path);
|
||||||
|
|
||||||
|
if (dinput8 == NULL) {
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
dprintf("DirectInput: LoadLibrary failed: %08x\n", (int) hr);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
api_entry = (void *) GetProcAddress(dinput8, "DirectInput8Create");
|
||||||
|
|
||||||
|
if (api_entry == NULL) {
|
||||||
|
dprintf("DirectInput: GetProcAddress failed\n");
|
||||||
|
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = api_entry(
|
||||||
inst,
|
inst,
|
||||||
DIRECTINPUT_VERSION,
|
DIRECTINPUT_VERSION,
|
||||||
&IID_IDirectInput8W,
|
&IID_IDirectInput8W,
|
||||||
(void**)&swdc_di_api,
|
(void **) &swdc_di_api,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dprintf("DirectInput: DirectInput8Create failed: %08x\n", (int) hr);
|
dprintf("DirectInput: API create failed: %08x\n", (int) hr);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ static int16_t calculate_norm_steering(int16_t axis, uint16_t deadzone, bool lin
|
|||||||
|
|
||||||
// optionally normalize the magnitude with respect to its expected range
|
// optionally normalize the magnitude with respect to its expected range
|
||||||
// giving a magnitude value of 0.0 to 1.0
|
// giving a magnitude value of 0.0 to 1.0
|
||||||
norm_magnitude = (magnitude / (max_stick_value - deadzone));
|
norm_magnitude = (int16_t)(magnitude / (max_stick_value - deadzone));
|
||||||
} else // if the controller is in the deadzone zero out the magnitude
|
} else // if the controller is in the deadzone zero out the magnitude
|
||||||
{
|
{
|
||||||
magnitude = 0.0;
|
magnitude = 0.0;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
[wrap-git]
|
[wrap-git]
|
||||||
directory = capnhook
|
directory = capnhook
|
||||||
url = https://gitea.tendokyu.moe/TeamTofuShop/capnhook
|
url = https://gitea.tendokyu.moe/TeamTofuShop/capnhook
|
||||||
revision = 252465b23f51f36206e614190496663425f4ee5d
|
revision = dafd0aa336ab80ba87a82370a9dc95a3389ef5e5
|
||||||
|
Reference in New Issue
Block a user