Decreased CPU usage dramatically and fixed multiple UI navigation glitches.

Also did some code cleanup.
This commit is contained in:
Leon Styhre 2020-09-15 22:57:54 +02:00
parent a6430ff0ff
commit ae7c9dabb8
18 changed files with 261 additions and 168 deletions

View file

@ -56,6 +56,7 @@ Many bugs have been fixed, and numerous features that were only partially implem
* Refactoring, cleanup and documentation of the source code, removal of deprecated files etc. * Refactoring, cleanup and documentation of the source code, removal of deprecated files etc.
* All required fonts bundled with the application, no dependencies on the OS to provide them any longer * All required fonts bundled with the application, no dependencies on the OS to provide them any longer
* Made pugixml an external dependency instead of bundling it * Made pugixml an external dependency instead of bundling it
* Decreased CPU usage dramatically by only rendering the currently visible view (previously every view were always rendered)
* Updated the CMake/CPack install and package build script to work as expected (it can now generate .deb, .rpm, .dmg and NSIS installation packages) * Updated the CMake/CPack install and package build script to work as expected (it can now generate .deb, .rpm, .dmg and NSIS installation packages)
* Added support for Clang/LLVM, made the application build with no errors or warnings using this compiler (Unix and macOS only) * Added support for Clang/LLVM, made the application build with no errors or warnings using this compiler (Unix and macOS only)
* License files included for all the libraries and resources that are bundled with the application * License files included for all the libraries and resources that are bundled with the application
@ -79,6 +80,7 @@ Many bugs have been fixed, and numerous features that were only partially implem
* The random game selection traversed folders, i.e. a game could be selected inside a subdirectory and vice versa * The random game selection traversed folders, i.e. a game could be selected inside a subdirectory and vice versa
* Deleting a game from the metadata editor did not delete the game media files or the entry in the gamelist.xml file * Deleting a game from the metadata editor did not delete the game media files or the entry in the gamelist.xml file
* SystemView didn't properly loop the systems if only two systems were available * SystemView didn't properly loop the systems if only two systems were available
* When changing to the video view style from inside a gamelist, the view was not initialized
* Hidden files still showed up if they had a gamelist.xml entry * Hidden files still showed up if they had a gamelist.xml entry
* Fixed an annoying gamelist issue that caused the game images and data to be updated and rendered up to six times every time the list was scrolled * Fixed an annoying gamelist issue that caused the game images and data to be updated and rendered up to six times every time the list was scrolled
* VRAM statistics overlay was somewhat broken and incorrectly displayed numbers in megabytes instead of mebibytes * VRAM statistics overlay was somewhat broken and incorrectly displayed numbers in megabytes instead of mebibytes

View file

@ -1,11 +1,11 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// MoveCameraAnimation.h // MoveCameraAnimation.h
// //
// Animation to play when moving the camera, used by the slide transition style // Animation to play when moving the camera, used by the slide transition style.
// (when moving between gamelists using quick system select).
// //
#pragma once
#ifndef ES_APP_ANIMATIONS_MOVE_CAMERA_ANIMATION_H #ifndef ES_APP_ANIMATIONS_MOVE_CAMERA_ANIMATION_H
#define ES_APP_ANIMATIONS_MOVE_CAMERA_ANIMATION_H #define ES_APP_ANIMATIONS_MOVE_CAMERA_ANIMATION_H

View file

