2016-11-19 01:24:49 +00:00
/*
Copyright 2016 Peter Repukat - FlatspotSoftware
Licensed under the Apache License , Version 2.0 ( the " License " ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an " AS IS " BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
*/
# pragma once
# include <thread>
# include <chrono>
2017-02-15 03:07:27 +00:00
# include <iostream>
# include <atomic>
# include <vector>
2016-11-19 01:24:49 +00:00
# include <Windows.h>
2017-02-15 03:07:27 +00:00
# include <psapi.h>
2016-11-19 01:24:49 +00:00
2017-02-15 03:07:27 +00:00
# include <SFML/System.hpp>
2016-11-19 01:24:49 +00:00
2017-02-15 03:07:27 +00:00
# include <Xinput.h>
# include <ViGEmUM.h>
2016-11-19 01:24:49 +00:00
class VirtualControllerThread
{
public :
VirtualControllerThread ( ) ;
~ VirtualControllerThread ( ) ;
void run ( ) ;
void stop ( ) ;
bool isRunning ( ) ;
private :
2017-02-15 03:07:27 +00:00
std : : atomic < bool > bShouldRun = false ;
typedef DWORD ( WINAPI * XInputGetState_t ) ( DWORD dwUserIndex , XINPUT_STATE * pState ) ;
2016-11-19 01:24:49 +00:00
2017-02-15 13:34:01 +00:00
static const uint8_t opPatchLenght = 5 ;
2017-02-15 03:07:27 +00:00
uint8_t valveHookBytes [ 5 ] ;
2017-02-15 20:43:14 +00:00
// First 5 bytes are the same for XInput1_4.dll and XInput9_1_0.dll (on AMD64 at least, didn't check yet for x86, there is no ViGEm build for Win7 anway...)
// So no change has to be made for Win7 Targets
# ifdef _AMD64_
2017-02-15 13:34:01 +00:00
const uint8_t realBytes [ 5 ] = { 0x48 , 0x89 , 0x5C , 0x24 , 0x08 } ;
2017-02-15 20:43:14 +00:00
# else
const uint8_t realBytes [ 5 ] = { 0x8B , 0xFF , 0x55 , 0x8B , 0xEC } ;
# endif
2017-02-15 03:07:27 +00:00
//uint8_t realBytes[5] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x90 };
int controllerCount = 0 ;
2017-02-15 13:34:01 +00:00
XInputGetState_t XGetState = nullptr ;
2016-11-19 01:24:49 +00:00
VIGEM_TARGET vtX360 [ XUSER_MAX_COUNT ] ;
std : : thread controllerThread ;
sf : : Clock sfClock ;
int tickTime = 0 ;
2017-01-25 16:14:23 +00:00
int delay = 1000000 / 200 ;
2016-11-19 01:24:49 +00:00
void controllerLoop ( ) ;
static void controllerCallback ( VIGEM_TARGET Target , UCHAR LargeMotor , UCHAR SmallMotor , UCHAR LedNumber ) ;
2017-02-15 20:43:29 +00:00
static DWORD XInputGetStateWrapper ( DWORD dwUserIndex , XINPUT_STATE * pState ) ; //Easier to find in x64dbg...
2017-02-15 03:07:27 +00:00
DWORD callRealXinputGetState ( DWORD dwUserIndex , XINPUT_STATE * pState ) ;
2016-11-19 01:24:49 +00:00
} ;