Rewrote the animation activation functions and state machines to

remove/reduce the glitch behaviour.
WARNING: This will disable workarounds that have been used in the themes so
far; many if not all themes will need to be changed to work properly!
This commit is contained in:
Pieter Hulshoff 2016-06-05 09:32:48 +02:00
parent 4b05992a19
commit 9da55a844e
12 changed files with 308 additions and 493 deletions

View File

@ -22,9 +22,8 @@
Component::Component(Page &p)
: page(p)
{
tweens_ = NULL;
newItemSelectedSinceEnter = false;
backgroundTexture_ = NULL;
tweens_ = NULL;
backgroundTexture_ = NULL;
freeGraphicsMemory();
}
@ -33,7 +32,6 @@ Component::Component(const Component &copy)
: page(copy.page)
{
tweens_ = NULL;
newItemSelectedSinceEnter = false;
backgroundTexture_ = NULL;
freeGraphicsMemory();
@ -53,23 +51,16 @@ Component::~Component()
void Component::freeGraphicsMemory()
{
currentAnimationState = HIDDEN;
enterRequested = false;
exitRequested = false;
menuEnterRequested = false;
menuEnterIndex = -1;
menuScrollRequested = false;
menuExitRequested = false;
menuExitIndex = -1;
animationRequestedType_ = "";
animationType_ = "";
animationRequested_ = false;
newItemSelected = false;
menuIndex_ = -1;
newItemSelected = false;
playlistChanged = false;
highlightExitComplete = false;
currentTweens_ = NULL;
currentTweenIndex_ = 0;
currentTweenComplete_ = false;
elapsedTweenTime_ = 0;
scrollActive = false;
currentTweens_ = NULL;
currentTweenIndex_ = 0;
currentTweenComplete_ = true;
elapsedTweenTime_ = 0;
if(backgroundTexture_)
{
@ -98,244 +89,71 @@ void Component::allocateGraphicsMemory()
}
}
void Component::triggerEnterEvent()
void Component::triggerEvent(std::string event, int menuIndex)
{
enterRequested = true;
animationRequestedType_ = event;
animationRequested_ = true;
menuIndex_ = menuIndex;
}
void Component::triggerExitEvent()
void Component::setPlaylist(std::string name)
{
exitRequested = true;
}
void Component::triggerMenuEnterEvent(int menuIndex)
{
menuEnterRequested = true;
menuEnterIndex = menuIndex;
}
void Component::triggerMenuScrollEvent()
{
menuScrollRequested = true;
}
void Component::triggerMenuExitEvent(int menuIndex)
{
menuExitRequested = true;
menuExitIndex = menuIndex;
}
void Component::triggerHighlightEvent()
{
newItemSelected = true;
}
void Component::triggerPlaylistChangeEvent(std::string name)
{
playlistChanged = true;
this->playlistName = name;
}
void Component::setNewItemSelected()
{
newItemSelected = true;
}
bool Component::isIdle()
{
return (currentAnimationState == IDLE);
}
bool Component::isHidden()
{
return (currentAnimationState == HIDDEN);
}
bool Component::isWaiting()
{
return (currentAnimationState == HIGHLIGHT_WAIT);
return (currentTweenComplete_ || animationType_ == "idle");
}
bool Component::isMenuScrolling()
{
return (currentAnimationState == MENU_ENTER || currentAnimationState == MENU_SCROLL || currentAnimationState == MENU_EXIT || menuScrollRequested);
return (!currentTweenComplete_ && animationType_ == "menuScroll");
}
void Component::setTweens(AnimationEvents *set)
{
tweens_ = set;
forceIdle();
}
void Component::forceIdle()
{
currentAnimationState = IDLE;
currentTweenIndex_ = 0;
currentTweenComplete_ = false;
elapsedTweenTime_ = 0;
currentTweens_ = NULL;
}
void Component::update(float dt)
{
elapsedTweenTime_ += dt;
highlightExitComplete = false;
if(isHidden() || isWaiting() || (isIdle() && (exitRequested || menuExitRequested || enterRequested || menuEnterRequested)))
if(animationRequested_ && animationRequestedType_ != "")
{
currentTweenComplete_ = true;
Animation *newTweens = tweens_->getAnimation( animationRequestedType_, menuIndex_ );
if (newTweens)
{
animationType_ = animationRequestedType_;
currentTweens_ = newTweens;
currentTweenIndex_ = 0;
elapsedTweenTime_ = 0;
currentTweenComplete_ = false;
}
animationRequested_ = false;
}
else if (tweens_ && currentTweenComplete_)
{
animationType_ = "idle";
currentTweens_ = tweens_->getAnimation( "idle", menuIndex_ );
currentTweenIndex_ = 0;
elapsedTweenTime_ = 0;
currentTweenComplete_ = false;
animationRequested_ = false;
}
currentTweenComplete_ = animate();
if(currentTweenComplete_)
{
currentTweens_ = NULL;
// There was no request to override our state path. Continue on as normal.
std::stringstream ss;
switch(currentAnimationState)
{
case MENU_ENTER:
currentTweens_ = NULL;
currentAnimationState = IDLE;
break;
case MENU_SCROLL:
currentTweens_ = NULL;
currentAnimationState = IDLE;
break;
case MENU_EXIT:
currentTweens_ = NULL;
currentAnimationState = IDLE;
break;
case ENTER:
currentTweens_ = tweens_->getAnimation("enter", menuEnterIndex);
currentAnimationState = HIGHLIGHT_ENTER;
break;
case EXIT:
currentTweens_ = NULL;
currentAnimationState = HIDDEN;
break;
case HIGHLIGHT_ENTER:
currentTweens_ = tweens_->getAnimation("idle", menuEnterIndex);
currentAnimationState = IDLE;
break;
case IDLE:
// prevent us from automatically jumping to the exit tween upon enter
if(enterRequested)
{
enterRequested = false;
newItemSelected = false;
}
else if(menuExitRequested && (!menuEnterRequested || menuExitRequested <= menuEnterRequested))
{
currentTweens_ = tweens_->getAnimation("menuExit", menuExitIndex);
currentAnimationState = MENU_EXIT;
menuExitRequested = false;
}
else if(menuEnterRequested && (!menuExitRequested || menuExitRequested > menuEnterRequested))
{
currentTweens_ = tweens_->getAnimation("menuEnter", menuEnterIndex);
currentAnimationState = MENU_ENTER;
menuEnterRequested = false;
}
else if(menuScrollRequested)
{
menuScrollRequested = false;
currentTweens_ = tweens_->getAnimation("menuScroll", menuEnterIndex);
currentAnimationState = MENU_SCROLL;
}
else if(scrollActive || newItemSelected || exitRequested)
{
currentTweens_ = tweens_->getAnimation("highlightExit", menuEnterIndex);
currentAnimationState = HIGHLIGHT_EXIT;
}
else
{
currentTweens_ = tweens_->getAnimation("idle", menuEnterIndex);
currentAnimationState = IDLE;
}
break;
case HIGHLIGHT_EXIT:
// intentionally break down
case HIGHLIGHT_WAIT:
if(exitRequested && (currentAnimationState == HIGHLIGHT_WAIT))
{
currentTweens_ = tweens_->getAnimation("highlightExit", menuEnterIndex);
currentAnimationState = HIGHLIGHT_EXIT;
}
else if(exitRequested && (currentAnimationState == HIGHLIGHT_EXIT))
{
currentTweens_ = tweens_->getAnimation("exit", menuEnterIndex);
currentAnimationState = EXIT;
exitRequested = false;
}
else if(scrollActive)
{
currentTweens_ = NULL;
currentAnimationState = HIGHLIGHT_WAIT;
}
else if(newItemSelected)
{
currentTweens_ = tweens_->getAnimation("highlightEnter", menuEnterIndex);
currentAnimationState = HIGHLIGHT_ENTER;
highlightExitComplete = true;
newItemSelected = false;
}
else
{
currentTweens_ = NULL;
currentAnimationState = HIGHLIGHT_WAIT;
}
break;
case HIDDEN:
if(enterRequested || exitRequested)
{
currentTweens_ = tweens_->getAnimation("enter", menuEnterIndex);
currentAnimationState = ENTER;
}
else if(menuExitRequested && (!menuEnterRequested || menuExitRequested <= menuEnterRequested))
{
currentTweens_ = tweens_->getAnimation("menuExit", menuExitIndex);
currentAnimationState = MENU_EXIT;
menuExitRequested = false;
}
else if(menuEnterRequested && (!menuExitRequested || menuExitRequested > menuEnterRequested))
{
currentTweens_ = tweens_->getAnimation("menuEnter", menuEnterIndex);
currentAnimationState = MENU_ENTER;
menuEnterRequested = false;
}
else if(menuScrollRequested)
{
menuScrollRequested = false;
currentTweens_ = tweens_->getAnimation("menuScroll", menuEnterIndex);
currentAnimationState = MENU_SCROLL;
}
else
{
currentTweens_ = NULL;
currentAnimationState = HIDDEN;
}
}
currentTweenIndex_ = 0;
currentTweenComplete_ = false;
elapsedTweenTime_ = 0;
currentTweens_ = NULL;
currentTweenIndex_ = 0;
}
currentTweenComplete_ = animate(isIdle());
}
void Component::draw()
@ -359,7 +177,7 @@ void Component::draw()
}
}
bool Component::animate(bool loop)
bool Component::animate()
{
bool completeDone = false;
if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->size())
@ -449,10 +267,6 @@ bool Component::animate(bool loop)
if(!currentTweens_ || currentTweenIndex_ >= currentTweens_->tweenSets()->size())
{
if(loop)
{
currentTweenIndex_ = 0;
}
completeDone = true;
}

