Changes from fieldofcows to separate screensaver into separate module, squashed by pjft.

This commit is contained in:
fieldofcows 2016-12-14 08:30:54 +00:00 committed by pjft
parent 2f1e03a500
commit 0d04633954
10 changed files with 327 additions and 19 deletions

View file

@ -11,6 +11,7 @@ set(ES_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/VolumeControl.h
${CMAKE_CURRENT_SOURCE_DIR}/src/Gamelist.h
${CMAKE_CURRENT_SOURCE_DIR}/src/FileFilterIndex.h
${CMAKE_CURRENT_SOURCE_DIR}/src/SystemScreenSaver.h
# GuiComponents
${CMAKE_CURRENT_SOURCE_DIR}/src/components/AsyncReqComponent.h
@ -60,6 +61,7 @@ set(ES_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/VolumeControl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/Gamelist.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/FileFilterIndex.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/SystemScreenSaver.cpp
# GuiComponents
${CMAKE_CURRENT_SOURCE_DIR}/src/components/AsyncReqComponent.cpp

View file

@ -0,0 +1,217 @@
#include "SystemScreenSaver.h"
#ifdef _RPI_
#include "components/VideoPlayerComponent.h"
#endif
#include "components/VideoVlcComponent.h"
#include "Renderer.h"
#include "Settings.h"
#include "SystemData.h"
#include "Util.h"
#define FADE_TIME 3000
#define SWAP_VIDEO_TIMEOUT 30000
SystemScreenSaver::SystemScreenSaver(Window* window) :
mVideoScreensaver(NULL),
mWindow(window),
mCounted(false),
mVideoCount(0),
mState(STATE_INACTIVE),
mOpacity(0.0f),
mTimer(0)
{
mWindow->setScreenSaver(this);
}
SystemScreenSaver::~SystemScreenSaver()
{
delete mVideoScreensaver;
}
bool SystemScreenSaver::allowSleep()
{
return false;
}
void SystemScreenSaver::startScreenSaver()
{
if (!mVideoScreensaver && (Settings::getInstance()->getString("ScreenSaverBehavior") == "random video"))
{
// Configure to fade out the windows
mState = STATE_FADE_OUT_WINDOW;
mOpacity = 0.0f;
// Load a random video
std::string path;
pickRandomVideo(path);
if (!path.empty())
{
// Create the correct type of video component
#ifdef _RPI_
if (Settings::getInstance()->getBool("VideoOmxPlayer"))
mVideoScreensaver = new VideoPlayerComponent(mWindow);
else
mVideoScreensaver = new VideoVlcComponent(mWindow);
#else
mVideoScreensaver = new VideoVlcComponent(mWindow);
#endif
mVideoScreensaver->setOrigin(0.0f, 0.0f);
mVideoScreensaver->setPosition(0.0f, 0.0f);
mVideoScreensaver->setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
mVideoScreensaver->setVideo(path);
mVideoScreensaver->onShow();
mTimer = 0;
}
else
{
// No videos. Just use a standard screensaver
mState = STATE_SCREENSAVER_ACTIVE;
}
}
}
void SystemScreenSaver::stopScreenSaver()
{
delete mVideoScreensaver;
mVideoScreensaver = NULL;
mState = STATE_INACTIVE;
}
void SystemScreenSaver::renderScreenSaver()
{
if (mVideoScreensaver)
{
// 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)
{
Renderer::setMatrix(Eigen::Affine3f::Identity());
unsigned char opacity = Settings::getInstance()->getString("ScreenSaverBehavior") == "dim" ? 0xA0 : 0xFF;
Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0x00000000 | opacity);
}
}
void SystemScreenSaver::countVideos()
{
if (!mCounted)
{
mVideoCount = 0;
mCounted = true;
std::vector<SystemData*>:: iterator it;
for (it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); ++it)
{
pugi::xml_document doc;
pugi::xml_node root;
std::string xmlReadPath = (*it)->getGamelistPath(false);
if(boost::filesystem::exists(xmlReadPath))
{
pugi::xml_parse_result result = doc.load_file(xmlReadPath.c_str());
if (!result)
continue;
root = doc.child("gameList");
if (!root)
continue;
for(pugi::xml_node fileNode = root.child("game"); fileNode; fileNode = fileNode.next_sibling("game"))
{
pugi::xml_node videoNode = fileNode.child("video");
if (videoNode)
++mVideoCount;
}
}
}
}
}
void SystemScreenSaver::pickRandomVideo(std::string& path)
{
countVideos();
if (mVideoCount > 0)
{
srand((unsigned int)time(NULL));
int video = (int)(((float)rand() / float(RAND_MAX)) * (float)mVideoCount);
std::vector<SystemData*>:: iterator it;
for (it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); ++it)
{
pugi::xml_document doc;
pugi::xml_node root;
std::string xmlReadPath = (*it)->getGamelistPath(false);
if(boost::filesystem::exists(xmlReadPath))
{
pugi::xml_parse_result result = doc.load_file(xmlReadPath.c_str());
if (!result)
continue;
root = doc.child("gameList");
if (!root)
continue;
for(pugi::xml_node fileNode = root.child("game"); fileNode; fileNode = fileNode.next_sibling("game"))
{
pugi::xml_node videoNode = fileNode.child("video");
if (videoNode)
{
// See if this is the randomly selected video
if (video-- == 0)
{
// Yes. Resolve to a full path
path = resolvePath(videoNode.text().get(), (*it)->getStartPath(), true).generic_string();
return;
}
}
}
}
}
}
}
void SystemScreenSaver::update(int deltaTime)
{
// Use this to update the fade value for the current fade stage
if (mState == STATE_FADE_OUT_WINDOW)
{
mOpacity += (float)deltaTime / FADE_TIME;
if (mOpacity >= 1.0f)
{
mOpacity = 1.0f;
// Update to the next state
mState = STATE_FADE_IN_VIDEO;
}
}
else if (mState == STATE_FADE_IN_VIDEO)
{
mOpacity -= (float)deltaTime / FADE_TIME;
if (mOpacity <= 0.0f)
{
mOpacity = 0.0f;
// Update to the next state
mState = STATE_SCREENSAVER_ACTIVE;
}
}
else if (mState == STATE_SCREENSAVER_ACTIVE)
{
// Update the timer that swaps the videos
mTimer += deltaTime;
if (mTimer > SWAP_VIDEO_TIMEOUT)
{
stopScreenSaver();
startScreenSaver();
mState = STATE_SCREENSAVER_ACTIVE;
}
}
// If we have a loaded video then update it
if (mVideoScreensaver)
mVideoScreensaver->update(deltaTime);
}

