2024-06-02 16:46:01 -04:00
# include <Windows.h>
# include <string>
2024-06-10 14:36:00 -04:00
# include <thread>
2024-06-02 16:46:01 -04:00
2024-06-03 12:36:51 -04:00
struct XINPUT_STATE ;
struct XINPUT_CAPABILITIES ;
2024-06-02 16:46:01 -04:00
2024-06-03 12:36:51 -04:00
constexpr static auto MAX_PATH_CHARS = 32768u ;
2024-06-02 16:46:01 -04:00
2024-06-03 12:36:51 -04:00
static HMODULE getXInput ( ) {
static auto xinput = [ ] ( ) - > HMODULE {
std : : wstring path ( MAX_PATH_CHARS , L ' \0 ' ) ;
auto size = GetSystemDirectoryW ( const_cast < wchar_t * > ( path . data ( ) ) , path . size ( ) ) ;
if ( size ) {
path . resize ( size ) ;
return LoadLibraryW ( ( path + L " \\ XInput1_4.dll " ) . c_str ( ) ) ;
}
return NULL ;
} ( ) ;
2024-06-02 16:46:01 -04:00
2024-06-03 12:36:51 -04:00
return xinput ;
}
static FARPROC getFP ( const std : : string & sym ) {
if ( auto xinput = getXInput ( ) )
return GetProcAddress ( xinput , sym . c_str ( ) ) ;
return NULL ;
}
2024-06-02 16:46:01 -04:00
# pragma comment(linker, " / export:XInputGetState,@2")
extern " C " DWORD XInputGetState ( DWORD dwUserIndex , XINPUT_STATE * pState ) {
2024-06-03 12:36:51 -04:00
static auto fp = getFP ( " XInputGetState " ) ;
if ( fp ) {
using FPType = decltype ( & XInputGetState ) ;
return reinterpret_cast < FPType > ( fp ) ( dwUserIndex , pState ) ;
2024-06-02 16:46:01 -04:00
}
return ERROR_DEVICE_NOT_CONNECTED ;
}
2024-06-03 10:03:37 -04:00
# pragma comment(linker, " / export:XInputGetCapabilities,@4")
extern " C " DWORD XInputGetCapabilities ( DWORD dwUserIndex , DWORD dwFlags , XINPUT_CAPABILITIES * pCapabilities ) {
2024-06-03 12:36:51 -04:00
static auto fp = getFP ( " XInputGetCapabilities " ) ;
if ( fp ) {
using FPType = decltype ( & XInputGetCapabilities ) ;
return reinterpret_cast < FPType > ( fp ) ( dwUserIndex , dwFlags , pCapabilities ) ;
2024-06-03 10:03:37 -04:00
}
return ERROR_DEVICE_NOT_CONNECTED ;
}
2024-06-10 14:36:00 -04:00
static std : : wstring getErrorString ( DWORD error ) {
return L " Could not load Geode! Error code: " + std : : to_wstring ( error ) ;
}
static std : : wstring get1114ErrorString ( DWORD error ) {
return L " Could not load Geode! Error code: " + std : : to_wstring ( error ) + L " \n \n Do you want to update Microsoft Visual C++ Redistributable 2022 to try to fix this issue? " ;
2024-06-02 16:46:01 -04:00
}
2024-06-03 12:36:51 -04:00
BOOL WINAPI DllMain ( HINSTANCE module , DWORD reason , LPVOID _ ) {
2024-06-02 16:46:01 -04:00
if ( reason = = DLL_PROCESS_ATTACH ) {
DisableThreadLibraryCalls ( module ) ;
// This is UB.
2024-06-10 14:36:00 -04:00
if ( LoadLibraryW ( L " Geode.dll " ) = = NULL ) {
auto error = GetLastError ( ) ;
if ( error = = 1114 ) {
if ( MessageBoxW ( NULL , get1114ErrorString ( error ) . c_str ( ) , L " Load failed " , MB_YESNO | MB_ICONWARNING ) = = IDYES ) {
std : : thread ( [ ] ( ) {
ShellExecuteW ( NULL , L " open " , L " https://aka.ms/vs/17/release/vc_redist.x64.exe " , NULL , NULL , SW_SHOWNORMAL ) ;
} ) . detach ( ) ;
}
} else {
MessageBoxW ( NULL , getErrorString ( error ) . c_str ( ) , L " Load failed " , MB_OK | MB_ICONWARNING ) ;
}
}
2024-06-02 16:46:01 -04:00
}
return TRUE ;
}