View File

@ -34,59 +34,26 @@ public:
virtual void allocateGraphicsMemory();
virtual void launchEnter() {}
virtual void launchExit() {}
void triggerEnterEvent();
void triggerExitEvent();
void triggerMenuEnterEvent(int menuIndex = -1);
void triggerMenuExitEvent(int menuIndex = -1);
void triggerMenuScrollEvent();
void triggerHighlightEvent();
void triggerPlaylistChangeEvent(std::string name);
void triggerEvent(std::string event, int menuIndex = -1);
void setPlaylist(std::string name );
void setNewItemSelected();
bool isIdle();
bool isHidden();
bool isWaiting();
bool isMenuScrolling();
bool newItemSelected;
virtual void update(float dt);
virtual void draw();
void setTweens(AnimationEvents *set);
void forceIdle();
ViewInfo baseViewInfo;
std::string collectionName;
bool scrollActive;
protected:
Page &page;
enum AnimationState
{
IDLE,
ENTER,
HIGHLIGHT_EXIT,
HIGHLIGHT_WAIT,
HIGHLIGHT_ENTER,
EXIT,
MENU_ENTER,
MENU_SCROLL,
MENU_EXIT,
HIDDEN
};
AnimationState currentAnimationState;
bool enterRequested;
bool exitRequested;
bool menuEnterRequested;
int menuEnterIndex;
bool menuScrollRequested;
bool menuExitRequested;
int menuExitIndex;
bool newItemSelected;
bool playlistChanged;
std::string playlistName;
bool highlightExitComplete;
bool newItemSelectedSinceEnter;
private:
bool animate(bool loop);
bool animate();
bool tweenSequencingComplete();
AnimationEvents *tweens_;
@ -94,6 +61,10 @@ private:
SDL_Texture *backgroundTexture_;
unsigned int currentTweenIndex_;
bool currentTweenComplete_;
float elapsedTweenTime_;
bool currentTweenComplete_;
float elapsedTweenTime_;
std::string animationRequestedType_;
std::string animationType_;
bool animationRequested_;
int menuIndex_;
};

