Fixed multiple issues with view transitions.

This commit is contained in:
Leon Styhre 2020-11-16 17:44:33 +01:00
parent 858b20bcc1
commit 2220787c3b
9 changed files with 52 additions and 28 deletions

View file

@ -237,7 +237,7 @@ void SystemScreensaver::launchGame()
IGameListView* view = ViewController::get()-> IGameListView* view = ViewController::get()->
getGameListView(mCurrentGame->getSystem()).get(); getGameListView(mCurrentGame->getSystem()).get();
view->setCursor(mCurrentGame); view->setCursor(mCurrentGame);
ViewController::get()->resetMovingCamera(); ViewController::get()->cancelViewTransitions();
ViewController::get()->launch(mCurrentGame); ViewController::get()->launch(mCurrentGame);
} }
} }
@ -250,7 +250,7 @@ void SystemScreensaver::goToGame()
IGameListView* view = ViewController::get()-> IGameListView* view = ViewController::get()->
getGameListView(mCurrentGame->getSystem()).get(); getGameListView(mCurrentGame->getSystem()).get();
view->setCursor(mCurrentGame); view->setCursor(mCurrentGame);
ViewController::get()->resetMovingCamera(); ViewController::get()->cancelViewTransitions();
} }
} }

View file

@ -162,7 +162,6 @@ void GuiMenu::openUISettings()
CollectionSystemManager::get()->updateSystemsList(); CollectionSystemManager::get()->updateSystemsList();
Settings::getInstance()->setString("ThemeSet", theme_set->getSelected()); Settings::getInstance()->setString("ThemeSet", theme_set->getSelected());
s->setNeedsSaving(); s->setNeedsSaving();
s->setNeedsGoToSystemView(SystemData::sSystemVector.front());
s->setNeedsReloading(); s->setNeedsReloading();
} }
}); });

View file

