mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 14:15:38 +00:00
Added a fullscreen game media viewer.
This commit is contained in:
parent
282d2fa445
commit
3ed17fbea2
|
@ -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
282
es-app/src/MediaViewer.cpp
Normal 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
56
es-app/src/MediaViewer.h
Normal 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
|
85
es-app/src/guis/GuiMediaViewerOptions.cpp
Normal file
85
es-app/src/guis/GuiMediaViewerOptions.cpp
Normal 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
|
||||
}
|
21
es-app/src/guis/GuiMediaViewerOptions.h
Normal file
21
es-app/src/guis/GuiMediaViewerOptions.h
Normal 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
|
|
@ -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"));
|
||||
|
|
|
@ -32,6 +32,7 @@ private:
|
|||
|
||||
void openScraperSettings();
|
||||
void openUISettings();
|
||||
void openMediaViewerOptions();
|
||||
void openScreensaverOptions();
|
||||
void openSoundSettings();
|
||||
void openCollectionSystemSettings();
|
||||
|
|
|
@ -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->
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue