Improvements to the screensaver and game overlay.

Also added functionality to jump to a game from the screensaver (without launching it).
This commit is contained in:
Leon Styhre 2020-11-12 17:13:24 +01:00
parent 9bea6bb17e
commit 00ba2e78ab
10 changed files with 96 additions and 41 deletions

View file

@ -116,7 +116,7 @@ Jumps to the first and last entry of the gamelists, menus and text edit dialogs.
**A button**\
_(Enter)_
Select button to open gamelists from the systems view, start games, choose menu entries etc.
Select button to open gamelists from the systems view, launch games, choose menu entries etc.
**B button**\
_(Back key)_
@ -131,7 +131,7 @@ Selects random games and systems.
**Y button**\
_(Insert on Unix and Windows, F13 on macOS)_
Marks games as favorites in the gamelist views. Used by some other minor functions as explained by the help system.
Marks games as favorites in the gamelist views. Used by some other minor functions as explained by the help system and this guide.
## Getting your games into EmulationStation
@ -679,7 +679,7 @@ The screensaven type to use; _Dim_, _Black_, _Slideshow_ or _Video_.
**Enable screensaver controls**
This includes the ability to start the screensaver manually, but also to browse Left and Right between images or videos, and to launch the game shown by the screensaver using the A button.
This includes the ability to start the screensaver manually, but also to jump to a new random game using the Left and Right buttons, to launch the game currently shown using the A button and to jump to the game in its gamelist by using the Y button. If this setting is disabled, any key or button press will stop the screensaver.
#### Slideshow screensaver settings
@ -687,7 +687,7 @@ Options specific to the slideshow screensaver.
**Swap images after (seconds)**
For how long to display images before changing to the next game. Allowed range is between 5 and 120 seconds.
For how long to display images before changing to the next game. Allowed range is between 2 and 120 seconds in 2-second increments. The default value is 10 seconds.
**Stretch images to screen resolution**
@ -719,7 +719,7 @@ Options specific to the video screensaver.
**Swap videos after (seconds)**
For how long to play videos before changing to the next game. Allowed range is between 5 and 120 seconds.
For how long to play videos before changing to the next game. Allowed range is between 0 and 120 seconds in 2-second increments. If set to 0 (which is the default setting), the next game will be selected when the entire video has finished playing.
**Play audio for screensaver videos**
@ -1060,7 +1060,7 @@ There are numerous options for the screensaver, refer to the Main menu section a
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.
If the option **Enable 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 or video using the left and right buttons on your keyboard or controller. It's also possible to launch the game currently displayed by pressing the 'A' button, and pressing the 'Y' button will jump to the game in its gamelist without starting it.
## Game collections

View file