View File

@ -33,8 +33,6 @@ ReloadableMedia::ReloadableMedia(Configuration &config, bool systemMode, std::st
, config_(config)
, systemMode_(systemMode)
, loadedComponent_(NULL)
, reloadRequested_(false)
, firstLoad_(true)
, videoInst_(NULL)
, isVideo_(isVideo)
, FfntInst_(font)
@ -63,23 +61,11 @@ void ReloadableMedia::enableTextFallback_(bool value)
void ReloadableMedia::update(float dt)
{
if(newItemSelected)
{
std::string collection;
config_.getProperty("currentCollection", collection);
if(!systemMode_ || (systemMode_ && currentCollection_ != collection))
{
reloadRequested_ = true;
}
}
// wait for the right moment to reload the image
if (reloadRequested_ && (highlightExitComplete || firstLoad_))
if (newItemSelected)
{
reloadTexture();
reloadRequested_ = false;
firstLoad_ = false;
newItemSelected = false;
}
if(loadedComponent_)
@ -102,8 +88,6 @@ void ReloadableMedia::update(float dt)
void ReloadableMedia::allocateGraphicsMemory()
{
firstLoad_ = true;
if(loadedComponent_)
{
loadedComponent_->allocateGraphicsMemory();

View File

@ -44,8 +44,6 @@ private:
Configuration &config_;
bool systemMode_;
Component *loadedComponent_;
bool reloadRequested_;
bool firstLoad_;
IVideo *videoInst_;
bool isVideo_;
Font *FfntInst_;

View File

@ -30,8 +30,6 @@ ReloadableText::ReloadableText(std::string type, Page &page, Configuration &conf
, imageInst_(NULL)
, type_(type)
, layoutKey_(layoutKey)
, reloadRequested_(false)
, firstLoad_(true)
, fontInst_(font)
, timeFormat_(timeFormat)
, scaleX_(scaleX)
@ -52,18 +50,10 @@ ReloadableText::~ReloadableText()
void ReloadableText::update(float dt)
{
if((type_ != "playlist" && newItemSelected) ||
(type_ == "playlist" && playlistChanged) ||
(type_ == "time"))
{
reloadRequested_ = true;
}
// wait for the right moment to reload the image
if (reloadRequested_ && (type_ == "time" || highlightExitComplete || firstLoad_))
if (newItemSelected || type_ == "time")
{
ReloadTexture();
reloadRequested_ = false;
firstLoad_ = false;
newItemSelected = false;
}
// needs to be ran at the end to prevent the NewItemSelected flag from being detected
@ -73,8 +63,6 @@ void ReloadableText::update(float dt)
void ReloadableText::allocateGraphicsMemory()
{
firstLoad_ = true;
ReloadTexture();
// NOTICE! needs to be done last to prevent flags from being missed

View File

@ -41,8 +41,6 @@ private:
Text *imageInst_;
std::string type_;
std::string layoutKey_;
bool reloadRequested_;
bool firstLoad_;
Font *fontInst_;
std::string timeFormat_;

View File

@ -381,7 +381,7 @@ void ScrollingList::freeGraphicsMemory()
deallocateSpritePoints();
}
void ScrollingList::triggerMenuEnterEvent()
void ScrollingList::triggerMenuEnterEvent( int menuIndex )
{
focus_ = true;
notifyAllRequested_ = true;
@ -389,11 +389,11 @@ void ScrollingList::triggerMenuEnterEvent()
for(unsigned int i = 0; i < components_.size(); ++i)
{
Component *c = components_.at(i);
if(c) c->triggerMenuEnterEvent();
if(c) c->triggerEvent( "menuEnter", menuIndex );
}
}
void ScrollingList::triggerMenuExitEvent()
void ScrollingList::triggerMenuExitEvent( int menuIndex )
{
focus_ = false;
notifyAllRequested_ = true;
@ -401,7 +401,7 @@ void ScrollingList::triggerMenuExitEvent()
for(unsigned int i = 0; i < components_.size(); ++i)
{
Component *c = components_.at(i);
if(c) c->triggerMenuExitEvent();
if(c) c->triggerEvent( "menuExit", menuIndex );
}
}
@ -500,7 +500,7 @@ void ScrollingList::update(float dt)
resetTweens(c, tweenPoints_->at(i), currentvi, nextvi, scrollPeriod_);
c->baseViewInfo.font = nextvi->font; // Use the font settings of the next index
c->triggerMenuScrollEvent();
c->triggerEvent( "menuScroll" );
}
if(c) c->update(dt);
@ -534,17 +534,17 @@ void ScrollingList::update(float dt)
notifyAllRequested_ = false;
}
unsigned int ScrollingList::getSelectedIndex()
{
unsigned int ScrollingList::getSelectedIndex()
{
if(!items_) return 0;
return loopIncrement(itemIndex_, selectedOffsetIndex_, items_->size());
}
unsigned int ScrollingList::getSize()
{
if(!items_) return 0;
return items_->size();
}
unsigned int ScrollingList::getSize()
{
if(!items_) return 0;
return items_->size();
}
void ScrollingList::resetTweens(Component *c, AnimationEvents *sets, ViewInfo *currentViewInfo, ViewInfo *nextViewInfo, double scrollTime)

View File

@ -53,8 +53,8 @@ public:
ScrollingList(const ScrollingList &copy);
virtual ~ScrollingList();
void triggerMenuEnterEvent();
void triggerMenuExitEvent();
void triggerMenuEnterEvent(int menuIndex = -1);
void triggerMenuExitEvent(int menuIndex = -1);
bool allocateTexture(unsigned int index, Item *i);
void deallocateTexture(unsigned int index);

View File

@ -33,8 +33,6 @@ Page::Page(Configuration &config)
, scrollActive_(false)
, selectedItem_(NULL)
, textStatusComponent_(NULL)
, selectedItemChanged_(false)
, playlistChanged_(false)
, loadSoundChunk_(NULL)
, unloadSoundChunk_(NULL)
, highlightSoundChunk_(NULL)
@ -97,7 +95,7 @@ void Page::DeInitialize()
}
CollectionVector_T::iterator itc = collections_.begin();
while(itc != collections_.end())
while(itc != collections_.end())
{
itc->collection->Save();
@ -132,12 +130,34 @@ void Page::setSelectSound(Sound *chunk)
{
selectSoundChunk_ = chunk;
}
void Page::onNewItemSelected(Item *item)
{
selectedItem_ = item;
selectedItemChanged_ = true;
for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++)
{
ScrollingList *menu = *it;
menu->setNewItemSelected();
}
if(unloadSoundChunk_)
{
unloadSoundChunk_->play();
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->setNewItemSelected();
}
}
}
void Page::pushMenu(ScrollingList *s)
{
menus_.push_back(s);
@ -201,7 +221,7 @@ bool Page::isMenuIdle()
bool Page::isIdle()
{
bool idle = isMenuIdle();
for(unsigned int i = 0; i < NUM_LAYERS && idle; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end() && idle; ++it)
@ -214,39 +234,12 @@ bool Page::isIdle()
}
bool Page::isHidden()
{
bool hidden = true;
for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++)
{
ScrollingList *menu = *it;
if(!menu->isHidden())
{
hidden = false;
break;
}
}
for(unsigned int i = 0; hidden && i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); hidden && it != LayerComponents[i].end(); ++it)
{
hidden = (*it)->isHidden();
}
}
return hidden;
}
void Page::start()
{
for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++)
{
ScrollingList *menu = *it;
menu->triggerEnterEvent();
menu->triggerEvent( "enter" );
}
if(loadSoundChunk_)
@ -264,7 +257,7 @@ void Page::startComponents()
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->triggerEnterEvent();
(*it)->triggerEvent( "enter" );
}
}
}
@ -274,7 +267,7 @@ void Page::stop()
for(MenuVector_T::iterator it = menus_.begin(); it != menus_.end(); it++)
{
ScrollingList *menu = *it;
menu->triggerExitEvent();
menu->triggerEvent( "exit" );
}
if(unloadSoundChunk_)
@ -286,12 +279,32 @@ void Page::stop()
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->triggerExitEvent();
(*it)->triggerEvent( "exit" );
}
}
}
void Page::setNewItemSelected()
{
if(activeMenu_)
{
activeMenu_->setNewItemSelected();
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->setNewItemSelected();
}
}
return;
}
Item *Page::getSelectedItem()
{
return selectedItem_;
@ -344,35 +357,54 @@ void Page::playlistChange()
{
if(activeMenu_)
{
activeMenu_->triggerPlaylistChangeEvent(playlist_->first);
activeMenu_->setPlaylist(playlist_->first);
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->triggerPlaylistChangeEvent(playlist_->first);
(*it)->setPlaylist(playlist_->first);
}
}
}
void Page::highlight()
void Page::highlightEnter()
{
Item *item = selectedItem_;
if(!item) return;
if(activeMenu_)
{
activeMenu_->triggerHighlightEvent();
activeMenu_->scrollActive = scrollActive_;
activeMenu_->triggerEvent( "highlightEnter" );
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->triggerHighlightEvent();
(*it)->scrollActive = scrollActive_;
(*it)->triggerEvent( "highlightEnter" );
}
}
}
void Page::highlightExit()
{
Item *item = selectedItem_;
if(!item) return;
if(activeMenu_)
{
activeMenu_->triggerEvent( "highlightExit" );
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->triggerEvent( "highlightExit" );
}
}
}
@ -433,7 +465,7 @@ void Page::pageScroll(ScrollDirection direction)
void Page::selectRandom()
{
if(activeMenu_) activeMenu_->random();
if(activeMenu_) activeMenu_->random();
}
void Page::letterScroll(ScrollDirection direction)
@ -465,28 +497,13 @@ unsigned int Page::getSelectedIndex()
bool Page::pushCollection(CollectionInfo *collection)
{
int menuExitIndex = -1;
int menuEnterIndex = -1;
if(activeMenu_)
{
activeMenu_->triggerMenuExitEvent();
}
if(menuDepth_ > 0)
{
menuExitIndex = menuDepth_ - 1;
}
// grow the menu as needed
if(menus_.size() >= menuDepth_ && activeMenu_)
{
activeMenu_ = new ScrollingList(*activeMenu_);
activeMenu_->forceIdle();
pushMenu(activeMenu_);
}
activeMenu_ = menus_[menuDepth_];
activeMenu_->collectionName = collection->name;
activeMenu_->setItems(&collection->items);
@ -501,11 +518,10 @@ bool Page::pushCollection(CollectionInfo *collection)
collections_.push_back(info);
playlist_ = info.playlist;
playlistChanged_ = true;
playlistChange();
if(menuDepth_ < menus_.size())
{
menuEnterIndex = menuDepth_;
menuDepth_++;
}
@ -514,15 +530,6 @@ bool Page::pushCollection(CollectionInfo *collection)
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->collectionName = collection->name;
if(menuEnterIndex >= 0)
{
(*it)->triggerMenuEnterEvent(menuEnterIndex);
}
if(menuExitIndex >= 0)
{
(*it)->triggerMenuExitEvent(menuExitIndex);
}
}
}
@ -531,8 +538,6 @@ bool Page::pushCollection(CollectionInfo *collection)
bool Page::popCollection()
{
int menuExitIndex = -1;
int menuEnterIndex = -1;
if(!activeMenu_) return false;
if(menuDepth_ <= 1) return false;
@ -547,44 +552,63 @@ bool Page::popCollection()
collections_.pop_back();
info = &collections_.back();
playlist_ = info->playlist;
playlistChanged_ = true;
if(activeMenu_)
{
activeMenu_->triggerMenuExitEvent();
}
playlistChange();
menuDepth_--;
menuExitIndex = menuDepth_;
menuEnterIndex = menuExitIndex - 1;
activeMenu_ = menus_[menuDepth_ - 1];
if(activeMenu_)
{
activeMenu_->triggerMenuEnterEvent();
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->collectionName = info->collection->name;
if(menuEnterIndex >= 0)
{
(*it)->triggerMenuEnterEvent(menuEnterIndex);
}
if(menuExitIndex >= 0)
{
(*it)->triggerMenuExitEvent(menuExitIndex);
}
}
}
return true;
}
void Page::enterMenu()
{
if(activeMenu_)
{
activeMenu_->triggerMenuEnterEvent( menuDepth_ - 1 );
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->triggerEvent( "menuEnter", menuDepth_ - 1 );
}
}
return;
}
void Page::exitMenu()
{
if(activeMenu_)
{
activeMenu_->triggerMenuExitEvent( menuDepth_ - 1 );
}
for(unsigned int i = 0; i < NUM_LAYERS; ++i)
{
for(std::vector<Component *>::iterator it = LayerComponents[i].begin(); it != LayerComponents[i].end(); ++it)
{
(*it)->triggerEvent( "menuExit", menuDepth_ - 1 );
}
}
return;
}
void Page::nextPlaylist()
{
MenuInfo_S &info = collections_.back();
@ -596,14 +620,14 @@ void Page::nextPlaylist()
playlist_++;
// wrap
if(playlist_ == info.collection->playlists.end()) playlist_ = info.collection->playlists.begin();
// find the first playlist
if(playlist_->second->size() != 0) break;
}
activeMenu_->setItems(playlist_->second);
activeMenu_->triggerMenuEnterEvent();
playlistChanged_ = true;
playlistChange();
}
void Page::favPlaylist()
@ -620,7 +644,7 @@ void Page::favPlaylist()
playlist_++;
// wrap
if(playlist_ == info.collection->playlists.end()) playlist_ = info.collection->playlists.begin();
// find the first playlist
if(playlist_->second->size() != 0 && playlist_->first == "favorites") break;
}
@ -631,7 +655,7 @@ void Page::favPlaylist()
activeMenu_->setItems(playlist_->second);
activeMenu_->triggerMenuEnterEvent();
playlistChanged_ = true;
playlistChange();
}
void Page::update(float dt)
@ -642,18 +666,6 @@ void Page::update(float dt)
menu->update(dt);
}
if(playlistChanged_)
{
playlistChange();
playlistChanged_ = false;
}
if(selectedItemChanged_ && !scrollActive_)
{
highlight();
selectedItemChanged_ = false;
}
if(textStatusComponent_)
{
@ -678,11 +690,11 @@ void Page::update(float dt)
{
MenuInfo_S &info = *del;
if(info.queueDelete && info.menu && info.menu->isIdle())
{
{
std::list<MenuInfo_S>::iterator next = del;
++next;
if(info.collection)
if(info.collection)
{
info.collection->Save();
delete info.collection;
@ -731,7 +743,7 @@ void Page::removePlaylist()
items->erase(it);
collection->saveRequest = true;
if(activeMenu_)
if(activeMenu_)
{
activeMenu_->deallocateSpritePoints();
activeMenu_->allocateSpritePoints();
@ -752,7 +764,7 @@ void Page::addPlaylist()
{
items->push_back(selectedItem_);
collection->saveRequest = true;
if(activeMenu_)
if(activeMenu_)
{
activeMenu_->deallocateSpritePoints();
activeMenu_->allocateSpritePoints();

View File

@ -47,6 +47,8 @@ public:
virtual void onNewItemSelected(Item *);
bool pushCollection(CollectionInfo *collection);
bool popCollection();
void enterMenu();
void exitMenu();
void nextPlaylist();
void favPlaylist();
void pushMenu(ScrollingList *s);
@ -67,6 +69,7 @@ public:
void setScrolling(ScrollDirection direction);
bool isHorizontalScroll();
unsigned int getMenuDepth();
void setNewItemSelected();
Item *getSelectedItem();
Item *getSelectedItem(int offset);
void removeSelectedItem();
@ -74,7 +77,6 @@ public:
unsigned int getScrollOffsetIndex();
bool isIdle();
bool isMenuIdle();
bool isHidden();
void setStatusTextComponent(Text *t);
void update(float dt);
void draw();
@ -89,7 +91,8 @@ public:
void removePlaylist();
private:
void highlight();
void highlightEnter();
void highlightExit();
void playlistChange();
std::string collectionName_;
Configuration &config_;
@ -120,8 +123,6 @@ private:
Item *selectedItem_;
Text *textStatusComponent_;
bool selectedItemChanged_;
bool playlistChanged_;
Sound *loadSoundChunk_;
Sound *unloadSoundChunk_;
Sound *highlightSoundChunk_;

View File

@ -60,7 +60,7 @@ RetroFE::RetroFE(Configuration &c)
, currentTime_(0)
, lastLaunchReturnTime_(0)
, keyLastTime_(0)
, keyDelayTime_(.3f)
, keyDelayTime_(.3f)
{
}
@ -90,8 +90,8 @@ int RetroFE::initialize(void *context)
Logger::write(Logger::ZONE_INFO, "RetroFE", "Initializing");
if(!instance->input_.initialize())
{
if(!instance->input_.initialize())
{
Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not initialize user controls");
instance->initializeError = true;
return -1;
@ -167,7 +167,6 @@ void RetroFE::allocateGraphicsMemory()
if(currentPage_)
{
currentPage_->allocateGraphicsMemory();
currentPage_->start();
}
}
@ -239,7 +238,8 @@ void RetroFE::run()
int initializeStatus = 0;
// load the initial splash screen, unload it once it is complete
currentPage_ = loadSplashPage();
currentPage_ = loadSplashPage();
state = RETROFE_ENTER;
bool splashMode = true;
Launcher l(*this, config_);
@ -270,9 +270,9 @@ void RetroFE::run()
if(currentPage_ && !splashMode)
{
// account for when returning from a menu and the previous key was still "stuck"
// account for when returning from a menu and the previous key was still "stuck"
if(lastLaunchReturnTime_ == 0 || (currentTime_ - lastLaunchReturnTime_ > .3))
{
{
state = processUserInput(currentPage_);
lastLaunchReturnTime_ = 0;
}
@ -288,6 +288,22 @@ void RetroFE::run()
break;
}
currentPage_->stop();
state = RETROFE_EXIT;
}
break;
case RETROFE_ENTER:
if(currentPage_->isIdle())
{
state = RETROFE_IDLE;
}
break;
case RETROFE_EXIT:
if(currentPage_->isIdle())
{
// delete the splash screen and use the standard menu
currentPage_->DeInitialize();
delete currentPage_;
@ -301,8 +317,6 @@ void RetroFE::run()
config_.getProperty("firstCollection", firstCollection);
config_.getProperty("collections." + firstCollection + ".list.menuSort", menuSort);
currentPage_->start();
config_.setProperty("currentCollection", firstCollection);
CollectionInfo *info = getCollection(firstCollection);
MenuParser mp;
@ -310,22 +324,62 @@ void RetroFE::run()
mp.buildMenuItems(info, menuSort);
currentPage_->pushCollection(info);
state = RETROFE_ENTER;
}
else
{
state = RETROFE_QUIT_REQUEST;
}
}
break;
case RETROFE_NEXT_PAGE_REQUEST:
currentPage_->exitMenu();
state = RETROFE_NEXT_PAGE_MENU_EXIT;
break;
case RETROFE_NEXT_PAGE_MENU_EXIT:
if(currentPage_->isIdle())
{
state = RETROFE_NEW;
}
break;
bool menuSort = true;
config_.setProperty("currentCollection", nextPageItem_->name);
config_.getProperty("collections." + nextPageItem_->name + ".list.menuSort", menuSort);
CollectionInfo *info = getCollection(nextPageItem_->name);
MenuParser mp;
mp.buildMenuItems(info, menuSort);
currentPage_->pushCollection(info);
bool rememberMenu = false;
config_.getProperty("rememberMenu", rememberMenu);
if(rememberMenu && lastMenuOffsets_.find(nextPageItem_->name) != lastMenuOffsets_.end())
{
currentPage_->setScrollOffsetIndex(lastMenuOffsets_[nextPageItem_->name]);
}
bool autoFavorites = true;
config_.getProperty("autoFavorites", autoFavorites);
if (autoFavorites)
currentPage_->favPlaylist(); // Switch to favorites if it exists
currentPage_->setNewItemSelected();
currentPage_->enterMenu();
state = RETROFE_NEXT_PAGE_MENU_ENTER;
}
break;
case RETROFE_NEXT_PAGE_MENU_ENTER:
if(currentPage_->isIdle())
{
state = RETROFE_IDLE;
}
break;
case RETROFE_LAUNCH_REQUEST:
nextPageItem_ = currentPage_->getSelectedItem();
@ -334,14 +388,28 @@ void RetroFE::run()
break;
case RETROFE_BACK_REQUEST:
currentPage_->exitMenu();
state = RETROFE_BACK_MENU_EXIT;
break;
case RETROFE_BACK_MENU_EXIT:
if(currentPage_->isIdle())
{
lastMenuOffsets_[currentPage_->getCollectionName()] = currentPage_->getScrollOffsetIndex();
currentPage_->popCollection();
config_.setProperty("currentCollection", currentPage_->getCollectionName());
currentPage_->setNewItemSelected();
currentPage_->enterMenu();
state = RETROFE_BACK_MENU_ENTER;
}
break;
state = RETROFE_NEW;
break;
case RETROFE_BACK_MENU_ENTER:
if(currentPage_->isIdle())
{
state = RETROFE_IDLE;
}
break;
case RETROFE_NEW:
if(currentPage_->isIdle())
@ -356,11 +424,10 @@ void RetroFE::run()
break;
case RETROFE_QUIT:
if(currentPage_->isHidden())
if(currentPage_->isIdle())
{
running = false;
running = false;
}
break;
}
@ -419,9 +486,6 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
bool exit = false;
RETROFE_STATE state = RETROFE_IDLE;
bool rememberMenu = false;
config_.getProperty("rememberMenu", rememberMenu);
if(page->isHorizontalScroll())
{
if (input_.keystate(UserInput::KeyCodeLeft))
@ -431,17 +495,17 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
if (input_.keystate(UserInput::KeyCodeRight))
{
page->setScrolling(Page::ScrollDirectionForward);
}
}
}
else
{
{
if (input_.keystate(UserInput::KeyCodeUp))
{
page->setScrolling(Page::ScrollDirectionBack);
}
if (input_.keystate(UserInput::KeyCodeDown))
{
page->setScrolling(Page::ScrollDirectionForward);
page->setScrolling(Page::ScrollDirectionForward);
}
}
@ -463,7 +527,7 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
keyLastTime_ = currentTime_;
keyDelayTime_-= .05f;
if(keyDelayTime_< 0.1f) keyDelayTime_= 0.1f;
if (input_.keystate(UserInput::KeyCodePageUp))
{
page->pageScroll(Page::ScrollDirectionBack);
@ -514,27 +578,6 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page)
}
else
{
bool menuSort = true;
config_.setProperty("currentCollection", nextPageItem_->name);
config_.getProperty("collections." + nextPageItem_->name + ".list.menuSort", menuSort);
CollectionInfo *info = getCollection(nextPageItem_->name);
MenuParser mp;
mp.buildMenuItems(info, menuSort);
page->pushCollection(info);
if(rememberMenu && lastMenuOffsets_.find(nextPageItem_->name) != lastMenuOffsets_.end())
{
page->setScrollOffsetIndex(lastMenuOffsets_[nextPageItem_->name]);
}
bool autoFavorites = true;
config_.getProperty("autoFavorites", autoFavorites);
if (autoFavorites)
page->favPlaylist(); // Switch to favorites if it exists
state = RETROFE_NEXT_PAGE_REQUEST;
}
}

View File

@ -52,9 +52,15 @@ private:
enum RETROFE_STATE
{
RETROFE_IDLE,
RETROFE_ENTER,
RETROFE_EXIT,
RETROFE_NEXT_PAGE_REQUEST,
RETROFE_NEXT_PAGE_MENU_EXIT,
RETROFE_NEXT_PAGE_MENU_ENTER,
RETROFE_LAUNCH_REQUEST,
RETROFE_BACK_REQUEST,
RETROFE_BACK_MENU_EXIT,
RETROFE_BACK_MENU_ENTER,
RETROFE_NEW,
RETROFE_QUIT_REQUEST,
RETROFE_QUIT,