diff --git a/GlosSITarget/GlosSITarget.vcxproj b/GlosSITarget/GlosSITarget.vcxproj
index e8a420f..ff5cb3a 100644
--- a/GlosSITarget/GlosSITarget.vcxproj
+++ b/GlosSITarget/GlosSITarget.vcxproj
@@ -153,6 +153,7 @@
+
diff --git a/GlosSITarget/GlosSITarget.vcxproj.filters b/GlosSITarget/GlosSITarget.vcxproj.filters
index 6a20838..958a665 100644
--- a/GlosSITarget/GlosSITarget.vcxproj.filters
+++ b/GlosSITarget/GlosSITarget.vcxproj.filters
@@ -72,6 +72,9 @@
Source Files\imgui-sfml
+
+ Source Files\imgui
+
diff --git a/GlosSITarget/HidHide.cpp b/GlosSITarget/HidHide.cpp
index e012593..1791e07 100644
--- a/GlosSITarget/HidHide.cpp
+++ b/GlosSITarget/HidHide.cpp
@@ -30,6 +30,8 @@ limitations under the License.
#include
//
+#include "Overlay.h"
+
#include
#include
#include
@@ -90,7 +92,7 @@ void HidHide::hideDevices(const std::filesystem::path& steam_path)
auto path = std::regex_replace(steam_path_string, std::wregex(L"(.:)(\\/|\\\\)"), dos_device + L"\\");
path = std::regex_replace(path, std::wregex(L"\\/"), L"\\") + L"\\" + std::wstring{exe};
if (std::ranges::none_of(whitelist, [&path](auto ep) { // make copy!
- auto p = path; // non-const(!) copy of path
+ auto p = path; // non-const(!) copy of path
std::ranges::transform(path, p.begin(), tolower);
std::ranges::transform(ep, ep.begin(), tolower);
return p == ep;
@@ -100,25 +102,26 @@ void HidHide::hideDevices(const std::filesystem::path& steam_path)
}
setAppWhiteList(whitelist);
- const auto device_list = GetHidDeviceList();
- auto blacklist = getBlackListDevices();
+ avail_devices_ = GetHidDeviceList();
+ blacklisted_devices_ = getBlackListDevices();
- for (const auto& dev : device_list) {
- if (std::ranges::none_of(blacklist, [&dev](const auto& blackdev) {
+ for (const auto& dev : avail_devices_) {
+ if (std::ranges::none_of(blacklisted_devices_, [&dev](const auto& blackdev) {
return blackdev == dev.device_instance_path || blackdev == dev.base_container_device_instance_path;
- })) {
+ })) {
if (!dev.device_instance_path.empty()) {
- blacklist.push_back(dev.device_instance_path);
+ blacklisted_devices_.push_back(dev.device_instance_path);
}
if (!dev.device_instance_path.empty()) {
- blacklist.push_back(dev.base_container_device_instance_path);
+ blacklisted_devices_.push_back(dev.base_container_device_instance_path);
}
}
}
- setBlacklistDevices(blacklist);
+ setBlacklistDevices(blacklisted_devices_);
setActive(true);
closeCtrlDevice();
- spdlog::info("Hid Gaming Devices"); // TODO: add list of blacklisted devices
+ spdlog::info("Hid Gaming Devices; Enabling Overlay element...");
+ enableOverlayElement();
}
void HidHide::disableHidHide()
@@ -126,7 +129,62 @@ void HidHide::disableHidHide()
openCtrlDevice();
setActive(false);
closeCtrlDevice();
- spdlog::info("Un-hid Gaming Devices"); // TODO: add list of blacklisted devices
+ spdlog::info("Un-hid Gaming Devices");
+}
+
+void HidHide::enableOverlayElement()
+{
+ Overlay::AddOverlayElem([this]() {
+ if (overlay_elem_clock_.getElapsedTime().asSeconds() > OVERLAY_ELEM_REFRESH_INTERVAL_S_) {
+ openCtrlDevice();
+ bool hidehide_state_store = hidhide_active_;
+ if (hidhide_active_) {
+ setActive(false);
+ }
+ avail_devices_ = GetHidDeviceList();
+ blacklisted_devices_ = getBlackListDevices();
+ if (hidehide_state_store) {
+ setActive(true);
+ }
+ closeCtrlDevice();
+ overlay_elem_clock_.restart();
+ }
+ ImGui::Begin("Hidden Devices");
+ ImGui::BeginChild("Inner", {0.f, ImGui::GetItemRectSize().y - 48}, true);
+ std::ranges::for_each(avail_devices_, [this](const auto& device) {
+ std::string label = (std::string(device.name.begin(), std::ranges::find(device.name, L'\0')) + "##" + std::string(device.device_instance_path.begin(), device.device_instance_path.end()));
+ const auto findDeviceFn = [&device](const auto& blackdev) {
+ return device.device_instance_path == blackdev || device.base_container_device_instance_path == blackdev;
+ };
+ bool hidden = std::ranges::find_if(blacklisted_devices_, findDeviceFn) != blacklisted_devices_.end();
+ if (ImGui::Checkbox(label.data(), &hidden)) {
+ openCtrlDevice();
+ if (hidden) {
+ if (std::ranges::none_of(blacklisted_devices_, findDeviceFn)) {
+ if (!device.device_instance_path.empty()) {
+ blacklisted_devices_.push_back(device.device_instance_path);
+ }
+ if (!device.device_instance_path.empty()) {
+ blacklisted_devices_.push_back(device.base_container_device_instance_path);
+ }
+ }
+ }
+ else {
+ blacklisted_devices_.erase(std::ranges::remove_if(blacklisted_devices_, findDeviceFn).begin(),
+ blacklisted_devices_.end());
+ }
+ setBlacklistDevices(blacklisted_devices_);
+ closeCtrlDevice();
+ }
+ });
+ ImGui::EndChild();
+ if (ImGui::Checkbox("Devices Hidden", &hidhide_active_)) {
+ openCtrlDevice();
+ setActive(hidhide_active_);
+ closeCtrlDevice();
+ }
+ ImGui::End();
+ });
}
std::wstring HidHide::DosDeviceForVolume(const std::wstring& volume)
@@ -166,7 +224,7 @@ std::vector HidHide::getBlackListDevices() const
return BufferToStringVec(buffer);
}
-bool HidHide::getActive() const
+bool HidHide::getActive()
{
DWORD bytes_needed;
BOOLEAN res;
@@ -175,6 +233,7 @@ bool HidHide::getActive() const
spdlog::error("Couldn't retrieve HidHide State");
return false;
}
+ hidhide_active_ = res;
return res;
}
@@ -198,13 +257,15 @@ void HidHide::setBlacklistDevices(const std::vector& blacklist) co
}
}
-void HidHide::setActive(bool active) const
+void HidHide::setActive(bool active)
{
DWORD bytes_needed;
if (!DeviceIoControl(
hidhide_handle, static_cast(IOCTL_TYPE::SET_ACTIVE), &active, sizeof(BOOLEAN), nullptr, 0, &bytes_needed, nullptr)) {
spdlog::error("Couldn't set HidHide State");
+ return;
}
+ hidhide_active_ = active;
}
DWORD HidHide::getRequiredOutputBufferSize(IOCTL_TYPE type) const
@@ -352,6 +413,10 @@ HidHide::SmallHidInfo HidHide::GetDeviceInfo(const DeviceInstancePath& instance_
res.name = (HidD_GetProductString(device_object.get(), buffer.data(), static_cast(sizeof(WCHAR) * buffer.size()))
? buffer
: L"");
+ // Valve emulated gamepad PID/VID; mirrord by ViGEm
+ if (attributes.VendorID == 0x28de && attributes.ProductID == 0x11FF) {
+ res.name = std::wstring(L"ViGEm Emulated: ") + res.name;
+ }
res.base_container_device_instance_path = BaseContainerDeviceInstancePath(instance_path);
res.gaming_device = IsGamingDevice(attributes, capabilities);
diff --git a/GlosSITarget/HidHide.h b/GlosSITarget/HidHide.h
index bd46a65..ee90d5a 100644
--- a/GlosSITarget/HidHide.h
+++ b/GlosSITarget/HidHide.h
@@ -24,6 +24,7 @@ limitations under the License.
#include
#include
#include
+#include
class HidHide {
private:
@@ -65,6 +66,14 @@ class HidHide {
private:
HANDLE hidhide_handle = nullptr;
+ void enableOverlayElement();
+ sf::Clock overlay_elem_clock_;
+
+ std::vector blacklisted_devices_;
+ std::vector avail_devices_;
+ bool hidhide_active_ = false;
+ static constexpr int OVERLAY_ELEM_REFRESH_INTERVAL_S_ = 5;
+
static inline constexpr std::array whitelist_executeables_{
L"GameOverlayUI.exe",
L"steam.exe",
@@ -74,10 +83,10 @@ class HidHide {
[[nodiscard]] std::vector getAppWhiteList() const;
[[nodiscard]] std::vector getBlackListDevices() const;
- [[nodiscard]] bool getActive() const;
+ [[nodiscard]] bool getActive();
void setAppWhiteList(const std::vector& whitelist) const;
void setBlacklistDevices(const std::vector& blacklist) const;
- void setActive(bool active) const;
+ void setActive(bool active);
[[nodiscard]] DWORD getRequiredOutputBufferSize(IOCTL_TYPE type) const;
diff --git a/GlosSITarget/Overlay.cpp b/GlosSITarget/Overlay.cpp
index 8a1558a..a35c03c 100644
--- a/GlosSITarget/Overlay.cpp
+++ b/GlosSITarget/Overlay.cpp
@@ -1,11 +1,5 @@
#include "Overlay.h"
-#include
-
-#define IMGUI_USER_CONFIG "imconfig.h"
-#include "imgui-SFML.h"
-#include "imgui.h"
-
Overlay::Overlay(sf::RenderWindow& window, const std::function& on_close) : window_(window), on_close_(on_close)
{
ImGui::SFML::Init(window_);
@@ -24,14 +18,14 @@ Overlay::Overlay(sf::RenderWindow& window, const std::function& on_close
style.ScrollbarRounding = 12;
style.GrabRounding = 5;
- ImVec4* colors = ImGui::GetStyle().Colors;
+ImVec4* colors = ImGui::GetStyle().Colors;
colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.36f, 0.42f, 0.47f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.10f, 0.13f, 0.14f, 0.95f);
colors[ImGuiCol_ChildBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f);
- colors[ImGuiCol_Border] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f);
- colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
+ colors[ImGuiCol_Border] = ImVec4(0.08f, 0.10f, 0.12f, 0.05f);
+ colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f);
colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.12f, 0.20f, 0.28f, 1.00f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.09f, 0.12f, 0.14f, 1.00f);
@@ -108,6 +102,8 @@ void Overlay::update()
std::ranges::for_each(OVERLAY_ELEMS_, [](const auto& fn) { fn(); });
+ ImGui::ShowDemoWindow();
+
if (closeButton()) {
return;
}
diff --git a/GlosSITarget/Overlay.h b/GlosSITarget/Overlay.h
index 44778e2..33127ae 100644
--- a/GlosSITarget/Overlay.h
+++ b/GlosSITarget/Overlay.h
@@ -5,6 +5,10 @@
#include
+#define IMGUI_USER_CONFIG "imconfig.h"
+#include "imgui-SFML.h"
+#include "imgui.h"
+
class Overlay {
public:
Overlay(sf::RenderWindow& window, const std::function& on_close);
diff --git a/GlosSITarget/SteamTarget.cpp b/GlosSITarget/SteamTarget.cpp
index 858f344..efeb833 100644
--- a/GlosSITarget/SteamTarget.cpp
+++ b/GlosSITarget/SteamTarget.cpp
@@ -27,8 +27,8 @@ limitations under the License.
SteamTarget::SteamTarget(int argc, char* argv[])
: window_([this] { run_ = false; }, getScreenshotHotkey()),
- detector_([this](bool overlay_open) { onOverlayChanged(overlay_open); }),
- overlay_(window_.getOverlay())
+ overlay_(window_.getOverlay()),
+ detector_([this](bool overlay_open) { onOverlayChanged(overlay_open); })
{
target_window_handle_ = window_.getSystemHandle();
}
@@ -40,18 +40,20 @@ int SteamTarget::run()
Application will not function!");
window_.setClickThrough(false);
overlay_.setEnabled(true);
+ steam_overlay_present_ = false;
} 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);
+ steam_overlay_present_ = true;
}
run_ = true;
#ifdef _WIN32
hidhide_.hideDevices(steam_path_);
- input_redirector_.run();
+ input_redirector_.run();
#endif
keepControllerConfig(true);
diff --git a/GlosSITarget/SteamTarget.h b/GlosSITarget/SteamTarget.h
index bfd6014..8580a38 100644
--- a/GlosSITarget/SteamTarget.h
+++ b/GlosSITarget/SteamTarget.h
@@ -46,6 +46,8 @@ class SteamTarget {
std::vector getOverlayHotkey();
std::vector getScreenshotHotkey();
+ bool steam_overlay_present_ = false;
+
// Keep controllerConfig even is window is switched.
// On Windoze hooking "GetForeGroundWindow" is enough;
void keepControllerConfig(bool keep);