@ -42,7 +42,8 @@ SystemScreensaver::SystemScreensaver(
mCurrentGame(nullptr),
mPreviousGame(nullptr),
mTimer(0),
mVideoChangeTime(30000),
mMediaSwapTime(0),
mTriggerNextGame(false),
mHasMediaFiles(false),
mOpacity(0.0f),
mDimValue(1.0),
@ -98,7 +99,7 @@ void SystemScreensaver::startScreensaver(bool generateMediaList)
// This creates a fade transition between the images.
mState = STATE_FADE_OUT_WINDOW;
mVideoChangeTime = Settings::getInstance()->getInt("ScreensaverSwapImageTimeout");
mMediaSwapTime = Settings::getInstance()->getInt("ScreensaverSwapImageTimeout");
// Load a random image.
if (Settings::getInstance()->getBool("ScreensaverSlideshowCustomImages")) {
@ -155,7 +156,7 @@ void SystemScreensaver::startScreensaver(bool generateMediaList)
// This creates a fade transition between the videos.
mState = STATE_FADE_OUT_WINDOW;
mVideoChangeTime = Settings::getInstance()->getInt("ScreensaverSwapVideoTimeout");
mMediaSwapTime = Settings::getInstance()->getInt("ScreensaverSwapVideoTimeout");
// Load a random video.
if (generateMediaList)
@ -241,6 +242,18 @@ void SystemScreensaver::launchGame()
}
}
void SystemScreensaver::goToGame()
{
if (mCurrentGame != nullptr) {
// Go to the game in the gamelist view, but don't launch it.
ViewController::get()->goToGameList(mCurrentGame->getSystem());
IGameListView* view = ViewController::get()->
getGameListView(mCurrentGame->getSystem()).get();
view->setCursor(mCurrentGame);
ViewController::get()->resetMovingCamera();
}
}
void SystemScreensaver::renderScreensaver()
{
std::string screensaverType = Settings::getInstance()->getString("ScreensaverType");
@ -290,7 +303,7 @@ void SystemScreensaver::renderScreensaver()
0x00000000 | mRectangleFadeIn );
}
if (mRectangleFadeIn < 180)
mRectangleFadeIn = Math::clamp(mRectangleFadeIn + 4, 0, 255);
mRectangleFadeIn = Math::clamp(mRectangleFadeIn + 6, 0, 255);
mGameOverlay.get()->setColor(0xFFFFFF00 | mTextFadeIn);
mGameOverlayFont.at(0)->renderTextCache(mGameOverlay.get());
@ -331,7 +344,7 @@ void SystemScreensaver::renderScreensaver()
0x00000000 | mRectangleFadeIn );
}
if (mRectangleFadeIn < 180)
mRectangleFadeIn = Math::clamp(mRectangleFadeIn + 4, 0, 255);
mRectangleFadeIn = Math::clamp(mRectangleFadeIn + 6, 0, 255);
mGameOverlay.get()->setColor(0xFFFFFF00 | mTextFadeIn);
mGameOverlayFont.at(0)->renderTextCache(mGameOverlay.get());
@ -406,13 +419,21 @@ void SystemScreensaver::update(int deltaTime)
}
}
else if (mState == STATE_SCREENSAVER_ACTIVE) {
// Update the timer that swaps the videos.
// Update the timer that swaps the media, unless the swap time is set to 0 (only
// applicable for the video screensaver). This means that videos play to the end,
// at which point VideoVlcComponent will trigger a skip to the next game.
if (mMediaSwapTime != 0) {
mTimer += deltaTime;
if (mTimer > mVideoChangeTime)
if (mTimer > mMediaSwapTime)
nextGame();
}
if (mTriggerNextGame) {
mTriggerNextGame = false;
nextGame();
}
}
// If we have a loaded video then update it.
// If we have a loaded a video or image, then update it.
if (mVideoScreensaver)
mVideoScreensaver->update(deltaTime);
if (mImageScreensaver)
@ -571,10 +592,14 @@ void SystemScreensaver::generateOverlayInfo()
if (mGameName == "" || mSystemName == "")
return;
float posX = static_cast<float>(Renderer::getWindowWidth()) * 0.03;
float posY = static_cast<float>(Renderer::getWindowHeight()) * 0.87;
float posX = static_cast<float>(Renderer::getWindowWidth()) * 0.023;
float posY = static_cast<float>(Renderer::getWindowHeight()) * 0.02;
const std::string gameName = Utils::String::toUpper(mGameName);
std::string favoriteChar;
if (mCurrentGame->getFavorite())
favoriteChar = " " + mCurrentGame->FAVORITE_CHAR;
const std::string gameName = Utils::String::toUpper(mGameName) + favoriteChar;
const std::string systemName = Utils::String::toUpper(mSystemName);
const std::string overlayText = gameName + "\n" + systemName;

View file

@ -29,11 +29,13 @@ public:
virtual void stopScreensaver();
virtual void nextGame();
virtual void launchGame();
virtual void goToGame();
virtual void renderScreensaver();
virtual void update(int deltaTime);
virtual FileData* getCurrentGame() { return mCurrentGame; };
virtual void triggerNextGame() { mTriggerNextGame = true; };
private:
void generateImageList();
@ -67,7 +69,8 @@ private:
std::string mSystemName;
int mTimer;
int mVideoChangeTime;
int mMediaSwapTime;
bool mTriggerNextGame;
bool mHasMediaFiles;
float mOpacity;
float mDimValue;

