mirror of
https://github.com/Thracky/GlosSI.git
synced 2024-11-03 09:40:18 +00:00
begin rewrite
This commit is contained in:
parent
e2fc546d69
commit
9f61d9fb3f
@ -71,7 +71,7 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\build\Win32Only\$(Configuration)</OutDir>
|
||||
<OutDir>$(SolutionDir)\build\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016 Peter Repukat - FlatspotSoftware
|
||||
Copyright 2018 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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016 Peter Repukat - FlatspotSoftware
|
||||
Copyright 2018 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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016 Peter Repukat - FlatspotSoftware
|
||||
Copyright 2018 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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016 Peter Repukat - FlatspotSoftware
|
||||
Copyright 2018 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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016 Peter Repukat - FlatspotSoftware
|
||||
Copyright 2018 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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016 Peter Repukat - FlatspotSoftware
|
||||
Copyright 2018 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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016 Peter Repukat - FlatspotSoftware
|
||||
Copyright 2018 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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016 Peter Repukat - FlatspotSoftware
|
||||
Copyright 2018 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.
|
||||
|
86
SteamTarget/SteamTarget.cpp
Normal file
86
SteamTarget/SteamTarget.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
#include "SteamTarget.h"
|
||||
#include <Windows.h>
|
||||
#include <QTimer>
|
||||
#include <QSettings>
|
||||
#include <qmessagebox.h>
|
||||
#include <iostream>
|
||||
|
||||
SteamTarget::SteamTarget(int& argc, char** argv) : QApplication(argc, argv)
|
||||
{
|
||||
}
|
||||
|
||||
void SteamTarget::init()
|
||||
{
|
||||
connect(this, SIGNAL(aboutToQuit()), this, SLOT(onAboutToQuit()));
|
||||
SetConsoleCtrlHandler(reinterpret_cast<PHANDLER_ROUTINE>(ConsoleCtrlCallback), true);
|
||||
read_ini();
|
||||
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
|
||||
target_overlay_.init(!enable_overlay_);
|
||||
if (enable_controllers_)
|
||||
controller_thread_.run();
|
||||
}
|
||||
|
||||
BOOL SteamTarget::ConsoleCtrlCallback(DWORD dwCtrlType)
|
||||
{
|
||||
if (dwCtrlType == CTRL_CLOSE_EVENT || dwCtrlType == CTRL_BREAK_EVENT || dwCtrlType == CTRL_C_EVENT)
|
||||
{
|
||||
quit();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SteamTarget::onAboutToQuit()
|
||||
{
|
||||
controller_thread_.stop();
|
||||
target_overlay_.stop();
|
||||
}
|
||||
|
||||
void SteamTarget::read_ini()
|
||||
{
|
||||
if (arguments().size() == 1)
|
||||
{
|
||||
QMessageBox::warning(nullptr, "Error", "Target configuration file must be specified! Using default Values!");
|
||||
}
|
||||
else {
|
||||
QSettings settings(arguments().at(1), QSettings::IniFormat);
|
||||
settings.beginGroup("BaseConf");
|
||||
QStringList childKeys = settings.childKeys();
|
||||
for (auto &childkey : childKeys)
|
||||
{
|
||||
if (childkey == "bEnableOverlay") {
|
||||
enable_overlay_ = settings.value(childkey).toBool();
|
||||
}
|
||||
else if (childkey == "bEnableControllers") {
|
||||
enable_controllers_ = settings.value(childkey).toBool();
|
||||
}
|
||||
else if (childkey == "bHookSteam") {
|
||||
hook_steam_ = settings.value(childkey).toBool();
|
||||
}
|
||||
else if (childkey == "bUseDesktopConfig") {
|
||||
use_desktop_conf_ = settings.value(childkey).toBool();
|
||||
}
|
||||
}
|
||||
settings.endGroup();
|
||||
settings.beginGroup("LaunchGame");
|
||||
childKeys = settings.childKeys();
|
||||
for (auto &childkey : childKeys)
|
||||
{
|
||||
if (childkey == "bLaunchGame") {
|
||||
launch_game_ = settings.value(childkey).toBool();
|
||||
}
|
||||
else if (childkey == "Path") {
|
||||
launch_app_path_ = settings.value(childkey).toString().toStdString();
|
||||
}
|
||||
else if (childkey == "Type") {
|
||||
launch_uwp_ = settings.value(childkey).toString() == QString("UWP");
|
||||
}
|
||||
else if (childkey == "bCloseWhenDone") {
|
||||
close_launched_done_ = settings.value(childkey).toBool();
|
||||
}
|
||||
}
|
||||
settings.endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
|
58
SteamTarget/SteamTarget.h
Normal file
58
SteamTarget/SteamTarget.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright 2018 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 <QApplication>
|
||||
#include <thread>
|
||||
#include <Windows.h>
|
||||
#include <dwmapi.h>
|
||||
#include "TargetOverlay.h"
|
||||
#include "VirtualControllerThread.h"
|
||||
|
||||
|
||||
class SteamTarget : public QApplication
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SteamTarget(int& argc, char** argv);
|
||||
~SteamTarget() = default;
|
||||
|
||||
void init();
|
||||
static BOOL WINAPI ConsoleCtrlCallback(DWORD dwCtrlType);
|
||||
|
||||
public slots:
|
||||
void onAboutToQuit();
|
||||
|
||||
|
||||
private:
|
||||
void read_ini();
|
||||
|
||||
TargetOverlay target_overlay_;
|
||||
VirtualControllerThread controller_thread_;
|
||||
|
||||
//Settings from .ini file
|
||||
bool hook_steam_ = true;
|
||||
bool enable_overlay_ = true;
|
||||
bool enable_controllers_ = true;
|
||||
bool use_desktop_conf_ = false;
|
||||
bool launch_game_ = false;
|
||||
bool close_launched_done_ = false;
|
||||
bool launch_uwp_ = false;
|
||||
std::string launch_app_path_ = "";
|
||||
std::string launch_app_args_ = "";
|
||||
|
||||
};
|
||||
|
@ -131,6 +131,10 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_SteamTarget.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_SteamTargetRenderer.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
@ -145,12 +149,18 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_SteamTarget.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_SteamTargetRenderer.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="SteamTarget.cpp" />
|
||||
<ClCompile Include="SteamTargetRenderer.cpp" />
|
||||
<ClCompile Include="TargetOverlay.cpp" />
|
||||
<ClCompile Include="VirtualControllerThread.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -195,6 +205,25 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="resource.h" />
|
||||
<CustomBuild Include="SteamTarget.h">
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing %(Identity)...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -D_CONSOLE -D_X86_ -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\..\dependencies\ViGEmClient" "-I.\..\dependencies\SFML-2.4.2-x86\include" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets"</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Identity)...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -D_CONSOLE -D_AMD64_ -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\..\dependencies\ViGEmClient" "-I.\..\dependencies\SFML-2.4.2-x64\include" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets"</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing %(Identity)...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -D_CONSOLE -D_X86_ -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\..\dependencies\ViGEmClient" "-I.\..\dependencies\SFML-2.4.2-x86\include" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets"</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing %(Identity)...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -D_CONSOLE -D_AMD64_ -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\..\dependencies\ViGEmClient" "-I.\..\dependencies\SFML-2.4.2-x64\include" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets"</Command>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="TargetOverlay.h" />
|
||||
<ClInclude Include="VirtualControllerThread.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -58,6 +58,18 @@
|
||||
<ClCompile Include="VirtualControllerThread.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SteamTarget.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_SteamTarget.cpp">
|
||||
<Filter>Generated Files\Debug</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_SteamTarget.cpp">
|
||||
<Filter>Generated Files\Release</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TargetOverlay.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="SteamTarget.qrc">
|
||||
@ -66,6 +78,9 @@
|
||||
<CustomBuild Include="SteamTargetRenderer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="SteamTarget.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="resource.h">
|
||||
@ -74,6 +89,9 @@
|
||||
<ClInclude Include="VirtualControllerThread.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TargetOverlay.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="SteamTarget.rc" />
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016 Peter Repukat - FlatspotSoftware
|
||||
Copyright 2018 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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016 Peter Repukat - FlatspotSoftware
|
||||
Copyright 2018 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.
|
||||
|
122
SteamTarget/TargetOverlay.cpp
Normal file
122
SteamTarget/TargetOverlay.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
Copyright 2018 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.
|
||||
*/
|
||||
|
||||
#include "TargetOverlay.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <dwmapi.h>
|
||||
#include <SFML/Window/Event.hpp>
|
||||
|
||||
bool TargetOverlay::init(bool hidden)
|
||||
{
|
||||
window_.create(sf::VideoMode::getDesktopMode(), "GloSC-SteamTarget");
|
||||
window_.setFramerateLimit(30);
|
||||
window_.setPosition({ 0, 0 });
|
||||
makeSfWindowTransparent();
|
||||
hidden_ = hidden;
|
||||
if (window_.setActive(false))
|
||||
{
|
||||
overlay_thread_ = std::thread(&TargetOverlay::overlayLoop, this);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TargetOverlay::stop()
|
||||
{
|
||||
run_ = false;
|
||||
overlay_thread_.join();
|
||||
}
|
||||
|
||||
void TargetOverlay::overlayLoop()
|
||||
{
|
||||
if (window_.setActive(true))
|
||||
{
|
||||
|
||||
if (hidden_)
|
||||
{
|
||||
ShowWindow(window_.getSystemHandle(), SW_HIDE);
|
||||
window_.setFramerateLimit(1); //Window is not shown anyway,
|
||||
}
|
||||
else
|
||||
{
|
||||
SetWindowPos(window_.getSystemHandle(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_ASYNCWINDOWPOS);
|
||||
}
|
||||
|
||||
|
||||
while (window_.isOpen() && run_)
|
||||
{
|
||||
mtx_.lock();
|
||||
sf::Event event{};
|
||||
while (window_.pollEvent(event))
|
||||
{
|
||||
if (event.type == sf::Event::Closed)
|
||||
window_.close();
|
||||
}
|
||||
window_.clear(sf::Color::Transparent);
|
||||
window_.display();
|
||||
mtx_.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TargetOverlay::onOverlayOpened()
|
||||
{
|
||||
mtx_.lock();
|
||||
//TODO: impl
|
||||
mtx_.unlock();
|
||||
}
|
||||
|
||||
void TargetOverlay::onOverlayClosed()
|
||||
{
|
||||
mtx_.lock();
|
||||
//TODO: impl
|
||||
mtx_.unlock();
|
||||
}
|
||||
|
||||
void TargetOverlay::makeSfWindowTransparent()
|
||||
{
|
||||
HWND hwnd = window_.getSystemHandle();
|
||||
SetWindowLong(hwnd, GWL_STYLE, WS_VISIBLE | WS_POPUP &~ WS_CAPTION);
|
||||
SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST);
|
||||
|
||||
MARGINS margins;
|
||||
margins.cxLeftWidth = -1;
|
||||
|
||||
DwmExtendFrameIntoClientArea(hwnd, &margins);
|
||||
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
|
||||
|
||||
window_.clear(sf::Color::Transparent);
|
||||
window_.display();
|
||||
}
|
||||
|
||||
void TargetOverlay::moveMouseIntoOverlay() const
|
||||
{
|
||||
RECT rect = { 0,0,0,0 };
|
||||
if (GetWindowRect(window_.getSystemHandle(), &rect))
|
||||
{
|
||||
POINT cursor_pos = { 0,0 };
|
||||
GetCursorPos(&cursor_pos);
|
||||
if (PtInRect(&rect, cursor_pos))
|
||||
{
|
||||
SetCursorPos(cursor_pos.x + 1, cursor_pos.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCursorPos(rect.left + 16, rect.top + 16);
|
||||
}
|
||||
}
|
||||
}
|
46
SteamTarget/TargetOverlay.h
Normal file
46
SteamTarget/TargetOverlay.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright 2018 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 <SFML/Graphics/RenderWindow.hpp>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
class TargetOverlay
|
||||
{
|
||||
public:
|
||||
TargetOverlay() = default;
|
||||
|
||||
|
||||
bool init(bool hidden = false);
|
||||
void stop();
|
||||
|
||||
void overlayLoop();
|
||||
|
||||
void onOverlayOpened();
|
||||
void onOverlayClosed();
|
||||
|
||||
private:
|
||||
|
||||
void makeSfWindowTransparent();
|
||||
void moveMouseIntoOverlay() const;
|
||||
|
||||
std::thread overlay_thread_;
|
||||
sf::RenderWindow window_;
|
||||
std::mutex mtx_;
|
||||
bool run_ = true;
|
||||
bool hidden_ = false;
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016 Peter Repukat - FlatspotSoftware
|
||||
Copyright 2018 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.
|
||||
@ -18,9 +18,9 @@ limitations under the License.
|
||||
|
||||
VirtualControllerThread::VirtualControllerThread()
|
||||
{
|
||||
driver = vigem_alloc();
|
||||
driver_ = vigem_alloc();
|
||||
|
||||
if (!VIGEM_SUCCESS(vigem_connect(driver)))
|
||||
if (!VIGEM_SUCCESS(vigem_connect(driver_)))
|
||||
{
|
||||
std::cout << "Error initializing ViGem!" << std::endl;
|
||||
MessageBoxW(NULL, L"Error initializing ViGem!", L"GloSC-SteamTarget", MB_OK);
|
||||
@ -29,24 +29,24 @@ VirtualControllerThread::VirtualControllerThread()
|
||||
|
||||
for (int i = 0; i < XUSER_MAX_COUNT; i++)
|
||||
{
|
||||
vtX360[i] = vigem_target_x360_alloc();
|
||||
vt_x360_[i] = vigem_target_x360_alloc();
|
||||
}
|
||||
|
||||
seven = IsWindows7OrGreater() != IsWindows8OrGreater();
|
||||
seven_ = IsWindows7OrGreater() != IsWindows8OrGreater();
|
||||
}
|
||||
|
||||
|
||||
VirtualControllerThread::~VirtualControllerThread()
|
||||
{
|
||||
if (controllerThread.joinable())
|
||||
controllerThread.join();
|
||||
vigem_disconnect(driver);
|
||||
if (controller_thread_.joinable())
|
||||
controller_thread_.join();
|
||||
vigem_disconnect(driver_);
|
||||
}
|
||||
|
||||
void VirtualControllerThread::run()
|
||||
{
|
||||
bShouldRun = true;
|
||||
controllerThread = std::thread(&VirtualControllerThread::controllerLoop, this);
|
||||
controller_thread_ = std::thread(&VirtualControllerThread::controllerLoop, this);
|
||||
}
|
||||
|
||||
void VirtualControllerThread::stop()
|
||||
@ -54,34 +54,32 @@ void VirtualControllerThread::stop()
|
||||
bShouldRun = false;
|
||||
for (int i = 0; i < XUSER_MAX_COUNT; i++)
|
||||
{
|
||||
vigem_target_remove(driver, vtX360[i]);
|
||||
vigem_target_remove(driver_, vt_x360_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool VirtualControllerThread::isRunning()
|
||||
bool VirtualControllerThread::isRunning() const
|
||||
{
|
||||
return bShouldRun;
|
||||
}
|
||||
|
||||
void VirtualControllerThread::controllerLoop()
|
||||
{
|
||||
DWORD result;
|
||||
DWORD result2;
|
||||
sf::Clock waitForHookTimer;
|
||||
while (bShouldRun)
|
||||
{
|
||||
sfClock.restart();
|
||||
sf_clock_.restart();
|
||||
|
||||
// We have to retrieve the XInputGetState function by loading it via GetProcAdress
|
||||
// otherwise the M$ compiler calls to a jumptable, jumping to the real function
|
||||
// otherwise we get calls to a jumptable, jumping to the real function
|
||||
// We can't have this if we wan't to dynamically unpatch and repatch Valve's XInput hook
|
||||
// Also wait a second, jut to be sure Steam has done it's hooking thing...
|
||||
if (XGetState == nullptr && waitForHookTimer.getElapsedTime().asSeconds() > 1)
|
||||
if (x_get_state_ == nullptr && waitForHookTimer.getElapsedTime().asSeconds() > 1)
|
||||
{
|
||||
HMODULE xinputmod = nullptr;
|
||||
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
const HANDLE hProcess = GetCurrentProcess();
|
||||
HMODULE hMods[1024];
|
||||
DWORD cbNeeded;
|
||||
EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded);
|
||||
@ -103,31 +101,31 @@ void VirtualControllerThread::controllerLoop()
|
||||
}
|
||||
}
|
||||
|
||||
XInputGetState_t realXgstate = reinterpret_cast<XInputGetState_t>(GetProcAddress(xinputmod, "XInputGetState"));
|
||||
const XInputGetState_t realXgstate = reinterpret_cast<XInputGetState_t>(GetProcAddress(xinputmod, "XInputGetState"));
|
||||
|
||||
std::cout << "realXgstate: " << std::hex << realXgstate << "\n";
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
valveHookBytes[i] = *reinterpret_cast<uint8_t*>(reinterpret_cast<uint64_t>(*realXgstate) + i);
|
||||
valve_hook_bytes_[i] = *reinterpret_cast<uint8_t*>(reinterpret_cast<uint64_t>(*realXgstate) + i);
|
||||
}
|
||||
|
||||
XGetState = realXgstate;
|
||||
controllerCount = 1;
|
||||
x_get_state_ = realXgstate;
|
||||
controller_count_ = 1;
|
||||
}
|
||||
|
||||
if (XGetState != nullptr)
|
||||
if (x_get_state_ != nullptr)
|
||||
{
|
||||
for (int i = 0; i < XUSER_MAX_COUNT; i++)
|
||||
{
|
||||
////////
|
||||
XINPUT_STATE state = { 0 };
|
||||
result = XInputGetStateWrapper(i, &state);
|
||||
const DWORD result = XInputGetStateWrapper(i, &state);
|
||||
XINPUT_STATE state2 = { 0 };
|
||||
result2 = callRealXinputGetState(i, &state2);
|
||||
const DWORD result2 = callRealXinputGetState(i, &state2);
|
||||
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
if ( (result2 != ERROR_SUCCESS) == seven )
|
||||
if ( (result2 != ERROR_SUCCESS) == seven_ )
|
||||
{
|
||||
// By using VID and PID of Valve's SteamController, Steam doesn't give us ANOTHER "fake" XInput device
|
||||
// Leading to endless pain and suffering.
|
||||
@ -135,38 +133,40 @@ void VirtualControllerThread::controllerLoop()
|
||||
// Also annoying the shit out of the user when they open the overlay as steam prompts to setup new XInput devices
|
||||
// Also avoiding any fake inputs from Valve's default controllerprofile
|
||||
// -> Leading to endless pain and suffering
|
||||
vigem_target_set_vid(vtX360[i], 0x28de); //Valve SteamController VID
|
||||
vigem_target_set_pid(vtX360[i], 0x1102); //Valve SteamController PID
|
||||
vigem_target_set_vid(vt_x360_[i], 0x28de); //Valve SteamController VID
|
||||
vigem_target_set_pid(vt_x360_[i], 0x1102); //Valve SteamController PID
|
||||
|
||||
int vigem_res = vigem_target_add(driver, vtX360[i]);
|
||||
const int vigem_res = vigem_target_add(driver_, vt_x360_[i]);
|
||||
if (vigem_res == VIGEM_ERROR_TARGET_UNINITIALIZED)
|
||||
{
|
||||
vtX360[i] = vigem_target_x360_alloc();
|
||||
vt_x360_[i] = vigem_target_x360_alloc();
|
||||
}
|
||||
if (vigem_res == VIGEM_ERROR_NONE)
|
||||
{
|
||||
std::cout << "Plugged in controller " << vigem_target_get_index(vtX360[i]) << std::endl;
|
||||
vigem_target_x360_register_notification(driver, vtX360[i], reinterpret_cast<PVIGEM_X360_NOTIFICATION>(&VirtualControllerThread::controllerCallback));
|
||||
std::cout << "Plugged in controller " << vigem_target_get_index(vt_x360_[i]) << std::endl;
|
||||
vigem_target_x360_register_notification(driver_, vt_x360_[i],
|
||||
reinterpret_cast<PVIGEM_X360_NOTIFICATION>(&VirtualControllerThread::
|
||||
controllerCallback));
|
||||
}
|
||||
}
|
||||
|
||||
if (vtX360[i] != nullptr)
|
||||
vigem_target_x360_update(driver, vtX360[i], *reinterpret_cast<XUSB_REPORT*>(&state.Gamepad));
|
||||
if (vt_x360_[i] != nullptr)
|
||||
vigem_target_x360_update(driver_, vt_x360_[i], *reinterpret_cast<XUSB_REPORT*>(&state.Gamepad));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (VIGEM_SUCCESS(vigem_target_remove(driver, vtX360[i])))
|
||||
if (VIGEM_SUCCESS(vigem_target_remove(driver_, vt_x360_[i])))
|
||||
{
|
||||
std::cout << "Unplugged controller " << vigem_target_get_index(vtX360[i]) << std::endl;
|
||||
std::cout << "Unplugged controller " << vigem_target_get_index(vt_x360_[i]) << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tickTime = sfClock.getElapsedTime().asMicroseconds();
|
||||
if (tickTime < delay)
|
||||
tick_time_ = sf_clock_.getElapsedTime().asMicroseconds();
|
||||
if (tick_time_ < delay_)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(delay - tickTime));
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(delay_ - tick_time_));
|
||||
}
|
||||
|
||||
}
|
||||
@ -192,20 +192,20 @@ DWORD VirtualControllerThread::callRealXinputGetState(DWORD dwUserIndex, XINPUT_
|
||||
DWORD ret;
|
||||
DWORD dwOldProtect, dwBkup;
|
||||
|
||||
BYTE* Address = reinterpret_cast<BYTE*>(XGetState);
|
||||
VirtualProtect(Address, opPatchLenght, PAGE_EXECUTE_READWRITE, &dwOldProtect); //Change permissions of memory..
|
||||
for (DWORD i = 0; i < opPatchLenght; i++) //unpatch Valve's hook
|
||||
BYTE* Address = reinterpret_cast<BYTE*>(x_get_state_);
|
||||
VirtualProtect(Address, op_patch_lenght, PAGE_EXECUTE_READWRITE, &dwOldProtect); //Change permissions of memory..
|
||||
for (DWORD i = 0; i < op_patch_lenght; i++) //unpatch Valve's hook
|
||||
{
|
||||
*(Address + i) = realBytes[i];
|
||||
*(Address + i) = real_bytes_[i];
|
||||
}
|
||||
|
||||
ret = XGetState(dwUserIndex, pState); //Cal REAL XInputGetState...
|
||||
ret = x_get_state_(dwUserIndex, pState); //Cal REAL XInputGetState...
|
||||
|
||||
for (int i = 0; i < opPatchLenght; i++) //repatch Valve's hook
|
||||
for (int i = 0; i < op_patch_lenght; i++) //repatch Valve's hook
|
||||
{
|
||||
*(Address + i) = valveHookBytes[i];
|
||||
*(Address + i) = valve_hook_bytes_[i];
|
||||
}
|
||||
VirtualProtect(Address, opPatchLenght, dwOldProtect, &dwBkup); //Revert permission change...
|
||||
VirtualProtect(Address, op_patch_lenght, dwOldProtect, &dwBkup); //Revert permission change...
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016 Peter Repukat - FlatspotSoftware
|
||||
Copyright 2018 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.
|
||||
@ -39,7 +39,7 @@ public:
|
||||
void run();
|
||||
void stop();
|
||||
|
||||
bool isRunning();
|
||||
bool isRunning() const;
|
||||
|
||||
private:
|
||||
|
||||
@ -48,33 +48,33 @@ private:
|
||||
|
||||
typedef DWORD(WINAPI* XInputGetState_t)(DWORD dwUserIndex, XINPUT_STATE* pState);
|
||||
|
||||
static const uint8_t opPatchLenght = 5;
|
||||
uint8_t valveHookBytes[5];
|
||||
static const uint8_t op_patch_lenght = 5;
|
||||
uint8_t valve_hook_bytes_[5];
|
||||
|
||||
bool seven = false;
|
||||
bool seven_ = false;
|
||||
|
||||
#ifdef _AMD64_
|
||||
const uint8_t realBytes[5] = {0x48, 0x89, 0x5C, 0x24, 0x08};
|
||||
#else
|
||||
const uint8_t realBytes[5] = { 0x8B, 0xFF, 0x55, 0x8B, 0xEC };
|
||||
const uint8_t real_bytes_[5] = { 0x8B, 0xFF, 0x55, 0x8B, 0xEC };
|
||||
#endif
|
||||
//uint8_t realBytes[5] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x90 };
|
||||
|
||||
int controllerCount = 0;
|
||||
XInputGetState_t XGetState = nullptr;
|
||||
int controller_count_ = 0;
|
||||
XInputGetState_t x_get_state_ = nullptr;
|
||||
|
||||
PVIGEM_CLIENT driver;
|
||||
PVIGEM_TARGET vtX360[XUSER_MAX_COUNT];
|
||||
PVIGEM_CLIENT driver_;
|
||||
PVIGEM_TARGET vt_x360_[XUSER_MAX_COUNT];
|
||||
|
||||
std::thread controllerThread;
|
||||
std::thread controller_thread_;
|
||||
|
||||
sf::Clock sfClock;
|
||||
int tickTime = 0;
|
||||
int delay = 1000000 / 200;
|
||||
sf::Clock sf_clock_;
|
||||
int tick_time_ = 0;
|
||||
int delay_ = 1000000 / 200;
|
||||
|
||||
void controllerLoop();
|
||||
|
||||
static void controllerCallback(PVIGEM_CLIENT client, PVIGEM_TARGET Target, UCHAR LargeMotor, UCHAR SmallMotor, UCHAR LedNumber);
|
||||
static void __RPC_CALLEE controllerCallback(PVIGEM_CLIENT client, PVIGEM_TARGET Target, UCHAR LargeMotor, UCHAR SmallMotor, UCHAR LedNumber);
|
||||
|
||||
static DWORD XInputGetStateWrapper(DWORD dwUserIndex, XINPUT_STATE* pState); //Easier to find in x64dbg...
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016 Peter Repukat - FlatspotSoftware
|
||||
Copyright 2018 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.
|
||||
@ -15,11 +15,12 @@ limitations under the License.
|
||||
*/
|
||||
#include "SteamTargetRenderer.h"
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include "SteamTarget.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SteamTargetRenderer renderer(argc, argv);
|
||||
renderer.run();
|
||||
return renderer.exec();
|
||||
SteamTarget target(argc, argv);
|
||||
target.init();
|
||||
return target.exec();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user