View file

@ -0,0 +1,39 @@
#pragma once
#include "Window.h"
class VideoComponent;
// Screensaver implementation for main window
class SystemScreenSaver : public Window::ScreenSaver
{
public:
SystemScreenSaver(Window* window);
virtual ~SystemScreenSaver();
virtual void startScreenSaver();
virtual void stopScreenSaver();
virtual void renderScreenSaver();
virtual bool allowSleep();
virtual void update(int deltaTime);
private:
void countVideos();
void pickRandomVideo(std::string& path);
enum STATE {
STATE_INACTIVE,
STATE_FADE_OUT_WINDOW,
STATE_FADE_IN_VIDEO,
STATE_SCREENSAVER_ACTIVE
};
private:
bool mCounted;
unsigned long mVideoCount;
VideoComponent* mVideoScreensaver;
Window* mWindow;
STATE mState;
float mOpacity;
int mTimer;
};

View file

@ -112,10 +112,11 @@ 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, "TRANSITION STYLE", false);
auto screensaver_behavior = std::make_shared< OptionListComponent<std::string> >(mWindow, "STYLE", false);
std::vector<std::string> screensavers;
screensavers.push_back("dim");
screensavers.push_back("black");
screensavers.push_back("random video");
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);

View file

@ -14,6 +14,7 @@
#include "platform.h"
#include "Log.h"
#include "Window.h"
#include "SystemScreenSaver.h"
#include "EmulationStation.h"
#include "Settings.h"
#include "ScraperCmdLine.h"
@ -222,6 +223,7 @@ int main(int argc, char* argv[])
atexit(&onExit);
Window window;
SystemScreenSaver screensaver(&window);
ViewController::init(&window);
window.pushGui(ViewController::get());

View file

@ -87,6 +87,7 @@ public:
virtual void onShow();
virtual void onHide();
virtual void onScreenSaverActivate();
virtual void onScreenSaverDeactivate();
virtual void topWindow(bool isTop);

