diff --git a/GlosSITarget/GlosSITarget.vcxproj b/GlosSITarget/GlosSITarget.vcxproj
index 1b6fbec..e8a420f 100644
--- a/GlosSITarget/GlosSITarget.vcxproj
+++ b/GlosSITarget/GlosSITarget.vcxproj
@@ -127,7 +127,7 @@
stdcpp20
- Console
+ Windows
true
hid.lib;Cfgmgr32.lib;opengl32.lib;sfml-window-d.lib;sfml-system-d.lib;sfml-graphics-d.lib;dwmapi.lib;xinput9_1_0.lib;setupapi.lib;ViGEmClient.lib;%(AdditionalDependencies)
@@ -143,7 +143,7 @@
stdcpp20
- Console
+ Windows
true
true
true
@@ -153,7 +153,6 @@
-
@@ -174,6 +173,7 @@
+
diff --git a/GlosSITarget/GlosSITarget.vcxproj.filters b/GlosSITarget/GlosSITarget.vcxproj.filters
index f0ce82a..6a20838 100644
--- a/GlosSITarget/GlosSITarget.vcxproj.filters
+++ b/GlosSITarget/GlosSITarget.vcxproj.filters
@@ -72,9 +72,6 @@
Source Files\imgui-sfml
-
- Source Files\imgui
-
@@ -110,6 +107,9 @@
Header Files\imgui-sfml
+
+ Header Files
+
diff --git a/GlosSITarget/InputRedirector.cpp b/GlosSITarget/InputRedirector.cpp
index 0dc339a..179effe 100644
--- a/GlosSITarget/InputRedirector.cpp
+++ b/GlosSITarget/InputRedirector.cpp
@@ -53,6 +53,7 @@ void InputRedirector::run()
void InputRedirector::stop()
{
run_ = false;
+ controller_thread_.join();
if (vigem_connected_) {
for (const auto& target : vt_x360_) {
vigem_target_remove(driver_, target);
diff --git a/GlosSITarget/Overlay.cpp b/GlosSITarget/Overlay.cpp
index 62a24fa..4f8127c 100644
--- a/GlosSITarget/Overlay.cpp
+++ b/GlosSITarget/Overlay.cpp
@@ -1,9 +1,8 @@
#include "Overlay.h"
#define IMGUI_USER_CONFIG "imconfig.h"
-#include "imgui.h"
#include "imgui-SFML.h"
-
+#include "imgui.h"
Overlay::Overlay(sf::RenderWindow& window, std::function on_close) : window_(window), on_close_(on_close)
{
@@ -84,6 +83,12 @@ void Overlay::setEnabled(bool enabled)
enabled_ = enabled;
}
+bool Overlay::isEnabled() const
+{
+ return enabled_;
+}
+
+
bool Overlay::toggle()
{
enabled_ = !enabled_;
@@ -94,14 +99,16 @@ void Overlay::update()
{
ImGui::SFML::Update(window_, update_clock_.restart());
- bool open = true;
+ showLogs();
+
if (enabled_) {
window_.clear(sf::Color(0, 0, 0, 64)); // make window slightly dim screen with overlay
- ImGui::ShowDemoWindow(&open);
+
+
if (closeButton()) {
return;
- }
+ }
}
ImGui::SFML::Render(window_);
@@ -117,15 +124,61 @@ void Overlay::Shutdown()
ImGui::SFML::Shutdown();
}
-void Overlay::ShowNotification(std::string noti_text)
-{}
+void Overlay::ShowNotification(const spdlog::details::log_msg& msg)
+{
+ LOG_MSGS_.push_back({.time = msg.time, .level = msg.level, .payload = msg.payload.data()});
+}
+
+void Overlay::showLogs() const
+{
+ std::vector logs;
+ if (enabled_) {
+ logs = LOG_MSGS_;
+ }
+ else {
+ std::ranges::copy_if(LOG_MSGS_,
+ std::back_inserter(logs),
+ [](const auto& log) {
+ return log.time.time_since_epoch() + std::chrono::seconds(LOG_RETENTION_TIME_) > std::chrono::system_clock::now().time_since_epoch();
+ });
+ }
+ if (logs.empty())
+ return;
+ if (!enabled_) {
+ ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, {32.f, 32.f});
+ ImGui::Begin("Log", nullptr,
+ ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar);
+ }
+ else {
+ ImGui::Begin("Log", nullptr);
+ }
+ std::ranges::for_each(LOG_MSGS_, [](const auto& msg) {
+ switch (msg.level) {
+ case spdlog::level::warn:
+ ImGui::TextColored({1.f, 0.8f, 0.f, 1.f}, msg.payload.data());
+ break;
+ case spdlog::level::err:
+ ImGui::TextColored({.8f, 0.0f, 0.f, 1.f}, msg.payload.data());
+ break;
+ case spdlog::level::debug:
+ ImGui::TextColored({.8f, 0.8f, 0.8f, .9f}, msg.payload.data());
+ break;
+ default:
+ ImGui::Text(msg.payload.data());
+ }
+ });
+ ImGui::End();
+ if (!enabled_) {
+ ImGui::PopStyleVar();
+ }
+}
bool Overlay::closeButton() const
{
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, {0, 0});
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.f, 0.f, 0.0f));
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.6f, 0.f, 0.f, 0.9f));
- ImGui::PushStyleColor(ImGuiCol_ButtonHovered,ImVec4(1.f, 0.16f, 0.16f, 1.00f));
+ ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.f, 0.16f, 0.16f, 1.00f));
ImGui::Begin("##CloseButton", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize);
ImGui::SetWindowSize({56 + 24, 32 + 24});
ImGui::SetWindowPos({window_.getSize().x - ImGui::GetWindowWidth() + 24, -24});
diff --git a/GlosSITarget/Overlay.h b/GlosSITarget/Overlay.h
index f8237ba..788f66c 100644
--- a/GlosSITarget/Overlay.h
+++ b/GlosSITarget/Overlay.h
@@ -3,21 +3,34 @@
#include
#include
+#include
+
class Overlay {
public:
Overlay(sf::RenderWindow& window, std::function on_close);
void setEnabled(bool enabled);
+ bool isEnabled() const;
bool toggle();
void update();
static void ProcessEvent(sf::Event evnt);
static void Shutdown();
- static void ShowNotification(std::string noti_text);
+ static void ShowNotification(const spdlog::details::log_msg& msg);
private:
sf::RenderWindow& window_;
sf::Clock update_clock_;
bool enabled_ = true;
std::function on_close_;
+ void showLogs() const;
bool closeButton() const;
+
+ struct Log {
+ std::chrono::system_clock::time_point time;
+ spdlog::level::level_enum level;
+ std::string payload;
+ };
+ static inline std::vector LOG_MSGS_;
+ static constexpr int LOG_RETENTION_TIME_ = 5;
+
};
diff --git a/GlosSITarget/OverlayLogSink.h b/GlosSITarget/OverlayLogSink.h
new file mode 100644
index 0000000..48c876d
--- /dev/null
+++ b/GlosSITarget/OverlayLogSink.h
@@ -0,0 +1,40 @@
+#pragma once
+
+
+#include "Overlay.h"
+
+namespace spdlog {
+namespace sinks {
+
+template
+class overlay_sink : public spdlog::sinks::base_sink {
+ public:
+ overlay_sink() = default;
+
+ protected:
+ void sink_it_(const spdlog::details::log_msg& msg) override
+ {
+ Overlay::ShowNotification(msg);
+ }
+
+ void flush_() override
+ {
+ // Do nothing because statement executed in sink_it_().
+ }
+
+ void set_pattern_(const std::string& pattern) override
+ {
+ // Don't format log message.
+ }
+
+ void set_formatter_(std::unique_ptr sink_formatter) override
+ {
+ // Don't format log message.
+ }
+
+};
+
+using overlay_sink_mt = overlay_sink;
+
+} // namespace sinks
+} // namespace spdlog
\ No newline at end of file
diff --git a/GlosSITarget/SteamOverlayDetector.cpp b/GlosSITarget/SteamOverlayDetector.cpp
index 336f6d1..f25acce 100644
--- a/GlosSITarget/SteamOverlayDetector.cpp
+++ b/GlosSITarget/SteamOverlayDetector.cpp
@@ -67,4 +67,11 @@ void SteamOverlayDetector::update()
}
}
#endif
-}
\ No newline at end of file
+}
+
+bool SteamOverlayDetector::IsSteamInjected()
+{
+#ifdef _WIN32
+ return GetModuleHandle(L"GameOverlayRenderer64.dll") != nullptr;
+#endif
+}
diff --git a/GlosSITarget/SteamOverlayDetector.h b/GlosSITarget/SteamOverlayDetector.h
index ff60e6c..74b305a 100644
--- a/GlosSITarget/SteamOverlayDetector.h
+++ b/GlosSITarget/SteamOverlayDetector.h
@@ -27,6 +27,7 @@ class SteamOverlayDetector {
explicit SteamOverlayDetector(
std::function overlay_changed = [](bool) {});
void update();
+ static bool IsSteamInjected();
private:
std::function overlay_changed_;
diff --git a/GlosSITarget/SteamTarget.cpp b/GlosSITarget/SteamTarget.cpp
index 9af15c9..858f344 100644
--- a/GlosSITarget/SteamTarget.cpp
+++ b/GlosSITarget/SteamTarget.cpp
@@ -35,12 +35,16 @@ SteamTarget::SteamTarget(int argc, char* argv[])
int SteamTarget::run()
{
- // TODO: Hide GlosSI overlay not based on time, but on game launch.
- sf::Clock mock_clock;
- bool mock_clock_flag = SteamOverlayDetector::IsSteamInjected();
- if (!mock_clock_flag) {
- spdlog::warn("Steam Overlay not detected. Keeping GlosSI Overlay!\n\
+ if (!SteamOverlayDetector::IsSteamInjected()) {
+ spdlog::warn("Steam-overlay not detected. Showing GlosSI-overlay!\n\
Application will not function!");
+ window_.setClickThrough(false);
+ overlay_.setEnabled(true);
+ } else {
+ spdlog::info("Steam-overlay detected.");
+ spdlog::warn("Open/Close Steam-overlay twice to show GlosSI-overlay"); // Just to color output and really get users attention
+ window_.setClickThrough(true);
+ overlay_.setEnabled(false);
}
run_ = true;
@@ -52,11 +56,6 @@ Application will not function!");
keepControllerConfig(true);
while (run_) {
- if (mock_clock_flag && mock_clock.getElapsedTime().asSeconds() > 5) {
- window_.setClickThrough(true);
- overlay_.setEnabled(false);
- mock_clock_flag = false;
- }
detector_.update();
window_.update();
overlayHotkeyWorkaround();
@@ -72,7 +71,6 @@ Application will not function!");
void SteamTarget::onOverlayChanged(bool overlay_open)
{
- window_.setClickThrough(!overlay_open);
if (overlay_open) {
focusWindow(target_window_handle_);
}
@@ -84,12 +82,22 @@ void SteamTarget::onOverlayChanged(bool overlay_open)
}
else {
if (overlay_trigger_clock_.getElapsedTime().asSeconds() <= overlay_trigger_max_seconds_) {
- window_.setClickThrough(!overlay_.toggle());
+ const auto ov_opened = overlay_.toggle();
+ window_.setClickThrough(!ov_opened);
+ if (ov_opened) {
+ spdlog::info("Opened GlosSI-overlay");
+ focusWindow(target_window_handle_);
+ } else {
+ focusWindow(last_foreground_window_);
+ spdlog::info("Closed GlosSI-overlay");
+ }
}
overlay_trigger_flag_ = false;
}
-
- focusWindow(last_foreground_window_);
+ if (!overlay_.isEnabled()) {
+ window_.setClickThrough(!overlay_open);
+ focusWindow(last_foreground_window_);
+ }
}
}
@@ -98,19 +106,23 @@ void SteamTarget::focusWindow(WindowHandle hndl)
#ifdef _WIN32
if (hndl == target_window_handle_) {
- spdlog::info("Bring own window to foreground");
+ spdlog::debug("Bring own window to foreground");
}
else {
- spdlog::info("Bring window \"{:#x}\" to foreground", reinterpret_cast(hndl));
+ spdlog::debug("Bring window \"{:#x}\" to foreground", reinterpret_cast(hndl));
}
keepControllerConfig(false); // unhook GetForegroundWindow
- last_foreground_window_ = GetForegroundWindow();
- const DWORD fg_thread = GetWindowThreadProcessId(last_foreground_window_, nullptr);
+ const auto current_fgw = GetForegroundWindow();
+ if (current_fgw != target_window_handle_) {
+ last_foreground_window_ = current_fgw;
+ }
+ const auto fg_thread = GetWindowThreadProcessId(current_fgw, nullptr);
+
keepControllerConfig(true); // re-hook GetForegroundWindow
// lot's of ways actually bringing our window to foreground...
- const DWORD current_thread = GetCurrentThreadId();
+ const auto current_thread = GetCurrentThreadId();
AttachThreadInput(current_thread, fg_thread, TRUE);
SetForegroundWindow(hndl);
@@ -231,14 +243,14 @@ void SteamTarget::keepControllerConfig(bool keep)
{
#ifdef _WIN32
if (keep && !getFgWinHook.IsInstalled()) {
- spdlog::debug("Hooking GetForegroudnWindow (in own process)");
+ spdlog::debug("Hooking GetForegroundWindow (in own process)");
getFgWinHook.Install(&GetForegroundWindow, &keepFgWindowHookFn, 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)");
+ spdlog::debug("Un-Hooking GetForegroundWindow (in own process)");
getFgWinHook.Remove();
if (getFgWinHook.IsInstalled()) {
spdlog::error("Couldn't un-install GetForegroundWindow hook!");
@@ -261,7 +273,7 @@ void SteamTarget::overlayHotkeyWorkaround()
[](const auto& key) {
return sf::Keyboard::isKeyPressed(keymap::sfkey[key]);
})) {
- spdlog::debug("Detected overlay hotkey(s)");
+ spdlog::trace("Detected overlay hotkey(s)");
pressed = true;
std::ranges::for_each(overlay_hotkey_, [this](const auto& key) {
#ifdef _WIN32
@@ -270,7 +282,7 @@ void SteamTarget::overlayHotkeyWorkaround()
#endif
});
- spdlog::debug("Sending Overlay KeyDown events...");
+ spdlog::trace("Sending Overlay KeyDown events...");
}
else if (pressed) {
pressed = false;
@@ -281,6 +293,6 @@ void SteamTarget::overlayHotkeyWorkaround()
#endif
});
- spdlog::debug("Sending Overlay KeyUp events...");
+ spdlog::trace("Sending Overlay KeyUp events...");
}
}
diff --git a/GlosSITarget/main.cpp b/GlosSITarget/main.cpp
index 8451df8..a31d386 100644
--- a/GlosSITarget/main.cpp
+++ b/GlosSITarget/main.cpp
@@ -23,8 +23,9 @@ limitations under the License.
#include
#include
#include
+#include "OverlayLogSink.h"
+
-#define CONSOLE
#ifdef _WIN32
#ifdef CONSOLE
int main(int argc, char* argv[])
@@ -47,7 +48,15 @@ int main(int argc, char* argv[])
auto file_sink = std::make_shared("/tmp/glossitarget.log", true);
#endif
file_sink->set_level(spdlog::level::trace);
- std::vector sinks{file_sink, console_sink};
+
+ const auto overlay_sink = std::make_shared();
+#ifdef _DEBUG
+ overlay_sink->set_level(spdlog::level::debug); // TODO: make configurable
+#else
+ overlay_sink->set_level(spdlog::level::info);
+#endif
+
+ std::vector sinks{file_sink, console_sink, overlay_sink};
auto logger = std::make_shared("log", sinks.begin(), sinks.end());
logger->set_level(spdlog::level::trace);
logger->flush_on(spdlog::level::info);