@ -200,12 +200,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(); ViewController::get()->cancelViewTransitions();
listInput(-1); listInput(-1);
return true; return true;
} }
if (config->isMappedLike("down", input)) { if (config->isMappedLike("down", input)) {
ViewController::get()->resetMovingCamera(); ViewController::get()->cancelViewTransitions();
listInput(1); listInput(1);
return true; return true;
} }
@ -214,12 +214,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(); ViewController::get()->cancelViewTransitions();
listInput(-1); listInput(-1);
return true; return true;
} }
if (config->isMappedLike("right", input)) { if (config->isMappedLike("right", input)) {
ViewController::get()->resetMovingCamera(); ViewController::get()->cancelViewTransitions();
listInput(1); listInput(1);
return true; return true;
} }
@ -244,6 +244,8 @@ bool SystemView::input(InputConfig* config, Input input)
config->isMappedTo("select", input) && config->isMappedTo("select", input) &&
Settings::getInstance()->getBool("ScreensaverControls")) { Settings::getInstance()->getBool("ScreensaverControls")) {
if (!mWindow->isScreensaverActive()) { if (!mWindow->isScreensaverActive()) {
ViewController::get()->stopScrolling();
ViewController::get()->cancelViewTransitions();
mWindow->startScreensaver(); mWindow->startScreensaver();
mWindow->renderScreensaver(); mWindow->renderScreensaver();
} }

View file

@ -53,6 +53,7 @@ ViewController::ViewController(
mCamera(Transform4x4f::Identity()), mCamera(Transform4x4f::Identity()),
mWrappedViews(false), mWrappedViews(false),
mFadeOpacity(0), mFadeOpacity(0),
mCancelledAnimation(false),
mLockInput(false) mLockInput(false)
{ {
mState.viewing = NOTHING; mState.viewing = NOTHING;
@ -124,13 +125,21 @@ bool ViewController::isCameraMoving()
return false; return false;
} }
void ViewController::resetMovingCamera() void ViewController::cancelViewTransitions()
{ {
if (Settings::getInstance()->getString("TransitionStyle") == "slide" && isCameraMoving()) { if (Settings::getInstance()->getString("TransitionStyle") == "slide" && isCameraMoving()) {
mCamera.r3().x() = -mCurrentView->getPosition().x(); mCamera.r3().x() = -mCurrentView->getPosition().x();
mCamera.r3().y() = -mCurrentView->getPosition().y(); mCamera.r3().y() = -mCurrentView->getPosition().y();
stopAllAnimations(); stopAllAnimations();
} }
else if (Settings::getInstance()->getString("TransitionStyle") == "fade") {
if (isAnimationPlaying(0)) {
finishAnimation(0);
mCancelledAnimation = true;
mFadeOpacity = 0;
mWindow->invalidateCachedBackground();
}
}
} }
void ViewController::stopScrolling() void ViewController::stopScrolling()
@ -218,6 +227,10 @@ void ViewController::goToGameList(SystemData* system)
{ {
bool wrapFirstToLast = false; bool wrapFirstToLast = false;
bool wrapLastToFirst = false; bool wrapLastToFirst = false;
bool slideTransitions = false;
if (Settings::getInstance()->getString("TransitionStyle") == "slide")
slideTransitions = true;
// Restore the X position for the view, if it was previously moved. // Restore the X position for the view, if it was previously moved.
if (mWrappedViews) if (mWrappedViews)
@ -226,8 +239,7 @@ void ViewController::goToGameList(SystemData* system)
// Find if we're wrapping around the first and last systems, which requires the gamelist // Find if we're wrapping around the first and last systems, which requires the gamelist
// to be moved in order to avoid weird camera movements. This is only needed for the // to be moved in order to avoid weird camera movements. This is only needed for the
// slide transition style though. // slide transition style though.
if (mState.viewing == GAME_LIST && if (mState.viewing == GAME_LIST && slideTransitions) {
Settings::getInstance()->getString("TransitionStyle") == "slide") {
if (SystemData::sSystemVector.front() == mState.getSystem()) { if (SystemData::sSystemVector.front() == mState.getSystem()) {
if (SystemData::sSystemVector.back() == system) if (SystemData::sSystemVector.back() == system)
wrapFirstToLast = true; wrapFirstToLast = true;
@ -244,7 +256,9 @@ void ViewController::goToGameList(SystemData* system)
if (mSystemListView->isAnimationPlaying(0)) if (mSystemListView->isAnimationPlaying(0))
mSystemListView->finishAnimation(0); mSystemListView->finishAnimation(0);
} }
resetMovingCamera();
if (slideTransitions)
cancelViewTransitions();
// Disable rendering of the system view. // Disable rendering of the system view.
if (getSystemListView()->getRenderView()) if (getSystemListView()->getRenderView())
@ -259,7 +273,7 @@ void ViewController::goToGameList(SystemData* system)
float offsetX = sysList->getPosition().x(); float offsetX = sysList->getPosition().x();
int sysId = getSystemId(system); int sysId = getSystemId(system);
sysList->setPosition(sysId* static_cast<float>(Renderer::getScreenWidth()), sysList->setPosition(sysId * static_cast<float>(Renderer::getScreenWidth()),
sysList->getPosition().y()); sysList->getPosition().y());
offsetX = sysList->getPosition().x() - offsetX; offsetX = sysList->getPosition().x() - offsetX;
mCamera.translation().x() -= offsetX; mCamera.translation().x() -= offsetX;
@ -309,6 +323,8 @@ void ViewController::goToGameList(SystemData* system)
void ViewController::playViewTransition(bool instant) void ViewController::playViewTransition(bool instant)
{ {
mCancelledAnimation = false;
Vector3f target(Vector3f::Zero()); Vector3f target(Vector3f::Zero());
if (mCurrentView) if (mCurrentView)
target = mCurrentView->getPosition(); target = mCurrentView->getPosition();
@ -330,7 +346,12 @@ void ViewController::playViewTransition(bool instant)
cancelAnimation(0); cancelAnimation(0);
auto fadeFunc = [this](float t) { auto fadeFunc = [this](float t) {
mFadeOpacity = Math::lerp(0, 1, t); // The flag mCancelledAnimation is required only when cancelViewTransitions()
// cancels the animation, and it's only needed for the Fade transitions.
// Without this, a (much shorter) fade transition would still play as
// finishedCallback is calling this function.
if (!mCancelledAnimation)
mFadeOpacity = Math::lerp(0, 1, t);
}; };
const static int FADE_DURATION = 120; // Fade in/out time. const static int FADE_DURATION = 120; // Fade in/out time.
@ -540,7 +561,7 @@ bool ViewController::input(InputConfig* config, Input input)
// also continue to run after closing the menu. // also continue to run after closing the menu.
mCurrentView->stopListScrolling(); mCurrentView->stopListScrolling();
// Finally, if the camera is currently moving, reset its position. // Finally, if the camera is currently moving, reset its position.
resetMovingCamera(); cancelViewTransitions();
mWindow->pushGui(new GuiMenu(mWindow)); mWindow->pushGui(new GuiMenu(mWindow));
return true; return true;
@ -705,6 +726,7 @@ void ViewController::reloadAll()
goToSystemView(SystemData::sSystemVector.front(), false); goToSystemView(SystemData::sSystemVector.front(), false);
mSystemListView->goToSystem(system, false); mSystemListView->goToSystem(system, false);
mCurrentView = mSystemListView; mCurrentView = mSystemListView;
mCamera.r3().x() = 0;
} }
else { else {
goToSystemView(SystemData::sSystemVector.front(), false); goToSystemView(SystemData::sSystemVector.front(), false);

View file

@ -55,7 +55,7 @@ public:
// Functions to make the GUI behave properly. // Functions to make the GUI behave properly.
bool isCameraMoving(); bool isCameraMoving();
void resetMovingCamera(); void cancelViewTransitions();
void stopScrolling(); void stopScrolling();
void onFileChanged(FileData* file, bool reloadGameList); void onFileChanged(FileData* file, bool reloadGameList);
@ -123,6 +123,7 @@ private:
bool mWrappedViews; bool mWrappedViews;
float mWrapPreviousPositionX; float mWrapPreviousPositionX;
float mFadeOpacity; float mFadeOpacity;
bool mCancelledAnimation; // Needed only for the Fade transition style.
bool mLockInput; bool mLockInput;
State mState; State mState;

View file

@ -19,7 +19,7 @@ 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) {
ViewController::get()->resetMovingCamera(); ViewController::get()->cancelViewTransitions();
stopListScrolling(); stopListScrolling();
mWindow->pushGui(new GuiGamelistOptions(mWindow, this->mRoot->getSystem())); mWindow->pushGui(new GuiGamelistOptions(mWindow, this->mRoot->getSystem()));
return true; return true;

View file

@ -104,14 +104,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) {
ViewController::get()->resetMovingCamera(); ViewController::get()->cancelViewTransitions();
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(); ViewController::get()->cancelViewTransitions();
NavigationSounds::getInstance()->playThemeNavigationSound(SELECTSOUND); NavigationSounds::getInstance()->playThemeNavigationSound(SELECTSOUND);
mCursorStack.push(cursor); mCursorStack.push(cursor);
populateList(cursor->getChildrenListToDisplay(), cursor); populateList(cursor->getChildrenListToDisplay(), cursor);
@ -123,7 +123,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(); ViewController::get()->cancelViewTransitions();
if (mCursorStack.size()) { if (mCursorStack.size()) {
NavigationSounds::getInstance()->playThemeNavigationSound(BACKSOUND); NavigationSounds::getInstance()->playThemeNavigationSound(BACKSOUND);
populateList(mCursorStack.top()->getParent()->getChildrenListToDisplay(), populateList(mCursorStack.top()->getParent()->getChildrenListToDisplay(),

View file

@ -393,14 +393,14 @@ bool GuiComponent::cancelAnimation(unsigned char slot)
bool GuiComponent::finishAnimation(unsigned char slot) bool GuiComponent::finishAnimation(unsigned char slot)
{ {
assert(slot < MAX_ANIMATIONS); assert(slot < MAX_ANIMATIONS);
if (mAnimationMap[slot]) { AnimationController* anim = mAnimationMap[slot];
if (anim) {
// Skip to animation's end. // Skip to animation's end.
const bool done = mAnimationMap[slot]->update(mAnimationMap[slot]-> const bool done = anim->update(anim->getAnimation()->getDuration() - anim->getTime());
getAnimation()->getDuration() - mAnimationMap[slot]->getTime()); if(done) {
assert(done); mAnimationMap[slot] = nullptr;
delete anim; // Will also call finishedCallback.
delete mAnimationMap[slot]; // Will also call finishedCallback. }
mAnimationMap[slot] = nullptr;
return true; return true;
} }
else { else {
@ -416,7 +416,7 @@ bool GuiComponent::advanceAnimation(unsigned char slot, unsigned int time)
bool done = anim->update(time); bool done = anim->update(time);
if (done) { if (done) {
mAnimationMap[slot] = nullptr; mAnimationMap[slot] = nullptr;
delete anim; delete anim; // Will also call finishedCallback.
} }
return true; return true;
} }

View file

@ -105,7 +105,7 @@ void Settings::setDefaults()
// UI settings. // UI settings.
mStringMap["StartupSystem"] = ""; mStringMap["StartupSystem"] = "";
mStringMap["GamelistViewStyle"] = "automatic"; mStringMap["GamelistViewStyle"] = "automatic";
mStringMap["TransitionStyle"] = "instant"; mStringMap["TransitionStyle"] = "slide";
mStringMap["ThemeSet"] = "rbsimple-DE"; mStringMap["ThemeSet"] = "rbsimple-DE";
mStringMap["UIMode"] = "full"; mStringMap["UIMode"] = "full";
mStringMap["DefaultSortOrder"] = "filename, ascending"; mStringMap["DefaultSortOrder"] = "filename, ascending";