From 45694cf1a4133435a0cd5bd1ddd9ffcccc8a293f Mon Sep 17 00:00:00 2001 From: hex007 Date: Thu, 20 Jul 2017 00:07:02 -0700 Subject: [PATCH] Power Saver Feature - Change Power Saver (PS) from Other Settings menu - 4 Modes are available : Disabled, Default [default], Enhanced, Instant - All modes work well with Screensavers and Video previews. - PS is disabled while running Videos through VLC. - PS is disabled while Scrapping - Game counts are shown immidiately if in Instant Mode - PS mode defaults if Transitions are changed while in Instant Mode --- es-app/src/components/TextListComponent.h | 2 +- es-app/src/guis/GuiGameScraper.cpp | 3 + es-app/src/guis/GuiMenu.cpp | 52 +++++++++++++++- es-app/src/guis/GuiScraperMulti.cpp | 3 + es-app/src/main.cpp | 61 +++++++++++++------ es-app/src/views/SystemView.cpp | 25 ++++---- es-app/src/views/ViewController.cpp | 2 + es-core/CMakeLists.txt | 2 + es-core/src/PowerSaver.cpp | 44 +++++++++++++ es-core/src/PowerSaver.h | 17 ++++++ es-core/src/Settings.cpp | 1 + .../src/components/ScrollableContainer.cpp | 4 +- es-core/src/components/VideoVlcComponent.cpp | 8 ++- 13 files changed, 182 insertions(+), 42 deletions(-) create mode 100644 es-core/src/PowerSaver.cpp create mode 100644 es-core/src/PowerSaver.h diff --git a/es-app/src/components/TextListComponent.h b/es-app/src/components/TextListComponent.h index b39dda3ce..0aa078ac2 100644 --- a/es-app/src/components/TextListComponent.h +++ b/es-app/src/components/TextListComponent.h @@ -86,7 +86,7 @@ protected: virtual void onCursorChanged(const CursorState& state); private: - static const int MARQUEE_DELAY = 2000; + static const int MARQUEE_DELAY = 1000; static const int MARQUEE_SPEED = 8; static const int MARQUEE_RATE = 1; diff --git a/es-app/src/guis/GuiGameScraper.cpp b/es-app/src/guis/GuiGameScraper.cpp index a54304c77..141d65262 100644 --- a/es-app/src/guis/GuiGameScraper.cpp +++ b/es-app/src/guis/GuiGameScraper.cpp @@ -6,6 +6,7 @@ #include "scrapers/Scraper.h" #include "Renderer.h" #include "Log.h" +#include "PowerSaver.h" #include "Settings.h" GuiGameScraper::GuiGameScraper(Window* window, ScraperSearchParams params, std::function doneFunc) : GuiComponent(window), @@ -14,6 +15,7 @@ GuiGameScraper::GuiGameScraper(Window* window, ScraperSearchParams params, std:: mSearchParams(params), mClose(false) { + PowerSaver::setState(false); addChild(&mBox); addChild(&mGrid); @@ -96,6 +98,7 @@ bool GuiGameScraper::input(InputConfig* config, Input input) { if(config->isMappedTo("b", input) && input.value) { + PowerSaver::setState(true); delete this; return true; } diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 88a972acd..1e8ade6ba 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -4,6 +4,7 @@ #include "Sound.h" #include "Log.h" #include "Settings.h" +#include "PowerSaver.h" #include "guis/GuiMsgBox.h" #include "guis/GuiSettings.h" #include "guis/GuiScreensaverOptions.h" @@ -175,7 +176,16 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN auto move_carousel = std::make_shared(mWindow); move_carousel->setState(Settings::getInstance()->getBool("MoveCarousel")); s->addWithLabel("CAROUSEL TRANSITIONS", move_carousel); - s->addSaveFunc([move_carousel] { Settings::getInstance()->setBool("MoveCarousel", move_carousel->getState()); }); + s->addSaveFunc([move_carousel] { + if (move_carousel->getState() + && !Settings::getInstance()->getBool("MoveCarousel") + && PowerSaver::ps_instant == PowerSaver::getTimeout()) + { + Settings::getInstance()->setString("PowerSaverMode", "default"); + PowerSaver::init(); + } + Settings::getInstance()->setBool("MoveCarousel", move_carousel->getState()); + }); // transition style auto transition_style = std::make_shared< OptionListComponent >(mWindow, "TRANSITION STYLE", false); @@ -186,7 +196,16 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN for(auto it = transitions.begin(); it != transitions.end(); it++) transition_style->add(*it, *it, Settings::getInstance()->getString("TransitionStyle") == *it); s->addWithLabel("TRANSITION STYLE", transition_style); - s->addSaveFunc([transition_style] { Settings::getInstance()->setString("TransitionStyle", transition_style->getSelected()); }); + s->addSaveFunc([transition_style] { + if (Settings::getInstance()->getString("TransitionStyle") == "instant" + && transition_style->getSelected() != "instant" + && PowerSaver::ps_instant == PowerSaver::getTimeout()) + { + Settings::getInstance()->setString("PowerSaverMode", "default"); + PowerSaver::init(); + } + Settings::getInstance()->setString("TransitionStyle", transition_style->getSelected()); + }); // theme set auto themeSets = ThemeData::getThemeSets(); @@ -247,6 +266,7 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN addEntry("GAME COLLECTION SETTINGS", 0x777777FF, true, [this] { openCollectionSystemSettings(); }); + addEntry("OTHER SETTINGS", 0x777777FF, true, [this] { auto s = new GuiSettings(mWindow, "OTHER SETTINGS"); @@ -257,6 +277,32 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN s->addWithLabel("VRAM LIMIT", max_vram); s->addSaveFunc([max_vram] { Settings::getInstance()->setInt("MaxVRAM", (int)round(max_vram->getValue())); }); + // power saver + auto power_saver = std::make_shared< OptionListComponent >(mWindow, "POWER SAVER MODES", false); + std::vector modes; + modes.push_back("disabled"); + modes.push_back("default"); + modes.push_back("enhanced"); + modes.push_back("instant"); + for (auto it = modes.begin(); it != modes.end(); it++) + power_saver->add(*it, *it, Settings::getInstance()->getString("PowerSaverMode") == *it); + s->addWithLabel("POWER SAVER MODES", power_saver); + s->addSaveFunc([this, power_saver] { + if (Settings::getInstance()->getString("PowerSaverMode") != "instant" && power_saver->getSelected() == "instant"){ + mWindow->pushGui(new GuiMsgBox(mWindow, "Setting Power Saver to Instant Mode disables Carousel transition and sets Transition Style to Instant. Would you like to continue?" + , "YES", [] { + Settings::getInstance()->setString("TransitionStyle", "instant"); + Settings::getInstance()->setString("PowerSaverMode", "instant"); + Settings::getInstance()->setBool("MoveCarousel", false); + PowerSaver::init(); + }, "NO", nullptr) + ); + } else { + Settings::getInstance()->setString("PowerSaverMode", power_saver->getSelected()); + PowerSaver::init(); + } + }); + // gamelists auto save_gamelists = std::make_shared(mWindow); save_gamelists->setState(Settings::getInstance()->getBool("SaveGamelistsOnExit")); @@ -366,7 +412,7 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN }); mVersion.setFont(Font::get(FONT_SIZE_SMALL)); - mVersion.setColor(0xC6C6C6FF); + mVersion.setColor(0x5E5E5EFF); mVersion.setText("EMULATIONSTATION V" + strToUpper(PROGRAM_VERSION_STRING)); mVersion.setAlignment(ALIGN_CENTER); diff --git a/es-app/src/guis/GuiScraperMulti.cpp b/es-app/src/guis/GuiScraperMulti.cpp index 8da0377df..841a7b9b9 100644 --- a/es-app/src/guis/GuiScraperMulti.cpp +++ b/es-app/src/guis/GuiScraperMulti.cpp @@ -3,6 +3,7 @@ #include "Log.h" #include "views/ViewController.h" #include "Gamelist.h" +#include "PowerSaver.h" #include "components/TextComponent.h" #include "components/ButtonComponent.h" @@ -18,6 +19,7 @@ GuiScraperMulti::GuiScraperMulti(Window* window, const std::queue @@ -224,6 +225,7 @@ int main(int argc, char* argv[]) Window window; SystemScreenSaver screensaver(&window); + PowerSaver::init(); ViewController::init(&window); CollectionSystemManager::init(&window); window.pushGui(ViewController::get()); @@ -293,31 +295,50 @@ int main(int argc, char* argv[]) SDL_JoystickEventState(SDL_ENABLE); int lastTime = SDL_GetTicks(); + int ps_time = SDL_GetTicks(); + bool running = true; + bool ps_standby = false; + + // assuming screensaver timeout is not updated regularly. + int timeout = (unsigned int) Settings::getInstance()->getInt("ScreenSaverTime"); while(running) { SDL_Event event; - while(SDL_PollEvent(&event)) + bool ps_standby = PowerSaver::getState() && SDL_GetTicks() - ps_time > PowerSaver::getTimeout(); + + if(ps_standby ? SDL_WaitEventTimeout(&event, timeout - 100) : SDL_PollEvent(&event)) { - switch(event.type) + do { - case SDL_JOYHATMOTION: - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - case SDL_KEYDOWN: - case SDL_KEYUP: - case SDL_JOYAXISMOTION: - case SDL_TEXTINPUT: - case SDL_TEXTEDITING: - case SDL_JOYDEVICEADDED: - case SDL_JOYDEVICEREMOVED: - InputManager::getInstance()->parseEvent(event, &window); - break; - case SDL_QUIT: - running = false; - break; - } + switch(event.type) + { + case SDL_JOYHATMOTION: + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + case SDL_KEYDOWN: + case SDL_KEYUP: + case SDL_JOYAXISMOTION: + case SDL_TEXTINPUT: + case SDL_TEXTEDITING: + case SDL_JOYDEVICEADDED: + case SDL_JOYDEVICEREMOVED: + InputManager::getInstance()->parseEvent(event, &window); + break; + case SDL_QUIT: + running = false; + break; + } + } while(SDL_PollEvent(&event)); + + // triggered if exiting from SDL_WaitEvent + if (ps_standby) + // show as if continuing from last event + lastTime = SDL_GetTicks(); + + // reset counter + ps_time = SDL_GetTicks(); } if(window.isSleeping()) @@ -331,8 +352,8 @@ int main(int argc, char* argv[]) int deltaTime = curTime - lastTime; lastTime = curTime; - // cap deltaTime at 1000 - if(deltaTime > 1000 || deltaTime < 0) + // cap deltaTime + if(deltaTime > timeout || deltaTime < 0) deltaTime = 1000; window.update(deltaTime); diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index 9bb7786df..acb14c8cf 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -5,6 +5,7 @@ #include "Window.h" #include "views/ViewController.h" #include "animations/LambdaAnimation.h" +#include "PowerSaver.h" #include "SystemData.h" #include "Settings.h" #include "Util.h" @@ -213,13 +214,15 @@ void SystemView::onCursorChanged(const CursorState& state) cancelAnimation(1); cancelAnimation(2); + std::string transition_style = Settings::getInstance()->getString("TransitionStyle"); + bool goFast = transition_style == "instant"; const float infoStartOpacity = mSystemInfo.getOpacity() / 255.f; Animation* infoFadeOut = new LambdaAnimation( [infoStartOpacity, this] (float t) { mSystemInfo.setOpacity((unsigned char)(lerp(infoStartOpacity, 0.f, t) * 255)); - }, (int)(infoStartOpacity * 150)); + }, (int)(infoStartOpacity * (goFast ? 10 : 150))); unsigned int gameCount = getSelected()->getDisplayedGameCount(); @@ -229,25 +232,20 @@ void SystemView::onCursorChanged(const CursorState& state) if (!getSelected()->isGameSystem()) ss << "CONFIGURATION"; - // only display a game count if there are at least 2 games - else if(gameCount > 1) + else ss << gameCount << " GAMES AVAILABLE"; mSystemInfo.setText(ss.str()); }, false, 1); - // only display a game count if there are at least 2 games - if(gameCount > 1) + Animation* infoFadeIn = new LambdaAnimation( + [this](float t) { - Animation* infoFadeIn = new LambdaAnimation( - [this](float t) - { - mSystemInfo.setOpacity((unsigned char)(lerp(0.f, 1.f, t) * 255)); - }, 300); + mSystemInfo.setOpacity((unsigned char)(lerp(0.f, 1.f, t) * 255)); + }, goFast ? 10 : 300); - // wait 600ms to fade in - setAnimation(infoFadeIn, 2000, nullptr, false, 2); - } + // wait 600ms to fade in + setAnimation(infoFadeIn, goFast ? 0 : 2000, nullptr, false, 2); // no need to animate transition, we're not going anywhere (probably mEntries.size() == 1) if(endPos == mCamOffset && endPos == mExtrasCamOffset) @@ -255,7 +253,6 @@ void SystemView::onCursorChanged(const CursorState& state) Animation* anim; bool move_carousel = Settings::getInstance()->getBool("MoveCarousel"); - std::string transition_style = Settings::getInstance()->getString("TransitionStyle"); if(transition_style == "fade") { float startExtrasFade = mExtrasFadeOpacity; diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index 254e84647..cb7b66a49 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -2,6 +2,7 @@ #include "Log.h" #include "SystemData.h" #include "Settings.h" +#include "PowerSaver.h" #include "views/gamelist/BasicGameListView.h" #include "views/gamelist/DetailedGameListView.h" @@ -71,6 +72,7 @@ void ViewController::goToSystemView(SystemData* system) systemList->goToSystem(system, false); mCurrentView = systemList; + PowerSaver::setState(true); playViewTransition(); } diff --git a/es-core/CMakeLists.txt b/es-core/CMakeLists.txt index c6b0ea8b6..825208d1f 100644 --- a/es-core/CMakeLists.txt +++ b/es-core/CMakeLists.txt @@ -11,6 +11,7 @@ set(CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/InputManager.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Log.h ${CMAKE_CURRENT_SOURCE_DIR}/src/platform.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/PowerSaver.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Renderer.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Settings.h ${CMAKE_CURRENT_SOURCE_DIR}/src/Sound.h @@ -73,6 +74,7 @@ set(CORE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/InputManager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Log.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/platform.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/PowerSaver.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Renderer_draw_gl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Renderer_init_sdlgl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Settings.cpp diff --git a/es-core/src/PowerSaver.cpp b/es-core/src/PowerSaver.cpp new file mode 100644 index 000000000..d12886a15 --- /dev/null +++ b/es-core/src/PowerSaver.cpp @@ -0,0 +1,44 @@ +#include "PowerSaver.h" +#include "Settings.h" +#include + +bool PowerSaver::mState = true; +int PowerSaver::mTimeout = PowerSaver::ps_default; + +void PowerSaver::init(bool state) +{ + setState(true); + updateTimeout(); +} + +int PowerSaver::getTimeout() +{ + return mTimeout; +} + +void PowerSaver::updateTimeout() +{ + std::string mode = Settings::getInstance()->getString("PowerSaverMode"); + + if (mode == "disabled") { + mTimeout = ps_disabled; + } else if (mode == "instant") { + mTimeout = ps_instant; + } else if (mode == "enhanced") { + mTimeout = ps_enhanced; + } else { // default + mTimeout = ps_default; + } +} + +bool PowerSaver::getState() +{ + return mState; +} + +void PowerSaver::setState(bool state) +{ + bool ps_enabled = Settings::getInstance()->getString("PowerSaverMode") != "disabled"; + mState = ps_enabled && state; +} + diff --git a/es-core/src/PowerSaver.h b/es-core/src/PowerSaver.h new file mode 100644 index 000000000..b6fd2a67f --- /dev/null +++ b/es-core/src/PowerSaver.h @@ -0,0 +1,17 @@ +class PowerSaver +{ +public: + enum ps_state : int { ps_disabled = -1, ps_instant = 200, ps_enhanced = 3000, ps_default = 10000 }; + + static void init(bool state = true); + + static int getTimeout(); + static void updateTimeout(); + + static bool getState(); + static void setState(bool state); + +private: + static bool mState; + static int mTimeout; +}; diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 1a5554a1c..395708efd 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -81,6 +81,7 @@ void Settings::setDefaults() mBoolMap["ScreenSaverControls"] = true; mStringMap["ScreenSaverGameInfo"] = "never"; mBoolMap["StretchVideoOnScreenSaver"] = false; + mStringMap["PowerSaverMode"] = "default"; // This setting only applies to raspberry pi but set it for all platforms so // we don't get a warning if we encounter it on a different platform diff --git a/es-core/src/components/ScrollableContainer.cpp b/es-core/src/components/ScrollableContainer.cpp index f709c062f..0c8440969 100644 --- a/es-core/src/components/ScrollableContainer.cpp +++ b/es-core/src/components/ScrollableContainer.cpp @@ -2,8 +2,8 @@ #include "Renderer.h" #include "Log.h" -#define AUTO_SCROLL_RESET_DELAY 10000 // ms to reset to top after we reach the bottom -#define AUTO_SCROLL_DELAY 8000 // ms to wait before we start to scroll +#define AUTO_SCROLL_RESET_DELAY 3000 // ms to reset to top after we reach the bottom +#define AUTO_SCROLL_DELAY 1000 // ms to wait before we start to scroll #define AUTO_SCROLL_SPEED 50 // ms between scrolls ScrollableContainer::ScrollableContainer(Window* window) : GuiComponent(window), diff --git a/es-core/src/components/VideoVlcComponent.cpp b/es-core/src/components/VideoVlcComponent.cpp index d042374cc..7cba4ba3b 100644 --- a/es-core/src/components/VideoVlcComponent.cpp +++ b/es-core/src/components/VideoVlcComponent.cpp @@ -3,11 +3,13 @@ #include "ThemeData.h" #include "Util.h" #include "Settings.h" +#include "PowerSaver.h" + #ifdef WIN32 #include #endif -libvlc_instance_t* VideoVlcComponent::mVLC = NULL; +libvlc_instance_t* VideoVlcComponent::mVLC = NULL; // VLC prepares to render a video frame. static void *lock(void *data, void **p_pixels) { @@ -289,7 +291,7 @@ void VideoVlcComponent::startVideo() mMedia = libvlc_media_new_path(mVLC, path.c_str()); if (mMedia) { - unsigned track_count; + unsigned track_count; // Get the media metadata so we can find the aspect ratio libvlc_media_parse(mMedia); libvlc_media_track_t** tracks; @@ -328,6 +330,7 @@ void VideoVlcComponent::startVideo() } } #endif + PowerSaver::setState(false); setupContext(); // Setup the media player @@ -358,6 +361,7 @@ void VideoVlcComponent::stopVideo() // Release the media player so it stops calling back to us if (mMediaPlayer) { + PowerSaver::setState(true); libvlc_media_player_stop(mMediaPlayer); libvlc_media_player_release(mMediaPlayer); libvlc_media_release(mMedia);