Keep controller bindings / support taking screenshots

whoop whoop
pull/130/head
Peter Repukat 3 years ago
parent feb25b9440
commit 07d29acbc0

@ -80,14 +80,14 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<ExternalIncludePath>..\deps\SFML\include;..\deps\WinReg;..\deps\spdlog\include;..\deps\ValveFileVDF;$(ExternalIncludePath)</ExternalIncludePath> <ExternalIncludePath>..\deps\SFML\include;..\deps\WinReg;..\deps\spdlog\include;..\deps\ValveFileVDF;..\deps\subhook;$(ExternalIncludePath)</ExternalIncludePath>
<LibraryPath>..\deps\SFML\out\build\x64-Debug\lib;$(LibraryPath)</LibraryPath> <LibraryPath>..\deps\SFML\out\build\x64-Debug\lib;$(LibraryPath)</LibraryPath>
<CopyLocalProjectReference>false</CopyLocalProjectReference> <CopyLocalProjectReference>false</CopyLocalProjectReference>
<CopyLocalDeploymentContent>true</CopyLocalDeploymentContent> <CopyLocalDeploymentContent>true</CopyLocalDeploymentContent>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<ExternalIncludePath>..\deps\SFML\include;..\deps\WinReg;..\deps\spdlog\include;..\deps\subhook;$(ExternalIncludePath)</ExternalIncludePath> <ExternalIncludePath>..\deps\SFML\include;..\deps\WinReg;..\deps\spdlog\include;..\deps\ValveFileVDF;..\deps\subhook;$(ExternalIncludePath)</ExternalIncludePath>
<LibraryPath>..\deps\SFML\out\build\x64-Release\lib;$(LibraryPath)</LibraryPath> <LibraryPath>..\deps\SFML\out\build\x64-Release\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@ -122,7 +122,7 @@
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;SPDLOG_WCHAR_TO_UTF8_SUPPORT;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;SPDLOG_WCHAR_TO_UTF8_SUPPORT;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;SUBHOOK_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard> <LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
@ -138,7 +138,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;SPDLOG_WCHAR_TO_UTF8_SUPPORT;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;SPDLOG_WCHAR_TO_UTF8_SUPPORT;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;SUBHOOK_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard> <LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
@ -150,12 +150,14 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\deps\subhook\subhook.c" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
<ClCompile Include="OverlayDetector.cpp" /> <ClCompile Include="OverlayDetector.cpp" />
<ClCompile Include="SteamTarget.cpp" /> <ClCompile Include="SteamTarget.cpp" />
<ClCompile Include="TargetWindow.cpp" /> <ClCompile Include="TargetWindow.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\deps\subhook\subhook.h" />
<ClInclude Include="OverlayDetector.h" /> <ClInclude Include="OverlayDetector.h" />
<ClInclude Include="SteamTarget.h" /> <ClInclude Include="SteamTarget.h" />
<ClInclude Include="steam_sf_keymap.h" /> <ClInclude Include="steam_sf_keymap.h" />

@ -27,6 +27,9 @@
<ClCompile Include="OverlayDetector.cpp"> <ClCompile Include="OverlayDetector.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\deps\subhook\subhook.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="SteamTarget.h"> <ClInclude Include="SteamTarget.h">
@ -41,6 +44,9 @@
<ClInclude Include="steam_sf_keymap.h"> <ClInclude Include="steam_sf_keymap.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\deps\subhook\subhook.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\deps\SFML\out\build\x64-Debug\lib\sfml-system-d-2.dll" /> <None Include="..\deps\SFML\out\build\x64-Debug\lib\sfml-system-d-2.dll" />

