From ce9d5c2599b8c0a3a4b8bd6a69baa4ff1036c35e Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Tue, 28 Jul 2020 11:10:14 +0200 Subject: [PATCH] Fixed the screensaver random function so it does not show the same game twice in a row. Also fixed a bug related to audio playing for the video screensaver and changed its name from 'random video' to simply 'video'. --- NEWS.md | 4 ++ es-app/src/SystemScreenSaver.cpp | 39 +++++++++++++++---- es-app/src/SystemScreenSaver.h | 3 +- .../src/guis/GuiGeneralScreensaverOptions.cpp | 6 +-- .../guis/GuiSlideshowScreensaverOptions.cpp | 2 +- .../src/guis/GuiVideoScreensaverOptions.cpp | 2 +- es-core/src/PowerSaver.cpp | 2 +- es-core/src/Window.cpp | 4 +- es-core/src/Window.h | 2 +- es-core/src/components/VideoVlcComponent.cpp | 5 ++- 10 files changed, 49 insertions(+), 20 deletions(-) diff --git a/NEWS.md b/NEWS.md index b6c9eb4cc..bc16ec1ac 100644 --- a/NEWS.md +++ b/NEWS.md @@ -32,6 +32,7 @@ Many bugs have been fixed, and numerous features that were only partially implem * Core location can be defined relative to the emulator binary using the %EMUPATH% variable in es_systems.cfg (mostly useful for Windows) * Properly implemented the option to show or hide hidden files and folders * Properly implemented the option to show or hide games flagged as hidden in the metadata editor +* Custom event scripts can now be enabled or disabled with a menu option * Help system updated and expanded to the complete application (previously it was only partially implemented) * Improved input device configuration, and default keyboard mappings are now applied if the keyboard has not been configured by the user * GUI-configurable option to sort favorite games on the top of the game lists (favorites marked with stars) @@ -57,7 +58,10 @@ Many bugs have been fixed, and numerous features that were only partially implem * Game images were sometimes scaled incorrectly * Non-transparent favorite icons were not rendered correctly * Restart and power-off menu entries not working +* Unknown command line options were silently accepted instead of generating an error and notifying the user * Toggling the screensaver didn't work as expected +* The setting to enable or disable audio for the video screensaver only worked on Raspberry Pi +* The screensaver random function did not consider the previously selected game and could potentially show the same image or video over and over again * Deleting a game did not delete the game media files or its entry in the gamelist.xml file * SystemView didn't properly loop the systems if only two systems were available * Hidden files still showed up if they had a gamelist.xml entry diff --git a/es-app/src/SystemScreenSaver.cpp b/es-app/src/SystemScreenSaver.cpp index ca0dd6f77..6d4bc602f 100644 --- a/es-app/src/SystemScreenSaver.cpp +++ b/es-app/src/SystemScreenSaver.cpp @@ -77,7 +77,14 @@ bool SystemScreenSaver::isScreenSaverActive() void SystemScreenSaver::startScreenSaver() { std::string screensaver_behavior = Settings::getInstance()->getString("ScreenSaverBehavior"); - if (!mVideoScreensaver && (screensaver_behavior == "random video")) { + + // Set mPreviousGame which will be used to avoid showing the same game again during + // the random selection. + if ((screensaver_behavior == "video" || screensaver_behavior == "slideshow") && + mCurrentGame != nullptr) + mPreviousGame = mCurrentGame; + + if (!mVideoScreensaver && (screensaver_behavior == "video")) { // Configure to fade out the windows, skip fading if mode is set to Instant. mState = PowerSaver::getMode() == PowerSaver::INSTANT ? STATE_SCREENSAVER_ACTIVE @@ -208,7 +215,7 @@ void SystemScreenSaver::stopScreenSaver() void SystemScreenSaver::renderScreenSaver() { std::string screensaver_behavior = Settings::getInstance()->getString("ScreenSaverBehavior"); - if (mVideoScreensaver && screensaver_behavior == "random video") { + if (mVideoScreensaver && screensaver_behavior == "video") { // Render black background. Renderer::setMatrix(Transform4x4f::Identity()); Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), @@ -341,9 +348,17 @@ void SystemScreenSaver::pickRandomVideo(std::string& path) countVideos(); mCurrentGame = nullptr; + if (mVideoCount < 2) + mPreviousGame = nullptr; + + // If there are more than 1 videos available, keep trying until the same game is + // not shown again. if (mVideoCount > 0) { - int video = (int)(((float)rand() / float(RAND_MAX)) * (float)mVideoCount); - pickGameListNode(video, "video", path); + do { + int video = (int)(((float)rand() / float(RAND_MAX)) * (float)mVideoCount); + pickGameListNode(video, "video", path); + } + while (mPreviousGame && mCurrentGame == mPreviousGame); } } @@ -352,9 +367,17 @@ void SystemScreenSaver::pickRandomGameListImage(std::string& path) countImages(); mCurrentGame = nullptr; + if (mImageCount < 2) + mPreviousGame = nullptr; + + // If there are more than 1 images available, keep trying until the same game is + // not shown again. if (mImageCount > 0) { - int image = (int)(((float)rand() / float(RAND_MAX)) * (float)mImageCount); - pickGameListNode(image, "image", path); + do { + int image = (int)(((float)rand() / float(RAND_MAX)) * (float)mImageCount); + pickGameListNode(image, "image", path); + } + while (mPreviousGame && mCurrentGame == mPreviousGame); } } @@ -420,7 +443,7 @@ void SystemScreenSaver::update(int deltaTime) // Update the timer that swaps the videos. mTimer += deltaTime; if (mTimer > mVideoChangeTime) - nextVideo(); + nextGame(); } // If we have a loaded video then update it. @@ -430,7 +453,7 @@ void SystemScreenSaver::update(int deltaTime) mImageScreensaver->update(deltaTime); } -void SystemScreenSaver::nextVideo() { +void SystemScreenSaver::nextGame() { mStopBackgroundAudio = false; stopScreenSaver(); startScreenSaver(); diff --git a/es-app/src/SystemScreenSaver.h b/es-app/src/SystemScreenSaver.h index 80243e573..65e7dbd4c 100644 --- a/es-app/src/SystemScreenSaver.h +++ b/es-app/src/SystemScreenSaver.h @@ -24,7 +24,7 @@ public: virtual void startScreenSaver(); virtual void stopScreenSaver(); - virtual void nextVideo(); + virtual void nextGame(); virtual void renderScreenSaver(); virtual bool allowSleep(); virtual void update(int deltaTime); @@ -64,6 +64,7 @@ private: float mOpacity; int mTimer; FileData* mCurrentGame; + FileData* mPreviousGame; std::string mGameName; std::string mSystemName; int mVideoChangeTime; diff --git a/es-app/src/guis/GuiGeneralScreensaverOptions.cpp b/es-app/src/guis/GuiGeneralScreensaverOptions.cpp index f86d52d94..72868cbaa 100644 --- a/es-app/src/guis/GuiGeneralScreensaverOptions.cpp +++ b/es-app/src/guis/GuiGeneralScreensaverOptions.cpp @@ -44,17 +44,17 @@ GuiGeneralScreensaverOptions::GuiGeneralScreensaverOptions(Window* window, const screensavers.push_back("dim"); screensavers.push_back("black"); screensavers.push_back("slideshow"); - screensavers.push_back("random video"); + screensavers.push_back("video"); for (auto it = screensavers.cbegin(); it != screensavers.cend(); it++) screensaver_behavior->add(*it, *it, Settings::getInstance()-> getString("ScreenSaverBehavior") == *it); addWithLabel("SCREENSAVER BEHAVIOR", screensaver_behavior); addSaveFunc([this, screensaver_behavior] { if (Settings::getInstance()->getString("ScreenSaverBehavior") != - "random video" && screensaver_behavior->getSelected() == "random video") { + "video" && screensaver_behavior->getSelected() == "video") { // If before it wasn't risky but now there's a risk of problems, show warning. mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(), - "THE \"RANDOM VIDEO\" SCREENSAVER\nSHOWS VIDEOS FROM YOUR GAMELISTS.\n\nIF YOU DO NOT " + "THE \"VIDEO\" SCREENSAVER SHOWS\nVIDEOS FROM YOUR GAMELISTS.\n\nIF YOU DO NOT " "HAVE ANY VIDEOS, THE\nSCREENSAVER WILL DEFAULT TO \"BLACK\"", "OK", [] { return; })); } diff --git a/es-app/src/guis/GuiSlideshowScreensaverOptions.cpp b/es-app/src/guis/GuiSlideshowScreensaverOptions.cpp index 52612776b..97e7ea740 100644 --- a/es-app/src/guis/GuiSlideshowScreensaverOptions.cpp +++ b/es-app/src/guis/GuiSlideshowScreensaverOptions.cpp @@ -33,7 +33,7 @@ GuiSlideshowScreensaverOptions::GuiSlideshowScreensaverOptions(Window* window, c // Stretch image. auto sss_stretch = std::make_shared(mWindow); sss_stretch->setState(Settings::getInstance()->getBool("ScreenSaverStretchImages")); - addWithLabel(row, "STRETCH IMAGES TO MONITOR RESOLUTION", sss_stretch); + addWithLabel(row, "STRETCH IMAGES TO SCREEN RESOLUTION", sss_stretch); addSaveFunc([sss_stretch] { Settings::getInstance()->setBool("ScreenSaverStretchImages", sss_stretch->getState()); }); diff --git a/es-app/src/guis/GuiVideoScreensaverOptions.cpp b/es-app/src/guis/GuiVideoScreensaverOptions.cpp index 0a2599dc9..468990179 100644 --- a/es-app/src/guis/GuiVideoScreensaverOptions.cpp +++ b/es-app/src/guis/GuiVideoScreensaverOptions.cpp @@ -29,7 +29,7 @@ GuiVideoScreensaverOptions::GuiVideoScreensaverOptions(Window* window, const cha auto stretch_screensaver = std::make_shared(mWindow); stretch_screensaver->setState(Settings::getInstance()->getBool("ScreenSaverStretchVideos")); - addWithLabel("STRETCH VIDEOS TO MONITOR RESOLUTION", stretch_screensaver); + addWithLabel("STRETCH VIDEOS TO SCREEN RESOLUTION", stretch_screensaver); addSaveFunc([stretch_screensaver] { Settings::getInstance()-> setBool("ScreenSaverStretchVideos", stretch_screensaver->getState()); }); diff --git a/es-core/src/PowerSaver.cpp b/es-core/src/PowerSaver.cpp index d11519603..2db56a1f9 100644 --- a/es-core/src/PowerSaver.cpp +++ b/es-core/src/PowerSaver.cpp @@ -35,7 +35,7 @@ void PowerSaver::loadWakeupTime() { // TODO : Move this to Screensaver Class. std::string behaviour = Settings::getInstance()->getString("ScreenSaverBehavior"); - if (behaviour == "random video") + if (behaviour == "video") mWakeupTimeout = Settings::getInstance()->getInt("ScreenSaverSwapVideoTimeout") - getMode(); else if (behaviour == "slideshow") mWakeupTimeout = Settings::getInstance()->getInt("ScreenSaverSwapImageTimeout") - getMode(); diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index 0eee26c6f..484fbf10e 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -131,7 +131,7 @@ void Window::input(InputConfig* config, Input input) if (mScreenSaver) { if (mScreenSaver->isScreenSaverActive() && Settings::getInstance()->getBool("ScreenSaverControls") && - ((Settings::getInstance()->getString("ScreenSaverBehavior") == "random video") || + ((Settings::getInstance()->getString("ScreenSaverBehavior") == "video") || (Settings::getInstance()->getString("ScreenSaverBehavior") == "slideshow"))) { if (mScreenSaver->getCurrentGame() != nullptr && (config->isMappedTo("a", input) || @@ -140,7 +140,7 @@ void Window::input(InputConfig* config, Input input) if (config->isMappedLike("left", input) || config->isMappedLike("right", input)) { if (input.value != 0) { // Handle screensaver control. - mScreenSaver->nextVideo(); + mScreenSaver->nextGame(); } return; } diff --git a/es-core/src/Window.h b/es-core/src/Window.h index 2976bc7b9..2cbf953a3 100644 --- a/es-core/src/Window.h +++ b/es-core/src/Window.h @@ -32,7 +32,7 @@ public: public: virtual void startScreenSaver() = 0; virtual void stopScreenSaver() = 0; - virtual void nextVideo() = 0; + virtual void nextGame() = 0; virtual void renderScreenSaver() = 0; virtual bool allowSleep() = 0; virtual void update(int deltaTime) = 0; diff --git a/es-core/src/components/VideoVlcComponent.cpp b/es-core/src/components/VideoVlcComponent.cpp index c780b8837..aab682e93 100644 --- a/es-core/src/components/VideoVlcComponent.cpp +++ b/es-core/src/components/VideoVlcComponent.cpp @@ -227,11 +227,12 @@ void VideoVlcComponent::handleLooping() if (mIsPlaying && mMediaPlayer) { libvlc_state_t state = libvlc_media_player_get_state(mMediaPlayer); if (state == libvlc_Ended) { - if (!Settings::getInstance()->getBool("GamelistVideoAudio") || + libvlc_media_player_set_media(mMediaPlayer, mMedia); + + if ((!Settings::getInstance()->getBool("GamelistVideoAudio") && !mScreensaverMode) || (!Settings::getInstance()->getBool("ScreenSaverVideoAudio") && mScreensaverMode)) libvlc_audio_set_mute(mMediaPlayer, 1); - libvlc_media_player_set_media(mMediaPlayer, mMedia); libvlc_media_player_play(mMediaPlayer); } }