View file

@ -101,7 +101,7 @@ void GuiScreensaverOptions::openSlideshowScreensaverOptions()
// Timer for swapping images (in seconds).
auto screensaver_swap_image_timeout =
std::make_shared<SliderComponent>(mWindow, 5.f, 120.f, 1.f, "s");
std::make_shared<SliderComponent>(mWindow, 2.f, 120.f, 2.f, "s");
screensaver_swap_image_timeout->setValue(static_cast<float>(Settings::getInstance()->
getInt("ScreensaverSwapImageTimeout") / (1000)));
s->addWithLabel("SWAP IMAGES AFTER (SECONDS)", screensaver_swap_image_timeout);
@ -213,7 +213,7 @@ void GuiScreensaverOptions::openVideoScreensaverOptions()
// Timer for swapping videos (in seconds).
auto screensaver_swap_video_timeout =
std::make_shared<SliderComponent>(mWindow, 5.f, 120.f, 1.f, "s");
std::make_shared<SliderComponent>(mWindow, 0.f, 120.f, 2.f, "s");
screensaver_swap_video_timeout->setValue(static_cast<float>(Settings::getInstance()->
getInt("ScreensaverSwapVideoTimeout") / (1000)));
s->addWithLabel("SWAP VIDEOS AFTER (SECONDS)", screensaver_swap_video_timeout);

View file

@ -128,7 +128,7 @@ void Settings::setDefaults()
mBoolMap["ScreensaverControls"] = true;
// UI settings -> screensaver settings -> slideshow screensaver settings.
mIntMap["ScreensaverSwapImageTimeout"] = 8000;
mIntMap["ScreensaverSwapImageTimeout"] = 10000;
mBoolMap["ScreensaverStretchImages"] = false;
mBoolMap["ScreensaverSlideshowGameInfo"] = true;
mBoolMap["ScreensaverSlideshowScanlines"] = true;
@ -138,7 +138,7 @@ void Settings::setDefaults()
"~/.emulationstation/slideshow/custom_images";
// UI settings -> screensaver settings -> video screensaver settings.
mIntMap["ScreensaverSwapVideoTimeout"] = 25000;
mIntMap["ScreensaverSwapVideoTimeout"] = 0;
mBoolMap["ScreensaverVideoAudio"] = false;
mBoolMap["ScreensaverStretchVideos"] = false;
mBoolMap["ScreensaverVideoGameInfo"] = true;

View file

