Added a fullscreen game media viewer.

This commit is contained in:
Leon Styhre 2021-05-16 13:12:31 +02:00
parent 282d2fa445
commit 3ed17fbea2
17 changed files with 637 additions and 46 deletions

View file

@ -7,6 +7,7 @@ set(ES_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/FileFilterIndex.h
${CMAKE_CURRENT_SOURCE_DIR}/src/FileSorts.h
${CMAKE_CURRENT_SOURCE_DIR}/src/Gamelist.h
${CMAKE_CURRENT_SOURCE_DIR}/src/MediaViewer.h
${CMAKE_CURRENT_SOURCE_DIR}/src/MetaData.h
${CMAKE_CURRENT_SOURCE_DIR}/src/PlatformId.h
${CMAKE_CURRENT_SOURCE_DIR}/src/SystemData.h
@ -19,6 +20,7 @@ set(ES_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGamelistOptions.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGameScraper.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiInfoPopup.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMediaViewerOptions.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMenu.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMetaDataEd.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperMenu.h
@ -55,6 +57,7 @@ set(ES_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/FileSorts.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/Gamelist.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/MediaViewer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/MetaData.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/PlatformId.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/SystemData.cpp
@ -68,6 +71,7 @@ set(ES_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGameScraper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiInfoPopup.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMenu.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMediaViewerOptions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMetaDataEd.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperMenu.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperMulti.cpp

282
es-app/src/MediaViewer.cpp Normal file
View file

@ -0,0 +1,282 @@
// SPDX-License-Identifier: MIT
//
// EmulationStation Desktop Edition
// MediaViewer.cpp
//
// Fullscreen game media viewer.
//
#include "MediaViewer.h"
#include "components/VideoFFmpegComponent.h"
#include "components/VideoVlcComponent.h"
#include "views/ViewController.h"
#include "AudioManager.h"
#include "Sound.h"
MediaViewer::MediaViewer(Window* window) : mWindow(window), mVideo(nullptr), mImage(nullptr)
{
mWindow->setMediaViewer(this);
}
MediaViewer::~MediaViewer()
{
if (mVideo) {
delete mVideo;
mVideo = nullptr;
}
if (mImage) {
delete mImage;
mImage = nullptr;
}
}
bool MediaViewer::startMediaViewer(FileData* game)
{
mHasVideo = false;
mHasImages = false;
mCurrentImageIndex = 0;
mScreenShotIndex = -1;
mGame = game;
initiateViewer();
if (mHasVideo) {
ViewController::get()->onPauseVideo();
AudioManager::getInstance()->clearStream();
}
if (mHasVideo || mHasImages)
return true;
else
return false;
}
void MediaViewer::stopMediaViewer()
{
NavigationSounds::getInstance()->playThemeNavigationSound(SCROLLSOUND);
if (mVideo) {
ViewController::get()->onStopVideo();
AudioManager::getInstance()->clearStream();
delete mVideo;
mVideo = nullptr;
}
if (mImage) {
delete mImage;
mImage = nullptr;
}
mVideoFile = "";
mImageFiles.clear();
}
void MediaViewer::update(int deltaTime)
{
if (mVideo)
mVideo->update(deltaTime);
}
void MediaViewer::render()
{
Transform4x4f transform = Transform4x4f::Identity();
Renderer::setMatrix(transform);
// Render a black background below the game media.
Renderer::drawRect(0.0f, 0.0f, static_cast<float>(Renderer::getScreenWidth()),
static_cast<float>(Renderer::getScreenHeight()), 0x000000FF, 0x000000FF);
if (mVideo && !mDisplayingImage) {
mVideo->render(transform);
#if defined(USE_OPENGL_21)
Renderer::shaderParameters videoParameters;
unsigned int shaders = 0;
if (Settings::getInstance()->getBool("MediaViewerVideoScanlines"))
shaders = Renderer::SHADER_SCANLINES;
if (Settings::getInstance()->getBool("MediaViewerVideoBlur")) {
shaders |= Renderer::SHADER_BLUR_HORIZONTAL;
float heightModifier = Renderer::getScreenHeightModifier();
if (heightModifier < 1)
videoParameters.blurPasses = 2; // Below 1080
else if (heightModifier >= 4)
videoParameters.blurPasses = 12; // 8K
else if (heightModifier >= 2.9)
videoParameters.blurPasses = 10; // 6K
else if (heightModifier >= 2.6)
videoParameters.blurPasses = 8; // 5K
else if (heightModifier >= 2)
videoParameters.blurPasses = 5; // 4K
else if (heightModifier >= 1.3)
videoParameters.blurPasses = 3; // 1440
else if (heightModifier >= 1)
videoParameters.blurPasses = 2; // 1080
}
Renderer::shaderPostprocessing(shaders, videoParameters);
#endif
}
else if (mImage && mImage->hasImage()) {
mImage->render(transform);
#if defined(USE_OPENGL_21)
if (mCurrentImageIndex == mScreenShotIndex &&
Settings::getInstance()->getBool("MediaViewerScreenshotScanlines"))
Renderer::shaderPostprocessing(Renderer::SHADER_SCANLINES);
#endif
// This is necessary so that the video loops if viewing an image when
// the video ends.
if (mVideo)
mVideo->handleLooping();
}
}
void MediaViewer::initiateViewer()
{
if (mGame->getType() == PLACEHOLDER)
return;
findMedia();
if (!mHasVideo && !mHasImages) {
NavigationSounds::getInstance()->playThemeNavigationSound(SCROLLSOUND);
return;
}
if (mHasVideo)
playVideo();
else
showImage(0);
}
void MediaViewer::findMedia()
{
std::string mediaFile;
if ((mediaFile = mGame->getVideoPath()) != "") {
mVideoFile = mediaFile;
mHasVideo = true;
}
if (!mHasVideo && (mediaFile = mGame->getScreenshotPath()) != "") {
mImageFiles.push_back(mediaFile);
mScreenShotIndex = 0;
}
if ((mediaFile = mGame->getCoverPath()) != "")
mImageFiles.push_back(mediaFile);
if (mHasVideo && (mediaFile = mGame->getScreenshotPath()) != "") {
mImageFiles.push_back(mediaFile);
mScreenShotIndex = mImageFiles.size() - 1;
}
if ((mediaFile = mGame->get3DBoxPath()) != "")
mImageFiles.push_back(mediaFile);
if (!mImageFiles.empty())
mHasImages = true;
}
void MediaViewer::showNext()
{
NavigationSounds::getInstance()->playThemeNavigationSound(SCROLLSOUND);
bool showedVideo = false;
if (mVideo && !mHasImages) {
return;
}
else if (mVideo && !Settings::getInstance()->getBool("MediaViewerKeepVideoRunning")) {
AudioManager::getInstance()->clearStream();
delete mVideo;
mVideo = nullptr;
showedVideo = true;
}
if (mImage) {
delete mImage;
mImage = nullptr;
}
if ((mVideo || showedVideo) && !mDisplayingImage)
mCurrentImageIndex = 0;
else if (mImageFiles.size() > mCurrentImageIndex + 1)
mCurrentImageIndex++;
if (mVideo)
mDisplayingImage = true;
showImage(mCurrentImageIndex);
}
void MediaViewer::showPrevious()
{
NavigationSounds::getInstance()->playThemeNavigationSound(SCROLLSOUND);
if (mCurrentImageIndex == 0 && !mHasVideo) {
return;
}
else if (mCurrentImageIndex == 0 && mHasVideo) {
if (mImage) {
delete mImage;
mImage = nullptr;
}
mDisplayingImage = false;
playVideo();
return;
}
if (mImage) {
delete mImage;
mImage = nullptr;
}
mCurrentImageIndex--;
showImage(mCurrentImageIndex);
}
void MediaViewer::playVideo()
{
if (mVideo || mVideoFile == "")
return;
mDisplayingImage = false;
if (Settings::getInstance()->getString("VideoPlayer") == "ffmpeg")
mVideo = new VideoFFmpegComponent(mWindow);
else
mVideo = new VideoVlcComponent(mWindow);
mVideo->topWindow(true);
mVideo->setOrigin(0.5f, 0.5f);
mVideo->setPosition(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f);
if (Settings::getInstance()->getBool("MediaViewerStretchVideos"))
mVideo->setResize(static_cast<float>(Renderer::getScreenWidth()),
static_cast<float>(Renderer::getScreenHeight()));
else
mVideo->setMaxSize(static_cast<float>(Renderer::getScreenWidth()),
static_cast<float>(Renderer::getScreenHeight()));
mVideo->setVideo(mVideoFile);
mVideo->setMediaViewerMode(true);
mVideo->onShow();
}
void MediaViewer::showImage(int index)
{
if (mImage)
return;
if (!mImageFiles.empty() && mImageFiles.size() >= index) {
mImage = new ImageComponent(mWindow, false, false);
mImage->setImage(mImageFiles[index]);
mImage->setOrigin(0.5f, 0.5f);
mImage->setPosition(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f);
mImage->setMaxSize(static_cast<float>(Renderer::getScreenWidth()),
static_cast<float>(Renderer::getScreenHeight()));
}
}

56
es-app/src/MediaViewer.h Normal file
View file

@ -0,0 +1,56 @@
// SPDX-License-Identifier: MIT
//
// EmulationStation Desktop Edition
// MediaViewer.h
//
// Fullscreen game media viewer.
//
#ifndef ES_APP_MEDIA_VIEWER_H
#define ES_APP_MEDIA_VIEWER_H
#include "components/ImageComponent.h"
#include "components/VideoComponent.h"
#include "FileData.h"
#include "Window.h"
class MediaViewer : public Window::MediaViewer
{
public:
MediaViewer(Window* window);
virtual ~MediaViewer();
virtual bool startMediaViewer(FileData* game);
virtual void stopMediaViewer();
virtual void update(int deltaTime);
virtual void render();
private:
void initiateViewer();
void findMedia();
void playVideo();
void showImage(int index);
virtual void showNext();
virtual void showPrevious();
Window* mWindow;
FileData* mGame;
bool mHasVideo;
bool mHasImages;
bool mDisplayingImage;
int mCurrentImageIndex;
int mScreenShotIndex;
std::string mVideoFile;
std::vector<std::string> mImageFiles;
VideoComponent* mVideo;
ImageComponent* mImage;
};
#endif // ES_APP_MEDIA_VIEWER_H

View file

@ -0,0 +1,85 @@
// SPDX-License-Identifier: MIT
//
// EmulationStation Desktop Edition
// GuiMediaViewerOptions.cpp
//
// User interface for the media viewer options.
// Submenu to the GuiMenu main menu.
//
#include "guis/GuiMediaViewerOptions.h"
#include "components/SwitchComponent.h"
#include "Settings.h"
GuiMediaViewerOptions::GuiMediaViewerOptions(Window* window, const std::string& title)
: GuiSettings(window, title)
{
// Keep videos running when viewing images.
auto keep_video_running = std::make_shared<SwitchComponent>(mWindow);
keep_video_running->setState(Settings::getInstance()->getBool("MediaViewerKeepVideoRunning"));
addWithLabel("KEEP VIDEOS RUNNING WHEN VIEWING IMAGES", keep_video_running);
addSaveFunc([keep_video_running, this] {
if (keep_video_running->getState() !=
Settings::getInstance()->getBool("MediaViewerKeepVideoRunning")) {
Settings::getInstance()->setBool("MediaViewerKeepVideoRunning",
keep_video_running->getState());
setNeedsSaving();
}
});
// Stretch videos to screen resolution.
auto stretch_videos = std::make_shared<SwitchComponent>(mWindow);
stretch_videos->setState(Settings::getInstance()->getBool("MediaViewerStretchVideos"));
addWithLabel("STRETCH VIDEOS TO SCREEN RESOLUTION", stretch_videos);
addSaveFunc([stretch_videos, this] {
if (stretch_videos->getState() !=
Settings::getInstance()->getBool("MediaViewerStretchVideos")) {
Settings::getInstance()->setBool("MediaViewerStretchVideos",
stretch_videos->getState());
setNeedsSaving();
}
});
#if defined(USE_OPENGL_21)
// Render scanlines for videos using a shader.
auto video_scanlines = std::make_shared<SwitchComponent>(mWindow);
video_scanlines->setState(Settings::getInstance()->getBool("MediaViewerVideoScanlines"));
addWithLabel("RENDER SCANLINES FOR VIDEOS", video_scanlines);
addSaveFunc([video_scanlines, this] {
if (video_scanlines->getState() !=
Settings::getInstance()->getBool("MediaViewerVideoScanlines")) {
Settings::getInstance()->setBool("MediaViewerVideoScanlines",
video_scanlines->getState());
setNeedsSaving();
}
});
// Render blur for videos using a shader.
auto video_blur = std::make_shared<SwitchComponent>(mWindow);
video_blur->setState(Settings::getInstance()->getBool("MediaViewerVideoBlur"));
addWithLabel("RENDER BLUR FOR VIDEOS", video_blur);
addSaveFunc([video_blur, this] {
if (video_blur->getState() !=
Settings::getInstance()->getBool("MediaViewerVideoBlur")) {
Settings::getInstance()->setBool("MediaViewerVideoBlur",
video_blur->getState());
setNeedsSaving();
}
});
// Render scanlines for screenshots using a shader.
auto screenshot_scanlines = std::make_shared<SwitchComponent>(mWindow);
screenshot_scanlines->setState(Settings::getInstance()->
getBool("MediaViewerScreenshotScanlines"));
addWithLabel("RENDER SCANLINES FOR SCREENSHOTS", screenshot_scanlines);
addSaveFunc([screenshot_scanlines, this] {
if (screenshot_scanlines->getState() !=
Settings::getInstance()->getBool("MediaViewerScreenshotScanlines")) {
Settings::getInstance()->setBool("MediaViewerScreenshotScanlines",
screenshot_scanlines->getState());
setNeedsSaving();
}
});
#endif
}

View file

@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
//
// EmulationStation Desktop Edition
// GuiMediaViewerOptions.h
//
// User interface for the media viewer options.
// Submenu to the GuiMenu main menu.
//
#ifndef ES_APP_GUIS_GUI_MEDIA_VIEWER_OPTIONS_H
#define ES_APP_GUIS_GUI_MEDIA_VIEWER_OPTIONS_H
#include "guis/GuiSettings.h"
class GuiMediaViewerOptions : public GuiSettings
{
public:
GuiMediaViewerOptions(Window* window, const std::string& title);
};
#endif // ES_APP_GUIS_GUI_MEDIA_VIEWER_OPTIONS_H

View file

@ -15,9 +15,10 @@
#include "guis/GuiCollectionSystemsOptions.h"
#include "guis/GuiComplexTextEditPopup.h"
#include "guis/GuiDetectDevice.h"
#include "guis/GuiScreensaverOptions.h"
#include "guis/GuiMediaViewerOptions.h"
#include "guis/GuiMsgBox.h"
#include "guis/GuiScraperMenu.h"
#include "guis/GuiScreensaverOptions.h"
#include "guis/GuiSettings.h"
#include "views/gamelist/IGameListView.h"
#include "views/UIModeController.h"
@ -504,6 +505,15 @@ void GuiMenu::openUISettings()
}
});
// Media viewer.
ComponentListRow media_viewer_row;
media_viewer_row.elements.clear();
media_viewer_row.addElement(std::make_shared<TextComponent>
(mWindow, "MEDIA VIEWER SETTINGS", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
media_viewer_row.addElement(makeArrow(mWindow), false);
media_viewer_row.makeAcceptInputHandler(std::bind(&GuiMenu::openMediaViewerOptions, this));
s->addRow(media_viewer_row);
// Screensaver.
ComponentListRow screensaver_row;
screensaver_row.elements.clear();
@ -668,7 +678,7 @@ void GuiMenu::openSoundSettings()
});
#endif
// Video audio.
// Play audio for gamelist videos.
auto gamelist_video_audio = std::make_shared<SwitchComponent>(mWindow);
gamelist_video_audio->setState(Settings::getInstance()->getBool("GamelistVideoAudio"));
s->addWithLabel("PLAY AUDIO FOR VIDEOS IN THE GAMELIST VIEW", gamelist_video_audio);
@ -681,6 +691,34 @@ void GuiMenu::openSoundSettings()
}
});
// Play audio for media viewer videos.
auto media_viewer_video_audio = std::make_shared<SwitchComponent>(mWindow);
media_viewer_video_audio->setState(Settings::getInstance()->
getBool("MediaViewerVideoAudio"));
s->addWithLabel("PLAY AUDIO FOR MEDIA VIEWER VIDEOS", media_viewer_video_audio);
s->addSaveFunc([media_viewer_video_audio, s] {
if (media_viewer_video_audio->getState() !=
Settings::getInstance()->getBool("MediaViewerVideoAudio")) {
Settings::getInstance()->setBool("MediaViewerVideoAudio",
media_viewer_video_audio->getState());
s->setNeedsSaving();
}
});
// Play audio for screensaver videos.
auto screensaver_video_audio = std::make_shared<SwitchComponent>(mWindow);
screensaver_video_audio->setState(Settings::getInstance()->
getBool("ScreensaverVideoAudio"));
s->addWithLabel("PLAY AUDIO FOR SCREENSAVER VIDEOS", screensaver_video_audio);
s->addSaveFunc([screensaver_video_audio, s] {
if (screensaver_video_audio->getState() !=
Settings::getInstance()->getBool("ScreensaverVideoAudio")) {
Settings::getInstance()->setBool("ScreensaverVideoAudio",
screensaver_video_audio->getState());
s->setNeedsSaving();
}
});
// Navigation sounds.
auto navigation_sounds = std::make_shared<SwitchComponent>(mWindow);
navigation_sounds->setState(Settings::getInstance()->
@ -1130,6 +1168,11 @@ void GuiMenu::addVersionInfo()
addChild(&mVersion);
}
void GuiMenu::openMediaViewerOptions()
{
mWindow->pushGui(new GuiMediaViewerOptions(mWindow, "MEDIA VIEWER SETTINGS"));
}
void GuiMenu::openScreensaverOptions()
{
mWindow->pushGui(new GuiScreensaverOptions(mWindow, "SCREENSAVER SETTINGS"));

View file

@ -32,6 +32,7 @@ private:
void openScraperSettings();
void openUISettings();
void openMediaViewerOptions();
void openScreensaverOptions();
void openSoundSettings();
void openCollectionSystemSettings();

View file

@ -225,19 +225,6 @@ void GuiScreensaverOptions::openVideoScreensaverOptions()
}
});
// PLay audio for screensaver videos.
auto screensaver_video_audio = std::make_shared<SwitchComponent>(mWindow);
screensaver_video_audio->setState(Settings::getInstance()->getBool("ScreensaverVideoAudio"));
s->addWithLabel("PLAY AUDIO FOR SCREENSAVER VIDEOS", screensaver_video_audio);
s->addSaveFunc([screensaver_video_audio, s] {
if (screensaver_video_audio->getState() !=
Settings::getInstance()->getBool("ScreensaverVideoAudio")) {
Settings::getInstance()->setBool("ScreensaverVideoAudio",
screensaver_video_audio->getState());
s->setNeedsSaving();
}
});
// Stretch videos to screen resolution.
auto screensaver_stretch_videos = std::make_shared<SwitchComponent>(mWindow);
screensaver_stretch_videos->