View file

@ -10,7 +10,7 @@
#include "components/ImageComponent.h"
Window::Window() : mNormalizeNextUpdate(false), mFrameTimeElapsed(0), mFrameCountElapsed(0), mAverageDeltaTime(10),
mAllowSleep(true), mSleeping(false), mTimeSinceLastInput(0)
mAllowSleep(true), mSleeping(false), mTimeSinceLastInput(0), mScreenSaver(NULL), mRenderScreenSaver(false)
{
mHelp = new HelpComponent(this);
mBackgroundOverlay = new ImageComponent(this);
@ -128,13 +128,14 @@ void Window::input(InputConfig* config, Input input)
{
// wake up
mTimeSinceLastInput = 0;
cancelScreenSaver();
mSleeping = false;
onWake();
return;
}
mTimeSinceLastInput = 0;
cancelScreenSaver();
if(config->getDeviceId() == DEVICE_KEYBOARD && input.value && input.id == SDLK_g && SDL_GetModState() & KMOD_LCTRL && Settings::getInstance()->getBool("Debug"))
{
@ -194,6 +195,10 @@ void Window::update(int deltaTime)
if(peekGui())
peekGui()->update(deltaTime);
// Update the screensaver
if (mScreenSaver)
mScreenSaver->update(deltaTime);
}
void Window::render()
@ -226,18 +231,16 @@ void Window::render()
}
unsigned int screensaverTime = (unsigned int)Settings::getInstance()->getInt("ScreenSaverTime");
if(mTimeSinceLastInput >= screensaverTime && screensaverTime != 0)
startScreenSaver();
// Always call the screensaver render function regardless of whether the screensaver is active
// or not because it may perform a fade on transition
renderScreenSaver();
if(mTimeSinceLastInput >= screensaverTime && screensaverTime != 0)
{
if (!mRenderScreenSaver)
{
for(auto i = mGuiStack.begin(); i != mGuiStack.end(); i++)
(*i)->onScreenSaverActivate();
mRenderScreenSaver = true;
}
renderScreenSaver();
if (!isProcessing() && mAllowSleep)
if (!isProcessing() && mAllowSleep && (!mScreenSaver || mScreenSaver->allowSleep()))
{
// go to sleep
mSleeping = true;
@ -374,9 +377,35 @@ bool Window::isProcessing()
return count_if(mGuiStack.begin(), mGuiStack.end(), [](GuiComponent* c) { return c->isProcessing(); }) > 0;
}
void Window::renderScreenSaver()
{
Renderer::setMatrix(Eigen::Affine3f::Identity());
unsigned char opacity = Settings::getInstance()->getString("ScreenSaverBehavior") == "dim" ? 0xA0 : 0xFF;
Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0x00000000 | opacity);
}
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();
}

View file

@ -11,6 +11,15 @@ class ImageComponent;
class Window
{
public:
class ScreenSaver {
public:
virtual void startScreenSaver() = 0;
virtual void stopScreenSaver() = 0;
virtual void renderScreenSaver() = 0;
virtual bool allowSleep() = 0;
virtual void update(int deltaTime) = 0;
};
Window();
~Window();
@ -38,6 +47,8 @@ public:
void renderHelpPromptsEarly(); // used to render HelpPrompts before a fade
void setHelpPrompts(const std::vector<HelpPrompt>& prompts, const HelpStyle& style);
void setScreenSaver(ScreenSaver* screenSaver) { mScreenSaver = screenSaver; }
private:
void onSleep();
void onWake();
@ -45,9 +56,13 @@ private:
// 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;
bool mRenderScreenSaver;
std::vector<GuiComponent*> mGuiStack;

View file

@ -19,6 +19,7 @@ VideoPlayerComponent::VideoPlayerComponent(Window* window) :
VideoPlayerComponent::~VideoPlayerComponent()
{
stopVideo();
}
void VideoPlayerComponent::render(const Eigen::Affine3f& parentTrans)

View file

@ -45,6 +45,7 @@ VideoVlcComponent::VideoVlcComponent(Window* window) :
VideoVlcComponent::~VideoVlcComponent()
{
stopVideo();
}
void VideoVlcComponent::setResize(float width, float height)