diff --git a/X360AdvanceApp/X360Advance.cpp b/X360AdvanceApp/X360Advance.cpp index 7951bbc..4157978 100644 --- a/X360AdvanceApp/X360Advance.cpp +++ b/X360AdvanceApp/X360Advance.cpp @@ -4,10 +4,10 @@ #include "IniReader\IniReader.h" float SensX, SensY; -float ArduinoData[4] = { 0, 0, 0, 0 }; //Mode, Yaw, Pitch, Roll +float ArduinoData[4] = { 0, 0, 0, 0 }; // Mode, Yaw, Pitch, Roll float LastArduinoData[4] = { 0, 0, 0, 0 }; float YRPOffset[3] = { 0, 0, 0 }; -int last_x = 0, last_y = 0; +float accumulatedX = 0, accumulatedY = 0; int GameMode = 2; bool ArduinoWork = false; @@ -36,40 +36,25 @@ bool CorrectAngleValue(float Value) } } -int MouseGetDelta(int val, int prev) //Implementation from OpenTrack https://github.com/opentrack/opentrack/blob/unstable/proto-mouse/ -{ - const int a = std::abs(val - prev), b = std::abs(val + prev); - if (b < a) - return val + prev; - else - return val - prev; -} - -void MouseMove(const double axisX, const double axisY) //Implementation from OpenTrack https://github.com/opentrack/opentrack/blob/unstable/proto-mouse/ -{ - int mouse_x = 0, mouse_y = 0; - - mouse_x = round(axisX * SensX * 2); - mouse_y = round(axisY * SensY * 2); - - const int dx = MouseGetDelta(mouse_x, last_x); - const int dy = MouseGetDelta(mouse_y, last_y); - - last_x = mouse_x; - last_y = mouse_y; - - if (dx || dy) - { - INPUT input; - input.type = INPUT_MOUSE; - MOUSEINPUT& mi = input.mi; - mi = {}; - mi.dx = dx; - mi.dy = dy; - mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE; - - SendInput(1, &input, sizeof(input)); - } +//Implementation from https://github.com/JibbSmart/JoyShockMapper/blob/master/JoyShockMapper/src/win32/InputHelpers.cpp +void MouseMove(float x, float y) { + accumulatedX += x; + accumulatedY += y; + + int applicableX = (int)accumulatedX; + int applicableY = (int)accumulatedY; + + accumulatedX -= applicableX; + accumulatedY -= applicableY; + + INPUT input; + input.type = INPUT_MOUSE; + input.mi.mouseData = 0; + input.mi.time = 0; + input.mi.dx = applicableX; + input.mi.dy = applicableY; + input.mi.dwFlags = MOUSEEVENTF_MOVE; + SendInput(1, &input, sizeof(input)); } int main() @@ -77,8 +62,8 @@ int main() SetConsoleTitle("X360Advance"); CIniReader IniFile("X360Advance.ini"); - SensX = IniFile.ReadFloat("Main", "SensX", 4.5); - SensY = IniFile.ReadFloat("Main", "SensY", 3.5); + SensX = IniFile.ReadFloat("Main", "SensX", 35); + SensY = IniFile.ReadFloat("Main", "SensY", 30); HANDLE hSerial; char sPortName[8]; @@ -112,7 +97,7 @@ int main() } else { - printf("Mouse movement activated\r\nNumpad 5 - centering\r\n"); + printf("Mouse movement activated\r\nNumpad 5 - reset\r\n"); printf("Press \"~\" to exit\r\n"); } @@ -162,9 +147,15 @@ int main() YRPOffset[2] = LastArduinoData[3]; } - if (GameMode == 2) - MouseMove(OffsetYPR(ArduinoData[1], YRPOffset[0]) * -1, OffsetYPR(ArduinoData[3], YRPOffset[2])); + if (GameMode == 2) { + float NewX = OffsetYPR(ArduinoData[1], YRPOffset[0]) * -1; + float NewY = OffsetYPR(ArduinoData[3], YRPOffset[2]); + MouseMove(NewX * SensX, NewY * SensY); + + YRPOffset[0] = LastArduinoData[1]; + YRPOffset[2] = LastArduinoData[3]; + } if ((GetAsyncKeyState(VK_NUMPAD5) & 0x8000) != 0) { PurgeComm(hSerial, PURGE_TXCLEAR | PURGE_RXCLEAR); diff --git a/X360AdvanceSettings/Unit1.dfm b/X360AdvanceSettings/Unit1.dfm index a7c8922..d6a8f1b 100644 --- a/X360AdvanceSettings/Unit1.dfm +++ b/X360AdvanceSettings/Unit1.dfm @@ -1,10 +1,10 @@ -object Form1: TForm1 +object Main: TMain Left = 192 Top = 125 BorderIcons = [biSystemMenu, biMinimize] BorderStyle = bsSingle Caption = 'X360Advance - Settings' - ClientHeight = 210 + ClientHeight = 249 ClientWidth = 384 Color = clBtnFace Font.Charset = DEFAULT_CHARSET @@ -19,7 +19,7 @@ object Form1: TForm1 TextHeight = 13 object ApplyBtn: TButton Left = 8 - Top = 176 + Top = 216 Width = 75 Height = 25 Caption = 'Apply' @@ -28,7 +28,7 @@ object Form1: TForm1 end object CloseBtn: TButton Left = 88 - Top = 176 + Top = 216 Width = 75 Height = 25 Caption = 'Close' @@ -39,26 +39,26 @@ object Form1: TForm1 Left = 192 Top = 8 Width = 185 - Height = 161 + Height = 201 Caption = 'Mouse' TabOrder = 2 object XAxisSensitivityLbl: TLabel Left = 8 - Top = 24 + Top = 48 Width = 76 Height = 13 Caption = 'X-axis sensitivity' end object YAxisSensitivityLbl: TLabel Left = 8 - Top = 88 + Top = 96 Width = 76 Height = 13 Caption = 'Y-axis sensitivity' end object XAxisSensitivityValueLbl: TLabel Left = 160 - Top = 52 + Top = 68 Width = 6 Height = 13 Caption = '0' @@ -70,15 +70,29 @@ object Form1: TForm1 Height = 13 Caption = '0' end + object TriggerSensitivityLbl: TLabel + Left = 8 + Top = 144 + Width = 118 + Height = 13 + Caption = 'Sensitivity with left trigger' + end + object TriggerSensitivityValueLbl: TLabel + Left = 160 + Top = 165 + Width = 6 + Height = 13 + Caption = '0' + end object XAxisSensitivityTB: TTrackBar Left = 8 - Top = 48 + Top = 64 Width = 150 Height = 33 Max = 100 Min = 1 Frequency = 10 - Position = 45 + Position = 30 TabOrder = 0 OnChange = XAxisSensitivityTBChange end @@ -90,16 +104,38 @@ object Form1: TForm1 Max = 100 Min = 1 Frequency = 10 - Position = 35 + Position = 25 TabOrder = 1 OnChange = YAxisSensitivityTBChange end + object CBOnlyTrigger: TCheckBox + Left = 8 + Top = 21 + Width = 169 + Height = 17 + Caption = 'Activate by left trigger' + TabOrder = 2 + end + object TriggerSensitivityTB: TTrackBar + Left = 8 + Top = 160 + Width = 150 + Height = 33 + Hint = 'Decrease the sensitivity to aim more accurately.' + Max = 20 + Min = 1 + ParentShowHint = False + Position = 10 + ShowHint = True + TabOrder = 3 + OnChange = TriggerSensitivityTBChange + end end object SteeringWheelGB: TGroupBox Left = 8 - Top = 88 + Top = 112 Width = 177 - Height = 81 + Height = 97 Caption = 'Steering wheel' TabOrder = 3 object SensitivityAngleLbl: TLabel @@ -133,7 +169,7 @@ object Form1: TForm1 Left = 8 Top = 8 Width = 177 - Height = 73 + Height = 97 Caption = 'Setup' TabOrder = 4 object COMPortLbl: TLabel @@ -154,7 +190,7 @@ object Form1: TForm1 end object AboutBtn: TButton Left = 349 - Top = 176 + Top = 216 Width = 27 Height = 25 Caption = '?' @@ -162,7 +198,7 @@ object Form1: TForm1 OnClick = AboutBtnClick end object XPManifest1: TXPManifest - Left = 312 - Top = 176 + Left = 152 + Top = 24 end end diff --git a/X360AdvanceSettings/Unit1.pas b/X360AdvanceSettings/Unit1.pas index 9312128..6f3f3c8 100644 --- a/X360AdvanceSettings/Unit1.pas +++ b/X360AdvanceSettings/Unit1.pas @@ -7,7 +7,7 @@ interface Dialogs, StdCtrls, Registry, ComCtrls, XPMan; type - TForm1 = class(TForm) + TMain = class(TForm) ApplyBtn: TButton; XPManifest1: TXPManifest; CloseBtn: TButton; @@ -26,6 +26,10 @@ TForm1 = class(TForm) XAxisSensitivityValueLbl: TLabel; YAxisSensitivityValueLbl: TLabel; AboutBtn: TButton; + CBOnlyTrigger: TCheckBox; + TriggerSensitivityLbl: TLabel; + TriggerSensitivityTB: TTrackBar; + TriggerSensitivityValueLbl: TLabel; procedure ApplyBtnClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure XAxisSensitivityTBChange(Sender: TObject); @@ -33,6 +37,7 @@ TForm1 = class(TForm) procedure SensitivityAngleTBChange(Sender: TObject); procedure AboutBtnClick(Sender: TObject); procedure CloseBtnClick(Sender: TObject); + procedure TriggerSensitivityTBChange(Sender: TObject); private { Private declarations } public @@ -40,29 +45,22 @@ TForm1 = class(TForm) end; var - Form1: TForm1; + Main: TMain; implementation {$R *.dfm} -procedure TForm1.ApplyBtnClick(Sender: TObject); +function GetLocaleInformation(flag: integer): string; var - Reg: TRegistry; + pcLCA: array [0..20] of Char; begin - Reg:=TRegistry.Create; - Reg.RootKey:=HKEY_CURRENT_USER; - if Reg.OpenKey('\Software\r57zone\X360Advance', true) then begin - Reg.WriteInteger('Port', StrToInt(COMPortNumberEdt.Text)); - Reg.WriteInteger('SensX', XAxisSensitivityTB.Position); - Reg.WriteInteger('SensY', YAxisSensitivityTB.Position); - Reg.WriteInteger('WheelAngle', SensitivityAngleTB.Position); - end; - Reg.Free; - Close; + if GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, flag, pcLCA, 19) <= 0 then + pcLCA[0]:=#0; + Result:=pcLCA; end; -procedure TForm1.FormCreate(Sender: TObject); +procedure TMain.FormCreate(Sender: TObject); var Reg: TRegistry; begin @@ -75,36 +73,78 @@ procedure TForm1.FormCreate(Sender: TObject); XAxisSensitivityTB.Position:=Reg.ReadInteger('SensX'); YAxisSensitivityTB.Position:=Reg.ReadInteger('SensY'); SensitivityAngleTB.Position:=Reg.ReadInteger('WheelAngle'); + CBOnlyTrigger.Checked:=Reg.ReadBool('OnlyTrigger'); + TriggerSensitivityTB.Position:=Reg.ReadInteger('TriggerSens'); end; Reg.Free; XAxisSensitivityValueLbl.Caption:=FloatToStr(XAxisSensitivityTB.Position * 0.1); YAxisSensitivityValueLbl.Caption:=FloatToStr(YAxisSensitivityTB.Position * 0.1); SensitivityAngleValueLbl.Caption:=FloatToStr(SensitivityAngleTB.Position); + TriggerSensitivityValueLbl.Caption:=FloatToStr(TriggerSensitivityTB.Position * 0.1); + + if GetLocaleInformation(LOCALE_SENGLANGUAGE) = 'Russian' then begin + Main.Caption:='X360Advance - Настройка'; + SetupGB.Caption:='Настройка'; + COMPortLbl.Caption:='Номер COM-порта'; + SteeringWheelGB.Caption:='Руль'; + SensitivityAngleLbl.Caption:='Угол чувствительности'; + MouseGB.Caption:='Мышь'; + CBOnlyTrigger.Caption:='Активир. по левому триггеру'; + XAxisSensitivityLbl.Caption:='Чувствительность оси Х'; + YAxisSensitivityLbl.Caption:='Чувствительность оси Y'; + TriggerSensitivityLbl.Caption:='Чувствит. с левым триггером'; + TriggerSensitivityLbl.Hint:='Уменьшите чувствительность, чтобы более точно целится.'; + ApplyBtn.Caption:='Применить'; + CloseBtn.Caption:='Выйти'; + end; end; -procedure TForm1.XAxisSensitivityTBChange(Sender: TObject); +procedure TMain.ApplyBtnClick(Sender: TObject); +var + Reg: TRegistry; +begin + Reg:=TRegistry.Create; + Reg.RootKey:=HKEY_CURRENT_USER; + if Reg.OpenKey('\Software\r57zone\X360Advance', true) then begin + Reg.WriteInteger('Port', StrToInt(COMPortNumberEdt.Text)); + Reg.WriteInteger('SensX', XAxisSensitivityTB.Position); + Reg.WriteInteger('SensY', YAxisSensitivityTB.Position); + Reg.WriteInteger('WheelAngle', SensitivityAngleTB.Position); + Reg.WriteBool('OnlyTrigger', CBOnlyTrigger.Checked); + Reg.WriteInteger('TriggerSens', TriggerSensitivityTB.Position); + end; + Reg.Free; + Close; +end; + +procedure TMain.XAxisSensitivityTBChange(Sender: TObject); begin XAxisSensitivityValueLbl.Caption:=FloatToStr(XAxisSensitivityTB.Position * 0.1); end; -procedure TForm1.YAxisSensitivityTBChange(Sender: TObject); +procedure TMain.YAxisSensitivityTBChange(Sender: TObject); begin YAxisSensitivityValueLbl.Caption:=FloatToStr(YAxisSensitivityTB.Position * 0.1); end; -procedure TForm1.SensitivityAngleTBChange(Sender: TObject); +procedure TMain.SensitivityAngleTBChange(Sender: TObject); begin SensitivityAngleValueLbl.Caption:=FloatToStr(SensitivityAngleTB.Position); end; -procedure TForm1.AboutBtnClick(Sender: TObject); +procedure TMain.AboutBtnClick(Sender: TObject); begin Application.MessageBox(PChar('X360Advance' + #13#10 + 'https://github.com/r57zone/X360Advance' + #13#10 + 'r57zone@gmail.com'), PChar(Caption), MB_ICONINFORMATION); end; -procedure TForm1.CloseBtnClick(Sender: TObject); +procedure TMain.CloseBtnClick(Sender: TObject); begin Close; end; +procedure TMain.TriggerSensitivityTBChange(Sender: TObject); +begin + TriggerSensitivityValueLbl.Caption:=FloatToStr(TriggerSensitivityTB.Position * 0.1); +end; + end. diff --git a/XInputInject/XInputInject.cpp b/XInputInject/XInputInject.cpp index 2d32be3..3ee4b1a 100644 --- a/XInputInject/XInputInject.cpp +++ b/XInputInject/XInputInject.cpp @@ -55,8 +55,8 @@ float ArduinoData[4] = { 0, 0, 0, 0 }; //Mode, Yaw, Pitch, Roll float LastArduinoData[4] = { 0, 0, 0, 0 }; float YRPOffset[3] = { 0, 0, 0 }; BYTE GameMode = 0; -DWORD WheelAngle, SensX, SensY;//, TriggerSens; -int last_x = 0, last_y = 0; +DWORD WheelAngle, SensX, SensY, TriggerSens, OnlyTrigger; +float accumulatedX = 0, accumulatedY = 0; DWORD WorkStatus = 0; void Centering() @@ -69,13 +69,9 @@ void Centering() bool CorrectAngleValue(float Value) { if (Value > -180 && Value < 180) - { return true; - } else - { return false; - } } void ArduinoRead() @@ -126,14 +122,12 @@ void ArduinoRead() Centering(); } - Sleep(1); //Don't overload CPU - + //Sleep(1); //Don't overload CPU } } void ArduinoStart() { - TCHAR HardwareInsertWav[MAX_PATH] = { 0 }; TCHAR HardwareFailWav[MAX_PATH] = { 0 }; GetSystemWindowsDirectory(HardwareInsertWav, sizeof(HardwareInsertWav)); @@ -151,9 +145,11 @@ void ArduinoStart() key.QueryDWORDValue(_T("Port"), PortNumber); key.QueryDWORDValue(_T("WheelAngle"), WheelAngle); //def 75 - key.QueryDWORDValue(_T("SensX"), SensX); //def 45 - key.QueryDWORDValue(_T("SensY"), SensY); //def 35 - + key.QueryDWORDValue(_T("SensX"), SensX); //def 35 + key.QueryDWORDValue(_T("SensY"), SensY); //def 30 + key.QueryDWORDValue(_T("TriggerSens"), TriggerSens); + TriggerSens = TriggerSens / 10.0f; + key.QueryDWORDValue(_T("OnlyTrigger"), OnlyTrigger); } key.Close(); @@ -219,40 +215,25 @@ double OffsetYPR(float f, float f2) return f; } -int MouseGetDelta(int val, int prev) //Implementation from OpenTrack https://github.com/opentrack/opentrack/blob/unstable/proto-mouse/ -{ - const int a = std::abs(val - prev), b = std::abs(val + prev); - if (b < a) - return val + prev; - else - return val - prev; -} - -void MouseMove(const double axisX, const double axisY) //Implementation from OpenTrack https://github.com/opentrack/opentrack/blob/unstable/proto-mouse/ -{ - int mouse_x = 0, mouse_y = 0; - - mouse_x = round(axisX * SensX * 0.1 * 2); //* 0.1 - mouse_y = round(axisY * SensY * 0.1 * 2); - - const int dx = MouseGetDelta(mouse_x, last_x); - const int dy = MouseGetDelta(mouse_y, last_y); - - last_x = mouse_x; - last_y = mouse_y; - - if (dx || dy) - { - INPUT input; - input.type = INPUT_MOUSE; - MOUSEINPUT& mi = input.mi; - mi = {}; - mi.dx = dx; - mi.dy = dy; - mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE; - - SendInput(1, &input, sizeof(input)); - } +//Implementation from https://github.com/JibbSmart/JoyShockMapper/blob/master/JoyShockMapper/src/win32/InputHelpers.cpp +void MoveMouse(float x, float y) { + accumulatedX += x; + accumulatedY += y; + + int applicableX = (int)accumulatedX; + int applicableY = (int)accumulatedY; + + accumulatedX -= applicableX; + accumulatedY -= applicableY; + + INPUT input; + input.type = INPUT_MOUSE; + input.mi.mouseData = 0; + input.mi.time = 0; + input.mi.dx = applicableX; + input.mi.dy = applicableY; + input.mi.dwFlags = MOUSEEVENTF_MOVE; + SendInput(1, &input, sizeof(input)); } //Own GetState @@ -264,31 +245,33 @@ DWORD WINAPI detourXInputGetState(DWORD dwUserIndex, XINPUT_STATE* pState) } //ZeroMemory(pState, sizeof(XINPUT_STATE)); + // first call the original function DWORD toReturn = hookedXInputGetState(dwUserIndex, pState); - - if (ArduinoWork) + + //Bugs: Crysis 2 is having problems, although it seemed to work before. + + if (toReturn == ERROR_SUCCESS && ArduinoWork) switch (GameMode) { - case 1: //Wheel + case 1: //Wheel { pState->Gamepad.sThumbLX = ToLeftStick(OffsetYPR(ArduinoData[1], YRPOffset[0])) * -1; break; } case 2: //FPS { - //Gyroscope offset, experimental - //pState->Gamepad.sThumbRX = ThumbFix(myPState.Gamepad.sThumbRX + OffsetYPR(ArduinoData[1], YRPOffset[0]) * -182 * StickSensX); //StickSensX - 9 - //pState->Gamepad.sThumbRY = ThumbFix(myPState.Gamepad.sThumbRY + OffsetYPR(ArduinoData[3], YRPOffset[2]) * -182 * StickSensY); //StickSensX - 7 - - - /*if (pState->Gamepad.bLeftTrigger == 0) { - MouseMove(OffsetYPR(ArduinoData[1], YRPOffset[0]) * -1, OffsetYPR(ArduinoData[3], YRPOffset[2])); - } else { - MouseMove(OffsetYPR(ArduinoData[1], YRPOffset[0]) * -1 * TriggerSens, OffsetYPR(ArduinoData[3], YRPOffset[2]) * TriggerSens); - }*/ - - MouseMove(OffsetYPR(ArduinoData[1], YRPOffset[0]) * -1, OffsetYPR(ArduinoData[3], YRPOffset[2])); + float NewX = OffsetYPR(ArduinoData[1], YRPOffset[0]) * -1; + float NewY = OffsetYPR(ArduinoData[3], YRPOffset[2]); + + if (pState->Gamepad.bLeftTrigger == 0) { + if (OnlyTrigger == false) + MoveMouse(NewX * SensX, NewY * SensY); + } else + MoveMouse(NewX * SensX * TriggerSens, NewY * SensY * TriggerSens); + + Centering(); + break; } case 3: //Fully emulation, experimental @@ -296,8 +279,16 @@ DWORD WINAPI detourXInputGetState(DWORD dwUserIndex, XINPUT_STATE* pState) pState->Gamepad.sThumbRX = ThumbFix(OffsetYPR(ArduinoData[1], YRPOffset[0]) * -750); pState->Gamepad.sThumbRY = ThumbFix(OffsetYPR(ArduinoData[3], YRPOffset[2]) * -750); + Centering(); + break; } + /*case 4: //FPS, gyroscope offset, experimental + { + pState->Gamepad.sThumbRX = ThumbFix(myPState.Gamepad.sThumbRX + OffsetYPR(ArduinoData[1], YRPOffset[0]) * -182 * StickSensX); //StickSensX - 9 + pState->Gamepad.sThumbRY = ThumbFix(myPState.Gamepad.sThumbRY + OffsetYPR(ArduinoData[3], YRPOffset[2]) * -182 * StickSensY); //StickSensX - 7 + }*/ + } return toReturn; @@ -315,7 +306,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, if (MH_Initialize() == MH_OK) { //1.0 - if (MH_CreateHookApiEx(L"XINPUT9_1_0", "XInputGetStateEx", &detourXInputGetState, &hookedXInputGetState) == MH_OK) //Ex, Bulletstorm + if (MH_CreateHookApiEx(L"XINPUT9_1_0", "XInputGetStateEx", &detourXInputGetState, &hookedXInputGetState) == MH_OK) //Ex! - Bulletstorm (2011) WorkStatus++; //1_1 diff --git a/XInputInjector/HiddenProcesses.txt b/XInputInjector/HiddenProcesses.txt index 5310554..0dd761d 100644 --- a/XInputInjector/HiddenProcesses.txt +++ b/XInputInjector/HiddenProcesses.txt @@ -2,6 +2,7 @@ explorer.exe iexplore.exe cmd.exe Taskmgr.exe +WinStore.App.exe ApplicationFrameHost.exe WindowsInternal.ComposableShell.Experiences.TextInput.InputApp.exe mspaint.exe @@ -15,4 +16,5 @@ MicrosoftEdgeCP.exe MicrosoftEdgeSH.exe opera.exe thunderbird.exe -Telegram.exe \ No newline at end of file +Telegram.exe +steam.exe \ No newline at end of file diff --git a/XInputInjector/Unit1.dfm b/XInputInjector/Unit1.dfm index 13033e5..6ab4beb 100644 --- a/XInputInjector/Unit1.dfm +++ b/XInputInjector/Unit1.dfm @@ -28,7 +28,7 @@ object Main: TMain end item AutoSize = True - Caption = 'Name' + Caption = 'Process' end item AutoSize = True @@ -65,14 +65,14 @@ object Main: TMain TabOrder = 2 OnChange = SelectLibCBChange end - object HideBtn: TButton + object SettingsBtn: TButton Left = 263 Top = 196 Width = 75 Height = 25 - Caption = 'Hide' + Caption = 'Settings' TabOrder = 3 - OnClick = HideBtnClick + OnClick = SettingsBtnClick end object ImageList: TImageList Height = 32 diff --git a/XInputInjector/Unit1.pas b/XInputInjector/Unit1.pas index bb564f6..d1cf0d7 100644 --- a/XInputInjector/Unit1.pas +++ b/XInputInjector/Unit1.pas @@ -20,7 +20,7 @@ TMain = class(TForm) N2: TMenuItem; ShowHideBtn: TMenuItem; SelectLibCB: TComboBox; - HideBtn: TButton; + SettingsBtn: TButton; procedure RefreshBtnClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); @@ -31,7 +31,7 @@ TMain = class(TForm) Shift: TShiftState; X, Y: Integer); procedure ListViewDblClick(Sender: TObject); procedure SelectLibCBChange(Sender: TObject); - procedure HideBtnClick(Sender: TObject); + procedure SettingsBtnClick(Sender: TObject); private procedure WMNCHITTEST(var Msg: TMessage); message WM_NCHITTEST; procedure DefaultHandler(var Message); override; @@ -139,8 +139,10 @@ procedure UpdateLibs(SelectName: string); Main.SelectLibCB.ItemIndex:=0; for i:=0 to Main.SelectLibCB.Items.Count - 1 do - if Main.SelectLibCB.Items.Strings[i] = SelectName then + if Main.SelectLibCB.Items.Strings[i] = SelectName then begin Main.SelectLibCB.ItemIndex:=i; + Main.SettingsBtn.Enabled:=FileExists(ExtractFilePath(ParamStr(0)) + 'Libraries\' + Main.SelectLibCB.Items.Strings[Main.SelectLibCB.ItemIndex] + '\Settings.exe'); + end; end; procedure TMain.RefreshBtnClick(Sender: TObject); @@ -178,7 +180,10 @@ procedure TMain.RefreshBtnClick(Sender: TObject); Item:=ListView.Items.Add; Item.SubItems.Add(string(ProcInfo.szExeFile)); - Item.SubItems.Add(StrPas(WindowTitle)); + if Trim(StrPas(WindowTitle)) <> '' then + Item.SubItems.Add(StrPas(WindowTitle)) + else + Item.SubItems.Add('-'); Item.SubItems.Add(PIDPath); Item.ImageIndex:=ImageList.AddIcon(Icon); @@ -249,11 +254,11 @@ procedure TMain.FormCreate(Sender: TObject); IDS_FAIL_INJECTION:='Failed to make an injection.'; IDS_LAST_UPDATE:='Last update:'; if GetLocaleInformation(LOCALE_SENGLANGUAGE) = 'Russian' then begin - ListView.Columns[1].Caption:='Имя'; + ListView.Columns[1].Caption:='Процесс'; ListView.Columns[2].Caption:='Заголовок'; ListView.Columns[3].Caption:='Расположение'; RefreshBtn.Caption:='Обновить'; - HideBtn.Caption:='Скрыть'; + SettingsBtn.Caption:='Настройка'; IDS_FAIL_INJECTION:='Не удалось внедриться в процесс.'; ShowHideBtn.Caption:='Показать / скрыть'; AboutBtn.Caption:='О программе...'; @@ -297,8 +302,8 @@ procedure TMain.WMNCHITTEST(var Msg: TMessage); procedure TMain.AboutBtnClick(Sender: TObject); begin - Application.MessageBox(PChar(Caption + ' 0.2.1' + #13#10 + - IDS_LAST_UPDATE + ' 01.12.2019' + #13#10 + + Application.MessageBox(PChar(Caption + ' 0.3' + #13#10 + + IDS_LAST_UPDATE + ' 18.01.2021' + #13#10 + 'https://r57zone.github.io' + #13#10 + 'r57zone@gmail.com'), PChar(AboutBtn.Caption), MB_ICONINFORMATION); end; @@ -388,15 +393,17 @@ procedure TMain.SelectLibCBChange(Sender: TObject); Ini: TIniFile; begin if SelectLibCB.Items.Strings[SelectLibCB.ItemIndex] <> '' then begin + SettingsBtn.Enabled:=FileExists(ExtractFilePath(ParamStr(0)) + 'Libraries\' + SelectLibCB.Items.Strings[SelectLibCB.ItemIndex] + '\Settings.exe'); Ini:=TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'Setup.ini'); Ini.WriteString('Main', 'CurrentLibrary', SelectLibCB.Items.Strings[SelectLibCB.ItemIndex]); Ini.Free; end; end; -procedure TMain.HideBtnClick(Sender: TObject); +procedure TMain.SettingsBtnClick(Sender: TObject); begin - AppHide; + if FileExists(ExtractFilePath(ParamStr(0)) + 'Libraries\' + SelectLibCB.Items.Strings[SelectLibCB.ItemIndex] + '\Settings.exe') then + WinExec(PChar(ExtractFilePath(ParamStr(0)) + 'Libraries\' + SelectLibCB.Items.Strings[SelectLibCB.ItemIndex] + '\Settings.exe'), SW_SHOW); end; end. diff --git a/XInputProxy/X360Advance.ini b/XInputProxy/X360Advance.ini index eb7eb2e..0cf5a94 100644 --- a/XInputProxy/X360Advance.ini +++ b/XInputProxy/X360Advance.ini @@ -1,14 +1,27 @@ [Main] -ComPort=3 +ComPort=2 ; The steering wheel angle is 25 degrees one way and 25 degrees to the other (two angles in total sum, for example, 50). ; Угол поворота руля, 25 градусов в одну сторону и 25 в другую (указывается суммарный, например, 50). WheelAngle=75 +; Activating the mouse along with pressing the left trigger +; 0 or 1 +; Активация мыши вместе с нажатием левого триггера +; 0 или 1 + +ActivateByTrigger=0 + ; Sensitivity of axes in FPS mode ; Чувствительность осей в режиме FPS -; 0 - 100 -SensX=4.5 -SensY=3.5 \ No newline at end of file +SensX=35 +SensY=30 + +; Reduce the sensitivity of the gyroscope axes when pressing the left trigger +; 0 - 1 (1 - 100% - off, 0.5 - 50% slowdown, 0.3 - 70% slowdown) +; Уменьшение чувствительности осей гироскопа, при нажатии левого триггера +; 0 - 1 (1 - 100% - выключено, 0.5 - 50% замедления, 0.3 - 70% замедления) + +TriggerSens=0.3 \ No newline at end of file diff --git a/XInputProxy/XInput.cpp b/XInputProxy/XInput.cpp index d766b52..0792645 100644 --- a/XInputProxy/XInput.cpp +++ b/XInputProxy/XInput.cpp @@ -89,15 +89,15 @@ _XINPUT_STATE myPState; HMODULE hDll; -bool ArduinoInit = false, ArduinoWork = false; +bool ArduinoInit = false, ArduinoWork = false, OnlyTrigger; std::thread *pArduinothread = NULL; HANDLE hSerial; float ArduinoData[4] = { 0, 0, 0, 0 }; //Mode, Yaw, Pitch, Roll float LastArduinoData[4] = { 0, 0, 0, 0 }; float YRPOffset[3] = { 0, 0, 0 }; BYTE GameMode = 0; -double WheelAngle, SensX, SensY;//, TriggerSens; -int last_x = 0, last_y = 0; +double WheelAngle, SensX, SensY, TriggerSens; +float accumulatedX = 0, accumulatedY = 0; void Centering() { @@ -171,9 +171,10 @@ void ArduinoRead() void ArduinoStart() { CIniReader IniFile("X360Advance.ini"); WheelAngle = IniFile.ReadFloat("Main", "WheelAngle", 75); - SensX = IniFile.ReadFloat("Main", "SensX", 4.5); - SensY = IniFile.ReadFloat("Main", "SensY", 3.5); - //TriggerSens = IniFile.ReadFloat("Main", "TriggerSens", 0.5); + SensX = IniFile.ReadFloat("Main", "SensX", 35); + SensY = IniFile.ReadFloat("Main", "SensY", 30); + TriggerSens = IniFile.ReadFloat("Main", "TriggerSens", 1); + OnlyTrigger = IniFile.ReadFloat("Main", "ActivateByTrigger", 0); TCHAR XInputPath[MAX_PATH] = { 0 }; GetSystemWindowsDirectory(XInputPath, sizeof(XInputPath)); @@ -192,8 +193,8 @@ void ArduinoStart() { hDll = NULL; } - CString sPortName; - sPortName.Format(_T("COM%d"), IniFile.ReadInteger("Main", "ComPort", 3)); + char sPortName[8]; + sprintf_s(sPortName, "COM%d", IniFile.ReadInteger("Main", "ComPort", 2)); hSerial = ::CreateFile(sPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); @@ -276,40 +277,25 @@ double OffsetYPR(float f, float f2) return f; } -int MouseGetDelta(int val, int prev) //Implementation from OpenTrack https://github.com/opentrack/opentrack/blob/unstable/proto-mouse/ -{ - const int a = std::abs(val - prev), b = std::abs(val + prev); - if (b < a) - return val + prev; - else - return val - prev; -} - -void MouseMove(const double axisX, const double axisY) //Implementation from OpenTrack https://github.com/opentrack/opentrack/blob/unstable/proto-mouse/ -{ - int mouse_x = 0, mouse_y = 0; - - mouse_x = round(axisX * SensX * 2); - mouse_y = round(axisY * SensY * 2); - - const int dx = MouseGetDelta(mouse_x, last_x); - const int dy = MouseGetDelta(mouse_y, last_y); - - last_x = mouse_x; - last_y = mouse_y; - - if (dx || dy) - { - INPUT input; - input.type = INPUT_MOUSE; - MOUSEINPUT& mi = input.mi; - mi = {}; - mi.dx = dx; - mi.dy = dy; - mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE; - - SendInput(1, &input, sizeof(input)); - } +//Implementation from https://github.com/JibbSmart/JoyShockMapper/blob/master/JoyShockMapper/src/win32/InputHelpers.cpp +void MoveMouse(float x, float y) { + accumulatedX += x; + accumulatedY += y; + + int applicableX = (int)accumulatedX; + int applicableY = (int)accumulatedY; + + accumulatedX -= applicableX; + accumulatedY -= applicableY; + + INPUT input; + input.type = INPUT_MOUSE; + input.mi.mouseData = 0; + input.mi.time = 0; + input.mi.dx = applicableX; + input.mi.dy = applicableY; + input.mi.dwFlags = MOUSEEVENTF_MOVE; + SendInput(1, &input, sizeof(input)); } DLLEXPORT DWORD WINAPI XInputGetState(_In_ DWORD dwUserIndex, _Out_ XINPUT_STATE *pState) @@ -406,21 +392,18 @@ DLLEXPORT DWORD WINAPI XInputGetState(_In_ DWORD dwUserIndex, _Out_ XINPUT_STATE case 2: //FPS { - //Fully emulation - //pState->Gamepad.sThumbRX = ThumbFix(OffsetYPR(ArduinoData[1], YRPOffset[0]) * -750); - //pState->Gamepad.sThumbRY = ThumbFix(OffsetYPR(ArduinoData[3], YRPOffset[2]) * -750); - - //Gyroscope offset - //pState->Gamepad.sThumbRX = ThumbFix(myPState.Gamepad.sThumbRX + OffsetYPR(ArduinoData[1], YRPOffset[0]) * -182 * StickSensX); //StickSensX - 9 - //pState->Gamepad.sThumbRY = ThumbFix(myPState.Gamepad.sThumbRY + OffsetYPR(ArduinoData[3], YRPOffset[2]) * -182 * StickSensY); //StickSensX - 7 - - /*if (pState->Gamepad.bLeftTrigger == 0) { - MouseMove(OffsetYPR(ArduinoData[1], YRPOffset[0]) * -1, OffsetYPR(ArduinoData[3], YRPOffset[2])); - } else { - MouseMove(OffsetYPR(ArduinoData[1], YRPOffset[0]) * -1 * TriggerSens, OffsetYPR(ArduinoData[3], YRPOffset[2]) * TriggerSens); - }*/ - - MouseMove(OffsetYPR(ArduinoData[1], YRPOffset[0]) * -1, OffsetYPR(ArduinoData[3], YRPOffset[2])); + float NewX = OffsetYPR(ArduinoData[1], YRPOffset[0]) * -1; + float NewY = OffsetYPR(ArduinoData[3], YRPOffset[2]); + + if (pState->Gamepad.bLeftTrigger == 0) { + if (OnlyTrigger == false) + MoveMouse(NewX * SensX, NewY * SensY); + } + else + MoveMouse(NewX * SensX * TriggerSens, NewY * SensY * TriggerSens); + + Centering(); + break; } @@ -429,6 +412,8 @@ DLLEXPORT DWORD WINAPI XInputGetState(_In_ DWORD dwUserIndex, _Out_ XINPUT_STATE pState->Gamepad.sThumbRX = ThumbFix(OffsetYPR(ArduinoData[1], YRPOffset[0]) * -750); pState->Gamepad.sThumbRY = ThumbFix(OffsetYPR(ArduinoData[3], YRPOffset[2]) * -750); + Centering(); + break; } }