View file

@ -30,6 +30,7 @@
#include "InputManager.h"
#include "Log.h"
#include "MameNames.h"
#include "MediaViewer.h"
#include "Platform.h"
#include "Settings.h"
#include "Sound.h"
@ -477,6 +478,7 @@ int main(int argc, char* argv[])
Window window;
SystemScreensaver screensaver(&window);
MediaViewer mediaViewer(&window);
ViewController::init(&window);
CollectionSystemsManager::init(&window);
window.pushGui(ViewController::get());

View file

@ -139,6 +139,13 @@ void Settings::setDefaults()
mBoolMap["PlayVideosImmediately"] = { false, false };
mBoolMap["EnableMenuKidMode"] = { false, false };
// UI settings -> media viewer settings.
mBoolMap["MediaViewerKeepVideoRunning"] = { true, true };
mBoolMap["MediaViewerStretchVideos"] = { false, false };
mBoolMap["MediaViewerVideoScanlines"] = { true, true };
mBoolMap["MediaViewerVideoBlur"] = { false, false };
mBoolMap["MediaViewerScreenshotScanlines"] = { true, true };
// UI settings -> screensaver settings.
mIntMap["ScreensaverTimer"] = { 5*60*1000, 5*60*1000 }; // 5 minutes
mStringMap["ScreensaverType"] = { "dim", "dim" };
@ -157,7 +164,6 @@ void Settings::setDefaults()
// UI settings -> screensaver settings -> video screensaver settings.
mIntMap["ScreensaverSwapVideoTimeout"] = { 0, 0 };
mBoolMap["ScreensaverVideoAudio"] = { false, false };
mBoolMap["ScreensaverStretchVideos"] = { false, false };
mBoolMap["ScreensaverVideoGameInfo"] = { true, true };
mBoolMap["ScreensaverVideoScanlines"] = { true, true };
@ -185,6 +191,8 @@ void Settings::setDefaults()
mIntMap["SoundVolumeNavigation"] = { 80, 80 };
mIntMap["SoundVolumeVideos"] = { 100, 100 };
mBoolMap["GamelistVideoAudio"] = { true, true };
mBoolMap["MediaViewerVideoAudio"] = { true, true };
mBoolMap["ScreensaverVideoAudio"] = { false, false };
mBoolMap["NavigationSounds"] = { true, true };
// Game collection settings.