@ -1,4 +1,6 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// GuiGamelistOptions.cpp // GuiGamelistOptions.cpp
// //
// Gamelist options menu for the 'Jump to...' quick selector, // Gamelist options menu for the 'Jump to...' quick selector,
@ -19,8 +21,8 @@
#include "FileFilterIndex.h" #include "FileFilterIndex.h"
#include "FileSorts.h" #include "FileSorts.h"
#include "GuiMetaDataEd.h" #include "GuiMetaDataEd.h"
#include "SystemData.h"
#include "Sound.h" #include "Sound.h"
#include "SystemData.h"
GuiGamelistOptions::GuiGamelistOptions( GuiGamelistOptions::GuiGamelistOptions(
Window* window, Window* window,
@ -177,6 +179,11 @@ GuiGamelistOptions::GuiGamelistOptions(
GuiGamelistOptions::~GuiGamelistOptions() GuiGamelistOptions::~GuiGamelistOptions()
{ {
// This is required for the situation where scrolling started just before the menu
// was openened. Without this, the scrolling would run until manually stopped after
// the menu has been closed.
ViewController::get()->stopScrolling();
if (mCancelled) if (mCancelled)
return; return;

View file

@ -1,4 +1,6 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// GuiGamelistOptions.h // GuiGamelistOptions.h
// //
// Gamelist options menu for the 'Jump to...' quick selector, // Gamelist options menu for the 'Jump to...' quick selector,
@ -8,15 +10,14 @@
// metadata edit interface is covered by GuiMetaDataEd. // metadata edit interface is covered by GuiMetaDataEd.
// //
#pragma once
#ifndef ES_APP_GUIS_GUI_GAME_LIST_OPTIONS_H #ifndef ES_APP_GUIS_GUI_GAME_LIST_OPTIONS_H
#define ES_APP_GUIS_GUI_GAME_LIST_OPTIONS_H #define ES_APP_GUIS_GUI_GAME_LIST_OPTIONS_H
#include "components/MenuComponent.h" #include "components/MenuComponent.h"
#include "components/OptionListComponent.h" #include "components/OptionListComponent.h"
#include "utils/StringUtil.h"
#include "FileData.h" #include "FileData.h"
#include "GuiComponent.h" #include "GuiComponent.h"
#include "utils/StringUtil.h"
class IGameListView; class IGameListView;
class SystemData; class SystemData;

View file

@ -1,4 +1,6 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// GuiMenu.cpp // GuiMenu.cpp
// //
// Main menu. // Main menu.
@ -17,9 +19,9 @@
#include "guis/GuiMsgBox.h" #include "guis/GuiMsgBox.h"
#include "guis/GuiScraperMenu.h" #include "guis/GuiScraperMenu.h"
#include "guis/GuiSettings.h" #include "guis/GuiSettings.h"
#include "views/gamelist/IGameListView.h"
#include "views/UIModeController.h" #include "views/UIModeController.h"
#include "views/ViewController.h" #include "views/ViewController.h"
#include "views/gamelist/IGameListView.h"
#include "CollectionSystemManager.h" #include "CollectionSystemManager.h"
#include "EmulationStation.h" #include "EmulationStation.h"
#include "FileSorts.h" #include "FileSorts.h"
@ -63,6 +65,14 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window),
Renderer::getScreenHeight() * 0.15f); Renderer::getScreenHeight() * 0.15f);
} }
GuiMenu::~GuiMenu()
{
// This is required for the situation where scrolling started just before the menu
// was openened. Without this, the scrolling would run until manually stopped after
// the menu has been closed.
ViewController::get()->stopScrolling();
}
void GuiMenu::openScraperSettings() void GuiMenu::openScraperSettings()
{ {
// Open the scrape menu. // Open the scrape menu.

View file

@ -1,11 +1,12 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// GuiMenu.h // GuiMenu.h
// //
// Main menu. // Main menu.
// Some submenus are covered in separate source files. // Some submenus are covered in separate source files.
// //
#pragma once
#ifndef ES_APP_GUIS_GUI_MENU_H #ifndef ES_APP_GUIS_GUI_MENU_H
#define ES_APP_GUIS_GUI_MENU_H #define ES_APP_GUIS_GUI_MENU_H
@ -16,6 +17,7 @@ class GuiMenu : public GuiComponent
{ {
public: public:
GuiMenu(Window* window); GuiMenu(Window* window);
~GuiMenu();
bool input(InputConfig* config, Input input) override; bool input(InputConfig* config, Input input) override;
void onSizeChanged() override; void onSizeChanged() override;

View file

@ -1,4 +1,6 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// SystemView.cpp // SystemView.cpp
// //
// Main system view. // Main system view.
@ -177,10 +179,12 @@ bool SystemView::input(InputConfig* config, Input input)
case VERTICAL: case VERTICAL:
case VERTICAL_WHEEL: case VERTICAL_WHEEL:
if (config->isMappedLike("up", input)) { if (config->isMappedLike("up", input)) {
ViewController::get()->resetMovingCamera();
listInput(-1); listInput(-1);
return true; return true;
} }
if (config->isMappedLike("down", input)) { if (config->isMappedLike("down", input)) {
ViewController::get()->resetMovingCamera();
listInput(1); listInput(1);
return true; return true;
} }
@ -189,10 +193,12 @@ bool SystemView::input(InputConfig* config, Input input)
case HORIZONTAL_WHEEL: case HORIZONTAL_WHEEL:
default: default:
if (config->isMappedLike("left", input)) { if (config->isMappedLike("left", input)) {
ViewController::get()->resetMovingCamera();
listInput(-1); listInput(-1);
return true; return true;
} }
if (config->isMappedLike("right", input)) { if (config->isMappedLike("right", input)) {
ViewController::get()->resetMovingCamera();
listInput(1); listInput(1);
return true; return true;
} }

View file

@ -1,10 +1,11 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// SystemView.h // SystemView.h
// //
// Main system view. // Main system view.
// //
#pragma once
#ifndef ES_APP_VIEWS_SYSTEM_VIEW_H #ifndef ES_APP_VIEWS_SYSTEM_VIEW_H
#define ES_APP_VIEWS_SYSTEM_VIEW_H #define ES_APP_VIEWS_SYSTEM_VIEW_H

View file

@ -1,4 +1,6 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// ViewController.cpp // ViewController.cpp
// //
// Handles overall system navigation including animations and transitions. // Handles overall system navigation including animations and transitions.
@ -11,14 +13,13 @@
#include "animations/Animation.h" #include "animations/Animation.h"
#include "animations/LambdaAnimation.h" #include "animations/LambdaAnimation.h"
#include "animations/LaunchAnimation.h"
#include "animations/MoveCameraAnimation.h" #include "animations/MoveCameraAnimation.h"
#include "guis/GuiInfoPopup.h" #include "guis/GuiInfoPopup.h"
#include "guis/GuiMenu.h" #include "guis/GuiMenu.h"
#include "guis/GuiMsgBox.h" #include "guis/GuiMsgBox.h"
#include "views/gamelist/DetailedGameListView.h" #include "views/gamelist/DetailedGameListView.h"
#include "views/gamelist/IGameListView.h"
#include "views/gamelist/GridGameListView.h" #include "views/gamelist/GridGameListView.h"
#include "views/gamelist/IGameListView.h"
#include "views/gamelist/VideoGameListView.h" #include "views/gamelist/VideoGameListView.h"
#include "views/SystemView.h" #include "views/SystemView.h"
#include "views/UIModeController.h" #include "views/UIModeController.h"
@ -111,28 +112,59 @@ void ViewController::ReloadAndGoToStart()
ViewController::get()->goToStart(); ViewController::get()->goToStart();
} }
bool ViewController::isCameraMoving()
{
if (mCurrentView) {
if (mCamera.r3().x() != -mCurrentView->getPosition().x() ||
mCamera.r3().y() != -mCurrentView->getPosition().y())
return true;
}
return false;
}
void ViewController::resetMovingCamera()
{
if (isCameraMoving()) {
mCamera.r3().x() = -mCurrentView->getPosition().x();
mCamera.r3().y() = -mCurrentView->getPosition().y();
stopAllAnimations();
}
}
void ViewController::stopScrolling()
{
mSystemListView->stopScrolling();
mCurrentView->stopListScrolling();
if (mSystemListView->isAnimationPlaying(0))
mSystemListView->finishAnimation(0);
}
int ViewController::getSystemId(SystemData* system) int ViewController::getSystemId(SystemData* system)
{ {
std::vector<SystemData*>& sysVec = SystemData::sSystemVector; std::vector<SystemData*>& sysVec = SystemData::sSystemVector;
return (int)(std::find(sysVec.cbegin(), sysVec.cend(), system) - sysVec.cbegin()); return static_cast<int>(std::find(sysVec.cbegin(), sysVec.cend(), system) - sysVec.cbegin());
} }
void ViewController::goToSystemView(SystemData* system) void ViewController::goToSystemView(SystemData* system)
{ {
// Tell any current view it's about to be hidden. // Tell any current view it's about to be hidden and stop its rendering.
if (mCurrentView) if (mCurrentView) {
mCurrentView->onHide(); mCurrentView->onHide();
mCurrentView->setRenderView(false);
}
mState.viewing = SYSTEM_SELECT; mState.viewing = SYSTEM_SELECT;
mState.system = system; mState.system = system;
auto systemList = getSystemListView(); auto systemList = getSystemListView();
systemList->setPosition(getSystemId(system) * (float)Renderer::getScreenWidth(), systemList->setPosition(getSystemId(system) * static_cast<float>(Renderer::getScreenWidth()),
systemList->getPosition().y()); systemList->getPosition().y());
systemList->goToSystem(system, false); systemList->goToSystem(system, false);
mCurrentView = systemList; mCurrentView = systemList;
mCurrentView->onShow(); mCurrentView->onShow();
mCurrentView->setRenderView(true);
PowerSaver::setState(true); PowerSaver::setState(true);
playViewTransition(); playViewTransition();
@ -158,13 +190,29 @@ void ViewController::goToPrevGameList()
void ViewController::goToGameList(SystemData* system) void ViewController::goToGameList(SystemData* system)
{ {
// Stop any scrolling, animations and camera movements.
if (mSystemListView) {
mSystemListView->stopScrolling();
if (mSystemListView->isAnimationPlaying(0))
mSystemListView->finishAnimation(0);
}
resetMovingCamera();
// Disable rendering of the system view.
if (getSystemListView()->getRenderView())
getSystemListView()->setRenderView(false);
// If switching between gamelists, disable rendering of the current view.
if (mCurrentView)
mCurrentView->setRenderView(false);
if (mState.viewing == SYSTEM_SELECT) { if (mState.viewing == SYSTEM_SELECT) {
// Move system list. // Move system list.
auto sysList = getSystemListView(); auto sysList = getSystemListView();
float offX = sysList->getPosition().x(); float offX = sysList->getPosition().x();
int sysId = getSystemId(system); int sysId = getSystemId(system);
sysList->setPosition(sysId * (float)Renderer::getScreenWidth(), sysList->setPosition(sysId * static_cast<float>(Renderer::getScreenWidth()),
sysList->getPosition().y()); sysList->getPosition().y());
offX = sysList->getPosition().x() - offX; offX = sysList->getPosition().x() - offX;
mCamera.translation().x() -= offX; mCamera.translation().x() -= offX;
@ -178,8 +226,10 @@ void ViewController::goToGameList(SystemData* system)
mCurrentView = getGameListView(system); mCurrentView = getGameListView(system);
if (mCurrentView) if (mCurrentView) {
mCurrentView->onShow(); mCurrentView->onShow();
mCurrentView->setRenderView(true);
}
playViewTransition(); playViewTransition();
} }
@ -218,10 +268,10 @@ void ViewController::playViewTransition()
// Not changing screens, so cancel the first half entirely. // Not changing screens, so cancel the first half entirely.
advanceAnimation(0, FADE_DURATION); advanceAnimation(0, FADE_DURATION);
advanceAnimation(0, FADE_WAIT); advanceAnimation(0, FADE_WAIT);
advanceAnimation(0, FADE_DURATION - (int)(mFadeOpacity * FADE_DURATION)); advanceAnimation(0, FADE_DURATION - static_cast<int>(mFadeOpacity * FADE_DURATION));
} }
else { else {
advanceAnimation(0, (int)(mFadeOpacity * FADE_DURATION)); advanceAnimation(0, static_cast<int>(mFadeOpacity * FADE_DURATION));
} }
} }
else if (transition_style == "slide") { else if (transition_style == "slide") {
@ -247,90 +297,43 @@ void ViewController::onFileChanged(FileData* file, FileChangeType change)
void ViewController::launch(FileData* game, Vector3f center) void ViewController::launch(FileData* game, Vector3f center)
{ {
if (game->getType() != GAME) { if (game->getType() != GAME) {
LOG(LogError) << "tried to launch something that isn't a game"; LOG(LogError) << "tried to launch something that isn't a game.";
return; return;
} }
// Hide the current view. // If the video view style is used, pause the video currently playing or block the
// video from starting to play if the static image is still shown.
if (mCurrentView) if (mCurrentView)
mCurrentView->onHide(); mCurrentView->onPauseVideo();
Transform4x4f origCamera = mCamera;
origCamera.translation() = -mCurrentView->getPosition();
center += mCurrentView->getPosition();
stopAnimation(1); // Make sure the fade in isn't still playing. stopAnimation(1); // Make sure the fade in isn't still playing.
mWindow->stopInfoPopup(); // Make sure we disable any existing info popup. mWindow->stopInfoPopup(); // Make sure we disable any existing info popup.
mLockInput = true; mLockInput = true;
// TEMPORARY - Until a proper game launch screen is implemented, at least this // Until a proper game launch screen is implemented, at least this will let the
// will let the user know that something is actually happening (in addition // user know that something is actually happening (in addition to the launch sound,
// to the launch sound, if navigation sounds are enabled). // if navigation sounds are enabled).
GuiInfoPopup* s = new GuiInfoPopup(mWindow, "LAUNCHING GAME '" + GuiInfoPopup* s = new GuiInfoPopup(mWindow, "LAUNCHING GAME '" +
Utils::String::toUpper(game->metadata.get("name") + "'"), 10000); Utils::String::toUpper(game->metadata.get("name") + "'"), 10000);
mWindow->setInfoPopup(s); mWindow->setInfoPopup(s);
std::string transition_style = Settings::getInstance()->getString("TransitionStyle");
NavigationSounds::getInstance()->playThemeNavigationSound(LAUNCHSOUND); NavigationSounds::getInstance()->playThemeNavigationSound(LAUNCHSOUND);
// Let launch sound play to the end before launching game.
while (NavigationSounds::getInstance()->isPlayingThemeNavigationSound(LAUNCHSOUND));
// TEMPORARY - disabled the launch animations as they don't work properly and more // This is just a dummy animation in order for the launch notification popup to be
// work is needed to fix them. This has been done in LaunchAnimation.h instead of here, // displayed briefly, and for the navigation sound playing to be able to complete.
// as not calling the animation leads to input not being properly consumed. This also // During this time period, all user input is blocked.
// needs to be fixed later on. setAnimation(new LambdaAnimation([](float t){}, 1700), 0, [this, game] {
setAnimation(new LaunchAnimation(mCamera, mFadeOpacity, center, 1500), 0, while (NavigationSounds::getInstance()->isPlayingThemeNavigationSound(LAUNCHSOUND));
[this, origCamera, center, game] {
game->launchGame(mWindow); game->launchGame(mWindow);
mCamera = origCamera; onFileChanged(game, FILE_METADATA_CHANGED);
setAnimation(new LaunchAnimation(mCamera, mFadeOpacity, center, 600), 0, [this] {
mLockInput = false; }, true);
this->onFileChanged(game, FILE_METADATA_CHANGED);
if (mCurrentView) if (mCurrentView)
mCurrentView->onShow(); mCurrentView->onShow();
// This is a workaround so that any key or button presses used for exiting the emulator
// are not captured upon returning to ES.
setAnimation(new LambdaAnimation([](float t){}, 1), 0, [this] {
mLockInput = false;
});
}); });
// if (transition_style == "fade") {
// // Fade out, launch game, fade back in.
// auto fadeFunc = [this](float t) {
// mFadeOpacity = Math::lerp(0.0f, 1.0f, t);
// };
// setAnimation(new LambdaAnimation(fadeFunc, 800), 0, [this, game, fadeFunc] {
// game->launchGame(mWindow);
// setAnimation(new LambdaAnimation(fadeFunc, 800), 0, [this] {
// mLockInput = false; }, true);
// this->onFileChanged(game, FILE_METADATA_CHANGED);
// if (mCurrentView)
// mCurrentView->onShow();
// });
// }
// else if (transition_style == "slide") {
// // Move camera to zoom in on center + fade out, launch game, come back in.
// setAnimation(new LaunchAnimation(mCamera, mFadeOpacity, center, 1500), 0,
// [this, origCamera, center, game] {
// game->launchGame(mWindow);
// mCamera = origCamera;
// setAnimation(new LaunchAnimation(mCamera, mFadeOpacity, center, 600), 0, [this] {
// mLockInput = false; }, true);
// this->onFileChanged(game, FILE_METADATA_CHANGED);
// if (mCurrentView)
// mCurrentView->onShow();
// });
// }
// // Instant
// else {
// setAnimation(new LaunchAnimation(mCamera, mFadeOpacity, center, 10), 0,
// [this, origCamera, center, game] {
// game->launchGame(mWindow);
// mCamera = origCamera;
// setAnimation(new LaunchAnimation(mCamera, mFadeOpacity, center, 10), 0,
// [this] { mLockInput = false; }, true);
// this->onFileChanged(game, FILE_METADATA_CHANGED);
// if (mCurrentView)
// mCurrentView->onShow();
// });
// }
} }
void ViewController::removeGameListView(SystemData* system) void ViewController::removeGameListView(SystemData* system)
@ -344,46 +347,46 @@ void ViewController::removeGameListView(SystemData* system)
std::shared_ptr<IGameListView> ViewController::getGameListView(SystemData* system) std::shared_ptr<IGameListView> ViewController::getGameListView(SystemData* system)
{ {
// If we already made one, return that one. // If we have already created an entry for this system, then return that one.
auto exists = mGameListViews.find(system); auto exists = mGameListViews.find(system);
if (exists != mGameListViews.cend()) if (exists != mGameListViews.cend())
return exists->second; return exists->second;
system->getIndex()->setUIModeFilters(); system->getIndex()->setUIModeFilters();
// If we didn't, make it, remember it, and return it. // If there's no entry, then create it and return it.
std::shared_ptr<IGameListView> view; std::shared_ptr<IGameListView> view;
bool themeHasVideoView = system->getTheme()->hasView("video"); bool themeHasVideoView = system->getTheme()->hasView("video");
// Decide type. // Decide which view style to use.
GameListViewType selectedViewType = AUTOMATIC; GameListViewType selectedViewStyle = AUTOMATIC;
std::string viewPreference = Settings::getInstance()->getString("GamelistViewStyle"); std::string viewPreference = Settings::getInstance()->getString("GamelistViewStyle");
if (viewPreference.compare("basic") == 0) if (viewPreference.compare("basic") == 0)
selectedViewType = BASIC; selectedViewStyle = BASIC;
if (viewPreference.compare("detailed") == 0) if (viewPreference.compare("detailed") == 0)
selectedViewType = DETAILED; selectedViewStyle = DETAILED;
if (viewPreference.compare("grid") == 0) if (viewPreference.compare("grid") == 0)
selectedViewType = GRID; selectedViewStyle = GRID;
if (viewPreference.compare("video") == 0) if (viewPreference.compare("video") == 0)
selectedViewType = VIDEO; selectedViewStyle = VIDEO;
if (selectedViewType == AUTOMATIC) { if (selectedViewStyle == AUTOMATIC) {
std::vector<FileData*> files = system->getRootFolder()->getFilesRecursive(GAME | FOLDER); std::vector<FileData*> files = system->getRootFolder()->getFilesRecursive(GAME | FOLDER);
for (auto it = files.cbegin(); it != files.cend(); it++) { for (auto it = files.cbegin(); it != files.cend(); it++) {
if (themeHasVideoView && !(*it)->getVideoPath().empty()) { if (themeHasVideoView && !(*it)->getVideoPath().empty()) {
selectedViewType = VIDEO; selectedViewStyle = VIDEO;
break; break;
} }
else if (!(*it)->getImagePath().empty()) { else if (!(*it)->getImagePath().empty()) {
selectedViewType = DETAILED; selectedViewStyle = DETAILED;
// Don't break out in case any subsequent files have videos. // Don't break out in case any subsequent files have videos.
} }
} }
} }
// Create the view. // Create the view.
switch (selectedViewType) switch (selectedViewStyle)
{ {
case VIDEO: case VIDEO:
view = std::shared_ptr<IGameListView>( view = std::shared_ptr<IGameListView>(
@ -407,9 +410,10 @@ std::shared_ptr<IGameListView> ViewController::getGameListView(SystemData* syste
view->setTheme(system->getTheme()); view->setTheme(system->getTheme());
std::vector<SystemData*>& sysVec = SystemData::sSystemVector; std::vector<SystemData*>& sysVec = SystemData::sSystemVector;
int id = (int)(std::find(sysVec.cbegin(), sysVec.cend(), system) - sysVec.cbegin()); int id = static_cast<int>(
view->setPosition(id * (float)Renderer::getScreenWidth(), std::find(sysVec.cbegin(), sysVec.cend(), system) - sysVec.cbegin());
(float)Renderer::getScreenHeight() * 2); view->setPosition(id * static_cast<float>(Renderer::getScreenWidth()),
static_cast<float>(Renderer::getScreenHeight() * 2));
addChild(view.get()); addChild(view.get());
@ -419,13 +423,13 @@ std::shared_ptr<IGameListView> ViewController::getGameListView(SystemData* syste
std::shared_ptr<SystemView> ViewController::getSystemListView() std::shared_ptr<SystemView> ViewController::getSystemListView()
{ {
// If we already made one, return that one. // If we have already created a system view entry, then return it.
if (mSystemListView) if (mSystemListView)
return mSystemListView; return mSystemListView;
mSystemListView = std::shared_ptr<SystemView>(new SystemView(mWindow)); mSystemListView = std::shared_ptr<SystemView>(new SystemView(mWindow));
addChild(mSystemListView.get()); addChild(mSystemListView.get());
mSystemListView->setPosition(0, (float)Renderer::getScreenHeight()); mSystemListView->setPosition(0, static_cast<float>(Renderer::getScreenHeight()));
return mSystemListView; return mSystemListView;
} }
@ -447,7 +451,7 @@ bool ViewController::input(InputConfig* config, Input input)
} }
#endif #endif
// Open menu. // Open the main menu.
if (!(UIModeController::getInstance()->isUIModeKid() && if (!(UIModeController::getInstance()->isUIModeKid() &&
!Settings::getInstance()->getBool("ShowKidStartMenu")) && !Settings::getInstance()->getBool("ShowKidStartMenu")) &&
config->isMappedTo("start", input) && input.value != 0) { config->isMappedTo("start", input) && input.value != 0) {
@ -461,8 +465,9 @@ bool ViewController::input(InputConfig* config, Input input)
mSystemListView->finishAnimation(0); mSystemListView->finishAnimation(0);
// Stop the gamelist scrolling as well as it would otherwise // Stop the gamelist scrolling as well as it would otherwise
// also continue to run after closing the menu. // also continue to run after closing the menu.
if (mCurrentView->isListScrolling()) mCurrentView->stopListScrolling();
mCurrentView->stopListScrolling(); // Finally, if the camera is currently moving, reset its position.
resetMovingCamera();
mWindow->pushGui(new GuiMenu(mWindow)); mWindow->pushGui(new GuiMenu(mWindow));
return true; return true;
@ -494,25 +499,32 @@ void ViewController::render(const Transform4x4f& parentTrans)
// Camera position, position + size. // Camera position, position + size.
Vector3f viewStart = transInverse.translation(); Vector3f viewStart = transInverse.translation();
Vector3f viewEnd = transInverse * Vector3f((float)Renderer::getScreenWidth(), Vector3f viewEnd = transInverse * Vector3f(static_cast<float>(Renderer::getScreenWidth()),
(float)Renderer::getScreenHeight(), 0); static_cast<float>(Renderer::getScreenHeight(), 0));
// Keep track of UI mode changes. // Keep track of UI mode changes.
UIModeController::getInstance()->monitorUIMode(); UIModeController::getInstance()->monitorUIMode();
// Draw system view. // Draw the system view if it's flagged to be rendered.
getSystemListView()->render(trans); // If the camera is moving, we're transitioning and in that case render it regardless
// of whether it's flagged for rendering or not. (Otherwise there will be a black portion
// shown on the screen during the animation).
if (getSystemListView()->getRenderView() || isCameraMoving())
getSystemListView()->render(trans);
// Draw gamelists. // Draw the gamelists.
for (auto it = mGameListViews.cbegin(); it != mGameListViews.cend(); it++) { for (auto it = mGameListViews.cbegin(); it != mGameListViews.cend(); it++) {
// Clipping. // Same thing as for the system view, limit the rendering only to what needs to be drawn.
Vector3f guiStart = it->second->getPosition(); if (it->second->getRenderView() || isCameraMoving()) {
Vector3f guiEnd = it->second->getPosition() + Vector3f(it->second->getSize().x(), // Clipping.
it->second->getSize().y(), 0); Vector3f guiStart = it->second->getPosition();
Vector3f guiEnd = it->second->getPosition() + Vector3f(it->second->getSize().x(),
it->second->getSize().y(), 0);
if (guiEnd.x() >= viewStart.x() && guiEnd.y() >= viewStart.y() && if (guiEnd.x() >= viewStart.x() && guiEnd.y() >= viewStart.y() &&
guiStart.x() <= viewEnd.x() && guiStart.y() <= viewEnd.y()) guiStart.x() <= viewEnd.x() && guiStart.y() <= viewEnd.y())
it->second->render(trans); it->second->render(trans);
}
} }
if (mWindow->peekGui() == this) if (mWindow->peekGui() == this)
@ -520,7 +532,7 @@ void ViewController::render(const Transform4x4f& parentTrans)
// Fade out. // Fade out.
if (mFadeOpacity) { if (mFadeOpacity) {
unsigned int fadeColor = 0x00000000 | (unsigned char)(mFadeOpacity * 255); unsigned int fadeColor = 0x00000000 | static_cast<unsigned char>(mFadeOpacity * 255);
Renderer::setMatrix(parentTrans); Renderer::setMatrix(parentTrans);
Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::drawRect(0.0f, 0.0f, Renderer::getScreenWidth(),
Renderer::getScreenHeight(), fadeColor, fadeColor); Renderer::getScreenHeight(), fadeColor, fadeColor);
@ -529,23 +541,21 @@ void ViewController::render(const Transform4x4f& parentTrans)
void ViewController::preload() void ViewController::preload()
{ {
uint32_t i = 0; unsigned int systemCount = SystemData::sSystemVector.size();
for (auto it = SystemData::sSystemVector.cbegin();
it != SystemData::sSystemVector.cend(); it++) {
if (Settings::getInstance()->getBool("SplashScreen") &&
Settings::getInstance()->getBool("SplashScreenProgress")) {
i++;
char buffer[100];
sprintf (buffer, "Loading '%s' (%d/%d)",
(*it)->getFullName().c_str(), i, (int)SystemData::sSystemVector.size());
mWindow->renderLoadingScreen(std::string(buffer));
}
for (auto it = SystemData::sSystemVector.cbegin();
it != SystemData::sSystemVector.cend(); it ++) {
if (Settings::getInstance()->getBool("SplashScreen") &&
Settings::getInstance()->getBool("SplashScreenProgress")) {
mWindow->renderLoadingScreen("Loading '" + (*it)->getFullName() + "' (" +
std::to_string(std::distance(SystemData::sSystemVector.cbegin(), it)+1) +
"/" + std::to_string(systemCount) + ")");
}
(*it)->getIndex()->resetFilters(); (*it)->getIndex()->resetFilters();
getGameListView(*it); getGameListView(*it);
} }
// Load navigation sounds, but only if at least one system exists. // Load navigation sounds, but only if at least one system exists.
if (SystemData::sSystemVector.size() > 0) if (systemCount > 0)
NavigationSounds::getInstance()->loadThemeNavigationSounds( NavigationSounds::getInstance()->loadThemeNavigationSounds(
SystemData::sSystemVector.front()->getTheme()); SystemData::sSystemVector.front()->getTheme());
} }
@ -587,8 +597,10 @@ void ViewController::reloadGameListView(IGameListView* view, bool reloadTheme)
#endif #endif
// Redisplay the current view. // Redisplay the current view.
if (mCurrentView) if (mCurrentView) {
mCurrentView->onShow(); mCurrentView->onShow();
mCurrentView->setRenderView(true);
}
} }
void ViewController::reloadAll() void ViewController::reloadAll()
@ -630,6 +642,8 @@ void ViewController::reloadAll()
NavigationSounds::getInstance()->loadThemeNavigationSounds( NavigationSounds::getInstance()->loadThemeNavigationSounds(
SystemData::sSystemVector.front()->getTheme()); SystemData::sSystemVector.front()->getTheme());
mCurrentView->onShow();
mCurrentView->setRenderView(true);
updateHelpPrompts(); updateHelpPrompts();
} }

View file

@ -1,4 +1,6 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// ViewController.h // ViewController.h
// //
// Handles overall system navigation including animations and transitions. // Handles overall system navigation including animations and transitions.
@ -7,13 +9,13 @@
// Initiates the launching of games, calling FileData to do the actual launch. // Initiates the launching of games, calling FileData to do the actual launch.
// //
#pragma once
#ifndef ES_APP_VIEWS_VIEW_CONTROLLER_H #ifndef ES_APP_VIEWS_VIEW_CONTROLLER_H
#define ES_APP_VIEWS_VIEW_CONTROLLER_H #define ES_APP_VIEWS_VIEW_CONTROLLER_H
#include "renderers/Renderer.h" #include "renderers/Renderer.h"
#include "FileData.h" #include "FileData.h"
#include "GuiComponent.h" #include "GuiComponent.h"
#include <vector> #include <vector>
class IGameListView; class IGameListView;
@ -51,10 +53,13 @@ public:
void goToStart(); void goToStart();
void ReloadAndGoToStart(); void ReloadAndGoToStart();
// Functions to make the GUI behave properly.
bool isCameraMoving();
void resetMovingCamera();
void stopScrolling();
void onFileChanged(FileData* file, FileChangeType change); void onFileChanged(FileData* file, FileChangeType change);
// Plays a nice launch effect and launches the game at the end of it.
// Once the game terminates, plays a return effect.
void launch(FileData* game, Vector3f centerCameraOn = void launch(FileData* game, Vector3f centerCameraOn =
Vector3f(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f, 0)); Vector3f(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f, 0));

View file

@ -1,4 +1,6 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// IGameListView.cpp // IGameListView.cpp
// //
// Interface that defines the minimum for a GameListView. // Interface that defines the minimum for a GameListView.
@ -17,8 +19,8 @@ bool IGameListView::input(InputConfig* config, Input input)
// Select button opens GuiGamelistOptions. // Select button opens GuiGamelistOptions.
if (!UIModeController::getInstance()->isUIModeKid() && if (!UIModeController::getInstance()->isUIModeKid() &&
config->isMappedTo("select", input) && input.value) { config->isMappedTo("select", input) && input.value) {
if (isListScrolling()) ViewController::get()->resetMovingCamera();
stopListScrolling(); stopListScrolling();
mWindow->pushGui(new GuiGamelistOptions(mWindow, this->mRoot->getSystem())); mWindow->pushGui(new GuiGamelistOptions(mWindow, this->mRoot->getSystem()));
return true; return true;
} }
@ -56,10 +58,10 @@ void IGameListView::render(const Transform4x4f& parentTrans)
float scaleX = trans.r0().x(); float scaleX = trans.r0().x();
float scaleY = trans.r1().y(); float scaleY = trans.r1().y();
Vector2i pos((int)Math::round(trans.translation()[0]), Vector2i pos(static_cast<int>(Math::round(trans.translation()[0])),
(int)Math::round(trans.translation()[1])); static_cast<int>(Math::round(trans.translation()[1])));
Vector2i size((int)Math::round(mSize.x() * scaleX), Vector2i size(static_cast<int>(Math::round(mSize.x() * scaleX)),
(int)Math::round(mSize.y() * scaleY)); static_cast<int>(Math::round(mSize.y() * scaleY)));
Renderer::pushClipRect(pos, size); Renderer::pushClipRect(pos, size);
renderChildren(trans); renderChildren(trans);

View file

@ -1,10 +1,11 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// IGameListView.h // IGameListView.h
// //
// Interface that defines the minimum for a GameListView. // Interface that defines the minimum for a GameListView.
// //
#pragma once
#ifndef ES_APP_VIEWS_GAME_LIST_IGAME_LIST_VIEW_H #ifndef ES_APP_VIEWS_GAME_LIST_IGAME_LIST_VIEW_H
#define ES_APP_VIEWS_GAME_LIST_IGAME_LIST_VIEW_H #define ES_APP_VIEWS_GAME_LIST_IGAME_LIST_VIEW_H
@ -24,15 +25,15 @@ public:
FileData* root) FileData* root)
: GuiComponent(window), : GuiComponent(window),
mRoot(root) mRoot(root)
{ setSize((float)Renderer::getScreenWidth(), { setSize(static_cast<float>(Renderer::getScreenWidth()),
(float)Renderer::getScreenHeight()); } static_cast<float>(Renderer::getScreenHeight())); }
virtual ~IGameListView() {} virtual ~IGameListView() {}
// Called when a new file is added, a file is removed, a file's metadata changes, // Called when a new file is added, a file is removed, a file's metadata changes,
// or a file's children are sorted. // or a file's children are sorted.
// NOTE: FILE_SORTED is only reported for the topmost FileData, where the sort started. // Note: FILE_SORTED is only reported for the topmost FileData, where the sort started.
// Since sorts are recursive, that FileData's children probably changed too. // Since sorts are recursive, FileData's children probably changed too.
virtual void onFileChanged(FileData* file, FileChangeType change) = 0; virtual void onFileChanged(FileData* file, FileChangeType change) = 0;
// Called whenever the theme changes. // Called whenever the theme changes.

View file

@ -1,7 +1,9 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// ISimpleGameListView.cpp // ISimpleGameListView.cpp
// //
// Interface that defines a simple GameListView. // Interface that defines a simple gamelist view.
// //
#include "views/gamelist/ISimpleGameListView.h" #include "views/gamelist/ISimpleGameListView.h"
@ -101,13 +103,14 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
if (config->isMappedTo("a", input)) { if (config->isMappedTo("a", input)) {
FileData* cursor = getCursor(); FileData* cursor = getCursor();
if (cursor->getType() == GAME) { if (cursor->getType() == GAME) {
if (isListScrolling()) ViewController::get()->resetMovingCamera();
stopListScrolling(); stopListScrolling();
launch(cursor); launch(cursor);
} }
else { else {
// It's a folder. // It's a folder.
if (cursor->getChildren().size() > 0) { if (cursor->getChildren().size() > 0) {
ViewController::get()->resetMovingCamera();
NavigationSounds::getInstance()->playThemeNavigationSound(SELECTSOUND); NavigationSounds::getInstance()->playThemeNavigationSound(SELECTSOUND);
mCursorStack.push(cursor); mCursorStack.push(cursor);
populateList(cursor->getChildrenListToDisplay()); populateList(cursor->getChildrenListToDisplay());
@ -119,6 +122,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
return true; return true;
} }
else if (config->isMappedTo("b", input)) { else if (config->isMappedTo("b", input)) {
ViewController::get()->resetMovingCamera();
if (mCursorStack.size()) { if (mCursorStack.size()) {
NavigationSounds::getInstance()->playThemeNavigationSound(BACKSOUND); NavigationSounds::getInstance()->playThemeNavigationSound(BACKSOUND);
populateList(mCursorStack.top()->getParent()->getChildren()); populateList(mCursorStack.top()->getParent()->getChildren());
@ -128,8 +132,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
else { else {
NavigationSounds::getInstance()->playThemeNavigationSound(BACKSOUND); NavigationSounds::getInstance()->playThemeNavigationSound(BACKSOUND);
onFocusLost(); onFocusLost();
if (isListScrolling()) stopListScrolling();
stopListScrolling();
SystemData* systemToView = getCursor()->getSystem(); SystemData* systemToView = getCursor()->getSystem();
if (systemToView->isCollection()) if (systemToView->isCollection())
systemToView = CollectionSystemManager::get()->getSystemToView(systemToView); systemToView = CollectionSystemManager::get()->getSystemToView(systemToView);
@ -142,8 +145,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
else if (config->isMappedLike(getQuickSystemSelectRightButton(), input)) { else if (config->isMappedLike(getQuickSystemSelectRightButton(), input)) {
if (Settings::getInstance()->getBool("QuickSystemSelect")) { if (Settings::getInstance()->getBool("QuickSystemSelect")) {
onFocusLost(); onFocusLost();
if (isListScrolling()) stopListScrolling();
stopListScrolling();
ViewController::get()->goToNextGameList(); ViewController::get()->goToNextGameList();
return true; return true;
} }
@ -151,16 +153,14 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
else if (config->isMappedLike(getQuickSystemSelectLeftButton(), input)) { else if (config->isMappedLike(getQuickSystemSelectLeftButton(), input)) {
if (Settings::getInstance()->getBool("QuickSystemSelect")) { if (Settings::getInstance()->getBool("QuickSystemSelect")) {
onFocusLost(); onFocusLost();
if (isListScrolling()) stopListScrolling();
stopListScrolling();
ViewController::get()->goToPrevGameList(); ViewController::get()->goToPrevGameList();
return true; return true;
} }
} }
else if (config->isMappedTo("x", input)) { else if (config->isMappedTo("x", input)) {
if (mRoot->getSystem()->isGameSystem() && getCursor()->getType() != PLACEHOLDER) { if (mRoot->getSystem()->isGameSystem() && getCursor()->getType() != PLACEHOLDER) {
if (isListScrolling()) stopListScrolling();
stopListScrolling();
// Go to random system game. // Go to random system game.
NavigationSounds::getInstance()->playThemeNavigationSound(SCROLLSOUND); NavigationSounds::getInstance()->playThemeNavigationSound(SCROLLSOUND);
FileData* randomGame = getCursor()->getSystem()->getRandomGame(getCursor()); FileData* randomGame = getCursor()->getSystem()->getRandomGame(getCursor());
@ -182,7 +182,6 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
if (mRoot->getSystem()->isGameSystem()) { if (mRoot->getSystem()->isGameSystem()) {
if (getCursor()->getType() == GAME || getCursor()->getType() == FOLDER) if (getCursor()->getType() == GAME || getCursor()->getType() == FOLDER)
NavigationSounds::getInstance()->playThemeNavigationSound(FAVORITESOUND); NavigationSounds::getInstance()->playThemeNavigationSound(FAVORITESOUND);
// Marking folders as favorites is only cosmetic as they're not sorted // Marking folders as favorites is only cosmetic as they're not sorted
// differently and they're not part of any collections. So it makes more // differently and they're not part of any collections. So it makes more
// sense to do it here than to add the function to CollectionSystemManager. // sense to do it here than to add the function to CollectionSystemManager.

View file

@ -1,16 +1,18 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// ISimpleGameListView.h // ISimpleGameListView.h
// //
// Interface that defines a simple GameListView. // Interface that defines a simple gamelist view.
// //
#pragma once
#ifndef ES_APP_VIEWS_GAME_LIST_ISIMPLE_GAME_LIST_VIEW_H #ifndef ES_APP_VIEWS_GAME_LIST_ISIMPLE_GAME_LIST_VIEW_H
#define ES_APP_VIEWS_GAME_LIST_ISIMPLE_GAME_LIST_VIEW_H #define ES_APP_VIEWS_GAME_LIST_ISIMPLE_GAME_LIST_VIEW_H
#include "components/ImageComponent.h" #include "components/ImageComponent.h"
#include "components/TextComponent.h" #include "components/TextComponent.h"
#include "views/gamelist/IGameListView.h" #include "views/gamelist/IGameListView.h"
#include <stack> #include <stack>
class ISimpleGameListView : public IGameListView class ISimpleGameListView : public IGameListView
@ -21,8 +23,8 @@ public:
// Called when a new file is added, a file is removed, a file's metadata changes, // Called when a new file is added, a file is removed, a file's metadata changes,
// or a file's children are sorted. // or a file's children are sorted.
// NOTE: FILE_SORTED is only reported for the topmost FileData, where the sort started. // Note: FILE_SORTED is only reported for the topmost FileData, where the sort started.
// Since sorts are recursive, that FileData's children probably changed too. // Since sorts are recursive, FileData's children probably changed too.
virtual void onFileChanged(FileData* file, FileChangeType change) override; virtual void onFileChanged(FileData* file, FileChangeType change) override;
// Called whenever the theme changes. // Called whenever the theme changes.

View file

@ -1,4 +1,6 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// GuiComponent.cpp // GuiComponent.cpp
// //
// Basic GUI component handling such as placement, rotation, Z-order, rendering and animation. // Basic GUI component handling such as placement, rotation, Z-order, rendering and animation.
@ -12,6 +14,7 @@
#include "Log.h" #include "Log.h"
#include "ThemeData.h" #include "ThemeData.h"
#include "Window.h" #include "Window.h"
#include <algorithm> #include <algorithm>
GuiComponent::GuiComponent(Window* window) GuiComponent::GuiComponent(Window* window)
@ -26,7 +29,8 @@ GuiComponent::GuiComponent(Window* window)
mTransform(Transform4x4f::Identity()), mTransform(Transform4x4f::Identity()),
mIsProcessing(false), mIsProcessing(false),
mVisible(true), mVisible(true),
mEnabled(true) mEnabled(true),
mRenderView(false)
{ {
for (unsigned char i = 0; i < MAX_ANIMATIONS; i++) for (unsigned char i = 0; i < MAX_ANIMATIONS; i++)
mAnimationMap[i] = nullptr; mAnimationMap[i] = nullptr;
@ -230,7 +234,7 @@ void GuiComponent::sortChildren()
unsigned int GuiComponent::getChildCount() const unsigned int GuiComponent::getChildCount() const
{ {
return (int)mChildren.size(); return static_cast<int>(mChildren.size());
} }
GuiComponent* GuiComponent::getChild(unsigned int i) const GuiComponent* GuiComponent::getChild(unsigned int i) const
@ -437,7 +441,8 @@ void GuiComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
const std::string& view, const std::string& element, unsigned int properties) const std::string& view, const std::string& element, unsigned int properties)
{ {
Vector2f scale = getParent() ? getParent()->getSize() Vector2f scale = getParent() ? getParent()->getSize()
: Vector2f((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight()); : Vector2f(static_cast<float>(Renderer::getScreenWidth()),
static_cast<float>(Renderer::getScreenHeight()));
const ThemeData::ThemeElement* elem = theme->getElement(view, element, ""); const ThemeData::ThemeElement* elem = theme->getElement(view, element, "");
if (!elem) if (!elem)
@ -511,6 +516,12 @@ void GuiComponent::onHide()
getChild(i)->onHide(); getChild(i)->onHide();
} }
void GuiComponent::onPauseVideo()
{
for (unsigned int i = 0; i < getChildCount(); i++)
getChild(i)->onPauseVideo();
}
void GuiComponent::onScreenSaverActivate() void GuiComponent::onScreenSaverActivate()
{ {
for (unsigned int i = 0; i < getChildCount(); i++) for (unsigned int i = 0; i < getChildCount(); i++)

View file

@ -1,4 +1,6 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// GuiComponent.h // GuiComponent.h
// //
// Basic GUI component handling such as placement, rotation, Z-order, rendering and animation. // Basic GUI component handling such as placement, rotation, Z-order, rendering and animation.
@ -91,7 +93,8 @@ public:
float getRotation() const; float getRotation() const;
void setRotation(float rotation); void setRotation(float rotation);
inline void setRotationDegrees(float rotation) { setRotation((float)ES_DEG_TO_RAD(rotation)); } inline void setRotationDegrees(float rotation) {
setRotation(static_cast<float>(ES_DEG_TO_RAD(rotation))); }
float getScale() const; float getScale() const;
void setScale(float scale); void setScale(float scale);
@ -163,6 +166,9 @@ public:
virtual void onShow(); virtual void onShow();
virtual void onHide(); virtual void onHide();
virtual void onPauseVideo();
virtual void setRenderView(bool status) { mRenderView = status; }
virtual bool getRenderView() { return mRenderView; };
virtual void onScreenSaverActivate(); virtual void onScreenSaverActivate();
virtual void onScreenSaverDeactivate(); virtual void onScreenSaverDeactivate();
@ -221,6 +227,7 @@ protected:
bool mIsProcessing; bool mIsProcessing;
bool mVisible; bool mVisible;
bool mEnabled; bool mEnabled;
bool mRenderView;
private: private:
// Don't access this directly! Use getTransform()! // Don't access this directly! Use getTransform()!

View file

@ -1,4 +1,6 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// VideoComponent.cpp // VideoComponent.cpp
// //
// Base class for playing videos. // Base class for playing videos.
@ -67,10 +69,11 @@ VideoComponent::VideoComponent(
mIsPlaying(false), mIsPlaying(false),
mPause(false), mPause(false),
mShowing(false), mShowing(false),
mScreensaverActive(false),
mGameLaunched(false),
mDisable(false), mDisable(false),
mScreensaverActive(false),
mScreensaverMode(false), mScreensaverMode(false),
mGameLaunched(false),
mBlockPlayer(false),
mTargetIsMax(false), mTargetIsMax(false),
mTargetSize(0, 0) mTargetSize(0, 0)
{ {
@ -236,6 +239,9 @@ std::vector<HelpPrompt> VideoComponent::getHelpPrompts()
void VideoComponent::handleStartDelay() void VideoComponent::handleStartDelay()
{ {
if (mBlockPlayer)
return;
// Only play if any delay has timed out. // Only play if any delay has timed out.
if (mStartDelayed) { if (mStartDelayed) {
// If the setting to override the theme-supplied video delay setting has been enabled, // If the setting to override the theme-supplied video delay setting has been enabled,
@ -284,6 +290,11 @@ void VideoComponent::startVideoWithDelay()
void VideoComponent::update(int deltaTime) void VideoComponent::update(int deltaTime)
{ {
if (mBlockPlayer) {
setImage(mStaticImagePath);
return;
}
manageState(); manageState();
// If the video start is delayed and there is less than the fade time, then set // If the video start is delayed and there is less than the fade time, then set
@ -340,6 +351,8 @@ void VideoComponent::manageState()
void VideoComponent::onShow() void VideoComponent::onShow()
{ {
mBlockPlayer = false;
mPause = false;
mShowing = true; mShowing = true;
manageState(); manageState();
} }
@ -350,6 +363,13 @@ void VideoComponent::onHide()
manageState(); manageState();
} }
void VideoComponent::onPauseVideo()
{
mBlockPlayer = true;
mPause = true;
manageState();
}
void VideoComponent::onScreenSaverActivate() void VideoComponent::onScreenSaverActivate()
{ {
mScreensaverActive = true; mScreensaverActive = true;

View file

@ -1,10 +1,11 @@
// SPDX-License-Identifier: MIT
// //
// EmulationStation Desktop Edition
// VideoComponent.h // VideoComponent.h
// //
// Base class for playing videos. // Base class for playing videos.
// //
#pragma once
#ifndef ES_CORE_COMPONENTS_VIDEO_COMPONENT_H #ifndef ES_CORE_COMPONENTS_VIDEO_COMPONENT_H
#define ES_CORE_COMPONENTS_VIDEO_COMPONENT_H #define ES_CORE_COMPONENTS_VIDEO_COMPONENT_H
@ -46,6 +47,7 @@ public:
virtual void onShow() override; virtual void onShow() override;
virtual void onHide() override; virtual void onHide() override;
virtual void onPauseVideo() override;
virtual void onScreenSaverActivate() override; virtual void onScreenSaverActivate() override;
virtual void onScreenSaverDeactivate() override; virtual void onScreenSaverDeactivate() override;
virtual void onGameLaunchedActivate() override; virtual void onGameLaunchedActivate() override;
@ -110,8 +112,8 @@ protected:
std::string mVideoPath; std::string mVideoPath;
std::string mPlayingVideoPath; std::string mPlayingVideoPath;
bool mStartDelayed;
unsigned mStartTime; unsigned mStartTime;
bool mStartDelayed;
bool mIsPlaying; bool mIsPlaying;
bool mPause; bool mPause;
bool mShowing; bool mShowing;
@ -119,6 +121,7 @@ protected:
bool mScreensaverActive; bool mScreensaverActive;
bool mScreensaverMode; bool mScreensaverMode;
bool mGameLaunched; bool mGameLaunched;
bool mBlockPlayer;
bool mTargetIsMax; bool mTargetIsMax;
Configuration mConfig; Configuration mConfig;