ES-DE/es-app/src/MediaViewer.cpp
Leon Styhre 63af859618 Modernized the OpenGL renderer and replaced most fixed function pipeline code with shaders.
Also greatly improved the shader post processing performance and added component dimming support.
2022-03-11 23:17:04 +01:00

288 lines
7.7 KiB
C++

// SPDX-License-Identifier: MIT
//
// EmulationStation Desktop Edition
// MediaViewer.cpp
//
// Fullscreen game media viewer.
//
#include "MediaViewer.h"
#include "Sound.h"
#include "components/VideoFFmpegComponent.h"
#include "views/ViewController.h"
MediaViewer::MediaViewer()
: mVideo {nullptr}
, mImage {nullptr}
{
Window::getInstance()->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;
mTitleScreenIndex = -1;
mGame = game;
initiateViewer();
if (mHasVideo || mHasImages)
return true;
else
return false;
}
void MediaViewer::stopMediaViewer()
{
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
ViewController::getInstance()->stopViewVideos();
if (mVideo) {
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(const glm::mat4& /*parentTrans*/)
{
glm::mat4 trans {Renderer::getIdentity()};
Renderer::setMatrix(trans);
// Render a black background below the game media.
Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
0x000000FF, 0x000000FF);
if (mVideo && !mDisplayingImage) {
mVideo->render(trans);
#if defined(USE_OPENGL_21)
Renderer::postProcessingParams 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()};
// clang-format off
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
// clang-format on
}
Renderer::shaderPostprocessing(shaders, videoParameters);
#endif
}
else if (mImage && mImage->hasImage() && mImage->getSize() != glm::vec2 {}) {
mImage->render(trans);
#if defined(USE_OPENGL_21)
if (mCurrentImageIndex == mScreenshotIndex &&
Settings::getInstance()->getBool("MediaViewerScreenshotScanlines"))
Renderer::shaderPostprocessing(Renderer::SHADER_SCANLINES);
else if (mCurrentImageIndex == mTitleScreenIndex &&
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)
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 ((mediaFile = mGame->getBackCoverPath()) != "")
mImageFiles.push_back(mediaFile);
if ((mediaFile = mGame->getTitleScreenPath()) != "") {
mImageFiles.push_back(mediaFile);
mTitleScreenIndex = static_cast<int>(mImageFiles.size() - 1);
}
if (mHasVideo && (mediaFile = mGame->getScreenshotPath()) != "") {
mImageFiles.push_back(mediaFile);
mScreenshotIndex = static_cast<int>(mImageFiles.size() - 1);
}
if ((mediaFile = mGame->getFanArtPath()) != "")
mImageFiles.push_back(mediaFile);
if ((mediaFile = mGame->getMiximagePath()) != "")
mImageFiles.push_back(mediaFile);
if (!mImageFiles.empty())
mHasImages = true;
}
void MediaViewer::showNext()
{
if (mHasImages && mCurrentImageIndex != static_cast<int>(mImageFiles.size()) - 1)
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
bool showedVideo = false;
if (mVideo && !mHasImages) {
return;
}
else if (mVideo && !Settings::getInstance()->getBool("MediaViewerKeepVideoRunning")) {
delete mVideo;
mVideo = nullptr;
showedVideo = true;
}
if (mImage) {
delete mImage;
mImage = nullptr;
}
if ((mVideo || showedVideo) && !mDisplayingImage)
mCurrentImageIndex = 0;
else if (static_cast<int>(mImageFiles.size()) > mCurrentImageIndex + 1)
++mCurrentImageIndex;
if (mVideo)
mDisplayingImage = true;
showImage(mCurrentImageIndex);
}
void MediaViewer::showPrevious()
{
if ((mHasVideo && mDisplayingImage) || (!mHasVideo && mCurrentImageIndex != 0))
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;
ViewController::getInstance()->pauseViewVideos();
mVideo = new VideoFFmpegComponent;
mVideo->setOrigin(0.5f, 0.5f);
mVideo->setPosition(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f);
if (Settings::getInstance()->getBool("MediaViewerStretchVideos"))
mVideo->setResize(Renderer::getScreenWidth(), Renderer::getScreenHeight());
else
mVideo->setMaxSize(Renderer::getScreenWidth(), Renderer::getScreenHeight());
mVideo->setVideo(mVideoFile);
mVideo->setMediaViewerMode(true);
mVideo->startVideoPlayer();
}
void MediaViewer::showImage(int index)
{
if (mImage)
return;
mDisplayingImage = true;
if (!mImageFiles.empty() && static_cast<int>(mImageFiles.size()) >= index) {
mImage = new ImageComponent(false, false);
mImage->setImage(mImageFiles[index]);
mImage->setOrigin(0.5f, 0.5f);
mImage->setPosition(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f);
mImage->setMaxSize(Renderer::getScreenWidth(), Renderer::getScreenHeight());
}
}