@ -24,16 +24,33 @@ limitations under the License.
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <vdf_parser.hpp> #include <vdf_parser.hpp>
#include <subhook.h>
#ifdef _WIN32
subhook::Hook getFgWinHook;
static HWND target_hwnd = nullptr;
HWND keepForegroundWindow()
{
return target_hwnd;
}
#endif
SteamTarget::SteamTarget(int argc, char *argv[]) SteamTarget::SteamTarget(int argc, char *argv[])
: window_([this] { run_ = false; }), : window_([this] { run_ = false; }, getScreenshotHotkey()),
detector_([this](bool overlay_open) { onOverlayChanged(overlay_open); }), target_window_handle_(window_.getSystemHandle()) detector_([this](bool overlay_open) { onOverlayChanged(overlay_open); }), target_window_handle_(window_.getSystemHandle())
{ {
#ifdef _WIN32
target_hwnd = target_window_handle_;
#endif
} }
int SteamTarget::run() int SteamTarget::run()
{ {
run_ = true; run_ = true;
window_.setFpsLimit(90); window_.setFpsLimit(90);
keepControllerConfig(true);
while (run_) { while (run_) {
detector_.update(); detector_.update();
window_.update(); window_.update();
@ -57,11 +74,17 @@ void SteamTarget::focusWindow(WindowHandle hndl)
{ {
#ifdef _WIN32 #ifdef _WIN32
//MH_DisableHook(&GetForegroundWindow); // TODO: when GetForegroundWindow hooked, unhook! if (hndl == target_window_handle_) {
// store last focused window for later restore spdlog::info("Bring own window to foreground");
}
else {
spdlog::info("Bring window \"{:#x}\" to foreground", reinterpret_cast<uint64_t>(hndl));
}
keepControllerConfig(false); // unhook GetForegroundWindow
last_foreground_window_ = GetForegroundWindow(); last_foreground_window_ = GetForegroundWindow();
const DWORD fg_thread = GetWindowThreadProcessId(last_foreground_window_, nullptr); const DWORD fg_thread = GetWindowThreadProcessId(last_foreground_window_, nullptr);
//MH_EnableHook(&GetForegroundWindow); // TODO: when GetForegroundWindow hooked, re-hook! keepControllerConfig(true); // re-hook GetForegroundWindow
// lot's of ways actually bringing our window to foreground... // lot's of ways actually bringing our window to foreground...
const DWORD current_thread = GetCurrentThreadId(); const DWORD current_thread = GetCurrentThreadId();
@ -91,7 +114,9 @@ std::wstring SteamTarget::getSteamPath()
// TODO: check if keys/value exist // TODO: check if keys/value exist
// steam should always be open and have written reg values... // steam should always be open and have written reg values...
winreg::RegKey key{HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam"}; winreg::RegKey key{HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam"};
return key.GetStringValue(L"SteamPath"); const auto res = key.GetStringValue(L"SteamPath");
spdlog::info(L"Detected Steam Path: {}", res);
return res;
#else #else
return L""; // TODO return L""; // TODO
#endif #endif
@ -103,7 +128,9 @@ std::wstring SteamTarget::getSteamUserId()
// TODO: check if keys/value exist // TODO: check if keys/value exist
// steam should always be open and have written reg values... // steam should always be open and have written reg values...
winreg::RegKey key{HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam\\ActiveProcess"}; winreg::RegKey key{HKEY_CURRENT_USER, L"SOFTWARE\\Valve\\Steam\\ActiveProcess"};
return std::to_wstring(key.GetDwordValue(L"ActiveUser")); const auto res = std::to_wstring(key.GetDwordValue(L"ActiveUser"));
spdlog::info(L"Detected Steam UserId: {}", res);
return res;
#else #else
return L""; // TODO return L""; // TODO
#endif #endif
@ -111,10 +138,7 @@ std::wstring SteamTarget::getSteamUserId()
std::vector<std::string> SteamTarget::getOverlayHotkey() std::vector<std::string> SteamTarget::getOverlayHotkey()
{ {
const auto steam_path = getSteamPath(); const auto config_path = steam_path_ + std::wstring(user_data_path_) + steam_user_id_ + std::wstring(config_file_name_);
const auto user_id = getSteamUserId();
const auto config_path = steam_path + std::wstring(user_data_path_) + user_id + std::wstring(config_file_name_);
std::ifstream config_file(config_path); std::ifstream config_file(config_path);
// TODO: check if file exists // TODO: check if file exists
auto root = tyti::vdf::read(config_file); auto root = tyti::vdf::read(config_file);
@ -125,7 +149,42 @@ std::vector<std::string> SteamTarget::getOverlayHotkey()
// has anyone more than 4 keys to open overlay?! // has anyone more than 4 keys to open overlay?!
std::smatch m; std::smatch m;
if (!std::regex_match(hotkeys, m, std::regex(R"((\w*)\s*(\w*)\s*(\w*)\s*(\w*))"))) { if (!std::regex_match(hotkeys, m, std::regex(R"((\w*)\s*(\w*)\s*(\w*)\s*(\w*))"))) {
return {"Shift", "KEY_TAB"}; spdlog::warn("Couldn't detect overlay hotkey, using default: Shift+Tab");
return {"Shift", "KEY_TAB"}; // default
}
std::vector<std::string> res;
for (auto i = 1; i < m.size(); i++) {
const auto s = std::string(m[i]);
if (!s.empty()) {
res.push_back(s);
}
}
if (res.empty()) {
spdlog::warn("Couldn't detect overlay hotkey, using default: Shift+Tab");
return {"Shift", "KEY_TAB"}; // default
}
spdlog::info("Detected Overlay hotkey(s): {}", std::accumulate(
res.begin() + 1, res.end(), res[0],
[](auto acc, const auto curr) { return acc += "+" + curr; }));
return res;
}
std::vector<std::string> SteamTarget::getScreenshotHotkey()
{
const auto config_path = steam_path_ + std::wstring(user_data_path_) + steam_user_id_ + std::wstring(config_file_name_);
std::ifstream config_file(config_path);
// TODO: check if file exists
auto root = tyti::vdf::read(config_file);
auto children = root.childs["system"];
auto hotkeys = children->attribs.at("InGameOverlayScreenshotHotKey");
// has anyone more than 4 keys to screenshot?!
std::smatch m;
if (!std::regex_match(hotkeys, m, std::regex(R"((\w*)\s*(\w*)\s*(\w*)\s*(\w*))"))) {
spdlog::warn("Couldn't detect overlay hotkey, using default: F12");
return {"KEY_F12"}; //default
} }
std::vector<std::string> res; std::vector<std::string> res;
@ -135,39 +194,63 @@ std::vector<std::string> SteamTarget::getOverlayHotkey()
res.push_back(s); res.push_back(s);
} }
} }
spdlog::info("Detected Overlay hotkeys: {}", std::accumulate( if (res.empty()) {
res.begin() + 1, res.end(), res[0], spdlog::warn("Couldn't detect overlay hotkey, using default: F12");
[](auto acc, const auto curr) { return acc += "+" + curr; })); return {"KEY_F12"}; //default
}
spdlog::info("Detected screenshot hotkey(s): {}", std::accumulate(
res.begin() + 1, res.end(), res[0],
[](auto acc, const auto curr) { return acc += "+" + curr; }));
return res; return res;
} }
void SteamTarget::keepControllerConfig(bool keep)
{
#ifdef _WIN32
if (keep && !getFgWinHook.IsInstalled()) {
spdlog::debug("Hooking GetForegroudnWindow (in own process)");
getFgWinHook.Install(&GetForegroundWindow, &keepForegroundWindow, subhook::HookFlags::HookFlag64BitOffset);
if (!getFgWinHook.IsInstalled()) {
spdlog::error("Couldn't install GetForegroundWindow hook!");
}
}
else if (!keep && getFgWinHook.IsInstalled()) {
spdlog::debug("Un-Hooking GetForegroudnWindow (in own process)");
getFgWinHook.Remove();
if (getFgWinHook.IsInstalled()) {
spdlog::error("Couldn't un-install GetForegroundWindow hook!");
}
}
#endif
}
void SteamTarget::overlayHotkeyWorkaround() void SteamTarget::overlayHotkeyWorkaround()
{ {
static bool pressed = false; static bool pressed = false;
if (std::all_of(overlay_hotkey_.begin(), overlay_hotkey_.end(), if (std::ranges::all_of(overlay_hotkey_,
[](const auto &key) { [](const auto &key) {
return sf::Keyboard::isKeyPressed(keymap::sfkey[key]); return sf::Keyboard::isKeyPressed(keymap::sfkey[key]);
})) { })) {
spdlog::debug("Detected overlay hotkey(s)");
pressed = true; pressed = true;
std::for_each( std::ranges::for_each(overlay_hotkey_, [this](const auto &key) {
overlay_hotkey_.begin(), overlay_hotkey_.end(), [this](const auto &key) {
#ifdef _WIN32 #ifdef _WIN32
PostMessage(target_window_handle_, WM_KEYDOWN, keymap::winkey[key], 0); PostMessage(target_window_handle_, WM_KEYDOWN, keymap::winkey[key], 0);
#else #else
#endif #endif
}); });
spdlog::debug("Sending Overlay KeyDown events..."); spdlog::debug("Sending Overlay KeyDown events...");
} else if (pressed) { }
else if (pressed) {
pressed = false; pressed = false;
std::for_each( std::ranges::for_each(overlay_hotkey_, [this](const auto &key) {
overlay_hotkey_.begin(), overlay_hotkey_.end(), [this](const auto &key) {
#ifdef _WIN32 #ifdef _WIN32
PostMessage(target_window_handle_, WM_KEYUP, keymap::winkey[key], 0); PostMessage(target_window_handle_, WM_KEYUP, keymap::winkey[key], 0);
#else #else
#endif #endif
}); });
spdlog::debug("Sending Overlay KeyUp events..."); spdlog::debug("Sending Overlay KeyUp events...");
} }
} }

@ -16,8 +16,8 @@ limitations under the License.
#pragma once #pragma once
#include "OverlayDetector.h" #include "OverlayDetector.h"
#include "TargetWindow.h"
#include "TargetWindow.h"
class SteamTarget { class SteamTarget {
public: public:
@ -29,8 +29,16 @@ class SteamTarget {
void focusWindow(WindowHandle hndl); void focusWindow(WindowHandle hndl);
std::wstring getSteamPath(); std::wstring getSteamPath();
std::wstring getSteamUserId(); std::wstring getSteamUserId();
std::wstring steam_path_ = getSteamPath();
std::wstring steam_user_id_ = getSteamUserId();
std::vector<std::string> getOverlayHotkey(); std::vector<std::string> getOverlayHotkey();
std::vector<std::string> getScreenshotHotkey();
// Keep controllerConfig even is window is switched.
// On Windoze hooking "GetForeGroundWindow" is enough;
void keepControllerConfig(bool keep);
/* /*
* Run once per frame * Run once per frame
* detects steam configured overlay hotkey, and simulates key presses to window * detects steam configured overlay hotkey, and simulates key presses to window
@ -49,5 +57,6 @@ class SteamTarget {
static constexpr std::wstring_view user_data_path_ = L"/userdata/"; static constexpr std::wstring_view user_data_path_ = L"/userdata/";
static constexpr std::wstring_view config_file_name_ = L"/config/localconfig.vdf"; static constexpr std::wstring_view config_file_name_ = L"/config/localconfig.vdf";
static constexpr std::string_view hotkey_name_ = "InGameOverlayShortcutKey "; static constexpr std::string_view overlay_hotkey_name_ = "InGameOverlayShortcutKey ";
static constexpr std::string_view screenshot_hotkey_name_ = "InGameOverlayScreenshotHotKey ";
}; };

@ -15,20 +15,24 @@ limitations under the License.
*/ */
#include "TargetWindow.h" #include "TargetWindow.h"
#include "steam_sf_keymap.h"
#include <iostream> #include <iostream>
#include <utility> #include <utility>
#include <SFML/Window/Event.hpp> #include <SFML/Window/Event.hpp>
#include <spdlog/spdlog.h>
#ifdef _WIN32 #ifdef _WIN32
#include <SFML/Graphics.hpp>
#include <Windows.h> #include <Windows.h>
#include <dwmapi.h> #include <dwmapi.h>
#endif #endif
static const bool DEV_MODE = false; static const bool DEV_MODE = false;
TargetWindow::TargetWindow(std::function<void()> on_close) TargetWindow::TargetWindow(std::function<void()> on_close, std::vector<std::string> screenshot_hotkey)
: on_close_(std::move(on_close)) : on_close_(std::move(on_close)), screenshot_keys_(std::move(screenshot_hotkey))
{ {
if (DEV_MODE) { if (DEV_MODE) {
window_.create(sf::VideoMode{1920, 1080}, "GlosSITarget", sf::Style::Default); window_.create(sf::VideoMode{1920, 1080}, "GlosSITarget", sf::Style::Default);
@ -82,6 +86,7 @@ void TargetWindow::update()
on_close_(); on_close_();
} }
} }
if (DEV_MODE) { if (DEV_MODE) {
window_.clear(sf::Color(0, 0, 0, 128)); window_.clear(sf::Color(0, 0, 0, 128));
} }
@ -89,6 +94,7 @@ void TargetWindow::update()
window_.clear(sf::Color::Transparent); window_.clear(sf::Color::Transparent);
} }
screenShotWorkaround();
window_.display(); window_.display();
} }
@ -98,6 +104,79 @@ void TargetWindow::close()
on_close_(); on_close_();
} }
void TargetWindow::screenShotWorkaround()
{
#ifdef _WIN32
if (std::ranges::all_of(screenshot_keys_,
[](const auto &key) {
return sf::Keyboard::isKeyPressed(keymap::sfkey[key]);
})) {
spdlog::debug("Detected screenshot hotkey(s); Taking screenshot");
// stolen from: https://en.sfml-dev.org/forums/index.php?topic=14323.15
// no time to do this shit.
HDC hScreenDC = GetDC(nullptr);
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
int width = GetDeviceCaps(hScreenDC, HORZRES);
int height = GetDeviceCaps(hScreenDC, VERTRES);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);
auto hOldBitmap = static_cast<HBITMAP>(SelectObject(hMemoryDC, hBitmap));
BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);
hBitmap = static_cast<HBITMAP>(SelectObject(hMemoryDC, hOldBitmap));
BITMAP bm;
GetObject(hBitmap, sizeof(bm), &bm);
BITMAPINFO bmpInfo;
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = bm.bmWidth;
bmpInfo.bmiHeader.biHeight = -bm.bmHeight;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 32;
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biSizeImage = 0;
bmpInfo.bmiHeader.biClrImportant = 0;
std::vector<COLORREF> pixel;
pixel.resize(bm.bmWidth * bm.bmHeight);
sf::Image captureImage;
captureImage.create(bm.bmWidth, bm.bmHeight, sf::Color::Black);
GetDIBits(hMemoryDC, hBitmap, 0, bm.bmHeight, pixel.data(), &bmpInfo, DIB_RGB_COLORS);
unsigned int j = 0;
for (unsigned int y = 0; y < bm.bmHeight; ++y) {
for (unsigned int x = 0; x < bm.bmWidth; ++x) {
const COLORREF this_color = pixel[j++];
captureImage.setPixel(x, y, sf::Color(GetBValue(this_color), GetGValue(this_color), GetRValue(this_color)));
}
}
ReleaseDC(NULL, hScreenDC);
DeleteObject(hBitmap);
DeleteDC(hMemoryDC);
DeleteDC(hScreenDC);
sf::Sprite sprite;
sf::Texture texture;
texture.loadFromImage(captureImage);
sprite.setTexture(texture);
spdlog::debug("Sending screenshot key events and rendering screen...");
std::ranges::for_each(screenshot_keys_, [this](const auto &key) {
PostMessage(window_.getSystemHandle(), WM_KEYDOWN, keymap::winkey[key], 0);
});
std::ranges::for_each(screenshot_keys_, [this](const auto &key) {
PostMessage(window_.getSystemHandle(), WM_KEYUP, keymap::winkey[key], 0);
});
//actually run event loop, so steam gets notified about keys.
sf::Event event{};
while (window_.pollEvent(event)) {
}
// steam takes screenshot on next frame, so render our screenshot and dipslay...
window_.clear(sf::Color::Black);
window_.draw(sprite);
window_.display();
// finally, draw another transparent frame.
window_.clear(sf::Color::Transparent);
}
#endif
}
WindowHandle TargetWindow::getSystemHandle() const WindowHandle TargetWindow::getSystemHandle() const
{ {
return window_.getSystemHandle(); return window_.getSystemHandle();

@ -29,17 +29,32 @@ using WindowHandle = int; // ???
class TargetWindow { class TargetWindow {
public: public:
explicit TargetWindow(std::function<void()> on_close = []() {}); explicit TargetWindow(
std::function<void()> on_close = []() {}, std::vector<std::string> screenshot_hotkey = {"KEY_F12"});
void setFpsLimit(unsigned int fps_limit); void setFpsLimit(unsigned int fps_limit);
void setClickThrough(bool click_through); void setClickThrough(bool click_through);
void update(); void update();
void close(); void close();
/*
* Run once per frame
* - detects steam configured screenshot hotkey
* - takes actual screenshot
* - renders it to window
* - simulates screenshot keys
* - Wait a few millis...
* (- steam takes screenshot)
* - return to normal
*
*/
void screenShotWorkaround();
WindowHandle getSystemHandle() const; WindowHandle getSystemHandle() const;
private: private:
const std::function<void()> on_close_; const std::function<void()> on_close_;
sf::RenderWindow window_; sf::RenderWindow window_;
std::vector<std::string> screenshot_keys_;
}; };

@ -24,19 +24,21 @@ limitations under the License.
#include <spdlog/sinks/stdout_color_sinks.h> #include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
//int CALLBACK WinMain( #define CONSOLE
// _In_ HINSTANCE hInstance, #ifdef _WIN32
// _In_ HINSTANCE hPrevInstance, #ifdef CONSOLE
// _In_ LPSTR lpCmdLine, int main(int argc, char *argv[])
// _In_ int nCmdShow #else
//) int CALLBACK WinMain(
//{ _In_ HINSTANCE hInstance,
// SteamTarget target(__argc, __argv); _In_ HINSTANCE hPrevInstance,
// target.init(); _In_ LPSTR lpCmdLine,
// return SteamTarget::exec(); _In_ int nCmdShow
//} )
#endif
#else
int main(int argc, char *argv[]) int main(int argc, char *argv[])
#endif
{ {
const auto console_sink = std::make_shared<spdlog::sinks::stderr_color_sink_mt>(); const auto console_sink = std::make_shared<spdlog::sinks::stderr_color_sink_mt>();
console_sink->set_level(spdlog::level::trace); console_sink->set_level(spdlog::level::trace);
@ -51,8 +53,11 @@ int main(int argc, char *argv[])
logger->set_level(spdlog::level::trace); logger->set_level(spdlog::level::trace);
logger->flush_on(spdlog::level::info); logger->flush_on(spdlog::level::info);
spdlog::set_default_logger(logger); spdlog::set_default_logger(logger);
#ifdef _WIN32
SteamTarget target(__argc, __argv);
#else
SteamTarget target(argc, argv); SteamTarget target(argc, argv);
#endif
const auto exit = target.run(); const auto exit = target.run();
spdlog::shutdown(); spdlog::shutdown();
return exit; return exit;

@ -5,11 +5,13 @@
#define QQ(x) #x #define QQ(x) #x
#define QUOTE(x) QQ(x) #define QUOTE(x) QQ(x)
#define KEYCONVSF(KEY) \ #define KEYCONVSF(KEY) \
{ QUOTE(KEY), sf::Keyboard::Key::KEY } { \
QUOTE(KEY), sf::Keyboard::Key::KEY \
}
namespace keymap { namespace keymap {
std::unordered_map<std::string, sf::Keyboard::Key> sfkey = { static std::unordered_map<std::string, sf::Keyboard::Key> sfkey = {
{"Shift", sf::Keyboard::Key::LShift}, {"Shift", sf::Keyboard::Key::LShift},
{"Alt", sf::Keyboard::Key::LAlt}, {"Alt", sf::Keyboard::Key::LAlt},
{"Ctrl", sf::Keyboard::Key::LControl}, {"Ctrl", sf::Keyboard::Key::LControl},
@ -56,20 +58,31 @@ std::unordered_map<std::string, sf::Keyboard::Key> sfkey = {
KEYCONVSF(W), KEYCONVSF(W),
KEYCONVSF(X), KEYCONVSF(X),
KEYCONVSF(Y), KEYCONVSF(Y),
KEYCONVSF(Z) KEYCONVSF(Z),
}; {"KEY_F1", sf::Keyboard::Key::F1},
{"KEY_F2", sf::Keyboard::Key::F2},
{"KEY_F3", sf::Keyboard::Key::F3},
{"KEY_F4", sf::Keyboard::Key::F4},
{"KEY_F5", sf::Keyboard::Key::F5},
{"KEY_F6", sf::Keyboard::Key::F6},
{"KEY_F7", sf::Keyboard::Key::F7},
{"KEY_F8", sf::Keyboard::Key::F8},
{"KEY_F9", sf::Keyboard::Key::F9},
{"KEY_F10", sf::Keyboard::Key::F10},
{"KEY_F11", sf::Keyboard::Key::F11},
{"KEY_F12", sf::Keyboard::Key::F12}};
#ifdef _WIN32 #ifdef _WIN32
#define NOMINMAX #define NOMINMAX
#include <Windows.h> #include <Windows.h>
//yep.. there are smarter ways to tho this... //yep.. there are smarter ways to tho this...
std::unordered_map<std::string, uint8_t> winkey = { static std::unordered_map<std::string, uint8_t> winkey = {
{"Shift", VK_SHIFT}, {"Shift", VK_SHIFT},
{"Alt", VK_MENU}, {"Alt", VK_MENU},
{"Ctrl", VK_CONTROL}, {"Ctrl", VK_CONTROL},
{"Del", VK_DELETE}, {"Del", VK_DELETE},
{"Ins",VK_INSERT}, {"Ins", VK_INSERT},
{"Home",VK_HOME}, {"Home", VK_HOME},
{"Space", VK_SPACE}, {"Space", VK_SPACE},
{"Backspace", VK_BACK}, {"Backspace", VK_BACK},
{"Enter", VK_RETURN}, {"Enter", VK_RETURN},
@ -110,8 +123,18 @@ std::unordered_map<std::string, uint8_t> winkey = {
{"KEY_W", 0x57}, {"KEY_W", 0x57},
{"KEY_X", 0x58}, {"KEY_X", 0x58},
{"KEY_Y", 0x59}, {"KEY_Y", 0x59},
{"KEY_Z", 0x5A} {"KEY_Z", 0x5A},
{"KEY_F1", VK_F1},
}; {"KEY_F2", VK_F2},
{"KEY_F3", VK_F3},
{"KEY_F4", VK_F4},
{"KEY_F5", VK_F5},
{"KEY_F6", VK_F6},
{"KEY_F7", VK_F7},
{"KEY_F8", VK_F8},
{"KEY_F9", VK_F9},
{"KEY_F10", VK_F10},
{"KEY_F11", VK_F11},
{"KEY_F12", VK_F12}};
#endif #endif
} } // namespace keymap

Loading…
Cancel
Save