@ -12,6 +12,7 @@
#include "components/HelpComponent.h"
#include "components/ImageComponent.h"
#include "resources/Font.h"
#include "Sound.h"
#include "InputManager.h"
#include "Log.h"
#include "Scripting.h"
@ -154,7 +155,7 @@ void Window::input(InputConfig* config, Input input)
customImageSlideshow = true;
if ((customImageSlideshow || mScreensaver->getCurrentGame() != nullptr) &&
(config->isMappedTo("a", input) ||
(config->isMappedTo("a", input) || config->isMappedTo("y", input) ||
config->isMappedLike("left", input) || config->isMappedLike("right", input))) {
// Left or right browses to the next video or image.
if (config->isMappedLike("left", input) || config->isMappedLike("right", input)) {
@ -166,18 +167,26 @@ void Window::input(InputConfig* config, Input input)
}
else if (config->isMappedTo("a", input) && input.value != 0) {
// Launch game.
cancelScreensaver();
stopScreensaver();
mScreensaver->launchGame();
// To force handling the wake up process.
mSleeping = true;
}
else if (config->isMappedTo("y", input) && input.value != 0) {
// Jump to the game in its gamelist, but do not launch it.
stopScreensaver();
NavigationSounds::getInstance()->playThemeNavigationSound(SCROLLSOUND);
mScreensaver->goToGame();
// To force handling the wake up process.
mSleeping = true;
}
}
}
}
if (mSleeping) {
// Wake up.
cancelScreensaver();
stopScreensaver();
mSleeping = false;
onWake();
return;
@ -185,7 +194,7 @@ void Window::input(InputConfig* config, Input input)
// Any keypress cancels the screensaver.
if (input.value != 0 && isScreensaverActive()) {
cancelScreensaver();
stopScreensaver();
return;
}
@ -590,7 +599,7 @@ void Window::startScreensaver()
}
}
bool Window::cancelScreensaver()
bool Window::stopScreensaver()
{
if (mScreensaver && mRenderScreensaver) {
mScreensaver->stopScreensaver();

View file

@ -33,15 +33,20 @@ public:
class Screensaver
{
public:
virtual bool allowSleep() = 0;
virtual bool isScreensaverActive() = 0;
virtual void startScreensaver(bool generateMediaList) = 0;
virtual void stopScreensaver() = 0;
virtual void nextGame() = 0;
virtual void renderScreensaver() = 0;
virtual bool allowSleep() = 0;
virtual void update(int deltaTime) = 0;
virtual bool isScreensaverActive() = 0;
virtual FileData* getCurrentGame() = 0;
virtual void launchGame() = 0;
virtual void goToGame() = 0;
virtual void renderScreensaver() = 0;
virtual void update(int deltaTime) = 0;
virtual FileData* getCurrentGame() = 0;
virtual void triggerNextGame() = 0;
};
class InfoPopup
@ -84,10 +89,11 @@ public:
void setInfoPopup(InfoPopup* infoPopup) { delete mInfoPopup; mInfoPopup = infoPopup; }
inline void stopInfoPopup() { if (mInfoPopup) mInfoPopup->stop(); };
void startScreensaver();
bool cancelScreensaver();
void renderScreensaver();
bool isScreensaverActive() { return mRenderScreensaver; };
void startScreensaver();
bool stopScreensaver();
void renderScreensaver();
void screensaverTriggerNextGame() { mScreensaver->triggerNextGame(); };
void setLaunchedGame();
void unsetLaunchedGame();

View file

@ -26,6 +26,7 @@ void VideoComponent::setScreensaverMode(bool isScreensaver)
VideoComponent::VideoComponent(
Window* window)
: GuiComponent(window),
mWindow(window),
mStaticImage(window),
mVideoHeight(0),
mVideoWidth(0),

View file

@ -100,6 +100,7 @@ private:
void manageState();
protected:
Window* mWindow;
unsigned mVideoWidth;
unsigned mVideoHeight;
Vector2f mTargetSize;

View file

@ -13,6 +13,7 @@
#include "utils/StringUtil.h"
#include "PowerSaver.h"
#include "Settings.h"
#include "Window.h"
#if defined(__APPLE__)
#include "utils/FileSystemUtil.h"
@ -234,16 +235,25 @@ void VideoVlcComponent::handleLooping()
if (mIsPlaying && mMediaPlayer) {
libvlc_state_t state = libvlc_media_player_get_state(mMediaPlayer);
if (state == libvlc_Ended) {
// If the screensaver video swap time is set to 0, it means we should
// skip to the next game when the video has finished playing.
if (mScreensaverMode &&
Settings::getInstance()->getInt("ScreensaverSwapVideoTimeout") == 0) {
mWindow->screensaverTriggerNextGame();
}
else {
libvlc_media_player_set_media(mMediaPlayer, mMedia);
if ((!Settings::getInstance()->getBool("GamelistVideoAudio") && !mScreensaverMode) ||
(!Settings::getInstance()->getBool("ScreensaverVideoAudio") && mScreensaverMode))
if ((!Settings::getInstance()->getBool("GamelistVideoAudio") &&
!mScreensaverMode) || (!Settings::getInstance()->
getBool("ScreensaverVideoAudio") && mScreensaverMode))
libvlc_audio_set_mute(mMediaPlayer, 1);
libvlc_media_player_play(mMediaPlayer);
}
}
}
}
void VideoVlcComponent::pauseVideo()
{