2020-09-18 16:40:22 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
2020-06-23 18:07:00 +00:00
|
|
|
//
|
2020-09-18 16:40:22 +00:00
|
|
|
// EmulationStation Desktop Edition
|
2020-06-23 18:07:00 +00:00
|
|
|
// SystemScreenSaver.cpp
|
|
|
|
//
|
|
|
|
// Screensaver, supporting the following modes:
|
2020-07-27 14:53:54 +00:00
|
|
|
// Dim, black, slideshow, video.
|
2020-06-23 18:07:00 +00:00
|
|
|
//
|
|
|
|
|
2016-12-14 08:30:54 +00:00
|
|
|
#include "SystemScreenSaver.h"
|
2017-11-01 22:21:10 +00:00
|
|
|
|
2020-08-23 15:04:30 +00:00
|
|
|
#if defined(_RPI_)
|
2016-12-14 08:30:54 +00:00
|
|
|
#include "components/VideoPlayerComponent.h"
|
|
|
|
#endif
|
|
|
|
#include "components/VideoVlcComponent.h"
|
2018-01-09 22:55:09 +00:00
|
|
|
#include "utils/FileSystemUtil.h"
|
2017-11-01 22:21:10 +00:00
|
|
|
#include "views/gamelist/IGameListView.h"
|
|
|
|
#include "views/ViewController.h"
|
|
|
|
#include "FileData.h"
|
|
|
|
#include "FileFilterIndex.h"
|
|
|
|
#include "Log.h"
|
2017-08-02 19:56:33 +00:00
|
|
|
#include "PowerSaver.h"
|
2017-11-01 22:21:10 +00:00
|
|
|
#include "Sound.h"
|
2016-12-14 08:30:54 +00:00
|
|
|
#include "SystemData.h"
|
2020-07-03 18:23:51 +00:00
|
|
|
|
2017-11-01 22:21:10 +00:00
|
|
|
#include <unordered_map>
|
2018-01-29 22:50:10 +00:00
|
|
|
#include <time.h>
|
2020-07-03 18:23:51 +00:00
|
|
|
|
2020-08-23 15:04:30 +00:00
|
|
|
#if defined(_WIN64)
|
2020-07-03 18:23:51 +00:00
|
|
|
#include <cstring>
|
|
|
|
#endif
|
|
|
|
|
2020-06-23 18:07:00 +00:00
|
|
|
#define FADE_TIME 300
|
|
|
|
|
|
|
|
SystemScreenSaver::SystemScreenSaver(
|
|
|
|
Window* window)
|
|
|
|
: mVideoScreensaver(nullptr),
|
|
|
|
mImageScreensaver(nullptr),
|
|
|
|
mWindow(window),
|
|
|
|
mVideosCounted(false),
|
|
|
|
mVideoCount(0),
|
|
|
|
mImagesCounted(false),
|
|
|
|
mImageCount(0),
|
|
|
|
mState(STATE_INACTIVE),
|
|
|
|
mOpacity(0.0f),
|
|
|
|
mTimer(0),
|
|
|
|
mSystemName(""),
|
|
|
|
mGameName(""),
|
|
|
|
mCurrentGame(nullptr),
|
|
|
|
mStopBackgroundAudio(true)
|
2016-12-14 08:30:54 +00:00
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
mWindow->setScreenSaver(this);
|
|
|
|
std::string path = getTitleFolder();
|
|
|
|
if (!Utils::FileSystem::exists(path))
|
|
|
|
Utils::FileSystem::createDirectory(path);
|
|
|
|
srand((unsigned int)time(nullptr));
|
|
|
|
mVideoChangeTime = 30000;
|
2016-12-14 08:30:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SystemScreenSaver::~SystemScreenSaver()
|
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
// Delete subtitle file, if it exists.
|
|
|
|
remove(getTitlePath().c_str());
|
|
|
|
mCurrentGame = nullptr;
|
|
|
|
delete mVideoScreensaver;
|
|
|
|
delete mImageScreensaver;
|
2016-12-14 08:30:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SystemScreenSaver::allowSleep()
|
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
return ((mVideoScreensaver == nullptr) && (mImageScreensaver == nullptr));
|
2017-06-01 20:08:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SystemScreenSaver::isScreenSaverActive()
|
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
return (mState != STATE_INACTIVE);
|
2016-12-14 08:30:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SystemScreenSaver::startScreenSaver()
|
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
std::string screensaver_behavior = Settings::getInstance()->getString("ScreenSaverBehavior");
|
2020-07-28 09:10:14 +00:00
|
|
|
|
|
|
|
// 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")) {
|
2020-06-23 18:07:00 +00:00
|
|
|
// Configure to fade out the windows, skip fading if mode is set to Instant.
|
2020-09-18 16:40:22 +00:00
|
|
|
mState = PowerSaver::getMode() ==
|
|
|
|
PowerSaver::INSTANT ? STATE_SCREENSAVER_ACTIVE : STATE_FADE_OUT_WINDOW;
|
2020-06-23 18:07:00 +00:00
|
|
|
mVideoChangeTime = Settings::getInstance()->getInt("ScreenSaverSwapVideoTimeout");
|
|
|
|
mOpacity = 0.0f;
|
|
|
|
|
|
|
|
// Load a random video.
|
|
|
|
std::string path = "";
|
|
|
|
pickRandomVideo(path);
|
|
|
|
|
|
|
|
int retry = 200;
|
|
|
|
while (retry > 0 && ((path.empty() || !Utils::FileSystem::exists(path)) ||
|
|
|
|
mCurrentGame == nullptr)) {
|
|
|
|
retry--;
|
|
|
|
pickRandomVideo(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!path.empty() && Utils::FileSystem::exists(path)) {
|
2020-08-23 15:04:30 +00:00
|
|
|
#if defined(_RPI_)
|
2020-06-23 18:07:00 +00:00
|
|
|
// Create the correct type of video component
|
|
|
|
if (Settings::getInstance()->getBool("ScreenSaverOmxPlayer"))
|
|
|
|
mVideoScreensaver = new VideoPlayerComponent(mWindow, getTitlePath());
|
|
|
|
else
|
|
|
|
mVideoScreensaver = new VideoVlcComponent(mWindow, getTitlePath());
|
|
|
|
#else
|
|
|
|
mVideoScreensaver = new VideoVlcComponent(mWindow, getTitlePath());
|
|
|
|
#endif
|
|
|
|
|
|
|
|
mVideoScreensaver->topWindow(true);
|
|
|
|
mVideoScreensaver->setOrigin(0.5f, 0.5f);
|
|
|
|
mVideoScreensaver->setPosition(Renderer::getScreenWidth() / 2.0f,
|
|
|
|
Renderer::getScreenHeight() / 2.0f);
|
|
|
|
|
2020-07-27 18:38:22 +00:00
|
|
|
if (Settings::getInstance()->getBool("ScreenSaverStretchVideos"))
|
2020-09-18 16:40:22 +00:00
|
|
|
mVideoScreensaver->setResize(static_cast<float>(Renderer::getScreenWidth()),
|
|
|
|
static_cast<float>(Renderer::getScreenHeight()));
|
2020-06-23 18:07:00 +00:00
|
|
|
else
|
2020-09-18 16:40:22 +00:00
|
|
|
mVideoScreensaver->setMaxSize(static_cast<float>(Renderer::getScreenWidth()),
|
|
|
|
static_cast<float>(Renderer::getScreenHeight()));
|
2020-06-23 18:07:00 +00:00
|
|
|
|
|
|
|
mVideoScreensaver->setVideo(path);
|
|
|
|
mVideoScreensaver->setScreensaverMode(true);
|
|
|
|
mVideoScreensaver->onShow();
|
|
|
|
PowerSaver::runningScreenSaver(true);
|
|
|
|
mTimer = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (screensaver_behavior == "slideshow") {
|
|
|
|
// Configure to fade out the windows, skip fading if mode is set to Instant.
|
2020-09-18 16:40:22 +00:00
|
|
|
mState = PowerSaver::getMode() ==
|
|
|
|
PowerSaver::INSTANT ? STATE_SCREENSAVER_ACTIVE : STATE_FADE_OUT_WINDOW;
|
2020-06-23 18:07:00 +00:00
|
|
|
mVideoChangeTime = Settings::getInstance()->getInt("ScreenSaverSwapImageTimeout");
|
|
|
|
mOpacity = 0.0f;
|
|
|
|
|
|
|
|
// Load a random image.
|
|
|
|
std::string path = "";
|
|
|
|
if (Settings::getInstance()->getBool("SlideshowScreenSaverCustomImageSource")) {
|
|
|
|
pickRandomCustomImage(path);
|
|
|
|
// Custom images are not tied to the game list.
|
|
|
|
mCurrentGame = nullptr;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pickRandomGameListImage(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mImageScreensaver)
|
|
|
|
mImageScreensaver = new ImageComponent(mWindow, false, false);
|
|
|
|
|
|
|
|
mTimer = 0;
|
|
|
|
|
|
|
|
mImageScreensaver->setImage(path);
|
|
|
|
mImageScreensaver->setOrigin(0.5f, 0.5f);
|
|
|
|
mImageScreensaver->setPosition(Renderer::getScreenWidth() / 2.0f,
|
|
|
|
Renderer::getScreenHeight() / 2.0f);
|
|
|
|
|
2020-07-27 18:38:22 +00:00
|
|
|
if (Settings::getInstance()->getBool("ScreenSaverStretchImages"))
|
2020-09-18 16:40:22 +00:00
|
|
|
mImageScreensaver->setResize(static_cast<float>(Renderer::getScreenWidth()),
|
|
|
|
static_cast<float>(Renderer::getScreenHeight()));
|
2020-06-23 18:07:00 +00:00
|
|
|
else
|
2020-09-18 16:40:22 +00:00
|
|
|
mImageScreensaver->setMaxSize(static_cast<float>(Renderer::getScreenWidth()),
|
|
|
|
static_cast<float>(Renderer::getScreenHeight()));
|
2020-06-23 18:07:00 +00:00
|
|
|
|
|
|
|
std::string bg_audio_file = Settings::getInstance()->
|
|
|
|
getString("SlideshowScreenSaverBackgroundAudioFile");
|
|
|
|
if ((!mBackgroundAudio) && (bg_audio_file != "")) {
|
|
|
|
if (Utils::FileSystem::exists(bg_audio_file)) {
|
|
|
|
// Pause PowerSaver so that the background audio keeps playing.
|
|
|
|
PowerSaver::pause();
|
|
|
|
mBackgroundAudio = Sound::get(bg_audio_file);
|
|
|
|
mBackgroundAudio->play();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PowerSaver::runningScreenSaver(true);
|
|
|
|
mTimer = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// No videos. Just use a standard screensaver.
|
|
|
|
mState = STATE_SCREENSAVER_ACTIVE;
|
|
|
|
mCurrentGame = nullptr;
|
2016-12-14 08:30:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SystemScreenSaver::stopScreenSaver()
|
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
if ((mBackgroundAudio) && (mStopBackgroundAudio)) {
|
|
|
|
mBackgroundAudio->stop();
|
|
|
|
mBackgroundAudio.reset();
|
|
|
|
// If we were playing audio, we paused PowerSaver.
|
|
|
|
PowerSaver::resume();
|
|
|
|
}
|
|
|
|
|
|
|
|
// So that we stop the background audio next time, unless we're restarting the screensaver.
|
|
|
|
mStopBackgroundAudio = true;
|
|
|
|
|
|
|
|
delete mVideoScreensaver;
|
|
|
|
mVideoScreensaver = nullptr;
|
|
|
|
delete mImageScreensaver;
|
|
|
|
mImageScreensaver = nullptr;
|
|
|
|
|
|
|
|
// We need this to loop through different videos.
|
|
|
|
mState = STATE_INACTIVE;
|
|
|
|
PowerSaver::runningScreenSaver(false);
|
2016-12-14 08:30:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SystemScreenSaver::renderScreenSaver()
|
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
std::string screensaver_behavior = Settings::getInstance()->getString("ScreenSaverBehavior");
|
2020-07-28 09:10:14 +00:00
|
|
|
if (mVideoScreensaver && screensaver_behavior == "video") {
|
2020-06-23 18:07:00 +00:00
|
|
|
// Render black background.
|
|
|
|
Renderer::setMatrix(Transform4x4f::Identity());
|
|
|
|
Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(),
|
|
|
|
Renderer::getScreenHeight(), 0x000000FF, 0x000000FF);
|
|
|
|
|
|
|
|
// Only render the video if the state requires it.
|
2020-09-18 16:40:22 +00:00
|
|
|
if (static_cast<int>(mState) >= STATE_FADE_IN_VIDEO) {
|
2020-06-23 18:07:00 +00:00
|
|
|
Transform4x4f transform = Transform4x4f::Identity();
|
|
|
|
mVideoScreensaver->render(transform);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (mImageScreensaver && screensaver_behavior == "slideshow") {
|
|
|
|
// Render black background.
|
|
|
|
Renderer::setMatrix(Transform4x4f::Identity());
|
|
|
|
Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(),
|
|
|
|
Renderer::getScreenHeight(), 0x000000FF, 0x000000FF);
|
|
|
|
|
|
|
|
// Only render the video if the state requires it.
|
|
|
|
if ((int)mState >= STATE_FADE_IN_VIDEO) {
|
|
|
|
if (mImageScreensaver->hasImage()) {
|
2020-09-18 16:40:22 +00:00
|
|
|
mImageScreensaver->setOpacity(255 - static_cast<unsigned char>(mOpacity * 255));
|
2020-06-23 18:07:00 +00:00
|
|
|
|
|
|
|
Transform4x4f transform = Transform4x4f::Identity();
|
|
|
|
mImageScreensaver->render(transform);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if we need to restart the background audio.
|
|
|
|
if ((mBackgroundAudio) && (Settings::getInstance()->
|
|
|
|
getString("SlideshowScreenSaverBackgroundAudioFile") != "")) {
|
|
|
|
if (!mBackgroundAudio->isPlaying())
|
|
|
|
mBackgroundAudio->play();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (mState != STATE_INACTIVE) {
|
2020-09-13 11:21:38 +00:00
|
|
|
#if !defined(USE_OPENGL_21)
|
2020-06-23 18:07:00 +00:00
|
|
|
Renderer::setMatrix(Transform4x4f::Identity());
|
|
|
|
unsigned char color = screensaver_behavior == "dim" ? 0x000000A0 : 0x000000FF;
|
|
|
|
Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(),
|
|
|
|
Renderer::getScreenHeight(), color, color);
|
2020-09-13 11:21:38 +00:00
|
|
|
#endif
|
2020-06-23 18:07:00 +00:00
|
|
|
}
|
2016-12-14 08:30:54 +00:00
|
|
|
}
|
|
|
|
|
2017-09-09 03:45:50 +00:00
|
|
|
unsigned long SystemScreenSaver::countGameListNodes(const char *nodeName)
|
2016-12-14 08:30:54 +00:00
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
unsigned long nodeCount = 0;
|
|
|
|
std::vector<SystemData*>::const_iterator it;
|
|
|
|
for (it = SystemData::sSystemVector.cbegin();
|
|
|
|
it != SystemData::sSystemVector.cend(); ++it) {
|
|
|
|
// We only want nodes from game systems that are not collections.
|
|
|
|
if (!(*it)->isGameSystem() || (*it)->isCollection())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
FileData* rootFileData = (*it)->getRootFolder();
|
|
|
|
|
|
|
|
FileType type = GAME;
|
|
|
|
std::vector<FileData*> allFiles = rootFileData->getFilesRecursive(type, true);
|
|
|
|
std::vector<FileData*>::const_iterator itf; // Declare an iterator to a vector of strings.
|
|
|
|
|
|
|
|
for (itf=allFiles.cbegin() ; itf < allFiles.cend(); itf++) {
|
|
|
|
if ((strcmp(nodeName, "video") == 0 && (*itf)->getVideoPath() != "") ||
|
|
|
|
(strcmp(nodeName, "image") == 0 && (*itf)->getImagePath() != ""))
|
|
|
|
nodeCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nodeCount;
|
2017-09-09 03:45:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SystemScreenSaver::countVideos()
|
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
if (!mVideosCounted) {
|
|
|
|
mVideoCount = countGameListNodes("video");
|
|
|
|
mVideosCounted = true;
|
|
|
|
}
|
2017-09-09 03:45:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SystemScreenSaver::countImages()
|
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
if (!mImagesCounted) {
|
|
|
|
mImageCount = countGameListNodes("image");
|
|
|
|
mImagesCounted = true;
|
|
|
|
}
|
2017-09-09 03:45:50 +00:00
|
|
|
}
|
|
|
|
|
2020-06-23 18:07:00 +00:00
|
|
|
void SystemScreenSaver::pickGameListNode(unsigned long index,
|
|
|
|
const char *nodeName, std::string& path)
|
2017-09-09 03:45:50 +00:00
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
std::vector<SystemData*>::const_iterator it;
|
|
|
|
for (it = SystemData::sSystemVector.cbegin();
|
|
|
|
it != SystemData::sSystemVector.cend(); ++it) {
|
|
|
|
// We only want nodes from game systems that are not collections.
|
|
|
|
if (!(*it)->isGameSystem() || (*it)->isCollection())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
FileData* rootFileData = (*it)->getRootFolder();
|
|
|
|
|
|
|
|
FileType type = GAME;
|
|
|
|
std::vector<FileData*> allFiles = rootFileData->getFilesRecursive(type, true);
|
|
|
|
std::vector<FileData*>::const_iterator itf; // Declare an iterator to a vector of strings.
|
|
|
|
|
|
|
|
for (itf=allFiles.cbegin() ; itf < allFiles.cend(); itf++) {
|
|
|
|
if ((strcmp(nodeName, "video") == 0 && (*itf)->getVideoPath() != "") ||
|
|
|
|
(strcmp(nodeName, "image") == 0 && (*itf)->getImagePath() != "")) {
|
|
|
|
if (index-- == 0) {
|
|
|
|
// We have it.
|
|
|
|
path = "";
|
|
|
|
if (strcmp(nodeName, "video") == 0)
|
|
|
|
path = (*itf)->getVideoPath();
|
|
|
|
else if (strcmp(nodeName, "image") == 0)
|
|
|
|
path = (*itf)->getImagePath();
|
|
|
|
mSystemName = (*it)->getFullName();
|
|
|
|
mGameName = (*itf)->getName();
|
|
|
|
mCurrentGame = (*itf);
|
|
|
|
|
|
|
|
// End of getting FileData.
|
2020-08-23 15:04:30 +00:00
|
|
|
#if defined(_RPI_)
|
2020-06-23 18:07:00 +00:00
|
|
|
if (Settings::getInstance()->getString("ScreenSaverGameInfo") != "never")
|
|
|
|
writeSubtitle(mGameName.c_str(), mSystemName.c_str(),
|
|
|
|
(Settings::getInstance()->getString("ScreenSaverGameInfo") ==
|
|
|
|
"always"));
|
2020-07-27 19:41:10 +00:00
|
|
|
#endif
|
2020-06-23 18:07:00 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-12-14 08:30:54 +00:00
|
|
|
}
|
|
|
|
|
2017-09-09 03:45:50 +00:00
|
|
|
void SystemScreenSaver::pickRandomVideo(std::string& path)
|
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
countVideos();
|
|
|
|
mCurrentGame = nullptr;
|
|
|
|
|
2020-07-28 09:10:14 +00:00
|
|
|
if (mVideoCount < 2)
|
|
|
|
mPreviousGame = nullptr;
|
|
|
|
|
|
|
|
// If there are more than 1 videos available, keep trying until the same game is
|
|
|
|
// not shown again.
|
2020-06-23 18:07:00 +00:00
|
|
|
if (mVideoCount > 0) {
|
2020-07-28 09:10:14 +00:00
|
|
|
do {
|
2020-09-18 16:40:22 +00:00
|
|
|
int video = static_cast<int>((static_cast<float>(rand()) /
|
|
|
|
static_cast<float>(RAND_MAX)) * static_cast<float>(mVideoCount));
|
2020-07-28 09:10:14 +00:00
|
|
|
pickGameListNode(video, "video", path);
|
|
|
|
}
|
|
|
|
while (mPreviousGame && mCurrentGame == mPreviousGame);
|
2020-06-23 18:07:00 +00:00
|
|
|
}
|
2017-09-09 03:45:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SystemScreenSaver::pickRandomGameListImage(std::string& path)
|
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
countImages();
|
|
|
|
mCurrentGame = nullptr;
|
|
|
|
|
2020-07-28 09:10:14 +00:00
|
|
|
if (mImageCount < 2)
|
|
|
|
mPreviousGame = nullptr;
|
|
|
|
|
|
|
|
// If there are more than 1 images available, keep trying until the same game is
|
|
|
|
// not shown again.
|
2020-06-23 18:07:00 +00:00
|
|
|
if (mImageCount > 0) {
|
2020-07-28 09:10:14 +00:00
|
|
|
do {
|
2020-09-18 16:40:22 +00:00
|
|
|
int image = static_cast<int>((static_cast<float>(rand()) /
|
|
|
|
static_cast<float>(RAND_MAX)) * static_cast<float>(mImageCount));
|
2020-07-28 09:10:14 +00:00
|
|
|
pickGameListNode(image, "image", path);
|
|
|
|
}
|
|
|
|
while (mPreviousGame && mCurrentGame == mPreviousGame);
|
2020-06-23 18:07:00 +00:00
|
|
|
}
|
2017-09-09 03:45:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SystemScreenSaver::pickRandomCustomImage(std::string& path)
|
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
std::string imageDir = Settings::getInstance()->getString("SlideshowScreenSaverImageDir");
|
|
|
|
|
|
|
|
if ((imageDir != "") && (Utils::FileSystem::exists(imageDir))) {
|
|
|
|
std::string imageFilter = Settings::getInstance()->
|
|
|
|
getString("SlideshowScreenSaverImageFilter");
|
|
|
|
std::vector<std::string> matchingFiles;
|
|
|
|
Utils::FileSystem::stringList dirContent = Utils::FileSystem::getDirContent(
|
|
|
|
imageDir, Settings::getInstance()->getBool("SlideshowScreenSaverRecurse"));
|
|
|
|
|
|
|
|
for (Utils::FileSystem::stringList::const_iterator it = dirContent.cbegin();
|
|
|
|
it != dirContent.cend(); ++it) {
|
|
|
|
if (Utils::FileSystem::isRegularFile(*it)) {
|
|
|
|
// If the image filter is empty, or the file extension is in the filter
|
|
|
|
// string, add it to the matching files list.
|
|
|
|
if ((imageFilter.length() <= 0) || (imageFilter.find(
|
|
|
|
Utils::FileSystem::getExtension(*it)) != std::string::npos))
|
|
|
|
matchingFiles.push_back(*it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-18 16:40:22 +00:00
|
|
|
int fileCount = static_cast<int>(matchingFiles.size());
|
2020-06-23 18:07:00 +00:00
|
|
|
if (fileCount > 0) {
|
|
|
|
// Get a random index in the range 0 to fileCount (exclusive).
|
|
|
|
int randomIndex = rand() % fileCount;
|
|
|
|
path = matchingFiles[randomIndex];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
LOG(LogError) << "Slideshow Screensaver - No image files found\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
LOG(LogError) << "Slideshow Screensaver - Image directory does not exist: " <<
|
|
|
|
imageDir << "\n";
|
|
|
|
}
|
2017-09-09 03:45:50 +00:00
|
|
|
}
|
|
|
|
|
2016-12-14 08:30:54 +00:00
|
|
|
void SystemScreenSaver::update(int deltaTime)
|
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
// Use this to update the fade value for the current fade stage.
|
|
|
|
if (mState == STATE_FADE_OUT_WINDOW) {
|
2020-09-18 16:40:22 +00:00
|
|
|
mOpacity += static_cast<float>(deltaTime) / FADE_TIME;
|
2020-06-23 18:07:00 +00:00
|
|
|
if (mOpacity >= 1.0f) {
|
|
|
|
mOpacity = 1.0f;
|
|
|
|
|
|
|
|
// Update to the next state.
|
|
|
|
mState = STATE_FADE_IN_VIDEO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (mState == STATE_FADE_IN_VIDEO) {
|
2020-09-18 16:40:22 +00:00
|
|
|
mOpacity -= static_cast<float>(deltaTime) / FADE_TIME;
|
2020-06-23 18:07:00 +00:00
|
|
|
if (mOpacity <= 0.0f) {
|
|
|
|
mOpacity = 0.0f;
|
|
|
|
// Update to the next state.
|
|
|
|
mState = STATE_SCREENSAVER_ACTIVE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (mState == STATE_SCREENSAVER_ACTIVE) {
|
|
|
|
// Update the timer that swaps the videos.
|
|
|
|
mTimer += deltaTime;
|
|
|
|
if (mTimer > mVideoChangeTime)
|
2020-07-28 09:10:14 +00:00
|
|
|
nextGame();
|
2020-06-23 18:07:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// If we have a loaded video then update it.
|
|
|
|
if (mVideoScreensaver)
|
|
|
|
mVideoScreensaver->update(deltaTime);
|
|
|
|
if (mImageScreensaver)
|
|
|
|
mImageScreensaver->update(deltaTime);
|
2016-12-14 08:30:54 +00:00
|
|
|
}
|
2017-06-01 20:08:44 +00:00
|
|
|
|
2020-07-28 09:10:14 +00:00
|
|
|
void SystemScreenSaver::nextGame() {
|
2020-06-23 18:07:00 +00:00
|
|
|
mStopBackgroundAudio = false;
|
|
|
|
stopScreenSaver();
|
|
|
|
startScreenSaver();
|
|
|
|
mState = STATE_SCREENSAVER_ACTIVE;
|
2017-06-01 20:08:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
FileData* SystemScreenSaver::getCurrentGame()
|
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
return mCurrentGame;
|
2017-06-01 20:08:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SystemScreenSaver::launchGame()
|
|
|
|
{
|
2020-06-23 18:07:00 +00:00
|
|
|
if (mCurrentGame != nullptr) {
|
|
|
|
// Launching game
|
|
|
|
ViewController::get()->goToGameList(mCurrentGame->getSystem());
|
|
|
|
IGameListView* view = ViewController::get()->
|
|
|
|
getGameListView(mCurrentGame->getSystem()).get();
|
|
|
|
view->setCursor(mCurrentGame);
|
2020-09-18 16:40:22 +00:00
|
|
|
ViewController::get()->resetMovingCamera();
|
|
|
|
ViewController::get()->launch(mCurrentGame);
|
2020-06-23 18:07:00 +00:00
|
|
|
}
|
2017-08-02 19:56:33 +00:00
|
|
|
}
|