2021-05-16 11:12:31 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
//
|
|
|
|
// EmulationStation Desktop Edition
|
|
|
|
// MediaViewer.cpp
|
|
|
|
//
|
|
|
|
// Fullscreen game media viewer.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "MediaViewer.h"
|
|
|
|
|
|
|
|
#include "Sound.h"
|
2022-01-02 12:13:01 +00:00
|
|
|
#include "components/VideoFFmpegComponent.h"
|
2021-07-07 18:03:42 +00:00
|
|
|
#include "views/ViewController.h"
|
2021-05-16 11:12:31 +00:00
|
|
|
|
2022-01-04 20:21:26 +00:00
|
|
|
MediaViewer::MediaViewer()
|
2022-03-14 18:51:48 +00:00
|
|
|
: mRenderer {Renderer::getInstance()}
|
2021-05-16 11:12:31 +00:00
|
|
|
{
|
2022-01-19 17:01:54 +00:00
|
|
|
Window::getInstance()->setMediaViewer(this);
|
2021-05-16 11:12:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool MediaViewer::startMediaViewer(FileData* game)
|
|
|
|
{
|
|
|
|
mHasVideo = false;
|
|
|
|
mHasImages = false;
|
|
|
|
mCurrentImageIndex = 0;
|
2021-10-28 19:00:23 +00:00
|
|
|
mScreenshotIndex = -1;
|
|
|
|
mTitleScreenIndex = -1;
|
2021-05-16 11:12:31 +00:00
|
|
|
|
|
|
|
mGame = game;
|
|
|
|
|
|
|
|
initiateViewer();
|
|
|
|
|
|
|
|
if (mHasVideo || mHasImages)
|
|
|
|
return true;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MediaViewer::stopMediaViewer()
|
|
|
|
{
|
2021-11-15 21:43:06 +00:00
|
|
|
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
2022-02-19 16:04:23 +00:00
|
|
|
ViewController::getInstance()->stopViewVideos();
|
2021-05-16 11:12:31 +00:00
|
|
|
|
|
|
|
mVideoFile = "";
|
2022-09-08 18:38:47 +00:00
|
|
|
mVideo.reset();
|
2021-05-16 11:12:31 +00:00
|
|
|
mImageFiles.clear();
|
2022-09-08 18:38:47 +00:00
|
|
|
mImages.clear();
|
2021-05-16 11:12:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MediaViewer::update(int deltaTime)
|
|
|
|
{
|
|
|
|
if (mVideo)
|
|
|
|
mVideo->update(deltaTime);
|
|
|
|
}
|
|
|
|
|
2021-09-18 09:49:39 +00:00
|
|
|
void MediaViewer::render(const glm::mat4& /*parentTrans*/)
|
2021-05-16 11:12:31 +00:00
|
|
|
{
|
2022-01-16 11:09:55 +00:00
|
|
|
glm::mat4 trans {Renderer::getIdentity()};
|
2022-03-14 18:51:48 +00:00
|
|
|
mRenderer->setMatrix(trans);
|
2021-05-16 11:12:31 +00:00
|
|
|
|
|
|
|
// Render a black background below the game media.
|
2022-03-14 18:51:48 +00:00
|
|
|
mRenderer->drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
|
|
|
0x000000FF, 0x000000FF);
|
2021-05-16 11:12:31 +00:00
|
|
|
|
|
|
|
if (mVideo && !mDisplayingImage) {
|
2021-08-15 17:30:31 +00:00
|
|
|
mVideo->render(trans);
|
2021-05-16 11:12:31 +00:00
|
|
|
|
2022-03-11 22:17:04 +00:00
|
|
|
Renderer::postProcessingParams videoParameters;
|
2022-01-16 11:09:55 +00:00
|
|
|
unsigned int shaders {0};
|
2021-05-16 11:12:31 +00:00
|
|
|
if (Settings::getInstance()->getBool("MediaViewerVideoScanlines"))
|
2022-03-14 21:30:24 +00:00
|
|
|
shaders = Renderer::Shader::SCANLINES;
|
2021-05-16 11:12:31 +00:00
|
|
|
if (Settings::getInstance()->getBool("MediaViewerVideoBlur")) {
|
2022-03-14 21:30:24 +00:00
|
|
|
shaders |= Renderer::Shader::BLUR_HORIZONTAL;
|
2023-02-06 22:38:35 +00:00
|
|
|
const float resolutionModifier {mRenderer->getScreenResolutionModifier()};
|
2021-07-07 18:03:42 +00:00
|
|
|
// clang-format off
|
2023-02-06 22:38:35 +00:00
|
|
|
if (resolutionModifier < 1)
|
2021-05-16 11:12:31 +00:00
|
|
|
videoParameters.blurPasses = 2; // Below 1080
|
2023-02-06 22:38:35 +00:00
|
|
|
else if (resolutionModifier >= 4)
|
2021-05-16 11:12:31 +00:00
|
|
|
videoParameters.blurPasses = 12; // 8K
|
2023-02-06 22:38:35 +00:00
|
|
|
else if (resolutionModifier >= 2.9)
|
2021-05-16 11:12:31 +00:00
|
|
|
videoParameters.blurPasses = 10; // 6K
|
2023-02-06 22:38:35 +00:00
|
|
|
else if (resolutionModifier >= 2.6)
|
2021-05-16 11:12:31 +00:00
|
|
|
videoParameters.blurPasses = 8; // 5K
|
2023-02-06 22:38:35 +00:00
|
|
|
else if (resolutionModifier >= 2)
|
2021-05-16 11:12:31 +00:00
|
|
|
videoParameters.blurPasses = 5; // 4K
|
2023-02-06 22:38:35 +00:00
|
|
|
else if (resolutionModifier >= 1.3)
|
2021-05-16 11:12:31 +00:00
|
|
|
videoParameters.blurPasses = 3; // 1440
|
2023-02-06 22:38:35 +00:00
|
|
|
else if (resolutionModifier >= 1)
|
2021-05-16 11:12:31 +00:00
|
|
|
videoParameters.blurPasses = 2; // 1080
|
2021-07-07 18:03:42 +00:00
|
|
|
// clang-format on
|
2021-05-16 11:12:31 +00:00
|
|
|
}
|
2022-03-13 22:52:32 +00:00
|
|
|
|
|
|
|
if (shaders != 0)
|
2022-03-14 18:51:48 +00:00
|
|
|
mRenderer->shaderPostprocessing(shaders, videoParameters);
|
2021-05-16 11:12:31 +00:00
|
|
|
}
|
2022-09-08 18:38:47 +00:00
|
|
|
else if (mImages[mCurrentImageIndex]->hasImage() &&
|
|
|
|
mImages[mCurrentImageIndex]->getSize() != glm::vec2 {0.0f, 0.0f}) {
|
|
|
|
mImages[mCurrentImageIndex]->render(trans);
|
2021-05-16 11:12:31 +00:00
|
|
|
|
2021-10-28 19:00:23 +00:00
|
|
|
if (mCurrentImageIndex == mScreenshotIndex &&
|
2021-07-07 18:03:42 +00:00
|
|
|
Settings::getInstance()->getBool("MediaViewerScreenshotScanlines"))
|
2022-03-14 21:30:24 +00:00
|
|
|
mRenderer->shaderPostprocessing(Renderer::Shader::SCANLINES);
|
2021-10-28 19:00:23 +00:00
|
|
|
else if (mCurrentImageIndex == mTitleScreenIndex &&
|
|
|
|
Settings::getInstance()->getBool("MediaViewerScreenshotScanlines"))
|
2022-03-14 21:30:24 +00:00
|
|
|
mRenderer->shaderPostprocessing(Renderer::Shader::SCANLINES);
|
2021-05-16 11:12:31 +00:00
|
|
|
|
|
|
|
// 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();
|
2022-09-08 18:38:47 +00:00
|
|
|
loadImages();
|
2021-05-16 11:12:31 +00:00
|
|
|
|
2021-06-21 20:13:56 +00:00
|
|
|
if (!mHasVideo && !mHasImages)
|
2021-05-16 11:12:31 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (mHasVideo)
|
|
|
|
playVideo();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MediaViewer::findMedia()
|
|
|
|
{
|
|
|
|
std::string mediaFile;
|
|
|
|
|
|
|
|
if ((mediaFile = mGame->getVideoPath()) != "") {
|
|
|
|
mVideoFile = mediaFile;
|
|
|
|
mHasVideo = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mHasVideo && (mediaFile = mGame->getScreenshotPath()) != "") {
|
|
|
|
mImageFiles.push_back(mediaFile);
|
2021-10-28 19:00:23 +00:00
|
|
|
mScreenshotIndex = 0;
|
2021-05-16 11:12:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((mediaFile = mGame->getCoverPath()) != "")
|
|
|
|
mImageFiles.push_back(mediaFile);
|
|
|
|
|
2021-10-28 19:00:23 +00:00
|
|
|
if ((mediaFile = mGame->getBackCoverPath()) != "")
|
|
|
|
mImageFiles.push_back(mediaFile);
|
|
|
|
|
|
|
|
if ((mediaFile = mGame->getTitleScreenPath()) != "") {
|
|
|
|
mImageFiles.push_back(mediaFile);
|
|
|
|
mTitleScreenIndex = static_cast<int>(mImageFiles.size() - 1);
|
|
|
|
}
|
|
|
|
|
2021-05-16 11:12:31 +00:00
|
|
|
if (mHasVideo && (mediaFile = mGame->getScreenshotPath()) != "") {
|
|
|
|
mImageFiles.push_back(mediaFile);
|
2021-10-28 19:00:23 +00:00
|
|
|
mScreenshotIndex = static_cast<int>(mImageFiles.size() - 1);
|
2021-05-16 11:12:31 +00:00
|
|
|
}
|
|
|
|
|
2022-01-15 12:16:23 +00:00
|
|
|
if ((mediaFile = mGame->getFanArtPath()) != "")
|
|
|
|
mImageFiles.push_back(mediaFile);
|
|
|
|
|
2021-06-07 20:22:22 +00:00
|
|
|
if ((mediaFile = mGame->getMiximagePath()) != "")
|
|
|
|
mImageFiles.push_back(mediaFile);
|
|
|
|
|
2021-05-16 11:12:31 +00:00
|
|
|
if (!mImageFiles.empty())
|
|
|
|
mHasImages = true;
|
|
|
|
}
|
|
|
|
|
2022-09-08 18:38:47 +00:00
|
|
|
void MediaViewer::loadImages()
|
|
|
|
{
|
|
|
|
for (auto& file : mImageFiles) {
|
|
|
|
mImages.emplace_back(std::make_unique<ImageComponent>(false, false));
|
|
|
|
mImages.back()->setOrigin(0.5f, 0.5f);
|
|
|
|
mImages.back()->setPosition(Renderer::getScreenWidth() / 2.0f,
|
|
|
|
Renderer::getScreenHeight() / 2.0f);
|
|
|
|
mImages.back()->setMaxSize(Renderer::getScreenWidth(), Renderer::getScreenHeight());
|
|
|
|
mImages.back()->setImage(file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MediaViewer::playVideo()
|
|
|
|
{
|
|
|
|
if (mVideo || mVideoFile == "")
|
|
|
|
return;
|
|
|
|
|
|
|
|
mDisplayingImage = false;
|
|
|
|
ViewController::getInstance()->pauseViewVideos();
|
|
|
|
|
|
|
|
mVideo = std::make_unique<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();
|
|
|
|
}
|
|
|
|
|
2021-05-16 11:12:31 +00:00
|
|
|
void MediaViewer::showNext()
|
|
|
|
{
|
2022-09-08 18:38:47 +00:00
|
|
|
if (mHasImages && ((mCurrentImageIndex != static_cast<int>(mImageFiles.size()) - 1) ||
|
|
|
|
(!mDisplayingImage && mCurrentImageIndex == 0 && mImageFiles.size() == 1)))
|
2021-11-15 21:43:06 +00:00
|
|
|
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
2021-05-16 11:12:31 +00:00
|
|
|
|
2022-09-08 18:38:47 +00:00
|
|
|
bool showedVideo {false};
|
2021-05-16 11:12:31 +00:00
|
|
|
|
|
|
|
if (mVideo && !mHasImages) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (mVideo && !Settings::getInstance()->getBool("MediaViewerKeepVideoRunning")) {
|
2022-09-08 18:38:47 +00:00
|
|
|
mVideo.reset();
|
2021-05-16 11:12:31 +00:00
|
|
|
showedVideo = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((mVideo || showedVideo) && !mDisplayingImage)
|
|
|
|
mCurrentImageIndex = 0;
|
2021-09-19 12:37:10 +00:00
|
|
|
else if (static_cast<int>(mImageFiles.size()) > mCurrentImageIndex + 1)
|
2021-11-17 16:35:34 +00:00
|
|
|
++mCurrentImageIndex;
|
2021-05-16 11:12:31 +00:00
|
|
|
|
2022-09-08 18:38:47 +00:00
|
|
|
mDisplayingImage = true;
|
2021-05-16 11:12:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MediaViewer::showPrevious()
|
|
|
|
{
|
2021-05-16 21:30:41 +00:00
|
|
|
if ((mHasVideo && mDisplayingImage) || (!mHasVideo && mCurrentImageIndex != 0))
|
2021-11-15 21:43:06 +00:00
|
|
|
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
2021-05-16 11:12:31 +00:00
|
|
|
|
|
|
|
if (mCurrentImageIndex == 0 && !mHasVideo) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (mCurrentImageIndex == 0 && mHasVideo) {
|
|
|
|
mDisplayingImage = false;
|
|
|
|
playVideo();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-17 16:35:34 +00:00
|
|
|
--mCurrentImageIndex;
|
2021-05-16 11:12:31 +00:00
|
|
|
}
|