diff --git a/SceneSwitcher.cpp b/SceneSwitcher.cpp new file mode 100644 index 00000000..98ce98c1 --- /dev/null +++ b/SceneSwitcher.cpp @@ -0,0 +1,66 @@ +#pragma once + +#include "stdafx.h" +#include "switcher.h" +#include + + +Switcher *switcher = new Switcher(); +using namespace std; + + +OBS_DECLARE_MODULE() + + + + +void SceneSwitcherHotkey(void *data, obs_hotkey_id id, obs_hotkey_t *hotkey, bool pressed) +{ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(hotkey); + + if (pressed) + { + + Switcher *switcher = static_cast(data); + if (switcher->getIsRunning()) + { + switcher->stop(); + } + else + { + switcher->start(); + } + } +} + +bool obs_module_load(void) +{ + //maybe do some UI stuff? + + //void obs_register_modeless_ui(const struct obs_modeless_ui *info); + obs_hotkey_register_frontend("Scene Switcher", "Toggle automatic scene switching", SceneSwitcherHotkey, switcher); + switcher->load(); + switcher->start(); + + return true; + +} + + +const char *obs_module_author(void) +{ + return "WarmUpTill"; +} + +const char *obs_module_name(void) +{ + return "Scene Switcher"; +} + +const char *obs_module_description(void) +{ + return "Automatic scene switching"; +} + + diff --git a/settings.cpp b/settings.cpp index 192165a7..4d6cd6da 100644 --- a/settings.cpp +++ b/settings.cpp @@ -15,11 +15,6 @@ using namespace std; -//possible settings: -// -//file path -//transition delay / type -//... class Settings { map settings; @@ -34,7 +29,7 @@ private : void Settings::load(string filepath) { - //read the settings file (csv like, each line is assignment of window -> scene) + //read the settings file std::vector settingsElements; int numValues = 0; ifstream infile(filepath); @@ -48,10 +43,9 @@ void Settings::load(string filepath) { while (lineStream.good()) { getline(lineStream, value, ','); settingsElements.push_back(value); + numValues++; } - - numValues++; } //create settings map containgin windowname and desired scene diff --git a/switcher.cpp b/switcher.cpp index 85cc6a1d..ef3cb3d4 100644 --- a/switcher.cpp +++ b/switcher.cpp @@ -9,26 +9,34 @@ #include #include #include +#include using namespace std; //is the thread running? see below :D -static bool isRunning = true; -string GetActiveWindowTitle(); +//static bool isRunning = true; + class Switcher { public: - map load(); + bool getIsRunning(); + void load(); + void start(); void stop(); + thread switcherThread; private: + bool isRunning = true; Settings settings; map settingsMap; + void switcherThreadFunc(); + bool isWindowFullscreen(); + string GetActiveWindowTitle(); }; //scene switching is done in here -void switcherThreadFunc(map settingsMap) { +void Switcher::switcherThreadFunc() { string windowname = ""; @@ -37,40 +45,47 @@ void switcherThreadFunc(map settingsMap) { //get active window title windowname = GetActiveWindowTitle(); - //do we know the window title? - if (!(settingsMap.find(windowname) == settingsMap.end())) { + //do we know the window title or is a fullscreen/backup Scene set? + if (!(settingsMap.find("Backup Scene Name") == settingsMap.end())||!(settingsMap.find(windowname) == settingsMap.end())){ - //check if current scene is already the desired scene - const char * name = settingsMap.find(windowname)->second.c_str(); - - //remember to release all sources - obs_source_t * transitionUsed = obs_get_output_source(0); - obs_source_t * sceneUsed = obs_transition_get_active_source(transitionUsed); - const char * sceneUsedName = obs_source_get_name(sceneUsed); - - //NOTE: transitions seem to be scenes and will be canceled unless we check if the current scene is a transition - if ((sceneUsedName) && strcmp(sceneUsedName,name) != 0) { - //switch scene - obs_source_t *source = obs_get_source_by_name(name); - if (source == NULL) - { - //warn("Source not found: \"%s\"", name); - ; - } - else if (obs_scene_from_source(source) == NULL) - { - //warn("\"%s\" is not a scene", name); - ; - } - else { - //create transition to new scene (otherwise UI wont work anymore) - //OBS_TRANSITION_MODE_AUTO uses the obs user settings for transitions - obs_transition_start(transitionUsed, OBS_TRANSITION_MODE_AUTO, 300, source); - } - obs_source_release(source); + string name = ""; + if (!(settingsMap.find(windowname) == settingsMap.end())) { + name = settingsMap.find(windowname)->second; } - obs_source_release(sceneUsed); - obs_source_release(transitionUsed); + else if (!(settingsMap.find("Fullscreen Scene Name") == settingsMap.end()) && isWindowFullscreen()) { + name = settingsMap.find("Fullscreen Scene Name")->second; + } + else if (!(settingsMap.find("Backup Scene Name") == settingsMap.end())) { + name = settingsMap.find("Backup Scene Name")->second; + } + + obs_source_t * transitionUsed = obs_get_output_source(0); + obs_source_t * sceneUsed = obs_transition_get_active_source(transitionUsed); + const char *sceneUsedName = obs_source_get_name(sceneUsed); + //check if current scene is already the desired scene + if ((sceneUsedName) && strcmp(sceneUsedName, name.c_str()) != 0) { + //switch scene + obs_source_t *source = obs_get_source_by_name(name.c_str()); + if (source == NULL) + { + //warn("Source not found: \"%s\"", name); + ; + } + else if (obs_scene_from_source(source) == NULL) + { + //warn("\"%s\" is not a scene", name); + ; + } + else { + //create transition to new scene (otherwise UI wont work anymore) + //OBS_TRANSITION_MODE_AUTO uses the obs user settings for transitions + obs_transition_start(transitionUsed, OBS_TRANSITION_MODE_AUTO, 300, source); + } + obs_source_release(source); + } + obs_source_release(sceneUsed); + obs_source_release(transitionUsed); + } //sleep for a bit this_thread::sleep_for(std::chrono::milliseconds(1000)); @@ -79,24 +94,47 @@ void switcherThreadFunc(map settingsMap) { //load the settings needed to start the thread -map Switcher::load() { - //settings file in - string settingsFilePath = "..\\..\\data\\obs-plugins\\DexterSceneSwitcher\\settings.txt"; //"..\\..\\data\\obs-plugins\\DexterSceneSwitcher\\settings.txt"; +void Switcher::load() { + string settingsFilePath = "..\\..\\data\\obs-plugins\\SceneSwitcher\\settings.txt"; settings.load(settingsFilePath); - map settingsMap = settings.getMap(); - isRunning = true; + settingsMap = settings.getMap(); string message = "The following settings were found for Scene Switcher:\n"; for (auto it = settingsMap.cbegin(); it != settingsMap.cend(); ++it) { message += (it->first) + " -> " + it->second + "\n"; } MessageBox(0, message.c_str(), "Scene Switcher", 0); - return settingsMap; - +} + +void Switcher::start() +{ + //start thread + isRunning = true; + switcherThread = thread(&Switcher::switcherThreadFunc, this); +} + +//checks if active window is in fullscreen +bool Switcher::isWindowFullscreen() { + RECT appBounds; + RECT rc; + GetWindowRect(GetDesktopWindow(), &rc); + HWND hwnd = GetForegroundWindow(); + //return (GetWindowLong(hwnd, GWL_STYLE) & WS_POPUP != 0); + //Check we haven't picked up the desktop or the shell + if (hwnd != GetDesktopWindow() || hwnd != GetShellWindow()) + { + GetWindowRect(hwnd, &appBounds); + //determine if window is fullscreen + if (rc.bottom == appBounds.bottom && rc.top == appBounds.top && rc.left == appBounds.left && rc.right == appBounds.right) + { + return true; + } + } + return false; } //reads the title of the currently active window -string GetActiveWindowTitle() +string Switcher::GetActiveWindowTitle() { char wnd_title[256]; HWND hwnd = GetForegroundWindow(); // get handle of currently active window @@ -107,5 +145,11 @@ string GetActiveWindowTitle() //tell the thread to stop void Switcher::stop() { isRunning = false; //isRunning seems to be called randomly and disables the plugin (?) + switcherThread.join(); return; } + +bool Switcher::getIsRunning() +{ + return isRunning; +} \ No newline at end of file diff --git a/switcher.h b/switcher.h index d00b88d0..f0c2bca8 100644 --- a/switcher.h +++ b/switcher.h @@ -11,13 +11,16 @@ using namespace std; class Switcher { public: - map load(); + bool getIsRunning(); + void load(); + void start(); void stop(); + thread switcherThread; private: + bool isRunning = true; Settings settings; map settingsMap; -}; - - -string GetActiveWindowTitle(); -void switcherThreadFunc(map settingsMap); + void switcherThreadFunc(); + bool isWindowFullscreen(); + string GetActiveWindowTitle(); +}; \ No newline at end of file