mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-18 07:05:39 +00:00
Random Game Screensaver, Game Name and Controls
- Final changes for VLC screensaver support as well - ALSA de-init/re-init only when needed - Adding screensaver options menu inside UI settings - Slightly moved options (Show Frameskip to "Other Settings", sorting within same menu) - Adding info popups on random video screensaver and OMX + Game Info setting
This commit is contained in:
parent
0d04633954
commit
59d7516a16
|
@ -24,6 +24,7 @@ set(ES_HEADERS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMetaDataEd.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGameScraper.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGamelistOptions.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScreensaverOptions.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMenu.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiSettings.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperMulti.h
|
||||
|
@ -73,6 +74,7 @@ set(ES_SOURCES
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMetaDataEd.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGameScraper.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiGamelistOptions.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScreensaverOptions.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMenu.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiSettings.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiScraperMulti.cpp
|
||||
|
|
|
@ -3,12 +3,17 @@
|
|||
#include "components/VideoPlayerComponent.h"
|
||||
#endif
|
||||
#include "components/VideoVlcComponent.h"
|
||||
#include "platform.h"
|
||||
#include "Renderer.h"
|
||||
#include "Settings.h"
|
||||
#include "SystemData.h"
|
||||
#include "Util.h"
|
||||
#include "Log.h"
|
||||
#include "views/ViewController.h"
|
||||
#include "views/gamelist/IGameListView.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define FADE_TIME 3000
|
||||
#define FADE_TIME 300
|
||||
#define SWAP_VIDEO_TIMEOUT 30000
|
||||
|
||||
SystemScreenSaver::SystemScreenSaver(Window* window) :
|
||||
|
@ -18,19 +23,35 @@ SystemScreenSaver::SystemScreenSaver(Window* window) :
|
|||
mVideoCount(0),
|
||||
mState(STATE_INACTIVE),
|
||||
mOpacity(0.0f),
|
||||
mTimer(0)
|
||||
mTimer(0),
|
||||
mSystemName(""),
|
||||
mGameName(""),
|
||||
mCurrentGame(NULL)
|
||||
{
|
||||
mWindow->setScreenSaver(this);
|
||||
std::string path = getTitleFolder();
|
||||
if(!boost::filesystem::exists(path))
|
||||
boost::filesystem::create_directory(path);
|
||||
srand((unsigned int)time(NULL));
|
||||
}
|
||||
|
||||
SystemScreenSaver::~SystemScreenSaver()
|
||||
{
|
||||
// Delete subtitle file, if existing
|
||||
remove(getTitlePath().c_str());
|
||||
mCurrentGame = NULL;
|
||||
delete mVideoScreensaver;
|
||||
}
|
||||
|
||||
bool SystemScreenSaver::allowSleep()
|
||||
{
|
||||
return false;
|
||||
//return false;
|
||||
return (mVideoScreensaver == NULL);
|
||||
}
|
||||
|
||||
bool SystemScreenSaver::isScreenSaverActive()
|
||||
{
|
||||
return (mState != STATE_INACTIVE);
|
||||
}
|
||||
|
||||
void SystemScreenSaver::startScreenSaver()
|
||||
|
@ -42,34 +63,50 @@ void SystemScreenSaver::startScreenSaver()
|
|||
mOpacity = 0.0f;
|
||||
|
||||
// Load a random video
|
||||
std::string path;
|
||||
std::string path = "";
|
||||
pickRandomVideo(path);
|
||||
if (!path.empty())
|
||||
|
||||
int retry = 200;
|
||||
while(retry > 0 && ((path.empty() || !boost::filesystem::exists(path)) || mCurrentGame == NULL))
|
||||
{
|
||||
// Create the correct type of video component
|
||||
retry--;
|
||||
pickRandomVideo(path);
|
||||
}
|
||||
|
||||
if (!path.empty() && boost::filesystem::exists(path))
|
||||
{
|
||||
// Create the correct type of video component
|
||||
|
||||
#ifdef _RPI_
|
||||
if (Settings::getInstance()->getBool("VideoOmxPlayer"))
|
||||
mVideoScreensaver = new VideoPlayerComponent(mWindow);
|
||||
if (Settings::getInstance()->getBool("ScreenSaverOmxPlayer"))
|
||||
mVideoScreensaver = new VideoPlayerComponent(mWindow, getTitlePath());
|
||||
else
|
||||
mVideoScreensaver = new VideoVlcComponent(mWindow);
|
||||
mVideoScreensaver = new VideoVlcComponent(mWindow, getTitlePath());
|
||||
#else
|
||||
mVideoScreensaver = new VideoVlcComponent(mWindow);
|
||||
mVideoScreensaver = new VideoVlcComponent(mWindow, getTitlePath());
|
||||
#endif
|
||||
|
||||
mVideoScreensaver->setOrigin(0.5f, 0.5f);
|
||||
mVideoScreensaver->setPosition(Renderer::getScreenWidth()/2, Renderer::getScreenHeight()/2);
|
||||
|
||||
mVideoScreensaver->setOrigin(0.0f, 0.0f);
|
||||
mVideoScreensaver->setPosition(0.0f, 0.0f);
|
||||
mVideoScreensaver->setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
|
||||
if (Settings::getInstance()->getBool("StretchVideoOnScreenSaver"))
|
||||
{
|
||||
mVideoScreensaver->setResize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
mVideoScreensaver->setMaxSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
|
||||
}
|
||||
mVideoScreensaver->setVideo(path);
|
||||
mVideoScreensaver->setScreensaverMode(true);
|
||||
mVideoScreensaver->onShow();
|
||||
mTimer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No videos. Just use a standard screensaver
|
||||
mState = STATE_SCREENSAVER_ACTIVE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// No videos. Just use a standard screensaver
|
||||
mState = STATE_SCREENSAVER_ACTIVE;
|
||||
mCurrentGame = NULL;
|
||||
}
|
||||
|
||||
void SystemScreenSaver::stopScreenSaver()
|
||||
|
@ -81,17 +118,18 @@ void SystemScreenSaver::stopScreenSaver()
|
|||
|
||||
void SystemScreenSaver::renderScreenSaver()
|
||||
{
|
||||
if (mVideoScreensaver)
|
||||
if (mVideoScreensaver && Settings::getInstance()->getString("ScreenSaverBehavior") == "random video")
|
||||
{
|
||||
// Render black background
|
||||
Renderer::setMatrix(Eigen::Affine3f::Identity());
|
||||
Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), (unsigned char)(255));
|
||||
|
||||
// Only render the video if the state requires it
|
||||
if ((int)mState >= STATE_FADE_IN_VIDEO)
|
||||
{
|
||||
Eigen::Affine3f transform = Eigen::Affine3f::Identity();
|
||||
mVideoScreensaver->render(transform);
|
||||
}
|
||||
// Handle any fade
|
||||
Renderer::setMatrix(Eigen::Affine3f::Identity());
|
||||
Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), (unsigned char)(mOpacity * 255));
|
||||
}
|
||||
else if (mState != STATE_INACTIVE)
|
||||
{
|
||||
|
@ -136,9 +174,9 @@ void SystemScreenSaver::countVideos()
|
|||
void SystemScreenSaver::pickRandomVideo(std::string& path)
|
||||
{
|
||||
countVideos();
|
||||
mCurrentGame = NULL;
|
||||
if (mVideoCount > 0)
|
||||
{
|
||||
srand((unsigned int)time(NULL));
|
||||
int video = (int)(((float)rand() / float(RAND_MAX)) * (float)mVideoCount);
|
||||
|
||||
std::vector<SystemData*>:: iterator it;
|
||||
|
@ -166,6 +204,48 @@ void SystemScreenSaver::pickRandomVideo(std::string& path)
|
|||
{
|
||||
// Yes. Resolve to a full path
|
||||
path = resolvePath(videoNode.text().get(), (*it)->getStartPath(), true).generic_string();
|
||||
mSystemName = (*it)->getFullName();
|
||||
mGameName = fileNode.child("name").text().get();
|
||||
|
||||
// getting corresponding FileData
|
||||
|
||||
// try the easy way. Should work for the majority of cases, unless in subfolders
|
||||
FileData* rootFileData = (*it)->getRootFolder();
|
||||
std::string gamePath = resolvePath(fileNode.child("path").text().get(), (*it)->getStartPath(), false).string();
|
||||
|
||||
std::string shortPath = gamePath;
|
||||
shortPath = shortPath.replace(0, (*it)->getStartPath().length()+1, "");
|
||||
|
||||
const std::unordered_map<std::string, FileData*>& children = rootFileData->getChildrenByFilename();
|
||||
std::unordered_map<std::string, FileData*>::const_iterator screenSaverGame = children.find(shortPath);
|
||||
|
||||
if (screenSaverGame != children.end())
|
||||
{
|
||||
// Found the corresponding FileData
|
||||
mCurrentGame = screenSaverGame->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Couldn't find FileData. Going for the full iteration.
|
||||
// iterate on children
|
||||
FileType type = GAME;
|
||||
std::vector<FileData*> allFiles = rootFileData->getFilesRecursive(type);
|
||||
std::vector<FileData*>::iterator itf; // declare an iterator to a vector of strings
|
||||
|
||||
int i = 0;
|
||||
for(itf=allFiles.begin() ; itf < allFiles.end(); itf++,i++ ) {
|
||||
if ((*itf)->getPath() == gamePath)
|
||||
{
|
||||
mCurrentGame = (*itf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// end of getting FileData
|
||||
if (Settings::getInstance()->getString("ScreenSaverGameInfo") != "never")
|
||||
writeSubtitle(mGameName.c_str(), mSystemName.c_str(),
|
||||
(Settings::getInstance()->getString("ScreenSaverGameInfo") == "always"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -205,9 +285,7 @@ void SystemScreenSaver::update(int deltaTime)
|
|||
mTimer += deltaTime;
|
||||
if (mTimer > SWAP_VIDEO_TIMEOUT)
|
||||
{
|
||||
stopScreenSaver();
|
||||
startScreenSaver();
|
||||
mState = STATE_SCREENSAVER_ACTIVE;
|
||||
nextVideo();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,3 +293,26 @@ void SystemScreenSaver::update(int deltaTime)
|
|||
if (mVideoScreensaver)
|
||||
mVideoScreensaver->update(deltaTime);
|
||||
}
|
||||
|
||||
void SystemScreenSaver::nextVideo() {
|
||||
stopScreenSaver();
|
||||
startScreenSaver();
|
||||
mState = STATE_SCREENSAVER_ACTIVE;
|
||||
}
|
||||
|
||||
FileData* SystemScreenSaver::getCurrentGame()
|
||||
{
|
||||
return mCurrentGame;
|
||||
}
|
||||
|
||||
void SystemScreenSaver::launchGame()
|
||||
{
|
||||
// launching Game
|
||||
ViewController::get()->goToGameList(mCurrentGame->getSystem());
|
||||
IGameListView* view = ViewController::get()->getGameListView(mCurrentGame->getSystem()).get();
|
||||
view->setCursor(mCurrentGame);
|
||||
if (Settings::getInstance()->getBool("ScreenSaverControls"))
|
||||
{
|
||||
view->launch(mCurrentGame);
|
||||
}
|
||||
}
|
|
@ -13,14 +13,21 @@ public:
|
|||
|
||||
virtual void startScreenSaver();
|
||||
virtual void stopScreenSaver();
|
||||
virtual void nextVideo();
|
||||
virtual void renderScreenSaver();
|
||||
virtual bool allowSleep();
|
||||
virtual void update(int deltaTime);
|
||||
virtual bool isScreenSaverActive();
|
||||
|
||||
virtual FileData* getCurrentGame();
|
||||
virtual void launchGame();
|
||||
|
||||
private:
|
||||
void countVideos();
|
||||
void pickRandomVideo(std::string& path);
|
||||
|
||||
void input(InputConfig* config, Input input);
|
||||
|
||||
enum STATE {
|
||||
STATE_INACTIVE,
|
||||
STATE_FADE_OUT_WINDOW,
|
||||
|
@ -36,4 +43,7 @@ private:
|
|||
STATE mState;
|
||||
float mOpacity;
|
||||
int mTimer;
|
||||
FileData* mCurrentGame;
|
||||
std::string mGameName;
|
||||
std::string mSystemName;
|
||||
};
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "Settings.h"
|
||||
#include "guis/GuiMsgBox.h"
|
||||
#include "guis/GuiSettings.h"
|
||||
#include "guis/GuiScreensaverOptions.h"
|
||||
#include "guis/GuiScraperStart.h"
|
||||
#include "guis/GuiDetectDevice.h"
|
||||
#include "views/ViewController.h"
|
||||
|
@ -98,6 +99,30 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
|
|||
s->addWithLabel("ENABLE NAVIGATION SOUNDS", sounds_enabled);
|
||||
s->addSaveFunc([sounds_enabled] { Settings::getInstance()->setBool("EnableSounds", sounds_enabled->getState()); });
|
||||
|
||||
auto video_audio = std::make_shared<SwitchComponent>(mWindow);
|
||||
video_audio->setState(Settings::getInstance()->getBool("VideoAudio"));
|
||||
s->addWithLabel("ENABLE VIDEO AUDIO", video_audio);
|
||||
s->addSaveFunc([video_audio] { Settings::getInstance()->setBool("VideoAudio", video_audio->getState()); });
|
||||
|
||||
#ifdef _RPI_
|
||||
// OMX player Audio Device
|
||||
auto omx_audio_dev = std::make_shared< OptionListComponent<std::string> >(mWindow, "OMX PLAYER AUDIO DEVICE", false);
|
||||
std::vector<std::string> devices;
|
||||
devices.push_back("local");
|
||||
devices.push_back("hdmi");
|
||||
devices.push_back("both");
|
||||
// USB audio
|
||||
devices.push_back("alsa:hw:0,0");
|
||||
devices.push_back("alsa:hw:1,0");
|
||||
for (auto it = devices.begin(); it != devices.end(); it++)
|
||||
omx_audio_dev->add(*it, *it, Settings::getInstance()->getString("OMXAudioDev") == *it);
|
||||
s->addWithLabel("OMX PLAYER AUDIO DEVICE", omx_audio_dev);
|
||||
s->addSaveFunc([omx_audio_dev] {
|
||||
if (Settings::getInstance()->getString("OMXAudioDev") != omx_audio_dev->getSelected())
|
||||
Settings::getInstance()->setString("OMXAudioDev", omx_audio_dev->getSelected());
|
||||
});
|
||||
#endif
|
||||
|
||||
mWindow->pushGui(s);
|
||||
});
|
||||
|
||||
|
@ -112,7 +137,7 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
|
|||
s->addSaveFunc([screensaver_time] { Settings::getInstance()->setInt("ScreenSaverTime", (int)round(screensaver_time->getValue()) * (1000 * 60)); });
|
||||
|
||||
// screensaver behavior
|
||||
auto screensaver_behavior = std::make_shared< OptionListComponent<std::string> >(mWindow, "STYLE", false);
|
||||
auto screensaver_behavior = std::make_shared< OptionListComponent<std::string> >(mWindow, "SCREENSAVER BEHAVIOR", false);
|
||||
std::vector<std::string> screensavers;
|
||||
screensavers.push_back("dim");
|
||||
screensavers.push_back("black");
|
||||
|
@ -120,19 +145,24 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
|
|||
for(auto it = screensavers.begin(); it != screensavers.end(); it++)
|
||||
screensaver_behavior->add(*it, *it, Settings::getInstance()->getString("ScreenSaverBehavior") == *it);
|
||||
s->addWithLabel("SCREENSAVER BEHAVIOR", screensaver_behavior);
|
||||
s->addSaveFunc([screensaver_behavior] { Settings::getInstance()->setString("ScreenSaverBehavior", screensaver_behavior->getSelected()); });
|
||||
s->addSaveFunc([this, screensaver_behavior] {
|
||||
if (Settings::getInstance()->getString("ScreenSaverBehavior") != "random video" && screensaver_behavior->getSelected() == "random video") {
|
||||
// if before it wasn't risky but now there's a risk of problems, show warning
|
||||
mWindow->pushGui(new GuiMsgBox(mWindow,
|
||||
"The \"Random Video\" screensaver shows videos from your gamelist.\n\nIf you do not have videos, or if in several consecutive attempts the games it selects don't have videos it will default to black.\n\nMore options in the \"UI Settings\" > \"Video Screensaver\" menu.",
|
||||
"OK", [] { return; }));
|
||||
}
|
||||
Settings::getInstance()->setString("ScreenSaverBehavior", screensaver_behavior->getSelected());
|
||||
});
|
||||
|
||||
// framerate
|
||||
auto framerate = std::make_shared<SwitchComponent>(mWindow);
|
||||
framerate->setState(Settings::getInstance()->getBool("DrawFramerate"));
|
||||
s->addWithLabel("SHOW FRAMERATE", framerate);
|
||||
s->addSaveFunc([framerate] { Settings::getInstance()->setBool("DrawFramerate", framerate->getState()); });
|
||||
ComponentListRow row;
|
||||
|
||||
// show help
|
||||
auto show_help = std::make_shared<SwitchComponent>(mWindow);
|
||||
show_help->setState(Settings::getInstance()->getBool("ShowHelpPrompts"));
|
||||
s->addWithLabel("ON-SCREEN HELP", show_help);
|
||||
s->addSaveFunc([show_help] { Settings::getInstance()->setBool("ShowHelpPrompts", show_help->getState()); });
|
||||
// show filtered menu
|
||||
row.elements.clear();
|
||||
row.addElement(std::make_shared<TextComponent>(mWindow, "VIDEO SCREENSAVER SETTINGS", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
|
||||
row.addElement(makeArrow(mWindow), false);
|
||||
row.makeAcceptInputHandler(std::bind(&GuiMenu::openScreensaverOptions, this));
|
||||
s->addRow(row);
|
||||
|
||||
// quick system select (left/right in game list view)
|
||||
auto quick_sys_select = std::make_shared<SwitchComponent>(mWindow);
|
||||
|
@ -198,52 +228,12 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
|
|||
if (needReload)
|
||||
ViewController::get()->reloadAll();
|
||||
});
|
||||
mWindow->pushGui(s);
|
||||
});
|
||||
|
||||
addEntry("VIDEO PLAYER SETTINGS", 0x777777FF, true,
|
||||
[this] {
|
||||
auto s = new GuiSettings(mWindow, "VIDEO PLAYER SETTINGS");
|
||||
|
||||
#ifdef _RPI_
|
||||
// Video Player - VideoOmxPlayer
|
||||
auto omx_player = std::make_shared<SwitchComponent>(mWindow);
|
||||
omx_player->setState(Settings::getInstance()->getBool("VideoOmxPlayer"));
|
||||
s->addWithLabel("USE OMX VIDEO PLAYER (HW ACCELERATED)", omx_player);
|
||||
s->addSaveFunc([omx_player]
|
||||
{
|
||||
// need to reload all views to re-create the right video components
|
||||
bool needReload = false;
|
||||
if(Settings::getInstance()->getBool("VideoOmxPlayer") != omx_player->getState())
|
||||
needReload = true;
|
||||
|
||||
Settings::getInstance()->setBool("VideoOmxPlayer", omx_player->getState());
|
||||
|
||||
if(needReload)
|
||||
ViewController::get()->reloadAll();
|
||||
});
|
||||
|
||||
// OMX player Audio Device
|
||||
auto omx_audio_dev = std::make_shared< OptionListComponent<std::string> >(mWindow, "OMX PLAYER AUDIO DEVICE", false);
|
||||
std::vector<std::string> devices;
|
||||
devices.push_back("local");
|
||||
devices.push_back("hdmi");
|
||||
devices.push_back("both");
|
||||
// USB audio
|
||||
devices.push_back("alsa:hw:0,0");
|
||||
devices.push_back("alsa:hw:1,0");
|
||||
for (auto it = devices.begin(); it != devices.end(); it++)
|
||||
omx_audio_dev->add(*it, *it, Settings::getInstance()->getString("OMXAudioDev") == *it);
|
||||
s->addWithLabel("OMX PLAYER AUDIO DEVICE", omx_audio_dev);
|
||||
s->addSaveFunc([omx_audio_dev] {
|
||||
if (Settings::getInstance()->getString("OMXAudioDev") != omx_audio_dev->getSelected())
|
||||
Settings::getInstance()->setString("OMXAudioDev", omx_audio_dev->getSelected());
|
||||
});
|
||||
#endif
|
||||
auto video_audio = std::make_shared<SwitchComponent>(mWindow);
|
||||
video_audio->setState(Settings::getInstance()->getBool("VideoAudio"));
|
||||
s->addWithLabel("ENABLE VIDEO AUDIO", video_audio);
|
||||
s->addSaveFunc([video_audio] { Settings::getInstance()->setBool("VideoAudio", video_audio->getState()); });
|
||||
// show help
|
||||
auto show_help = std::make_shared<SwitchComponent>(mWindow);
|
||||
show_help->setState(Settings::getInstance()->getBool("ShowHelpPrompts"));
|
||||
s->addWithLabel("ON-SCREEN HELP", show_help);
|
||||
s->addSaveFunc([show_help] { Settings::getInstance()->setBool("ShowHelpPrompts", show_help->getState()); });
|
||||
|
||||
mWindow->pushGui(s);
|
||||
});
|
||||
|
@ -263,12 +253,39 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
|
|||
s->addWithLabel("PARSE GAMESLISTS ONLY", parse_gamelists);
|
||||
s->addSaveFunc([parse_gamelists] { Settings::getInstance()->setBool("ParseGamelistOnly", parse_gamelists->getState()); });
|
||||
|
||||
#ifdef _RPI_
|
||||
// Video Player - VideoOmxPlayer
|
||||
auto omx_player = std::make_shared<SwitchComponent>(mWindow);
|
||||
omx_player->setState(Settings::getInstance()->getBool("VideoOmxPlayer"));
|
||||
s->addWithLabel("USE OMX PLAYER (HW ACCELERATED)", omx_player);
|
||||
s->addSaveFunc([omx_player]
|
||||
{
|
||||
// need to reload all views to re-create the right video components
|
||||
bool needReload = false;
|
||||
if(Settings::getInstance()->getBool("VideoOmxPlayer") != omx_player->getState())
|
||||
needReload = true;
|
||||
|
||||
Settings::getInstance()->setBool("VideoOmxPlayer", omx_player->getState());
|
||||
|
||||
if(needReload)
|
||||
ViewController::get()->reloadAll();
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
// maximum vram
|
||||
auto max_vram = std::make_shared<SliderComponent>(mWindow, 0.f, 1000.f, 10.f, "Mb");
|
||||
max_vram->setValue((float)(Settings::getInstance()->getInt("MaxVRAM")));
|
||||
s->addWithLabel("VRAM LIMIT", max_vram);
|
||||
s->addSaveFunc([max_vram] { Settings::getInstance()->setInt("MaxVRAM", (int)round(max_vram->getValue())); });
|
||||
|
||||
// framerate
|
||||
auto framerate = std::make_shared<SwitchComponent>(mWindow);
|
||||
framerate->setState(Settings::getInstance()->getBool("DrawFramerate"));
|
||||
s->addWithLabel("SHOW FRAMERATE", framerate);
|
||||
s->addSaveFunc([framerate] { Settings::getInstance()->setBool("DrawFramerate", framerate->getState()); });
|
||||
|
||||
|
||||
mWindow->pushGui(s);
|
||||
});
|
||||
|
||||
|
@ -351,6 +368,11 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
|
|||
setPosition((Renderer::getScreenWidth() - mSize.x()) / 2, Renderer::getScreenHeight() * 0.15f);
|
||||
}
|
||||
|
||||
void GuiMenu::openScreensaverOptions() {
|
||||
GuiScreensaverOptions* ggf = new GuiScreensaverOptions(mWindow, "VIDEO SCREENSAVER");
|
||||
mWindow->pushGui(ggf);
|
||||
}
|
||||
|
||||
void GuiMenu::onSizeChanged()
|
||||
{
|
||||
mVersion.setSize(mSize.x(), 0);
|
||||
|
|
|
@ -16,7 +16,7 @@ public:
|
|||
|
||||
private:
|
||||
void addEntry(const char* name, unsigned int color, bool add_arrow, const std::function<void()>& func);
|
||||
|
||||
void openScreensaverOptions();
|
||||
MenuComponent mMenu;
|
||||
TextComponent mVersion;
|
||||
};
|
||||
|
|
125
es-app/src/guis/GuiScreensaverOptions.cpp
Normal file
125
es-app/src/guis/GuiScreensaverOptions.cpp
Normal file
|
@ -0,0 +1,125 @@
|
|||
#include "guis/GuiScreensaverOptions.h"
|
||||
#include "Window.h"
|
||||
#include "Settings.h"
|
||||
#include "views/ViewController.h"
|
||||
|
||||
#include "components/ButtonComponent.h"
|
||||
#include "components/SwitchComponent.h"
|
||||
#include "components/SliderComponent.h"
|
||||
#include "components/TextComponent.h"
|
||||
#include "components/OptionListComponent.h"
|
||||
#include "components/MenuComponent.h"
|
||||
#include "guis/GuiMsgBox.h"
|
||||
|
||||
GuiScreensaverOptions::GuiScreensaverOptions(Window* window, const char* title) : GuiComponent(window), mMenu(window, title)
|
||||
{
|
||||
addChild(&mMenu);
|
||||
|
||||
#ifdef _RPI_
|
||||
auto ss_omx = std::make_shared<SwitchComponent>(mWindow);
|
||||
ss_omx->setState(Settings::getInstance()->getBool("ScreenSaverOmxPlayer"));
|
||||
addWithLabel("USE OMX PLAYER FOR SCREENSAVER", ss_omx);
|
||||
addSaveFunc([ss_omx, this] { Settings::getInstance()->setBool("ScreenSaverOmxPlayer", ss_omx->getState()); });
|
||||
#endif
|
||||
|
||||
// Allow ScreenSaver Controls - ScreenSaverControls
|
||||
auto ss_controls = std::make_shared<SwitchComponent>(mWindow);
|
||||
ss_controls->setState(Settings::getInstance()->getBool("ScreenSaverControls"));
|
||||
addWithLabel("SCREENSAVER CONTROLS", ss_controls);
|
||||
addSaveFunc([ss_controls] { Settings::getInstance()->setBool("ScreenSaverControls", ss_controls->getState()); });
|
||||
|
||||
// Render Video Game Name as subtitles
|
||||
auto ss_info = std::make_shared< OptionListComponent<std::string> >(mWindow, "SHOW GAME INFO", false);
|
||||
std::vector<std::string> info_type;
|
||||
info_type.push_back("always");
|
||||
info_type.push_back("start & end");
|
||||
info_type.push_back("never");
|
||||
for(auto it = info_type.begin(); it != info_type.end(); it++)
|
||||
ss_info->add(*it, *it, Settings::getInstance()->getString("ScreenSaverGameInfo") == *it);
|
||||
addWithLabel("SHOW GAME INFO ON SCREENSAVER", ss_info);
|
||||
addSaveFunc([ss_info, this] { Settings::getInstance()->setString("ScreenSaverGameInfo", ss_info->getSelected()); });
|
||||
|
||||
#ifndef _RPI_
|
||||
auto captions_compatibility = std::make_shared<SwitchComponent>(mWindow);
|
||||
captions_compatibility->setState(Settings::getInstance()->getBool("CaptionsCompatibility"));
|
||||
addWithLabel("USE COMPATIBLE LOW RESOLUTION FOR CAPTIONS", captions_compatibility);
|
||||
addSaveFunc([captions_compatibility] { Settings::getInstance()->setBool("CaptionsCompatibility", captions_compatibility->getState()); });
|
||||
#endif
|
||||
|
||||
auto stretch_screensaver = std::make_shared<SwitchComponent>(mWindow);
|
||||
stretch_screensaver->setState(Settings::getInstance()->getBool("StretchVideoOnScreenSaver"));
|
||||
addWithLabel("STRETCH VIDEO ON SCREENSAVER", stretch_screensaver);
|
||||
addSaveFunc([stretch_screensaver] { Settings::getInstance()->setBool("StretchVideoOnScreenSaver", stretch_screensaver->getState()); });
|
||||
|
||||
mMenu.addButton("BACK", "go back", [this] { delete this; });
|
||||
|
||||
setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
|
||||
mMenu.setPosition((mSize.x() - mMenu.getSize().x()) / 2, Renderer::getScreenHeight() * 0.15f);
|
||||
}
|
||||
|
||||
GuiScreensaverOptions::~GuiScreensaverOptions()
|
||||
{
|
||||
save();
|
||||
}
|
||||
|
||||
void GuiScreensaverOptions::save()
|
||||
{
|
||||
if(!mSaveFuncs.size())
|
||||
return;
|
||||
|
||||
#ifdef _RPI_
|
||||
bool startingStatusNotRisky = (Settings::getInstance()->getString("ScreenSaverGameInfo") == "never" || !Settings::getInstance()->getBool("ScreenSaverOmxPlayer"));
|
||||
#endif
|
||||
|
||||
for(auto it = mSaveFuncs.begin(); it != mSaveFuncs.end(); it++)
|
||||
(*it)();
|
||||
|
||||
Settings::getInstance()->saveFile();
|
||||
|
||||
#ifdef _RPI_
|
||||
bool endStatusRisky = (Settings::getInstance()->getString("ScreenSaverGameInfo") != "never" && Settings::getInstance()->getBool("ScreenSaverOmxPlayer"));
|
||||
if (startingStatusNotRisky && endStatusRisky) {
|
||||
// if before it wasn't risky but now there's a risk of problems, show warning
|
||||
mWindow->pushGui(new GuiMsgBox(mWindow,
|
||||
"Using OMX Player and displaying Game Info may result in the video flickering in some TV modes. If that happens, consider:\n\n• Disabling the \"Show Game Info\" option;\n• Disabling \"Overscan\" on the Pi configuration menu might help:\nRetroPie > Raspi-Config > Advanced Options > Overscan > \"No\".\n• Disabling the use of OMX Player for the screensaver.",
|
||||
"GOT IT!", [] { return; }));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GuiScreensaverOptions::input(InputConfig* config, Input input)
|
||||
{
|
||||
if(config->isMappedTo("b", input) && input.value != 0)
|
||||
{
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(config->isMappedTo("start", input) && input.value != 0)
|
||||
{
|
||||
// close everything
|
||||
Window* window = mWindow;
|
||||
while(window->peekGui() && window->peekGui() != ViewController::get())
|
||||
delete window->peekGui();
|
||||
return true;
|
||||
}
|
||||
|
||||
return GuiComponent::input(config, input);
|
||||
}
|
||||
|
||||
HelpStyle GuiScreensaverOptions::getHelpStyle()
|
||||
{
|
||||
HelpStyle style = HelpStyle();
|
||||
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system");
|
||||
return style;
|
||||
}
|
||||
|
||||
std::vector<HelpPrompt> GuiScreensaverOptions::getHelpPrompts()
|
||||
{
|
||||
std::vector<HelpPrompt> prompts = mMenu.getHelpPrompts();
|
||||
|
||||
prompts.push_back(HelpPrompt("b", "back"));
|
||||
prompts.push_back(HelpPrompt("start", "close"));
|
||||
|
||||
return prompts;
|
||||
}
|
24
es-app/src/guis/GuiScreensaverOptions.h
Normal file
24
es-app/src/guis/GuiScreensaverOptions.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "GuiComponent.h"
|
||||
#include "components/MenuComponent.h"
|
||||
#include "SystemData.h"
|
||||
|
||||
// This is just a really simple template for a GUI that calls some save functions when closed.
|
||||
class GuiScreensaverOptions : public GuiComponent
|
||||
{
|
||||
public:
|
||||
GuiScreensaverOptions(Window* window, const char* title);
|
||||
virtual ~GuiScreensaverOptions(); // just calls save();
|
||||
|
||||
void save();
|
||||
inline void addRow(const ComponentListRow& row) { mMenu.addRow(row); };
|
||||
inline void addWithLabel(const std::string& label, const std::shared_ptr<GuiComponent>& comp) { mMenu.addWithLabel(label, comp); };
|
||||
inline void addSaveFunc(const std::function<void()>& func) { mSaveFuncs.push_back(func); };
|
||||
|
||||
bool input(InputConfig* config, Input input) override;
|
||||
std::vector<HelpPrompt> getHelpPrompts() override;
|
||||
HelpStyle getHelpStyle() override;
|
||||
|
||||
private:
|
||||
MenuComponent mMenu;
|
||||
std::vector< std::function<void()> > mSaveFuncs;
|
||||
};
|
|
@ -158,6 +158,12 @@ bool SystemView::input(InputConfig* config, Input input)
|
|||
config->isMappedTo("up", input) ||
|
||||
config->isMappedTo("down", input))
|
||||
listInput(0);
|
||||
if(config->isMappedTo("select", input) && Settings::getInstance()->getBool("ScreenSaverControls"))
|
||||
{
|
||||
mWindow->startScreenSaver();
|
||||
mWindow->renderScreenSaver();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return GuiComponent::input(config, input);
|
||||
|
@ -348,6 +354,10 @@ std::vector<HelpPrompt> SystemView::getHelpPrompts()
|
|||
prompts.push_back(HelpPrompt("left/right", "choose"));
|
||||
prompts.push_back(HelpPrompt("a", "select"));
|
||||
prompts.push_back(HelpPrompt("x", "random"));
|
||||
|
||||
if (Settings::getInstance()->getBool("ScreenSaverControls"))
|
||||
prompts.push_back(HelpPrompt("select", "launch screensaver"));
|
||||
|
||||
return prompts;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,10 +19,10 @@ public:
|
|||
virtual const char* getName() const override { return "basic"; }
|
||||
|
||||
virtual std::vector<HelpPrompt> getHelpPrompts() override;
|
||||
virtual void launch(FileData* game) override;
|
||||
|
||||
protected:
|
||||
virtual void populateList(const std::vector<FileData*>& files) override;
|
||||
virtual void launch(FileData* game) override;
|
||||
virtual void remove(FileData* game) override;
|
||||
|
||||
TextListComponent<FileData*> mList;
|
||||
|
|
|
@ -14,7 +14,6 @@ public:
|
|||
|
||||
virtual const char* getName() const override { return "detailed"; }
|
||||
|
||||
protected:
|
||||
virtual void launch(FileData* game) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -20,10 +20,10 @@ public:
|
|||
virtual const char* getName() const override { return "grid"; }
|
||||
|
||||
virtual std::vector<HelpPrompt> getHelpPrompts() override;
|
||||
virtual void launch(FileData* game) override;
|
||||
|
||||
protected:
|
||||
virtual void populateList(const std::vector<FileData*>& files) override;
|
||||
virtual void launch(FileData* game) override;
|
||||
|
||||
ImageGridComponent<FileData*> mGrid;
|
||||
};
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
virtual void remove(FileData* game) = 0;
|
||||
|
||||
virtual const char* getName() const = 0;
|
||||
virtual void launch(FileData* game) = 0;
|
||||
|
||||
virtual HelpStyle getHelpStyle() override;
|
||||
|
||||
|
|
|
@ -23,10 +23,10 @@ public:
|
|||
virtual void setCursor(FileData*) = 0;
|
||||
|
||||
virtual bool input(InputConfig* config, Input input) override;
|
||||
virtual void launch(FileData* game) = 0;
|
||||
|
||||
protected:
|
||||
virtual void populateList(const std::vector<FileData*>& files) = 0;
|
||||
virtual void launch(FileData* game) = 0;
|
||||
|
||||
TextComponent mHeaderText;
|
||||
ImageComponent mHeaderImage;
|
||||
|
|
|
@ -29,11 +29,11 @@ VideoGameListView::VideoGameListView(Window* window, FileData* root) :
|
|||
// Create the correct type of video window
|
||||
#ifdef _RPI_
|
||||
if (Settings::getInstance()->getBool("VideoOmxPlayer"))
|
||||
mVideo = new VideoPlayerComponent(window);
|
||||
mVideo = new VideoPlayerComponent(window, "");
|
||||
else
|
||||
mVideo = new VideoVlcComponent(window);
|
||||
mVideo = new VideoVlcComponent(window, getTitlePath());
|
||||
#else
|
||||
mVideo = new VideoVlcComponent(window);
|
||||
mVideo = new VideoVlcComponent(window, getTitlePath());
|
||||
#endif
|
||||
|
||||
mList.setPosition(mSize.x() * (0.50f + padding), mList.getPosition().y());
|
||||
|
@ -227,6 +227,8 @@ void VideoGameListView::updateInfoPanel()
|
|||
{
|
||||
FileData* file = (mList.size() == 0 || mList.isScrolling()) ? NULL : mList.getSelected();
|
||||
|
||||
boost::filesystem::remove(getTitlePath().c_str());
|
||||
|
||||
bool fadingOut;
|
||||
if(file == NULL)
|
||||
{
|
||||
|
|
|
@ -17,10 +17,9 @@ public:
|
|||
virtual void onThemeChanged(const std::shared_ptr<ThemeData>& theme) override;
|
||||
|
||||
virtual const char* getName() const override { return "video"; }
|
||||
virtual void launch(FileData* game) override;
|
||||
|
||||
protected:
|
||||
virtual void launch(FileData* game) override;
|
||||
|
||||
virtual void update(int deltaTime) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -77,10 +77,22 @@ void Settings::setDefaults()
|
|||
mStringMap["Scraper"] = "TheGamesDB";
|
||||
mStringMap["GamelistViewStyle"] = "automatic";
|
||||
|
||||
mBoolMap["ScreenSaverControls"] = true;
|
||||
mStringMap["ScreenSaverGameInfo"] = "never";
|
||||
mBoolMap["StretchVideoOnScreenSaver"] = false;
|
||||
|
||||
// This setting only applies to raspberry pi but set it for all platforms so
|
||||
// we don't get a warning if we encounter it on a different platform
|
||||
mBoolMap["VideoOmxPlayer"] = false;
|
||||
#ifdef _RPI_
|
||||
// we're defaulting to OMX Player for full screen video on the Pi
|
||||
mBoolMap["ScreenSaverOmxPlayer"] = true;
|
||||
#else
|
||||
mBoolMap["ScreenSaverOmxPlayer"] = false;
|
||||
#endif
|
||||
|
||||
mBoolMap["VideoAudio"] = true;
|
||||
mBoolMap["CaptionsCompatibility"] = true;
|
||||
// Audio out device for Video playback using OMX player.
|
||||
mStringMap["OMXAudioDev"] = "both";
|
||||
|
||||
|
|
|
@ -115,13 +115,34 @@ void Window::textInput(const char* text)
|
|||
|
||||
void Window::input(InputConfig* config, Input input)
|
||||
{
|
||||
if (mRenderScreenSaver)
|
||||
{
|
||||
mRenderScreenSaver = false;
|
||||
|
||||
// Tell the GUI components the screensaver has stopped
|
||||
for(auto i = mGuiStack.begin(); i != mGuiStack.end(); i++)
|
||||
(*i)->onScreenSaverDeactivate();
|
||||
if (mScreenSaver) {
|
||||
if(mScreenSaver->isScreenSaverActive() && Settings::getInstance()->getBool("ScreenSaverControls") &&
|
||||
(Settings::getInstance()->getString("ScreenSaverBehavior") == "random video"))
|
||||
{
|
||||
if(mScreenSaver->getCurrentGame() != NULL && (config->isMappedTo("right", input) || config->isMappedTo("start", input) || config->isMappedTo("select", input)))
|
||||
{
|
||||
if(config->isMappedTo("right", input) || config->isMappedTo("select", input))
|
||||
{
|
||||
if (input.value != 0) {
|
||||
// handle screensaver control
|
||||
mScreenSaver->nextVideo();
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(config->isMappedTo("start", input))
|
||||
{
|
||||
// launch game!
|
||||
cancelScreenSaver();
|
||||
mScreenSaver->launchGame();
|
||||
// to force handling the wake up process
|
||||
mSleeping = true;
|
||||
}
|
||||
}
|
||||
else if(input.value != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(mSleeping)
|
||||
|
@ -377,35 +398,35 @@ bool Window::isProcessing()
|
|||
return count_if(mGuiStack.begin(), mGuiStack.end(), [](GuiComponent* c) { return c->isProcessing(); }) > 0;
|
||||
}
|
||||
|
||||
void Window::startScreenSaver()
|
||||
{
|
||||
if (mScreenSaver && !mRenderScreenSaver)
|
||||
{
|
||||
// Tell the GUI components the screensaver is starting
|
||||
for(auto i = mGuiStack.begin(); i != mGuiStack.end(); i++)
|
||||
(*i)->onScreenSaverActivate();
|
||||
|
||||
mScreenSaver->startScreenSaver();
|
||||
mRenderScreenSaver = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Window::cancelScreenSaver()
|
||||
{
|
||||
if (mScreenSaver && mRenderScreenSaver)
|
||||
{
|
||||
mScreenSaver->stopScreenSaver();
|
||||
mRenderScreenSaver = false;
|
||||
|
||||
// Tell the GUI components the screensaver has stopped
|
||||
for(auto i = mGuiStack.begin(); i != mGuiStack.end(); i++)
|
||||
(*i)->onScreenSaverDeactivate();
|
||||
}
|
||||
}
|
||||
|
||||
void Window::renderScreenSaver()
|
||||
{
|
||||
if (mScreenSaver)
|
||||
mScreenSaver->renderScreenSaver();
|
||||
void Window::startScreenSaver()
|
||||
{
|
||||
if (mScreenSaver && !mRenderScreenSaver)
|
||||
{
|
||||
// Tell the GUI components the screensaver is starting
|
||||
for(auto i = mGuiStack.begin(); i != mGuiStack.end(); i++)
|
||||
(*i)->onScreenSaverActivate();
|
||||
|
||||
mScreenSaver->startScreenSaver();
|
||||
mRenderScreenSaver = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Window::cancelScreenSaver()
|
||||
{
|
||||
if (mScreenSaver && mRenderScreenSaver)
|
||||
{
|
||||
mScreenSaver->stopScreenSaver();
|
||||
mRenderScreenSaver = false;
|
||||
|
||||
// Tell the GUI components the screensaver has stopped
|
||||
for(auto i = mGuiStack.begin(); i != mGuiStack.end(); i++)
|
||||
(*i)->onScreenSaverDeactivate();
|
||||
}
|
||||
}
|
||||
|
||||
void Window::renderScreenSaver()
|
||||
{
|
||||
if (mScreenSaver)
|
||||
mScreenSaver->renderScreenSaver();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "resources/Font.h"
|
||||
#include "InputManager.h"
|
||||
|
||||
class FileData;
|
||||
class HelpComponent;
|
||||
class ImageComponent;
|
||||
|
||||
|
@ -15,9 +16,13 @@ public:
|
|||
public:
|
||||
virtual void startScreenSaver() = 0;
|
||||
virtual void stopScreenSaver() = 0;
|
||||
virtual void nextVideo() = 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;
|
||||
};
|
||||
|
||||
Window();
|
||||
|
@ -49,16 +54,17 @@ public:
|
|||
|
||||
void setScreenSaver(ScreenSaver* screenSaver) { mScreenSaver = screenSaver; }
|
||||
|
||||
void startScreenSaver();
|
||||
void cancelScreenSaver();
|
||||
void renderScreenSaver();
|
||||
|
||||
private:
|
||||
void onSleep();
|
||||
void onWake();
|
||||
|
||||
// Returns true if at least one component on the stack is processing
|
||||
bool isProcessing();
|
||||
void renderScreenSaver();
|
||||
void startScreenSaver();
|
||||
void cancelScreenSaver();
|
||||
|
||||
|
||||
HelpComponent* mHelp;
|
||||
ImageComponent* mBackgroundOverlay;
|
||||
ScreenSaver* mScreenSaver;
|
||||
|
@ -71,7 +77,6 @@ private:
|
|||
int mFrameTimeElapsed;
|
||||
int mFrameCountElapsed;
|
||||
int mAverageDeltaTime;
|
||||
bool mRenderScreenSaver;
|
||||
|
||||
std::unique_ptr<TextCache> mFrameDataText;
|
||||
|
||||
|
|
|
@ -9,6 +9,45 @@
|
|||
|
||||
#define FADE_TIME_MS 200
|
||||
|
||||
std::string getTitlePath() {
|
||||
std::string titleFolder = getTitleFolder();
|
||||
return titleFolder + "last_title.srt";
|
||||
}
|
||||
|
||||
std::string getTitleFolder() {
|
||||
std::string home = getHomePath();
|
||||
return home + "/.emulationstation/tmp/";
|
||||
}
|
||||
|
||||
void writeSubtitle(const char* gameName, const char* systemName, bool always)
|
||||
{
|
||||
FILE* file = fopen(getTitlePath().c_str(), "w");
|
||||
if (always) {
|
||||
fprintf(file, "1\n00:00:01,000 --> 00:00:30,000\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, "1\n00:00:01,000 --> 00:00:08,000\n");
|
||||
}
|
||||
fprintf(file, "%s\n", gameName);
|
||||
fprintf(file, "<i>%s</i>\n\n", systemName);
|
||||
|
||||
if (!always) {
|
||||
fprintf(file, "2\n00:00:26,000 --> 00:00:30,000\n");
|
||||
fprintf(file, "%s\n", gameName);
|
||||
fprintf(file, "<i>%s</i>\n", systemName);
|
||||
}
|
||||
|
||||
fflush(file);
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
void VideoComponent::setScreensaverMode(bool isScreensaver)
|
||||
{
|
||||
mScreensaverMode = isScreensaver;
|
||||
}
|
||||
|
||||
VideoComponent::VideoComponent(Window* window) :
|
||||
GuiComponent(window),
|
||||
mStaticImage(window),
|
||||
|
@ -19,6 +58,7 @@ VideoComponent::VideoComponent(Window* window) :
|
|||
mShowing(false),
|
||||
mScreensaverActive(false),
|
||||
mDisable(false),
|
||||
mScreensaverMode(false),
|
||||
mTargetIsMax(false),
|
||||
mOrigin(0, 0),
|
||||
mTargetSize(0, 0)
|
||||
|
@ -31,12 +71,17 @@ VideoComponent::VideoComponent(Window* window) :
|
|||
topWindow(false);
|
||||
}
|
||||
|
||||
std::string path = getTitleFolder();
|
||||
if(!boost::filesystem::exists(path))
|
||||
boost::filesystem::create_directory(path);
|
||||
}
|
||||
|
||||
VideoComponent::~VideoComponent()
|
||||
{
|
||||
// Stop any currently running video
|
||||
stopVideo();
|
||||
// Delete subtitle file, if existing
|
||||
remove(getTitlePath().c_str());
|
||||
}
|
||||
|
||||
void VideoComponent::setOrigin(float originX, float originY)
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
#include <SDL_mutex.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
std::string getTitlePath();
|
||||
std::string getTitleFolder();
|
||||
void writeSubtitle(const char* gameName, const char* systemName, bool always);
|
||||
|
||||
class VideoComponent : public GuiComponent
|
||||
{
|
||||
// Structure that groups together the configuration of the video component
|
||||
|
@ -35,6 +39,9 @@ public:
|
|||
// Configures the component to show the default video
|
||||
void setDefaultVideo();
|
||||
|
||||
// sets whether it's going to render in screensaver mode
|
||||
void setScreensaverMode(bool isScreensaver);
|
||||
|
||||
virtual void onShow() override;
|
||||
virtual void onHide() override;
|
||||
virtual void onScreenSaverActivate() override;
|
||||
|
@ -107,6 +114,7 @@ protected:
|
|||
bool mShowing;
|
||||
bool mDisable;
|
||||
bool mScreensaverActive;
|
||||
bool mScreensaverMode;
|
||||
bool mTargetIsMax;
|
||||
|
||||
Configuration mConfig;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#ifdef _RPI_
|
||||
#include "components/VideoPlayerComponent.h"
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include "AudioManager.h"
|
||||
#include "Renderer.h"
|
||||
#include "ThemeData.h"
|
||||
|
@ -11,9 +12,10 @@
|
|||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
VideoPlayerComponent::VideoPlayerComponent(Window* window) :
|
||||
VideoPlayerComponent::VideoPlayerComponent(Window* window, std::string path) :
|
||||
VideoComponent(window),
|
||||
mPlayerPid(-1)
|
||||
mPlayerPid(-1),
|
||||
subtitlePath(path)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -47,7 +49,8 @@ void VideoPlayerComponent::setMaxSize(float width, float height)
|
|||
|
||||
void VideoPlayerComponent::startVideo()
|
||||
{
|
||||
if (!mIsPlaying) {
|
||||
if (!mIsPlaying)
|
||||
{
|
||||
mVideoWidth = 0;
|
||||
mVideoHeight = 0;
|
||||
|
||||
|
@ -59,8 +62,11 @@ void VideoPlayerComponent::startVideo()
|
|||
// Set the video that we are going to be playing so we don't attempt to restart it
|
||||
mPlayingVideoPath = mVideoPath;
|
||||
|
||||
// Disable AudioManager so video can play
|
||||
AudioManager::getInstance()->deinit();
|
||||
// Disable AudioManager so video can play, in case we're requesting ALSA
|
||||
if (boost::starts_with(Settings::getInstance()->getString("OMXAudioDev").c_str(), "alsa"))
|
||||
{
|
||||
AudioManager::getInstance()->deinit();
|
||||
}
|
||||
|
||||
// Start the player process
|
||||
pid_t pid = fork();
|
||||
|
@ -89,7 +95,7 @@ void VideoPlayerComponent::startVideo()
|
|||
// We need to specify the layer of 10000 or above to ensure the video is displayed on top
|
||||
// of our SDL display
|
||||
|
||||
const char* argv[] = { "", "--layer", "10010", "--loop", "--no-osd", "--aspect-mode", "letterbox", "--vol", "0", "-o", "both","--win", buf, "-b", "", "", "", "", NULL };
|
||||
const char* argv[] = { "", "--layer", "10010", "--loop", "--no-osd", "--aspect-mode", "letterbox", "--vol", "0", "-o", "both","--win", buf, "--no-ghost-box", "", "", "", "", NULL };
|
||||
|
||||
// check if we want to mute the audio
|
||||
if (!Settings::getInstance()->getBool("VideoAudio"))
|
||||
|
@ -97,16 +103,43 @@ void VideoPlayerComponent::startVideo()
|
|||
argv[8] = "-1000000";
|
||||
}
|
||||
|
||||
// if we are rendering a video gamelist
|
||||
if (!mTargetIsMax)
|
||||
// test if there's a path for possible subtitles, meaning we're a screensaver video
|
||||
if (!subtitlePath.empty())
|
||||
{
|
||||
argv[6] = "stretch";
|
||||
// if we are rendering a screensaver
|
||||
|
||||
// check if we want to stretch the image
|
||||
if (Settings::getInstance()->getBool("StretchVideoOnScreenSaver"))
|
||||
{
|
||||
argv[6] = "stretch";
|
||||
}
|
||||
|
||||
if (Settings::getInstance()->getString("ScreenSaverGameInfo") != "never")
|
||||
{
|
||||
// if we have chosen to render subtitles
|
||||
argv[13] = "--subtitles";
|
||||
argv[14] = subtitlePath.c_str();
|
||||
argv[15] = mPlayingVideoPath.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we have chosen NOT to render subtitles in the screensaver
|
||||
argv[13] = mPlayingVideoPath.c_str();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we are rendering a video gamelist
|
||||
if (!mTargetIsMax)
|
||||
{
|
||||
argv[6] = "stretch";
|
||||
}
|
||||
argv[13] = mPlayingVideoPath.c_str();
|
||||
}
|
||||
|
||||
argv[10] = Settings::getInstance()->getString("OMXAudioDev").c_str();
|
||||
|
||||
argv[13] = mPlayingVideoPath.c_str();
|
||||
|
||||
//const char* argv[] = args;
|
||||
const char* env[] = { "LD_LIBRARY_PATH=/opt/vc/libs:/usr/lib/omxplayer", NULL };
|
||||
|
||||
// Redirect stdout
|
||||
|
@ -142,7 +175,10 @@ void VideoPlayerComponent::stopVideo()
|
|||
kill(mPlayerPid, SIGKILL);
|
||||
waitpid(mPlayerPid, &status, WNOHANG);
|
||||
// Restart AudioManager
|
||||
AudioManager::getInstance()->init();
|
||||
if (boost::starts_with(Settings::getInstance()->getString("OMXAudioDev").c_str(), "alsa"))
|
||||
{
|
||||
AudioManager::getInstance()->init();
|
||||
}
|
||||
mPlayerPid = -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ void catch_child(int sig_num);
|
|||
class VideoPlayerComponent : public VideoComponent
|
||||
{
|
||||
public:
|
||||
VideoPlayerComponent(Window* window);
|
||||
VideoPlayerComponent(Window* window, std::string path);
|
||||
virtual ~VideoPlayerComponent();
|
||||
|
||||
void render(const Eigen::Affine3f& parentTrans) override;
|
||||
|
@ -36,6 +36,7 @@ private:
|
|||
|
||||
private:
|
||||
pid_t mPlayerPid;
|
||||
std::string subtitlePath;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,26 +11,26 @@ libvlc_instance_t* VideoVlcComponent::mVLC = NULL;
|
|||
|
||||
// VLC prepares to render a video frame.
|
||||
static void *lock(void *data, void **p_pixels) {
|
||||
struct VideoContext *c = (struct VideoContext *)data;
|
||||
SDL_LockMutex(c->mutex);
|
||||
SDL_LockSurface(c->surface);
|
||||
struct VideoContext *c = (struct VideoContext *)data;
|
||||
SDL_LockMutex(c->mutex);
|
||||
SDL_LockSurface(c->surface);
|
||||
*p_pixels = c->surface->pixels;
|
||||
return NULL; // Picture identifier, not needed here.
|
||||
return NULL; // Picture identifier, not needed here.
|
||||
}
|
||||
|
||||
// VLC just rendered a video frame.
|
||||
static void unlock(void *data, void *id, void *const *p_pixels) {
|
||||
struct VideoContext *c = (struct VideoContext *)data;
|
||||
SDL_UnlockSurface(c->surface);
|
||||
SDL_UnlockMutex(c->mutex);
|
||||
struct VideoContext *c = (struct VideoContext *)data;
|
||||
SDL_UnlockSurface(c->surface);
|
||||
SDL_UnlockMutex(c->mutex);
|
||||
}
|
||||
|
||||
// VLC wants to display a video frame.
|
||||
static void display(void *data, void *id) {
|
||||
//Data to be displayed
|
||||
//Data to be displayed
|
||||
}
|
||||
|
||||
VideoVlcComponent::VideoVlcComponent(Window* window) :
|
||||
VideoVlcComponent::VideoVlcComponent(Window* window, std::string subtitles) :
|
||||
VideoComponent(window),
|
||||
mMediaPlayer(nullptr)
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ VideoVlcComponent::VideoVlcComponent(Window* window) :
|
|||
mTexture = TextureResource::get("");
|
||||
|
||||
// Make sure VLC has been initialised
|
||||
setupVLC();
|
||||
setupVLC(subtitles);
|
||||
}
|
||||
|
||||
VideoVlcComponent::~VideoVlcComponent()
|
||||
|
@ -227,13 +227,27 @@ void VideoVlcComponent::freeContext()
|
|||
}
|
||||
}
|
||||
|
||||
void VideoVlcComponent::setupVLC()
|
||||
void VideoVlcComponent::setupVLC(std::string subtitles)
|
||||
{
|
||||
// If VLC hasn't been initialised yet then do it now
|
||||
if (!mVLC)
|
||||
{
|
||||
const char* args[] = { "--quiet" };
|
||||
mVLC = libvlc_new(sizeof(args) / sizeof(args[0]), args);
|
||||
const char** args;
|
||||
const char* newargs[] = { "--quiet", "--sub-file", subtitles.c_str() };
|
||||
const char* singleargs[] = { "--quiet" };
|
||||
int argslen = 0;
|
||||
|
||||
if (!subtitles.empty())
|
||||
{
|
||||
argslen = sizeof(newargs) / sizeof(newargs[0]);
|
||||
args = newargs;
|
||||
}
|
||||
else
|
||||
{
|
||||
argslen = sizeof(singleargs) / sizeof(singleargs[0]);
|
||||
args = singleargs;
|
||||
}
|
||||
mVLC = libvlc_new(argslen, args);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,10 +306,31 @@ void VideoVlcComponent::startVideo()
|
|||
// Make sure we found a valid video track
|
||||
if ((mVideoWidth > 0) && (mVideoHeight > 0))
|
||||
{
|
||||
#ifndef _RPI_
|
||||
if (mScreensaverMode)
|
||||
{
|
||||
if(!Settings::getInstance()->getBool("CaptionsCompatibility")) {
|
||||
|
||||
Eigen::Vector2f resizeScale((Renderer::getScreenWidth() / mVideoWidth), (Renderer::getScreenHeight() / mVideoHeight));
|
||||
|
||||
if(resizeScale.x() < resizeScale.y())
|
||||
{
|
||||
mVideoWidth *= resizeScale.x();
|
||||
mVideoHeight *= resizeScale.x();
|
||||
}else{
|
||||
mVideoWidth *= resizeScale.y();
|
||||
mVideoHeight *= resizeScale.y();
|
||||
}
|
||||
mVideoHeight = round(mVideoHeight);
|
||||
mVideoWidth = round(mVideoWidth);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
setupContext();
|
||||
|
||||
// Setup the media player
|
||||
mMediaPlayer = libvlc_media_player_new_from_media(mMedia);
|
||||
|
||||
if (!Settings::getInstance()->getBool("VideoAudio"))
|
||||
{
|
||||
libvlc_audio_set_mute(mMediaPlayer, 1);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "VideoComponent.h"
|
||||
#include <vlc/vlc.h>
|
||||
#include <vlc/libvlc_media.h>
|
||||
#include "resources/TextureResource.h"
|
||||
|
||||
struct VideoContext {
|
||||
|
@ -26,9 +27,9 @@ class VideoVlcComponent : public VideoComponent
|
|||
};
|
||||
|
||||
public:
|
||||
static void setupVLC();
|
||||
static void setupVLC(std::string subtitles);
|
||||
|
||||
VideoVlcComponent(Window* window);
|
||||
VideoVlcComponent(Window* window, std::string subtitles);
|
||||
virtual ~VideoVlcComponent();
|
||||
|
||||
void render(const Eigen::Affine3f& parentTrans) override;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
std::string getHomePath();
|
||||
|
||||
|
||||
int runShutdownCommand(); // shut down the system (returns 0 if successful)
|
||||
int runRestartCommand(); // restart the system (returns 0 if successful)
|
||||
int runSystemCommand(const std::string& cmd_utf8); // run a utf-8 encoded in the shell (requires wstring conversion on Windows)
|
||||
|
|
Loading…
Reference in a new issue