View file

@ -24,6 +24,7 @@
Window::Window()
: mScreensaver(nullptr),
mMediaViewer(nullptr),
mInfoPopup(nullptr),
mNormalizeNextUpdate(false),
mFrameTimeElapsed(0),
@ -33,6 +34,7 @@ Window::Window()
mSleeping(false),
mTimeSinceLastInput(0),
mRenderScreensaver(false),
mRenderMediaViewer(false),
mGameLaunchedState(false),
mAllowTextScrolling(true),
mCachedBackground(false),
@ -151,6 +153,17 @@ void Window::input(InputConfig* config, Input input)
if (Settings::getInstance()->getBool("Debug"))
logInput(config, input);
if (mMediaViewer && mRenderMediaViewer) {
if (config->isMappedLike("right", input) && input.value != 0)
mMediaViewer->showNext();
else if (config->isMappedLike("left", input) && input.value != 0)
mMediaViewer->showPrevious();
else if (input.value != 0)
// Any other input than left or right stops the media viewer.
stopMediaViewer();
return;
}
if (mScreensaver) {
if (mScreensaver->isScreensaverActive() &&
Settings::getInstance()->getBool("ScreensaverControls") &&
@ -303,8 +316,10 @@ void Window::update(int deltaTime)
mChangedThemeSet = false;
}
// Update the screensaver.
if (mScreensaver)
if (mMediaViewer && mRenderMediaViewer)
mMediaViewer->update(deltaTime);
if (mScreensaver && mRenderScreensaver)
mScreensaver->update(deltaTime);
}
@ -319,7 +334,7 @@ void Window::render()
auto& bottom = mGuiStack.front();
auto& top = mGuiStack.back();
if (mRenderScreensaver) {
if (mRenderMediaViewer || mRenderScreensaver) {
bottom->cancelAllAnimations();
bottom->stopAllAnimations();
}
@ -464,8 +479,9 @@ void Window::render()
unsigned int screensaverTimer =
static_cast<unsigned int>(Settings::getInstance()->getInt("ScreensaverTimer"));
if (mTimeSinceLastInput >= screensaverTimer && screensaverTimer != 0) {
// If a menu is open, reset the screensaver timer so that the screensaver won't start.
if (mGuiStack.front() != mGuiStack.back())
// If the media viewer is running or if a menu is open, reset the screensaver timer so
// that the screensaver won't start.
if (mRenderMediaViewer || mGuiStack.front() != mGuiStack.back())
mTimeSinceLastInput = 0;
// If a game has been launched, reset the screensaver timer as we don't want to start
// the screensaver in the background when running a game.
@ -492,6 +508,9 @@ void Window::render()
}
}
if (mRenderMediaViewer)
mMediaViewer->render();
if (Settings::getInstance()->getBool("DisplayGPUStatistics") && mFrameDataText) {
Renderer::setMatrix(Transform4x4f::Identity());
mDefaultFonts.at(1)->renderTextCache(mFrameDataText.get());
@ -711,3 +730,19 @@ void Window::renderScreensaver()
if (mScreensaver)
mScreensaver->renderScreensaver();
}
void Window::startMediaViewer(FileData* game)
{
if (mMediaViewer) {
if (mMediaViewer->startMediaViewer(game))
mRenderMediaViewer = true;
}
}
void Window::stopMediaViewer()
{
if (mMediaViewer)
mMediaViewer->stopMediaViewer();
mRenderMediaViewer = false;
}

