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'.
This commit is contained in:
Leon Styhre 2020-07-28 11:10:14 +02:00
parent 35758e58d7
commit ce9d5c2599
10 changed files with 49 additions and 20 deletions

View file

@ -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

View file

@ -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();

View file

@ -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;

View file

@ -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; }));
}

View file

@ -33,7 +33,7 @@ GuiSlideshowScreensaverOptions::GuiSlideshowScreensaverOptions(Window* window, c
// Stretch image.
auto sss_stretch = std::make_shared<SwitchComponent>(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());
});

View file

@ -29,7 +29,7 @@ GuiVideoScreensaverOptions::GuiVideoScreensaverOptions(Window* window, const cha
auto stretch_screensaver = std::make_shared<SwitchComponent>(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()); });

View file

@ -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();

View file

@ -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;
}

View file

@ -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;

View file

@ -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);
}
}