diff --git a/USERGUIDE.md b/USERGUIDE.md index 26b7dab6b..414db03e0 100644 --- a/USERGUIDE.md +++ b/USERGUIDE.md @@ -914,7 +914,7 @@ There is a screensaver built into ES with four different behaviours: _Dim_, _Bla There are numerous options for the screensaver, refer to the Main menu section above to find out about them. -The _Dim_ screensaver simply dims the current view and _Black_ will show a black screen. The _Slideshow_ and _Video_ screensavers are a bit more interesting as they can display images and videos from your game collection. (In addition to this, Slideshow can be configured to only show images from a specified directory). +The _Dim_ screensaver simply dims and desaturates the current view and _Black_ will show a black screen. The _Slideshow_ and _Video_ screensavers are a bit more interesting as they can display images and videos from your game collection. (In addition to this, Slideshow can be configured to only show images from a specified directory). If the option **Screensaver controls** has been activated, you can manually toggle the screensaver from the system view by pressing the 'Select' key. In addition to this the controls will allow you to jump to a new random image video or by using the left and right buttons on your keyboard or controller, and it allows you to actually launch the game just shown by pressing the 'A' button. diff --git a/es-app/src/views/gamelist/DetailedGameListView.cpp b/es-app/src/views/gamelist/DetailedGameListView.cpp index 50bf51310..ebbb07c1f 100644 --- a/es-app/src/views/gamelist/DetailedGameListView.cpp +++ b/es-app/src/views/gamelist/DetailedGameListView.cpp @@ -1,4 +1,6 @@ +// SPDX-License-Identifier: MIT // +// EmulationStation Desktop Edition // DetailedGameListView.cpp // // Interface that defines a GameListView of the type 'detailed'. @@ -54,7 +56,7 @@ DetailedGameListView::DetailedGameListView( mThumbnail.setOrigin(0.5f, 0.5f); mThumbnail.setPosition(2.0f, 2.0f); mThumbnail.setVisible(false); - mThumbnail.setMaxSize(mSize.x() * (0.25f - 2*padding), mSize.y() * 0.10f); + mThumbnail.setMaxSize(mSize.x() * (0.25f - 2 * padding), mSize.y() * 0.10f); mThumbnail.setDefaultZIndex(25); addChild(&mThumbnail); @@ -63,14 +65,14 @@ DetailedGameListView::DetailedGameListView( // Default to off the screen. mMarquee.setPosition(2.0f, 2.0f); mMarquee.setVisible(false); - mMarquee.setMaxSize(mSize.x() * (0.5f - 2*padding), mSize.y() * 0.18f); + mMarquee.setMaxSize(mSize.x() * (0.5f - 2 * padding), mSize.y() * 0.18f); mMarquee.setDefaultZIndex(35); addChild(&mMarquee); // Image. mImage.setOrigin(0.5f, 0.5f); mImage.setPosition(mSize.x() * 0.25f, mList.getPosition().y() + mSize.y() * 0.2125f); - mImage.setMaxSize(mSize.x() * (0.50f - 2*padding), mSize.y() * 0.4f); + mImage.setMaxSize(mSize.x() * (0.50f - 2 * padding), mSize.y() * 0.4f); mImage.setDefaultZIndex(30); addChild(&mImage); @@ -109,7 +111,7 @@ DetailedGameListView::DetailedGameListView( addChild(&mName); mDescContainer.setPosition(mSize.x() * padding, mSize.y() * 0.65f); - mDescContainer.setSize(mSize.x() * (0.50f - 2*padding), mSize.y() - + mDescContainer.setSize(mSize.x() * (0.50f - 2 * padding), mSize.y() - mDescContainer.getPosition().y()); mDescContainer.setAutoScroll(true); mDescContainer.setDefaultZIndex(40); @@ -173,7 +175,7 @@ void DetailedGameListView::initMDLabels() std::vector components = getMDLabels(); const unsigned int colCount = 2; - const unsigned int rowCount = (int)(components.size() / 2); + const unsigned int rowCount = static_cast(components.size() / 2); Vector3f start(mSize.x() * 0.01f, mSize.y() * 0.625f, 0.0f); @@ -204,7 +206,7 @@ void DetailedGameListView::initMDValues() std::vector values = getMDValues(); std::shared_ptr defaultFont = Font::get(FONT_SIZE_SMALL); - mRating.setSize(defaultFont->getHeight() * 5.0f, (float)defaultFont->getHeight()); + mRating.setSize(defaultFont->getHeight() * 5.0f, static_cast(defaultFont->getHeight())); mReleaseDate.setFont(defaultFont); mDeveloper.setFont(defaultFont); mPublisher.setFont(defaultFont); @@ -297,8 +299,8 @@ void DetailedGameListView::updateInfoPanel() // Fade in the game image. auto func = [this](float t) { - mImage.setOpacity((unsigned char)(Math::lerp( - static_cast(FADE_IN_START_OPACITY), 1.0f, t)*255)); + mImage.setOpacity(static_cast(Math::lerp( + static_cast(FADE_IN_START_OPACITY), 1.0f, t) * 255)); }; mImage.setAnimation(new LambdaAnimation(func, FADE_IN_TIME), 0, nullptr, false); @@ -346,7 +348,7 @@ void DetailedGameListView::updateInfoPanel() if ((comp->isAnimationPlaying(0) && comp->isAnimationReversed(0) != fadingOut) || (!comp->isAnimationPlaying(0) && comp->getOpacity() != (fadingOut ? 0 : 255))) { auto func = [comp](float t) { - comp->setOpacity((unsigned char)(Math::lerp(0.0f, 1.0f, t)*255)); + comp->setOpacity(static_cast(Math::lerp(0.0f, 1.0f, t) * 255)); }; comp->setAnimation(new LambdaAnimation(func, 150), 0, nullptr, fadingOut); } diff --git a/es-app/src/views/gamelist/DetailedGameListView.h b/es-app/src/views/gamelist/DetailedGameListView.h index 03a9c59ac..a5e446958 100644 --- a/es-app/src/views/gamelist/DetailedGameListView.h +++ b/es-app/src/views/gamelist/DetailedGameListView.h @@ -1,4 +1,6 @@ +// SPDX-License-Identifier: MIT // +// EmulationStation Desktop Edition // DetailedGameListView.h // // Interface that defines a GameListView of the type 'detailed'. diff --git a/es-app/src/views/gamelist/VideoGameListView.cpp b/es-app/src/views/gamelist/VideoGameListView.cpp index f0ba12745..c646c2317 100644 --- a/es-app/src/views/gamelist/VideoGameListView.cpp +++ b/es-app/src/views/gamelist/VideoGameListView.cpp @@ -1,4 +1,6 @@ +// SPDX-License-Identifier: MIT // +// EmulationStation Desktop Edition // VideoGameListView.cpp // // Interface that defines a GameListView of the type 'video'. @@ -17,6 +19,9 @@ #include "Settings.h" #endif +#define FADE_IN_START_OPACITY 0.5f +#define FADE_IN_TIME 650 + VideoGameListView::VideoGameListView( Window* window, FileData* root) @@ -70,21 +75,21 @@ VideoGameListView::VideoGameListView( mThumbnail.setOrigin(0.5f, 0.5f); mThumbnail.setPosition(2.0f, 2.0f); mThumbnail.setVisible(false); - mThumbnail.setMaxSize(mSize.x() * (0.25f - 2*padding), mSize.y() * 0.10f); + mThumbnail.setMaxSize(mSize.x() * (0.25f - 2 * padding), mSize.y() * 0.10f); mThumbnail.setDefaultZIndex(35); addChild(&mThumbnail); // Marquee. mMarquee.setOrigin(0.5f, 0.5f); mMarquee.setPosition(mSize.x() * 0.25f, mSize.y() * 0.10f); - mMarquee.setMaxSize(mSize.x() * (0.5f - 2*padding), mSize.y() * 0.18f); + mMarquee.setMaxSize(mSize.x() * (0.5f - 2 * padding), mSize.y() * 0.18f); mMarquee.setDefaultZIndex(35); addChild(&mMarquee); // Video. mVideo->setOrigin(0.5f, 0.5f); mVideo->setPosition(mSize.x() * 0.25f, mSize.y() * 0.4f); - mVideo->setSize(mSize.x() * (0.5f - 2*padding), mSize.y() * 0.4f); + mVideo->setSize(mSize.x() * (0.5f - 2 * padding), mSize.y() * 0.4f); mVideo->setDefaultZIndex(30); addChild(mVideo); @@ -123,7 +128,7 @@ VideoGameListView::VideoGameListView( addChild(&mName); mDescContainer.setPosition(mSize.x() * padding, mSize.y() * 0.65f); - mDescContainer.setSize(mSize.x() * (0.50f - 2*padding), mSize.y() - + mDescContainer.setSize(mSize.x() * (0.50f - 2 * padding), mSize.y() - mDescContainer.getPosition().y()); mDescContainer.setAutoScroll(true); mDescContainer.setDefaultZIndex(40); @@ -193,7 +198,7 @@ void VideoGameListView::initMDLabels() std::vector components = getMDLabels(); const unsigned int colCount = 2; - const unsigned int rowCount = (int)(components.size() / 2); + const unsigned int rowCount = static_cast(components.size() / 2); Vector3f start(mSize.x() * 0.01f, mSize.y() * 0.625f, 0.0f); @@ -224,7 +229,7 @@ void VideoGameListView::initMDValues() std::vector values = getMDValues(); std::shared_ptr defaultFont = Font::get(FONT_SIZE_SMALL); - mRating.setSize(defaultFont->getHeight() * 5.0f, (float)defaultFont->getHeight()); + mRating.setSize(defaultFont->getHeight() * 5.0f, static_cast(defaultFont->getHeight())); mReleaseDate.setFont(defaultFont); mDeveloper.setFont(defaultFont); mPublisher.setFont(defaultFont); @@ -308,21 +313,25 @@ void VideoGameListView::updateInfoPanel() bool fadingOut; if (file == nullptr) { - mVideo->setVideo(""); - mVideo->setImage(""); mVideoPlaying = false; fadingOut = true; - } else { + mThumbnail.setImage(file->getThumbnailPath()); + mMarquee.setImage(file->getMarqueePath()); + mVideo->setImage(file->getImagePath()); + if (!mVideo->setVideo(file->getVideoPath())) mVideo->setDefaultVideo(); mVideoPlaying = true; - mVideo->setImage(file->getImagePath()); - mThumbnail.setImage(file->getThumbnailPath()); - mMarquee.setImage(file->getMarqueePath()); + // Fade in the game image. + auto func = [this](float t) { + mVideo->setOpacity((unsigned char)(Math::lerp( + static_cast(FADE_IN_START_OPACITY), 1.0f, t) * 255)); + }; + mVideo->setAnimation(new LambdaAnimation(func, FADE_IN_TIME), 0, nullptr, false); mDescription.setText(file->metadata.get("desc")); mDescContainer.reset(); @@ -357,29 +366,28 @@ void VideoGameListView::updateInfoPanel() comps.push_back(&mMarquee); comps.push_back(mVideo); comps.push_back(&mDescription); - comps.push_back(&mImage); comps.push_back(&mName); std::vector labels = getMDLabels(); comps.insert(comps.cend(), labels.cbegin(), labels.cend()); for (auto it = comps.cbegin(); it != comps.cend(); it++) { GuiComponent* comp = *it; - // An animation is playing, then animate if reverse != fadingOut + // An animation is playing, then animate if reverse != fadingOut. // An animation is not playing, then animate if opacity != our target opacity if ((comp->isAnimationPlaying(0) && comp->isAnimationReversed(0) != fadingOut) || (!comp->isAnimationPlaying(0) && comp->getOpacity() != (fadingOut ? 0 : 255))) { auto func = [comp](float t) { - comp->setOpacity((unsigned char)(Math::lerp(0.0f, 1.0f, t)*255)); + comp->setOpacity(static_cast(Math::lerp(0.0f, 1.0f, t) * 255)); }; - comp->setAnimation(new LambdaAnimation(func, 150), 0, nullptr, fadingOut); + comp->setAnimation(new LambdaAnimation(func, 200), 0, nullptr, fadingOut); } } } void VideoGameListView::launch(FileData* game) { - float screenWidth = (float) Renderer::getScreenWidth(); - float screenHeight = (float) Renderer::getScreenHeight(); + float screenWidth = static_cast(Renderer::getScreenWidth()); + float screenHeight = static_cast(Renderer::getScreenHeight()); Vector3f target(screenWidth / 2.0f, screenHeight / 2.0f, 0); diff --git a/es-app/src/views/gamelist/VideoGameListView.h b/es-app/src/views/gamelist/VideoGameListView.h index 1a1e19e45..24fe026dd 100644 --- a/es-app/src/views/gamelist/VideoGameListView.h +++ b/es-app/src/views/gamelist/VideoGameListView.h @@ -1,4 +1,6 @@ +// SPDX-License-Identifier: MIT // +// EmulationStation Desktop Edition // VideoGameListView.h // // Interface that defines a GameListView of the type 'video'. diff --git a/es-core/src/components/VideoComponent.cpp b/es-core/src/components/VideoComponent.cpp index ed92f4f60..8e89958d1 100644 --- a/es-core/src/components/VideoComponent.cpp +++ b/es-core/src/components/VideoComponent.cpp @@ -16,9 +16,7 @@ #include -#define FADE_IN_START_OPACITY 0.5f -#define FADE_IN_TIME 1300 -#define FADE_OUT_TIME 100 +#define SCREENSAVER_FADE_IN_TIME 800 std::string getTitlePath() { std::string titleFolder = getTitleFolder(); @@ -147,7 +145,6 @@ void VideoComponent::setImage(std::string path) return; mStaticImage.setImage(path); - mFadeIn = FADE_IN_START_OPACITY; mStaticImagePath = path; } @@ -158,8 +155,8 @@ void VideoComponent::setDefaultVideo() void VideoComponent::setOpacity(unsigned char opacity) { - // Update the embeded static image. - mStaticImage.setOpacity(opacity); + // Set the opacity for the embedded static image. + mOpacity = opacity; } void VideoComponent::render(const Transform4x4f& parentTrans) @@ -189,7 +186,7 @@ void VideoComponent::renderSnapshot(const Transform4x4f& parentTrans) if ((mConfig.showSnapshotNoVideo && mVideoPath.empty()) || (mStartDelayed && mConfig.showSnapshotDelay)) { // Display the static image instead. - mStaticImage.setOpacity(static_cast(mFadeIn * 255.0f)); + mStaticImage.setOpacity(mOpacity); mStaticImage.render(parentTrans); } } @@ -282,7 +279,6 @@ void VideoComponent::startVideoWithDelay() else { // Configure the start delay. mStartDelayed = true; - mFadeIn = FADE_IN_START_OPACITY; mStartTime = SDL_GetTicks() + mConfig.startDelay; } mIsPlaying = true; @@ -298,20 +294,11 @@ void VideoComponent::update(int deltaTime) manageState(); - // If the video start is delayed and there is less than the fade time, then set - // the image fade accordingly. - if (mStartDelayed) { - Uint32 ticks = SDL_GetTicks(); - if (mStartTime > ticks) { - Uint32 diff = mStartTime - ticks; - if (diff < FADE_OUT_TIME) { - mFadeIn = static_cast(diff) / static_cast(FADE_OUT_TIME); - return; - } - } - } + // This is only used to fade in the screensaver, fade-in of the static image is + // handled using a lambda animation in VideoGameListView. if (mFadeIn < 1.0f) - mFadeIn = Math::clamp(mFadeIn + (deltaTime / static_cast(FADE_IN_TIME)), 0.0, 1.0); + mFadeIn = Math::clamp(mFadeIn + (deltaTime / + static_cast(SCREENSAVER_FADE_IN_TIME)), 0.0, 1.0); GuiComponent::update(deltaTime); } @@ -383,7 +370,6 @@ void VideoComponent::onScreenSaverActivate() void VideoComponent::onScreenSaverDeactivate() { mBlockPlayer = false; -// mPause = false; // Stop video when deactivating the screensaver to force a reload of the // static image (if the theme is configured as such). stopVideo(); diff --git a/es-core/src/components/VideoComponent.h b/es-core/src/components/VideoComponent.h index 57a1d0335..bcff577ac 100644 --- a/es-core/src/components/VideoComponent.h +++ b/es-core/src/components/VideoComponent.h @@ -106,7 +106,7 @@ protected: unsigned mVideoHeight; Vector2f mTargetSize; std::shared_ptr mTexture; - float mFadeIn; + float mFadeIn; // Used for fading in the video screensaver. std::string mStaticImagePath; ImageComponent mStaticImage;