View file

@ -50,6 +50,19 @@ public:
virtual void triggerNextGame() = 0;
};
class MediaViewer
{
public:
virtual bool startMediaViewer(FileData* game) = 0;
virtual void stopMediaViewer() = 0;
virtual void showNext() = 0;
virtual void showPrevious() = 0;
virtual void update(int deltaTime) = 0;
virtual void render() = 0;
};
class InfoPopup
{
public:
@ -92,11 +105,16 @@ public:
void setInfoPopup(InfoPopup* infoPopup);
void stopInfoPopup();
bool isScreensaverActive() { return mRenderScreensaver; };
void startScreensaver();
bool stopScreensaver();
void renderScreensaver();
void screensaverTriggerNextGame() { mScreensaver->triggerNextGame(); };
bool isScreensaverActive() { return mRenderScreensaver; };
void startMediaViewer(FileData* game);
void stopMediaViewer();
void setMediaViewer(MediaViewer* mediaViewer) { mMediaViewer = mediaViewer; }
bool isMediaViewerActive() { return mRenderMediaViewer; };
void setLaunchedGame();
void unsetLaunchedGame();
@ -124,6 +142,9 @@ private:
std::vector<std::shared_ptr<Font>> mDefaultFonts;
std::unique_ptr<TextCache> mFrameDataText;
MediaViewer* mMediaViewer;
bool mRenderMediaViewer;
std::string mListScrollText;
std::shared_ptr<Font> mListScrollFont;
unsigned char mListScrollOpacity;

View file

@ -88,8 +88,9 @@ void ScrollableContainer::reset()
void ScrollableContainer::update(int deltaTime)
{
// Don't scroll if the screensaver is active or text scrolling is disabled;
if (mWindow->isScreensaverActive() || !mWindow->getAllowTextScrolling()) {
// Don't scroll if the media viewer or screensaver is active or if text scrolling is disabled;
if (mWindow->isMediaViewerActive() || mWindow->isScreensaverActive() ||
!mWindow->getAllowTextScrolling()) {
if (mScrollPos != 0)
reset();
return;

View file

@ -30,6 +30,7 @@ VideoComponent::VideoComponent(
mPause(false),
mShowing(false),
mDisable(false),
mMediaViewerMode(false),
mScreensaverActive(false),
mScreensaverMode(false),
mGameLaunched(false),
@ -97,6 +98,11 @@ void VideoComponent::setScreensaverMode(bool isScreensaver)
mScreensaverMode = isScreensaver;
}
void VideoComponent::setMediaViewerMode(bool isMediaViewer)
{
mMediaViewerMode = isMediaViewer;
}
void VideoComponent::setOpacity(unsigned char opacity)
{
mOpacity = opacity;

View file

@ -14,6 +14,7 @@
#include <string>
class MediaViewer;
class TextureResource;
class VideoComponent : public GuiComponent
@ -36,7 +37,9 @@ public:
void setDefaultVideo();
// Loads a static image that is displayed if the video cannot be played.
void setImage(std::string path);
// Sets whether it's going to render in screensaver mode.
// Sets whether we're in media viewer mode.
void setMediaViewerMode(bool isMediaViewer);
// Sets whether we're in screensaver mode.
void setScreensaverMode(bool isScreensaver);
// Set the opacity for the embedded static image.
void setOpacity(unsigned char opacity) override;
@ -98,6 +101,8 @@ private:
// Manage the playing state of the component.
void manageState();
friend MediaViewer;
protected:
Window* mWindow;
unsigned mVideoWidth;
@ -118,6 +123,7 @@ protected:
bool mPause;
bool mShowing;
bool mDisable;
bool mMediaViewerMode;
bool mScreensaverActive;
bool mScreensaverMode;
bool mGameLaunched;

View file

@ -158,10 +158,11 @@ void VideoFFmpegComponent::render(const Transform4x4f& parentTrans)
mTexture->bind();
#if defined(USE_OPENGL_21)
// Render scanlines if this option is enabled. However, if this is the video
// screensaver, then skip this as screensaver scanline rendering is handled in
// SystemScreenSaver as a postprocessing step.
if (!mScreensaverMode && Settings::getInstance()->getBool("GamelistVideoScanlines"))
// Render scanlines if this option is enabled. However, if this is the media viewer
// or the video screensaver, then skip this as the scanline rendering is then handled
// in those modules as a postprocessing step.
if ((!mScreensaverMode && !mMediaViewerMode) &&
Settings::getInstance()->getBool("GamelistVideoScanlines"))
vertices[0].shaders = Renderer::SHADER_SCANLINES;
#endif
@ -466,9 +467,19 @@ void VideoFFmpegComponent::outputFrames()
// LOG(LogDebug) << "Total audio frames processed / audio frame queue size: " <<
// mAudioFrameCount << " / " << std::to_string(mAudioFrameQueue.size());
if ((Settings::getInstance()->getBool("GamelistVideoAudio") &&
!mScreensaverMode) || (Settings::getInstance()->
getBool("ScreensaverVideoAudio") && mScreensaverMode)) {
bool outputSound = false;
if ((!mScreensaverMode && !mMediaViewerMode) &&
Settings::getInstance()->getBool("GamelistVideoAudio"))
outputSound = true;
else if (mScreensaverMode && Settings::getInstance()->
getBool("ScreensaverVideoAudio"))
outputSound = true;
else if (mMediaViewerMode && Settings::getInstance()->
getBool("MediaViewerVideoAudio"))
outputSound = true;
if (outputSound) {
AudioManager::getInstance()->processStream(
&mAudioFrameQueue.front().resampledData.at(0),
mAudioFrameQueue.front().resampledDataSize);

View file

@ -225,10 +225,11 @@ void VideoVlcComponent::render(const Transform4x4f& parentTrans)
mTexture->bind();
#if defined(USE_OPENGL_21)
// Render scanlines if this option is enabled. However, if this is the video
// screensaver, then skip this as screensaver scanline rendering is handled in
// SystemScreenSaver as a postprocessing step.
if (!mScreensaverMode && Settings::getInstance()->getBool("GamelistVideoScanlines"))
// Render scanlines if this option is enabled. However, if this is the media viewer
// or the video screensaver, then skip this as the scanline rendering is then handled
// in those modules as a postprocessing step.
if ((!mScreensaverMode && !mMediaViewerMode) &&
Settings::getInstance()->getBool("GamelistVideoScanlines"))
vertices[0].shaders = Renderer::SHADER_SCANLINES;
#endif
@ -303,18 +304,29 @@ void VideoVlcComponent::setAudioVolume()
if (mMediaPlayer && libvlc_media_player_get_state(mMediaPlayer) == libvlc_Playing) {
// This small delay may avoid a race condition in libVLC that could crash the application.
SDL_Delay(2);
if ((!Settings::getInstance()->getBool("GamelistVideoAudio") &&
!mScreensaverMode) ||
(!Settings::getInstance()->getBool("ScreensaverVideoAudio") &&
mScreensaverMode)) {
libvlc_audio_set_volume(mMediaPlayer, 0);
}
else {
bool outputSound = false;
if ((!mScreensaverMode && !mMediaViewerMode) &&
Settings::getInstance()->getBool("GamelistVideoAudio"))
outputSound = true;
else if (mScreensaverMode && Settings::getInstance()->
getBool("ScreensaverVideoAudio"))
outputSound = true;
else if (mMediaViewerMode && Settings::getInstance()->
getBool("MediaViewerVideoAudio"))
outputSound = true;
if (outputSound) {
if (libvlc_audio_get_mute(mMediaPlayer) == 1)
libvlc_audio_set_mute(mMediaPlayer, 0);
libvlc_audio_set_volume(mMediaPlayer,
Settings::getInstance()->getInt("SoundVolumeVideos"));
}
else {
libvlc_audio_set_volume(mMediaPlayer, 0);
}
mHasSetAudioVolume = true;
}
}
@ -510,9 +522,19 @@ void VideoVlcComponent::handleLooping()
libvlc_media_player_set_media(mMediaPlayer, mMedia);
libvlc_media_player_play(mMediaPlayer);
if ((!Settings::getInstance()->getBool("GamelistVideoAudio") &&
!mScreensaverMode) || (!Settings::getInstance()->
getBool("ScreensaverVideoAudio") && mScreensaverMode))
bool outputSound = false;
if ((!mScreensaverMode && !mMediaViewerMode) &&
Settings::getInstance()->getBool("GamelistVideoAudio"))
outputSound = true;
else if (mScreensaverMode && Settings::getInstance()->
getBool("ScreensaverVideoAudio"))
outputSound = true;
else if (mMediaViewerMode && Settings::getInstance()->
getBool("MediaViewerVideoAudio"))
outputSound = true;
if (!outputSound)
libvlc_audio_set_volume(mMediaPlayer, 0);
}
}